1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-09 18:50:54 +03:00

0032101: Visualization, TKOpenGl - use GL_UNPACK_ROW_LENGTH within OpenGL ES 3.0 / WebGL 2.0

Added OpenGl_Context::hasUnpackRowLength property for using GL_UNPACK_ROW_LENGTH in runtime.
OpenGl_Texture now uses GL_UNPACK_ROW_LENGTH on OpenGL ES 3.0 when necessary.
OpenGl_Texture::InitCubeMap() now allows uploading vertically-stacked cubemaps
without GL_UNPACK_ROW_LENGTH requirement.
This commit is contained in:
kgv 2021-02-01 20:46:00 +03:00 committed by bugmaster
parent 82b856b880
commit e1d17cebe2
5 changed files with 102 additions and 78 deletions

View File

@ -146,10 +146,14 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps)
caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()), caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()),
hasGetBufferData (Standard_False), hasGetBufferData (Standard_False),
#if defined(GL_ES_VERSION_2_0) #if defined(GL_ES_VERSION_2_0)
hasPackRowLength (Standard_False),
hasUnpackRowLength (Standard_False),
hasHighp (Standard_False), hasHighp (Standard_False),
hasUintIndex(Standard_False), hasUintIndex(Standard_False),
hasTexRGBA8(Standard_False), hasTexRGBA8(Standard_False),
#else #else
hasPackRowLength (Standard_True),
hasUnpackRowLength (Standard_True),
hasHighp (Standard_True), hasHighp (Standard_True),
hasUintIndex(Standard_True), hasUintIndex(Standard_True),
hasTexRGBA8(Standard_True), hasTexRGBA8(Standard_True),
@ -1558,6 +1562,8 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile)
hasFboRenderMipmap = IsGlGreaterEqual (3, 0) hasFboRenderMipmap = IsGlGreaterEqual (3, 0)
|| CheckExtension ("GL_OES_fbo_render_mipmap"); || CheckExtension ("GL_OES_fbo_render_mipmap");
hasSRGBControl = CheckExtension ("GL_EXT_sRGB_write_control"); hasSRGBControl = CheckExtension ("GL_EXT_sRGB_write_control");
hasPackRowLength = IsGlGreaterEqual (3, 0);
hasUnpackRowLength = IsGlGreaterEqual (3, 0); // || CheckExtension ("GL_EXT_unpack_subimage");
// NPOT textures has limited support within OpenGL ES 2.0 // NPOT textures has limited support within OpenGL ES 2.0
// which are relaxed by OpenGL ES 3.0 or some extensions // which are relaxed by OpenGL ES 3.0 or some extensions
//arbNPTW = IsGlGreaterEqual (3, 0) //arbNPTW = IsGlGreaterEqual (3, 0)

View File

