00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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 }