From fe3a29bc9a8107aa16d99a41f1e7f9761c17c1f1 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 6 May 2015 16:05:47 +0300 Subject: [PATCH] 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. --- src/OpenGl/OpenGl_Font.cxx | 13 ++++--- src/OpenGl/OpenGl_FrameBuffer.cxx | 64 +++++++++++++++++++------------ src/OpenGl/OpenGl_FrameBuffer.hxx | 3 -- src/OpenGl/OpenGl_Texture.cxx | 52 ++++++++++++++++--------- src/OpenGl/OpenGl_Workspace.cxx | 4 +- 5 files changed, 83 insertions(+), 53 deletions(-) diff --git a/src/OpenGl/OpenGl_Font.cxx b/src/OpenGl/OpenGl_Font.cxx index c29f3c7874..1a17c604ab 100755 --- a/src/OpenGl/OpenGl_Font.cxx +++ b/src/OpenGl/OpenGl_Font.cxx @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -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; } diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index 59f99c813b..2e0c192c84 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -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 : diff --git a/src/OpenGl/OpenGl_FrameBuffer.hxx b/src/OpenGl/OpenGl_FrameBuffer.hxx index 799b2920bd..c2f03d6f84 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.hxx +++ b/src/OpenGl/OpenGl_FrameBuffer.hxx @@ -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; diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index 6d752b2787..32a837fb87 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -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(); diff --git a/src/OpenGl/OpenGl_Workspace.cxx b/src/OpenGl/OpenGl_Workspace.cxx index 237ece8dc4..b93bd86b37 100644 --- a/src/OpenGl/OpenGl_Workspace.cxx +++ b/src/OpenGl/OpenGl_Workspace.cxx @@ -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); } -- 2.39.5