raw-framebuffer.cpp

Go to the documentation of this file.
00001 /*
00002  * raw-framebuffer.cpp
00003  *
00004  * Copyright (C) 2010  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Simple test of OpenGL framebuffer rendering.  Uses raw OpenGL APIs directly
00008  * rather than the glut::Framebuffer object.
00009  */
00010 
00011 // includes --------------------------------------------------------------------
00012 #include "glut-demo/glut-demo.h"
00013 
00014 
00015 ////////////////////////////////////////////////////////////////////////////////
00016 //
00017 //      static helper methods
00018 //
00019 ////////////////////////////////////////////////////////////////////////////////
00020 
00021 
00022 class TestHost : public glut::DemoHost {
00023 public:
00024         ~TestHost(void) throw() { }
00025 
00026         // glut::DemoHost class interface methods ------------------------------
00027         void onInit(void) {
00028                         // framebuffer dimensions
00029                         m_width = 240;
00030                         m_height = m_width;
00031 
00032                         // create framebuffer
00033                         glGenFramebuffersEXT(1, (GLuint *) &m_fboId);
00034                         DPRINTF("Created framebuffer id=%d", m_fboId);
00035                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId);
00036 
00037                         // create renderbuffer for depth field
00038                         int dbId;
00039                         glGenRenderbuffersEXT(1, (GLuint *) &dbId);
00040                         DPRINTF("Created render buffer id=%d", dbId);
00041                         glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, dbId);
00042                         glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT,
00043                             GL_DEPTH_COMPONENT, m_width, m_height);
00044                         glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
00045                             GL_RENDERBUFFER_EXT, dbId);
00046 
00047                         // create texture as a render target
00048                         glGenTextures(1, (GLuint *) &m_texId);
00049                         DPRINTF("Created texture id=%d", m_texId);
00050                         glBindTexture(GL_TEXTURE_2D, m_texId);
00051                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00052                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00053                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00054                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00055 
00056                         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_width, m_height,
00057                             0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
00058                         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
00059                             GL_TEXTURE_2D, m_texId, 0);
00060 
00061                         // verify happy
00062                         GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00063                         ASSERT_THROW(GL_FRAMEBUFFER_COMPLETE_EXT == status,
00064                             "OpenGL framebuffer not complete?  status=" << status);
00065 
00066                         // unbind for now
00067                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00068                 }
00069 
00070         void display3D(IN const glut::render_context_t& rc,
00071                                 IN glut::RenderQueue * rq) {
00072 
00073                         static float s_rotate = 0.0;
00074                         s_rotate += 0.67;
00075 
00076                         // separate view context for texture
00077                         glut::render_context_t rc2;
00078                         rc2.viewer.setPosition(point3d_t(0, 0, -10.0));
00079                         glMatrixMode(GL_MODELVIEW);
00080                         glPushMatrix();
00081                         glMatrixMode(GL_PROJECTION);
00082                         glPushMatrix();
00083                         rc2.camera.setAspect(m_width, m_height);
00084                         glut::setOpenGLProjection(rc2.camera);
00085                         glut::setOpenGLViewer(rc2.viewer);
00086                         glRotatef(s_rotate, 0, 1, 0);
00087 
00088                         // bind to the framebuffer for rendering
00089                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId);
00090                         glPushAttrib(GL_VIEWPORT_BIT);
00091                         glViewport(0, 0, m_width, m_height);
00092 
00093                         // render to framebuffer
00094                         glEnable(GL_BLEND);
00095                         glBlendFunc(GL_SRC_ALPHA, GL_ONE);
00096                         glClearColor(0.0, 0.0, 0.0, 0.0);
00097                         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00098                         glColor4f(1.0, 0.0, 1.0, 0.8);
00099                         glEnable(GL_COLOR_MATERIAL);
00100                         glutSolidSphere(1.5, 12, 12);
00101                         glDisable(GL_COLOR_MATERIAL);
00102                         glDisable(GL_BLEND);
00103 
00104                         // clean up after framebuffer
00105                         glPopAttrib();
00106                         glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00107 
00108                         // restore modelview matrix
00109                         glMatrixMode(GL_PROJECTION);
00110                         glPopMatrix();
00111                         glMatrixMode(GL_MODELVIEW);
00112                         glPopMatrix();
00113 
00114                         // add to render queue
00115                         glut::poly_request_t * pr = rq->grabRequestSlot();
00116                         if (!pr) {
00117                                 DPRINTF("No available slots?");
00118                                 return;
00119                         }
00120 
00121                         // get transform
00122                         matrix4_t T;
00123                         glut::getModelViewMatrix(T);
00124 
00125                         pr->nVertices = 4;
00126                         pr->textureId = m_texId;
00127                         pr->normal.set(0, 0, -1);
00128 
00129                         pr->u[0] = 0;
00130                         pr->v[0] = 0;
00131                         pr->vertex[0] = T * point3d_t(-1, -1, -1);
00132 
00133                         pr->u[1] = 0;
00134                         pr->v[1] = 1;
00135                         pr->vertex[1] = T * point3d_t(-1,  1, -1);
00136 
00137                         pr->u[2] = 1;
00138                         pr->v[2] = 1;
00139                         pr->vertex[2] = T * point3d_t( 1,  1, -1);
00140 
00141                         pr->u[3] = 1;
00142                         pr->v[3] = 0;
00143                         pr->vertex[3] = T * point3d_t( 1, -1, -1);
00144                 }
00145 
00146 private:
00147         // private member data -------------------------------------------------
00148         int             m_fboId;
00149         int             m_texId;
00150         int             m_width;
00151         int             m_height;
00152 };
00153 
00154 
00155 
00156 ////////////////////////////////////////////////////////////////////////////////
00157 //
00158 //      entry point
00159 //
00160 ////////////////////////////////////////////////////////////////////////////////
00161 
00162 int
00163 main
00164 (
00165 IN int argc,
00166 IN const char * argv[]
00167 )
00168 {
00169         try {
00170                 smart_ptr<glut::DemoHost> host = new TestHost;
00171                 ASSERT(host, "out of memory");
00172                 glut::startDemo(argc, argv, "Framebuffer Demo", host);
00173 
00174         } catch (std::exception& e) {
00175                 DPRINTF("Exception: %s", e.what());
00176                 return 1;
00177         }
00178 
00179         // don't ever get here
00180         return 0;
00181 }
00182