From a4c29e8425bb275c51bf5b399ef555e7351e4c7a Mon Sep 17 00:00:00 2001 From: duv Date: Fri, 25 Mar 2016 12:41:49 +0300 Subject: [PATCH] OpenGl_Texture API extended. --- src/OpenGl/OpenGl_Texture.cxx | 99 ++++++++++++++++++++++++++ src/OpenGl/OpenGl_Texture.hxx | 9 +++ src/OpenGl/OpenGl_TextureBufferArb.cxx | 92 ++++++++++++++++++++++++ src/OpenGl/OpenGl_TextureBufferArb.hxx | 14 ++++ 4 files changed, 214 insertions(+) diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index a35e65384f..7511909d60 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -919,3 +919,102 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx, Unbind (theCtx); return true; } + +// ======================================================================= +// function : Init2D +// purpose : +// ======================================================================= +bool OpenGl_Texture::Init2D (const Handle(OpenGl_Context)& theCtx, + const GLint theTextFormat, + const GLenum thePixelFormat, + const GLenum theDataType, + const Standard_Integer theSizeX, + const Standard_Integer theSizeY, + const void* thePixels) +{ + if (!Create(theCtx)) + { + return false; + } + + myTarget = GL_TEXTURE_2D; + + const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX); + const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY); + + Bind (theCtx); + + if (theDataType == GL_FLOAT && !theCtx->arbTexFloat) + { + TCollection_ExtendedString aMsg ("Error: floating-point textures are not supported by hardware."); + + theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, + GL_DEBUG_TYPE_ERROR, + 0, + GL_DEBUG_SEVERITY_HIGH, + aMsg); + + Release (theCtx.operator->()); + Unbind (theCtx); + return false; + } + + const GLint anIntFormat = theTextFormat; + +#if !defined (GL_ES_VERSION_2_0) + theCtx->core15fwd->glTexImage2D (GL_PROXY_TEXTURE_2D, + 0, + anIntFormat, + aSizeX, + aSizeY, + 0, + thePixelFormat, + theDataType, + NULL); + + GLint aTestSizeX = 0; + GLint aTestSizeY = 0; + + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestSizeX); + glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestSizeY); + + if (aTestSizeX == 0 || aTestSizeY == 0) + { + Unbind (theCtx); + Release (theCtx.operator->()); + return false; + } +#endif + + const GLenum aWrapMode = myParams->IsRepeat() ? GL_REPEAT : theCtx->TextureWrapClamp(); + const GLenum aFilter = (myParams->Filter() == Graphic3d_TOTF_NEAREST) ? GL_NEAREST : GL_LINEAR; + + glTexParameteri (myTarget, GL_TEXTURE_WRAP_S, aWrapMode); + glTexParameteri (myTarget, GL_TEXTURE_WRAP_T, aWrapMode); + + glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter); + glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter); + + theCtx->core15fwd->glTexImage2D (myTarget, + 0, + anIntFormat, + aSizeX, + aSizeY, + 0, + thePixelFormat, + theDataType, + thePixels); + + if (glGetError() != GL_NO_ERROR) + { + Unbind (theCtx); + Release (theCtx.operator->()); + return false; + } + + mySizeX = aSizeX; + mySizeY = aSizeY; + + Unbind (theCtx); + return true; +} diff --git a/src/OpenGl/OpenGl_Texture.hxx b/src/OpenGl/OpenGl_Texture.hxx index c7242b0628..7921dff0cb 100644 --- a/src/OpenGl/OpenGl_Texture.hxx +++ b/src/OpenGl/OpenGl_Texture.hxx @@ -404,6 +404,15 @@ public: const Standard_Integer theSizeZ, const void* thePixels); + //! Initializes 2D texture with specified format and size. + Standard_EXPORT bool Init2D (const Handle(OpenGl_Context)& theCtx, + const GLint theTextFormat, + const GLenum thePixelFormat, + const GLenum theDataType, + const Standard_Integer theSizeX, + const Standard_Integer theSizeY, + const void* thePixels); + //! @return true if texture was generated within mipmaps Standard_EXPORT Standard_Boolean HasMipmaps() const; diff --git a/src/OpenGl/OpenGl_TextureBufferArb.cxx b/src/OpenGl/OpenGl_TextureBufferArb.cxx index 964a66bee4..6c3f552f47 100644 --- a/src/OpenGl/OpenGl_TextureBufferArb.cxx +++ b/src/OpenGl/OpenGl_TextureBufferArb.cxx @@ -181,6 +181,98 @@ bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx, return true; } +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const GLushort* theData) +{ + if (theGlCtx->arbTBO == NULL) + { + return false; + } + else if (theComponentsNb < 1 + || theComponentsNb > 4) + { + // unsupported format + return false; + } + else if (theComponentsNb == 3 + && !theGlCtx->arbTboRGB32) + { + return false; + } + else if (!Create (theGlCtx) + || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData)) + { + return false; + } + + switch (theComponentsNb) + { + case 1: myTexFormat = GL_R16I; break; + case 2: myTexFormat = GL_RG16I; break; + case 3: myTexFormat = GL_RGB16I; break; + case 4: myTexFormat = GL_RGBA16I; break; + } + + Bind (theGlCtx); + BindTexture (theGlCtx); + theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId); + UnbindTexture (theGlCtx); + Unbind (theGlCtx); + return true; +} + +// ======================================================================= +// function : Init +// purpose : +// ======================================================================= +bool OpenGl_TextureBufferArb::Init (const Handle(OpenGl_Context)& theGlCtx, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const GLubyte* theData) +{ + if (theGlCtx->arbTBO == NULL) + { + return false; + } + else if (theComponentsNb < 1 + || theComponentsNb > 4) + { + // unsupported format + return false; + } + else if (theComponentsNb == 3 + && !theGlCtx->arbTboRGB32) + { + return false; + } + else if (!Create (theGlCtx) + || !OpenGl_VertexBuffer::Init (theGlCtx, theComponentsNb, theElemsNb, theData)) + { + return false; + } + + switch (theComponentsNb) + { + case 1: myTexFormat = GL_R8; break; + case 2: myTexFormat = GL_RG8; break; + case 3: myTexFormat = GL_RGB8; break; + case 4: myTexFormat = GL_RGBA8; break; + } + + Bind (theGlCtx); + BindTexture (theGlCtx); + theGlCtx->arbTBO->glTexBuffer (GetTarget(), myTexFormat, myBufferId); + UnbindTexture (theGlCtx); + Unbind (theGlCtx); + return true; +} + // ======================================================================= // function : BindTexture // purpose : diff --git a/src/OpenGl/OpenGl_TextureBufferArb.hxx b/src/OpenGl/OpenGl_TextureBufferArb.hxx index 7b0a51256c..d375f7b2c7 100644 --- a/src/OpenGl/OpenGl_TextureBufferArb.hxx +++ b/src/OpenGl/OpenGl_TextureBufferArb.hxx @@ -76,6 +76,20 @@ public: const GLsizei theElemsNb, const GLuint* theData); + //! Perform TBO initialization with specified data. + //! Existing data will be deleted. + Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const GLushort* theData); + + //! Perform TBO initialization with specified data. + //! Existing data will be deleted. + Standard_EXPORT bool Init (const Handle(OpenGl_Context)& theGlCtx, + const GLuint theComponentsNb, + const GLsizei theElemsNb, + const GLubyte* theData); + //! Bind TBO to specified Texture Unit. Standard_EXPORT void BindTexture (const Handle(OpenGl_Context)& theGlCtx, const GLenum theTextureUnit = GL_TEXTURE0) const; -- 2.39.5