dungeon_crawler
diff prototype/src/renderer.cc @ 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 | 84a56fb24850 |
children | c45c42c3d32e |
line diff
1.1 --- a/prototype/src/renderer.cc Thu Aug 30 03:05:04 2012 +0300 1.2 +++ b/prototype/src/renderer.cc Thu Aug 30 05:35:00 2012 +0300 1.3 @@ -1,247 +1,97 @@ 1.4 -#include <stdio.h> 1.5 -#include <stdlib.h> 1.6 -#include <string.h> 1.7 -#include <limits.h> 1.8 -#include <assert.h> 1.9 #include "opengl.h" 1.10 #include "renderer.h" 1.11 #include "level.h" 1.12 #include "sdr.h" 1.13 #include "datapath.h" 1.14 1.15 -#undef DBG_VIS_MRT 1.16 +static unsigned int load_sdr(const char *vfname, const char *pfname); 1.17 1.18 -#ifdef DBG_VIS_MRT 1.19 -static void draw_deferred_debug(); 1.20 -#endif 1.21 +Renderer *rend; 1.22 1.23 -static bool create_fbo(int xsz, int ysz); 1.24 -static unsigned int load_sdr(const char *vfname, const char *pfname); 1.25 -static int round_pow2(int x); 1.26 1.27 +Renderer::Renderer() 1.28 +{ 1.29 + width = height = 0; 1.30 +} 1.31 1.32 -#define MRT_COUNT 3 1.33 -static unsigned int mrt_tex[MRT_COUNT]; 1.34 +Renderer::~Renderer() 1.35 +{ 1.36 +} 1.37 1.38 -static unsigned int mrt_prog; 1.39 -static unsigned int deferred_omni, deferred_debug; 1.40 +bool Renderer::init(int xsz, int ysz) 1.41 +{ 1.42 + width = xsz; 1.43 + height = ysz; 1.44 1.45 -static unsigned int fbo, rbuf_depth; 1.46 -static const char *fbstname[] = { 1.47 - "GL_FRAMEBUFFER_COMPLETE", 1.48 - "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", 1.49 - "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", 1.50 - "no such fbo error", 1.51 - "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", 1.52 - "GL_FRAMEBUFFER_INCOMPLETE_FORMATS", 1.53 - "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", 1.54 - "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", 1.55 - "GL_FRAMEBUFFER_UNSUPPORTED" 1.56 -}; 1.57 + rend = this; 1.58 + return true; 1.59 +} 1.60 1.61 -static int fb_xsz, fb_ysz, tex_xsz, tex_ysz; 1.62 +int Renderer::get_tangent_location() const 1.63 +{ 1.64 + return -1; 1.65 +} 1.66 1.67 +unsigned int Renderer::get_current_program() const 1.68 +{ 1.69 + return 0; 1.70 +} 1.71 1.72 +void Renderer::resize(int xsz, int ysz) 1.73 +{ 1.74 + width = xsz; 1.75 + height = ysz; 1.76 +} 1.77 1.78 -bool init_renderer(int xsz, int ysz) 1.79 + 1.80 +// ---- fallback forward renderer ---- 1.81 +FwdRenderer::FwdRenderer() 1.82 { 1.83 - if(!GLEW_ARB_texture_float) { 1.84 - fprintf(stderr, "Error: OpenGL implementation doesn't support floating point textures\n"); 1.85 - return false; 1.86 + sdrprog = 0; 1.87 + tang_attr = -1; 1.88 +} 1.89 + 1.90 +FwdRenderer::~FwdRenderer() 1.91 +{ 1.92 + if(sdrprog) { 1.93 + free_program(sdrprog); 1.94 } 1.95 - if(!GLEW_ARB_draw_buffers) { 1.96 - fprintf(stderr, "Error: OpenGL implementation doesn't support multiple render targets\n"); 1.97 - return false; 1.98 - } 1.99 +} 1.100 1.101 - int max_draw_buf; 1.102 - glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buf); 1.103 - printf("max draw buffers: %d\n", max_draw_buf); 1.104 - if(max_draw_buf < MRT_COUNT) { 1.105 - fprintf(stderr, "OpenGL implementation doesn't support enough draw buffers\n"); 1.106 - return false; 1.107 - } 1.108 +bool FwdRenderer::init(int xsz, int ysz) 1.109 +{ 1.110 + width = xsz; 1.111 + height = ysz; 1.112 1.113 - if(!create_fbo(xsz, ysz)) { 1.114 - return false; 1.115 - } 1.116 - CHECKGLERR; 1.117 - 1.118 - if(!(mrt_prog = load_sdr("mrt.v.glsl", "mrt.p.glsl"))) { 1.119 - return false; 1.120 - } 1.121 - set_uniform_int(mrt_prog, "tex_dif", 0); 1.122 - set_uniform_int(mrt_prog, "tex_norm", 1); 1.123 - 1.124 - if(!(deferred_debug = load_sdr("deferred.v.glsl", "deferred.p.glsl"))) { 1.125 - return false; 1.126 - } 1.127 - for(int i=0; i<MRT_COUNT; i++) { 1.128 - char uname[32]; 1.129 - sprintf(uname, "mrt%d", i); 1.130 - set_uniform_int(deferred_debug, uname, i); 1.131 - } 1.132 - 1.133 - if(!(deferred_omni = load_sdr("deferred_omni.v.glsl", "deferred_omni.p.glsl"))) { 1.134 - return false; 1.135 - } 1.136 - for(int i=0; i<MRT_COUNT; i++) { 1.137 - char uname[32]; 1.138 - sprintf(uname, "mrt%d", i); 1.139 - set_uniform_int(deferred_omni, uname, i); 1.140 + if(glUseProgram && (sdrprog = load_sdr("fallback.v.glsl", "fallback.p.glsl"))) { 1.141 + tang_attr = get_attrib_loc(sdrprog, "attr_tangent"); 1.142 + set_uniform_int(sdrprog, "tex_dif", 0); 1.143 + set_uniform_int(sdrprog, "tex_norm", 1); 1.144 } 1.145 return true; 1.146 } 1.147 1.148 -void destroy_renderer() 1.149 +int FwdRenderer::get_tangent_location() const 1.150 { 1.151 - free_program(mrt_prog); 1.152 - free_program(deferred_omni); 1.153 - 1.154 - glDeleteTextures(MRT_COUNT, mrt_tex); 1.155 - glDeleteFramebuffersEXT(1, &fbo); 1.156 + return tang_attr; 1.157 } 1.158 1.159 -unsigned int get_deferred_shader(void) 1.160 +unsigned int FwdRenderer::get_current_program() const 1.161 { 1.162 - return deferred_omni; 1.163 + return sdrprog; 1.164 } 1.165 1.166 -int get_tangent_location(void) 1.167 +void FwdRenderer::render(const Level *level) const 1.168 { 1.169 - return get_attrib_loc(mrt_prog, "attr_tangent"); 1.170 -} 1.171 + glPushAttrib(GL_ENABLE_BIT); 1.172 + glUseProgram(sdrprog); 1.173 1.174 -void resize_renderer(int xsz, int ysz) 1.175 -{ 1.176 - fb_xsz = xsz; 1.177 - fb_ysz = ysz; 1.178 - 1.179 - // if we need a bigger rendertarget resize all colorbuffer textures and the depth buffer 1.180 - if(xsz > tex_xsz || ysz > tex_ysz) { 1.181 - tex_xsz = round_pow2(xsz); 1.182 - tex_ysz = round_pow2(ysz); 1.183 - 1.184 - for(int i=0; i<MRT_COUNT; i++) { 1.185 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 1.186 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0); 1.187 - } 1.188 - 1.189 - glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 1.190 - glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 1.191 - } 1.192 - 1.193 - 1.194 - // update the texture coordinate scaling factors 1.195 - float tex_scale_x = (float)fb_xsz / tex_xsz; 1.196 - float tex_scale_y = (float)fb_ysz / tex_ysz; 1.197 - 1.198 - set_uniform_float2(deferred_omni, "tex_scale", tex_scale_x, tex_scale_y); 1.199 - set_uniform_float2(deferred_omni, "fb_size", fb_xsz, fb_ysz); 1.200 - 1.201 - set_uniform_float2(deferred_debug, "tex_scale", tex_scale_x, tex_scale_y); 1.202 -} 1.203 - 1.204 -void render_deferred(const Level *level) 1.205 -{ 1.206 - // render into the MRT buffers 1.207 - glUseProgram(mrt_prog); 1.208 - glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 1.209 - 1.210 - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.211 + glEnable(GL_LIGHTING); 1.212 level->draw(); 1.213 1.214 - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 1.215 - 1.216 -#ifdef DBG_VIS_MRT 1.217 - draw_deferred_debug(); 1.218 -#else 1.219 - 1.220 - // post-process lighting 1.221 - glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); 1.222 - 1.223 - glEnable(GL_BLEND); 1.224 - glBlendFunc(GL_ONE, GL_ONE); 1.225 - 1.226 - glDisable(GL_LIGHTING); 1.227 - glDisable(GL_DEPTH_TEST); 1.228 - glCullFace(GL_FRONT); 1.229 - 1.230 - glUseProgram(deferred_omni); 1.231 - for(int i=0; i<MRT_COUNT; i++) { 1.232 - glActiveTexture(GL_TEXTURE0 + i); 1.233 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 1.234 - glEnable(GL_TEXTURE_2D); 1.235 - } 1.236 - 1.237 - glDepthMask(0); 1.238 - level->draw_lights(); 1.239 - glDepthMask(1); 1.240 - 1.241 - for(int i=0; i<MRT_COUNT; i++) { 1.242 - glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1); 1.243 - glDisable(GL_TEXTURE_2D); 1.244 - } 1.245 + glPopAttrib(); 1.246 1.247 glUseProgram(0); 1.248 - glPopAttrib(); 1.249 -#endif // DBG_VIS_MRT 1.250 -} 1.251 - 1.252 -static bool create_fbo(int xsz, int ysz) 1.253 -{ 1.254 - unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; 1.255 - 1.256 - // round the texture size up to the next power of 2 1.257 - tex_xsz = round_pow2(xsz); 1.258 - tex_ysz = round_pow2(ysz); 1.259 - fb_xsz = xsz; 1.260 - fb_ysz = ysz; 1.261 - 1.262 - if(!glGenFramebuffersEXT) { 1.263 - fprintf(stderr, "FBO support missing\n"); 1.264 - return false; 1.265 - } 1.266 - glGenFramebuffersEXT(1, &fbo); 1.267 - glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 1.268 - 1.269 - glGenTextures(MRT_COUNT, mrt_tex); 1.270 - for(int i=0; i<MRT_COUNT; i++) { 1.271 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 1.272 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp); 1.273 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp); 1.274 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.275 - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.276 - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0); 1.277 - 1.278 - // attach to fbo 1.279 - glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, 1.280 - GL_TEXTURE_2D, mrt_tex[i], 0); 1.281 - CHECKGLERR; 1.282 - } 1.283 - 1.284 - static GLenum draw_bufs[] = { 1.285 - GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT, 1.286 - GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT, 1.287 - GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT, 1.288 - GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT 1.289 - }; 1.290 - glDrawBuffersARB(MRT_COUNT, draw_bufs); 1.291 - 1.292 - glGenRenderbuffersEXT(1, &rbuf_depth); 1.293 - glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); 1.294 - glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 1.295 - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth); 1.296 - 1.297 - int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 1.298 - if(fbst != GL_FRAMEBUFFER_COMPLETE) { 1.299 - fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]); 1.300 - return false; 1.301 - } 1.302 - CHECKGLERR; 1.303 - 1.304 - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 1.305 - return true; 1.306 } 1.307 1.308 static unsigned int load_sdr(const char *vfname, const char *pfname) 1.309 @@ -266,61 +116,3 @@ 1.310 } 1.311 return prog; 1.312 } 1.313 - 1.314 -static int round_pow2(int x) 1.315 -{ 1.316 - x--; 1.317 - x = (x >> 1) | x; 1.318 - x = (x >> 2) | x; 1.319 - x = (x >> 4) | x; 1.320 - x = (x >> 8) | x; 1.321 - x = (x >> 16) | x; 1.322 - return x + 1; 1.323 -} 1.324 - 1.325 -#ifdef DBG_VIS_MRT 1.326 -// visualize the MRT buffers 1.327 -static void draw_deferred_debug() 1.328 -{ 1.329 - glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); 1.330 - glUseProgram(deferred_debug); 1.331 - glDisable(GL_DEPTH_TEST); 1.332 - 1.333 - glMatrixMode(GL_PROJECTION); 1.334 - glPushMatrix(); 1.335 - glLoadIdentity(); 1.336 - glMatrixMode(GL_MODELVIEW); 1.337 - glPushMatrix(); 1.338 - glLoadIdentity(); 1.339 - 1.340 - for(int i=0; i<MRT_COUNT; i++) { 1.341 - glActiveTexture(GL_TEXTURE0 + i); 1.342 - glBindTexture(GL_TEXTURE_2D, mrt_tex[i]); 1.343 - glEnable(GL_TEXTURE_2D); 1.344 - } 1.345 - 1.346 - glBegin(GL_QUADS); 1.347 - glTexCoord2f(0, 0); 1.348 - glVertex2f(-1, -1); 1.349 - glTexCoord2f(1, 0); 1.350 - glVertex2f(1, -1); 1.351 - glTexCoord2f(1, 1); 1.352 - glVertex2f(1, 1); 1.353 - glTexCoord2f(0, 1); 1.354 - glVertex2f(-1, 1); 1.355 - glEnd(); 1.356 - 1.357 - for(int i=0; i<MRT_COUNT; i++) { 1.358 - glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1); 1.359 - glDisable(GL_TEXTURE_2D); 1.360 - } 1.361 - 1.362 - glMatrixMode(GL_PROJECTION); 1.363 - glPopMatrix(); 1.364 - glMatrixMode(GL_MODELVIEW); 1.365 - glPopMatrix(); 1.366 - 1.367 - glUseProgram(0); 1.368 - glPopAttrib(); 1.369 -} 1.370 -#endif