dungeon_crawler

diff prototype/src/renderer.cc @ 41:acfe0c0110fc

- cleaned up the renderer - implemented fallback (non-deferred renderer)
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 30 Aug 2012 05:35:00 +0300
parents 84a56fb24850
children c45c42c3d32e
line diff
     1.1 --- a/prototype/src/renderer.cc	Thu Aug 30 03:05:04 2012 +0300
     1.2 +++ b/prototype/src/renderer.cc	Thu Aug 30 05:35:00 2012 +0300
     1.3 @@ -1,247 +1,97 @@
     1.4 -#include <stdio.h>
     1.5 -#include <stdlib.h>
     1.6 -#include <string.h>
     1.7 -#include <limits.h>
     1.8 -#include <assert.h>
     1.9  #include "opengl.h"
    1.10  #include "renderer.h"
    1.11  #include "level.h"
    1.12  #include "sdr.h"
    1.13  #include "datapath.h"
    1.14  
    1.15 -#undef DBG_VIS_MRT
    1.16 +static unsigned int load_sdr(const char *vfname, const char *pfname);
    1.17  
    1.18 -#ifdef DBG_VIS_MRT
    1.19 -static void draw_deferred_debug();
    1.20 -#endif
    1.21 +Renderer *rend;
    1.22  
    1.23 -static bool create_fbo(int xsz, int ysz);
    1.24 -static unsigned int load_sdr(const char *vfname, const char *pfname);
    1.25 -static int round_pow2(int x);
    1.26  
    1.27 +Renderer::Renderer()
    1.28 +{
    1.29 +	width = height = 0;
    1.30 +}
    1.31  
    1.32 -#define MRT_COUNT	3
    1.33 -static unsigned int mrt_tex[MRT_COUNT];
    1.34 +Renderer::~Renderer()
    1.35 +{
    1.36 +}
    1.37  
    1.38 -static unsigned int mrt_prog;
    1.39 -static unsigned int deferred_omni, deferred_debug;
    1.40 +bool Renderer::init(int xsz, int ysz)
    1.41 +{
    1.42 +	width = xsz;
    1.43 +	height = ysz;
    1.44  
    1.45 -static unsigned int fbo, rbuf_depth;
    1.46 -static const char *fbstname[] = {
    1.47 -	"GL_FRAMEBUFFER_COMPLETE",
    1.48 -	"GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
    1.49 -	"GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
    1.50 -	"no such fbo error",
    1.51 -	"GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
    1.52 -	"GL_FRAMEBUFFER_INCOMPLETE_FORMATS",
    1.53 -	"GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER",
    1.54 -	"GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER",
    1.55 -	"GL_FRAMEBUFFER_UNSUPPORTED"
    1.56 -};
    1.57 +	rend = this;
    1.58 +	return true;
    1.59 +}
    1.60  
    1.61 -static int fb_xsz, fb_ysz, tex_xsz, tex_ysz;
    1.62 +int Renderer::get_tangent_location() const
    1.63 +{
    1.64 +	return -1;
    1.65 +}
    1.66  
    1.67 +unsigned int Renderer::get_current_program() const
    1.68 +{
    1.69 +	return 0;
    1.70 +}
    1.71  
    1.72 +void Renderer::resize(int xsz, int ysz)
    1.73 +{
    1.74 +	width = xsz;
    1.75 +	height = ysz;
    1.76 +}
    1.77  
    1.78 -bool init_renderer(int xsz, int ysz)
    1.79 +
    1.80 +// ---- fallback forward renderer ----
    1.81 +FwdRenderer::FwdRenderer()
    1.82  {
    1.83 -	if(!GLEW_ARB_texture_float) {
    1.84 -		fprintf(stderr, "Error: OpenGL implementation doesn't support floating point textures\n");
    1.85 -		return false;
    1.86 +	sdrprog = 0;
    1.87 +	tang_attr = -1;
    1.88 +}
    1.89 +
    1.90 +FwdRenderer::~FwdRenderer()
    1.91 +{
    1.92 +	if(sdrprog) {
    1.93 +		free_program(sdrprog);
    1.94  	}
    1.95 -	if(!GLEW_ARB_draw_buffers) {
    1.96 -		fprintf(stderr, "Error: OpenGL implementation doesn't support multiple render targets\n");
    1.97 -		return false;
    1.98 -	}
    1.99 +}
   1.100  
   1.101 -	int max_draw_buf;
   1.102 -	glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buf);
   1.103 -	printf("max draw buffers: %d\n", max_draw_buf);
   1.104 -	if(max_draw_buf < MRT_COUNT) {
   1.105 -		fprintf(stderr, "OpenGL implementation doesn't support enough draw buffers\n");
   1.106 -		return false;
   1.107 -	}
   1.108 +bool FwdRenderer::init(int xsz, int ysz)
   1.109 +{
   1.110 +	width = xsz;
   1.111 +	height = ysz;
   1.112  
   1.113 -	if(!create_fbo(xsz, ysz)) {
   1.114 -		return false;
   1.115 -	}
   1.116 -	CHECKGLERR;
   1.117 -
   1.118 -	if(!(mrt_prog = load_sdr("mrt.v.glsl", "mrt.p.glsl"))) {
   1.119 -		return false;
   1.120 -	}
   1.121 -	set_uniform_int(mrt_prog, "tex_dif", 0);
   1.122 -	set_uniform_int(mrt_prog, "tex_norm", 1);
   1.123 -
   1.124 -	if(!(deferred_debug = load_sdr("deferred.v.glsl", "deferred.p.glsl"))) {
   1.125 -		return false;
   1.126 -	}
   1.127 -	for(int i=0; i<MRT_COUNT; i++) {
   1.128 -		char uname[32];
   1.129 -		sprintf(uname, "mrt%d", i);
   1.130 -		set_uniform_int(deferred_debug, uname, i);
   1.131 -	}
   1.132 -
   1.133 -	if(!(deferred_omni = load_sdr("deferred_omni.v.glsl", "deferred_omni.p.glsl"))) {
   1.134 -		return false;
   1.135 -	}
   1.136 -	for(int i=0; i<MRT_COUNT; i++) {
   1.137 -		char uname[32];
   1.138 -		sprintf(uname, "mrt%d", i);
   1.139 -		set_uniform_int(deferred_omni, uname, i);
   1.140 +	if(glUseProgram && (sdrprog = load_sdr("fallback.v.glsl", "fallback.p.glsl"))) {
   1.141 +		tang_attr = get_attrib_loc(sdrprog, "attr_tangent");
   1.142 +		set_uniform_int(sdrprog, "tex_dif", 0);
   1.143 +		set_uniform_int(sdrprog, "tex_norm", 1);
   1.144  	}
   1.145  	return true;
   1.146  }
   1.147  
   1.148 -void destroy_renderer()
   1.149 +int FwdRenderer::get_tangent_location() const
   1.150  {
   1.151 -	free_program(mrt_prog);
   1.152 -	free_program(deferred_omni);
   1.153 -
   1.154 -	glDeleteTextures(MRT_COUNT, mrt_tex);
   1.155 -	glDeleteFramebuffersEXT(1, &fbo);
   1.156 +	return tang_attr;
   1.157  }
   1.158  
   1.159 -unsigned int get_deferred_shader(void)
   1.160 +unsigned int FwdRenderer::get_current_program() const
   1.161  {
   1.162 -	return deferred_omni;
   1.163 +	return sdrprog;
   1.164  }
   1.165  
   1.166 -int get_tangent_location(void)
   1.167 +void FwdRenderer::render(const Level *level) const
   1.168  {
   1.169 -	return get_attrib_loc(mrt_prog, "attr_tangent");
   1.170 -}
   1.171 +	glPushAttrib(GL_ENABLE_BIT);
   1.172 +	glUseProgram(sdrprog);
   1.173  
   1.174 -void resize_renderer(int xsz, int ysz)
   1.175 -{
   1.176 -	fb_xsz = xsz;
   1.177 -	fb_ysz = ysz;
   1.178 -
   1.179 -	// if we need a bigger rendertarget resize all colorbuffer textures and the depth buffer
   1.180 -	if(xsz > tex_xsz || ysz > tex_ysz) {
   1.181 -		tex_xsz = round_pow2(xsz);
   1.182 -		tex_ysz = round_pow2(ysz);
   1.183 -
   1.184 -		for(int i=0; i<MRT_COUNT; i++) {
   1.185 -			glBindTexture(GL_TEXTURE_2D, mrt_tex[i]);
   1.186 -			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0);
   1.187 -		}
   1.188 -
   1.189 -		glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth);
   1.190 -		glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
   1.191 -	}
   1.192 -
   1.193 -
   1.194 -	// update the texture coordinate scaling factors
   1.195 -	float tex_scale_x = (float)fb_xsz / tex_xsz;
   1.196 -	float tex_scale_y = (float)fb_ysz / tex_ysz;
   1.197 -
   1.198 -	set_uniform_float2(deferred_omni, "tex_scale", tex_scale_x, tex_scale_y);
   1.199 -	set_uniform_float2(deferred_omni, "fb_size", fb_xsz, fb_ysz);
   1.200 -
   1.201 -	set_uniform_float2(deferred_debug, "tex_scale", tex_scale_x, tex_scale_y);
   1.202 -}
   1.203 -
   1.204 -void render_deferred(const Level *level)
   1.205 -{
   1.206 -	// render into the MRT buffers
   1.207 -	glUseProgram(mrt_prog);
   1.208 -	glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
   1.209 -
   1.210 -	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   1.211 +	glEnable(GL_LIGHTING);
   1.212  	level->draw();
   1.213  
   1.214 -	glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
   1.215 -
   1.216 -#ifdef DBG_VIS_MRT
   1.217 -	draw_deferred_debug();
   1.218 -#else
   1.219 -
   1.220 -	// post-process lighting
   1.221 -	glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
   1.222 -
   1.223 -	glEnable(GL_BLEND);
   1.224 -	glBlendFunc(GL_ONE, GL_ONE);
   1.225 -
   1.226 -	glDisable(GL_LIGHTING);
   1.227 -	glDisable(GL_DEPTH_TEST);
   1.228 -	glCullFace(GL_FRONT);
   1.229 -
   1.230 -	glUseProgram(deferred_omni);
   1.231 -	for(int i=0; i<MRT_COUNT; i++) {
   1.232 -		glActiveTexture(GL_TEXTURE0 + i);
   1.233 -		glBindTexture(GL_TEXTURE_2D, mrt_tex[i]);
   1.234 -		glEnable(GL_TEXTURE_2D);
   1.235 -	}
   1.236 -
   1.237 -	glDepthMask(0);
   1.238 -	level->draw_lights();
   1.239 -	glDepthMask(1);
   1.240 -
   1.241 -	for(int i=0; i<MRT_COUNT; i++) {
   1.242 -		glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1);
   1.243 -		glDisable(GL_TEXTURE_2D);
   1.244 -	}
   1.245 +	glPopAttrib();
   1.246  
   1.247  	glUseProgram(0);
   1.248 -	glPopAttrib();
   1.249 -#endif	// DBG_VIS_MRT
   1.250 -}
   1.251 -
   1.252 -static bool create_fbo(int xsz, int ysz)
   1.253 -{
   1.254 -	unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP;
   1.255 -
   1.256 -	// round the texture size up to the next power of 2
   1.257 -	tex_xsz = round_pow2(xsz);
   1.258 -	tex_ysz = round_pow2(ysz);
   1.259 -	fb_xsz = xsz;
   1.260 -	fb_ysz = ysz;
   1.261 -
   1.262 -	if(!glGenFramebuffersEXT) {
   1.263 -		fprintf(stderr, "FBO support missing\n");
   1.264 -		return false;
   1.265 -	}
   1.266 -	glGenFramebuffersEXT(1, &fbo);
   1.267 -	glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
   1.268 -
   1.269 -	glGenTextures(MRT_COUNT, mrt_tex);
   1.270 -	for(int i=0; i<MRT_COUNT; i++) {
   1.271 -		glBindTexture(GL_TEXTURE_2D, mrt_tex[i]);
   1.272 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
   1.273 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
   1.274 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   1.275 -		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
   1.276 -		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0);
   1.277 -
   1.278 -		// attach to fbo
   1.279 -		glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
   1.280 -				GL_TEXTURE_2D, mrt_tex[i], 0);
   1.281 -		CHECKGLERR;
   1.282 -	}
   1.283 -
   1.284 -	static GLenum draw_bufs[] = {
   1.285 -		GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT,
   1.286 -		GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT,
   1.287 -		GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT,
   1.288 -		GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT
   1.289 -	};
   1.290 -	glDrawBuffersARB(MRT_COUNT, draw_bufs);
   1.291 -
   1.292 -	glGenRenderbuffersEXT(1, &rbuf_depth);
   1.293 -	glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth);
   1.294 -	glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
   1.295 -	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth);
   1.296 -
   1.297 -	int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
   1.298 -	if(fbst != GL_FRAMEBUFFER_COMPLETE) {
   1.299 -		fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]);
   1.300 -		return false;
   1.301 -	}
   1.302 -	CHECKGLERR;
   1.303 -
   1.304 -	glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
   1.305 -	return true;
   1.306  }
   1.307  
   1.308  static unsigned int load_sdr(const char *vfname, const char *pfname)
   1.309 @@ -266,61 +116,3 @@
   1.310  	}
   1.311  	return prog;
   1.312  }
   1.313 -
   1.314 -static int round_pow2(int x)
   1.315 -{
   1.316 -	x--;
   1.317 -	x = (x >> 1) | x;
   1.318 -	x = (x >> 2) | x;
   1.319 -	x = (x >> 4) | x;
   1.320 -	x = (x >> 8) | x;
   1.321 -	x = (x >> 16) | x;
   1.322 -	return x + 1;
   1.323 -}
   1.324 -
   1.325 -#ifdef DBG_VIS_MRT
   1.326 -// visualize the MRT buffers
   1.327 -static void draw_deferred_debug()
   1.328 -{
   1.329 -	glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
   1.330 -	glUseProgram(deferred_debug);
   1.331 -	glDisable(GL_DEPTH_TEST);
   1.332 -
   1.333 -	glMatrixMode(GL_PROJECTION);
   1.334 -	glPushMatrix();
   1.335 -	glLoadIdentity();
   1.336 -	glMatrixMode(GL_MODELVIEW);
   1.337 -	glPushMatrix();
   1.338 -	glLoadIdentity();
   1.339 -
   1.340 -	for(int i=0; i<MRT_COUNT; i++) {
   1.341 -		glActiveTexture(GL_TEXTURE0 + i);
   1.342 -		glBindTexture(GL_TEXTURE_2D, mrt_tex[i]);
   1.343 -		glEnable(GL_TEXTURE_2D);
   1.344 -	}
   1.345 -
   1.346 -	glBegin(GL_QUADS);
   1.347 -	glTexCoord2f(0, 0);
   1.348 -	glVertex2f(-1, -1);
   1.349 -	glTexCoord2f(1, 0);
   1.350 -	glVertex2f(1, -1);
   1.351 -	glTexCoord2f(1, 1);
   1.352 -	glVertex2f(1, 1);
   1.353 -	glTexCoord2f(0, 1);
   1.354 -	glVertex2f(-1, 1);
   1.355 -	glEnd();
   1.356 -
   1.357 -	for(int i=0; i<MRT_COUNT; i++) {
   1.358 -		glActiveTexture(GL_TEXTURE0 + MRT_COUNT - i - 1);
   1.359 -		glDisable(GL_TEXTURE_2D);
   1.360 -	}
   1.361 -
   1.362 -	glMatrixMode(GL_PROJECTION);
   1.363 -	glPopMatrix();
   1.364 -	glMatrixMode(GL_MODELVIEW);
   1.365 -	glPopMatrix();
   1.366 -
   1.367 -	glUseProgram(0);
   1.368 -	glPopAttrib();
   1.369 -}
   1.370 -#endif