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:
parent
2ff806d1ab
commit
fe3a29bc9a
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 :
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user