dungeon_crawler

diff prototype/src/renderer.cc @ 17:d98240a13793

lalala
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 20 Aug 2012 06:11:58 +0300
parents 91180ee7b7d9
children 5c41e6fcb300
line diff
     1.1 --- a/prototype/src/renderer.cc	Mon Aug 20 03:40:51 2012 +0300
     1.2 +++ b/prototype/src/renderer.cc	Mon Aug 20 06:11:58 2012 +0300
     1.3 @@ -7,40 +7,119 @@
     1.4  #include "sdr.h"
     1.5  #include "datapath.h"
     1.6  
     1.7 -#define MRT_COUNT	(sizeof mrt_sdr_file / sizeof *mrt_sdr_file)
     1.8 +static bool create_fbo(int xsz, int ysz);
     1.9 +static bool load_shaders();
    1.10 +static int round_pow2(int x);
    1.11  
    1.12 -static const char *mrt_sdr_file[][2] = {
    1.13 -	{0, "mrt0.p.glsl"}/*,
    1.14 -	{0, "mrt1.p.glsl"},
    1.15 -	{0, "mrt2.p.glsl"},
    1.16 -	{0, "mrt3.p.glsl"}*/
    1.17 +
    1.18 +#define MRT_COUNT	4
    1.19 +static unsigned int mrt_tex[MRT_COUNT];
    1.20 +
    1.21 +static unsigned int mrt_prog;
    1.22 +static unsigned int deferred_omni;
    1.23 +
    1.24 +static unsigned int fbo, rbuf_depth;
    1.25 +static const char *fbstname[] = {
    1.26 +	"GL_FRAMEBUFFER_COMPLETE",
    1.27 +	"GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
    1.28 +	"GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
    1.29 +	"no such fbo error",
    1.30 +	"GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
    1.31 +	"GL_FRAMEBUFFER_INCOMPLETE_FORMATS",
    1.32 +	"GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER",
    1.33 +	"GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER",
    1.34 +	"GL_FRAMEBUFFER_UNSUPPORTED"
    1.35  };
    1.36  
    1.37 -static unsigned int mrt_prog[MRT_COUNT];
    1.38 -static unsigned int deferred_prog;
    1.39 +static int fb_xsz, fb_ysz, tex_xsz, tex_ysz;
    1.40  
    1.41 -bool init_renderer()
    1.42 +bool init_renderer(int xsz, int ysz)
    1.43 +{
    1.44 +	if(!create_fbo(xsz, ysz)) {
    1.45 +		return false;
    1.46 +	}
    1.47 +	if(!load_shaders()) {
    1.48 +		return false;
    1.49 +	}
    1.50 +	return true;
    1.51 +}
    1.52 +
    1.53 +void destroy_renderer()
    1.54 +{
    1.55 +	free_program(mrt_prog);
    1.56 +	free_program(deferred_omni);
    1.57 +
    1.58 +	glDeleteTextures(MRT_COUNT, mrt_tex);
    1.59 +	glDeleteFramebuffersEXT(1, &fbo);
    1.60 +}
    1.61 +
    1.62 +void render_deferred(void (*draw_func)())
    1.63 +{
    1.64 +	bind_program(mrt_prog);
    1.65 +	draw_func();
    1.66 +	bind_program(0);
    1.67 +}
    1.68 +
    1.69 +static bool create_fbo(int xsz, int ysz)
    1.70 +{
    1.71 +	unsigned int clamp = GL_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP;
    1.72 +
    1.73 +	tex_xsz = round_pow2(xsz);
    1.74 +	tex_ysz = round_pow2(ysz);
    1.75 +	fb_xsz = xsz;
    1.76 +	fb_ysz = ysz;
    1.77 +
    1.78 +	if(!glGenFramebuffersEXT) {
    1.79 +		fprintf(stderr, "FBO support missing\n");
    1.80 +		return false;
    1.81 +	}
    1.82 +	glGenFramebuffersEXT(1, &fbo);
    1.83 +
    1.84 +	glGenRenderbuffersEXT(1, &rbuf_depth);
    1.85 +	glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth);
    1.86 +	glRenderbufferStorageEXT(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, tex_xsz, tex_ysz);
    1.87 +	glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbuf_depth);
    1.88 +
    1.89 +	glGenTextures(MRT_COUNT, mrt_tex);
    1.90 +	for(int i=0; i<MRT_COUNT; i++) {
    1.91 +		glBindTexture(GL_TEXTURE_2D, mrt_tex[i]);
    1.92 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clamp);
    1.93 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clamp);
    1.94 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    1.95 +		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    1.96 +		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_xsz, tex_ysz, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    1.97 +
    1.98 +		// attach to fbo
    1.99 +		glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D,
   1.100 +				mrt_tex[i], 0);
   1.101 +	}
   1.102 +
   1.103 +	int fbst = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER);
   1.104 +	if(fbst != GL_FRAMEBUFFER_COMPLETE) {
   1.105 +		fprintf(stderr, "incomplete fbo: %u (%s)\n", fbo, fbstname[fbst - GL_FRAMEBUFFER_COMPLETE]);
   1.106 +		return false;
   1.107 +	}
   1.108 +	return true;
   1.109 +}
   1.110 +
   1.111 +static bool load_shaders()
   1.112  {
   1.113  	char vsfile[PATH_MAX], psfile[PATH_MAX];
   1.114  	const char *fname;
   1.115  
   1.116 -	for(int i=0; i<MRT_COUNT; i++) {
   1.117 -		if((fname = datafile_path(mrt_sdr_file[i][0]))) {
   1.118 -			strcpy(vsfile, mrt_sdr_file[i][0]);
   1.119 -		} else {
   1.120 -			vsfile[0] = 0;
   1.121 -		}
   1.122 -
   1.123 -		if((fname = datafile_path(mrt_sdr_file[i][1]))) {
   1.124 -			strcpy(psfile, mrt_sdr_file[i][1]);
   1.125 -		} else {
   1.126 -			psfile[0] = 0;
   1.127 -		}
   1.128 -
   1.129 -		if(!(mrt_prog[i] = create_program_load(vsfile, psfile))) {
   1.130 -			fprintf(stderr, "failed to load MRT program\n");
   1.131 -			return false;
   1.132 -		}
   1.133 +	if((fname = datafile_path("mrt.v.glsl"))) {
   1.134 +		strcpy(vsfile, fname);
   1.135 +	} else {
   1.136 +		vsfile[0] = 0;
   1.137 +	}
   1.138 +	if((fname = datafile_path("mrt.p.glsl"))) {
   1.139 +		strcpy(psfile, fname);
   1.140 +	} else {
   1.141 +		psfile[0] = 0;
   1.142 +	}
   1.143 +	if(!(mrt_prog = create_program_load(vsfile, psfile))) {
   1.144 +		fprintf(stderr, "failed to load MRT program\n");
   1.145 +		return false;
   1.146  	}
   1.147  
   1.148  	if((fname = datafile_path("deferred.v.glsl"))) {
   1.149 @@ -54,24 +133,20 @@
   1.150  		psfile[0] = 0;
   1.151  	}
   1.152  
   1.153 -	if(!(deferred_prog = create_program_load(vsfile, psfile))) {
   1.154 +	if(!(deferred_omni = create_program_load(vsfile, psfile))) {
   1.155  		fprintf(stderr, "failed to load deferred shader program\n");
   1.156  		return false;
   1.157  	}
   1.158  	return true;
   1.159  }
   1.160  
   1.161 -void destroy_renderer()
   1.162 +static int round_pow2(int x)
   1.163  {
   1.164 -	for(int i=0; i<MRT_COUNT; i++) {
   1.165 -		free_program(mrt_prog[i]);
   1.166 -	}
   1.167 -	free_program(deferred_prog);
   1.168 +	x--;
   1.169 +	x = (x >> 1) | x;
   1.170 +	x = (x >> 2) | x;
   1.171 +	x = (x >> 4) | x;
   1.172 +	x = (x >> 8) | x;
   1.173 +	x = (x >> 16) | x;
   1.174 +	return x + 1;
   1.175  }
   1.176 -
   1.177 -void render_deferred(void (*draw_func)())
   1.178 -{
   1.179 -
   1.180 -
   1.181 -	draw_func();
   1.182 -}