1
0
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:
kgv
2015-04-02 16:28:54 +03:00
committed by bugmaster
parent 44ef962bdd
commit a2e4f780c2
18 changed files with 819 additions and 146 deletions

View File

@@ -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);
}
}