#include <OpenGl_ArbFBO.hxx>
#include <OpenGl_Context.hxx>
#include <OpenGl_GlCore32.hxx>
+#include <OpenGl_Sampler.hxx>
#include <Graphic3d_TextureParams.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Standard_Assert.hxx>
#include <Image_PixMap.hxx>
-
-IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture,OpenGl_Resource)
+IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource)
//! Simple class to reset unpack alignment settings
struct OpenGl_UnpackAlignmentSentry
{
//! Reset unpack alignment settings to safe values
- void Reset()
+ static void Reset()
{
glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
#if !defined(GL_ES_VERSION_2_0)
#endif
}
+ OpenGl_UnpackAlignmentSentry() {}
+
~OpenGl_UnpackAlignmentSentry()
{
Reset();
// function : OpenGl_Texture
// purpose :
// =======================================================================
-OpenGl_Texture::OpenGl_Texture (const Handle(Graphic3d_TextureParams)& theParams)
-: OpenGl_Resource(),
+OpenGl_Texture::OpenGl_Texture (const TCollection_AsciiString& theResourceId,
+ const Handle(Graphic3d_TextureParams)& theParams)
+: OpenGl_NamedResource (theResourceId),
+ mySampler (new OpenGl_Sampler (theParams)),
myRevision (0),
myTextureId (NO_TEXTURE),
myTarget (GL_TEXTURE_2D),
mySizeY (0),
mySizeZ (0),
myTextFormat (GL_RGBA),
+ mySizedFormat(GL_RGBA8),
+ myNbSamples (1),
myHasMipmaps (Standard_False),
- myIsAlpha (false),
- myParams (theParams)
+ myIsAlpha (false)
{
- if (myParams.IsNull())
- {
- myParams = new Graphic3d_TextureParams();
- }
+ //
}
// =======================================================================
Release (NULL);
}
-// =======================================================================
-// function : HasMipmaps
-// purpose :
-// =======================================================================
-Standard_Boolean OpenGl_Texture::HasMipmaps() const
-{
- return myHasMipmaps;
-}
-
-// =======================================================================
-// function : GetParams
-// purpose :
-// =======================================================================
-const Handle(Graphic3d_TextureParams)& OpenGl_Texture::GetParams() const
-{
- return myParams;
-}
-
-// =======================================================================
-// function : SetParams
-// purpose :
-// =======================================================================
-void OpenGl_Texture::SetParams (const Handle(Graphic3d_TextureParams)& theParams)
-{
- myParams = theParams;
-}
-
// =======================================================================
// function : Create
// purpose :
// =======================================================================
-bool OpenGl_Texture::Create (const Handle(OpenGl_Context)& )
+bool OpenGl_Texture::Create (const Handle(OpenGl_Context)& theCtx)
{
+ if (myTextureId != NO_TEXTURE)
+ {
+ return true;
+ }
+
+ theCtx->core11fwd->glGenTextures (1, &myTextureId);
if (myTextureId == NO_TEXTURE)
{
- glGenTextures (1, &myTextureId);
+ return false;
}
- return myTextureId != NO_TEXTURE;
+
+ //mySampler->Create (theCtx); // do not create sampler object by default
+ return true;
}
// =======================================================================
// =======================================================================
void OpenGl_Texture::Release (OpenGl_Context* theGlCtx)
{
+ mySampler->Release (theGlCtx);
if (myTextureId == NO_TEXTURE)
{
return;
mySizeX = mySizeY = mySizeZ = 0;
}
+// =======================================================================
+// function : applyDefaultSamplerParams
+// purpose :
+// =======================================================================
+void OpenGl_Texture::applyDefaultSamplerParams (const Handle(OpenGl_Context)& theCtx)
+{
+ OpenGl_Sampler::applySamplerParams (theCtx, mySampler->Parameters(), NULL, myTarget, myHasMipmaps);
+ if (mySampler->IsValid() && !mySampler->IsImmutable())
+ {
+ OpenGl_Sampler::applySamplerParams (theCtx, mySampler->Parameters(), mySampler.get(), myTarget, myHasMipmaps);
+ }
+}
+
// =======================================================================
// function : Bind
// purpose :
// =======================================================================
void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
- const GLenum theTextureUnit) const
+ const Graphic3d_TextureUnit theTextureUnit) const
{
if (theCtx->core15fwd != NULL)
{
- theCtx->core15fwd->glActiveTexture (theTextureUnit);
+ theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
}
+ mySampler->Bind (theCtx, theTextureUnit);
glBindTexture (myTarget, myTextureId);
}
// purpose :
// =======================================================================
void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
- const GLenum theTextureUnit) const
+ const Graphic3d_TextureUnit theTextureUnit) const
{
if (theCtx->core15fwd != NULL)
{
- theCtx->core15fwd->glActiveTexture (theTextureUnit);
+ theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
}
+ mySampler->Unbind (theCtx, theTextureUnit);
glBindTexture (myTarget, NO_TEXTURE);
}
+//=======================================================================
+//function : InitSamplerObject
+//purpose :
+//=======================================================================
+bool OpenGl_Texture::InitSamplerObject (const Handle(OpenGl_Context)& theCtx)
+{
+ return myTextureId != NO_TEXTURE
+ && mySampler->Init (theCtx, *this);
+}
+
//=======================================================================
//function : GetDataFormat
//purpose :
const Graphic3d_TypeOfTexture theType,
const Image_PixMap* theImage)
{
+ if (theSizeX < 1
+ || theSizeY < 1)
+ {
+ theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
+ "Error: texture of 0 size cannot be created.");
+ Release (theCtx.operator->());
+ return false;
+ }
+
#if !defined(GL_ES_VERSION_2_0)
const GLenum aTarget = theType == Graphic3d_TOT_1D
? GL_TEXTURE_1D
myHasMipmaps = toCreateMipMaps;
myTextFormat = thePixelFormat;
+ mySizedFormat = theTextFormat;
+ myNbSamples = 1;
#if !defined(GL_ES_VERSION_2_0)
const GLint anIntFormat = theTextFormat;
#else
}
#endif
- 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;
GLint aTestHeight = 0;
{
#if !defined(GL_ES_VERSION_2_0)
Bind (theCtx);
- 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);
+ applyDefaultSamplerParams (theCtx);
if (toPatchExisting)
{
glTexSubImage1D (GL_TEXTURE_1D, 0, 0,
theSizeX, 0,
thePixelFormat, theDataType, NULL);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
+ glGetTexLevelParameteriv (GL_PROXY_TEXTURE_1D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestWidth == 0)
{
// no memory or broken input parameters
case Graphic3d_TOT_2D:
{
Bind (theCtx);
- 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);
+ applyDefaultSamplerParams (theCtx);
if (toPatchExisting)
{
glTexSubImage2D (GL_TEXTURE_2D, 0,
thePixelFormat, theDataType, NULL);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
+ glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestWidth == 0 || aTestHeight == 0)
{
// no memory or broken input parameters
}
case Graphic3d_TOT_2D_MIPMAP:
{
- 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, 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);
+ applyDefaultSamplerParams (theCtx);
if (toPatchExisting)
{
glTexSubImage2D (GL_TEXTURE_2D, 0,
thePixelFormat, theDataType, NULL);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &aTestWidth);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &aTestHeight);
+ glGetTexLevelParameteriv (GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestWidth == 0 || aTestHeight == 0)
{
// no memory or broken input parameters
return false;
}
- const GLsizei aNbSamples = OpenGl_Context::GetPowerOfTwo (theNbSamples, theCtx->MaxMsaaSamples());
+ myNbSamples = OpenGl_Context::GetPowerOfTwo (theNbSamples, theCtx->MaxMsaaSamples());
myTarget = GL_TEXTURE_2D_MULTISAMPLE;
+ myHasMipmaps = false;
if(theSizeX > theCtx->MaxTextureSize()
|| theSizeY > theCtx->MaxTextureSize())
{
Bind (theCtx);
//myTextFormat = theTextFormat;
+ mySizedFormat = theTextFormat;
#if !defined(GL_ES_VERSION_2_0)
if (theCtx->Functions()->glTexStorage2DMultisample != NULL)
{
- theCtx->Functions()->glTexStorage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
+ theCtx->Functions()->glTexStorage2DMultisample (myTarget, myNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
}
else
{
- theCtx->Functions()->glTexImage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
+ theCtx->Functions()->glTexImage2DMultisample (myTarget, myNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
}
#else
- theCtx->Functions() ->glTexStorage2DMultisample (myTarget, aNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
+ theCtx->Functions() ->glTexStorage2DMultisample (myTarget, myNbSamples, theTextFormat, theSizeX, theSizeY, GL_FALSE);
#endif
if (theCtx->core11fwd->glGetError() != GL_NO_ERROR)
{
#if !defined(GL_ES_VERSION_2_0)
myTarget = GL_TEXTURE_RECTANGLE;
+ myNbSamples = 1;
+ myHasMipmaps = false;
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);
- 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();
-
- glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE,
- 0,
- anIntFormat,
- aSizeX,
- aSizeY,
- 0,
- theFormat.Format(),
- GL_FLOAT,
- NULL);
+ applyDefaultSamplerParams (theCtx);
+
+ myTextFormat = theFormat.Format();
+ mySizedFormat = theFormat.Internal();
+
+ // setup the alignment
+ OpenGl_UnpackAlignmentSentry::Reset();
+
+ glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE, 0, mySizedFormat,
+ aSizeX, aSizeY, 0,
+ myTextFormat, GL_FLOAT, NULL);
GLint aTestSizeX = 0;
GLint aTestSizeY = 0;
- glGetTexLevelParameteriv (
- GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
- glGetTexLevelParameteriv (
- GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
+ glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
+ glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
+ glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestSizeX == 0 || aTestSizeY == 0)
{
return false;
}
- glTexImage2D (myTarget,
- 0,
- anIntFormat,
- aSizeX,
- aSizeY,
- 0,
- theFormat.Format(),
- GL_FLOAT,
- NULL);
+ glTexImage2D (myTarget, 0, mySizedFormat,
+ aSizeX, aSizeY, 0,
+ myTextFormat, GL_FLOAT, NULL);
if (glGetError() != GL_NO_ERROR)
{
}
myTarget = GL_TEXTURE_3D;
+ myNbSamples = 1;
+ myHasMipmaps = false;
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
return false;
}
- const GLint anIntFormat = theTextFormat;
+ mySizedFormat = theTextFormat;
+
+ // setup the alignment
+ OpenGl_UnpackAlignmentSentry::Reset();
#if !defined (GL_ES_VERSION_2_0)
- theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D,
- 0,
- anIntFormat,
- aSizeX,
- aSizeY,
- aSizeZ,
- 0,
- thePixelFormat,
- theDataType,
- NULL);
+ theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D, 0, mySizedFormat,
+ aSizeX, aSizeY, aSizeZ, 0,
+ thePixelFormat, theDataType, NULL);
GLint aTestSizeX = 0;
GLint aTestSizeY = 0;
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeX);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeY);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeZ);
+ glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestSizeX == 0 || aTestSizeY == 0 || aTestSizeZ == 0)
{
}
#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_WRAP_R, aWrapMode);
-
- glTexParameteri (myTarget, GL_TEXTURE_MIN_FILTER, aFilter);
- glTexParameteri (myTarget, GL_TEXTURE_MAG_FILTER, aFilter);
-
- theCtx->Functions()->glTexImage3D (myTarget,
- 0,
- anIntFormat,
- aSizeX,
- aSizeY,
- aSizeZ,
- 0,
- thePixelFormat,
- theDataType,
- thePixels);
+ applyDefaultSamplerParams (theCtx);
+ theCtx->Functions()->glTexImage3D (myTarget, 0, mySizedFormat,
+ aSizeX, aSizeY, aSizeZ, 0,
+ thePixelFormat, theDataType, thePixels);
if (glGetError() != GL_NO_ERROR)
{
Unbind (theCtx);
return true;
}
+
+// =======================================================================
+// function : PixelSizeOfPixelFormat
+// purpose :
+// =======================================================================
+Standard_Size OpenGl_Texture::PixelSizeOfPixelFormat (Standard_Integer theInternalFormat)
+{
+ switch(theInternalFormat)
+ {
+ // RED variations (GL_RED, OpenGL 3.0+)
+ case GL_RED:
+ case GL_R8: return 1;
+ case GL_R16: return 2;
+ case GL_R16F: return 2;
+ case GL_R32F: return 4;
+ // RGB variations
+ case GL_RGB: return 3;
+ case GL_RGB8: return 3;
+ case GL_RGB16: return 6;
+ case GL_RGB16F: return 6;
+ case GL_RGB32F: return 12;
+ // RGBA variations
+ case GL_RGBA: return 4;
+ case GL_RGBA8: return 4;
+ case GL_RGB10_A2: return 4;
+ case GL_RGBA12: return 6;
+ case GL_RGBA16: return 8;
+ case GL_RGBA16F: return 8;
+ case GL_RGBA32F: return 16;
+ //
+ case GL_BGRA_EXT: return 4;
+ // ALPHA variations (deprecated)
+ case GL_ALPHA:
+ case GL_ALPHA8: return 1;
+ case GL_ALPHA16: return 2;
+ case GL_LUMINANCE: return 1;
+ case GL_LUMINANCE_ALPHA: return 2;
+ // depth-stencil
+ case GL_DEPTH24_STENCIL8: return 4;
+ case GL_DEPTH32F_STENCIL8: return 8;
+ case GL_DEPTH_COMPONENT16: return 2;
+ case GL_DEPTH_COMPONENT24: return 3;
+ case GL_DEPTH_COMPONENT32F: return 4;
+ }
+ return 0;
+}
+
+// =======================================================================
+// function : EstimatedDataSize
+// purpose :
+// =======================================================================
+Standard_Size OpenGl_Texture::EstimatedDataSize() const
+{
+ if (!IsValid())
+ {
+ return 0;
+ }
+
+ Standard_Size aSize = PixelSizeOfPixelFormat (mySizedFormat) * mySizeX * myNbSamples;
+ if (mySizeY != 0)
+ {
+ aSize *= Standard_Size(mySizeY);
+ }
+ if (mySizeZ != 0)
+ {
+ aSize *= Standard_Size(mySizeZ);
+ }
+ if (myHasMipmaps)
+ {
+ aSize = aSize + aSize / 3;
+ }
+ return aSize;
+}