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 +