# HG changeset patch # User John Tsiombikas # Date 1346294100 -10800 # Node ID acfe0c0110fce047008305a27342117605ef5c93 # Parent 38e16366efc2fabc88254dbb3e33911b9f4553a4 - cleaned up the renderer - implemented fallback (non-deferred renderer) diff -r 38e16366efc2 -r acfe0c0110fc prototype/sdr/fallback.p.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prototype/sdr/fallback.p.glsl Thu Aug 30 05:35:00 2012 +0300 @@ -0,0 +1,38 @@ +uniform sampler2D tex_dif, tex_norm; + +varying vec3 pos, norm, tang; + +const float fog_start = 3.0; +const float fog_end = 6.0; + +void main() +{ + vec3 texel = texture2D(tex_dif, gl_TexCoord[0].st).xyz; + + vec3 n = normalize(norm); + vec3 t = normalize(tang); + vec3 b = cross(n, t); + + mat3 tbn_mat = mat3( + t.x, b.x, n.x, + t.y, b.y, n.y, + t.z, b.z, n.z); + + + const vec3 lpos = vec3(0.0, 0.0, -0.5); + vec3 ldir = tbn_mat * normalize(lpos - pos); + + const vec3 vdir = vec3(0.0, 0.0, 1.0); + vec3 hvec = normalize(vdir + ldir); + + n = normalize(texture2D(tex_norm, gl_TexCoord[0].st).xyz * 2.0 - 1.0); + float ndotl = max(dot(n, ldir), 0.0); + float ndoth = max(dot(n, hvec), 0.0); + + vec3 diffuse = gl_FrontMaterial.diffuse.xyz * texel * ndotl; + vec3 specular = gl_FrontMaterial.specular.xyz * pow(ndoth, gl_FrontMaterial.shininess); + + float fog = clamp((fog_end + pos.z) / (fog_end - fog_start), 0.0, 1.0); + + gl_FragColor = vec4((diffuse + specular) * fog, 1.0); +} diff -r 38e16366efc2 -r acfe0c0110fc prototype/sdr/fallback.v.glsl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/prototype/sdr/fallback.v.glsl Thu Aug 30 05:35:00 2012 +0300 @@ -0,0 +1,13 @@ +attribute vec3 attr_tangent; + +varying vec3 pos, norm, tang; + +void main() +{ + gl_Position = ftransform(); + pos = (gl_ModelViewMatrix * gl_Vertex).xyz; + norm = gl_NormalMatrix * gl_Normal; + tang = gl_NormalMatrix * attr_tangent; + + gl_TexCoord[0] = gl_MultiTexCoord0; +} diff -r 38e16366efc2 -r acfe0c0110fc prototype/src/light.cc --- a/prototype/src/light.cc Thu Aug 30 03:05:04 2012 +0300 +++ b/prototype/src/light.cc Thu Aug 30 05:35:00 2012 +0300 @@ -114,7 +114,7 @@ void PointLight::draw() const { - unsigned int sdr = get_deferred_shader(); + unsigned int sdr = rend->get_current_program(); if(sdr) { int loc; if((loc = glGetUniformLocation(sdr, "light_radius")) != -1) { diff -r 38e16366efc2 -r acfe0c0110fc prototype/src/main.cc --- a/prototype/src/main.cc Thu Aug 30 03:05:04 2012 +0300 +++ b/prototype/src/main.cc Thu Aug 30 05:35:00 2012 +0300 @@ -8,6 +8,7 @@ #include "datapath.h" #include "tileset.h" #include "renderer.h" +#include "renderer_deferred.h" #include "cmdcon.h" #include "cfg.h" #include "timer.h" @@ -70,11 +71,15 @@ bool init(int xsz, int ysz) { + // backup light for the forward crappy renderer glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); - float ldir[] = {-1, 1, 2, 0}; + + float ldir[] = {0, 0, -0.5, 1}; glLightfv(GL_LIGHT0, GL_POSITION, ldir); - glEnable(GL_NORMALIZE); + float lcol[] = {1, 1, 1, 1}; + glLightfv(GL_LIGHT0, GL_DIFFUSE, lcol); + glLightfv(GL_LIGHT0, GL_SPECULAR, lcol); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); @@ -84,8 +89,15 @@ add_data_path("data"); add_data_path("sdr"); - if(!init_renderer(xsz, ysz)) { - return false; + rend = new DeferredRenderer(); + if(!rend->init(xsz, ysz)) { + printf("falling back to crappy renderer...\n"); + + rend = new FwdRenderer(); + if(!rend->init(xsz, ysz)) { + fprintf(stderr, "failed to create renderer\n"); + return false; + } } if(!init_cmdcon()) { @@ -115,8 +127,7 @@ { delete level; delete tileset; - - destroy_renderer(); + delete rend; cleanup_cmdcon(); } @@ -165,15 +176,13 @@ glutSwapBuffers(); assert(glGetError() == GL_NO_ERROR); - - usleep(10000); } void draw() { - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - render_deferred(level); + rend->render(level); if(show_con) { draw_cmdcon(); @@ -240,7 +249,7 @@ cfg.width = x; cfg.height = y; - resize_renderer(x, y); + rend->resize(x, y); } static bool stereo_shift_pressed; diff -r 38e16366efc2 -r acfe0c0110fc prototype/src/material.cc --- a/prototype/src/material.cc Thu Aug 30 03:05:04 2012 +0300 +++ b/prototype/src/material.cc Thu Aug 30 05:35:00 2012 +0300 @@ -3,6 +3,7 @@ #include #include "opengl.h" #include "material.h" +#include "renderer.h" extern bool ass_obj_hack; @@ -74,7 +75,7 @@ glDisable(GL_TEXTURE_2D); } - if(tex[TEXTYPE_NORMAL]) { + if(rend->get_current_program() && tex[TEXTYPE_NORMAL]) { glActiveTextureARB(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, tex[TEXTYPE_NORMAL]); glEnable(GL_TEXTURE_2D); diff -r 38e16366efc2 -r acfe0c0110fc prototype/src/renderer.cc --- a/prototype/src/renderer.cc Thu Aug 30 03:05:04 2012 +0300 +++ b/prototype/src/renderer.cc Thu Aug 30 05:35:00 2012 +0300 @@ -1,247 +1,97 @@ -#include -#include -#include -#include -#include #include "opengl.h" #include "renderer.h" #include "level.h" #include "sdr.h" #include "datapath.h" -#undef DBG_VIS_MRT +static unsigned int load_sdr(const char *vfname, const char *pfname); -#ifdef DBG_VIS_MRT -static void draw_deferred_debug(); -#endif +Renderer *rend; -static bool create_fbo(int xsz, int ysz); -static unsigned int load_sdr(const char *vfname, const char *pfname); -static int round_pow2(int x); +Renderer::Renderer() +{ + width = height = 0; +} -#define MRT_COUNT 3 -static unsigned int mrt_tex[MRT_COUNT]; +Renderer::~Renderer() +{ +} -static unsigned int mrt_prog; -static unsigned int deferred_omni, deferred_debug; +bool Renderer::init(int xsz, int ysz) +{ + width = xsz; + height = ysz; -static unsigned int fbo, rbuf_depth; -static const char *fbstname[] = { - "GL_FRAMEBUFFER_COMPLETE", - "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT", - "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT", - "no such fbo error", - "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS", - "GL_FRAMEBUFFER_INCOMPLETE_FORMATS", - "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER", - "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER", - "GL_FRAMEBUFFER_UNSUPPORTED" -}; + rend = this; + return true; +} -static int fb_xsz, fb_ysz, tex_xsz, tex_ysz; +int Renderer::get_tangent_location() const +{ + return -1; +} +unsigned int Renderer::get_current_program() const +{ + return 0; +} +void Renderer::resize(int xsz, int ysz) +{ + width = xsz; + height = ysz; +} -bool init_renderer(int xsz, int ysz) + +// ---- fallback forward renderer ---- +FwdRenderer::FwdRenderer() { - if(!GLEW_ARB_texture_float) { - fprintf(stderr, "Error: OpenGL implementation doesn't support floating point textures\n"); - return false; + sdrprog = 0; + tang_attr = -1; +} + +FwdRenderer::~FwdRenderer() +{ + if(sdrprog) { + free_program(sdrprog); } - if(!GLEW_ARB_draw_buffers) { - fprintf(stderr, "Error: OpenGL implementation doesn't support multiple render targets\n"); - return false; - } +} - int max_draw_buf; - glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buf); - printf("max draw buffers: %d\n", max_draw_buf); - if(max_draw_buf < MRT_COUNT) { - fprintf(stderr, "OpenGL implementation doesn't support enough draw buffers\n"); - return false; - } +bool FwdRenderer::init(int xsz, int ysz) +{ + width = xsz; + height = ysz; - if(!create_fbo(xsz, ysz)) { - return false; - } - CHECKGLERR; - - if(!(mrt_prog = load_sdr("mrt.v.glsl", "mrt.p.glsl"))) { - return false; - } - set_uniform_int(mrt_prog, "tex_dif", 0); - set_uniform_int(mrt_prog, "tex_norm", 1); - - if(!(deferred_debug = load_sdr("deferred.v.glsl", "deferred.p.glsl"))) { - return false; - } - for(int i=0; i tex_xsz || ysz > tex_ysz) { - tex_xsz = round_pow2(xsz); - tex_ysz = round_pow2(ysz); - - for(int i=0; idraw(); - glBindFramebufferEXT(GL_FRAMEBUFFER, 0); - -#ifdef DBG_VIS_MRT - draw_deferred_debug(); -#else - - // post-process lighting - glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); - - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE); - - glDisable(GL_LIGHTING); - glDisable(GL_DEPTH_TEST); - glCullFace(GL_FRONT); - - glUseProgram(deferred_omni); - for(int i=0; idraw_lights(); - glDepthMask(1); - - for(int i=0; i> 1) | x; - x = (x >> 2) | x; - x = (x >> 4) | x; - x = (x >> 8) | x; - x = (x >> 16) | x; - return x + 1; -} - -#ifdef DBG_VIS_MRT -// visualize the MRT buffers -static void draw_deferred_debug() -{ - glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); - glUseProgram(deferred_debug); - glDisable(GL_DEPTH_TEST); - - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - for(int i=0; i +#include +#include +#include +#include "opengl.h" +#include "renderer_deferred.h" +#include "level.h" +#include "sdr.h" +#include "datapath.h" + +static unsigned int load_sdr(const char *vfname, const char *pfname); +static int round_pow2(int x); + +DeferredRenderer::DeferredRenderer() +{ + fbo = rbuf_depth = 0; + for(int i=0; i tex_xsz || ysz > tex_ysz) { + tex_xsz = round_pow2(xsz); + tex_ysz = round_pow2(ysz); + + // ... resize all the color buffers + for(int i=0; idraw(); + + glBindFramebufferEXT(GL_FRAMEBUFFER, 0); + + // post-process lighting + glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); + + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE); + + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glCullFace(GL_FRONT); + + glUseProgram(deferred_omni); + curr_prog = deferred_omni; + + for(int i=0; idraw_lights(); + glDepthMask(1); + + for(int i=0; i> 1) | x; + x = (x >> 2) | x; + x = (x >> 4) | x; + x = (x >> 8) | x; + x = (x >> 16) | x; + return x + 1; +} + +#ifdef DBG_VIS_MRT +// visualize the MRT buffers +static void draw_deferred_debug() +{ + glPushAttrib(GL_ENABLE_BIT | GL_POLYGON_BIT); + glUseProgram(deferred_debug); + glDisable(GL_DEPTH_TEST); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + for(int i=0; iget_tangent_location(); if(attr_loc == -1) { fprintf(stderr, "warning: failed to retrieve tangent attribute location while loading tile\n"); }