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