X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Frenderer.cc;h=43a96db101dda147b94ce6bd30a976d2c1be7eee;hp=bb274f21960f29b6f30da8de90ae79380d1ef0c4;hb=844f36f03073c5db86a8acd2cf7cd1a89e1a16b9;hpb=74034a459f47934ef60ba295033b9cb7e597d32a diff --git a/src/renderer.cc b/src/renderer.cc index bb274f2..43a96db 100644 --- a/src/renderer.cc +++ b/src/renderer.cc @@ -1,16 +1,31 @@ #include "renderer.h" +#include "rtarg.h" +#include "app.h" + +static RenderTarget *rtmirror; Renderer::Renderer() { mscn = 0; + ropt = RENDER_ALL; } Renderer::~Renderer() { + destroy(); } bool Renderer::init() { + static bool once; + if(!rtmirror && !once) { + once = true; + rtmirror = new RenderTarget; + if(!rtmirror->create(vp_width, vp_height, GL_SRGB)) { + error_log("failed to create mirror render target (%dx%d)\n", vp_width, vp_height); + } + } + return true; } @@ -28,16 +43,43 @@ MetaScene *Renderer::get_scene() const return mscn; } +// render mirror reflections if ... +#define DO_MIRRORS \ + mscn->mirrors && /* scene contains mirrors */ \ + (ropt & RENDER_MIRRORS) && /* mirror rendering is enabled */ \ + rtmirror /* mirror render target succesfully created */ + void Renderer::draw() const { if(!mscn) return; + if(DO_MIRRORS && current_render_target() != rtmirror) { + // check if the render target needs resizing + if(rtmirror->get_width() != vp_width || rtmirror->get_height() != vp_height) { + if(!rtmirror->resize(vp_width, vp_height)) { + error_log("failed to resize mirror render target (%dx%d)\n", vp_width, vp_height); + goto abort_mirrors; + } + } + + FlatMirror *mir = mscn->mirrors; + while(mir) { + draw_mirror(mir); + mir = mir->next; + } + } +abort_mirrors: + int num = (int)mscn->scenes.size(); for(int i=0; iscenes[i]; int nobj = (int)scn->objects.size(); for(int j=0; jobjects[j]->mtl.flat_mirror) { + continue; + } draw_object(scn->objects[j]); } } @@ -59,3 +101,37 @@ void Renderer::draw_object(Object *obj) const obj->draw(); } } + +void Renderer::draw_mirror(FlatMirror *mir) const +{ + push_render_target(rtmirror); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + 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; + } + + Mat4 mirmat; + mirmat.mirror(peq.x, peq.y, peq.z, peq.w); + glMultMatrixf(mirmat[0]); + + glFrontFace(GL_CW); + draw(); + glFrontFace(GL_CCW); + + glPopMatrix(); + pop_render_target(); + + dump_gl_texture(rtmirror->texture()->get_id(), "mirror.ppm"); + + int nobj = mir->objects.size(); + for(int i=0; iobjects[i]); + } +}