mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-08 14:17:06 +03:00
0029528: Visualization, TKOpenGl - allow defining sRGB textures
OpenGL rendering is now done into sRGB framebuffer. OpenGl_ShaderManager::prepareStdProgramFboBlit() has been extended by programs resolving MSAA texture and applying gamma correction as fallbacks. Quantity_Color definition has been modified to store RGB components in linear color space within Quantity_TOC_RGB type. Standard colors defined by Quantity_NameOfColor enumeration has been updated accordingly. New Quantity_TOC_sRGB type has been introduced to handle RGB components in non-linear sRGB color space. OpenGl_TextureFormat class definition has been moved to dedicated files. New method OpenGl_TextureFormat::FindFormat() replaces OpenGl_Texture::GetDataFormat(). New method OpenGl_TextureFormat::FindSizedFormat() replaces OpenGl_FrameBuffer::getColorDataFormat() and OpenGl_FrameBuffer::getDepthDataFormat(). Graphic3d_TextureRoot::IsColorMap() - introduced new property defining if RGB(A)8 image formats should be loaded as sRGB(A) textures or as data RGB(A) textures. OpenGl_Texture initialization methods have been extended with new theIsColorMap argument. vreadpixel - added argument -sRGB printing color in sRGB color space. Test cases have been updated to new sRGB rendered results.
This commit is contained in:
@@ -177,240 +177,22 @@ bool OpenGl_Texture::InitSamplerObject (const Handle(OpenGl_Context)& theCtx)
|
||||
&& mySampler->Init (theCtx, *this);
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetDataFormat
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
bool OpenGl_Texture::GetDataFormat (const Handle(OpenGl_Context)& theCtx,
|
||||
const Image_Format theFormat,
|
||||
GLint& theTextFormat,
|
||||
GLenum& thePixelFormat,
|
||||
GLenum& theDataType)
|
||||
{
|
||||
theTextFormat = GL_RGBA8;
|
||||
thePixelFormat = 0;
|
||||
theDataType = 0;
|
||||
switch (theFormat)
|
||||
{
|
||||
case Image_Format_GrayF:
|
||||
{
|
||||
if (theCtx->core11 == NULL)
|
||||
{
|
||||
theTextFormat = GL_R8; // GL_R32F
|
||||
thePixelFormat = GL_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
theTextFormat = GL_LUMINANCE8;
|
||||
#else
|
||||
theTextFormat = GL_LUMINANCE;
|
||||
#endif
|
||||
thePixelFormat = GL_LUMINANCE;
|
||||
}
|
||||
theDataType = GL_FLOAT;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_AlphaF:
|
||||
{
|
||||
if (theCtx->core11 == NULL)
|
||||
{
|
||||
theTextFormat = GL_R8; // GL_R32F
|
||||
thePixelFormat = GL_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
theTextFormat = GL_ALPHA8;
|
||||
#else
|
||||
theTextFormat = GL_ALPHA;
|
||||
#endif
|
||||
thePixelFormat = GL_ALPHA;
|
||||
}
|
||||
theDataType = GL_FLOAT;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_RGBAF:
|
||||
{
|
||||
theTextFormat = GL_RGBA8; // GL_RGBA32F
|
||||
thePixelFormat = GL_RGBA;
|
||||
theDataType = GL_FLOAT;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_BGRAF:
|
||||
{
|
||||
if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theTextFormat = GL_RGBA8; // GL_RGBA32F
|
||||
thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
|
||||
theDataType = GL_FLOAT;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_RGBF:
|
||||
{
|
||||
theTextFormat = GL_RGB8; // GL_RGB32F
|
||||
thePixelFormat = GL_RGB;
|
||||
theDataType = GL_FLOAT;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_BGRF:
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
theTextFormat = GL_RGB8; // GL_RGB32F
|
||||
thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
|
||||
theDataType = GL_FLOAT;
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
case Image_Format_RGBA:
|
||||
{
|
||||
theTextFormat = GL_RGBA8;
|
||||
thePixelFormat = GL_RGBA;
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_BGRA:
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theTextFormat = GL_RGBA8;
|
||||
#else
|
||||
if (!theCtx->extBgra)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theTextFormat = GL_BGRA_EXT;
|
||||
#endif
|
||||
thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_RGB32:
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
// ask driver to convert data to RGB8 to save memory
|
||||
theTextFormat = GL_RGB8;
|
||||
#else
|
||||
// conversion is not supported
|
||||
theTextFormat = GL_RGBA8;
|
||||
#endif
|
||||
thePixelFormat = GL_RGBA;
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_BGR32:
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (!theCtx->IsGlGreaterEqual(1, 2) && !theCtx->extBgra)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theTextFormat = GL_RGB8;
|
||||
#else
|
||||
if (!theCtx->extBgra)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theTextFormat = GL_BGRA_EXT;
|
||||
#endif
|
||||
thePixelFormat = GL_BGRA_EXT; // equals to GL_BGRA
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_RGB:
|
||||
{
|
||||
theTextFormat = GL_RGB8;
|
||||
thePixelFormat = GL_RGB;
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_BGR:
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
if (!theCtx->IsGlGreaterEqual (1, 2) && !theCtx->extBgra)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
theTextFormat = GL_RGB8;
|
||||
thePixelFormat = GL_BGR; // equals to GL_BGR_EXT
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
case Image_Format_Gray:
|
||||
{
|
||||
if (theCtx->core11 == NULL)
|
||||
{
|
||||
theTextFormat = GL_R8;
|
||||
thePixelFormat = GL_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
theTextFormat = GL_LUMINANCE8;
|
||||
#else
|
||||
theTextFormat = GL_LUMINANCE;
|
||||
#endif
|
||||
thePixelFormat = GL_LUMINANCE;
|
||||
}
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_Alpha:
|
||||
{
|
||||
if (theCtx->core11 == NULL)
|
||||
{
|
||||
theTextFormat = GL_R8;
|
||||
thePixelFormat = GL_RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
theTextFormat = GL_ALPHA8;
|
||||
#else
|
||||
theTextFormat = GL_ALPHA;
|
||||
#endif
|
||||
thePixelFormat = GL_ALPHA;
|
||||
}
|
||||
theDataType = GL_UNSIGNED_BYTE;
|
||||
return true;
|
||||
}
|
||||
case Image_Format_UNKNOWN:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : Init
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
const Standard_Integer theTextFormat,
|
||||
const GLenum thePixelFormat,
|
||||
const GLenum theDataType,
|
||||
const Standard_Integer theSizeX,
|
||||
const Standard_Integer theSizeY,
|
||||
const OpenGl_TextureFormat& theFormat,
|
||||
const Graphic3d_Vec2i& theSizeXY,
|
||||
const Graphic3d_TypeOfTexture theType,
|
||||
const Image_PixMap* theImage)
|
||||
{
|
||||
if (theSizeX < 1
|
||||
|| theSizeY < 1)
|
||||
if (theSizeXY.x() < 1
|
||||
|| theSizeXY.y() < 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->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -423,14 +205,14 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
#endif
|
||||
const Standard_Boolean toCreateMipMaps = (theType == Graphic3d_TOT_2D_MIPMAP);
|
||||
const bool toPatchExisting = IsValid()
|
||||
&& myTextFormat == thePixelFormat
|
||||
&& myTextFormat == theFormat.PixelFormat()
|
||||
&& myTarget == aTarget
|
||||
&& myHasMipmaps == toCreateMipMaps
|
||||
&& mySizeX == theSizeX
|
||||
&& (mySizeY == theSizeY || theType == Graphic3d_TOT_1D);
|
||||
&& mySizeX == theSizeXY.x()
|
||||
&& (mySizeY == theSizeXY.y() || theType == Graphic3d_TOT_1D);
|
||||
if (!Create (theCtx))
|
||||
{
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -441,37 +223,37 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
}
|
||||
else
|
||||
{
|
||||
myIsAlpha = thePixelFormat == GL_ALPHA;
|
||||
myIsAlpha = theFormat.PixelFormat() == GL_ALPHA;
|
||||
}
|
||||
|
||||
myHasMipmaps = toCreateMipMaps;
|
||||
myTextFormat = thePixelFormat;
|
||||
mySizedFormat = theTextFormat;
|
||||
myTextFormat = theFormat.PixelFormat();
|
||||
mySizedFormat = theFormat.InternalFormat();
|
||||
myNbSamples = 1;
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
const GLint anIntFormat = theTextFormat;
|
||||
const GLint anIntFormat = theFormat.InternalFormat();
|
||||
#else
|
||||
// ES 2.0 does not support sized formats and format conversions - them detected from data type
|
||||
const GLint anIntFormat = theCtx->IsGlGreaterEqual (3, 0) ? theTextFormat : thePixelFormat;
|
||||
const GLint anIntFormat = theCtx->IsGlGreaterEqual (3, 0) ? theFormat.InternalFormat() : theFormat.PixelFormat();
|
||||
#endif
|
||||
|
||||
if (theDataType == GL_FLOAT && !theCtx->arbTexFloat)
|
||||
if (theFormat.DataType() == GL_FLOAT
|
||||
&& !theCtx->arbTexFloat)
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Error: floating-point textures are not supported by hardware.");
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
const GLsizei aMaxSize = theCtx->MaxTextureSize();
|
||||
if (theSizeX > aMaxSize
|
||||
|| theSizeY > aMaxSize)
|
||||
if (theSizeXY.x() > aMaxSize
|
||||
|| theSizeXY.y() > aMaxSize)
|
||||
{
|
||||
TCollection_ExtendedString aWarnMessage = TCollection_ExtendedString ("Error: Texture dimension - ")
|
||||
+ theSizeX + "x" + theSizeY + " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")";
|
||||
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
|
||||
Release (theCtx.operator->());
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Error: Texture dimension - ") + theSizeXY.x() + "x" + theSizeXY.y()
|
||||
+ " exceeds hardware limits (" + aMaxSize + "x" + aMaxSize + ")");
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
@@ -481,18 +263,15 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
// however some hardware (NV30 - GeForce FX, RadeOn 9xxx and Xxxx) supports GLSL but not NPOT!
|
||||
// Trying to create NPOT textures on such hardware will not fail
|
||||
// but driver will fall back into software rendering,
|
||||
const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize);
|
||||
const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize);
|
||||
|
||||
if (theSizeX != aWidthP2
|
||||
|| (theType != Graphic3d_TOT_1D && theSizeY != aHeightP2))
|
||||
const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.x(), aMaxSize);
|
||||
const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.y(), aMaxSize);
|
||||
if (theSizeXY.x() != aWidthP2
|
||||
|| (theType != Graphic3d_TOT_1D && theSizeXY.y() != aHeightP2))
|
||||
{
|
||||
TCollection_ExtendedString aWarnMessage =
|
||||
TCollection_ExtendedString ("Error: NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by hardware.";
|
||||
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
|
||||
|
||||
Release (theCtx.operator->());
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Error: NPOT Textures (") + theSizeXY.x() + "x" + theSizeXY.y() + ")"
|
||||
" are not supported by hardware.");
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -500,18 +279,15 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
else if (!theCtx->IsGlGreaterEqual (3, 0) && theType == Graphic3d_TOT_2D_MIPMAP)
|
||||
{
|
||||
// Mipmap NPOT textures are not supported by OpenGL ES 2.0.
|
||||
const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeX, aMaxSize);
|
||||
const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeY, aMaxSize);
|
||||
|
||||
if (theSizeX != aWidthP2
|
||||
|| theSizeY != aHeightP2)
|
||||
const GLsizei aWidthP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.x(), aMaxSize);
|
||||
const GLsizei aHeightP2 = OpenGl_Context::GetPowerOfTwo (theSizeXY.y(), aMaxSize);
|
||||
if (theSizeXY.x() != aWidthP2
|
||||
|| theSizeXY.y() != aHeightP2)
|
||||
{
|
||||
TCollection_ExtendedString aWarnMessage =
|
||||
TCollection_ExtendedString ("Error: Mipmap NPOT Textures (") + theSizeX + "x" + theSizeY + ") are not supported by OpenGL ES 2.0";
|
||||
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
|
||||
|
||||
Release (theCtx.operator->());
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Error: Mipmap NPOT Textures (") + theSizeXY.x() + "x" + theSizeXY.y() + ")"
|
||||
" are not supported by OpenGL ES 2.0");
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -551,15 +327,15 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
if (toPatchExisting)
|
||||
{
|
||||
glTexSubImage1D (GL_TEXTURE_1D, 0, 0,
|
||||
theSizeX, thePixelFormat, theDataType, aDataPtr);
|
||||
theSizeXY.x(), theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
|
||||
Unbind (theCtx);
|
||||
return true;
|
||||
}
|
||||
|
||||
// use proxy to check texture could be created or not
|
||||
glTexImage1D (GL_PROXY_TEXTURE_1D, 0, anIntFormat,
|
||||
theSizeX, 0,
|
||||
thePixelFormat, theDataType, NULL);
|
||||
theSizeXY.x(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), 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)
|
||||
@@ -571,16 +347,16 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
}
|
||||
|
||||
glTexImage1D (GL_TEXTURE_1D, 0, anIntFormat,
|
||||
theSizeX, 0,
|
||||
thePixelFormat, theDataType, aDataPtr);
|
||||
theSizeXY.x(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
mySizeX = theSizeX;
|
||||
mySizeX = theSizeXY.x();
|
||||
mySizeY = 1;
|
||||
|
||||
Unbind (theCtx);
|
||||
@@ -588,7 +364,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
#else
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Error: 1D textures are not supported by hardware.");
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
@@ -600,8 +376,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
{
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
0, 0,
|
||||
theSizeX, theSizeY,
|
||||
thePixelFormat, theDataType, aDataPtr);
|
||||
theSizeXY.x(), theSizeXY.y(),
|
||||
theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
|
||||
Unbind (theCtx);
|
||||
return true;
|
||||
}
|
||||
@@ -609,8 +385,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
// use proxy to check texture could be created or not
|
||||
glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
|
||||
theSizeX, theSizeY, 0,
|
||||
thePixelFormat, theDataType, NULL);
|
||||
theSizeXY.x(), theSizeXY.y(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), 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);
|
||||
@@ -618,28 +394,29 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
{
|
||||
// no memory or broken input parameters
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
|
||||
theSizeX, theSizeY, 0,
|
||||
thePixelFormat, theDataType, aDataPtr);
|
||||
theSizeXY.x(), theSizeXY.y(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
|
||||
const GLenum anErr = glGetError();
|
||||
if (anErr != GL_NO_ERROR)
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Error: 2D texture ") + theSizeX + "x" + theSizeY
|
||||
+ " IF: " + int(anIntFormat) + " PF: " + int(thePixelFormat) + " DT: " + int(theDataType)
|
||||
TCollection_AsciiString ("Error: 2D texture ") + theSizeXY.x() + "x" + theSizeXY.y()
|
||||
+ " IF: " + int(anIntFormat) + " PF: " + int(theFormat.PixelFormat())
|
||||
+ " DT: " + int(theFormat.DataType())
|
||||
+ " can not be created with error " + int(anErr) + ".");
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
mySizeX = theSizeX;
|
||||
mySizeY = theSizeY;
|
||||
mySizeX = theSizeXY.x();
|
||||
mySizeY = theSizeXY.y();
|
||||
|
||||
Unbind (theCtx);
|
||||
return true;
|
||||
@@ -652,8 +429,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
{
|
||||
glTexSubImage2D (GL_TEXTURE_2D, 0,
|
||||
0, 0,
|
||||
theSizeX, theSizeY,
|
||||
thePixelFormat, theDataType, aDataPtr);
|
||||
theSizeXY.x(), theSizeXY.y(),
|
||||
theFormat.PixelFormat(), theFormat.DataType(), aDataPtr);
|
||||
if (theCtx->arbFBO != NULL)
|
||||
{
|
||||
// generate mipmaps
|
||||
@@ -661,7 +438,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -673,8 +450,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
#if !defined(GL_ES_VERSION_2_0)
|
||||
// use proxy to check texture could be created or not
|
||||
glTexImage2D (GL_PROXY_TEXTURE_2D, 0, anIntFormat,
|
||||
theSizeX, theSizeY, 0,
|
||||
thePixelFormat, theDataType, NULL);
|
||||
theSizeXY.x(), theSizeXY.y(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), 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);
|
||||
@@ -682,29 +459,30 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
{
|
||||
// no memory or broken input parameters
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// upload main picture
|
||||
glTexImage2D (GL_TEXTURE_2D, 0, anIntFormat,
|
||||
theSizeX, theSizeY, 0,
|
||||
thePixelFormat, theDataType, theImage->Data());
|
||||
theSizeXY.x(), theSizeXY.y(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), theImage->Data());
|
||||
const GLenum aTexImgErr = glGetError();
|
||||
if (aTexImgErr != GL_NO_ERROR)
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Error: 2D texture ") + theSizeX + "x" + theSizeY
|
||||
+ " IF: " + int(anIntFormat) + " PF: " + int(thePixelFormat) + " DT: " + int(theDataType)
|
||||
TCollection_AsciiString ("Error: 2D texture ") + theSizeXY.x() + "x" + theSizeXY.y()
|
||||
+ " IF: " + int(anIntFormat) + " PF: " + int(theFormat.PixelFormat())
|
||||
+ " DT: " + int(theFormat.DataType())
|
||||
+ " can not be created with error " + int(aTexImgErr) + ".");
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
mySizeX = theSizeX;
|
||||
mySizeY = theSizeY;
|
||||
mySizeX = theSizeXY.x();
|
||||
mySizeY = theSizeXY.y();
|
||||
|
||||
if (theCtx->arbFBO != NULL)
|
||||
{
|
||||
@@ -715,18 +493,16 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const TCollection_ExtendedString aWarnMessage ("Warning: generating mipmaps requires GL_ARB_framebuffer_object extension which is missing.");
|
||||
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH, aWarnMessage);
|
||||
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Warning: generating mipmaps requires GL_ARB_framebuffer_object extension which is missing.");
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -741,7 +517,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
}
|
||||
}
|
||||
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -751,27 +527,23 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
// =======================================================================
|
||||
bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
const Image_PixMap& theImage,
|
||||
const Graphic3d_TypeOfTexture theType)
|
||||
const Graphic3d_TypeOfTexture theType,
|
||||
const Standard_Boolean theIsColorMap)
|
||||
{
|
||||
if (theImage.IsEmpty())
|
||||
{
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
GLenum aPixelFormat;
|
||||
GLenum aDataType;
|
||||
GLint aTextFormat;
|
||||
if (!GetDataFormat (theCtx, theImage, aTextFormat, aPixelFormat, aDataType))
|
||||
const OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindFormat (theCtx, theImage.Format(), theIsColorMap);
|
||||
if (!aFormat.IsValid())
|
||||
{
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
return Init (theCtx,
|
||||
aTextFormat, aPixelFormat, aDataType,
|
||||
(Standard_Integer)theImage.SizeX(),
|
||||
(Standard_Integer)theImage.SizeY(),
|
||||
return Init (theCtx, aFormat, Graphic3d_Vec2i ((Standard_Integer)theImage.SizeX(), (Standard_Integer)theImage.SizeY()),
|
||||
theType, &theImage);
|
||||
}
|
||||
|
||||
@@ -791,7 +563,8 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
{
|
||||
case Graphic3d_TOT_CUBEMAP:
|
||||
{
|
||||
return InitCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap));
|
||||
return initCubeMap (theCtx, Handle(Graphic3d_CubeMap)::DownCast(theTextureMap),
|
||||
0, Image_Format_RGB, false, theTextureMap->IsColorMap());
|
||||
}
|
||||
default:
|
||||
{
|
||||
@@ -800,7 +573,7 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Init (theCtx, *anImage, theTextureMap->Type());
|
||||
return Init (theCtx, *anImage, theTextureMap->Type(), theTextureMap->IsColorMap());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -935,24 +708,14 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
|
||||
const GLint theTextFormat,
|
||||
const GLenum thePixelFormat,
|
||||
const GLenum theDataType,
|
||||
const Standard_Integer theSizeX,
|
||||
const Standard_Integer theSizeY,
|
||||
const Standard_Integer theSizeZ,
|
||||
const OpenGl_TextureFormat& theFormat,
|
||||
const Graphic3d_Vec3i& theSizeXYZ,
|
||||
const void* thePixels)
|
||||
{
|
||||
if (theCtx->Functions()->glTexImage3D == NULL)
|
||||
{
|
||||
TCollection_ExtendedString aMsg ("Error: three-dimensional textures are not supported by hardware.");
|
||||
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION,
|
||||
GL_DEBUG_TYPE_ERROR,
|
||||
0,
|
||||
GL_DEBUG_SEVERITY_HIGH,
|
||||
aMsg);
|
||||
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Error: three-dimensional textures are not supported by hardware.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -965,83 +728,80 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
|
||||
myNbSamples = 1;
|
||||
myHasMipmaps = false;
|
||||
|
||||
const GLsizei aSizeX = Min (theCtx->MaxTextureSize(), theSizeX);
|
||||
const GLsizei aSizeY = Min (theCtx->MaxTextureSize(), theSizeY);
|
||||
const GLsizei aSizeZ = Min (theCtx->MaxTextureSize(), theSizeZ);
|
||||
|
||||
const Graphic3d_Vec3i aSizeXYZ = theSizeXYZ.cwiseMin (Graphic3d_Vec3i (theCtx->MaxTextureSize()));
|
||||
if (aSizeXYZ != theSizeXYZ)
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Error: 3D texture dimensions exceed hardware limits.");
|
||||
Release (theCtx.get());
|
||||
Unbind (theCtx);
|
||||
return false;
|
||||
}
|
||||
Bind (theCtx);
|
||||
|
||||
if (theDataType == GL_FLOAT && !theCtx->arbTexFloat)
|
||||
if (theFormat.DataType() == 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->());
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Error: floating-point textures are not supported by hardware.");
|
||||
Release (theCtx.get());
|
||||
Unbind (theCtx);
|
||||
return false;
|
||||
}
|
||||
|
||||
mySizedFormat = theTextFormat;
|
||||
mySizedFormat = theFormat.InternalFormat();
|
||||
|
||||
// setup the alignment
|
||||
OpenGl_UnpackAlignmentSentry::Reset();
|
||||
|
||||
#if !defined (GL_ES_VERSION_2_0)
|
||||
theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D, 0, mySizedFormat,
|
||||
aSizeX, aSizeY, aSizeZ, 0,
|
||||
thePixelFormat, theDataType, NULL);
|
||||
aSizeXYZ.x(), aSizeXYZ.y(), aSizeXYZ.z(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), NULL);
|
||||
|
||||
GLint aTestSizeX = 0;
|
||||
GLint aTestSizeY = 0;
|
||||
GLint aTestSizeZ = 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);
|
||||
NCollection_Vec3<GLint> aTestSizeXYZ;
|
||||
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_WIDTH, &aTestSizeXYZ.x());
|
||||
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_HEIGHT, &aTestSizeXYZ.y());
|
||||
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_DEPTH, &aTestSizeXYZ.z());
|
||||
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_3D, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
|
||||
|
||||
if (aTestSizeX == 0 || aTestSizeY == 0 || aTestSizeZ == 0)
|
||||
if (aTestSizeXYZ.x() == 0 || aTestSizeXYZ.y() == 0 || aTestSizeXYZ.z() == 0)
|
||||
{
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
applyDefaultSamplerParams (theCtx);
|
||||
theCtx->Functions()->glTexImage3D (myTarget, 0, mySizedFormat,
|
||||
aSizeX, aSizeY, aSizeZ, 0,
|
||||
thePixelFormat, theDataType, thePixels);
|
||||
aSizeXYZ.x(), aSizeXYZ.y(), aSizeXYZ.z(), 0,
|
||||
theFormat.PixelFormat(), theFormat.DataType(), thePixels);
|
||||
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.operator->());
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
|
||||
mySizeX = aSizeX;
|
||||
mySizeY = aSizeY;
|
||||
mySizeZ = aSizeZ;
|
||||
mySizeX = aSizeXYZ.x();
|
||||
mySizeY = aSizeXYZ.y();
|
||||
mySizeZ = aSizeXYZ.z();
|
||||
|
||||
Unbind (theCtx);
|
||||
return true;
|
||||
}
|
||||
|
||||
// =======================================================================
|
||||
// function : InitCubeMap
|
||||
// function : initCubeMap
|
||||
// purpose :
|
||||
// =======================================================================
|
||||
bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
bool OpenGl_Texture::initCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
const Handle(Graphic3d_CubeMap)& theCubeMap,
|
||||
Standard_Size theSize,
|
||||
Image_Format theFormat,
|
||||
Standard_Boolean theToGenMipmap)
|
||||
Standard_Size theSize,
|
||||
Image_Format theFormat,
|
||||
Standard_Boolean theToGenMipmap,
|
||||
Standard_Boolean theIsColorMap)
|
||||
{
|
||||
if (!Create (theCtx))
|
||||
{
|
||||
@@ -1051,8 +811,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
|
||||
if (!theCubeMap.IsNull())
|
||||
{
|
||||
Handle(Image_PixMap) anImage = theCubeMap->Reset().Value();
|
||||
if (!anImage.IsNull())
|
||||
if (Handle(Image_PixMap) anImage = theCubeMap->Reset().Value())
|
||||
{
|
||||
theSize = anImage->SizeX();
|
||||
theFormat = anImage->Format();
|
||||
@@ -1060,17 +819,14 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
else
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Unable to get the first side of cubemap");
|
||||
"Unable to get the first side of cubemap");
|
||||
Release(theCtx.get());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
GLenum aPixelFormat = GL_RGB;
|
||||
GLenum aDataType = 0;
|
||||
GLint aTextFormat = 0;
|
||||
|
||||
if (!GetDataFormat (theCtx, theFormat, aTextFormat, aPixelFormat, aDataType))
|
||||
OpenGl_TextureFormat aFormat = OpenGl_TextureFormat::FindFormat (theCtx, theFormat, theIsColorMap);
|
||||
if (!aFormat.IsValid())
|
||||
{
|
||||
Unbind(theCtx);
|
||||
Release(theCtx.get());
|
||||
@@ -1123,8 +879,8 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
}
|
||||
else
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, TCollection_AsciiString() +
|
||||
"Unable to get [" + i + "] side of cubemap");
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString() + "Unable to get [" + i + "] side of cubemap");
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
@@ -1133,17 +889,18 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
}
|
||||
|
||||
glTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,
|
||||
aTextFormat,
|
||||
aFormat.InternalFormat(),
|
||||
GLsizei(theSize), GLsizei(theSize),
|
||||
0, aPixelFormat, aDataType,
|
||||
0, aFormat.PixelFormat(), aFormat.DataType(),
|
||||
aData);
|
||||
|
||||
OpenGl_UnpackAlignmentSentry::Reset();
|
||||
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
const GLenum anErr = glGetError();
|
||||
if (anErr != GL_NO_ERROR)
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Unable to initialize side of cubemap");
|
||||
TCollection_AsciiString ("Unable to initialize side of cubemap. Error #") + int(anErr));
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
@@ -1152,16 +909,16 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
|
||||
|
||||
if (theToGenMipmap && theCtx->arbFBO != NULL)
|
||||
{
|
||||
theCtx->arbFBO->glGenerateMipmap (myTarget);
|
||||
|
||||
if (glGetError() != GL_NO_ERROR)
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
"Unable to generate mipmap of cubemap");
|
||||
Unbind(theCtx);
|
||||
Release(theCtx.get());
|
||||
return false;
|
||||
}
|
||||
theCtx->arbFBO->glGenerateMipmap (myTarget);
|
||||
const GLenum anErr = glGetError();
|
||||
if (anErr != GL_NO_ERROR)
|
||||
{
|
||||
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
|
||||
TCollection_AsciiString ("Unable to generate mipmap of cubemap. Error #") + int(anErr));
|
||||
Unbind (theCtx);
|
||||
Release (theCtx.get());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Unbind (theCtx.get());
|
||||
|
Reference in New Issue
Block a user