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