1 /* 2 Copyright (c) 2018-2019 Timur Gafarov 3 4 Boost Software License - Version 1.0 - August 17th, 2003 5 Permission is hereby granted, free of charge, to any person or organization 6 obtaining a copy of the software and accompanying documentation covered by 7 this license (the "Software") to use, reproduce, display, distribute, 8 execute, and transmit the Software, and to prepare derivative works of the 9 Software, and to permit third-parties to whom the Software is furnished to 10 do so, all subject to the following: 11 12 The copyright notices in the Software and this entire statement, including 13 the above license grant, this restriction and the following disclaimer, 14 must be included in all copies of the Software, in whole or in part, and 15 all derivative works of the Software, unless such copies or derivative 16 works are solely in the form of machine-executable object code generated by 17 a source language processor. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 22 SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 23 FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 24 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 DEALINGS IN THE SOFTWARE. 26 */ 27 28 module dagon.graphics.gbuffer; 29 30 import std.stdio; 31 import std.math; 32 33 import dlib.core.memory; 34 import dlib.math.vector; 35 import dlib.image.color; 36 37 import dagon.core.libs; 38 import dagon.core.ownership; 39 import dagon.graphics.rc; 40 import dagon.graphics.shaders.geometrypass; 41 import dagon.graphics.terrain; 42 import dagon.resource.scene; 43 44 class GBuffer: Owner 45 { 46 uint width; 47 uint height; 48 49 GeometryPassShader geometryPassShader; 50 51 GLuint fbo; 52 GLuint depthTexture = 0; 53 GLuint colorTexture = 0; 54 GLuint rmsTexture = 0; 55 GLuint positionTexture = 0; 56 GLuint normalTexture = 0; 57 GLuint velocityTexture = 0; 58 GLuint emissionTexture = 0; 59 60 this(uint w, uint h, Owner o) 61 { 62 super(o); 63 64 width = w; 65 height = h; 66 67 geometryPassShader = New!GeometryPassShader(this); 68 69 glActiveTexture(GL_TEXTURE0); 70 71 glGenTextures(1, &depthTexture); 72 glBindTexture(GL_TEXTURE_2D, depthTexture); 73 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 77 glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, null); 78 glBindTexture(GL_TEXTURE_2D, 0); 79 80 glGenTextures(1, &colorTexture); 81 glBindTexture(GL_TEXTURE_2D, colorTexture); 82 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 83 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 84 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 85 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 86 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, null); 87 glBindTexture(GL_TEXTURE_2D, 0); 88 89 glGenTextures(1, &rmsTexture); 90 glBindTexture(GL_TEXTURE_2D, rmsTexture); 91 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, null); 92 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 93 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 94 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 96 glBindTexture(GL_TEXTURE_2D, 0); 97 98 glGenTextures(1, &positionTexture); 99 glBindTexture(GL_TEXTURE_2D, positionTexture); 100 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_RGBA, GL_FLOAT, null); 101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 103 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 104 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 105 glBindTexture(GL_TEXTURE_2D, 0); 106 107 glGenTextures(1, &normalTexture); 108 glBindTexture(GL_TEXTURE_2D, normalTexture); 109 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, null); 110 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 111 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 112 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 113 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 114 glBindTexture(GL_TEXTURE_2D, 0); 115 116 glGenTextures(1, &velocityTexture); 117 glBindTexture(GL_TEXTURE_2D, velocityTexture); 118 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, null); 119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 122 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 123 glBindTexture(GL_TEXTURE_2D, 0); 124 125 glGenTextures(1, &emissionTexture); 126 glBindTexture(GL_TEXTURE_2D, emissionTexture); 127 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, null); 128 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 132 glBindTexture(GL_TEXTURE_2D, 0); 133 134 glGenFramebuffers(1, &fbo); 135 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 136 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture, 0); 137 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, rmsTexture, 0); 138 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, positionTexture, 0); 139 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, normalTexture, 0); 140 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, velocityTexture, 0); 141 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT5, GL_TEXTURE_2D, emissionTexture, 0); 142 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0); 143 144 GLenum[6] bufs = [GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3, GL_COLOR_ATTACHMENT4, GL_COLOR_ATTACHMENT5]; 145 glDrawBuffers(6, bufs.ptr); 146 147 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 148 if (status != GL_FRAMEBUFFER_COMPLETE) 149 writeln(status); 150 151 glBindFramebuffer(GL_FRAMEBUFFER, 0); 152 } 153 154 ~this() 155 { 156 glBindFramebuffer(GL_FRAMEBUFFER, 0); 157 glDeleteFramebuffers(1, &fbo); 158 159 if (glIsTexture(depthTexture)) 160 glDeleteTextures(1, &depthTexture); 161 if (glIsTexture(colorTexture)) 162 glDeleteTextures(1, &colorTexture); 163 if (glIsTexture(velocityTexture)) 164 glDeleteTextures(1, &velocityTexture); 165 if (glIsTexture(rmsTexture)) 166 glDeleteTextures(1, &rmsTexture); 167 if (glIsTexture(positionTexture)) 168 glDeleteTextures(1, &positionTexture); 169 if (glIsTexture(normalTexture)) 170 glDeleteTextures(1, &normalTexture); 171 if (glIsTexture(emissionTexture)) 172 glDeleteTextures(1, &emissionTexture); 173 } 174 175 void bind() 176 { 177 glBindFramebuffer(GL_FRAMEBUFFER, fbo); 178 } 179 180 void unbind() 181 { 182 glBindFramebuffer(GL_FRAMEBUFFER, 0); 183 } 184 185 void clear() 186 { 187 bind(); 188 189 glViewport(0, 0, width, height); 190 glScissor(0, 0, width, height); 191 glClear(GL_DEPTH_BUFFER_BIT); 192 Color4f zero = Color4f(0, 0, 0, 0); 193 glClearBufferfv(GL_COLOR, 0, zero.arrayof.ptr); 194 glClearBufferfv(GL_COLOR, 1, zero.arrayof.ptr); 195 glClearBufferfv(GL_COLOR, 2, zero.arrayof.ptr); 196 glClearBufferfv(GL_COLOR, 3, zero.arrayof.ptr); 197 glClearBufferfv(GL_COLOR, 4, zero.arrayof.ptr); 198 glClearBufferfv(GL_COLOR, 5, zero.arrayof.ptr); 199 200 unbind(); 201 } 202 203 void renderStatic(Scene scene, RenderingContext* rc) 204 { 205 bind(); 206 207 glEnable(GL_DEPTH_TEST); 208 209 auto rcLocal = *rc; 210 211 rcLocal.overrideShader = geometryPassShader; 212 rcLocal.rebindShaderProgram = false; 213 geometryPassShader.bindProgram(); 214 scene.renderer.renderStaticOpaqueEntities3D(scene, &rcLocal); 215 //renderOpaqueEntities3D(scene, &rcLocal); 216 geometryPassShader.unbindProgram(); 217 218 unbind(); 219 } 220 221 void renderDynamic(Scene scene, RenderingContext* rc) 222 { 223 bind(); 224 225 glEnable(GL_DEPTH_TEST); 226 227 auto rcLocal = *rc; 228 229 rcLocal.overrideShader = geometryPassShader; 230 rcLocal.rebindShaderProgram = false; 231 geometryPassShader.bindProgram(); 232 scene.renderer.renderDynamicOpaqueEntities3D(scene, &rcLocal); 233 //renderOpaqueEntities3D(scene, &rcLocal); 234 geometryPassShader.unbindProgram(); 235 236 unbind(); 237 } 238 239 void renderTerrains(Scene scene, RenderingContext* rc) 240 { 241 bind(); 242 243 glEnable(GL_DEPTH_TEST); 244 foreach(e; scene.entities3Dflat) 245 { 246 if (entityIsTerrain(e)) 247 e.render(rc); 248 } 249 250 unbind(); 251 } 252 }