dungeon_crawler

changeset 60:aa86119e3295

added multipass deferred
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 25 Sep 2012 06:19:37 +0300
parents b6bf86d4f1cf
children 4472ef41a209
files prototype/Makefile.in prototype/data/test.level prototype/sdr/mrt.p.glsl prototype/sdr/multi0.p.glsl prototype/sdr/multi1.p.glsl prototype/sdr/multi2.p.glsl prototype/src/cfg.cc prototype/src/cfg.h prototype/src/light.cc prototype/src/light.h prototype/src/main.cc prototype/src/renderer_deferred.cc prototype/src/renderer_deferred.h prototype/src/renderer_multipass.cc prototype/src/renderer_multipass.h prototype/src/tile.cc
diffstat 16 files changed, 325 insertions(+), 54 deletions(-) [+]
line diff
     1.1 --- a/prototype/Makefile.in	Fri Sep 21 05:28:45 2012 +0300
     1.2 +++ b/prototype/Makefile.in	Tue Sep 25 06:19:37 2012 +0300
     1.3 @@ -15,7 +15,7 @@
     1.4  
     1.5  inc = -I. -Isrc -Ivmath -Idrawtext -Ikdtree `pkg-config --cflags freetype2`
     1.6  
     1.7 -CFLAGS = -pedantic $(warn) $(dbg) $(prof) $(opt) $(inc)
     1.8 +CFLAGS = -pedantic -fno-strict-aliasing $(warn) $(dbg) $(prof) $(opt) $(inc)
     1.9  CXXFLAGS = $(CFLAGS) $(cxx11_cflags)
    1.10  LDFLAGS = $(cxx11_ldflags) $(prof) $(libgl) $(libal) -lvorbisfile -lm -lassimp -limago -lpsys `pkg-config --libs freetype2`
    1.11  
     2.1 --- a/prototype/data/test.level	Fri Sep 21 05:28:45 2012 +0300
     2.2 +++ b/prototype/data/test.level	Tue Sep 25 06:19:37 2012 +0300
     2.3 @@ -17,7 +17,6 @@
     2.4  ################################################################
     2.5  ################################################################
     2.6  ################################################################
     2.7 -############################### ################################
     2.8  ################################################################
     2.9  ################################################################
    2.10  ################################################################
    2.11 @@ -29,9 +28,9 @@
    2.12  ################################################################
    2.13  ################################################################
    2.14  ################################################################
    2.15 -################################ ###############################
    2.16 -################################ ############# #################
    2.17  ################################################################
    2.18 +################################*###############################
    2.19 +################################*###############################
    2.20  ################################################################
    2.21  ################################################################
    2.22  ################################################################
    2.23 @@ -63,3 +62,4 @@
    2.24  ################################################################
    2.25  ################################################################
    2.26  ################################################################
    2.27 +################################################################
     3.1 --- a/prototype/sdr/mrt.p.glsl	Fri Sep 21 05:28:45 2012 +0300
     3.2 +++ b/prototype/sdr/mrt.p.glsl	Tue Sep 25 06:19:37 2012 +0300
     3.3 @@ -1,8 +1,8 @@
     3.4  /* MRT assignments
     3.5   * 0 - RGB: position, A: shininess
     3.6   * 1 - RGB: normal
     3.7 - * 3 - RGB: diffuse color, A: shininess str.
     3.8 - * 4 - unused
     3.9 + * 2 - RGB: diffuse color, A: shininess str.
    3.10 + * 3 - unused
    3.11   */
    3.12  
    3.13  uniform sampler2D tex_dif, tex_norm;
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/prototype/sdr/multi0.p.glsl	Tue Sep 25 06:19:37 2012 +0300
     4.3 @@ -0,0 +1,8 @@
     4.4 +/* mutlipass renderer shader 0: RGB: position, A: shininess */
     4.5 +
     4.6 +varying vec3 pos, norm, tang;
     4.7 +
     4.8 +void main()
     4.9 +{
    4.10 +	gl_FragColor = vec4(pos, gl_FrontMaterial.shininess);
    4.11 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/prototype/sdr/multi1.p.glsl	Tue Sep 25 06:19:37 2012 +0300
     5.3 @@ -0,0 +1,23 @@
     5.4 +/* multipass renderer shader 1: RGB: normal */
     5.5 +
     5.6 +uniform sampler2D tex_norm;
     5.7 +
     5.8 +varying vec3 pos, norm, tang;
     5.9 +
    5.10 +void main()
    5.11 +{
    5.12 +	vec3 n = normalize(norm);
    5.13 +	vec3 t = normalize(tang);
    5.14 +	vec3 b = cross(n, t);
    5.15 +
    5.16 +	mat3 tbn_mat = mat3(
    5.17 +			t.x, t.y, t.z,
    5.18 +			b.x, b.y, b.z,
    5.19 +			n.x, n.y, n.z);
    5.20 +
    5.21 +	// grab normal from the normal map, remap it and transform it to view space
    5.22 +	n = texture2D(tex_norm, gl_TexCoord[0].st).xyz * 2.0 - 1.0;
    5.23 +	n = normalize(tbn_mat * n);
    5.24 +
    5.25 +	gl_FragColor = vec4(n, 0.0);
    5.26 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/prototype/sdr/multi2.p.glsl	Tue Sep 25 06:19:37 2012 +0300
     6.3 @@ -0,0 +1,20 @@
     6.4 +/* multipass renderer shader 2: RGB: diffuse color, A: shininess str. */
     6.5 +
     6.6 +uniform sampler2D tex_dif;
     6.7 +
     6.8 +varying vec3 pos, norm, tang;
     6.9 +
    6.10 +const float fog_start = 3.0;
    6.11 +const float fog_end = 6.0;
    6.12 +
    6.13 +void main()
    6.14 +{
    6.15 +	float fog = clamp((fog_end + pos.z) / (fog_end - fog_start), 0.0, 1.0);
    6.16 +
    6.17 +	vec4 texel = texture2D(tex_dif, gl_TexCoord[0].st);
    6.18 +	vec3 diffuse = fog * (gl_FrontMaterial.diffuse * texel).xyz;
    6.19 +	vec3 spec = fog * gl_FrontMaterial.specular.xyz;
    6.20 +	float sstr = (spec.x + spec.y + spec.z) / 3.0;
    6.21 +
    6.22 +	gl_FragColor = vec4(diffuse, sstr);
    6.23 +}
     7.1 --- a/prototype/src/cfg.cc	Fri Sep 21 05:28:45 2012 +0300
     7.2 +++ b/prototype/src/cfg.cc	Tue Sep 25 06:19:37 2012 +0300
     7.3 @@ -7,13 +7,14 @@
     7.4  
     7.5  Config::Config()
     7.6  {
     7.7 -	width = 800;
     7.8 -	height = 600;
     7.9 +	width = 1280;
    7.10 +	height = 800;
    7.11  	stereo = false;
    7.12  	sound = true;
    7.13  	level_file = "0.level";
    7.14  	tileset_file = "default.tileset";
    7.15 -	use_deferred = true;
    7.16 +
    7.17 +	rend = Renderer::any;
    7.18  }
    7.19  
    7.20  bool Config::parse_args(int argc, char **argv)
    7.21 @@ -33,17 +34,31 @@
    7.22  				level_file = argv[++i];
    7.23  			} else if(strcmp(argv[i], "-tileset") == 0) {
    7.24  				tileset_file = argv[++i];
    7.25 -			} else if(strcmp(argv[i], "-no-deferred") == 0) {
    7.26 -				use_deferred = false;
    7.27 +			} else if(strcmp(argv[i], "-renderer") == 0) {
    7.28 +				if(strcmp(argv[++i], "mrt") == 0) {
    7.29 +					rend = Renderer::mrt;
    7.30 +				} else if(strcmp(argv[i], "mp") == 0) {
    7.31 +					rend = Renderer::multipass;
    7.32 +				} else if(strcmp(argv[i], "fwd") == 0) {
    7.33 +					rend = Renderer::fwd;
    7.34 +				} else {
    7.35 +					fprintf(stderr, "invalid renderer specified: %s\n", argv[i]);
    7.36 +					return false;
    7.37 +				}
    7.38  			} else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-help") == 0) {
    7.39  				printf("Usage: %s [options]\n", argv[0]);
    7.40 -				printf("  -s WxH              window size (resolution)\n");
    7.41 -				printf("  -level <filename>   specify which level file to load\n");
    7.42 -				printf("  -tileset <filename> specify which tileset to use\n");
    7.43 -				printf("  -stereo             enable stereoscopic rendering\n");
    7.44 -				printf("  -nosound            disable sound output\n");
    7.45 -				printf("  -no-deferred        disable deferred renderer\n");
    7.46 -				printf("  -h/-help            print usage information and exit\n");
    7.47 +				printf("  -s WxH           window size (resolution)\n");
    7.48 +				printf("  -level <file>    specify which level file to load\n");
    7.49 +				printf("  -tileset <file>  specify which tileset to use\n");
    7.50 +				printf("  -renderer <rend> specify which renderer to use\n");
    7.51 +				printf("  -stereo          enable stereoscopic rendering\n");
    7.52 +				printf("  -nosound         disable sound output\n");
    7.53 +				printf("  -h/-help         print usage information and exit\n");
    7.54 +				printf("\n");
    7.55 +				printf("Renderers:\n");
    7.56 +				printf("  mrt  - deferred renderer using multiple draw buffers\n");
    7.57 +				printf("  mp   - multipass deferred renderer for each g-buffer\n");
    7.58 +				printf("  fwd  - fallback forward renderer with simplistic lighting\n");
    7.59  				exit(0);
    7.60  
    7.61  			} else {
     8.1 --- a/prototype/src/cfg.h	Fri Sep 21 05:28:45 2012 +0300
     8.2 +++ b/prototype/src/cfg.h	Tue Sep 25 06:19:37 2012 +0300
     8.3 @@ -1,13 +1,16 @@
     8.4  #ifndef CFG_H_
     8.5  #define CFG_H_
     8.6  
     8.7 +
     8.8 +
     8.9  extern class Config {
    8.10  public:
    8.11  	int width, height;
    8.12  	bool stereo;
    8.13  	bool sound;
    8.14  	const char *level_file, *tileset_file;
    8.15 -	bool use_deferred;
    8.16 +
    8.17 +	enum class Renderer { any, mrt, multipass, fwd } rend;
    8.18  
    8.19  	Config();
    8.20  
     9.1 --- a/prototype/src/light.cc	Fri Sep 21 05:28:45 2012 +0300
     9.2 +++ b/prototype/src/light.cc	Tue Sep 25 06:19:37 2012 +0300
     9.3 @@ -4,6 +4,8 @@
     9.4  #include "renderer.h"
     9.5  #include "timer.h"
     9.6  
     9.7 +unsigned int PointLight::sph_vbo = 0;
     9.8 +
     9.9  Light::Light(const Color &col)
    9.10  	: color(col)
    9.11  {
    9.12 @@ -159,6 +161,13 @@
    9.13  
    9.14  bool PointLight::create_mesh()
    9.15  {
    9.16 +	if(sph_vbo) {
    9.17 +		vbo = sph_vbo;
    9.18 +		return true;
    9.19 +	}
    9.20 +
    9.21 +	printf("building sphere mesh for point light drawing\n");
    9.22 +
    9.23  	const static int udiv = 8;
    9.24  	const static int vdiv = 4;
    9.25  
    9.26 @@ -169,8 +178,8 @@
    9.27  	float du = 1.0 / (float)udiv;
    9.28  	float dv = 1.0 / (float)vdiv;
    9.29  
    9.30 -	glGenBuffers(1, &vbo);
    9.31 -	glBindBuffer(GL_ARRAY_BUFFER, vbo);
    9.32 +	glGenBuffers(1, &sph_vbo);
    9.33 +	glBindBuffer(GL_ARRAY_BUFFER, sph_vbo);
    9.34  	glBufferData(GL_ARRAY_BUFFER, nverts * sizeof(Vector3), 0, GL_STATIC_DRAW);
    9.35  
    9.36  	Vector3 *vptr = (Vector3*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    9.37 @@ -191,6 +200,8 @@
    9.38  	}
    9.39  	glUnmapBuffer(GL_ARRAY_BUFFER);
    9.40  	glBindBuffer(GL_ARRAY_BUFFER, 0);
    9.41 +
    9.42 +	vbo = sph_vbo;
    9.43  	return true;
    9.44  }
    9.45  
    10.1 --- a/prototype/src/light.h	Fri Sep 21 05:28:45 2012 +0300
    10.2 +++ b/prototype/src/light.h	Tue Sep 25 06:19:37 2012 +0300
    10.3 @@ -36,6 +36,8 @@
    10.4  	float atten[3];
    10.5  	float radius;
    10.6  
    10.7 +	static unsigned int sph_vbo;
    10.8 +
    10.9  	bool create_mesh();
   10.10  
   10.11  public:
    11.1 --- a/prototype/src/main.cc	Fri Sep 21 05:28:45 2012 +0300
    11.2 +++ b/prototype/src/main.cc	Tue Sep 25 06:19:37 2012 +0300
    11.3 @@ -11,6 +11,7 @@
    11.4  #include "tileset.h"
    11.5  #include "renderer.h"
    11.6  #include "renderer_deferred.h"
    11.7 +#include "renderer_multipass.h"
    11.8  #include "cmdcon.h"
    11.9  #include "cfg.h"
   11.10  #include "timer.h"
   11.11 @@ -117,15 +118,52 @@
   11.12  		}
   11.13  	}
   11.14  
   11.15 -	rend = new DeferredRenderer();
   11.16 -	if(!cfg.use_deferred || !rend->init(xsz, ysz)) {
   11.17 -		printf("falling back to crappy renderer...\n");
   11.18 +	switch(cfg.rend) {
   11.19 +	case Config::Renderer::mrt:
   11.20 +		rend = new DeferredRenderer;
   11.21 +		if(!rend->init(xsz, ysz)) {
   11.22 +			fprintf(stderr, "failed to initialize deferred mrt renderer\n");
   11.23 +			delete rend;
   11.24 +			return false;
   11.25 +		}
   11.26 +		break;
   11.27  
   11.28 -		rend = new FwdRenderer();
   11.29 +	case Config::Renderer::multipass:
   11.30 +		rend = new MultipassRenderer;
   11.31  		if(!rend->init(xsz, ysz)) {
   11.32 -			fprintf(stderr, "failed to create renderer\n");
   11.33 +			fprintf(stderr, "failed to initialize multipass deferred renderer\n");
   11.34 +			delete rend;
   11.35  			return false;
   11.36  		}
   11.37 +		break;
   11.38 +
   11.39 +	case Config::Renderer::fwd:
   11.40 +		rend = new FwdRenderer;
   11.41 +		if(!rend->init(xsz, ysz)) {
   11.42 +			fprintf(stderr, "failed to initialize forward renderer\n");
   11.43 +			delete rend;
   11.44 +			return false;
   11.45 +		}
   11.46 +		break;
   11.47 +
   11.48 +	default:
   11.49 +		// try each in turn falling back to progressively worse renderers
   11.50 +		rend = new DeferredRenderer;
   11.51 +		if(!rend->init(xsz, ysz)) {
   11.52 +			printf("falling back to multipass renderer...\n");
   11.53 +
   11.54 +			delete rend;
   11.55 +			rend = new MultipassRenderer();
   11.56 +			if(!rend->init(xsz, ysz)) {
   11.57 +				printf("falling back to crappy renderer...\n");
   11.58 +
   11.59 +				rend = new FwdRenderer();
   11.60 +				if(!rend->init(xsz, ysz)) {
   11.61 +					fprintf(stderr, "failed to create renderer\n");
   11.62 +					return false;
   11.63 +				}
   11.64 +			}
   11.65 +		}
   11.66  	}
   11.67  
   11.68  	if(!init_cmdcon()) {
    12.1 --- a/prototype/src/renderer_deferred.cc	Fri Sep 21 05:28:45 2012 +0300
    12.2 +++ b/prototype/src/renderer_deferred.cc	Tue Sep 25 06:19:37 2012 +0300
    12.3 @@ -22,6 +22,7 @@
    12.4  	mrt_prog = deferred_debug = deferred_omni = 0;
    12.5  
    12.6  	curr_prog = 0;
    12.7 +	num_draw_bufs = 1;
    12.8  }
    12.9  
   12.10  DeferredRenderer::~DeferredRenderer()
   12.11 @@ -65,6 +66,7 @@
   12.12  		fprintf(stderr, "%s: error: not enough draw buffers (%d), %d required\n", __func__, max_draw_buf, MRT_COUNT);
   12.13  		return false;
   12.14  	}
   12.15 +	num_draw_bufs = MRT_COUNT;
   12.16  
   12.17  	if(!create_fbo()) {
   12.18  		return false;
   12.19 @@ -138,10 +140,17 @@
   12.20  
   12.21  	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   12.22  	level->draw();
   12.23 -
   12.24  	glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
   12.25  
   12.26  	// post-process lighting
   12.27 +	light_pass(level);
   12.28 +
   12.29 +	glUseProgram(0);
   12.30 +	curr_prog = 0;
   12.31 +}
   12.32 +
   12.33 +void DeferredRenderer::light_pass(const Level *level) const
   12.34 +{
   12.35  	glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT);
   12.36  
   12.37  	glEnable(GL_BLEND);
   12.38 @@ -169,8 +178,6 @@
   12.39  		glDisable(GL_TEXTURE_2D);
   12.40  	}
   12.41  
   12.42 -	glUseProgram(0);
   12.43 -	curr_prog = 0;
   12.44  	glPopAttrib();
   12.45  }
   12.46  
   12.47 @@ -211,18 +218,21 @@
   12.48  		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, tex_xsz, tex_ysz, 0, GL_RGBA, GL_FLOAT, 0);
   12.49  
   12.50  		// attach to fbo
   12.51 -		glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
   12.52 -				GL_TEXTURE_2D, mrt_tex[i], 0);
   12.53 +		GLenum color_att = num_draw_bufs >= MRT_COUNT ? GL_COLOR_ATTACHMENT0 + i : GL_COLOR_ATTACHMENT0;
   12.54 +		glFramebufferTexture2DEXT(GL_FRAMEBUFFER, color_att, GL_TEXTURE_2D,
   12.55 +				mrt_tex[i], 0);
   12.56  		CHECKGLERR;
   12.57  	}
   12.58  
   12.59 -	static GLenum draw_bufs[] = {
   12.60 -		GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT,
   12.61 -		GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT,
   12.62 -		GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT,
   12.63 -		GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT
   12.64 -	};
   12.65 -	glDrawBuffersARB(MRT_COUNT, draw_bufs);
   12.66 +	if(num_draw_bufs >= MRT_COUNT) {
   12.67 +		static GLenum draw_bufs[] = {
   12.68 +			GL_COLOR_ATTACHMENT0_EXT, GL_COLOR_ATTACHMENT1_EXT,
   12.69 +			GL_COLOR_ATTACHMENT2_EXT, GL_COLOR_ATTACHMENT3_EXT,
   12.70 +			GL_COLOR_ATTACHMENT4_EXT, GL_COLOR_ATTACHMENT5_EXT,
   12.71 +			GL_COLOR_ATTACHMENT6_EXT, GL_COLOR_ATTACHMENT7_EXT
   12.72 +		};
   12.73 +		glDrawBuffersARB(num_draw_bufs, draw_bufs);
   12.74 +	}
   12.75  
   12.76  	glGenRenderbuffersEXT(1, &rbuf_depth);
   12.77  	glBindRenderbufferEXT(GL_RENDERBUFFER, rbuf_depth);
    13.1 --- a/prototype/src/renderer_deferred.h	Fri Sep 21 05:28:45 2012 +0300
    13.2 +++ b/prototype/src/renderer_deferred.h	Tue Sep 25 06:19:37 2012 +0300
    13.3 @@ -6,7 +6,7 @@
    13.4  #define MRT_COUNT	3
    13.5  
    13.6  class DeferredRenderer : public Renderer {
    13.7 -private:
    13.8 +protected:
    13.9  	unsigned int fbo, rbuf_depth;
   13.10  	unsigned int mrt_tex[MRT_COUNT];
   13.11  	int tex_xsz, tex_ysz;
   13.12 @@ -16,20 +16,24 @@
   13.13  
   13.14  	mutable unsigned int curr_prog;
   13.15  
   13.16 -	bool create_fbo();
   13.17 +	int num_draw_bufs;
   13.18 +
   13.19 +	virtual bool create_fbo();
   13.20  
   13.21  public:
   13.22  	DeferredRenderer();
   13.23 -	~DeferredRenderer();
   13.24 +	virtual ~DeferredRenderer();
   13.25  
   13.26 -	bool init(int xsz, int ysz);
   13.27 +	virtual bool init(int xsz, int ysz);
   13.28  
   13.29 -	int get_tangent_location() const;
   13.30 -	unsigned int get_current_program() const;
   13.31 +	virtual int get_tangent_location() const;
   13.32 +	virtual unsigned int get_current_program() const;
   13.33  
   13.34 -	void resize(int xsz, int ysz);
   13.35 +	virtual void resize(int xsz, int ysz);
   13.36  
   13.37 -	void render(const Level *level) const;
   13.38 +	virtual void render(const Level *level) const;
   13.39 +
   13.40 +	virtual void light_pass(const Level *level) const;
   13.41  };
   13.42  
   13.43  #endif	// RENDERER_DEFERRED_H_
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/prototype/src/renderer_multipass.cc	Tue Sep 25 06:19:37 2012 +0300
    14.3 @@ -0,0 +1,120 @@
    14.4 +#include <stdio.h>
    14.5 +#include <stdlib.h>
    14.6 +#include <string.h>
    14.7 +#include "opengl.h"
    14.8 +#include "renderer_multipass.h"
    14.9 +#include "level.h"
   14.10 +#include "sdr.h"
   14.11 +#include "datapath.h"
   14.12 +
   14.13 +static unsigned int load_sdr(const char *vfname, const char *pfname);
   14.14 +
   14.15 +
   14.16 +MultipassRenderer::MultipassRenderer()
   14.17 +{
   14.18 +	for(int i=0; i<MRT_COUNT; i++) {
   14.19 +		rt_prog[i] = 0;
   14.20 +	}
   14.21 +}
   14.22 +
   14.23 +MultipassRenderer::~MultipassRenderer()
   14.24 +{
   14.25 +	for(int i=0; i<MRT_COUNT; i++) {
   14.26 +		if(rt_prog[i]) {
   14.27 +			free_program(rt_prog[i]);
   14.28 +		}
   14.29 +	}
   14.30 +}
   14.31 +
   14.32 +bool MultipassRenderer::init(int xsz, int ysz)
   14.33 +{
   14.34 +	width = xsz;
   14.35 +	height = ysz;
   14.36 +
   14.37 +	if(!GLEW_ARB_texture_float) {
   14.38 +		fprintf(stderr, "%s: error: no floating point texture support\n", __func__);
   14.39 +		return false;
   14.40 +	}
   14.41 +
   14.42 +	if(!create_fbo()) {
   14.43 +		return false;
   14.44 +	}
   14.45 +
   14.46 +	for(int i=0; i<MRT_COUNT; i++) {
   14.47 +		char fname[128];
   14.48 +		sprintf(fname, "multi%d.p.glsl", i);
   14.49 +
   14.50 +		if(!(rt_prog[i] = load_sdr("mrt.v.glsl", fname))) {
   14.51 +			return false;
   14.52 +		}
   14.53 +		set_uniform_int(rt_prog[i], "tex_dif", 0);
   14.54 +		set_uniform_int(rt_prog[i], "tex_norm", 1);
   14.55 +	}
   14.56 +
   14.57 +	if(!(deferred_omni = load_sdr("deferred_omni.v.glsl", "deferred_omni.p.glsl"))) {
   14.58 +		return false;
   14.59 +	}
   14.60 +	for(int i=0; i<MRT_COUNT; i++) {
   14.61 +		char uname[32];
   14.62 +		sprintf(uname, "mrt%d", i);
   14.63 +		set_uniform_int(deferred_omni, uname, i);
   14.64 +	}
   14.65 +
   14.66 +	rend = this;
   14.67 +	return true;
   14.68 +}
   14.69 +
   14.70 +int MultipassRenderer::get_tangent_location() const
   14.71 +{
   14.72 +	if(!curr_prog) {
   14.73 +		return -1;
   14.74 +	}
   14.75 +	return get_attrib_loc(curr_prog, "attr_tangent");
   14.76 +}
   14.77 +
   14.78 +void MultipassRenderer::render(const Level *level) const
   14.79 +{
   14.80 +	// render into the MRT buffers
   14.81 +	glBindFramebufferEXT(GL_FRAMEBUFFER, fbo);
   14.82 +
   14.83 +	for(int i=0; i<MRT_COUNT; i++) {
   14.84 +		glUseProgram(rt_prog[i]);
   14.85 +		curr_prog = rt_prog[i];
   14.86 +
   14.87 +		glFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
   14.88 +				mrt_tex[i], 0);
   14.89 +
   14.90 +		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   14.91 +		level->draw();
   14.92 +	}
   14.93 +	glBindFramebufferEXT(GL_FRAMEBUFFER, 0);
   14.94 +
   14.95 +	// post-process lighting
   14.96 +	light_pass(level);
   14.97 +
   14.98 +	glUseProgram(0);
   14.99 +	curr_prog = 0;
  14.100 +}
  14.101 +
  14.102 +static unsigned int load_sdr(const char *vfname, const char *pfname)
  14.103 +{
  14.104 +	char vsfile[PATH_MAX], psfile[PATH_MAX];
  14.105 +	const char *fname;
  14.106 +	unsigned int prog;
  14.107 +
  14.108 +	if((fname = datafile_path(vfname))) {
  14.109 +		strcpy(vsfile, fname);
  14.110 +	} else {
  14.111 +		vsfile[0] = 0;
  14.112 +	}
  14.113 +	if((fname = datafile_path(pfname))) {
  14.114 +		strcpy(psfile, fname);
  14.115 +	} else {
  14.116 +		psfile[0] = 0;
  14.117 +	}
  14.118 +	if(!(prog = create_program_load(vsfile, psfile))) {
  14.119 +		fprintf(stderr, "failed to load shader program (%s, %s)\n", vsfile, psfile);
  14.120 +		return 0;
  14.121 +	}
  14.122 +	return prog;
  14.123 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/prototype/src/renderer_multipass.h	Tue Sep 25 06:19:37 2012 +0300
    15.3 @@ -0,0 +1,21 @@
    15.4 +#ifndef RENDERER_MULTIPASS_H_
    15.5 +#define RENDERER_MULTIPASS_H_
    15.6 +
    15.7 +#include "renderer_deferred.h"
    15.8 +
    15.9 +class MultipassRenderer : public DeferredRenderer {
   15.10 +private:
   15.11 +	unsigned int rt_prog[MRT_COUNT];
   15.12 +
   15.13 +public:
   15.14 +	MultipassRenderer();
   15.15 +	virtual ~MultipassRenderer();
   15.16 +
   15.17 +	virtual bool init(int xsz, int ysz);
   15.18 +
   15.19 +	virtual int get_tangent_location() const;
   15.20 +
   15.21 +	virtual void render(const Level *level) const;
   15.22 +};
   15.23 +
   15.24 +#endif	// RENDERER_MULTIPASS_H_
    16.1 --- a/prototype/src/tile.cc	Fri Sep 21 05:28:45 2012 +0300
    16.2 +++ b/prototype/src/tile.cc	Tue Sep 25 06:19:37 2012 +0300
    16.3 @@ -141,8 +141,11 @@
    16.4  
    16.5  void Tile::draw(unsigned int draw_mask) const
    16.6  {
    16.7 +	int tang_loc = rend->get_tangent_location();
    16.8 +
    16.9  	for(size_t i=0; i<meshes.size(); i++) {
   16.10  		if(mesh_side[i] & draw_mask) {
   16.11 +			meshes[i]->set_attrib_location(MESH_ATTR_TANGENT, tang_loc);
   16.12  			meshes[i]->draw();
   16.13  		}
   16.14  	}
   16.15 @@ -152,6 +155,7 @@
   16.16  {
   16.17  	for(size_t i=0; i<lights.size(); i++) {
   16.18  		if(light_side[i] & draw_mask) {
   16.19 +			printf("rendering light ...\n");
   16.20  			lights[i]->draw();
   16.21  		}
   16.22  	}
   16.23 @@ -205,11 +209,6 @@
   16.24  {
   16.25  	int count = 0;
   16.26  
   16.27 -	int attr_loc = rend->get_tangent_location();
   16.28 -	if(attr_loc == -1) {
   16.29 -		fprintf(stderr, "warning: failed to retrieve tangent attribute location while loading tile\n");
   16.30 -	}
   16.31 -
   16.32  	for(int i=0; i<(int)scn->mNumMeshes; i++) {
   16.33  		// ignore any lines or other crap
   16.34  		if(scn->mMeshes[i]->mPrimitiveTypes != aiPrimitiveType_TRIANGLE) {
   16.35 @@ -221,9 +220,6 @@
   16.36  			delete mesh;
   16.37  			continue;
   16.38  		}
   16.39 -		if(attr_loc != -1) {
   16.40 -			mesh->set_attrib_location(MESH_ATTR_TANGENT, attr_loc);
   16.41 -		}
   16.42  
   16.43  		Material mat;
   16.44  		mat.load(scn->mMaterials[scn->mMeshes[i]->mMaterialIndex], tset->get_textures());