+ bool vis = true;
+ SceneNode *n = obj->node;
+ while(n) {
+ if(!n->visible) {
+ vis = false;
+ break;
+ }
+ n = n->get_parent();
+ }
+
+ 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();
+ }
+}
+
+void Renderer::draw_mirror(FlatMirror *mir) const
+{
+ push_render_target(rtmirror);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ // TODO update mirror plane for movable mirrors?
+
+ Mat4 mirmat;
+ mirmat.mirror(mir->wplane.normal, -dot(mir->wplane.normal, mir->wplane.pt));
+ glMultMatrixf(mirmat[0]);
+
+ glFrontFace(GL_CW);
+ draw();
+ glFrontFace(GL_CCW);
+
+ glPopMatrix();
+ pop_render_target();
+
+ 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++) {
+ 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]);
+
+ obj->mtl.stdtex[MTL_TEX_REFLECT] = prev_refl_tex;
+ }