2
* Copyright 2010 Inalogic Inc.
4
* This program is free software: you can redistribute it and/or modify it
5
* under the terms of the GNU Lesser General Public License version 3, as
6
* published by the Free Software Foundation.
8
* This program is distributed in the hope that it will be useful, but
9
* WITHOUT ANY WARRANTY; without even the implied warranties of
10
* MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
11
* PURPOSE. See the applicable version of the GNU Lesser General Public
12
* License for more details.
14
* You should have received a copy of both the GNU Lesser General Public
15
* License version 3 along with this program. If not, see
16
* <http://www.gnu.org/licenses/>
18
* Authored by: Jay Taoko <jay.taoko_AT_gmail_DOT_com>
23
#include "GLResource.h"
24
#include "GLDeviceFactory.h"
25
#include "GLDeviceObjects.h"
26
#include "GLResourceManager.h"
28
#include "GLTextureResourceManager.h"
29
#include "GLVertexResourceManager.h"
30
#include "GLDeviceFrameBufferObject.h"
31
#include "GLTemplatePrimitiveBuffer.h"
32
#include "OpenGLEngine.h"
36
GLenum AttachmentBuffer[] =
38
GL_COLOR_ATTACHMENT0_EXT
39
,GL_COLOR_ATTACHMENT1_EXT
40
,GL_COLOR_ATTACHMENT2_EXT
41
,GL_COLOR_ATTACHMENT3_EXT
44
//////////////////////////////////////////////////////////////////////////
45
// GLFramebufferObject
46
//////////////////////////////////////////////////////////////////////////
48
GLFramebufferObject::GLFramebufferObject()
49
: m_fboId(_GenerateFboId()),
52
// Bind this FBO so that it actually gets created now
57
GLFramebufferObject::~GLFramebufferObject()
59
CHECKGL( glDeleteFramebuffersEXT(1, &m_fboId) );
62
void GLFramebufferObject::Bind()
64
CHECKGL( glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId) );
67
void GLFramebufferObject::Disable()
69
CHECKGL( glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0) );
73
GLFramebufferObject::AttachTexture( GLenum attachment, GLenum texType,
74
GLuint texId, int mipLevel, int zSlice)
77
if( GetAttachedId(attachment) != texId )
79
_FramebufferTextureND( attachment, texType,
80
texId, mipLevel, zSlice );
84
// nuxError(TEXT("GLFramebufferObject::AttachTexture PERFORMANCE WARNING:\n \
85
// \tRedundant bind of texture (id = %d).\n"), texId);
90
GLFramebufferObject::AttachTextures( int numTextures, GLenum texTarget[], GLuint texId[],
91
GLenum attachment[], int mipLevel[], int zSlice[] )
93
for(int i = 0; i < numTextures; ++i) {
94
AttachTexture( texTarget[i], texId[i],
95
attachment ? attachment[i] : (GL_COLOR_ATTACHMENT0_EXT + i),
96
mipLevel ? mipLevel[i] : 0,
97
zSlice ? zSlice[i] : 0 );
103
GLFramebufferObject::AttachRenderBuffer( GLenum attachment, GLuint buffId )
106
if( GetAttachedId(attachment) != buffId )
108
CHECKGL( glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, attachment,
109
GL_RENDERBUFFER_EXT, buffId) );
113
// nuxError(TEXT("GLFramebufferObject::AttachRenderBuffer PERFORMANCE WARNING:\n \
114
// \tRedundant bind of GLRenderbuffer (id = %d).\n"), buffId);
120
GLFramebufferObject::Unattach( GLenum attachment )
123
GLenum type = GetAttachedType(attachment);
129
case GL_RENDERBUFFER_EXT:
130
AttachRenderBuffer( attachment, 0 );
133
AttachTexture( attachment, GL_TEXTURE_2D, 0 );
136
std::cout << "GLFramebufferObject::unbind_attachment ERROR: Unknown attached resource type\n";
141
GLint GLFramebufferObject::GetMaxColorAttachments()
144
CHECKGL( glGetIntegerv( GL_MAX_COLOR_ATTACHMENTS_EXT, &maxAttach ) );
148
GLuint GLFramebufferObject::_GenerateFboId()
151
CHECKGL( glGenFramebuffersEXT(1, &id) );
155
void GLFramebufferObject::_GuardedBind()
157
// Only binds if m_fboId is different than the currently bound FBO
158
CHECKGL( glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &m_savedFboId ) );
159
if (m_fboId != m_savedFboId)
161
CHECKGL( glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fboId) );
165
void GLFramebufferObject::_GuardedUnbind()
167
// Returns FBO binding to the previously enabled FBO
168
if (m_savedFboId != m_fboId)
170
CHECKGL( glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, (GLuint)m_savedFboId) );
175
GLFramebufferObject::_FramebufferTextureND( GLenum attachment, GLenum texType,
176
GLuint texId, int mipLevel,
179
if(texType == GL_TEXTURE_2D)
181
// Default is GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE_ARB, or cube faces
182
CHECKGL( glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, attachment,
183
texType, texId, mipLevel ) );
185
else if (texType == GL_TEXTURE_1D)
187
CHECKGL( glFramebufferTexture1DEXT( GL_FRAMEBUFFER_EXT, attachment,
188
GL_TEXTURE_1D, texId, mipLevel ) );
190
else if (texType == GL_TEXTURE_3D)
192
CHECKGL( glFramebufferTexture3DEXT( GL_FRAMEBUFFER_EXT, attachment,
193
GL_TEXTURE_3D, texId, mipLevel, zSlice ) );
197
bool GLFramebufferObject::IsValid()
204
status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
205
CHECKGL_MSG(glCheckFramebufferStatusEXT);
209
case GL_FRAMEBUFFER_COMPLETE_EXT: // Everything's OK
212
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
213
nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT"));
216
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
217
nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT"));
220
// See issue (87) of http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt
221
// case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
222
// nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT"));
225
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
226
nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT"));
229
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
230
nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT"));
233
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
234
nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT"));
237
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
238
nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT"));
241
// case GL_FRAMEBUFFER_STATUS_ERROR_EXT:
242
// nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_STATUS_ERROR_EXT"));
245
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
246
nuxError(TEXT("[GLFramebufferObject::IsValid] GL_FRAMEBUFFER_UNSUPPORTED_EXT"));
250
nuxError(TEXT("[GLFramebufferObject::IsValid] Unknown ERROR"));
259
GLenum GLFramebufferObject::GetAttachedType( GLenum attachment )
261
// Returns GL_RENDERBUFFER_EXT or GL_TEXTURE
264
CHECKGL( glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
265
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT,
271
GLuint GLFramebufferObject::GetAttachedId( GLenum attachment )
275
CHECKGL( glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
276
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
282
GLint GLFramebufferObject::GetAttachedMipLevel( GLenum attachment )
286
CHECKGL( glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
287
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT,
293
GLint GLFramebufferObject::GetAttachedCubeFace( GLenum attachment )
297
CHECKGL( glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
298
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT,
304
GLint GLFramebufferObject::GetAttachedZSlice( GLenum attachment )
308
CHECKGL( glGetFramebufferAttachmentParameterivEXT(GL_FRAMEBUFFER_EXT, attachment,
309
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT,
315
//////////////////////////////////////////////////////////////////////////
317
//////////////////////////////////////////////////////////////////////////
320
GLRenderbuffer::GLRenderbuffer()
321
: m_bufId(_CreateBufferId())
324
GLRenderbuffer::GLRenderbuffer(GLenum internalFormat, int width, int height)
325
: m_bufId(_CreateBufferId())
327
Set(internalFormat, width, height);
330
GLRenderbuffer::~GLRenderbuffer()
332
CHECKGL( glDeleteRenderbuffersEXT(1, &m_bufId) );
335
void GLRenderbuffer::Bind()
337
CHECKGL( glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_bufId) );
340
void GLRenderbuffer::Unbind()
342
CHECKGL( glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0) );
345
void GLRenderbuffer::Set(GLenum internalFormat, int width, int height)
347
int maxSize = GLRenderbuffer::GetMaxSize();
348
if (width > maxSize || height > maxSize )
350
std::cout << "GLRenderbuffer::GLRenderbuffer() ERROR: Size too big width=" << width << "height=" << height << "\n";
356
CHECKGL( glGetIntegerv( GL_RENDERBUFFER_BINDING_EXT, &savedId ) );
357
if (savedId != m_bufId)
362
// Allocate memory for renderBuffer
363
CHECKGL( glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalFormat, width, height ) );
366
if (savedId != m_bufId)
372
GLuint GLRenderbuffer::GetId() const
377
GLint GLRenderbuffer::GetMaxSize()
380
CHECKGL( glGetIntegerv( GL_MAX_RENDERBUFFER_SIZE_EXT, &maxAttach ) );
384
GLuint GLRenderbuffer::_CreateBufferId()
387
CHECKGL( glGenRenderbuffersEXT(1, &id) );