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  */
19 public class OutputScreen : RefreshListener{
20     private SDL_Window* window;
21     private IRaster mainRaster;
22     public SDL_Renderer* renderer;
23 	private SDL_Rect* outputArea;
24     private void* mPixels;
25     private int mPitch;
26 
27     ///Constructor. x , y : resolution of the window
28     this(const char* title, ushort x, ushort y, uint flags = SDL_WINDOW_OPENGL, SDL_Rect* outputArea = null){
29         SDL_Init(SDL_INIT_VIDEO);
30 		this.outputArea = outputArea;
31         window = SDL_CreateWindow(title , cast(int)SDL_WINDOWPOS_UNDEFINED, cast(int)SDL_WINDOWPOS_UNDEFINED, x, y,
32 				cast(SDL_WindowFlags)flags);
33         if (window == null) {
34 //                throw new Exception();
35 			throw new GraphicsInitializationException("Graphics initialization error! " ~ to!string(SDL_GetError()));
36         }
37         renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
38     }
39     ~this(){
40         SDL_DestroyWindow(window);
41     }
42     ///Sets the main raster. Useful for changing rendering resolutions.
43     public void setMainRaster(IRaster r){
44         mainRaster = r;
45         //sdlTexture = SDL_CreateTextureFromSurface(renderer, mainRaster.getOutput());
46     }
47 	///Enters into fullscreen mode.
48 	public void setToFullscreen(const SDL_DisplayMode* videoMode){
49 		if(SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN)){
50 			throw new VideoModeException("Error while changing to fullscreen mode!" ~ to!string(SDL_GetError()));
51 		}
52 		if(SDL_SetWindowDisplayMode(window, videoMode)){
53 			throw new VideoModeException("Error while changing to fullscreen mode!" ~ to!string(SDL_GetError()));
54 		}
55 	}
56 	///Changes video mode.
57 	public void setVideoMode(const SDL_DisplayMode* videoMode){
58 		/*if(SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN)){
59 			throw new VideoModeException("Error while changing video mode!" ~ to!string(SDL_GetError()));
60 		}*/
61 		if(SDL_SetWindowDisplayMode(window, videoMode)){
62 			throw new VideoModeException("Error while changing video mode!" ~ to!string(SDL_GetError()));
63 		}
64 	}
65 	///Exits fullscreen mode.
66 	public void setToWindowed(){
67 		if(SDL_SetWindowFullscreen(window, SDL_WindowFlags.SDL_WINDOW_SHOWN)){
68 			throw new VideoModeException("Error while changing to windowed mode!" ~ to!string(SDL_GetError()));
69 		}
70 	}
71 	///Sets the scaling quality of the program, affects all output screens.
72 	public static void setScalingQuality(string q){
73 		switch(q){
74 			case "0": SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); break;
75 			case "1": SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); break;
76 			case "2": SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"); break;
77 			default: SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); break;
78 		}
79 
80 	}
81 	///Sets the used video driver.
82 	public static void setDriver(string drv){
83 		switch(drv){
84 			case "direct3d": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "direct3d"); break;
85 			case "opengl": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); break;
86 			case "opengles2": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles2"); break;
87 			case "opengles": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengles"); break;
88 			case "software": SDL_SetHint(SDL_HINT_RENDER_DRIVER, "software"); break;
89 			default: break;
90 		}
91 	}
92 
93     ///Displays the output from the raster when invoked.
94     public void refreshFinished(){
95 		//SDL_Rect r = SDL_Rect(0,0,640,480);
96 		SDL_RenderClear(renderer);
97 		SDL_RenderCopy(renderer, mainRaster.getOutput,null,null);
98 		SDL_RenderPresent(renderer);
99 
100     }
101 }