nuclear@41: #include nuclear@41: #include nuclear@41: #include nuclear@41: #include nuclear@41: #include "opengl.h" nuclear@41: #include "renderer_deferred.h" nuclear@41: #include "level.h" nuclear@41: #include "sdr.h" nuclear@41: #include "datapath.h" nuclear@41: nuclear@41: static unsigned int load_sdr(const char *vfname, const char *pfname); nuclear@65: static void attach_color_buffer(unsigned int fbo, int count, const unsigned int *tex); nuclear@41: static int round_pow2(int x); nuclear@41: nuclear@41: DeferredRenderer::DeferredRenderer() nuclear@41: { nuclear@65: fbo = rbuf_depth = rend_tex = 0; nuclear@41: for(int i=0; i tex_xsz || ysz > tex_ysz) { nuclear@41: tex_xsz = round_pow2(xsz); nuclear@41: tex_ysz = round_pow2(ysz); nuclear@41: nuclear@41: // ... resize all the color buffers nuclear@41: for(int i=0; idraw(); nuclear@65: nuclear@65: attach_color_buffer(fbo, 1, &rend_tex); nuclear@65: glClear(GL_COLOR_BUFFER_BIT); nuclear@41: nuclear@41: // post-process lighting nuclear@60: light_pass(level); nuclear@60: nuclear@60: glUseProgram(0); nuclear@60: curr_prog = 0; nuclear@62: nuclear@62: render_post(level); nuclear@65: nuclear@65: glBindFramebufferEXT(GL_FRAMEBUFFER, 0); nuclear@65: nuclear@65: // XXX this should be moved to render_post nuclear@65: glBindTexture(GL_TEXTURE_2D, rend_tex); nuclear@65: glEnable(GL_TEXTURE_2D); nuclear@65: nuclear@65: glUseProgram(post_sdr); nuclear@65: glBegin(GL_QUADS); nuclear@65: glTexCoord2f(0, 0); nuclear@65: glVertex2f(-1, -1); nuclear@65: glTexCoord2f((float)width / tex_xsz, 0); nuclear@65: glVertex2f(1, -1); nuclear@65: glTexCoord2f((float)width / tex_xsz, (float)height / tex_ysz); nuclear@65: glVertex2f(1, 1); nuclear@65: glTexCoord2f(0, (float)height / tex_ysz); nuclear@65: glVertex2f(-1, 1); nuclear@65: glEnd(); nuclear@65: glUseProgram(0); nuclear@60: } nuclear@60: nuclear@60: void DeferredRenderer::light_pass(const Level *level) const nuclear@60: { nuclear@65: glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT | GL_TEXTURE_BIT); nuclear@41: nuclear@41: glEnable(GL_BLEND); nuclear@41: glBlendFunc(GL_ONE, GL_ONE); nuclear@41: nuclear@41: glDisable(GL_LIGHTING); nuclear@41: glDisable(GL_DEPTH_TEST); nuclear@41: glCullFace(GL_FRONT); nuclear@41: nuclear@41: glUseProgram(deferred_omni); nuclear@41: curr_prog = deferred_omni; nuclear@41: nuclear@41: for(int i=0; idraw_lights(); nuclear@41: glDepthMask(1); nuclear@41: nuclear@41: for(int i=0; i> 1) | x; nuclear@41: x = (x >> 2) | x; nuclear@41: x = (x >> 4) | x; nuclear@41: x = (x >> 8) | x; nuclear@41: x = (x >> 16) | x; nuclear@41: return x + 1; nuclear@41: } nuclear@41: nuclear@41: #ifdef DBG_VIS_MRT nuclear@41: // visualize the MRT buffers nuclear@41: static void draw_deferred_debug() nuclear@41: { nuclear@41: glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); nuclear@41: glUseProgram(deferred_debug); nuclear@41: glDisable(GL_DEPTH_TEST); nuclear@41: nuclear@41: glMatrixMode(GL_PROJECTION); nuclear@41: glPushMatrix(); nuclear@41: glLoadIdentity(); nuclear@41: glMatrixMode(GL_MODELVIEW); nuclear@41: glPushMatrix(); nuclear@41: glLoadIdentity(); nuclear@41: nuclear@41: for(int i=0; i