simple ubershader system, reflection debugging
[laserbrain_demo] / src / renderer.cc
index 43a96db..deff1b9 100644 (file)
@@ -1,6 +1,18 @@
 #include "renderer.h"
 #include "rtarg.h"
 #include "app.h"
 #include "renderer.h"
 #include "rtarg.h"
 #include "app.h"
+#include "sdr.h"
+
+enum {
+       USE_TEXMAP = 1,
+       USE_MIRROR = 2,
+};
+static const char *use_flag_str[] = {
+       "#define USE_TEXMAP\n",
+       "#define USE_MIRROR\n"
+};
+#define NUM_USE_FLAGS  ((int)(sizeof use_flag_str / sizeof *use_flag_str))
+
 
 static RenderTarget *rtmirror;
 
 
 static RenderTarget *rtmirror;
 
@@ -8,11 +20,13 @@ Renderer::Renderer()
 {
        mscn = 0;
        ropt = RENDER_ALL;
 {
        mscn = 0;
        ropt = RENDER_ALL;
+       shaders = 0;
 }
 
 Renderer::~Renderer()
 {
        destroy();
 }
 
 Renderer::~Renderer()
 {
        destroy();
+       delete [] shaders;
 }
 
 bool Renderer::init()
 }
 
 bool Renderer::init()
@@ -26,6 +40,26 @@ bool Renderer::init()
                }
        }
 
                }
        }
 
+       int numsdr = 1 << NUM_USE_FLAGS;
+       shaders = new unsigned int[numsdr];
+
+       for(int i=0; i<numsdr; i++) {
+               clear_shader_header(0);
+
+               for(int j=0; j<NUM_USE_FLAGS; j++) {
+                       if(i & (1 << j)) {
+                               add_shader_header(0, use_flag_str[j]);
+                       }
+               }
+
+               if(!(shaders[i] = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap.p.glsl"))) {
+                       return false;
+               }
+               set_uniform_int(shaders[i], "texmap", MTL_TEX_DIFFUSE);
+               set_uniform_int(shaders[i], "lightmap", MTL_TEX_LIGHTMAP);
+               set_uniform_int(shaders[i], "mirrortex", MTL_TEX_REFLECT);
+       }
+
        return true;
 }
 
        return true;
 }
 
@@ -98,6 +132,23 @@ void Renderer::draw_object(Object *obj) const
        }
 
        if(vis) {
        }
 
        if(vis) {
+               unsigned int use_mask = 0;
+               if(obj->mtl.stdtex[MTL_TEX_DIFFUSE]) {
+                       use_mask |= USE_TEXMAP;
+               }
+               if(obj->mtl.stdtex[MTL_TEX_REFLECT] && obj->mtl.flat_mirror) {
+                       use_mask |= USE_MIRROR;
+               }
+
+               unsigned int sdr = shaders[use_mask];
+               if(use_mask & USE_MIRROR) {
+                       float sx = 1.0f / rtmirror->texture()->get_width();
+                       float sy = 1.0f / rtmirror->texture()->get_height();
+                       set_uniform_float2(sdr, "mirtex_scale", sx, sy);
+                       set_uniform_float(sdr, "reflectivity", obj->mtl.reflect);
+               }
+               bind_program(sdr);
+
                obj->draw();
        }
 }
                obj->draw();
        }
 }
@@ -105,20 +156,17 @@ void Renderer::draw_object(Object *obj) const
 void Renderer::draw_mirror(FlatMirror *mir) const
 {
        push_render_target(rtmirror);
 void Renderer::draw_mirror(FlatMirror *mir) const
 {
        push_render_target(rtmirror);
+       glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+       glClearColor(1, 1, 1, 1);
 
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
 
 
        glMatrixMode(GL_MODELVIEW);
        glPushMatrix();
 
-       float pdist = dot(mir->plane.normal, mir->plane.pt);
-       Vec4 peq = Vec4(mir->plane.normal.x, mir->plane.normal.y, mir->plane.normal.z, pdist);
-
-       if(mir->node) {
-               peq = mir->node->get_matrix() * peq;
-       }
+       // TODO update mirror plane for movable mirrors?
 
        Mat4 mirmat;
 
        Mat4 mirmat;
-       mirmat.mirror(peq.x, peq.y, peq.z, peq.w);
+       mirmat.mirror(mir->wplane.normal, dot(mir->wplane.normal, mir->wplane.pt));
        glMultMatrixf(mirmat[0]);
 
        glFrontFace(GL_CW);
        glMultMatrixf(mirmat[0]);
 
        glFrontFace(GL_CW);
@@ -128,10 +176,20 @@ void Renderer::draw_mirror(FlatMirror *mir) const
        glPopMatrix();
        pop_render_target();
 
        glPopMatrix();
        pop_render_target();
 
-       dump_gl_texture(rtmirror->texture()->get_id(), "mirror.ppm");
+       if(dbg_key_pending & 1) {
+               dump_gl_texture(rtmirror->texture()->get_id(), "mirror.ppm");
+               dbg_key_pending &= ~1;
+       }
 
        int nobj = mir->objects.size();
        for(int i=0; i<nobj; i++) {
 
        int nobj = mir->objects.size();
        for(int i=0; i<nobj; i++) {
+               Object *obj = (Object*)mir->objects[i];
+
+               Texture *prev_refl_tex = obj->mtl.stdtex[MTL_TEX_REFLECT];
+               obj->mtl.stdtex[MTL_TEX_REFLECT] = rtmirror->texture();
+
                draw_object(mir->objects[i]);
                draw_object(mir->objects[i]);
+
+               obj->mtl.stdtex[MTL_TEX_REFLECT] = prev_refl_tex;
        }
 }
        }
 }