1 module prova.graphics.screen;
2 
3 import derelict.sdl2.sdl,
4        prova.core,
5        prova.graphics,
6        prova.math,
7        std.conv,
8        std.math;
9 
10 ///
11 class Screen : RenderTarget
12 {
13   ///
14   GLContext glContext;
15   private Game game;
16   private Mesh quad;
17   private Matrix quadProjectionMatrix;
18   private Color clearColor;
19 
20   private this(int width, int height)
21   {
22     super(width, height);
23   }
24 
25   package(prova) this(Game game, int width, int height)
26   {
27     this.game = game;
28 
29     glContext = new GLContext(game.window);
30     this(width, height);
31     disableVSync();
32 
33     quad = new SpriteMesh();
34     quadProjectionMatrix = createQuadProjectionMatrix();
35     clearColor.set(0, 0, 0, 0);
36   }
37 
38   private Matrix createQuadProjectionMatrix()
39   {
40     Matrix quadProjectionMatrix = Matrix.identity;
41     quadProjectionMatrix = quadProjectionMatrix.scale(2, 2, 1);
42     quadProjectionMatrix = quadProjectionMatrix.translate(-1, -1);
43 
44     return quadProjectionMatrix;
45   }
46 
47   // Forward of the active scene's camera
48   private @property Camera camera()
49   {
50     return game.activeScene.camera;
51   }
52 
53   /// Resizes the window
54   override void resize(int width, int height)
55   {
56     SDL_SetWindowSize(game.window, width, height);
57     updateResolution(width, height);
58   }
59 
60   package(prova) void updateResolution(int width, int height)
61   {
62     super.resize(width, height);
63   }
64 
65   ///
66   void enableVSync()
67   {
68     if(SDL_GL_SetSwapInterval(1) < 0)
69       throw new Exception("VSync Error: " ~ to!string(SDL_GetError()));
70   }
71 
72   ///
73   void disableVSync()
74   {
75     if(SDL_GL_SetSwapInterval(0) < 0)
76       throw new Exception("VSync Error: " ~ to!string(SDL_GetError()));
77   }
78 
79   ///
80   void setClearColor(float r, float g, float b)
81   {
82     clearColor.r = r;
83     clearColor.g = g;
84     clearColor.b = b;
85   }
86 
87   ///
88   void setClearColor(Color color)
89   {
90     clearColor = color;
91   }
92 
93   ///
94   override void clear()
95   {
96     bindFrameBuffer(0);
97 
98     glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a);
99     glClearDepth(1);
100     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
101 
102     super.clear();
103   }
104 
105   package(prova) void prepare()
106   {
107     clear();
108 
109     if(camera.useDepthBuffer)
110       glEnable(GL_DEPTH_TEST);
111     else
112       glDisable(GL_DEPTH_TEST);
113 
114     if(camera.resolutionDependent) {
115       camera.width = width;
116       camera.height = height;
117     }
118   }
119 
120   package(prova) void prepareDynamic()
121   {
122     Matrix projection = camera.getScreenMatrix();
123 
124     begin(projection);
125   }
126 
127   package(prova) void endDynamic()
128   {
129     end();
130   }
131 
132   package(prova) void prepareStatic()
133   {
134     Matrix projection = camera.getUIMatrix();
135 
136     begin(projection);
137   }
138 
139   package(prova) void endStatic()
140   {
141     end();
142   }
143 
144   package(prova) void swapBuffer()
145   {
146     // render the FBO
147     ShaderProgram shaderProgram = SpriteBatch.defaultShaderProgram;
148 
149     shaderProgram.setMatrix("transform", quadProjectionMatrix);
150     shaderProgram.setTexture(0, texture.id);
151     shaderProgram.setVector4("clip", Rect(0, 0, 1, 1));
152     shaderProgram.setVector4("tint", Color(1, 1, 1));
153     shaderProgram.drawMesh(quad, 0, DrawMode.TRIANGLE_FAN);
154 
155     SDL_GL_SwapWindow(game.window);
156   }
157 }