@ -1078,6 +1078,8 @@ public: //! @name core profiles
public: //! @name extensions public: //! @name extensions
Standard_Boolean hasGetBufferData; //!< flag indicating if GetBufferSubData() is supported Standard_Boolean hasGetBufferData; //!< flag indicating if GetBufferSubData() is supported
Standard_Boolean hasPackRowLength; //!< supporting of GL_PACK_ROW_LENGTH parameters (any desktop OpenGL; OpenGL ES 3.0)
Standard_Boolean hasUnpackRowLength; //!< supporting of GL_UNPACK_ROW_LENGTH parameters (any desktop OpenGL; OpenGL ES 3.0)
Standard_Boolean hasHighp; //!< highp in GLSL ES fragment shader is supported Standard_Boolean hasHighp; //!< highp in GLSL ES fragment shader is supported
Standard_Boolean hasUintIndex; //!< GLuint for index buffer is supported (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_element_index_uint) Standard_Boolean hasUintIndex; //!< GLuint for index buffer is supported (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_element_index_uint)
Standard_Boolean hasTexRGBA8; //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8 Standard_Boolean hasTexRGBA8; //!< always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_rgb8_rgba8
@ -1085,7 +1087,7 @@ public: //! @name extensions
Standard_Boolean hasTexSRGB; //!< sRGB texture formats (desktop OpenGL 2.1, OpenGL ES 3.0 or GL_EXT_texture_sRGB) Standard_Boolean hasTexSRGB; //!< sRGB texture formats (desktop OpenGL 2.1, OpenGL ES 3.0 or GL_EXT_texture_sRGB)
Standard_Boolean hasFboSRGB; //!< sRGB FBO render targets (desktop OpenGL 2.1, OpenGL ES 3.0) Standard_Boolean hasFboSRGB; //!< sRGB FBO render targets (desktop OpenGL 2.1, OpenGL ES 3.0)
Standard_Boolean hasSRGBControl; //!< sRGB write control (any desktop OpenGL, OpenGL ES + GL_EXT_sRGB_write_control extension) Standard_Boolean hasSRGBControl; //!< sRGB write control (any desktop OpenGL, OpenGL ES + GL_EXT_sRGB_write_control extension)
Standard_Boolean hasFboRenderMipmap; //!< FBO render target could be non-zero mimap level of texture Standard_Boolean hasFboRenderMipmap; //!< FBO render target could be non-zero mipmap level of texture
OpenGl_FeatureFlag hasFlatShading; //!< Complex flag indicating support of Flat shading (Graphic3d_TOSM_FACET) (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_standard_derivatives) OpenGl_FeatureFlag hasFlatShading; //!< Complex flag indicating support of Flat shading (Graphic3d_TOSM_FACET) (always available on desktop; on OpenGL ES - since 3.0 or as extension GL_OES_standard_derivatives)
OpenGl_FeatureFlag hasGlslBitwiseOps; //!< GLSL supports bitwise operations; OpenGL 3.0 / OpenGL ES 3.0 (GLSL 130 / GLSL ES 300) or OpenGL 2.1 + GL_EXT_gpu_shader4 OpenGl_FeatureFlag hasGlslBitwiseOps; //!< GLSL supports bitwise operations; OpenGL 3.0 / OpenGL ES 3.0 (GLSL 130 / GLSL ES 300) or OpenGL 2.1 + GL_EXT_gpu_shader4
OpenGl_FeatureFlag hasDrawBuffers; //!< Complex flag indicating support of multiple draw buffers (desktop OpenGL 2.0, OpenGL ES 3.0, GL_ARB_draw_buffers, GL_EXT_draw_buffers) OpenGl_FeatureFlag hasDrawBuffers; //!< Complex flag indicating support of multiple draw buffers (desktop OpenGL 2.0, OpenGL ES 3.0, GL_ARB_draw_buffers, GL_EXT_draw_buffers)
@ -1101,7 +1103,7 @@ public: //! @name extensions
OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture OpenGl_ArbTexBindless* arbTexBindless; //!< GL_ARB_bindless_texture
OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object (on desktop OpenGL - since 3.1 or as extension GL_ARB_texture_buffer_object; on OpenGL ES - since 3.2) OpenGl_ArbTBO* arbTBO; //!< GL_ARB_texture_buffer_object (on desktop OpenGL - since 3.1 or as extension GL_ARB_texture_buffer_object; on OpenGL ES - since 3.2)
Standard_Boolean arbTboRGB32; //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0 Standard_Boolean arbTboRGB32; //!< GL_ARB_texture_buffer_object_rgb32 (3-component TBO), in core since 4.0
OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced (on desktop OpenGL - since 3.1 or as extebsion GL_ARB_draw_instanced; on OpenGL ES - since 3.0 or as extension GL_ANGLE_instanced_arrays to WebGL 1.0) OpenGl_ArbIns* arbIns; //!< GL_ARB_draw_instanced (on desktop OpenGL - since 3.1 or as extension GL_ARB_draw_instanced; on OpenGL ES - since 3.0 or as extension GL_ANGLE_instanced_arrays to WebGL 1.0)
OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output (on desktop OpenGL - since 4.3 or as extension GL_ARB_debug_output; on OpenGL ES - since 3.2 or as extension GL_KHR_debug) OpenGl_ArbDbg* arbDbg; //!< GL_ARB_debug_output (on desktop OpenGL - since 4.3 or as extension GL_ARB_debug_output; on OpenGL ES - since 3.2 or as extension GL_KHR_debug)
OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object OpenGl_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object
OpenGl_ArbFBOBlit* arbFBOBlit; //!< glBlitFramebuffer function, moved out from OpenGl_ArbFBO structure for compatibility with OpenGL ES 2.0 OpenGl_ArbFBOBlit* arbFBOBlit; //!< glBlitFramebuffer function, moved out from OpenGl_ArbFBO structure for compatibility with OpenGL ES 2.0

