mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-07-10 12:25:50 +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_Font.hxx>
|
||||||
|
|
||||||
#include <OpenGl_Context.hxx>
|
#include <OpenGl_Context.hxx>
|
||||||
|
#include <Graphic3d_TextureParams.hxx>
|
||||||
#include <Standard_Assert.hxx>
|
#include <Standard_Assert.hxx>
|
||||||
#include <TCollection_ExtendedString.hxx>
|
#include <TCollection_ExtendedString.hxx>
|
||||||
|
|
||||||
@ -113,7 +114,13 @@ bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
|
|||||||
memset (&myLastTilePx, 0, sizeof(myLastTilePx));
|
memset (&myLastTilePx, 0, sizeof(myLastTilePx));
|
||||||
myLastTilePx.Bottom = myTileSizeY;
|
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();
|
Handle(OpenGl_Texture)& aTexture = myTextures.ChangeLast();
|
||||||
|
|
||||||
Image_PixMap aBlackImg;
|
Image_PixMap aBlackImg;
|
||||||
@ -130,10 +137,6 @@ bool OpenGl_Font::createTexture (const Handle(OpenGl_Context)& theCtx)
|
|||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,26 +69,56 @@ Standard_Boolean OpenGl_FrameBuffer::Init (const Handle(OpenGl_Context)& theGlCo
|
|||||||
myVPSizeY = theViewportSizeY;
|
myVPSizeY = theViewportSizeY;
|
||||||
|
|
||||||
// Create the textures (will be used as color buffer and depth-stencil buffer)
|
// 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->());
|
Release (theGlContext.operator->());
|
||||||
return Standard_False;
|
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
|
// Build FBO and setup it as texture
|
||||||
theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
|
theGlContext->arbFBO->glGenFramebuffers (1, &myGlFBufferId);
|
||||||
theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
|
theGlContext->arbFBO->glBindFramebuffer (GL_FRAMEBUFFER, myGlFBufferId);
|
||||||
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
|
GL_TEXTURE_2D, myColorTexture->TextureId(), 0);
|
||||||
#ifdef GL_DEPTH_STENCIL_ATTACHMENT
|
if (myDepthStencilTexture->IsValid())
|
||||||
|
{
|
||||||
|
#ifdef GL_DEPTH_STENCIL_ATTACHMENT
|
||||||
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
|
||||||
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
|
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
|
||||||
#else
|
#else
|
||||||
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
|
||||||
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
|
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
|
||||||
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
theGlContext->arbFBO->glFramebufferTexture2D (GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
|
||||||
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
|
GL_TEXTURE_2D, myDepthStencilTexture->TextureId(), 0);
|
||||||
#endif
|
#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)
|
if (theGlContext->arbFBO->glCheckFramebufferStatus (GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
{
|
{
|
||||||
Release (theGlContext.operator->());
|
Release (theGlContext.operator->());
|
||||||
@ -287,20 +317,6 @@ void OpenGl_FrameBuffer::Release (OpenGl_Context* theGlCtx)
|
|||||||
myDepthStencilTexture->Release (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
|
// function : SetupViewport
|
||||||
// purpose :
|
// purpose :
|
||||||
|
@ -153,9 +153,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
//! Generate textures with undefined data
|
|
||||||
Standard_Boolean initTrashTextures (const Handle(OpenGl_Context)& theGlContext);
|
|
||||||
|
|
||||||
Standard_Boolean isValidFrameBuffer() const
|
Standard_Boolean isValidFrameBuffer() const
|
||||||
{
|
{
|
||||||
return myGlFBufferId != NO_FRAMEBUFFER;
|
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 bool toForceP2 = !theCtx->IsGlGreaterEqual (3, 0) && !theCtx->arbNPTW;
|
||||||
const GLsizei aWidthOut = toForceP2 ? OpenGl_Context::GetPowerOfTwo (aWidth, aMaxSize) : Min (aWidth, aMaxSize);
|
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 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)
|
#if !defined(GL_ES_VERSION_2_0)
|
||||||
GLint aTestWidth = 0;
|
GLint aTestWidth = 0;
|
||||||
@ -419,8 +421,9 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
|||||||
#if !defined(GL_ES_VERSION_2_0)
|
#if !defined(GL_ES_VERSION_2_0)
|
||||||
myTarget = GL_TEXTURE_1D;
|
myTarget = GL_TEXTURE_1D;
|
||||||
Bind (theCtx);
|
Bind (theCtx);
|
||||||
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, aFilter);
|
||||||
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, aFilter);
|
||||||
|
glTexParameteri (GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, aWrapMode);
|
||||||
|
|
||||||
Image_PixMap aCopy;
|
Image_PixMap aCopy;
|
||||||
if (aDataPtr != NULL)
|
if (aDataPtr != NULL)
|
||||||
@ -480,8 +483,10 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
|||||||
{
|
{
|
||||||
myTarget = GL_TEXTURE_2D;
|
myTarget = GL_TEXTURE_2D;
|
||||||
Bind (theCtx);
|
Bind (theCtx);
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilter);
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
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;
|
Image_PixMap aCopy;
|
||||||
if (aDataPtr != NULL)
|
if (aDataPtr != NULL)
|
||||||
@ -548,9 +553,23 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
|||||||
{
|
{
|
||||||
myTarget = GL_TEXTURE_2D;
|
myTarget = GL_TEXTURE_2D;
|
||||||
myHasMipmaps = Standard_True;
|
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);
|
Bind (theCtx);
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, aFilterMin);
|
||||||
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
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
|
if (theCtx->arbFBO != NULL
|
||||||
&& aWidth == aWidthOut && aHeight == aHeightOut)
|
&& aWidth == aWidthOut && aHeight == aHeightOut)
|
||||||
@ -669,19 +688,14 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
|
|||||||
|
|
||||||
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
|
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
|
||||||
const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
|
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);
|
Bind (theCtx);
|
||||||
|
glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
|
||||||
if (myParams->Filter() == Graphic3d_TOTF_NEAREST)
|
glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
|
||||||
{
|
glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode);
|
||||||
glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
const GLint anIntFormat = theFormat.Internal();
|
const GLint anIntFormat = theFormat.Internal();
|
||||||
myTextFormat = theFormat.Format();
|
myTextFormat = theFormat.Format();
|
||||||
|
@ -775,11 +775,11 @@ bool OpenGl_Workspace::blitBuffers (OpenGl_FrameBuffer* theReadFbo,
|
|||||||
{
|
{
|
||||||
theReadFbo->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
|
theReadFbo->ColorTexture() ->Bind (myGlContext, GL_TEXTURE0 + 0);
|
||||||
theReadFbo->DepthStencilTexture()->Bind (myGlContext, GL_TEXTURE0 + 1);
|
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);
|
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->DepthStencilTexture()->Unbind (myGlContext, GL_TEXTURE0 + 1);
|
||||||
theReadFbo->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
|
theReadFbo->ColorTexture() ->Unbind (myGlContext, GL_TEXTURE0 + 0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user