25 #include "glfFramebufferObject.hh"
26 #include "glfException.hh"
27 #include <OpenGLFramework/Base/glfFBOAttachmentReleaseException.hh>
29 #include <OpenGLFramework/Base/glfCommon.hh>
35 numSimultaneousDrawBuffers_(0),
36 listOfSimultaneousDrawBuffers_(NULL),
37 FramebufferCreated_(false)
53 delete listOfSimultaneousDrawBuffers_;
55 if (FramebufferCreated_){
56 glDeleteFramebuffersEXT(1, &id_);
62 if(!GLEW_EXT_framebuffer_object) {
63 GLF_THROW_EXCEPTION(
"Framebuffer objects are not supported");
67 glGenFramebuffersEXT(1, &id_);
68 FramebufferCreated_=
true;
71 GLF_THROW_ON_OPENGL_ERROR;
75 GLenum attachmentPoint,
76 int attachedMipMapLevel,
77 int zSlice, GLenum cubeMapSide)
84 switch(textureTarget) {
86 glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
87 GL_TEXTURE_1D, textureID, attachedMipMapLevel);
90 case GL_TEXTURE_RECTANGLE_NV :
91 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
92 textureTarget, textureID, attachedMipMapLevel);
95 glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
96 GL_TEXTURE_3D, textureID,
97 attachedMipMapLevel, zSlice);
99 case GL_TEXTURE_CUBE_MAP :
100 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
101 cubeMapSide, textureID, attachedMipMapLevel);
104 GLF_THROW_EXCEPTION(
"Texture cannot be attached to framebuffer object");
108 GLF_THROW_ON_OPENGL_ERROR;
112 GLenum attachmentPoint)
115 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
119 GLF_THROW_ON_OPENGL_ERROR;
126 GLint attachmentType;
127 glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
128 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
131 switch(attachmentType) {
133 glFramebufferTexture1DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint,
134 GL_TEXTURE_1D, 0, 0 );
136 case GL_RENDERBUFFER_EXT:
137 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
138 GL_RENDERBUFFER_EXT, 0);
145 GLF_THROW_ON_OPENGL_ERROR;
152 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
156 case GL_FRAMEBUFFER_COMPLETE_EXT:
159 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
160 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n");
162 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
163 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
164 " GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n");
167 #ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
168 case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
169 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
170 "GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT\n");
172 #endif // GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
174 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
175 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
176 "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n");
179 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
180 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
181 <<
"GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n");
184 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
186 glGetIntegerv(GL_DRAW_BUFFER, &answer);
187 if(answer == GL_NONE) {
188 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
189 <<
"GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n"
190 <<
" current draw buffer is set to GL_NONE!");
192 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
193 <<
"GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n"
194 <<
" is any color attachment set to NONE?");
198 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
199 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
200 <<
"GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n"
201 <<
" is any color attachment set to NONE?");
204 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
205 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
206 <<
"GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");
209 #ifdef GL_FRAMEBUFFER_STATUS_ERROR_EXT
210 case GL_FRAMEBUFFER_STATUS_ERROR_EXT:
211 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
212 <<
"GL_FRAMEBUFFER_STATUS_ERROR_EXT\n");
214 #endif // GL_FRAMEBUFFER_STATUS_ERROR_EXT
217 GLF_THROW_EXCEPTION(
"FBO ERROR:\n\t"
218 <<
"Unknown ERROR\n");
226 BIASASSERT(id_ != 0);
228 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id_);
230 if(numSimultaneousDrawBuffers_>0) {
231 glDrawBuffers(numSimultaneousDrawBuffers_, listOfSimultaneousDrawBuffers_);
234 GLF_THROW_ON_OPENGL_ERROR;
239 GLint maxNumberOfSimultaneousBuffers = 0;
240 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxNumberOfSimultaneousBuffers);
241 if(maxNumberOfSimultaneousBuffers < (GLint)drawbuffers.size()) {
242 GLF_THROW_EXCEPTION(
"MRT ERROR : requesting too many drawbuffers max"
243 <<maxNumberOfSimultaneousBuffers);
245 numSimultaneousDrawBuffers_ = drawbuffers.size();
246 delete[] listOfSimultaneousDrawBuffers_;
247 listOfSimultaneousDrawBuffers_ =
new GLenum[numSimultaneousDrawBuffers_];
248 for(
unsigned int i=0; i<drawbuffers.size(); i++)
249 listOfSimultaneousDrawBuffers_[i] = drawbuffers[i];
255 delete[] listOfSimultaneousDrawBuffers_;
256 listOfSimultaneousDrawBuffers_ = NULL;
257 numSimultaneousDrawBuffers_ = 0;
263 GLint maxbuffers = 0;
264 glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxbuffers);
273 Blit_(source, target, GL_COLOR_BUFFER_BIT, colorFilter);
280 GLbitfield bufferMask)
282 Blit_(source, target, bufferMask, GL_NEAREST);
286 void glfFramebufferObject::
289 GLbitfield bufferMask,
294 GLint widthSrc,heightSrc;
295 source->
GetSize(widthSrc,heightSrc);
296 GLint widthTrgt,heightTrgt;
297 target->
GetSize(widthTrgt,heightTrgt);
299 glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source->id_);
300 glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, target->id_);
301 glBlitFramebufferEXT(0,0,widthSrc,heightSrc,0,0,widthTrgt,heightTrgt, bufferMask, colorFilter);
302 GLF_THROW_ON_OPENGL_ERROR;
309 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &width);
310 glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &height);
312 GLF_THROW_ON_OPENGL_ERROR;
void AttachTexture(const glfTexture &texture, GLenum attachmentPoint, int attachedMipMapLevel=0, int zSlice=0, GLenum cubeMapSide=0)
Attaches a texture to an attachment point which can be.
static GLint MaxRenderTargets()
void SetDrawBuffers(const std::vector< GLenum > &drawbuffers)
void ReleaseAttachment(GLenum attachmentPoint)
Removes an attachment from the framebuffer object.
void AttachRenderbuffer(const glfRenderbuffer &renderbuffer, GLenum attachmentPoint)
Attaches a renderbuffer to the framebuffer object.
GLuint GetTextureID() const
Returns the OpenGL texture id.
Class is thrown when an release of some FBO attachment point is not possible.
void CheckComplete() const
Checks whether the framebuffer object is supported in its current state.
void GetSize(GLint &width, GLint &height)
static void Blit(glfFramebufferObject *source, glfFramebufferObject *target, GLbitfield bufferMask)
Blits the attachments from source to target, requires EXT_framebuffer_blit extension.
virtual void Bind() const
Makes this render target the currently used render target.
GLuint GetRenderbufferID() const
Returns the OpenGL id of the renderbuffer.
GLenum GetTextureTarget() const
Returns the OpenGL texture target.
static void BlitColorBuffer(glfFramebufferObject *source, glfFramebufferObject *target, GLenum colorFilter)
Blits the attachments from source to target, requires EXT_framebuffer_blit extension.
void Create()
Creates the framebuffer object.