nuclear@15: #include nuclear@15: #include nuclear@15: #include nuclear@15: #include nuclear@18: #include nuclear@15: #include "opengl.h" nuclear@15: #include "renderer.h" nuclear@23: #include "level.h" nuclear@15: #include "sdr.h" nuclear@15: #include "datapath.h" nuclear@15: nuclear@18: nuclear@17: static bool create_fbo(int xsz, int ysz); nuclear@18: static unsigned int load_sdr(const char *vfname, const char *pfname); nuclear@17: static int round_pow2(int x); nuclear@15: nuclear@17: nuclear@19: #define MRT_COUNT 4 nuclear@17: static unsigned int mrt_tex[MRT_COUNT]; nuclear@17: nuclear@17: static unsigned int mrt_prog; nuclear@18: static unsigned int deferred_omni, deferred_debug; nuclear@17: nuclear@17: static unsigned int fbo, rbuf_depth; nuclear@17: static const char *fbstname[] = { nuclear@17: "GL_FRAMEBUFFER_COMPLETE", nuclear@17: "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", nuclear@17: "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", nuclear@17: "no such fbo error", nuclear@17: "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", nuclear@17: "GL_FRAMEBUFFER_INCOMPLETE_FORMATS", nuclear@17: "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", nuclear@17: "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", nuclear@17: "GL_FRAMEBUFFER_UNSUPPORTED" nuclear@15: }; nuclear@15: nuclear@17: static int fb_xsz, fb_ysz, tex_xsz, tex_ysz; nuclear@15: nuclear@21: nuclear@21: nuclear@17: bool init_renderer(int xsz, int ysz) nuclear@17: { nuclear@32: if(!GLEW_ARB_texture_float) { nuclear@32: fprintf(stderr, "Error: OpenGL implementation doesn't support floating point textures\n"); nuclear@32: return false; nuclear@32: } nuclear@21: if(!GLEW_ARB_draw_buffers) { nuclear@32: fprintf(stderr, "Error: OpenGL implementation doesn't support multiple render targets\n"); nuclear@21: return false; nuclear@21: } nuclear@21: nuclear@19: int max_draw_buf; nuclear@19: glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buf); nuclear@19: printf("max draw buffers: %d\n", max_draw_buf); nuclear@19: if(max_draw_buf < MRT_COUNT) { nuclear@19: fprintf(stderr, "OpenGL implementation doesn't support enough draw buffers\n"); nuclear@19: return false; nuclear@19: } nuclear@19: nuclear@17: if(!create_fbo(xsz, ysz)) { nuclear@17: return false; nuclear@17: } nuclear@19: CHECKGLERR; nuclear@18: nuclear@18: if(!(mrt_prog = load_sdr("mrt.v.glsl", "mrt.p.glsl"))) { nuclear@18: return false; nuclear@18: } nuclear@23: set_uniform_int(mrt_prog, "tex_dif", 0); nuclear@23: set_uniform_int(mrt_prog, "tex_norm", 1); nuclear@23: nuclear@18: if(!(deferred_debug = load_sdr("deferred.v.glsl", "deferred.p.glsl"))) { nuclear@17: return false; nuclear@17: } nuclear@23: for(int i=0; i tex_xsz || ysz > tex_ysz) { nuclear@23: tex_xsz = round_pow2(xsz); nuclear@23: tex_ysz = round_pow2(ysz); nuclear@23: nuclear@23: for(int i=0; idraw(); nuclear@20: nuclear@18: glBindFramebufferEXT(GL_FRAMEBUFFER, 0); nuclear@18: nuclear@18: nuclear@18: // post-process lighting nuclear@33: glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); nuclear@18: nuclear@30: glEnable(GL_BLEND); nuclear@30: glBlendFunc(GL_ONE, GL_ONE); nuclear@30: nuclear@18: glDisable(GL_LIGHTING); nuclear@30: glDisable(GL_DEPTH_TEST); nuclear@33: glCullFace(GL_FRONT); nuclear@18: nuclear@23: glUseProgram(deferred_omni); nuclear@19: for(int i=0; idraw_lights(); nuclear@23: glDepthMask(1); nuclear@18: nuclear@19: for(int i=0; i> 1) | x; nuclear@17: x = (x >> 2) | x; nuclear@17: x = (x >> 4) | x; nuclear@17: x = (x >> 8) | x; nuclear@17: x = (x >> 16) | x; nuclear@17: return x + 1; nuclear@15: }