dungeon_crawler
diff prototype/src/renderer.cc @ 72:a27528035e20
- re-organized the renderer classes a bit wrt final render-target
- implemented identity color-grading palette for now
- broke particle systems....
- removed multipass renderer
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 19 Oct 2012 02:45:57 +0300 |
parents | 7f52d6310317 |
children | 67d330038629 |
line diff
1.1 --- a/prototype/src/renderer.cc Tue Oct 16 04:08:35 2012 +0300 1.2 +++ b/prototype/src/renderer.cc Fri Oct 19 02:45:57 2012 +0300 1.3 @@ -6,17 +6,34 @@ 1.4 #include "datapath.h" 1.5 1.6 static unsigned int load_sdr(const char *vfname, const char *pfname); 1.7 +static int round_pow2(int x); 1.8 1.9 Renderer *rend; 1.10 1.11 1.12 Renderer::Renderer() 1.13 { 1.14 + fbo = 0; 1.15 + rend_tex = rend_depth = 0; 1.16 width = height = 0; 1.17 + tex_xsz = tex_ysz = 0; 1.18 + post_sdr = 0; 1.19 } 1.20 1.21 Renderer::~Renderer() 1.22 { 1.23 + if(post_sdr) { 1.24 + free_program(post_sdr); 1.25 + } 1.26 + if(rend_tex) { 1.27 + glDeleteTextures(1, &rend_tex); 1.28 + } 1.29 + if(rend_depth) { 1.30 + glDeleteRenderbuffersEXT(1, &rend_depth); 1.31 + } 1.32 + if(fbo) { 1.33 + glDeleteFramebuffersEXT(1, &fbo); 1.34 + } 1.35 } 1.36 1.37 bool Renderer::init(int xsz, int ysz) 1.38 @@ -24,6 +41,18 @@ 1.39 width = xsz; 1.40 height = ysz; 1.41 1.42 + if(!create_rtarg()) { 1.43 + return false; 1.44 + } 1.45 + 1.46 + if(!(post_sdr = load_sdr("post.v.glsl", "post.p.glsl"))) { 1.47 + return false; 1.48 + } 1.49 + 1.50 + if(!gradepal.create()) { 1.51 + return false; 1.52 + } 1.53 + 1.54 rend = this; 1.55 return true; 1.56 } 1.57 @@ -42,6 +71,20 @@ 1.58 { 1.59 width = xsz; 1.60 height = ysz; 1.61 + 1.62 + // if we need a bigger rendertarget ... 1.63 + if(xsz > tex_xsz || ysz > tex_ysz) { 1.64 + tex_xsz = round_pow2(xsz); 1.65 + tex_ysz = round_pow2(ysz); 1.66 + 1.67 + // ... resize the render target 1.68 + glBindTexture(GL_TEXTURE_2D, rend_tex); 1.69 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 1.70 + 1.71 + // ... resize the depth buffer 1.72 + glBindRenderbufferEXT(GL_RENDERBUFFER, rend_depth); 1.73 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 1.74 + } 1.75 } 1.76 1.77 void Renderer::render_pre(const Level *level) const 1.78 @@ -51,11 +94,106 @@ 1.79 glFogf(GL_FOG_START, 3.0f); 1.80 glFogf(GL_FOG_END, 6.0f); 1.81 // TODO level->draw_pre(); 1.82 + 1.83 + // bind the render target 1.84 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 1.85 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rend_tex, 0); 1.86 + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 1.87 + 1.88 + CHECKGLERR; 1.89 } 1.90 1.91 void Renderer::render_post(const Level *level) const 1.92 { 1.93 level->draw_post(); 1.94 + CHECKGLERR; 1.95 + 1.96 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 1.97 + 1.98 + // draw the rendered output 1.99 + glActiveTextureARB(GL_TEXTURE0); 1.100 + glBindTexture(GL_TEXTURE_2D, rend_tex); 1.101 + glEnable(GL_TEXTURE_2D); 1.102 + 1.103 + // use the color-grading palette 1.104 + glActiveTextureARB(GL_TEXTURE1); 1.105 + glBindTexture(GL_TEXTURE_3D, gradepal.get_texture()); 1.106 + glEnable(GL_TEXTURE_3D); 1.107 + 1.108 + glUseProgram(post_sdr); 1.109 + set_uniform_int(post_sdr, "fbtex", 0); 1.110 + set_uniform_int(post_sdr, "paltex", 1); 1.111 + 1.112 + glBegin(GL_QUADS); 1.113 + glTexCoord2f(0, 0); 1.114 + glVertex2f(-1, -1); 1.115 + glTexCoord2f((float)width / tex_xsz, 0); 1.116 + glVertex2f(1, -1); 1.117 + glTexCoord2f((float)width / tex_xsz, (float)height / tex_ysz); 1.118 + glVertex2f(1, 1); 1.119 + glTexCoord2f(0, (float)height / tex_ysz); 1.120 + glVertex2f(-1, 1); 1.121 + glEnd(); 1.122 + glUseProgram(0); 1.123 + 1.124 + glActiveTextureARB(GL_TEXTURE0); 1.125 + 1.126 + CHECKGLERR; 1.127 +} 1.128 + 1.129 +static const char *fbstname[] = { 1.130 + "GL_FRAMEBUFFER_COMPLETE", 1.131 + "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", 1.132 + "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", 1.133 + "no such fbo error", 1.134 + "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", 1.135 + "GL_FRAMEBUFFER_INCOMPLETE_FORMATS", 1.136 + "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", 1.137 + "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", 1.138 + "GL_FRAMEBUFFER_UNSUPPORTED" 1.139 +}; 1.140 + 1.141 +bool Renderer::create_rtarg() 1.142 +{ 1.143 + unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP; 1.144 + 1.145 + tex_xsz = round_pow2(width); 1.146 + tex_ysz = round_pow2(height); 1.147 + 1.148 + if(!glGenFramebuffersEXT) { 1.149 + fprintf(stderr, "FBO support missing!\n"); 1.150 + return false; 1.151 + } 1.152 + glGenFramebuffersEXT(1, &fbo); 1.153 + glBindFramebufferEXT(GL_FRAMEBUFFER, fbo); 1.154 + 1.155 + // create the render target 1.156 + glGenTextures(1, &rend_tex); 1.157 + glBindTexture(GL_TEXTURE_2D, rend_tex); 1.158 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp); 1.159 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp); 1.160 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 1.161 + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 1.162 + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); 1.163 + 1.164 + glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rend_tex, 0); 1.165 + 1.166 + // create depth buffer 1.167 + glGenRenderbuffersEXT(1, &rend_depth); 1.168 + glBindRenderbufferEXT(GL_RENDERBUFFER, rend_depth); 1.169 + glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz); 1.170 + 1.171 + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rend_depth); 1.172 + 1.173 + int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER); 1.174 + if(fbst != GL_FRAMEBUFFER_COMPLETE) { 1.175 + fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]); 1.176 + return false; 1.177 + } 1.178 + CHECKGLERR; 1.179 + 1.180 + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); 1.181 + return true; 1.182 } 1.183 1.184 1.185 @@ -75,8 +213,9 @@ 1.186 1.187 bool FwdRenderer::init(int xsz, int ysz) 1.188 { 1.189 - width = xsz; 1.190 - height = ysz; 1.191 + if(!Renderer::init(xsz, ysz)) { 1.192 + return false; 1.193 + } 1.194 1.195 if(glUseProgram && (sdrprog = load_sdr("fallback.v.glsl", "fallback.p.glsl"))) { 1.196 tang_attr = get_attrib_loc(sdrprog, "attr_tangent"); 1.197 @@ -128,3 +267,15 @@ 1.198 } 1.199 return prog; 1.200 } 1.201 + 1.202 +static int round_pow2(int x) 1.203 +{ 1.204 + x--; 1.205 + x = (x >> 1) | x; 1.206 + x = (x >> 2) | x; 1.207 + x = (x >> 4) | x; 1.208 + x = (x >> 8) | x; 1.209 + x = (x >> 16) | x; 1.210 + return x + 1; 1.211 +} 1.212 +