libmoldeo (Moldeo 1.0 Core)  1.0
libmoldeo is the group of objects and functions that executes the basic operations of Moldeo 1.0 Platform.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
moFBO.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 
3  moFBO.cpp
4 
5  ****************************************************************************
6  * *
7  * This source is free software; you can redistribute it and/or modify *
8  * it under the terms of the GNU General Public License as published by *
9  * the Free Software Foundation; either version 2 of the License, or *
10  * (at your option) any later version. *
11  * *
12  * This code is distributed in the hope that it will be useful, but *
13  * WITHOUT ANY WARRANTY; without even the implied warranty of *
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
15  * General Public License for more details. *
16  * *
17  * A copy of the GNU General Public License is available on the World *
18  * Wide Web at <http://www.gnu.org/copyleft/gpl.html>. You can also *
19  * obtain it by writing to the Free Software Foundation, *
20  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21  * *
22  ****************************************************************************
23 
24  Copyright(C) 2006 Fabricio Costa
25 
26  Authors:
27  Fabricio Costa
28  Andrés Colubri
29 
30 *******************************************************************************/
31 
32 #include "moFBO.h"
33 
34 #include "moArray.h"
36 
37 //===========================================
38 //
39 // moFBO
40 //
41 //===========================================
42 
43 moFBO::moFBO()
44 {
45  m_gl = NULL;
46  m_fbo = 0;
47  m_num_color_attach_points = 0;
48  m_has_depth_buffer = m_has_stencil_buffer = false;
49  m_width = 0;
50  m_height = 0;
51 }
52 
54 {
55  Finish();
56 }
57 
59 {
60  m_gl = p_gl;
61  glGenFramebuffersEXT(1, &m_fbo);
62  m_num_color_attach_points = 0;
63  m_has_depth_buffer = m_has_stencil_buffer = false;
64  m_width = 0;
65  m_height = 0;
66  InitAttachPointsArray();
67  return (m_gl!=NULL);
68 }
69 
71 {
72  if (m_has_depth_buffer && m_has_stencil_buffer)
73  {
74  glDeleteTextures(1, &m_DepthStencilTex);
75  m_has_depth_buffer = false;
76  m_has_stencil_buffer = false;
77  }
78  if (0 < m_fbo)
79  {
80  glDeleteFramebuffersEXT(1, &m_fbo);
81  m_fbo = 0;
82  }
83  return true;
84 }
85 
87 {
88 #ifndef OPENGLESV2
89  if (!m_has_depth_buffer && !m_has_stencil_buffer && (0 < m_width) && (0 < m_height))
90  {
91  glGenTextures(1, &m_DepthStencilTex);
92  glBindTexture(GL_TEXTURE_2D, m_DepthStencilTex);
93  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
94  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT,
95  m_width, m_height, 0, GL_DEPTH_STENCIL_EXT,
96  GL_UNSIGNED_INT_24_8_EXT, NULL);
97 
98  Bind();
99 
100  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
101  GL_DEPTH_ATTACHMENT_EXT,
102  GL_TEXTURE_2D, m_DepthStencilTex, 0);
103 
104  Unbind();
105 
106  m_has_depth_buffer = true;
107  m_has_stencil_buffer = true;
108  return true;
109  }
110  else return false;
111 #endif
112 }
113 
115 {
116  m_gl->SaveFBOState();
117  m_gl->SetCurrentFBO(m_fbo);
118 }
119 
121 {
122  m_gl->RestoreFBOState();
123 }
124 
125 void moFBO::SetReadTexture(MOuint p_attach_point)
126 {
127  if (p_attach_point < m_num_color_attach_points)
128  m_gl->SetCurrentReadBuffer(m_attach_points_array[p_attach_point]);
129 }
130 
131 void moFBO::SetDrawTexture(MOuint p_attach_point)
132 {
133  if (p_attach_point < m_num_color_attach_points)
134  m_gl->SetCurrentDrawBuffer(m_attach_points_array[p_attach_point]);
135 }
136 
137 void moFBO::SetReadTexture(MOuint p_glid, MOuint p_width, MOuint p_height, const moTexParam& p_param, MOuint p_attach_point)
138 {
139  MOint i = GetColorAttachPointIndex(p_glid);
140  if (i == -1) AttachTexture(p_width, p_height, p_param, p_glid, p_attach_point);
141  else p_attach_point = (MOuint)i;
142  SetReadTexture(p_attach_point);
143 }
144 
145 void moFBO::SetDrawTexture(MOuint p_glid, MOuint p_width, MOuint p_height, const moTexParam& p_param, MOuint p_attach_point)
146 {
147  MOint i = GetColorAttachPointIndex(p_glid);
148  if (i == -1) AttachTexture(p_width, p_height, p_param, p_glid, p_attach_point);
149  else p_attach_point = (MOuint)i;
150  SetDrawTexture(p_attach_point);
151 }
152 
154 {
155  if (p_attach_point < m_num_color_attach_points)
156  return m_attach_points_array[p_attach_point];
157  else return -1;
158 }
159 
161 {
162  if (p_attach_point < m_num_color_attach_points)
163  return m_tex_glid_array[p_attach_point];
164  else return -1;
165 }
166 
168 {
169  for (MOuint i = 0; i < m_num_color_attach_points; i++)
170  if (m_tex_glid_array[i] == p_glid) return i;
171  return -1;
172 }
173 
174 MOuint moFBO::AddTexture(MOuint p_width, MOuint p_height, const moTexParam& p_param, MOuint p_glid, MOuint &p_attach_point)
175 {
176  bool valid_tex;
177  MOuint status;
178  if (m_num_color_attach_points < MO_MAX_COLOR_ATTACHMENTS_EXT)
179  {
180  if (m_num_color_attach_points == 0)
181  {
182  m_target = p_param.target;
183  m_internal_format = p_param.internal_format;
184  m_width = p_width;
185  m_height = p_height;
186  valid_tex = true;
187  }
188  else
189  {
190  valid_tex = (m_target == p_param.target) && (m_internal_format == p_param.internal_format) &&
191  (m_width == p_width) && (m_height == p_height);
192  }
193 
194  if (!valid_tex)
195  {
197  return status;
198  }
199 
200  Bind();
201  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
202  m_attach_points_array[m_num_color_attach_points],
203  m_target, p_glid, 0);
204  status = CheckStatus();
205  Unbind();
206 
207  if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
208  {
209  m_tex_glid_array[m_num_color_attach_points] = p_glid;
210  p_attach_point = m_num_color_attach_points;
211  m_num_color_attach_points++;
212  }
213  }
214  else status = MO_FRAMEBUFFER_FULL;
215  return status;
216 }
217 
218 MOuint moFBO::AttachTexture(MOuint p_width, MOuint p_height, const moTexParam& p_param, MOuint p_glid, MOuint p_attach_point)
219 {
220  bool valid_tex;
221  MOuint status;
222  if (p_attach_point < MO_MAX_COLOR_ATTACHMENTS_EXT)
223  {
224  if (m_num_color_attach_points == 0)
225  {
226  m_target = p_param.target;
227  m_internal_format = p_param.internal_format;
228  m_width = p_width;
229  m_height = p_height;
230  valid_tex = true;
231  }
232  else
233  {
234  valid_tex = (m_target == p_param.target) && (m_internal_format == p_param.internal_format) &&
235  (m_width == p_width) && (m_height == p_height);
236  }
237 
238  if (!valid_tex)
239  {
241  return status;
242  }
243 
244  Bind();
245  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
246  m_attach_points_array[p_attach_point],
247  m_target, p_glid, 0);
248  status = CheckStatus();
249  Unbind();
250 
251  if (status == GL_FRAMEBUFFER_COMPLETE_EXT)
252  {
253  m_tex_glid_array[p_attach_point] = p_glid;
254  }
255  }
256  else status = MO_FRAMEBUFFER_FULL;
257  return status;
258 }
259 
261 {
262  if (m_num_color_attach_points > 0)
263  {
264  Bind();
265  for (MOuint i = 0; i < m_num_color_attach_points; i++)
266  glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
267  m_attach_points_array[i],
268  m_target, 0, 0);
269  Unbind();
270  }
271 }
272 
274 {
275  if (MODebug2 != NULL) MODebug2->Log("moFBO::CheckStatus > Framebuffer status: ");
276  GLenum status;
277  status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
278  switch (status)
279  {
280  case GL_FRAMEBUFFER_COMPLETE_EXT:
281  if (MODebug2 != NULL) MODebug2->Log("moFBO::CheckStatus > GL_FRAMEBUFFER_COMPLETE_EXT");
282  break;
283  case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
284  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT");
285  break;
286  case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
287  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT");
288  break;
289 // case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
290 // if (MODebug2 != NULL) MODebug2->Push("GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT");
291 // break;
292  case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
293  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT");
294  break;
295 #ifndef OPENGLESV2
296  case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
297  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT");
298  break;
299  case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
300  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT");
301  break;
302  case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
303  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT");
304  break;
305 #endif
306  case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
307  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > GL_FRAMEBUFFER_UNSUPPORTED_EXT");
308  break;
309  default:
310  if (MODebug2 != NULL) MODebug2->Error("moFBO::CheckStatus > Unknown error");
311  break;
312  }
313  return status;
314 }
315 
316 MOboolean moFBO::IsValidTexture(MOuint p_width, MOuint p_height, const moTexParam& p_param) const
317 {
318  if (m_num_color_attach_points == 0) return true;
319  else
320  return (m_target == p_param.target) && (m_internal_format == p_param.internal_format) &&
321  (m_width == p_width) && (m_height == p_height);
322 }
323 
324 void moFBO::InitAttachPointsArray()
325 {
326  for (MOuint i = 0; i < MO_MAX_COLOR_ATTACHMENTS_EXT; i++)
327  m_attach_points_array[i] = GL_COLOR_ATTACHMENT0_EXT + i;
328 }
329 
Parámetros internos de una textura.
Definition: moTypes.h:543
void Error(moText p_text)
Anuncia y registra un error.
Definition: moAbstract.cpp:79
GLint internal_format
Definition: moTypes.h:546
void RestoreFBOState()
MOint GetColorAttachPointIndex(MOuint p_glid)
Definition: moFBO.cpp:167
virtual ~moFBO()
Definition: moFBO.cpp:53
void ClearAttachements()
Definition: moFBO.cpp:260
#define MOboolean
Definition: moTypes.h:385
MOuint AttachTexture(MOuint p_width, MOuint p_height, const moTexParam &p_param, MOuint p_glid, MOuint p_attach_point)
Definition: moFBO.cpp:218
virtual MOboolean Init()
Inicializa el objeto.
Definition: moAbstract.cpp:141
Definition: moFBO.h:60
void SetDrawTexture(MOuint p_attach_point)
Definition: moFBO.cpp:131
void SaveFBOState()
void Unbind()
Definition: moFBO.cpp:120
void Log(moText p_text)
Escribe un mensaje en el archivo de registro (log)
Definition: moAbstract.cpp:123
void SetCurrentDrawBuffer(MOint p_buffer)
void SetCurrentReadBuffer(MOint p_buffer)
MOuint AddTexture(MOuint p_width, MOuint p_height, const moTexParam &p_param, MOuint p_glid, MOuint &p_attach_point)
Definition: moFBO.cpp:174
#define MO_MAX_COLOR_ATTACHMENTS_EXT
Definition: moFBO.h:46
void SetCurrentFBO(MOuint m_fbo)
MOboolean IsValidTexture(MOuint p_width, MOuint p_height, const moTexParam &p_param) const
Definition: moFBO.cpp:316
#define MOint
Definition: moTypes.h:388
#define MO_FRAMEBUFFER_INVALID_TEX
Definition: moFBO.h:39
MOboolean AddDepthStencilBuffer()
Definition: moFBO.cpp:86
virtual MOboolean Finish()
Definition: moFBO.cpp:70
MOint GetTextureGLId(MOuint p_attach_point)
Definition: moFBO.cpp:160
MOuint CheckStatus() const
Definition: moFBO.cpp:273
MOint GetColorAttachPoint(MOuint p_attach_point)
Definition: moFBO.cpp:153
manejador de operaciones comunes de Open GL
Definition: moGLManager.h:154
static moDebug * MODebug2
Clase de impresión de errores para depuración
Definition: moAbstract.h:225
GLenum target
Definition: moTypes.h:545
#define MOuint
Definition: moTypes.h:387
#define MO_FRAMEBUFFER_FULL
Definition: moFBO.h:38
void SetReadTexture(MOuint p_attach_point)
Definition: moFBO.cpp:125
moDefineDynamicArray(moFBOArray) moFBO
Definition: moFBO.cpp:35
void Bind()
Definition: moFBO.cpp:114