View File

@ -204,14 +204,17 @@ bool OpenGl_Font::renderGlyph (const Handle(OpenGl_Context)& theCtx,
aTexture->Bind (theCtx); aTexture->Bind (theCtx);
#if !defined(GL_ES_VERSION_2_0) #if !defined(GL_ES_VERSION_2_0)
glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); theCtx->core11fwd->glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE);
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
#endif #endif
glPixelStorei (GL_UNPACK_ALIGNMENT, 1); if (theCtx->hasUnpackRowLength)
{
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
}
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glTexSubImage2D (GL_TEXTURE_2D, 0, theCtx->core11fwd->glTexSubImage2D (GL_TEXTURE_2D, 0,
myLastTilePx.Left, myLastTilePx.Top, (GLsizei )anImg.SizeX(), (GLsizei )anImg.SizeY(), myLastTilePx.Left, myLastTilePx.Top, (GLsizei )anImg.SizeX(), (GLsizei )anImg.SizeY(),
aTexture->GetFormat(), GL_UNSIGNED_BYTE, anImg.Data()); aTexture->GetFormat(), GL_UNSIGNED_BYTE, anImg.Data());
OpenGl_Font::Tile aTile; OpenGl_Font::Tile aTile;
aTile.uv.Left = GLfloat(myLastTilePx.Left) / GLfloat(aTexture->SizeX()); aTile.uv.Left = GLfloat(myLastTilePx.Left) / GLfloat(aTexture->SizeX());

View File

