1 /*
2  * Copyright (C) 2015-2017, by Laszlo Szeremi under the Boost license.
3  *
4  * Pixel Perfect Engine, graphics.outputScreen module
5  */
6 module pixelperfectengine.graphics.outputscreen;
7 
8 import bindbc.sdl;
9 import pixelperfectengine.graphics.raster;
10 import pixelperfectengine.system.exc;
11 import std.stdio;
12 import std.conv;
13 
14 
15 /**
16  * Output window, uses SDL to output the graphics on screen.
17  * TODO: Add borderless window support for better concreteUI integration.
18  * NOTE: Once the iota library gets raster output support, this subsystem will get refactored.
19  */
20 public class OutputScreen : RefreshListener{
21 	private SDL_Window* window;
22 	private IRaster mainRaster;
23 	public SDL_Renderer* renderer;
24 	private SDL_Rect* outputArea;
25 	private void* mPixels;
26 	private int mPitch;
27 
28 	///Constructor. x , y : resolution of the window
29 	this(const char* title, ushort x, ushort y, uint flags = SDL_WINDOW_OPENGL, SDL_Rect* outputArea = null){
30 	SDL_Init(SDL_INIT_VIDEO);
31 		this.outputArea = outputArea;
32 		window = SDL_CreateWindow(title , cast(int)SDL_WINDOWPOS_UNDEFINED, cast(int)SDL_WINDOWPOS_UNDEFINED, x, y,
33 				cast(SDL_WindowFlags)flags);
34 		if (window == null) {
35 //                throw new Exception();
36 			throw new GraphicsInitializationException("Graphics initialization error! " ~ to!string(SDL_GetError()));
37 		}
38 		renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
39 	}
40 	~this(){
41 		SDL_DestroyWindow(window);
42 	}
43 	///Sets the main raster. Useful for changing rendering resolutions.
44 	public void setMainRaster(IRaster r){
45 		mainRaster = r;
46 		//sdlTexture = SDL_CreateTextureFromSurface(renderer, mainRaster.getOutput());
47 	}
48 	///Enters into fullscreen mode.
49 	public void setToFullscreen(const SDL_DisplayMode* videoMode){
50 		if(SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN)){
51 			throw new VideoModeException("Error while changing to fullscreen mode!" ~ to!string(SDL_GetError()));
52 		}
53 		if(SDL_SetWindowDisplayMode(window, videoMode)){
54 			throw new VideoModeException("Error while changing to fullscreen mode!" ~ to!string(SDL_GetError()));
55 		}
56 	}
57 	///Changes video mode.
58 	public void setVideoMode(const SDL_DisplayMode* videoMode){
59 		/*if(SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN)){
60 			throw new VideoModeException("Error while changing video mode!" ~ to!string(SDL_GetError()));
61 		}*/
62 		if(SDL_SetWindowDisplayMode(window, videoMode)){
63 			throw new VideoModeException("Error while changing video mode!" ~ to!string(SDL_GetError()));
64 		}
65 	}
66 	///Exits fullscreen mode.
67 	public void setToWindowed(){
68 		if(SDL_SetWindowFullscreen(window, SDL_WINDOW_SHOWN)){
69 			throw new VideoModeException("Error while changing to windowed mode!" ~ to!string(SDL_GetError()));
70 		}
71 	}
72 	///Sets the scaling quality of the program, affects all output screens.
73 	public static void setScalingQuality(string q){
74 		switch(q){
75 			case "0": SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); break;
76 			case "1": SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); break;
77 			case "2": SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); break;
78 			default: SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); break;
79 		}
80 
81 	}
82 	///Sets the used video driver.
83 	public static void setDriver(string drv){
84 		switch(drv){
85 			case "direct3d": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d"); break;
86 			case "opengl": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); break;
87 			case "opengles2": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2"); break;
88 			case "opengles": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles"); break;
89 			case "software": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); break;
90 			default: break;
91 		}
92 	}
93 
94 	///Displays the output from the raster when invoked.
95 	public void refreshFinished(){
96 		//SDL_Rect r = SDL_Rect(0,0,640,480);
97 		SDL_RenderClear(renderer);
98 		SDL_RenderCopy(renderer, mainRaster.getOutput,null,null);
99 		SDL_RenderPresent(renderer);
100 
101 	}
102 }