1 /****************************************************************************
2 * Render Radiance Scaling *
3 * Meshlab's plugin *
4 * *
5 * Copyright(C) 2010 *
6 * Vergne Romain, Dumas Olivier *
7 * INRIA - Institut Nationnal de Recherche en Informatique et Automatique *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 #include "framebufferObject.h"
24 #include <iostream>
25 #include <assert.h>
26
27 using namespace std;
28
29 std::vector<GLenum> _buffers;
30
FramebufferObject()31 FramebufferObject::FramebufferObject()
32 : fbo_id(0) {
33 glGenFramebuffersEXT(1,&fbo_id);
34 }
35
~FramebufferObject()36 FramebufferObject::~FramebufferObject() {
37 glDeleteFramebuffersEXT(1,&fbo_id);
38 }
39
attachTexture(GLenum tex_target,GLuint tex_id,GLenum attachment,int mip_level,int z_slice)40 void FramebufferObject::attachTexture(GLenum tex_target,GLuint tex_id,
41 GLenum attachment,int mip_level,int z_slice) {
42 unbindCurrentBindThis();
43
44 glBindTexture(tex_target,tex_id);
45
46 if(tex_target==GL_TEXTURE_1D)
47 glFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,attachment,
48 GL_TEXTURE_1D,tex_id,mip_level);
49 else if(tex_target == GL_TEXTURE_3D)
50 glFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,attachment,
51 GL_TEXTURE_3D,tex_id,mip_level,z_slice);
52 else
53 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,attachment,
54 tex_target,tex_id,mip_level);
55
56 unbindThisBindCurrent();
57 }
58
attachRenderBuffer(GLuint buff_id,GLenum attachment)59 void FramebufferObject::attachRenderBuffer(GLuint buff_id,GLenum attachment) {
60 unbindCurrentBindThis();
61
62 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,attachment,
63 GL_RENDERBUFFER_EXT,buff_id);
64
65 unbindThisBindCurrent();
66 }
67
unattach(GLenum attachment)68 void FramebufferObject::unattach(GLenum attachment) {
69 unbindCurrentBindThis();
70
71 GLenum type = getAttachedType(attachment);
72 switch(type){
73 case GL_RENDERBUFFER_EXT:
74 attachRenderBuffer(0, attachment);
75 break;
76 case GL_TEXTURE:
77 attachTexture(GL_TEXTURE_2D, 0, attachment);
78 break;
79 default:
80 break;
81 }
82
83 unbindThisBindCurrent();
84 }
85
unattachAll()86 void FramebufferObject::unattachAll() {
87 int nb_attachments = getMaxColorAttachments();
88 for(int i=0;i<nb_attachments;i++)
89 unattach(GL_COLOR_ATTACHMENT0_EXT+i);
90 }
91
getMaxColorAttachments()92 GLint FramebufferObject::getMaxColorAttachments() {
93 GLint max_attach = 0;
94 glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &max_attach);
95 return max_attach;
96 }
97
unbindCurrentBindThis()98 void FramebufferObject::unbindCurrentBindThis() {
99 glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT,¤t_fbo_id);
100 if(fbo_id != (GLuint)current_fbo_id)
101 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fbo_id);
102 }
103
unbindThisBindCurrent()104 void FramebufferObject::unbindThisBindCurrent() {
105 if(fbo_id != (GLuint)current_fbo_id)
106 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,(GLuint)current_fbo_id);
107 }
108
isValid()109 bool FramebufferObject::isValid() {
110 unbindCurrentBindThis();
111
112 bool res = false;
113
114 GLenum status;
115 status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
116 switch(status){
117 case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK
118 res = true;
119 break;
120 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
121 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
122 << "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n";
123 res = false;
124 break;
125 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
126 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
127 << "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n";
128 res = false;
129 break;
130 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
131 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
132 << "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT\n";
133 res = false;
134 break;
135 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
136 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
137 << "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT\n";
138 res = false;
139 break;
140 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
141 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
142 << "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n";
143 res = false;
144 break;
145 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
146 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
147 << "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n";
148 res = false;
149 break;
150 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
151 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
152 << "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n";
153 res = false;
154 break;
155 default:
156 cerr << "glift::CheckFramebufferStatus() ERROR:\n\t"
157 << "Unknown ERROR\n";
158 res = false;
159 }
160
161 unbindThisBindCurrent();
162 return res;
163 }
164
getAttachedType(GLenum attachment)165 GLenum FramebufferObject::getAttachedType(GLenum attachment) {
166 // GL_RENDERBUFFER_EXT or GL_TEXTURE
167 unbindCurrentBindThis();
168
169 GLint type = 0;
170 glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
171 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
172 &type);
173 unbindThisBindCurrent();
174
175 return GLenum(type);
176 }
177
getAttachedId(GLenum attachment)178 GLuint FramebufferObject::getAttachedId(GLenum attachment) {
179 unbindCurrentBindThis();
180
181 GLint id = 0;
182 glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
183 GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
184 &id);
185 unbindThisBindCurrent();
186
187 return GLuint(id);
188 }
189
getAttachedMipLevel(GLenum attachment)190 GLint FramebufferObject::getAttachedMipLevel(GLenum attachment) {
191 unbindCurrentBindThis();
192
193 GLint level = 0;
194 glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
195 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
196 &level);
197 unbindThisBindCurrent();
198
199 return level;
200 }
201
getAttachedCubeFace(GLenum attachment)202 GLint FramebufferObject::getAttachedCubeFace(GLenum attachment) {
203 unbindCurrentBindThis();
204
205 GLint level = 0;
206 glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
207 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,
208 &level);
209 unbindThisBindCurrent();
210
211 return level;
212 }
213
getAttachedZSlice(GLenum attachment)214 GLint FramebufferObject::getAttachedZSlice(GLenum attachment) {
215 unbindCurrentBindThis();
216
217 GLint slice = 0;
218 glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
219 GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT,
220 &slice);
221 unbindThisBindCurrent();
222
223 return slice;
224 }
225
buffers(unsigned int i)226 GLenum *FramebufferObject::buffers(unsigned int i) {
227 if(_buffers.empty()) {
228 for(int j=0;j<getMaxColorAttachments();++j) {
229 _buffers.push_back(GL_COLOR_ATTACHMENT0_EXT+j);
230 }
231 }
232
233 assert((int)i<getMaxColorAttachments());
234
235 return &(_buffers[i]);
236 }
237
238