@ -953,16 +953,16 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
else else
{ {
#if !defined(GL_ES_VERSION_2_0) #if !defined(GL_ES_VERSION_2_0)
glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev); theGlCtx->core11fwd->glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev);
GLint aDrawBufferPrev = GL_BACK; GLint aDrawBufferPrev = GL_BACK;
glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev); theGlCtx->core11fwd->glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev);
glReadBuffer (aDrawBufferPrev); glReadBuffer (aDrawBufferPrev);
#endif #endif
} }
// setup alignment // setup alignment
const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
glPixelStorei (GL_PACK_ALIGNMENT, anAligment); theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
bool isBatchCopy = !theImage.IsTopDown(); bool isBatchCopy = !theImage.IsTopDown();
const GLint anExtraBytes = GLint(theImage.RowExtraBytes()); const GLint anExtraBytes = GLint(theImage.RowExtraBytes());
@ -977,14 +977,15 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
aPixelsWidth = 0; aPixelsWidth = 0;
isBatchCopy = false; isBatchCopy = false;
} }
#if !defined(GL_ES_VERSION_2_0) if (theGlCtx->hasPackRowLength)
glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth); {
#else theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth);
if (aPixelsWidth != 0) }
else if (aPixelsWidth != 0)
{ {
isBatchCopy = false; isBatchCopy = false;
} }
#endif
if (toConvRgba2Rgb) if (toConvRgba2Rgb)
{ {
Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16); Handle(NCollection_BaseAllocator) anAlloc = new NCollection_AlignedAllocator (16);
@ -999,7 +1000,7 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
{ {
// Image_PixMap rows indexation always starts from the upper corner // Image_PixMap rows indexation always starts from the upper corner
// while order in memory depends on the flag and processed by ChangeRow() method // while order in memory depends on the flag and processed by ChangeRow() method
glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, aRowBuffer.ChangeData()); theGlCtx->core11fwd->glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, aRowBuffer.ChangeData());
const Image_ColorRGBA* aRowDataRgba = (const Image_ColorRGBA* )aRowBuffer.Data(); const Image_ColorRGBA* aRowDataRgba = (const Image_ColorRGBA* )aRowBuffer.Data();
if (theImage.Format() == Image_Format_BGR) if (theImage.Format() == Image_Format_BGR)
{ {
@ -1018,19 +1019,20 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t
{ {
// Image_PixMap rows indexation always starts from the upper corner // Image_PixMap rows indexation always starts from the upper corner
// while order in memory depends on the flag and processed by ChangeRow() method // while order in memory depends on the flag and processed by ChangeRow() method
glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow)); theGlCtx->core11fwd->glReadPixels (0, GLint(theImage.SizeY() - aRow - 1), GLsizei (theImage.SizeX()), 1, aFormat, aType, theImage.ChangeRow (aRow));
} }
} }
else else
{ {
glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData()); theGlCtx->core11fwd->glReadPixels (0, 0, GLsizei (theImage.SizeX()), GLsizei (theImage.SizeY()), aFormat, aType, theImage.ChangeData());
} }
const bool hasErrors = theGlCtx->ResetErrors (true); const bool hasErrors = theGlCtx->ResetErrors (true);
glPixelStorei (GL_PACK_ALIGNMENT, 1); theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, 1);
#if !defined(GL_ES_VERSION_2_0) if (theGlCtx->hasPackRowLength)
glPixelStorei (GL_PACK_ROW_LENGTH, 0); {
#endif theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0);
}
if (!theFbo.IsNull() && theFbo->IsValid()) if (!theFbo.IsNull() && theFbo->IsValid())
{ {

View File

@ -25,6 +25,8 @@
#include <Image_PixMap.hxx> #include <Image_PixMap.hxx>
#include <Image_SupportedFormats.hxx> #include <Image_SupportedFormats.hxx>
#include <algorithm>
IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource) IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource)
namespace namespace
@ -33,23 +35,26 @@ namespace
//! Simple class to reset unpack alignment settings //! Simple class to reset unpack alignment settings
struct OpenGl_UnpackAlignmentSentry struct OpenGl_UnpackAlignmentSentry
{ {
//! Reset unpack alignment settings to safe values //! Reset unpack alignment settings to safe values
static void Reset() static void Reset (const OpenGl_Context& theCtx)
{ {
glPixelStorei (GL_UNPACK_ALIGNMENT, 1); theCtx.core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
#if !defined(GL_ES_VERSION_2_0) if (theCtx.hasUnpackRowLength)
glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); {
#endif theCtx.core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
}
} }
OpenGl_UnpackAlignmentSentry() {} OpenGl_UnpackAlignmentSentry (const Handle(OpenGl_Context)& theCtx)
: myCtx (theCtx.get()) {}
~OpenGl_UnpackAlignmentSentry() ~OpenGl_UnpackAlignmentSentry()
{ {
Reset(); Reset (*myCtx);
} }
private:
OpenGl_Context* myCtx;
}; };
//! Compute the upper mipmap level for complete mipmap set (e.g. till the 1x1 level). //! Compute the upper mipmap level for complete mipmap set (e.g. till the 1x1 level).
@ -161,7 +166,7 @@ void OpenGl_Texture::Release (OpenGl_Context* theGlCtx)
if (theGlCtx->IsValid()) if (theGlCtx->IsValid())
{ {
glDeleteTextures (1, &myTextureId); theGlCtx->core11fwd->glDeleteTextures (1, &myTextureId);
} }
myTextureId = NO_TEXTURE; myTextureId = NO_TEXTURE;
mySizeX = mySizeY = mySizeZ = 0; mySizeX = mySizeY = mySizeZ = 0;
@ -192,7 +197,7 @@ void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx,
theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit); theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
} }
mySampler->Bind (theCtx, theTextureUnit); mySampler->Bind (theCtx, theTextureUnit);
glBindTexture (myTarget, myTextureId); theCtx->core11fwd->glBindTexture (myTarget, myTextureId);
} }
// ======================================================================= // =======================================================================
@ -207,7 +212,7 @@ void OpenGl_Texture::Unbind (const Handle(OpenGl_Context)& theCtx,
theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit); theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + theTextureUnit);
} }
mySampler->Unbind (theCtx, theTextureUnit); mySampler->Unbind (theCtx, theTextureUnit);
glBindTexture (myTarget, NO_TEXTURE); theCtx->core11fwd->glBindTexture (myTarget, NO_TEXTURE);
} }
//======================================================================= //=======================================================================
@ -340,25 +345,31 @@ bool OpenGl_Texture::Init (const Handle(OpenGl_Context)& theCtx,
#endif #endif
#if !defined(GL_ES_VERSION_2_0) #if !defined(GL_ES_VERSION_2_0)
GLint aTestWidth = 0, aTestHeight = 0; GLint aTestWidth = 0, aTestHeight = 0;
#endif #endif
GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL; GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL;
// setup the alignment // setup the alignment
OpenGl_UnpackAlignmentSentry anUnpackSentry; OpenGl_UnpackAlignmentSentry anUnpackSentry (theCtx);
(void)anUnpackSentry; // avoid compiler warning (void)anUnpackSentry; // avoid compiler warning
if (aDataPtr != NULL) if (aDataPtr != NULL)
{ {
const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment); theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
#if !defined(GL_ES_VERSION_2_0)
// notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
const GLint anExtraBytes = GLint(theImage->RowExtraBytes()); const GLint anExtraBytes = GLint(theImage->RowExtraBytes());
const GLint aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes()); const GLint aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes());
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0); if (theCtx->hasUnpackRowLength)
#endif {
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0);
}
else if (anExtraBytes >= anAligment)
{
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_PORTABILITY, 0, GL_DEBUG_SEVERITY_HIGH,
TCollection_AsciiString ("Error: unsupported image stride within OpenGL ES 2.0 [") + myResourceId +"]");
Release (theCtx.get());
return false;
}
} }
myTarget = aTarget; myTarget = aTarget;
@ -659,7 +670,7 @@ bool OpenGl_Texture::InitCompressed (const Handle(OpenGl_Context)& theCtx,
applyDefaultSamplerParams (theCtx); applyDefaultSamplerParams (theCtx);
// setup the alignment // setup the alignment
OpenGl_UnpackAlignmentSentry::Reset(); OpenGl_UnpackAlignmentSentry::Reset (*theCtx);
Graphic3d_Vec2i aMipSizeXY (theImage.SizeX(), theImage.SizeY()); Graphic3d_Vec2i aMipSizeXY (theImage.SizeX(), theImage.SizeY());
const Standard_Byte* aData = theImage.FaceData()->Data(); const Standard_Byte* aData = theImage.FaceData()->Data();
@ -667,7 +678,7 @@ bool OpenGl_Texture::InitCompressed (const Handle(OpenGl_Context)& theCtx,
{ {
const Standard_Integer aMipLength = theImage.MipMaps().Value (aMipIter); const Standard_Integer aMipLength = theImage.MipMaps().Value (aMipIter);
theCtx->Functions()->glCompressedTexImage2D (GL_TEXTURE_2D, aMipIter, mySizedFormat, aMipSizeXY.x(), aMipSizeXY.y(), 0, aMipLength, aData); theCtx->Functions()->glCompressedTexImage2D (GL_TEXTURE_2D, aMipIter, mySizedFormat, aMipSizeXY.x(), aMipSizeXY.y(), 0, aMipLength, aData);
const GLenum aTexImgErr = glGetError(); const GLenum aTexImgErr = theCtx->core11fwd->glGetError();
if (aTexImgErr != GL_NO_ERROR) if (aTexImgErr != GL_NO_ERROR)
{ {
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
@ -764,8 +775,8 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
myNbSamples = 1; myNbSamples = 1;
myMaxMipLevel = 0; myMaxMipLevel = 0;
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);
Bind (theCtx); Bind (theCtx);
applyDefaultSamplerParams (theCtx); applyDefaultSamplerParams (theCtx);
@ -774,19 +785,16 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
mySizedFormat = theFormat.Internal(); mySizedFormat = theFormat.Internal();
// setup the alignment // setup the alignment
OpenGl_UnpackAlignmentSentry::Reset(); OpenGl_UnpackAlignmentSentry::Reset (*theCtx);
theCtx->core11fwd->glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE, 0, mySizedFormat, theCtx->core11fwd->glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE, 0, mySizedFormat,
aSizeX, aSizeY, 0, aSizeX, aSizeY, 0,
myTextFormat, GL_FLOAT, NULL); myTextFormat, GL_FLOAT, NULL);
GLint aTestSizeX = 0; GLint aTestSizeX = 0, aTestSizeY = 0;
GLint aTestSizeY = 0;
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_WIDTH, &aTestSizeX); 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_HEIGHT, &aTestSizeY);
glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat); glGetTexLevelParameteriv (GL_PROXY_TEXTURE_RECTANGLE, 0, GL_TEXTURE_INTERNAL_FORMAT, &mySizedFormat);
if (aTestSizeX == 0 || aTestSizeY == 0) if (aTestSizeX == 0 || aTestSizeY == 0)
{ {
Unbind (theCtx); Unbind (theCtx);
@ -796,7 +804,6 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
theCtx->core11fwd->glTexImage2D (myTarget, 0, mySizedFormat, theCtx->core11fwd->glTexImage2D (myTarget, 0, mySizedFormat,
aSizeX, aSizeY, 0, aSizeX, aSizeY, 0,
myTextFormat, GL_FLOAT, NULL); myTextFormat, GL_FLOAT, NULL);
if (theCtx->core11fwd->glGetError() != GL_NO_ERROR) if (theCtx->core11fwd->glGetError() != GL_NO_ERROR)
{ {
Unbind (theCtx); Unbind (theCtx);
@ -805,7 +812,6 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx,
mySizeX = aSizeX; mySizeX = aSizeX;
mySizeY = aSizeY; mySizeY = aSizeY;
Unbind (theCtx); Unbind (theCtx);
return true; return true;
#else #else
@ -865,7 +871,7 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx,
mySizedFormat = theFormat.InternalFormat(); mySizedFormat = theFormat.InternalFormat();
// setup the alignment // setup the alignment
OpenGl_UnpackAlignmentSentry::Reset(); OpenGl_UnpackAlignmentSentry::Reset (*theCtx);
#if !defined (GL_ES_VERSION_2_0) #if !defined (GL_ES_VERSION_2_0)
theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D, 0, mySizedFormat, theCtx->core15fwd->glTexImage3D (GL_PROXY_TEXTURE_3D, 0, mySizedFormat,
@ -960,7 +966,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
} }
} }
OpenGl_UnpackAlignmentSentry::Reset(); OpenGl_UnpackAlignmentSentry::Reset (*theCtx);
} }
else else
{ {
@ -1047,7 +1053,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
{ {
const Standard_Integer aMipLength = aCompImage->MipMaps().Value (aMipIter); const Standard_Integer aMipLength = aCompImage->MipMaps().Value (aMipIter);
theCtx->Functions()->glCompressedTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, aMipIter, mySizedFormat, aMipSizeXY.x(), aMipSizeXY.y(), 0, aMipLength, aData); theCtx->Functions()->glCompressedTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, aMipIter, mySizedFormat, aMipSizeXY.x(), aMipSizeXY.y(), 0, aMipLength, aData);
const GLenum aTexImgErr = glGetError(); const GLenum aTexImgErr = theCtx->core11fwd->glGetError();
if (aTexImgErr != GL_NO_ERROR) if (aTexImgErr != GL_NO_ERROR)
{ {
theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH,
@ -1073,32 +1079,34 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
if (!anImage.IsNull()) if (!anImage.IsNull())
{ {
#if !defined(GL_ES_VERSION_2_0)
const GLint anAligment = Min ((GLint)anImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes const GLint anAligment = Min ((GLint)anImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
// notice that GL_UNPACK_ROW_LENGTH is not available on OpenGL ES 2.0 without GL_EXT_unpack_subimage extension
const GLint anExtraBytes = GLint(anImage->RowExtraBytes()); const GLint anExtraBytes = GLint(anImage->RowExtraBytes());
const GLint aPixelsWidth = GLint(anImage->SizeRowBytes() / anImage->SizePixelBytes()); const GLint aPixelsWidth = GLint(anImage->SizeRowBytes() / anImage->SizePixelBytes());
const GLint aRowLength = (anExtraBytes >= anAligment) ? aPixelsWidth : 0; const GLint aRowLength = (anExtraBytes >= anAligment) ? aPixelsWidth : 0;
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, aRowLength); if (theCtx->hasUnpackRowLength)
#else
Handle(Image_PixMap) aCopyImage = new Image_PixMap();
aCopyImage->InitTrash (theFormat, theSize, theSize);
for (unsigned int y = 0; y < theSize; ++y)
{ {
for (unsigned int x = 0; x < theSize; ++x) theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, aRowLength);
{
for (unsigned int aByte = 0; aByte < anImage->SizePixelBytes(); ++aByte)
{
aCopyImage->ChangeRawValue (y, x)[aByte] = anImage->RawValue (y, x)[aByte];
}
}
} }
anImage = aCopyImage;
const GLint anAligment = Min((GLint)anImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes if (aRowLength > 0
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment); && !theCtx->hasUnpackRowLength)
#endif {
Handle(Image_PixMap) aCopyImage = new Image_PixMap();
aCopyImage->InitTrash (theFormat, theSize, theSize);
const Standard_Size aRowBytesPacked = std::min (aCopyImage->SizeRowBytes(), anImage->SizeRowBytes());
for (unsigned int y = 0; y < theSize; ++y)
{
memcpy (aCopyImage->ChangeRow (y), anImage->ChangeRow (y), aRowBytesPacked);
}
anImage = aCopyImage;
const GLint anAligment2 = Min((GLint)anImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment2);
}
else
{
theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment);
}
aData = anImage->Data(); aData = anImage->Data();
} }
else else
@ -1118,7 +1126,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx,
0, aFormat.PixelFormat(), aFormat.DataType(), 0, aFormat.PixelFormat(), aFormat.DataType(),
aData); aData);
OpenGl_UnpackAlignmentSentry::Reset(); OpenGl_UnpackAlignmentSentry::Reset (*theCtx);
const GLenum anErr = theCtx->core11fwd->glGetError(); const GLenum anErr = theCtx->core11fwd->glGetError();
if (anErr != GL_NO_ERROR) if (anErr != GL_NO_ERROR)
@ -1278,7 +1286,10 @@ bool OpenGl_Texture::ImageDump (Image_PixMap& theImage,
const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL
theCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment); theCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment);
theCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0); if (theCtx->hasPackRowLength)
{
theCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0);
}
// glGetTextureImage() allows avoiding to binding texture id, but apparently requires clean FBO binding state... // glGetTextureImage() allows avoiding to binding texture id, but apparently requires clean FBO binding state...
//if (theCtx->core45 != NULL) { theCtx->core45->glGetTextureImage (myTextureId, theLevel, aFormat.PixelFormat(), aFormat.DataType(), (GLsizei )theImage.SizeBytes(), theImage.ChangeData()); } else //if (theCtx->core45 != NULL) { theCtx->core45->glGetTextureImage (myTextureId, theLevel, aFormat.PixelFormat(), aFormat.DataType(), (GLsizei )theImage.SizeBytes(), theImage.ChangeData()); } else
{ {