fixed reflections in VR
[laserbrain_demo] / src / rtarg.cc
index 12a4ddb..8a232b0 100644 (file)
@@ -34,7 +34,7 @@ RenderTarget *current_render_target()
        return rstack[rtop].rt;
 }
 
-bool push_render_target(RenderTarget *rt)
+bool push_render_target(RenderTarget *rt, unsigned int flags)
 {
        if(!rt) {
                error_log("push_render_target(0) is invalid\n");
@@ -44,36 +44,39 @@ bool push_render_target(RenderTarget *rt)
                warning_log("push_render_target: overflow\n");
                return false;
        }
-       int *vp = rstack[rtop + 1].saved_vp;
-       RenderTarget *prev = current_render_target();
 
-       if(prev) {
-               vp[0] = vp[1] = 0;
-               vp[2] = prev->get_width();
-               vp[3] = prev->get_height();
-       } else {
+       if(!(flags & RT_NO_VPORT)) {
+               int *vp = rstack[rtop + 1].saved_vp;
                glGetIntegerv(GL_VIEWPORT, vp);
        }
        rstack[++rtop].rt = rt;
 
-       rt->bind();
+       if(!(flags & RT_NO_BIND)) {
+               rt->bind();
+       }
        return true;
 }
 
-bool pop_render_target()
+bool pop_render_target(unsigned int flags)
 {
        if(rtop <= 0) {
-               error_log("pop_render_target: undeflow\n");
+               error_log("pop_render_target: underflow\n");
                return false;
        }
 
-       int *vp = rstack[rtop].saved_vp;
-       glViewport(vp[0], vp[1], vp[2], vp[3]);
+       if(!(flags & RT_NO_VPORT)) {
+               int *vp = rstack[rtop].saved_vp;
+               glViewport(vp[0], vp[1], vp[2], vp[3]);
+       }
+
+       --rtop;
 
-       if(rstack[--rtop].rt) {
-               rstack[rtop].rt->bind();
-       } else {
-               glBindFramebuffer(GL_FRAMEBUFFER, 0);
+       if(!(flags & RT_NO_BIND)) {
+               if(rstack[rtop].rt) {
+                       rstack[rtop].rt->bind(RT_NO_VPORT);
+               } else {
+                       glBindFramebuffer(GL_FRAMEBUFFER, 0);
+               }
        }
        return true;
 }
@@ -87,6 +90,7 @@ RenderTarget::RenderTarget()
        auto_vport = true;
        rtcount = 0;
 
+       own_fbo = true;
        for(int i=0; i<4; i++) {
                tex[i] = 0;
                own_texture[i] = true;
@@ -108,6 +112,7 @@ bool RenderTarget::create_mrt(int xsz, int ysz, int num, unsigned int fmt, unsig
 {
        glGenFramebuffers(1, &fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       own_fbo = true;
 
        width = xsz;
        height = ysz;
@@ -171,6 +176,20 @@ bool RenderTarget::create_mrt(int xsz, int ysz, int num, unsigned int fmt, unsig
        return true;
 }
 
+bool RenderTarget::create_wrap_fbo(unsigned int fbo, int xsz, int ysz)
+{
+       this->fbo = fbo;
+       own_fbo = false;
+
+       width = tex_width = xsz;
+       height = tex_height = ysz;
+       rtcount = 1;
+
+       texmat = Mat4::identity;
+
+       return true;
+}
+
 void RenderTarget::destroy()
 {
        for(int i=0; i<4; i++) {
@@ -183,7 +202,7 @@ void RenderTarget::destroy()
                glDeleteRenderbuffers(1, &rbdepth);
                rbdepth = 0;
        }
-       if(fbo) {
+       if(fbo && own_fbo) {
                glDeleteFramebuffers(1, &fbo);
                fbo = 0;
        }
@@ -191,6 +210,8 @@ void RenderTarget::destroy()
 
 bool RenderTarget::resize(int xsz, int ysz)
 {
+       if(!own_fbo) return false;      /* TODO */
+
        int new_tx = next_pow2(xsz);
        int new_ty = next_pow2(ysz);
 
@@ -276,11 +297,11 @@ bool RenderTarget::auto_viewport() const
        return auto_vport;
 }
 
-void RenderTarget::bind() const
+void RenderTarget::bind(unsigned int flags) const
 {
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
 
-       if(auto_vport) {
+       if(auto_vport && !(flags & RT_NO_VPORT)) {
                glViewport(0, 0, width, height);
        }
 }