dungeon_crawler

annotate prototype/src/renderer.cc @ 73:67d330038629

ok fixed the dissapearing particle system. Had forgotten to disable TEXTURE_3D after color grading pass
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 21 Oct 2012 02:11:23 +0300
parents a27528035e20
children 5981917093ff
rev   line source
nuclear@44 1 #include <limits.h>
nuclear@15 2 #include "opengl.h"
nuclear@15 3 #include "renderer.h"
nuclear@23 4 #include "level.h"
nuclear@15 5 #include "sdr.h"
nuclear@15 6 #include "datapath.h"
nuclear@15 7
nuclear@41 8 static unsigned int load_sdr(const char *vfname, const char *pfname);
nuclear@72 9 static int round_pow2(int x);
nuclear@35 10
nuclear@41 11 Renderer *rend;
nuclear@18 12
nuclear@15 13
nuclear@41 14 Renderer::Renderer()
nuclear@41 15 {
nuclear@72 16 fbo = 0;
nuclear@72 17 rend_tex = rend_depth = 0;
nuclear@41 18 width = height = 0;
nuclear@72 19 tex_xsz = tex_ysz = 0;
nuclear@72 20 post_sdr = 0;
nuclear@41 21 }
nuclear@17 22
nuclear@41 23 Renderer::~Renderer()
nuclear@41 24 {
nuclear@72 25 if(post_sdr) {
nuclear@72 26 free_program(post_sdr);
nuclear@72 27 }
nuclear@72 28 if(rend_tex) {
nuclear@72 29 glDeleteTextures(1, &rend_tex);
nuclear@72 30 }
nuclear@72 31 if(rend_depth) {
nuclear@72 32 glDeleteRenderbuffersEXT(1, &rend_depth);
nuclear@72 33 }
nuclear@72 34 if(fbo) {
nuclear@72 35 glDeleteFramebuffersEXT(1, &fbo);
nuclear@72 36 }
nuclear@41 37 }
nuclear@17 38
nuclear@41 39 bool Renderer::init(int xsz, int ysz)
nuclear@41 40 {
nuclear@41 41 width = xsz;
nuclear@41 42 height = ysz;
nuclear@17 43
nuclear@72 44 if(!create_rtarg()) {
nuclear@72 45 return false;
nuclear@72 46 }
nuclear@72 47
nuclear@72 48 if(!(post_sdr = load_sdr("post.v.glsl", "post.p.glsl"))) {
nuclear@72 49 return false;
nuclear@72 50 }
nuclear@72 51
nuclear@72 52 if(!gradepal.create()) {
nuclear@72 53 return false;
nuclear@72 54 }
nuclear@72 55
nuclear@41 56 rend = this;
nuclear@41 57 return true;
nuclear@41 58 }
nuclear@15 59
nuclear@41 60 int Renderer::get_tangent_location() const
nuclear@41 61 {
nuclear@41 62 return -1;
nuclear@41 63 }
nuclear@15 64
nuclear@41 65 unsigned int Renderer::get_current_program() const
nuclear@41 66 {
nuclear@41 67 return 0;
nuclear@41 68 }
nuclear@21 69
nuclear@41 70 void Renderer::resize(int xsz, int ysz)
nuclear@41 71 {
nuclear@41 72 width = xsz;
nuclear@41 73 height = ysz;
nuclear@72 74
nuclear@72 75 // if we need a bigger rendertarget ...
nuclear@72 76 if(xsz > tex_xsz || ysz > tex_ysz) {
nuclear@72 77 tex_xsz = round_pow2(xsz);
nuclear@72 78 tex_ysz = round_pow2(ysz);
nuclear@72 79
nuclear@72 80 // ... resize the render target
nuclear@72 81 glBindTexture(GL_TEXTURE_2D, rend_tex);
nuclear@72 82 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
nuclear@72 83
nuclear@72 84 // ... resize the depth buffer
nuclear@72 85 glBindRenderbufferEXT(GL_RENDERBUFFER, rend_depth);
nuclear@72 86 glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
nuclear@72 87 }
nuclear@41 88 }
nuclear@21 89
nuclear@62 90 void Renderer::render_pre(const Level *level) const
nuclear@62 91 {
nuclear@62 92 glEnable(GL_FOG);
nuclear@62 93 glFogi(GL_FOG_MODE, GL_LINEAR);
nuclear@62 94 glFogf(GL_FOG_START, 3.0f);
nuclear@62 95 glFogf(GL_FOG_END, 6.0f);
nuclear@62 96 // TODO level->draw_pre();
nuclear@72 97
nuclear@72 98 // bind the render target
nuclear@72 99 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
nuclear@72 100 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rend_tex, 0);
nuclear@72 101 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@72 102
nuclear@72 103 CHECKGLERR;
nuclear@62 104 }
nuclear@62 105
nuclear@62 106 void Renderer::render_post(const Level *level) const
nuclear@62 107 {
nuclear@62 108 level->draw_post();
nuclear@72 109 CHECKGLERR;
nuclear@72 110
nuclear@72 111 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
nuclear@72 112
nuclear@72 113 // draw the rendered output
nuclear@72 114 glActiveTextureARB(GL_TEXTURE0);
nuclear@72 115 glBindTexture(GL_TEXTURE_2D, rend_tex);
nuclear@72 116 glEnable(GL_TEXTURE_2D);
nuclear@72 117
nuclear@72 118 // use the color-grading palette
nuclear@72 119 glActiveTextureARB(GL_TEXTURE1);
nuclear@72 120 glBindTexture(GL_TEXTURE_3D, gradepal.get_texture());
nuclear@72 121 glEnable(GL_TEXTURE_3D);
nuclear@72 122
nuclear@72 123 glUseProgram(post_sdr);
nuclear@72 124 set_uniform_int(post_sdr, "fbtex", 0);
nuclear@72 125 set_uniform_int(post_sdr, "paltex", 1);
nuclear@72 126
nuclear@72 127 glBegin(GL_QUADS);
nuclear@72 128 glTexCoord2f(0, 0);
nuclear@72 129 glVertex2f(-1, -1);
nuclear@72 130 glTexCoord2f((float)width / tex_xsz, 0);
nuclear@72 131 glVertex2f(1, -1);
nuclear@72 132 glTexCoord2f((float)width / tex_xsz, (float)height / tex_ysz);
nuclear@72 133 glVertex2f(1, 1);
nuclear@72 134 glTexCoord2f(0, (float)height / tex_ysz);
nuclear@72 135 glVertex2f(-1, 1);
nuclear@72 136 glEnd();
nuclear@72 137 glUseProgram(0);
nuclear@72 138
nuclear@73 139 glActiveTextureARB(GL_TEXTURE1);
nuclear@73 140 glDisable(GL_TEXTURE_3D);
nuclear@72 141 glActiveTextureARB(GL_TEXTURE0);
nuclear@73 142 glDisable(GL_TEXTURE_2D);
nuclear@72 143
nuclear@72 144 CHECKGLERR;
nuclear@72 145 }
nuclear@72 146
nuclear@72 147 static const char *fbstname[] = {
nuclear@72 148 "GL_FRAMEBUFFER_COMPLETE",
nuclear@72 149 "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
nuclear@72 150 "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
nuclear@72 151 "no such fbo error",
nuclear@72 152 "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
nuclear@72 153 "GL_FRAMEBUFFER_INCOMPLETE_FORMATS",
nuclear@72 154 "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER",
nuclear@72 155 "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER",
nuclear@72 156 "GL_FRAMEBUFFER_UNSUPPORTED"
nuclear@72 157 };
nuclear@72 158
nuclear@72 159 bool Renderer::create_rtarg()
nuclear@72 160 {
nuclear@72 161 unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP;
nuclear@72 162
nuclear@72 163 tex_xsz = round_pow2(width);
nuclear@72 164 tex_ysz = round_pow2(height);
nuclear@72 165
nuclear@72 166 if(!glGenFramebuffersEXT) {
nuclear@72 167 fprintf(stderr, "FBO support missing!\n");
nuclear@72 168 return false;
nuclear@72 169 }
nuclear@72 170 glGenFramebuffersEXT(1, &fbo);
nuclear@72 171 glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
nuclear@72 172
nuclear@72 173 // create the render target
nuclear@72 174 glGenTextures(1, &rend_tex);
nuclear@72 175 glBindTexture(GL_TEXTURE_2D, rend_tex);
nuclear@72 176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
nuclear@72 177 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
nuclear@72 178 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@72 179 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@72 180 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
nuclear@72 181
nuclear@72 182 glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rend_tex, 0);
nuclear@72 183
nuclear@72 184 // create depth buffer
nuclear@72 185 glGenRenderbuffersEXT(1, &rend_depth);
nuclear@72 186 glBindRenderbufferEXT(GL_RENDERBUFFER, rend_depth);
nuclear@72 187 glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
nuclear@72 188
nuclear@72 189 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rend_depth);
nuclear@72 190
nuclear@72 191 int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
nuclear@72 192 if(fbst != GL_FRAMEBUFFER_COMPLETE) {
nuclear@72 193 fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]);
nuclear@72 194 return false;
nuclear@72 195 }
nuclear@72 196 CHECKGLERR;
nuclear@72 197
nuclear@72 198 glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
nuclear@72 199 return true;
nuclear@62 200 }
nuclear@62 201
nuclear@41 202
nuclear@41 203 // ---- fallback forward renderer ----
nuclear@41 204 FwdRenderer::FwdRenderer()
nuclear@17 205 {
nuclear@41 206 sdrprog = 0;
nuclear@41 207 tang_attr = -1;
nuclear@41 208 }
nuclear@41 209
nuclear@41 210 FwdRenderer::~FwdRenderer()
nuclear@41 211 {
nuclear@41 212 if(sdrprog) {
nuclear@41 213 free_program(sdrprog);
nuclear@32 214 }
nuclear@41 215 }
nuclear@21 216
nuclear@41 217 bool FwdRenderer::init(int xsz, int ysz)
nuclear@41 218 {
nuclear@72 219 if(!Renderer::init(xsz, ysz)) {
nuclear@72 220 return false;
nuclear@72 221 }
nuclear@19 222
nuclear@41 223 if(glUseProgram && (sdrprog = load_sdr("fallback.v.glsl", "fallback.p.glsl"))) {
nuclear@41 224 tang_attr = get_attrib_loc(sdrprog, "attr_tangent");
nuclear@41 225 set_uniform_int(sdrprog, "tex_dif", 0);
nuclear@41 226 set_uniform_int(sdrprog, "tex_norm", 1);
nuclear@23 227 }
nuclear@17 228 return true;
nuclear@17 229 }
nuclear@17 230
nuclear@41 231 int FwdRenderer::get_tangent_location() const
nuclear@17 232 {
nuclear@41 233 return tang_attr;
nuclear@17 234 }
nuclear@17 235
nuclear@41 236 unsigned int FwdRenderer::get_current_program() const
nuclear@33 237 {
nuclear@41 238 return sdrprog;
nuclear@33 239 }
nuclear@33 240
nuclear@41 241 void FwdRenderer::render(const Level *level) const
nuclear@35 242 {
nuclear@41 243 glPushAttrib(GL_ENABLE_BIT);
nuclear@51 244 glEnable(GL_LIGHTING);
nuclear@62 245
nuclear@62 246 render_pre(level);
nuclear@51 247
nuclear@41 248 glUseProgram(sdrprog);
nuclear@62 249 level->draw();
nuclear@62 250 glUseProgram(0);
nuclear@35 251
nuclear@62 252 render_post(level);
nuclear@46 253
nuclear@41 254 glPopAttrib();
nuclear@17 255 }
nuclear@17 256
nuclear@18 257 static unsigned int load_sdr(const char *vfname, const char *pfname)
nuclear@15 258 {
nuclear@18 259 unsigned int prog;
nuclear@15 260
nuclear@63 261 std::string vsfile = datafile_path(vfname);
nuclear@63 262 std::string psfile = datafile_path(pfname);
nuclear@63 263
nuclear@63 264 const char *vs = vsfile.empty() ? 0 : vsfile.c_str();
nuclear@63 265 const char *ps = psfile.empty() ? 0 : psfile.c_str();
nuclear@63 266
nuclear@63 267 if(!(prog = create_program_load(vs, ps))) {
nuclear@63 268 fprintf(stderr, "failed to load shader program (%s, %s)\n", vs, ps);
nuclear@18 269 return 0;
nuclear@15 270 }
nuclear@18 271 return prog;
nuclear@15 272 }
nuclear@72 273
nuclear@72 274 static int round_pow2(int x)
nuclear@72 275 {
nuclear@72 276 x--;
nuclear@72 277 x = (x >> 1) | x;
nuclear@72 278 x = (x >> 2) | x;
nuclear@72 279 x = (x >> 4) | x;
nuclear@72 280 x = (x >> 8) | x;
nuclear@72 281 x = (x >> 16) | x;
nuclear@72 282 return x + 1;
nuclear@72 283 }
nuclear@72 284