1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-05-16 10:54:53 +03:00

0026165: Visualization, TKOpenGl - fix FBO blitting on some mobile devices

OpenGl_Texture::Init() - initialize FBO textures with GL_TEXTURE_WRAP_ set to GL_CLAMP_TO_EDGE,
since some devices do not support GL_REPEAT (which is default) in such combination.
OpenGl_Font::createTexture() - define texture parameters explicitly.

OpenGl_FrameBuffer::Init() create Depth render buffer object instead of texture
on devices which do not support GL_DEPTH24_STENCIL8.
This commit is contained in:
kgv 2015-05-06 16:05:47 +03:00 committed by abv
parent 2ff806d1ab
commit fe3a29bc9a
5 changed files with 83 additions and 53 deletions

View File

@ -16,6 +16,7 @@
#include <OpenGl_Font.hxx>
#include <OpenGl_Context.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <Standard_Assert.hxx>
#include <TCollection_ExtendedString.hxx>
@ -113,7 +114,13 @@ bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
memset (&myLastTilePx, 0, sizeof(myLastTilePx));
myLastTilePx.Bottom = myTileSizeY;
myTextures.Append (new OpenGl_Texture());
Handle(Graphic3d_TextureParams) aParams = new Graphic3d_TextureParams();
aParams->SetModulate (Standard_False);
aParams->SetRepeat (Standard_False);
aParams->SetFilter (Graphic3d_TOTF_BILINEAR);
aParams->SetAnisoFilter (Graphic3d_LOTA_OFF);
myTextures.Append (new OpenGl_Texture (aParams));
Handle(OpenGl_Texture)& aTexture = myTextures.ChangeLast();
Image_PixMap aBlackImg;
@ -130,10 +137,6 @@ bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
return false;
}
aTexture->Bind (theCtx);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, theCtx->TextureWrapClamp());
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, theCtx->TextureWrapClamp());
aTexture->Unbind (theCtx);
return true;
}

View File

@ -69,26 +69,56 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
myVPSizeY = theViewportSizeY;
// Create the textures (will be used as color buffer and depth-stencil buffer)
if (!initTrashTextures (theGlContext))
if (!myColorTexture->Init (theGlContext, myTextFormat,
GL_RGBA, GL_UNSIGNED_BYTE,
myVPSizeX, myVPSizeY, Graphic3d_TOT_2D))
{
Release (theGlContext.operator->());
return Standard_False;
}
// extensions (GL_OES_packed_depth_stencil, GL_OES_depth_texture) + GL version might be used to determine supported formats
// instead of just trying to create such texture
if (!myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
myVPSizeX, myVPSizeY, Graphic3d_TOT_2D))
{
TCollection_ExtendedString aMsg = TCollection_ExtendedString()
+ "Warning! Depth textures are not supported by hardware!";
theGlContext->PushMessage (GL_DEBUG_SOURCE_APPLICATION_ARB,
GL_DEBUG_TYPE_PORTABILITY_ARB,
0,
GL_DEBUG_SEVERITY_HIGH_ARB,
aMsg);
theGlContext->arbFBO->glGenRenderbuffers (1, &myGlDepthRBufferId);
theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, myGlDepthRBufferId);
theGlContext->arbFBO->glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, myVPSizeX, myVPSizeY);
theGlContext->arbFBO->glBindRenderbuffer (GL_RENDERBUFFER, NO_RENDERBUFFER);
}
// Build FBO and setup it as texture
theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
#ifdef GL_DEPTH_STENCIL_ATTACHMENT
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
#else
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
#endif
if (myDepthStencilTexture->IsValid())
{
#ifdef GL_DEPTH_STENCIL_ATTACHMENT
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
#else
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
#endif
}
else if (myGlDepthRBufferId != NO_RENDERBUFFER)
{
theGlContext->arbFBO->glFramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, myGlDepthRBufferId);
}
if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
Release (theGlContext.operator->());
@ -287,20 +317,6 @@ void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
myDepthStencilTexture->Release (theGlCtx);
}
// =======================================================================
// function : initTrashTexture
// purpose :
// =======================================================================
Standard_Boolean OpenGl_FrameBuffer::initTrashTextures (const Handle(OpenGl_Context)& theGlContext)
{
return myColorTexture->Init (theGlContext, myTextFormat,
GL_RGBA, GL_UNSIGNED_BYTE,
myVPSizeX, myVPSizeY, Graphic3d_TOT_2D)
&& myDepthStencilTexture->Init (theGlContext, GL_DEPTH24_STENCIL8,
GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8,
myVPSizeX, myVPSizeY, Graphic3d_TOT_2D);
}
// =======================================================================
// function : SetupViewport
// purpose :

View File

@ -153,9 +153,6 @@ public:
protected:
//! Generate textures with undefined data
Standard_Boolean initTrashTextures (const Handle(OpenGl_Context)& theGlContext);
Standard_Boolean isValidFrameBuffer() const
{
return myGlFBufferId != NO_FRAMEBUFFER;

View File

@ -390,6 +390,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
const bool toForceP2 = !theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW;
const GLsizei aWidthOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aWidth, aMaxSize) : Min (aWidth, aMaxSize);
const GLsizei aHeightOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aHeight, aMaxSize) : Min (aHeight, aMaxSize);
const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
#if !defined(GL_ES_VERSION_2_0)
GLint aTestWidth = 0;
@ -419,8 +421,9 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
#if !defined(GL_ES_VERSION_2_0)
myTarget = GL_TEXTURE_1D;
Bind (theCtx);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
Image_PixMap aCopy;
if (aDataPtr != NULL)
@ -480,8 +483,10 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
{
myTarget = GL_TEXTURE_2D;
Bind (theCtx);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilter);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
Image_PixMap aCopy;
if (aDataPtr != NULL)
@ -548,9 +553,23 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
{
myTarget = GL_TEXTURE_2D;
myHasMipmaps = Standard_True;
GLenum aFilterMin = aFilter;
aFilterMin = GL_NEAREST_MIPMAP_NEAREST;
if (myParams->Filter() == Graphic3d_TOTF_BILINEAR)
{
aFilterMin = GL_LINEAR_MIPMAP_NEAREST;
}
else if (myParams->Filter() == Graphic3d_TOTF_TRILINEAR)
{
aFilterMin = GL_LINEAR_MIPMAP_LINEAR;
}
Bind (theCtx);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, aFilter);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, aWrapMode);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, aWrapMode);
if (theCtx->arbFBO != NULL
&& aWidth == aWidthOut && aHeight == aHeightOut)
@ -667,21 +686,16 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
#if !defined(GL_ES_VERSION_2_0)
myTarget = GL_TEXTURE_RECTANGLE;
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR;
const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp();
Bind (theCtx);
if (myParams->Filter() == Graphic3d_TOTF_NEAREST)
{
glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
else
{
glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode);
glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode);
const GLint anIntFormat = theFormat.Internal();
myTextFormat = theFormat.Format();

View File

@ -775,11 +775,11 @@ bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo,
{
theReadFbo->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
theReadFbo->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
myFullScreenQuad.BindVertexAttrib (myGlContext, 0);
myFullScreenQuad.BindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
myGlContext->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
myFullScreenQuad.UnbindVertexAttrib (myGlContext, 0);
myFullScreenQuad.UnbindVertexAttrib (myGlContext, Graphic3d_TOA_POS);
theReadFbo->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
theReadFbo->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
}