gl_framebuffer.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2008 by Kutumov Alexey                                  *
00003  *   ru.pixel@gmail.com                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00033 #include "gl_graphic_core/gl_framebuffer.h"
00034 #include "gl_graphic_core/gl_graphic_core.h"
00035 #include "gl_graphic_core/gl_texture.h"
00036 
00037 #include "gpucalc/log_manager.h"
00038 #include "gpucalc/string_util.h"
00039 #include "gpucalc/application.h"
00040 #include "gpucalc/data.h"
00041 
00042 
00043 namespace gpucalc
00044 {
00045  void GLFrameBuffer::initialize()
00046  {
00047   glGenFramebuffersEXT(1, &mGLFrameBufferID);
00048   LogManager::getSingleton().logMessage(this, "Successfully initialized.", LML_Trivial);
00049  }
00050 
00051 
00052  GLint GLFrameBuffer::getFirstFreeAttachment() const
00053  {
00054   for (GLint i = 0; i < mMaxNumberOfAttachment; ++i)
00055   {
00056    if (mAttachmentList[i] == 0)
00057    {
00058     return i;
00059    }
00060   }
00061 
00062   Except<ERR_ITEM_NOT_FOUND>(this, "this framebuffer does not have any free attachment point.", "GLFrameBuffer::getFirstFreeAttachment()", __FILE__, __LINE__);
00063   return mMaxNumberOfAttachment;
00064  }
00065 
00066 
00067  GLint GLFrameBuffer::getIndexByTexture(const Texture * texture) const
00068  {
00069   for (GLint i = 0; i < mMaxNumberOfAttachment; ++i)
00070   {
00071    if (mAttachmentList[i] == texture)
00072    {
00073     return i;
00074    }
00075   }
00076   return mMaxNumberOfAttachment;
00077  }
00078 
00079 
00080  GLint GLFrameBuffer::getIndexByTextureName(const std::string & TextureName) const
00081  {
00082   for (GLint i = 0; i < mMaxNumberOfAttachment; ++i)
00083   {
00084    if (mAttachmentList[i] != 0)
00085    {
00086     if (mAttachmentList[i]->getObjectName() == TextureName)
00087     {
00088      return i;
00089     }
00090    }
00091   }
00092   return mMaxNumberOfAttachment;
00093  }
00094 
00095 
00096  void GLFrameBuffer::attach(const Texture * texture)
00097  {
00098   GLint Index = getFirstFreeAttachment();
00099   mAttachmentList[Index] = texture;
00100 
00101 
00102   const GLTexture * gl_texture = dynamic_cast<const GLTexture *>(texture);
00103   
00104   glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + Index,
00105    gl_texture->getGLTextureTarget(), gl_texture->getGLTextureID(), 0);
00106 
00107   this->mGLFrameBufferWidth = gl_texture->getSizeX();
00108   this->mGLFrameBufferHeight = gl_texture->getSizeY();
00109   this->mGLFrameBufferFormat = gl_texture->getGLTextureFormat();
00110   this->mGLFrameBufferType = gl_texture->getGLTextureType();
00111 
00112   this->checkErrors("GLFrameBuffer::attach()");
00113   mDefaultGraphicCore->checkErrors("GLFrameBuffer::attach()");
00114  }
00115 
00116 
00117  void GLFrameBuffer::detach(const Texture * texture)
00118  {
00119   GLint Index = 0;
00120   for ( ; Index < mMaxNumberOfAttachment; ++Index)
00121   {
00122    if (mAttachmentList[Index] == texture)
00123    {
00124     mAttachmentList[Index] = 0;
00125    }
00126   }
00127   if (Index < mMaxNumberOfAttachment)
00128   {
00129    glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + Index,
00130     dynamic_cast<const GLTexture *>(texture)->getGLTextureTarget(), 0, 0);
00131   }
00132  }
00133 
00134 
00135  void GLFrameBuffer::drawBuffer(const Texture * RenderTarget)
00136  {
00138   
00139   LogManager::getSingleton().logMessage(this, "Starting rendering into texture(s)...", LML_Trivial);
00140   
00141   GLint Index = getIndexByTexture(RenderTarget);
00142   if (Index == mMaxNumberOfAttachment)
00143   {
00144    attach(RenderTarget);
00145   }
00146   Index = getIndexByTexture(RenderTarget);
00147 
00148   glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT + Index);
00149   this->checkErrors("GLFrameBuffer::drawBuffer");
00150   mDefaultGraphicCore->checkErrors("GLFrameBuffer::drawBuffer");
00151  }
00152 
00153 
00154  void GLFrameBuffer::getData(Data & to, const Texture * from)
00155  {
00156   LogManager::getSingleton().logMessage(this, "Reading data from framebuffer...", LML_Trivial);
00157 
00158   GLint Index = getIndexByTexture(from);
00159   glReadBuffer(GL_COLOR_ATTACHMENT0_EXT + Index);
00160   glReadPixels(0, 0, this->mGLFrameBufferWidth, this->mGLFrameBufferHeight,
00161    this->mGLFrameBufferFormat, this->mGLFrameBufferType, to.pointer());
00162 
00163   Application::getSingleton().getDefaultGraphicCore()->checkErrors("GLFrameBuffer::getDataFromRenderedTexture");
00164   this->checkErrors("GLFrameBuffer::getDataFromRenderedTexture");
00165  }
00166 
00167 
00168  void GLFrameBuffer::checkErrors(const std::string & where)
00169  {
00170   GLenum status;
00171   status = (GLenum) glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00172   switch (status)
00173   {
00174    case GL_FRAMEBUFFER_COMPLETE_EXT:
00175     return;
00176 
00177    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
00178     Except<ERR_RENDERINGAPI_ERROR>(this, "Framebuffer incomplete, incomplete attachment.", where, __FILE__, __LINE__);
00179     return;
00180     
00181    case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00182     Except<ERR_RENDERINGAPI_ERROR>(this, "Unsupported framebuffer format.", where, __FILE__, __LINE__);
00183     return;
00184     
00185    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00186     Except<ERR_RENDERINGAPI_ERROR>(this, "Framebuffer incomplete, missing attachment.", where, __FILE__, __LINE__);
00187     return;
00188     
00189    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00190     Except<ERR_RENDERINGAPI_ERROR>(this, "Framebuffer incomplete, attached images must have same dimensions.", where, __FILE__, __LINE__);
00191     return;
00192     
00193    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00194     Except<ERR_RENDERINGAPI_ERROR>(this, "Framebuffer incomplete, attached images must have same format.", where, __FILE__, __LINE__);
00195     return;
00196     
00197    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00198     Except<ERR_RENDERINGAPI_ERROR>(this, "Framebuffer incomplete, missing draw buffer.", where, __FILE__, __LINE__);
00199     return;
00200     
00201    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00202     Except<ERR_RENDERINGAPI_ERROR>(this, "Framebuffer incomplete, missing read buffer.", where, __FILE__, __LINE__);
00203     return;
00204     
00205    default:
00206     Except<ERR_RENDERINGAPI_ERROR>(this, "Unknown error.", where, __FILE__, __LINE__);
00207   }
00208  }
00209 }

Generated on Thu Mar 5 22:36:42 2009 for gpucalc by  doxygen 1.5.6