dungeon_crawler
changeset 41:acfe0c0110fc
- cleaned up the renderer
- implemented fallback (non-deferred renderer)
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Thu, 30 Aug 2012 05:35:00 +0300 |
parents | 38e16366efc2 |
children | 6d71dd4760f9 |
files | prototype/sdr/fallback.p.glsl prototype/sdr/fallback.v.glsl prototype/src/light.cc prototype/src/main.cc prototype/src/material.cc prototype/src/renderer.cc prototype/src/renderer.h prototype/src/renderer_deferred.cc prototype/src/renderer_deferred.h prototype/src/tile.cc |
diffstat | 10 files changed, 526 insertions(+), 287 deletions(-) [+] |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/prototype/sdr/fallback.p.glsl Thu Aug 30 05:35:00 2012 +0300 1.3 @@ -0,0 +1,38 @@ 1.4 +uniform sampler2D tex_dif, tex_norm; 1.5 + 1.6 +varying vec3 pos, norm, tang; 1.7 + 1.8 +const float fog_start = 3.0; 1.9 +const float fog_end = 6.0; 1.10 + 1.11 +void main() 1.12 +{ 1.13 + vec3 texel = texture2D(tex_dif, gl_TexCoord[0].st).xyz; 1.14 + 1.15 + vec3 n = normalize(norm); 1.16 + vec3 t = normalize(tang); 1.17 + vec3 b = cross(n, t); 1.18 + 1.19 + mat3 tbn_mat = mat3( 1.20 + t.x, b.x, n.x, 1.21 + t.y, b.y, n.y, 1.22 + t.z, b.z, n.z); 1.23 + 1.24 + 1.25 + const vec3 lpos = vec3(0.0, 0.0, -0.5); 1.26 + vec3 ldir = tbn_mat * normalize(lpos - pos); 1.27 + 1.28 + const vec3 vdir = vec3(0.0, 0.0, 1.0); 1.29 + vec3 hvec = normalize(vdir + ldir); 1.30 + 1.31 + n = normalize(texture2D(tex_norm, gl_TexCoord[0].st).xyz * 2.0 - 1.0); 1.32 + float ndotl = max(dot(n, ldir), 0.0); 1.33 + float ndoth = max(dot(n, hvec), 0.0); 1.34 + 1.35 + vec3 diffuse = gl_FrontMaterial.diffuse.xyz * texel * ndotl; 1.36 + vec3 specular = gl_FrontMaterial.specular.xyz * pow(ndoth, gl_FrontMaterial.shininess); 1.37 + 1.38 + float fog = clamp((fog_end + pos.z) / (fog_end - fog_start), 0.0, 1.0); 1.39 + 1.40 + gl_FragColor = vec4((diffuse + specular) * fog, 1.0); 1.41 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/prototype/sdr/fallback.v.glsl Thu Aug 30 05:35:00 2012 +0300 2.3 @@ -0,0 +1,13 @@ 2.4 +attribute vec3 attr_tangent; 2.5 + 2.6 +varying vec3 pos, norm, tang; 2.7 + 2.8 +void main() 2.9 +{ 2.10 + gl_Position = ftransform(); 2.11 + pos = (gl_ModelViewMatrix * gl_Vertex).xyz; 2.12 + norm = gl_NormalMatrix * gl_Normal; 2.13 + tang = gl_NormalMatrix * attr_tangent; 2.14 + 2.15 + gl_TexCoord[0] = gl_MultiTexCoord0; 2.16 +}
3.1 --- a/prototype/src/light.cc Thu Aug 30 03:05:04 2012 +0300 3.2 +++ b/prototype/src/light.cc Thu Aug 30 05:35:00 2012 +0300 3.3 @@ -114,7 +114,7 @@ 3.4 3.5 void PointLight::draw() const 3.6 { 3.7 - unsigned int sdr = get_deferred_shader(); 3.8 + unsigned int sdr = rend->get_current_program(); 3.9 if(sdr) { 3.10 int loc; 3.11 if((loc = glGetUniformLocation(sdr, "light_radius")) != -1) {
4.1 --- a/prototype/src/main.cc Thu Aug 30 03:05:04 2012 +0300 4.2 +++ b/prototype/src/main.cc Thu Aug 30 05:35:00 2012 +0300 4.3 @@ -8,6 +8,7 @@ 4.4 #include "datapath.h" 4.5 #include "tileset.h" 4.6 #include "renderer.h" 4.7 +#include "renderer_deferred.h" 4.8 #include "cmdcon.h" 4.9 #include "cfg.h" 4.10 #include "timer.h" 4.11 @@ -70,11 +71,15 @@ 4.12 4.13 bool init(int xsz, int ysz) 4.14 { 4.15 + // backup light for the forward crappy renderer 4.16 glEnable(GL_LIGHTING); 4.17 glEnable(GL_LIGHT0); 4.18 - float ldir[] = {-1, 1, 2, 0}; 4.19 + 4.20 + float ldir[] = {0, 0, -0.5, 1}; 4.21 glLightfv(GL_LIGHT0, GL_POSITION, ldir); 4.22 - glEnable(GL_NORMALIZE); 4.23 + float lcol[] = {1, 1, 1, 1}; 4.24 + glLightfv(GL_LIGHT0, GL_DIFFUSE, lcol); 4.25 + glLightfv(GL_LIGHT0, GL_SPECULAR, lcol); 4.26 4.27 glEnable(GL_DEPTH_TEST); 4.28 glEnable(GL_CULL_FACE); 4.29 @@ -84,8 +89,15 @@ 4.30 add_data_path("data"); 4.31 add_data_path("sdr"); 4.32 4.33 - if(!init_renderer(xsz, ysz)) { 4.34 - return false; 4.35 + rend = new DeferredRenderer(); 4.36 + if(!rend->init(xsz, ysz)) { 4.37 + printf("falling back to crappy renderer...\n"); 4.38 + 4.39 + rend = new FwdRenderer(); 4.40 + if(!rend->init(xsz, ysz)) { 4.41 + fprintf(stderr, "failed to create renderer\n"); 4.42 + return false; 4.43 + } 4.44 } 4.45 4.46 if(!init_cmdcon()) { 4.47 @@ -115,8 +127,7 @@ 4.48 { 4.49 delete level; 4.50 delete tileset; 4.51 - 4.52 - destroy_renderer(); 4.53 + delete rend; 4.54 4.55 cleanup_cmdcon(); 4.56 } 4.57 @@ -165,15 +176,13 @@ 4.58 4.59 glutSwapBuffers(); 4.60 assert(glGetError() == GL_NO_ERROR); 4.61 - 4.62 - usleep(10000); 4.63 } 4.64 4.65 void draw() 4.66 { 4.67 - glClear(GL_COLOR_BUFFER_BIT); 4.68 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 4.69 4.70 - render_deferred(level); 4.71 + rend->render(level); 4.72 4.73 if(show_con) { 4.74 draw_cmdcon(); 4.75 @@ -240,7 +249,7 @@ 4.76 cfg.width = x; 4.77 cfg.height = y; 4.78 4.79 - resize_renderer(x, y); 4.80 + rend->resize(x, y); 4.81 } 4.82 4.83 static bool stereo_shift_pressed;
5.1 --- a/prototype/src/material.cc Thu Aug 30 03:05:04 2012 +0300 5.2 +++ b/prototype/src/material.cc Thu Aug 30 05:35:00 2012 +0300 5.3 @@ -3,6 +3,7 @@ 5.4 #include <assimp/material.h> 5.5 #include "opengl.h" 5.6 #include "material.h" 5.7 +#include "renderer.h" 5.8 5.9 extern bool ass_obj_hack; 5.10 5.11 @@ -74,7 +75,7 @@ 5.12 glDisable(GL_TEXTURE_2D); 5.13 } 5.14 5.15 - if(tex[TEXTYPE_NORMAL]) { 5.16 + if(rend->get_current_program() && tex[TEXTYPE_NORMAL]) { 5.17 glActiveTextureARB(GL_TEXTURE1); 5.18 glBindTexture(GL_TEXTURE_2D, tex[TEXTYPE_NORMAL]); 5.19 glEnable(GL_TEXTURE_2D);
6.1 --- a/prototype/src/renderer.cc Thu Aug 30 03:05:04 2012 +0300 6.2 +++ b/prototype/src/renderer.cc Thu Aug 30 05:35:00 2012 +0300 6.3 @@ -1,247 +1,97 @@ 6.4 -#include <stdio.h> 6.5 -#include <stdlib.h> 6.6 -#include <string.h> 6.7 -#include <limits.h> 6.8 -#include <assert.h> 6.9 #include "opengl.h" 6.10 #include "renderer.h" 6.11 #include "level.h" 6.12 #include "sdr.h" 6.13 #include "datapath.h" 6.14 6.15 -#undef DBG_VIS_MRT 6.16 +static unsigned int load_sdr(const char *vfname, const char *pfname); 6.17 6.18 -#ifdef DBG_VIS_MRT 6.19 -static void draw_deferred_debug(); 6.20 -#endif 6.21 +Renderer *rend; 6.22 6.23 -static bool create_fbo(int xsz, int ysz); 6.24 -static unsigned int load_sdr(const char *vfname, const char *pfname); 6.25 -static int round_pow2(int x); 6.26 6.27 +Renderer::Renderer() 6.28 +{ 6.29 + width = height = 0; 6.30 +} 6.31 6.32 -#define MRT_COUNT 3 6.33 -static unsigned int mrt_tex[MRT_COUNT]; 6.34 +Renderer::~Renderer() 6.35 +{ 6.36 +} 6.37 6.38 -static unsigned int mrt_prog; 6.39 -static unsigned int deferred_omni, deferred_debug; 6.40 +bool Renderer::init(int xsz, int ysz) 6.41 +{ 6.42 + width = xsz; 6.43 + height = ysz; 6.44 6.45 -static unsigned int fbo, rbuf_depth; 6.46 -static const char *fbstname[] = { 6.47 - "GL_FRAMEBUFFER_COMPLETE", 6.48 - "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", 6.49 - "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", 6.50 - "no such fbo error", 6.51 - "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", 6.52 - "GL_FRAMEBUFFER_INCOMPLETE_FORMATS", 6.53 - "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", 6.54 - "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", 6.55 - "GL_FRAMEBUFFER_UNSUPPORTED" 6.56 -}; 6.57 + rend = this; 6.58 + return true; 6.59 +} 6.60 6.61 -static int fb_xsz, fb_ysz, tex_xsz, tex_ysz; 6.62 +int Renderer::get_tangent_location() const 6.63 +{ 6.64 + return -1; 6.65 +} 6.66 6.67 +unsigned int Renderer::get_current_program() const 6.68 +{ 6.69 + return 0; 6.70 +} 6.71 6.72 +void Renderer::resize(int xsz, int ysz) 6.73 +{ 6.74 + width = xsz; 6.75 + height = ysz; 6.76 +} 6.77 6.78 -bool init_renderer(int xsz, int ysz) 6.79 + 6.80 +// ---- fallback forward renderer ---- 6.81 +FwdRenderer::FwdRenderer() 6.82 { 6.83 - if(!GLEW_ARB_texture_float) { 6.84 - fprintf(stderr, "Error: OpenGL implementation doesn't support floating point textures\n"); 6.85 - return false; 6.86 + sdrprog = 0; 6.87 + tang_attr = -1; 6.88 +} 6.89 + 6.90 +FwdRenderer::~FwdRenderer() 6.91 +{ 6.92 + if(sdrprog) { 6.93 + free_program(sdrprog); 6.94 } 6.95 - if(!GLEW_ARB_draw_buffers) { 6.96 - fprintf(stderr, "Error: OpenGL implementation doesn't support multiple render targets\n"); 6.97 - return false; 6.98 - } 6.99 +} 6.100 6.101 - int max_draw_buf; 6.102 - glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buf); 6.103 - printf("max draw buffers: %d\n", max_draw_buf); 6.104 - if(max_draw_buf < MRT_COUNT) { 6.105 - fprintf(stderr, "OpenGL implementation doesn't support enough draw buffers\n"); 6.106 - return false; 6.107 - } 6.108 +bool FwdRenderer::init(int xsz, int ysz) 6.109 +{ 6.110 + width = xsz; 6.111 + height = ysz; 6.112 6.113 - if(!create_fbo(xsz, ysz)) { 6.114 - return false; 6.115 - } 6.116 - CHECKGLERR; 6.117 - 6.118 - if(!(mrt_prog = load_sdr("mrt.v.glsl", "mrt.p.glsl"))) { 6.119 - return false; 6.120 - } 6.121 - set_uniform_int(mrt_prog, "tex_dif", 0); 6.122 - set_uniform_int(mrt_prog, "tex_norm", 1); 6.123 - 6.124 - if(!(deferred_debug = load_sdr("deferred.v.glsl", "deferred.p.glsl"))) { 6.125 - return false; 6.126 - } 6.127 - for(int i=0; i<MRT_COUNT; i++) { 6.128 - char uname[32]; 6.129 - sprintf(uname, "mrt%d", i); 6.130 - set_uniform_int(deferred_debug, uname, i); 6.131 - } 6.132 - 6.133 - if(!(deferred_omni = load_sdr("deferred_omni.v.glsl", "deferred_omni.p.glsl"))) { 6.134 - return false; 6.135 - } 6.136 - for(int i=0; i<MRT_COUNT; i++) { 6.137 - char uname[32]; 6.138 - sprintf(uname, "mrt%d", i); 6.139 - set_uniform_int(deferred_omni, uname, i); 6.140 + if(glUseProgram && (sdrprog = load_sdr("fallback.v.glsl", "fallback.p.glsl"))) { 6.141 + tang_attr = get_attrib_loc(sdrprog, "attr_tangent"); 6.142 + set_uniform_int(sdrprog, "tex_dif", 0); 6.143 + set_uniform_int(sdrprog, "tex_norm", 1); 6.144 } 6.145 return true; 6.146 } 6.147 6.148 -void destroy_renderer() 6.149 +int FwdRenderer::get_tangent_location() const 6.150 { 6.151 - free_program(mrt_prog); 6.152 - free_program(deferred_omni); 6.153 - 6.154 - glDeleteTextures(MRT_COUNT, mrt_tex); 6.155 - glDeleteFramebuffersEXT(1, &fbo); 6.156 + return tang_attr; 6.157 } 6.158 6.159 -unsigned int get_deferred_shader(void) 6.160 +unsigned int FwdRenderer::get_current_program() const 6.161 { 6.162 - return deferred_omni; 6.163 + return sdrprog; 6.164 } 6.165 6.166 -int get_tangent_location(void) 6.167 +void FwdRenderer::render(const Level *level) const 6.168 { 6.169 - return get_attrib_loc(mrt_prog, "attr_tangent"); 6.170 -} 6.171 + glPushAttrib(GL_ENABLE_BIT); 6.172 + glUseProgram(sdrprog); 6.173 6.174 -void resize_renderer(int xsz, int ysz) 6.175 -{ 6.176 - fb_xsz = xsz; 6.177 - fb_ysz = ysz; 6.178 - 6.179 - // if we need a bigger rendertarget resize all colorbuffer textures and the depth buffer 6.180 - if(xsz > tex_xsz || ysz > tex_ysz) { 6.181 - tex_xsz = round_pow2(xsz); 6.182 - tex_ysz = round_pow2(ysz); 6.183 - 6.184 - for(int i=0; i<MRT_COUNT; i++) { 6.185 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 6.186 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0); 6.187 - } 6.188 - 6.189 - glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 6.190 - glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 6.191 - } 6.192 - 6.193 - 6.194 - // update the texture coordinate scaling factors 6.195 - float tex_scale_x = (float)fb_xsz / tex_xsz; 6.196 - float tex_scale_y = (float)fb_ysz / tex_ysz; 6.197 - 6.198 - set_uniform_float2(deferred_omni, "tex_scale", tex_scale_x, tex_scale_y); 6.199 - set_uniform_float2(deferred_omni, "fb_size", fb_xsz, fb_ysz); 6.200 - 6.201 - set_uniform_float2(deferred_debug, "tex_scale", tex_scale_x, tex_scale_y); 6.202 -} 6.203 - 6.204 -void render_deferred(const Level *level) 6.205 -{ 6.206 - // render into the MRT buffers 6.207 - glUseProgram(mrt_prog); 6.208 - glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 6.209 - 6.210 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 6.211 + glEnable(GL_LIGHTING); 6.212 level->draw(); 6.213 6.214 - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 6.215 - 6.216 -#ifdef DBG_VIS_MRT 6.217 - draw_deferred_debug(); 6.218 -#else 6.219 - 6.220 - // post-process lighting 6.221 - glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); 6.222 - 6.223 - glEnable(GL_BLEND); 6.224 - glBlendFunc(GL_ONE, GL_ONE); 6.225 - 6.226 - glDisable(GL_LIGHTING); 6.227 - glDisable(GL_DEPTH_TEST); 6.228 - glCullFace(GL_FRONT); 6.229 - 6.230 - glUseProgram(deferred_omni); 6.231 - for(int i=0; i<MRT_COUNT; i++) { 6.232 - glActiveTexture(GL_TEXTURE0 + i); 6.233 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 6.234 - glEnable(GL_TEXTURE_2D); 6.235 - } 6.236 - 6.237 - glDepthMask(0); 6.238 - level->draw_lights(); 6.239 - glDepthMask(1); 6.240 - 6.241 - for(int i=0; i<MRT_COUNT; i++) { 6.242 - glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1); 6.243 - glDisable(GL_TEXTURE_2D); 6.244 - } 6.245 + glPopAttrib(); 6.246 6.247 glUseProgram(0); 6.248 - glPopAttrib(); 6.249 -#endif // DBG_VIS_MRT 6.250 -} 6.251 - 6.252 -static bool create_fbo(int xsz, int ysz) 6.253 -{ 6.254 - unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; 6.255 - 6.256 - // round the texture size up to the next power of 2 6.257 - tex_xsz = round_pow2(xsz); 6.258 - tex_ysz = round_pow2(ysz); 6.259 - fb_xsz = xsz; 6.260 - fb_ysz = ysz; 6.261 - 6.262 - if(!glGenFramebuffersEXT) { 6.263 - fprintf(stderr, "FBO support missing\n"); 6.264 - return false; 6.265 - } 6.266 - glGenFramebuffersEXT(1, &fbo); 6.267 - glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 6.268 - 6.269 - glGenTextures(MRT_COUNT, mrt_tex); 6.270 - for(int i=0; i<MRT_COUNT; i++) { 6.271 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 6.272 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp); 6.273 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp); 6.274 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 6.275 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 6.276 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0); 6.277 - 6.278 - // attach to fbo 6.279 - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, 6.280 - GL_TEXTURE_2D, mrt_tex[i], 0); 6.281 - CHECKGLERR; 6.282 - } 6.283 - 6.284 - static GLenum draw_bufs[] = { 6.285 - GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, 6.286 - GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT, 6.287 - GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT, 6.288 - GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT 6.289 - }; 6.290 - glDrawBuffersARB(MRT_COUNT, draw_bufs); 6.291 - 6.292 - glGenRenderbuffersEXT(1, &rbuf_depth); 6.293 - glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 6.294 - glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 6.295 - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth); 6.296 - 6.297 - int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 6.298 - if(fbst != GL_FRAMEBUFFER_COMPLETE) { 6.299 - fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]); 6.300 - return false; 6.301 - } 6.302 - CHECKGLERR; 6.303 - 6.304 - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 6.305 - return true; 6.306 } 6.307 6.308 static unsigned int load_sdr(const char *vfname, const char *pfname) 6.309 @@ -266,61 +116,3 @@ 6.310 } 6.311 return prog; 6.312 } 6.313 - 6.314 -static int round_pow2(int x) 6.315 -{ 6.316 - x--; 6.317 - x = (x >> 1) | x; 6.318 - x = (x >> 2) | x; 6.319 - x = (x >> 4) | x; 6.320 - x = (x >> 8) | x; 6.321 - x = (x >> 16) | x; 6.322 - return x + 1; 6.323 -} 6.324 - 6.325 -#ifdef DBG_VIS_MRT 6.326 -// visualize the MRT buffers 6.327 -static void draw_deferred_debug() 6.328 -{ 6.329 - glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); 6.330 - glUseProgram(deferred_debug); 6.331 - glDisable(GL_DEPTH_TEST); 6.332 - 6.333 - glMatrixMode(GL_PROJECTION); 6.334 - glPushMatrix(); 6.335 - glLoadIdentity(); 6.336 - glMatrixMode(GL_MODELVIEW); 6.337 - glPushMatrix(); 6.338 - glLoadIdentity(); 6.339 - 6.340 - for(int i=0; i<MRT_COUNT; i++) { 6.341 - glActiveTexture(GL_TEXTURE0 + i); 6.342 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 6.343 - glEnable(GL_TEXTURE_2D); 6.344 - } 6.345 - 6.346 - glBegin(GL_QUADS); 6.347 - glTexCoord2f(0, 0); 6.348 - glVertex2f(-1, -1); 6.349 - glTexCoord2f(1, 0); 6.350 - glVertex2f(1, -1); 6.351 - glTexCoord2f(1, 1); 6.352 - glVertex2f(1, 1); 6.353 - glTexCoord2f(0, 1); 6.354 - glVertex2f(-1, 1); 6.355 - glEnd(); 6.356 - 6.357 - for(int i=0; i<MRT_COUNT; i++) { 6.358 - glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1); 6.359 - glDisable(GL_TEXTURE_2D); 6.360 - } 6.361 - 6.362 - glMatrixMode(GL_PROJECTION); 6.363 - glPopMatrix(); 6.364 - glMatrixMode(GL_MODELVIEW); 6.365 - glPopMatrix(); 6.366 - 6.367 - glUseProgram(0); 6.368 - glPopAttrib(); 6.369 -} 6.370 -#endif
7.1 --- a/prototype/src/renderer.h Thu Aug 30 03:05:04 2012 +0300 7.2 +++ b/prototype/src/renderer.h Thu Aug 30 05:35:00 2012 +0300 7.3 @@ -3,15 +3,44 @@ 7.4 7.5 class Level; 7.6 7.7 -bool init_renderer(int xsz, int ysz); 7.8 -void destroy_renderer(); 7.9 +class Renderer { 7.10 +protected: 7.11 + int width, height; 7.12 7.13 -unsigned int get_deferred_shader(void); 7.14 -int get_tangent_location(void); 7.15 +public: 7.16 + Renderer(); 7.17 + virtual ~Renderer(); 7.18 7.19 -void resize_renderer(int xsz, int ysz); 7.20 + virtual bool init(int xsz, int ysz); 7.21 7.22 -void update_renderer(unsigned long msec, float dt); 7.23 -void render_deferred(const Level *level); 7.24 + virtual int get_tangent_location() const; 7.25 + virtual unsigned int get_current_program() const; 7.26 + 7.27 + virtual void resize(int xsz, int ysz); 7.28 + 7.29 + virtual void render(const Level *level) const = 0; 7.30 +}; 7.31 + 7.32 + 7.33 +class FwdRenderer : public Renderer { 7.34 +protected: 7.35 + unsigned int sdrprog; 7.36 + int tang_attr; 7.37 + 7.38 +public: 7.39 + FwdRenderer(); 7.40 + ~FwdRenderer(); 7.41 + 7.42 + bool init(int xsz, int ysz); 7.43 + 7.44 + int get_tangent_location() const; 7.45 + unsigned int get_current_program() const; 7.46 + 7.47 + void render(const Level *level) const; 7.48 +}; 7.49 + 7.50 + 7.51 +extern Renderer *rend; 7.52 + 7.53 7.54 #endif // RENDERER_H_
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/prototype/src/renderer_deferred.cc Thu Aug 30 05:35:00 2012 +0300 8.3 @@ -0,0 +1,322 @@ 8.4 +#include <stdio.h> 8.5 +#include <stdlib.h> 8.6 +#include <string.h> 8.7 +#include <limits.h> 8.8 +#include "opengl.h" 8.9 +#include "renderer_deferred.h" 8.10 +#include "level.h" 8.11 +#include "sdr.h" 8.12 +#include "datapath.h" 8.13 + 8.14 +static unsigned int load_sdr(const char *vfname, const char *pfname); 8.15 +static int round_pow2(int x); 8.16 + 8.17 +DeferredRenderer::DeferredRenderer() 8.18 +{ 8.19 + fbo = rbuf_depth = 0; 8.20 + for(int i=0; i<MRT_COUNT; i++) { 8.21 + mrt_tex[i] = 0; 8.22 + } 8.23 + tex_xsz = tex_ysz = 0; 8.24 + 8.25 + mrt_prog = deferred_debug = deferred_omni = 0; 8.26 + 8.27 + curr_prog = 0; 8.28 +} 8.29 + 8.30 +DeferredRenderer::~DeferredRenderer() 8.31 +{ 8.32 + if(mrt_prog) { 8.33 + free_program(mrt_prog); 8.34 + } 8.35 + if(deferred_omni) { 8.36 + free_program(deferred_omni); 8.37 + } 8.38 + if(deferred_debug) { 8.39 + free_program(deferred_debug); 8.40 + } 8.41 + 8.42 + if(mrt_tex[0]) { 8.43 + glDeleteTextures(MRT_COUNT, mrt_tex); 8.44 + } 8.45 + if(fbo) { 8.46 + glDeleteFramebuffersEXT(1, &fbo); 8.47 + } 8.48 +} 8.49 + 8.50 +bool DeferredRenderer::init(int xsz, int ysz) 8.51 +{ 8.52 + width = xsz; 8.53 + height = ysz; 8.54 + 8.55 + if(!GLEW_ARB_texture_float) { 8.56 + fprintf(stderr, "%s: error: no floating point texture support\n", __func__); 8.57 + return false; 8.58 + } 8.59 + if(!GLEW_ARB_draw_buffers) { 8.60 + fprintf(stderr, "%s: error: no multiple render target support\n", __func__); 8.61 + return false; 8.62 + } 8.63 + 8.64 + int max_draw_buf; 8.65 + glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buf); 8.66 + printf("max draw buffers: %d\n", max_draw_buf); 8.67 + if(max_draw_buf < MRT_COUNT) { 8.68 + fprintf(stderr, "%s: error: not enough draw buffers (%d), %d required\n", __func__, max_draw_buf, MRT_COUNT); 8.69 + return false; 8.70 + } 8.71 + 8.72 + if(!create_fbo()) { 8.73 + return false; 8.74 + } 8.75 + 8.76 + if(!(mrt_prog = load_sdr("mrt.v.glsl", "mrt.p.glsl"))) { 8.77 + return false; 8.78 + } 8.79 + set_uniform_int(mrt_prog, "tex_dif", 0); 8.80 + set_uniform_int(mrt_prog, "tex_norm", 1); 8.81 + 8.82 + if(!(deferred_omni = load_sdr("deferred_omni.v.glsl", "deferred_omni.p.glsl"))) { 8.83 + return false; 8.84 + } 8.85 + for(int i=0; i<MRT_COUNT; i++) { 8.86 + char uname[32]; 8.87 + sprintf(uname, "mrt%d", i); 8.88 + set_uniform_int(deferred_omni, uname, i); 8.89 + } 8.90 + 8.91 + rend = this; 8.92 + return true; 8.93 +} 8.94 + 8.95 +int DeferredRenderer::get_tangent_location() const 8.96 +{ 8.97 + return get_attrib_loc(mrt_prog, "attr_tangent"); 8.98 +} 8.99 + 8.100 +unsigned int DeferredRenderer::get_current_program() const 8.101 +{ 8.102 + return curr_prog; 8.103 +} 8.104 + 8.105 +void DeferredRenderer::resize(int xsz, int ysz) 8.106 +{ 8.107 + width = xsz; 8.108 + height = ysz; 8.109 + 8.110 + // if we need a bigger rendertarget ... 8.111 + if(xsz > tex_xsz || ysz > tex_ysz) { 8.112 + tex_xsz = round_pow2(xsz); 8.113 + tex_ysz = round_pow2(ysz); 8.114 + 8.115 + // ... resize all the color buffers 8.116 + for(int i=0; i<MRT_COUNT; i++) { 8.117 + glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 8.118 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0); 8.119 + } 8.120 + 8.121 + // ... resize the depth buffer 8.122 + glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 8.123 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 8.124 + } 8.125 + 8.126 + // update the texture coordinate scaling factors 8.127 + float tex_scale_x = (float)width / tex_xsz; 8.128 + float tex_scale_y = (float)height / tex_ysz; 8.129 + 8.130 + set_uniform_float2(deferred_omni, "tex_scale", tex_scale_x, tex_scale_y); 8.131 + set_uniform_float2(deferred_omni, "fb_size", width, height); 8.132 +} 8.133 + 8.134 +void DeferredRenderer::render(const Level *level) const 8.135 +{ 8.136 + // render into the MRT buffers 8.137 + glUseProgram(mrt_prog); 8.138 + curr_prog = mrt_prog; 8.139 + 8.140 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 8.141 + 8.142 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 8.143 + level->draw(); 8.144 + 8.145 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 8.146 + 8.147 + // post-process lighting 8.148 + glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); 8.149 + 8.150 + glEnable(GL_BLEND); 8.151 + glBlendFunc(GL_ONE, GL_ONE); 8.152 + 8.153 + glDisable(GL_LIGHTING); 8.154 + glDisable(GL_DEPTH_TEST); 8.155 + glCullFace(GL_FRONT); 8.156 + 8.157 + glUseProgram(deferred_omni); 8.158 + curr_prog = deferred_omni; 8.159 + 8.160 + for(int i=0; i<MRT_COUNT; i++) { 8.161 + glActiveTexture(GL_TEXTURE0 + i); 8.162 + glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 8.163 + glEnable(GL_TEXTURE_2D); 8.164 + } 8.165 + 8.166 + glDepthMask(0); 8.167 + level->draw_lights(); 8.168 + glDepthMask(1); 8.169 + 8.170 + for(int i=0; i<MRT_COUNT; i++) { 8.171 + glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1); 8.172 + glDisable(GL_TEXTURE_2D); 8.173 + } 8.174 + 8.175 + glUseProgram(0); 8.176 + curr_prog = 0; 8.177 + glPopAttrib(); 8.178 +} 8.179 + 8.180 +static const char *fbstname[] = { 8.181 + "GL_FRAMEBUFFER_COMPLETE", 8.182 + "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", 8.183 + "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", 8.184 + "no such fbo error", 8.185 + "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", 8.186 + "GL_FRAMEBUFFER_INCOMPLETE_FORMATS", 8.187 + "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", 8.188 + "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", 8.189 + "GL_FRAMEBUFFER_UNSUPPORTED" 8.190 +}; 8.191 + 8.192 +bool DeferredRenderer::create_fbo() 8.193 +{ 8.194 + unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; 8.195 + 8.196 + // round the texture size up to the next power of 2 8.197 + tex_xsz = round_pow2(width); 8.198 + tex_ysz = round_pow2(height); 8.199 + 8.200 + if(!glGenFramebuffersEXT) { 8.201 + fprintf(stderr, "FBO support missing\n"); 8.202 + return false; 8.203 + } 8.204 + glGenFramebuffersEXT(1, &fbo); 8.205 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 8.206 + 8.207 + glGenTextures(MRT_COUNT, mrt_tex); 8.208 + for(int i=0; i<MRT_COUNT; i++) { 8.209 + glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 8.210 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp); 8.211 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp); 8.212 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 8.213 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 8.214 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0); 8.215 + 8.216 + // attach to fbo 8.217 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, 8.218 + GL_TEXTURE_2D, mrt_tex[i], 0); 8.219 + CHECKGLERR; 8.220 + } 8.221 + 8.222 + static GLenum draw_bufs[] = { 8.223 + GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, 8.224 + GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT, 8.225 + GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT, 8.226 + GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT 8.227 + }; 8.228 + glDrawBuffersARB(MRT_COUNT, draw_bufs); 8.229 + 8.230 + glGenRenderbuffersEXT(1, &rbuf_depth); 8.231 + glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 8.232 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 8.233 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth); 8.234 + 8.235 + int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 8.236 + if(fbst != GL_FRAMEBUFFER_COMPLETE) { 8.237 + fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]); 8.238 + return false; 8.239 + } 8.240 + CHECKGLERR; 8.241 + 8.242 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 8.243 + return true; 8.244 +} 8.245 + 8.246 +static unsigned int load_sdr(const char *vfname, const char *pfname) 8.247 +{ 8.248 + char vsfile[PATH_MAX], psfile[PATH_MAX]; 8.249 + const char *fname; 8.250 + unsigned int prog; 8.251 + 8.252 + if((fname = datafile_path(vfname))) { 8.253 + strcpy(vsfile, fname); 8.254 + } else { 8.255 + vsfile[0] = 0; 8.256 + } 8.257 + if((fname = datafile_path(pfname))) { 8.258 + strcpy(psfile, fname); 8.259 + } else { 8.260 + psfile[0] = 0; 8.261 + } 8.262 + if(!(prog = create_program_load(vsfile, psfile))) { 8.263 + fprintf(stderr, "failed to load shader program (%s, %s)\n", vsfile, psfile); 8.264 + return 0; 8.265 + } 8.266 + return prog; 8.267 +} 8.268 + 8.269 +static int round_pow2(int x) 8.270 +{ 8.271 + x--; 8.272 + x = (x >> 1) | x; 8.273 + x = (x >> 2) | x; 8.274 + x = (x >> 4) | x; 8.275 + x = (x >> 8) | x; 8.276 + x = (x >> 16) | x; 8.277 + return x + 1; 8.278 +} 8.279 + 8.280 +#ifdef DBG_VIS_MRT 8.281 +// visualize the MRT buffers 8.282 +static void draw_deferred_debug() 8.283 +{ 8.284 + glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); 8.285 + glUseProgram(deferred_debug); 8.286 + glDisable(GL_DEPTH_TEST); 8.287 + 8.288 + glMatrixMode(GL_PROJECTION); 8.289 + glPushMatrix(); 8.290 + glLoadIdentity(); 8.291 + glMatrixMode(GL_MODELVIEW); 8.292 + glPushMatrix(); 8.293 + glLoadIdentity(); 8.294 + 8.295 + for(int i=0; i<MRT_COUNT; i++) { 8.296 + glActiveTexture(GL_TEXTURE0 + i); 8.297 + glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 8.298 + glEnable(GL_TEXTURE_2D); 8.299 + } 8.300 + 8.301 + glBegin(GL_QUADS); 8.302 + glTexCoord2f(0, 0); 8.303 + glVertex2f(-1, -1); 8.304 + glTexCoord2f(1, 0); 8.305 + glVertex2f(1, -1); 8.306 + glTexCoord2f(1, 1); 8.307 + glVertex2f(1, 1); 8.308 + glTexCoord2f(0, 1); 8.309 + glVertex2f(-1, 1); 8.310 + glEnd(); 8.311 + 8.312 + for(int i=0; i<MRT_COUNT; i++) { 8.313 + glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1); 8.314 + glDisable(GL_TEXTURE_2D); 8.315 + } 8.316 + 8.317 + glMatrixMode(GL_PROJECTION); 8.318 + glPopMatrix(); 8.319 + glMatrixMode(GL_MODELVIEW); 8.320 + glPopMatrix(); 8.321 + 8.322 + glUseProgram(0); 8.323 + glPopAttrib(); 8.324 +} 8.325 +#endif
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/prototype/src/renderer_deferred.h Thu Aug 30 05:35:00 2012 +0300 9.3 @@ -0,0 +1,35 @@ 9.4 +#ifndef RENDERER_DEFERRED_H_ 9.5 +#define RENDERER_DEFERRED_H_ 9.6 + 9.7 +#include "renderer.h" 9.8 + 9.9 +#define MRT_COUNT 3 9.10 + 9.11 +class DeferredRenderer : public Renderer { 9.12 +private: 9.13 + unsigned int fbo, rbuf_depth; 9.14 + unsigned int mrt_tex[MRT_COUNT]; 9.15 + int tex_xsz, tex_ysz; 9.16 + 9.17 + unsigned int mrt_prog; 9.18 + unsigned int deferred_omni, deferred_debug; 9.19 + 9.20 + mutable unsigned int curr_prog; 9.21 + 9.22 + bool create_fbo(); 9.23 + 9.24 +public: 9.25 + DeferredRenderer(); 9.26 + ~DeferredRenderer(); 9.27 + 9.28 + bool init(int xsz, int ysz); 9.29 + 9.30 + int get_tangent_location() const; 9.31 + unsigned int get_current_program() const; 9.32 + 9.33 + void resize(int xsz, int ysz); 9.34 + 9.35 + void render(const Level *level) const; 9.36 +}; 9.37 + 9.38 +#endif // RENDERER_DEFERRED_H_
10.1 --- a/prototype/src/tile.cc Thu Aug 30 03:05:04 2012 +0300 10.2 +++ b/prototype/src/tile.cc Thu Aug 30 05:35:00 2012 +0300 10.3 @@ -134,7 +134,7 @@ 10.4 { 10.5 int count = 0; 10.6 10.7 - int attr_loc = get_tangent_location(); 10.8 + int attr_loc = rend->get_tangent_location(); 10.9 if(attr_loc == -1) { 10.10 fprintf(stderr, "warning: failed to retrieve tangent attribute location while loading tile\n"); 10.11 }