mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0025973: Visualization, TKOpenGl - support EAGLContext as alternative to NSOpenGLContext
OpenGl_FrameBuffer::InitWithRB() - add method to initialize FBO with Render Buffer Objects. OpenGl_FrameBuffer::InitWrapper() - add new method to initialize FBO from currently bound in context. Aspect_RenderingContext - define type explicitly to EAGLContext* / NSOpenGLContext* for ARC. OpenGl_Window - allow initialization from alien context for OS X / iOS.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include <OpenGl_ArbFBO.hxx>
|
||||
|
||||
#include <Standard_Assert.hxx>
|
||||
#include <TCollection_ExtendedString.hxx>
|
||||
|
||||
IMPLEMENT_STANDARD_HANDLE (OpenGl_FrameBuffer, OpenGl_Resource)
|
||||
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_FrameBuffer, OpenGl_Resource)
|
||||
@@ -29,6 +30,9 @@ OpenGl_FrameBuffer::OpenGl_FrameBuffer (GLint theTextureFormat)
|
||||
myVPSizeY (0),
|
||||
myTextFormat (theTextureFormat),
|
||||
myGlFBufferId (NO_FRAMEBUFFER),
|
||||
myGlColorRBufferId (NO_RENDERBUFFER),
|
||||
myGlDepthRBufferId (NO_RENDERBUFFER),
|
||||
myIsOwnBuffer (false),
|
||||
myColorTexture (new OpenGl_Texture()),
|
||||
myDepthStencilTexture (new OpenGl_Texture())
|
||||
{
|
||||
@@ -95,6 +99,143 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : InitWithRB
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_FrameBuffer::InitWithRB (const Handle(OpenGl_Context)& theGlCtx,
|
||||
const GLsizei theViewportSizeX,
|
||||
const GLsizei theViewportSizeY,
|
||||
const GLuint theColorRBufferFromWindow)
|
||||
{
|
||||
if (theGlCtx->arbFBO == NULL)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// clean up previous state
|
||||
Release (theGlCtx.operator->());
|
||||
|
||||
// setup viewport sizes as is
|
||||
myVPSizeX = theViewportSizeX;
|
||||
myVPSizeY = theViewportSizeY;
|
||||
|
||||
// Create the render-buffers
|
||||
if (theColorRBufferFromWindow != NO_RENDERBUFFER)
|
||||
{
|
||||
myGlColorRBufferId = theColorRBufferFromWindow;
|
||||
}
|
||||
else
|
||||
{
|
||||
theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlColorRBufferId);
|
||||
theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlColorRBufferId);
|
||||
theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_RGBA8, myVPSizeX, myVPSizeY);
|
||||
}
|
||||
|
||||
theGlCtx->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
|
||||
theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
|
||||
theGlCtx->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, myVPSizeX, myVPSizeY);
|
||||
|
||||
theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
|
||||
|
||||
// create FBO
|
||||
theGlCtx->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
|
||||
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
|
||||
theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||
GL_RENDERBUFFER, myGlColorRBufferId);
|
||||
#ifdef GL_DEPTH_STENCIL_ATTACHMENT
|
||||
theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, myGlDepthRBufferId);
|
||||
#else
|
||||
theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||
GL_RENDERBUFFER, myGlDepthRBufferId);
|
||||
theGlCtx->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||
GL_RENDERBUFFER, myGlDepthRBufferId);
|
||||
#endif
|
||||
if (theGlCtx->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
UnbindBuffer (theGlCtx);
|
||||
Release (theGlCtx.operator->());
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
UnbindBuffer (theGlCtx);
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : InitWrapper
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
Standard_Boolean OpenGl_FrameBuffer::InitWrapper (const Handle(OpenGl_Context)& theGlCtx)
|
||||
{
|
||||
if (theGlCtx->arbFBO == NULL)
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
// clean up previous state
|
||||
Release (theGlCtx.operator->());
|
||||
|
||||
GLint anFbo = GLint(NO_FRAMEBUFFER);
|
||||
::glGetIntegerv (GL_FRAMEBUFFER_BINDING, &anFbo);
|
||||
if (anFbo == GLint(NO_FRAMEBUFFER))
|
||||
{
|
||||
return Standard_False;
|
||||
}
|
||||
|
||||
GLint aColorType = 0;
|
||||
GLint aColorId = 0;
|
||||
GLint aDepthType = 0;
|
||||
GLint aDepthId = 0;
|
||||
theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aColorType);
|
||||
theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &aDepthType);
|
||||
|
||||
myGlFBufferId = GLuint(anFbo);
|
||||
myIsOwnBuffer = false;
|
||||
if (aColorType == GL_RENDERBUFFER)
|
||||
{
|
||||
theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aColorId);
|
||||
myGlColorRBufferId = aColorId;
|
||||
}
|
||||
else if (aColorType != GL_NONE)
|
||||
{
|
||||
TCollection_ExtendedString aMsg = "OpenGl_FrameBuffer::InitWrapper(), color attachment of unsupported type has been skipped!";
|
||||
theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||
GL_DEBUG_TYPE_ERROR_ARB,
|
||||
0,
|
||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||
aMsg);
|
||||
}
|
||||
|
||||
if (aDepthType == GL_RENDERBUFFER)
|
||||
{
|
||||
theGlCtx->arbFBO->glGetFramebufferAttachmentParameteriv (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &aDepthId);
|
||||
myGlDepthRBufferId = aDepthId;
|
||||
}
|
||||
else if (aDepthType != GL_NONE)
|
||||
{
|
||||
TCollection_ExtendedString aMsg = "OpenGl_FrameBuffer::InitWrapper(), depth attachment of unsupported type has been skipped!";
|
||||
theGlCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
|
||||
GL_DEBUG_TYPE_ERROR_ARB,
|
||||
0,
|
||||
GL_DEBUG_SEVERITY_HIGH_ARB,
|
||||
aMsg);
|
||||
}
|
||||
|
||||
// retrieve dimensions
|
||||
GLuint aRBuffer = myGlColorRBufferId != NO_RENDERBUFFER ? myGlColorRBufferId : myGlDepthRBufferId;
|
||||
if (aRBuffer != NO_RENDERBUFFER)
|
||||
{
|
||||
theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, aRBuffer);
|
||||
theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &myVPSizeX);
|
||||
theGlCtx->arbFBO->glGetRenderbufferParameteriv (GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &myVPSizeY);
|
||||
theGlCtx->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
|
||||
}
|
||||
|
||||
return aRBuffer != NO_RENDERBUFFER;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Release
|
||||
// purpose :
|
||||
@@ -106,11 +247,23 @@ void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
|
||||
// application can not handle this case by exception - this is bug in code
|
||||
Standard_ASSERT_RETURN (theGlCtx != NULL,
|
||||
"OpenGl_FrameBuffer destroyed without GL context! Possible GPU memory leakage...",);
|
||||
if (theGlCtx->IsValid())
|
||||
if (theGlCtx->IsValid()
|
||||
&& myIsOwnBuffer)
|
||||
{
|
||||
theGlCtx->arbFBO->glDeleteFramebuffers (1, &myGlFBufferId);
|
||||
if (myGlColorRBufferId != NO_RENDERBUFFER)
|
||||
{
|
||||
theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlColorRBufferId);
|
||||
}
|
||||
if (myGlDepthRBufferId != NO_RENDERBUFFER)
|
||||
{
|
||||
theGlCtx->arbFBO->glDeleteRenderbuffers (1, &myGlDepthRBufferId);
|
||||
}
|
||||
}
|
||||
myGlFBufferId = NO_FRAMEBUFFER;
|
||||
myGlFBufferId = NO_FRAMEBUFFER;
|
||||
myGlColorRBufferId = NO_RENDERBUFFER;
|
||||
myGlDepthRBufferId = NO_RENDERBUFFER;
|
||||
myIsOwnBuffer = false;
|
||||
}
|
||||
|
||||
myColorTexture->Release (theGlCtx);
|
||||
@@ -184,5 +337,13 @@ void OpenGl_FrameBuffer::BindReadBuffer (const Handle(OpenGl_Context)& theGlCtx)
|
||||
// =======================================================================
|
||||
void OpenGl_FrameBuffer::UnbindBuffer (const Handle(OpenGl_Context)& theGlCtx)
|
||||
{
|
||||
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);
|
||||
if (!theGlCtx->DefaultFrameBuffer().IsNull()
|
||||
&& theGlCtx->DefaultFrameBuffer().operator->() != this)
|
||||
{
|
||||
theGlCtx->DefaultFrameBuffer()->BindBuffer (theGlCtx);
|
||||
}
|
||||
else
|
||||
{
|
||||
theGlCtx->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, NO_FRAMEBUFFER);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user