#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;
}
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; i<num; i++) {
Scene *scn = mscn->scenes[i];
int nobj = (int)scn->objects.size();
for(int j=0; j<nobj; j++) {
+ // don't draw mirrors, we already did that earlier (if mirror rendering enabled)
+ if((ropt & RENDER_MIRRORS) && scn->objects[j]->mtl.flat_mirror) {
+ continue;
+ }
draw_object(scn->objects[j]);
}
}
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; i<nobj; i++) {
+ draw_object(mir->objects[i]);
+ }
+}