cubemap renderer progress (untested)
[laserbrain_demo] / src / rend_cubemap.cc
diff --git a/src/rend_cubemap.cc b/src/rend_cubemap.cc
new file mode 100644 (file)
index 0000000..89d1b8b
--- /dev/null
@@ -0,0 +1,86 @@
+#include "opengl.h"
+#include "rend_cubemap.h"
+
+RendCubemap::RendCubemap()
+{
+       cubemap = 0;
+       fbo = zbuf = 0;
+       zbuf_width = zbuf_height = 0;
+
+       proj_matrix.perspective(M_PI / 2.0, 1, 0.5, 10000);
+}
+
+void RendCubemap::set_position(const Vec3 &pos)
+{
+       this->pos = pos;
+}
+
+void RendCubemap::set_cubemap(Texture *cubemap)
+{
+       this->cubemap = cubemap;
+}
+
+void RendCubemap::draw() const
+{
+       static const Vec3 targ[] = {
+               Vec3{1, 0, 0}, Vec3{-1, 0, 0},
+               Vec3{0, 1, 0}, Vec3{0, -1, 0},
+               Vec3{0, 0, 1}, Vec3{0, 0, -1}
+       };
+       static const Vec3 up[] = {
+               Vec3{0, 1, 0}, Vec3{0, 1, 0},
+               Vec3{0, 0, 1}, Vec3{0, 0, -1},
+               Vec3{0, 1, 0}, Vec3{0, 1, 0}
+       };
+       if(!cubemap) return;
+
+       glMatrixMode(GL_PROJECTION);
+       glPushMatrix();
+       glLoadMatrixf(proj_matrix[0]);
+
+       for(int i=0; i<6; i++) {
+               Mat4 vmat;
+               vmat.inv_lookat(pos, targ[i], up[i]);
+
+               glMatrixMode(GL_MODELVIEW);
+               if(i == 0) glPushMatrix();
+               glLoadMatrixf(vmat[0]);
+
+               setup(i);
+
+               Renderer::draw();
+       }
+
+       glMatrixMode(GL_PROJECTION);
+       glPopMatrix();
+       glMatrixMode(GL_MODELVIEW);
+       glPopMatrix();
+}
+
+void RendCubemap::draw_object(Object *obj) const
+{
+       obj->draw();
+}
+
+void RendCubemap::setup(int face_idx) const
+{
+       if(!cubemap) return;
+
+       if(!fbo) {
+               glGenFramebuffers(1, &fbo);
+       }
+       glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+       if(!zbuf) {
+               glGenRenderbuffers(1, &zbuf);
+               glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, zbuf);
+       }
+
+       if(zbuf_width != cubemap->get_width() || zbuf_height != cubemap->get_height()) {
+               zbuf_width = cubemap->get_width();
+               zbuf_height = cubemap->get_height();
+               glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, zbuf_width, zbuf_height);
+       }
+
+       glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                       GL_TEXTURE_CUBE_MAP_POSITIVE_X + face_idx, cubemap->get_id(), 0);
+}