nuclear@15: #include nuclear@15: #include nuclear@15: #include nuclear@15: #include nuclear@15: #include "opengl.h" nuclear@15: #include "renderer.h" nuclear@15: #include "sdr.h" nuclear@15: #include "datapath.h" nuclear@15: nuclear@17: static bool create_fbo(int xsz, int ysz); nuclear@17: static bool load_shaders(); nuclear@17: static int round_pow2(int x); nuclear@15: nuclear@17: nuclear@17: #define MRT_COUNT 4 nuclear@17: static unsigned int mrt_tex[MRT_COUNT]; nuclear@17: nuclear@17: static unsigned int mrt_prog; nuclear@17: static unsigned int deferred_omni; 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@17: bool init_renderer(int xsz, int ysz) nuclear@17: { nuclear@17: if(!create_fbo(xsz, ysz)) { nuclear@17: return false; nuclear@17: } nuclear@17: if(!load_shaders()) { nuclear@17: return false; nuclear@17: } nuclear@17: return true; nuclear@17: } nuclear@17: nuclear@17: void destroy_renderer() nuclear@17: { nuclear@17: free_program(mrt_prog); nuclear@17: free_program(deferred_omni); nuclear@17: nuclear@17: glDeleteTextures(MRT_COUNT, mrt_tex); nuclear@17: glDeleteFramebuffersEXT(1, &fbo); nuclear@17: } nuclear@17: nuclear@17: void render_deferred(void (*draw_func)()) nuclear@17: { nuclear@17: bind_program(mrt_prog); nuclear@17: draw_func(); nuclear@17: bind_program(0); nuclear@17: } nuclear@17: nuclear@17: static bool create_fbo(int xsz, int ysz) nuclear@17: { nuclear@17: unsigned int clamp = GL_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; nuclear@17: nuclear@17: tex_xsz = round_pow2(xsz); nuclear@17: tex_ysz = round_pow2(ysz); nuclear@17: fb_xsz = xsz; nuclear@17: fb_ysz = ysz; nuclear@17: nuclear@17: if(!glGenFramebuffersEXT) { nuclear@17: fprintf(stderr, "FBO support missing\n"); nuclear@17: return false; nuclear@17: } nuclear@17: glGenFramebuffersEXT(1, &fbo); nuclear@17: nuclear@17: glGenRenderbuffersEXT(1, &rbuf_depth); nuclear@17: glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth); nuclear@17: glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); nuclear@17: glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth); nuclear@17: nuclear@17: glGenTextures(MRT_COUNT, mrt_tex); nuclear@17: 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: }