You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
729 lines
21 KiB
C++
729 lines
21 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkFrameBufferObject2.cxx
|
|
|
|
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
|
|
All rights reserved.
|
|
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
|
|
|
|
This software is distributed WITHOUT ANY WARRANTY; without even
|
|
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
PURPOSE. See the above copyright notice for more information.
|
|
|
|
=========================================================================*/
|
|
#include "vtkFrameBufferObject2.h"
|
|
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkOpenGLRenderWindow.h"
|
|
#include "vtkTextureObject.h"
|
|
#include "vtkRenderbuffer.h"
|
|
#include "vtkPixelBufferObject.h"
|
|
#include "vtkOpenGLExtensionManager.h"
|
|
#include "vtkOpenGLError.h"
|
|
|
|
#include "vtkgl.h"
|
|
|
|
#include <cassert>
|
|
#include <vector>
|
|
using std::vector;
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkStandardNewMacro(vtkFrameBufferObject2);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkFrameBufferObject2::vtkFrameBufferObject2()
|
|
{
|
|
this->FBOIndex = 0;
|
|
this->PreviousDrawFBO = 0;
|
|
this->PreviousReadFBO = 0;
|
|
this->PreviousDrawBuffer = GL_NONE;
|
|
this->PreviousReadBuffer = GL_NONE;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkFrameBufferObject2::~vtkFrameBufferObject2()
|
|
{
|
|
this->DestroyFBO();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::CreateFBO()
|
|
{
|
|
this->FBOIndex=0;
|
|
GLuint temp;
|
|
vtkgl::GenFramebuffersEXT(1,&temp);
|
|
vtkOpenGLCheckErrorMacro("failed at glGenFramebuffers");
|
|
this->FBOIndex=temp;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::DestroyFBO()
|
|
{
|
|
// because we don't hold a reference to the render
|
|
// context we don't have any control on when it is
|
|
// destroyed. In fact it may be destroyed before
|
|
// we are(eg smart pointers), in which case we should
|
|
// do nothing.
|
|
if (this->Context && (this->FBOIndex!=0))
|
|
{
|
|
GLuint fbo=static_cast<GLuint>(this->FBOIndex);
|
|
vtkgl::DeleteFramebuffersEXT(1,&fbo);
|
|
vtkOpenGLCheckErrorMacro("failed at glDeleteFramebuffers");
|
|
this->FBOIndex=0;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkFrameBufferObject2::IsSupported(vtkRenderWindow *win)
|
|
{
|
|
vtkOpenGLRenderWindow *renWin=vtkOpenGLRenderWindow::SafeDownCast(win);
|
|
if(renWin!=0)
|
|
{
|
|
vtkOpenGLExtensionManager *mgr=renWin->GetExtensionManager();
|
|
|
|
bool gl12 = mgr->ExtensionSupported("GL_VERSION_1_2")==1;
|
|
bool tex3D = gl12 || mgr->ExtensionSupported("GL_EXT_texture3D");
|
|
|
|
bool gl14 = mgr->ExtensionSupported("GL_VERSION_1_4")==1;
|
|
bool depthTex = gl14 || mgr->ExtensionSupported("GL_ARB_depth_texture")==1;
|
|
|
|
bool gl20 = mgr->ExtensionSupported("GL_VERSION_2_0")==1;
|
|
bool drawBufs = gl20 || mgr->ExtensionSupported("GL_ARB_draw_buffers")==1;
|
|
|
|
bool fbo = mgr->ExtensionSupported("GL_EXT_framebuffer_object")==1;
|
|
bool fboBlit = mgr->ExtensionSupported("GL_EXT_framebuffer_blit")==1;
|
|
|
|
return tex3D && depthTex && drawBufs && fbo && fboBlit;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkFrameBufferObject2::LoadRequiredExtensions(vtkRenderWindow *win)
|
|
{
|
|
vtkOpenGLRenderWindow *oglRenWin
|
|
= dynamic_cast<vtkOpenGLRenderWindow*>(win);
|
|
|
|
vtkOpenGLExtensionManager *mgr = oglRenWin->GetExtensionManager();
|
|
|
|
bool gl12 = mgr->ExtensionSupported("GL_VERSION_1_2")==1;
|
|
bool tex3D = gl12 || mgr->ExtensionSupported("GL_EXT_texture3D");
|
|
|
|
bool gl14 = mgr->ExtensionSupported("GL_VERSION_1_4")==1;
|
|
bool depthTex = gl14 || mgr->ExtensionSupported("GL_ARB_depth_texture")==1;
|
|
|
|
bool gl20 = mgr->ExtensionSupported("GL_VERSION_2_0")==1;
|
|
bool drawBufs = gl20 || mgr->ExtensionSupported("GL_ARB_draw_buffers");
|
|
|
|
bool fbo = mgr->ExtensionSupported("GL_EXT_framebuffer_object")==1;
|
|
bool fboBlit = mgr->ExtensionSupported("GL_EXT_framebuffer_blit")==1;
|
|
|
|
bool supported = tex3D && depthTex && drawBufs && fbo && fboBlit;
|
|
|
|
if(supported)
|
|
{
|
|
if(gl12)
|
|
{
|
|
mgr->LoadSupportedExtension("GL_VERSION_1_2");
|
|
}
|
|
else
|
|
{
|
|
mgr->LoadCorePromotedExtension("GL_EXT_texture3D");
|
|
}
|
|
|
|
if(gl14)
|
|
{
|
|
mgr->LoadSupportedExtension("GL_VERSION_1_4");
|
|
}
|
|
else
|
|
{
|
|
mgr->LoadCorePromotedExtension("GL_ARB_depth_texture");
|
|
}
|
|
|
|
if(gl20)
|
|
{
|
|
mgr->LoadSupportedExtension("GL_VERSION_2_0");
|
|
}
|
|
else
|
|
{
|
|
mgr->LoadCorePromotedExtension("GL_ARB_draw_buffers");
|
|
}
|
|
|
|
mgr->LoadSupportedExtension("GL_EXT_framebuffer_object");
|
|
mgr->LoadSupportedExtension("GL_EXT_framebuffer_blit");
|
|
}
|
|
|
|
return supported;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::SetContext(vtkRenderWindow *renWin)
|
|
{
|
|
// avoid pointless re-assignment
|
|
if (this->Context==renWin)
|
|
{
|
|
return;
|
|
}
|
|
// free previous resources
|
|
this->DestroyFBO();
|
|
this->Context = NULL;
|
|
this->Modified();
|
|
// all done if assigned null
|
|
if (!renWin)
|
|
{
|
|
return;
|
|
}
|
|
// check for support
|
|
vtkOpenGLRenderWindow *context
|
|
= dynamic_cast<vtkOpenGLRenderWindow*>(renWin);
|
|
if ( !context
|
|
|| !this->LoadRequiredExtensions(renWin))
|
|
{
|
|
vtkErrorMacro("Context does not support the required extensions");
|
|
return;
|
|
}
|
|
// intialize
|
|
this->Context=renWin;
|
|
this->Context->MakeCurrent();
|
|
this->CreateFBO();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkRenderWindow *vtkFrameBufferObject2::GetContext()
|
|
{
|
|
return this->Context;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::SaveCurrentBindings()
|
|
{
|
|
glGetIntegerv(vtkgl::DRAW_FRAMEBUFFER_BINDING_EXT, (int*)&this->PreviousDrawFBO);
|
|
glGetIntegerv(vtkgl::READ_FRAMEBUFFER_BINDING_EXT, (int*)&this->PreviousReadFBO);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::SaveCurrentBuffers()
|
|
{
|
|
glGetIntegerv(GL_DRAW_BUFFER, (int*)&this->PreviousDrawBuffer);
|
|
glGetIntegerv(GL_READ_BUFFER, (int*)&this->PreviousReadBuffer);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::RestorePreviousBuffers(unsigned int mode)
|
|
{
|
|
switch((GLenum)mode)
|
|
{
|
|
case vtkgl::FRAMEBUFFER_EXT:
|
|
glDrawBuffer((GLenum)this->PreviousDrawBuffer);
|
|
vtkOpenGLCheckErrorMacro("failed at glDrawBuffer");
|
|
|
|
glReadBuffer((GLenum)this->PreviousReadBuffer);
|
|
vtkOpenGLCheckErrorMacro("failed at glReadBuffer");
|
|
break;
|
|
|
|
case vtkgl::DRAW_FRAMEBUFFER_EXT:
|
|
glDrawBuffer((GLenum)this->PreviousDrawBuffer);
|
|
vtkOpenGLCheckErrorMacro("failed at glDrawBuffer");
|
|
break;
|
|
|
|
case vtkgl::READ_FRAMEBUFFER_EXT:
|
|
glReadBuffer((GLenum)this->PreviousReadBuffer);
|
|
vtkOpenGLCheckErrorMacro("failed at glReadBuffer");
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::Bind(unsigned int mode)
|
|
{
|
|
assert(this->FBOIndex!=0); // need to call glGenFramebuffers first
|
|
|
|
// need to ensure that binding is esxtablished *every* time because
|
|
// if other code binds over us then all of our subsequent calls
|
|
// will affect that fbo not ours.
|
|
vtkgl::BindFramebufferEXT((GLenum)mode, this->FBOIndex);
|
|
vtkOpenGLCheckErrorMacro("failed at glBindFramebuffer");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::UnBind(unsigned int mode)
|
|
{
|
|
assert(this->FBOIndex!=0); // need to GenFramebuffers first
|
|
|
|
bool drawing
|
|
= ((GLenum)mode)==vtkgl::DRAW_FRAMEBUFFER_EXT
|
|
|| ((GLenum)mode)==vtkgl::FRAMEBUFFER_EXT;
|
|
|
|
GLuint prevFbo
|
|
= (drawing ? this->PreviousDrawFBO : this->PreviousReadFBO);
|
|
|
|
vtkgl::BindFramebufferEXT((GLenum)mode, prevFbo);
|
|
vtkOpenGLCheckErrorMacro("failed at glBindFramebuffer");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::ActivateDrawBuffers(unsigned int *ids, int num)
|
|
{
|
|
assert(num<17); // a practical limit, increase if needed
|
|
GLenum colorAtts[16];
|
|
for (int i=0; i<num; ++i)
|
|
{
|
|
colorAtts[i] = vtkgl::COLOR_ATTACHMENT0 + ids[i];
|
|
}
|
|
vtkgl::DrawBuffers(num, &colorAtts[0]);
|
|
vtkOpenGLCheckErrorMacro("failed at glDrawBuffers");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::ActivateDrawBuffers(unsigned int num)
|
|
{
|
|
assert(num<17); // a practical limit, increase if needed
|
|
GLenum colorAtts[16];
|
|
for (unsigned int i=0; i<num; ++i)
|
|
{
|
|
colorAtts[i] = vtkgl::COLOR_ATTACHMENT0 + i;
|
|
}
|
|
vtkgl::DrawBuffers(num, &colorAtts[0]);
|
|
vtkOpenGLCheckErrorMacro("failed at glDrawBuffers");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::DeactivateDrawBuffers()
|
|
{
|
|
GLenum att = GL_NONE;
|
|
vtkgl::DrawBuffers(1, &att);
|
|
vtkOpenGLCheckErrorMacro("failed at glDrawBuffers(GL_NONE)");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::ActivateDrawBuffer(
|
|
unsigned int colorAtt)
|
|
{
|
|
colorAtt += vtkgl::COLOR_ATTACHMENT0;
|
|
vtkgl::DrawBuffers(1, &colorAtt);
|
|
vtkOpenGLCheckErrorMacro("failed at glDrawBuffers");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::ActivateReadBuffer(
|
|
unsigned int colorAtt)
|
|
{
|
|
colorAtt += vtkgl::COLOR_ATTACHMENT0;
|
|
glReadBuffer((GLenum)colorAtt);
|
|
vtkOpenGLCheckErrorMacro("failed at glReadBuffer");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::DeactivateReadBuffer()
|
|
{
|
|
glReadBuffer(GL_NONE);
|
|
vtkOpenGLCheckErrorMacro("failed at glReadBuffer(GL_NONE)");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddTexColorAttachment(
|
|
unsigned int mode,
|
|
unsigned int i,
|
|
unsigned int handle)
|
|
{
|
|
vtkgl::FramebufferTexture2DEXT(
|
|
(GLenum)mode,
|
|
vtkgl::COLOR_ATTACHMENT0_EXT+i,
|
|
GL_TEXTURE_2D,
|
|
handle,
|
|
0);
|
|
vtkOpenGLCheckErrorMacro("failed at glFramebufferTexture2D");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::RemoveTexColorAttachments(
|
|
unsigned int mode,
|
|
unsigned int num)
|
|
{
|
|
for (unsigned int i=0; i<num; ++i)
|
|
{
|
|
this->AddTexColorAttachment(mode, i, 0U);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddColorAttachment(
|
|
unsigned int mode,
|
|
unsigned int i,
|
|
vtkTextureObject* tex)
|
|
{
|
|
unsigned int handle = (tex==NULL) ? 0 : tex->GetHandle();
|
|
this->AddTexColorAttachment(mode,i,handle);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddRenColorAttachment(
|
|
unsigned int mode,
|
|
unsigned int i,
|
|
unsigned int handle)
|
|
{
|
|
vtkgl::FramebufferRenderbufferEXT(
|
|
(GLenum)mode,
|
|
vtkgl::COLOR_ATTACHMENT0_EXT+i,
|
|
vtkgl::RENDERBUFFER,
|
|
handle);
|
|
vtkOpenGLCheckErrorMacro("failed at glFramebufferRenderbuffer");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddColorAttachment(
|
|
unsigned int mode,
|
|
unsigned int i,
|
|
vtkRenderbuffer* renbuf)
|
|
{
|
|
unsigned int handle = (renbuf==NULL) ? 0 : renbuf->GetHandle();
|
|
this->AddRenColorAttachment(mode, i, handle);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::RemoveRenColorAttachments(
|
|
unsigned int mode,
|
|
unsigned int num)
|
|
{
|
|
for (unsigned int i=0; i<num; ++i)
|
|
{
|
|
this->AddRenColorAttachment(mode, i, 0U);
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddTexDepthAttachment(
|
|
unsigned int mode,
|
|
unsigned int handle)
|
|
{
|
|
vtkgl::FramebufferTexture2DEXT(
|
|
(GLenum)mode,
|
|
vtkgl::DEPTH_ATTACHMENT,
|
|
GL_TEXTURE_2D,
|
|
handle,
|
|
0);
|
|
vtkOpenGLCheckErrorMacro("failed at glFramebufferTexture2D");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddDepthAttachment(
|
|
unsigned int mode,
|
|
vtkTextureObject* tex)
|
|
{
|
|
unsigned int handle = (tex==NULL) ? 0 : tex->GetHandle();
|
|
this->AddTexDepthAttachment(mode,handle);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddRenDepthAttachment(
|
|
unsigned int mode,
|
|
unsigned int handle)
|
|
{
|
|
vtkgl::FramebufferRenderbufferEXT(
|
|
(GLenum)mode,
|
|
vtkgl::DEPTH_ATTACHMENT,
|
|
vtkgl::RENDERBUFFER,
|
|
handle);
|
|
vtkOpenGLCheckErrorMacro("failed at glFramebufferRenderbuffer");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::AddDepthAttachment(
|
|
unsigned int mode,
|
|
vtkRenderbuffer* renbuf)
|
|
{
|
|
unsigned int handle = (renbuf==NULL) ? 0 : renbuf->GetHandle();
|
|
this->AddRenDepthAttachment(mode, handle);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::InitializeViewport(int width, int height)
|
|
{
|
|
glDisable(GL_ALPHA_TEST);
|
|
glDisable(GL_BLEND);
|
|
glDisable(GL_DEPTH_TEST);
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_SCISSOR_TEST);
|
|
|
|
// Viewport transformation for 1:1 'pixel=texel=data' mapping.
|
|
// Note this note enough for 1:1 mapping, because depending on the
|
|
// primitive displayed (point,line,polygon), the rasterization rules
|
|
// are different.
|
|
glMatrixMode(GL_PROJECTION);
|
|
glLoadIdentity();
|
|
glOrtho(0.0, width, 0.0, height, -1, 1);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glLoadIdentity();
|
|
glViewport(0, 0, width, height);
|
|
|
|
vtkOpenGLStaticCheckErrorMacro("failed after InitializeViewport");
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkFrameBufferObject2::Blit(
|
|
int srcExt[4],
|
|
int destExt[4],
|
|
unsigned int bits,
|
|
unsigned int mapping)
|
|
{
|
|
vtkgl::BlitFramebufferEXT(
|
|
(GLint)srcExt[0],
|
|
(GLint)srcExt[2],
|
|
(GLint)srcExt[1],
|
|
(GLint)srcExt[3],
|
|
(GLint)destExt[0],
|
|
(GLint)destExt[2],
|
|
(GLint)destExt[1],
|
|
(GLint)destExt[3],
|
|
(GLbitfield)bits,
|
|
(GLenum)mapping);
|
|
|
|
vtkOpenGLStaticCheckErrorMacro("failed at glBlitFramebuffer");
|
|
|
|
return 1;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPixelBufferObject *vtkFrameBufferObject2::DownloadDepth(
|
|
int extent[4],
|
|
int vtkType)
|
|
{
|
|
assert(this->Context);
|
|
|
|
return this->Download(
|
|
extent,
|
|
vtkType,
|
|
1,
|
|
this->GetOpenGLType(vtkType),
|
|
GL_DEPTH_COMPONENT);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPixelBufferObject *vtkFrameBufferObject2::DownloadColor4(
|
|
int extent[4],
|
|
int vtkType)
|
|
{
|
|
assert(this->Context);
|
|
|
|
return this->Download(
|
|
extent,
|
|
vtkType,
|
|
4,
|
|
this->GetOpenGLType(vtkType),
|
|
GL_RGBA);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPixelBufferObject *vtkFrameBufferObject2::DownloadColor3(
|
|
int extent[4],
|
|
int vtkType)
|
|
{
|
|
assert(this->Context);
|
|
|
|
return this->Download(
|
|
extent,
|
|
vtkType,
|
|
3,
|
|
this->GetOpenGLType(vtkType),
|
|
GL_RGB);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPixelBufferObject *vtkFrameBufferObject2::DownloadColor1(
|
|
int extent[4],
|
|
int vtkType,
|
|
int channel)
|
|
{
|
|
assert(this->Context);
|
|
GLenum oglChannel = 0;
|
|
switch (channel)
|
|
{
|
|
case 0:
|
|
oglChannel = GL_RED;
|
|
break;
|
|
case 1:
|
|
oglChannel = GL_GREEN;
|
|
break;
|
|
case 2:
|
|
oglChannel = GL_BLUE;
|
|
break;
|
|
default:
|
|
vtkErrorMacro("Inavlid channel");
|
|
return NULL;
|
|
}
|
|
|
|
return this->Download(
|
|
extent,
|
|
vtkType,
|
|
1,
|
|
this->GetOpenGLType(vtkType),
|
|
oglChannel);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPixelBufferObject *vtkFrameBufferObject2::Download(
|
|
int extent[4],
|
|
int vtkType,
|
|
int nComps,
|
|
int oglType,
|
|
int oglFormat)
|
|
{
|
|
vtkPixelBufferObject *pbo = vtkPixelBufferObject::New();
|
|
pbo->SetContext(this->Context);
|
|
|
|
this->Download(
|
|
extent,
|
|
vtkType,
|
|
nComps,
|
|
oglType,
|
|
oglFormat,
|
|
pbo);
|
|
|
|
return pbo;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::Download(
|
|
int extent[4],
|
|
int vtkType,
|
|
int nComps,
|
|
int oglType,
|
|
int oglFormat,
|
|
vtkPixelBufferObject *pbo)
|
|
{
|
|
unsigned int extentSize[2] = {
|
|
static_cast<unsigned int>(extent[1] - extent[0] + 1),
|
|
static_cast<unsigned int>(extent[3] - extent[2] + 1)
|
|
};
|
|
|
|
unsigned int nTups = extentSize[0]*extentSize[1];
|
|
|
|
pbo->Allocate(
|
|
vtkType,
|
|
nTups,
|
|
nComps,
|
|
vtkPixelBufferObject::PACKED_BUFFER);
|
|
|
|
pbo->Bind(vtkPixelBufferObject::PACKED_BUFFER);
|
|
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
|
glReadPixels(
|
|
extent[0],
|
|
extent[2],
|
|
extentSize[0],
|
|
extentSize[1],
|
|
oglFormat,
|
|
oglType,
|
|
NULL);
|
|
|
|
vtkOpenGLStaticCheckErrorMacro("failed at glReadPixels");
|
|
|
|
pbo->UnBind();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int vtkFrameBufferObject2::GetOpenGLType(int vtkType)
|
|
{
|
|
// convert vtk type to open gl type
|
|
int oglType = 0;
|
|
switch (vtkType)
|
|
{
|
|
case VTK_FLOAT:
|
|
oglType = GL_FLOAT;
|
|
break;
|
|
case VTK_INT:
|
|
oglType = GL_INT;
|
|
break;
|
|
case VTK_UNSIGNED_INT:
|
|
oglType = GL_UNSIGNED_INT;
|
|
break;
|
|
case VTK_CHAR:
|
|
oglType = GL_BYTE;
|
|
break;
|
|
case VTK_UNSIGNED_CHAR:
|
|
oglType = GL_UNSIGNED_BYTE;
|
|
break;
|
|
default:
|
|
vtkErrorMacro("Unsupported type");
|
|
return 0;
|
|
}
|
|
return oglType;
|
|
}
|
|
|
|
// Description:
|
|
// Common switch for parsing fbo status return.
|
|
#define vtkFBOStrErrorMacro(status, str, ok) \
|
|
ok = false; \
|
|
switch(status) \
|
|
{ \
|
|
case vtkgl::FRAMEBUFFER_COMPLETE_EXT: \
|
|
str = "FBO complete"; \
|
|
ok = true; \
|
|
break; \
|
|
case vtkgl::FRAMEBUFFER_UNSUPPORTED_EXT: \
|
|
str = "FRAMEBUFFER_UNSUPPORTED"; \
|
|
break; \
|
|
case vtkgl::FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: \
|
|
str = "FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; \
|
|
break; \
|
|
case vtkgl::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: \
|
|
str = "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; \
|
|
break; \
|
|
case vtkgl::FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: \
|
|
str = "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; \
|
|
break; \
|
|
case vtkgl::FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: \
|
|
str = "FRAMEBUFFER_INCOMPLETE_FORMATS"; \
|
|
break; \
|
|
case vtkgl::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: \
|
|
str = "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; \
|
|
break; \
|
|
case vtkgl::FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: \
|
|
str = "FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; \
|
|
break; \
|
|
default: \
|
|
str = "Unknown status"; \
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
bool vtkFrameBufferObject2::GetFrameBufferStatus(
|
|
unsigned int mode,
|
|
const char *&desc)
|
|
{
|
|
bool ok;
|
|
GLenum status = vtkgl::CheckFramebufferStatusEXT((GLenum)mode);
|
|
vtkFBOStrErrorMacro(status, desc, ok);
|
|
return ok;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
int vtkFrameBufferObject2::CheckFrameBufferStatus(unsigned int mode)
|
|
{
|
|
bool ok;
|
|
const char *desc = "error";
|
|
GLenum status = vtkgl::CheckFramebufferStatusEXT((GLenum)mode);
|
|
vtkOpenGLCheckErrorMacro("failed at glCheckFramebufferStatus");
|
|
vtkFBOStrErrorMacro(status, desc, ok);
|
|
if (!ok)
|
|
{
|
|
vtkErrorMacro("The framebuffer is incomplete : " << desc);
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
void vtkFrameBufferObject2::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
|
|
os
|
|
<< indent << "Context=" << this->Context << endl
|
|
<< indent << "FBOIndex=" << this->FBOIndex << endl
|
|
<< indent << "PreviousDrawFBO=" << this->PreviousDrawFBO << endl
|
|
<< indent << "PreviousReadFBO=" << this->PreviousReadFBO << endl
|
|
<< indent << "PreviousDrawBuffer=" << this->PreviousDrawBuffer << endl
|
|
<< indent << "PreviousReadBuffer=" << this->PreviousReadBuffer << endl
|
|
<< endl;
|
|
}
|