Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
glfFramebufferObject.cpp
1 /*
2  This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4  Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10  BIAS is free software; you can redistribute it and/or modify
11  it under the terms of the GNU Lesser General Public License as published by
12  the Free Software Foundation; either version 2.1 of the License, or
13  (at your option) any later version.
14 
15  BIAS is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU Lesser General Public License for more details.
19 
20  You should have received a copy of the GNU Lesser General Public License
21  along with BIAS; if not, write to the Free Software
22  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23  */
24 
25 #include "glfFramebufferObject.hh"
26 #include "glfException.hh"
27 #include <OpenGLFramework/Base/glfFBOAttachmentReleaseException.hh>
28 
29 #include <OpenGLFramework/Base/glfCommon.hh>
30 
31 using namespace BIAS;
32 
34  id_(0),
35  numSimultaneousDrawBuffers_(0),
36  listOfSimultaneousDrawBuffers_(NULL),
37  FramebufferCreated_(false)
38 {
39 }
40 
42 glfFramebufferObject::operator=(const glfFramebufferObject& fbo)
43 {
44  return (*this);
45 }
46 
47 
49 {}
50 
52 {
53  delete listOfSimultaneousDrawBuffers_;
54 
55  if (FramebufferCreated_){
56  glDeleteFramebuffersEXT(1, &id_);
57  }
58 }
59 
61 {
62  if(!GLEW_EXT_framebuffer_object) {
63  GLF_THROW_EXCEPTION("Framebuffer objects are not supported");
64  }
65 
66  if(id_ == 0) {
67  glGenFramebuffersEXT(1, &id_);
68  FramebufferCreated_=true;
69  }
70 
71  GLF_THROW_ON_OPENGL_ERROR;
72 }
73 
75  GLenum attachmentPoint,
76  int attachedMipMapLevel,
77  int zSlice, GLenum cubeMapSide)
78 {
79  Bind();
80 
81  GLuint textureID = texture.GetTextureID();
82  GLenum textureTarget = texture.GetTextureTarget();
83 
84  switch(textureTarget) {
85  case GL_TEXTURE_1D :
86  glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
87  GL_TEXTURE_1D, textureID, attachedMipMapLevel);
88  break;
89  case GL_TEXTURE_2D :
90  case GL_TEXTURE_RECTANGLE_NV :
91  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
92  textureTarget, textureID, attachedMipMapLevel);
93  break;
94  case GL_TEXTURE_3D :
95  glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
96  GL_TEXTURE_3D, textureID,
97  attachedMipMapLevel, zSlice);
98  break;
99  case GL_TEXTURE_CUBE_MAP :
100  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
101  cubeMapSide, textureID, attachedMipMapLevel);
102  break;
103  default:
104  GLF_THROW_EXCEPTION("Texture cannot be attached to framebuffer object");
105  break;
106  }
107 
108  GLF_THROW_ON_OPENGL_ERROR;
109 }
110 
112  GLenum attachmentPoint)
113 {
114  Bind();
115  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
116  attachmentPoint,
117  GL_RENDERBUFFER_EXT,
118  renderbuffer.GetRenderbufferID());
119  GLF_THROW_ON_OPENGL_ERROR;
120 }
121 
122 void glfFramebufferObject::ReleaseAttachment(GLenum attachmentPoint)
123 {
124  Bind();
125 
126  GLint attachmentType;
127  glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
128  GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
129  &attachmentType);
130 
131  switch(attachmentType) {
132  case GL_TEXTURE:
133  glFramebufferTexture1DEXT( GL_FRAMEBUFFER_EXT, attachmentPoint,
134  GL_TEXTURE_1D, 0, 0 );
135  break;
136  case GL_RENDERBUFFER_EXT:
137  glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachmentPoint,
138  GL_RENDERBUFFER_EXT, 0);
139  break;
140  default:
141  throw glfFBOAttachmentReleaseException(__FILE__, __LINE__, "nothing detachable attached");
142  break;
143  }
144 
145  GLF_THROW_ON_OPENGL_ERROR;
146 }
147 
149 {
150  Bind();
151 
152  GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
153 
154  switch(status) {
155 
156  case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK
157  return;
158 
159  case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
160  GLF_THROW_EXCEPTION( "FBO ERROR:\n\t GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n");
161  break;
162  case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
163  GLF_THROW_EXCEPTION( "FBO ERROR:\n\t"
164  " GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n");
165  break;
166 
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");
171  break;
172 #endif // GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
173 
174  case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
175  GLF_THROW_EXCEPTION( "FBO ERROR:\n\t"
176  "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n");
177  break;
178 
179  case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
180  GLF_THROW_EXCEPTION( "FBO ERROR:\n\t"
181  << "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n");
182  break;
183 
184  case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
185  GLint answer;
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!");
191  } else {
192  GLF_THROW_EXCEPTION( "FBO ERROR:\n\t"
193  << "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n"
194  <<" is any color attachment set to NONE?");
195  }
196  break;
197 
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?");
202  break;
203 
204  case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
205  GLF_THROW_EXCEPTION( "FBO ERROR:\n\t"
206  << "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n");
207  break;
208 
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");
213  break;
214 #endif // GL_FRAMEBUFFER_STATUS_ERROR_EXT
215 
216  default:
217  GLF_THROW_EXCEPTION( "FBO ERROR:\n\t"
218  << "Unknown ERROR\n");
219  break;
220  }
221 }
222 
223 
225 {
226  BIASASSERT(id_ != 0);
227 
228  glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id_);
229  //last call changed the draw buffer to GL_COLOR_ATTACHMENT0_EXT
230  if(numSimultaneousDrawBuffers_>0) {
231  glDrawBuffers(numSimultaneousDrawBuffers_, listOfSimultaneousDrawBuffers_);
232  }
233 
234  GLF_THROW_ON_OPENGL_ERROR;
235 }
236 
237 void glfFramebufferObject::SetDrawBuffers(const std::vector<GLenum>& drawbuffers)
238 {
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);
244  } else {
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];
250  }
251 }
252 
254 {
255  delete[] listOfSimultaneousDrawBuffers_;
256  listOfSimultaneousDrawBuffers_ = NULL;
257  numSimultaneousDrawBuffers_ = 0;
258 }
259 
260 GLint
262 {
263  GLint maxbuffers = 0;
264  glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxbuffers);
265  return maxbuffers;
266 }
267 
270  glfFramebufferObject* target,
271  GLenum colorFilter)
272 {
273  Blit_(source, target, GL_COLOR_BUFFER_BIT, colorFilter);
274 }
275 
276 
279  glfFramebufferObject* target,
280  GLbitfield bufferMask)
281 {
282  Blit_(source, target, bufferMask, GL_NEAREST);
283 }
284 
285 
286 void glfFramebufferObject::
287 Blit_(glfFramebufferObject* source,
288  glfFramebufferObject* target,
289  GLbitfield bufferMask,
290  GLenum colorFilter)
291 {
292 
293  //do this before because Bind() is called!!
294  GLint widthSrc,heightSrc;
295  source->GetSize(widthSrc,heightSrc);
296  GLint widthTrgt,heightTrgt;
297  target->GetSize(widthTrgt,heightTrgt);
298 
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;
303 }
304 
306 GetSize(GLint& width, GLint& height)
307 {
308  Bind();
309  glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_WIDTH_EXT, &width);
310  glGetRenderbufferParameterivEXT(GL_RENDERBUFFER_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &height);
311 
312  GLF_THROW_ON_OPENGL_ERROR;
313 }
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.
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.
Definition: glfTexture.hh:144
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.
Base class for textures.
Definition: glfTexture.hh:42
GLuint GetRenderbufferID() const
Returns the OpenGL id of the renderbuffer.
GLenum GetTextureTarget() const
Returns the OpenGL texture target.
Definition: glfTexture.hh:150
static void BlitColorBuffer(glfFramebufferObject *source, glfFramebufferObject *target, GLenum colorFilter)
Blits the attachments from source to target, requires EXT_framebuffer_blit extension.
The renderbuffer.
void Create()
Creates the framebuffer object.