diff --git a/src/OpenGl/OpenGl_Context.cxx b/src/OpenGl/OpenGl_Context.cxx index 9147d26bcf..7d8713a303 100644 --- a/src/OpenGl/OpenGl_Context.cxx +++ b/src/OpenGl/OpenGl_Context.cxx @@ -146,10 +146,14 @@ OpenGl_Context::OpenGl_Context (const Handle(OpenGl_Caps)& theCaps) caps (!theCaps.IsNull() ? theCaps : new OpenGl_Caps()), hasGetBufferData (Standard_False), #if defined(GL_ES_VERSION_2_0) + hasPackRowLength (Standard_False), + hasUnpackRowLength (Standard_False), hasHighp (Standard_False), hasUintIndex(Standard_False), hasTexRGBA8(Standard_False), #else + hasPackRowLength (Standard_True), + hasUnpackRowLength (Standard_True), hasHighp (Standard_True), hasUintIndex(Standard_True), hasTexRGBA8(Standard_True), @@ -1558,6 +1562,8 @@ void OpenGl_Context::init (const Standard_Boolean theIsCoreProfile) hasFboRenderMipmap = IsGlGreaterEqual (3, 0) || CheckExtension ("GL_OES_fbo_render_mipmap"); 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 // which are relaxed by OpenGL ES 3.0 or some extensions //arbNPTW = IsGlGreaterEqual (3, 0) diff --git a/src/OpenGl/OpenGl_Context.hxx b/src/OpenGl/OpenGl_Context.hxx index 8bde7aaea4..04ce1e1485 100644 --- a/src/OpenGl/OpenGl_Context.hxx +++ b/src/OpenGl/OpenGl_Context.hxx @@ -1078,6 +1078,8 @@ public: //! @name core profiles public: //! @name extensions 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 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 @@ -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 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 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 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) @@ -1101,7 +1103,7 @@ public: //! @name extensions 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) 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_ArbFBO* arbFBO; //!< GL_ARB_framebuffer_object OpenGl_ArbFBOBlit* arbFBOBlit; //!< glBlitFramebuffer function, moved out from OpenGl_ArbFBO structure for compatibility with OpenGL ES 2.0 diff --git a/src/OpenGl/OpenGl_Font.cxx b/src/OpenGl/OpenGl_Font.cxx index 99471b8a11..a5e66273da 100755 --- a/src/OpenGl/OpenGl_Font.cxx +++ b/src/OpenGl/OpenGl_Font.cxx @@ -204,14 +204,17 @@ bool OpenGl_Font::renderGlyph (const Handle(OpenGl_Context)& theCtx, aTexture->Bind (theCtx); #if !defined(GL_ES_VERSION_2_0) - glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); - glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + theCtx->core11fwd->glPixelStorei (GL_UNPACK_LSB_FIRST, GL_FALSE); #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, - myLastTilePx.Left, myLastTilePx.Top, (GLsizei )anImg.SizeX(), (GLsizei )anImg.SizeY(), - aTexture->GetFormat(), GL_UNSIGNED_BYTE, anImg.Data()); + theCtx->core11fwd->glTexSubImage2D (GL_TEXTURE_2D, 0, + myLastTilePx.Left, myLastTilePx.Top, (GLsizei )anImg.SizeX(), (GLsizei )anImg.SizeY(), + aTexture->GetFormat(), GL_UNSIGNED_BYTE, anImg.Data()); OpenGl_Font::Tile aTile; aTile.uv.Left = GLfloat(myLastTilePx.Left) / GLfloat(aTexture->SizeX()); diff --git a/src/OpenGl/OpenGl_FrameBuffer.cxx b/src/OpenGl/OpenGl_FrameBuffer.cxx index 0956287b83..0246700a94 100644 --- a/src/OpenGl/OpenGl_FrameBuffer.cxx +++ b/src/OpenGl/OpenGl_FrameBuffer.cxx @@ -953,16 +953,16 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t else { #if !defined(GL_ES_VERSION_2_0) - glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev); + theGlCtx->core11fwd->glGetIntegerv (GL_READ_BUFFER, &aReadBufferPrev); GLint aDrawBufferPrev = GL_BACK; - glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev); + theGlCtx->core11fwd->glGetIntegerv (GL_DRAW_BUFFER, &aDrawBufferPrev); glReadBuffer (aDrawBufferPrev); #endif } // setup alignment - const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL - glPixelStorei (GL_PACK_ALIGNMENT, anAligment); + const GLint anAligment = Min (GLint(theImage.MaxRowAligmentBytes()), 8); // limit to 8 bytes for OpenGL + theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, anAligment); bool isBatchCopy = !theImage.IsTopDown(); const GLint anExtraBytes = GLint(theImage.RowExtraBytes()); @@ -977,14 +977,15 @@ Standard_Boolean OpenGl_FrameBuffer::BufferDump (const Handle(OpenGl_Context)& t aPixelsWidth = 0; isBatchCopy = false; } -#if !defined(GL_ES_VERSION_2_0) - glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth); -#else - if (aPixelsWidth != 0) + if (theGlCtx->hasPackRowLength) + { + theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, aPixelsWidth); + } + else if (aPixelsWidth != 0) { isBatchCopy = false; } -#endif + if (toConvRgba2Rgb) { 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 // 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(); 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 // 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 { - 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); - glPixelStorei (GL_PACK_ALIGNMENT, 1); -#if !defined(GL_ES_VERSION_2_0) - glPixelStorei (GL_PACK_ROW_LENGTH, 0); -#endif + theGlCtx->core11fwd->glPixelStorei (GL_PACK_ALIGNMENT, 1); + if (theGlCtx->hasPackRowLength) + { + theGlCtx->core11fwd->glPixelStorei (GL_PACK_ROW_LENGTH, 0); + } if (!theFbo.IsNull() && theFbo->IsValid()) { diff --git a/src/OpenGl/OpenGl_Texture.cxx b/src/OpenGl/OpenGl_Texture.cxx index 939e5bc991..68e44560bc 100644 --- a/src/OpenGl/OpenGl_Texture.cxx +++ b/src/OpenGl/OpenGl_Texture.cxx @@ -25,6 +25,8 @@ #include #include +#include + IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Texture, OpenGl_NamedResource) namespace @@ -33,23 +35,26 @@ namespace //! Simple class to reset unpack alignment settings struct OpenGl_UnpackAlignmentSentry { - //! Reset unpack alignment settings to safe values - static void Reset() + static void Reset (const OpenGl_Context& theCtx) { - glPixelStorei (GL_UNPACK_ALIGNMENT, 1); - #if !defined(GL_ES_VERSION_2_0) - glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); - #endif + theCtx.core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, 1); + if (theCtx.hasUnpackRowLength) + { + theCtx.core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); + } } - OpenGl_UnpackAlignmentSentry() {} + OpenGl_UnpackAlignmentSentry (const Handle(OpenGl_Context)& theCtx) + : myCtx (theCtx.get()) {} ~OpenGl_UnpackAlignmentSentry() { - Reset(); + Reset (*myCtx); } +private: + OpenGl_Context* myCtx; }; //! 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()) { - glDeleteTextures (1, &myTextureId); + theGlCtx->core11fwd->glDeleteTextures (1, &myTextureId); } myTextureId = NO_TEXTURE; mySizeX = mySizeY = mySizeZ = 0; @@ -192,7 +197,7 @@ void OpenGl_Texture::Bind (const Handle(OpenGl_Context)& theCtx, theCtx->core15fwd->glActiveTexture (GL_TEXTURE0 + 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); } 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 #if !defined(GL_ES_VERSION_2_0) - GLint aTestWidth = 0, aTestHeight = 0; + GLint aTestWidth = 0, aTestHeight = 0; #endif GLvoid* aDataPtr = (theImage != NULL) ? (GLvoid* )theImage->Data() : NULL; // setup the alignment - OpenGl_UnpackAlignmentSentry anUnpackSentry; + OpenGl_UnpackAlignmentSentry anUnpackSentry (theCtx); (void)anUnpackSentry; // avoid compiler warning if (aDataPtr != NULL) { const GLint anAligment = Min ((GLint )theImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes 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 aPixelsWidth = GLint(theImage->SizeRowBytes() / theImage->SizePixelBytes()); - theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, (anExtraBytes >= anAligment) ? aPixelsWidth : 0); - #endif + if (theCtx->hasUnpackRowLength) + { + 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; @@ -659,7 +670,7 @@ bool OpenGl_Texture::InitCompressed (const Handle(OpenGl_Context)& theCtx, applyDefaultSamplerParams (theCtx); // setup the alignment - OpenGl_UnpackAlignmentSentry::Reset(); + OpenGl_UnpackAlignmentSentry::Reset (*theCtx); Graphic3d_Vec2i aMipSizeXY (theImage.SizeX(), theImage.SizeY()); 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); 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) { 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; myMaxMipLevel = 0; - 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); Bind (theCtx); applyDefaultSamplerParams (theCtx); @@ -774,19 +785,16 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx, mySizedFormat = theFormat.Internal(); // setup the alignment - OpenGl_UnpackAlignmentSentry::Reset(); + OpenGl_UnpackAlignmentSentry::Reset (*theCtx); theCtx->core11fwd->glTexImage2D (GL_PROXY_TEXTURE_RECTANGLE, 0, mySizedFormat, aSizeX, aSizeY, 0, myTextFormat, GL_FLOAT, NULL); - GLint aTestSizeX = 0; - GLint aTestSizeY = 0; - + GLint aTestSizeX = 0, 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_INTERNAL_FORMAT, &mySizedFormat); - if (aTestSizeX == 0 || aTestSizeY == 0) { Unbind (theCtx); @@ -796,7 +804,6 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx, theCtx->core11fwd->glTexImage2D (myTarget, 0, mySizedFormat, aSizeX, aSizeY, 0, myTextFormat, GL_FLOAT, NULL); - if (theCtx->core11fwd->glGetError() != GL_NO_ERROR) { Unbind (theCtx); @@ -805,7 +812,6 @@ bool OpenGl_Texture::InitRectangle (const Handle(OpenGl_Context)& theCtx, mySizeX = aSizeX; mySizeY = aSizeY; - Unbind (theCtx); return true; #else @@ -865,7 +871,7 @@ bool OpenGl_Texture::Init3D (const Handle(OpenGl_Context)& theCtx, mySizedFormat = theFormat.InternalFormat(); // setup the alignment - OpenGl_UnpackAlignmentSentry::Reset(); + OpenGl_UnpackAlignmentSentry::Reset (*theCtx); #if !defined (GL_ES_VERSION_2_0) 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 { @@ -1047,7 +1053,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, { 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); - const GLenum aTexImgErr = glGetError(); + const GLenum aTexImgErr = theCtx->core11fwd->glGetError(); if (aTexImgErr != GL_NO_ERROR) { 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 !defined(GL_ES_VERSION_2_0) 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 aPixelsWidth = GLint(anImage->SizeRowBytes() / anImage->SizePixelBytes()); const GLint aRowLength = (anExtraBytes >= anAligment) ? aPixelsWidth : 0; - theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, aRowLength); -#else - Handle(Image_PixMap) aCopyImage = new Image_PixMap(); - aCopyImage->InitTrash (theFormat, theSize, theSize); - for (unsigned int y = 0; y < theSize; ++y) + if (theCtx->hasUnpackRowLength) { - for (unsigned int x = 0; x < theSize; ++x) - { - for (unsigned int aByte = 0; aByte < anImage->SizePixelBytes(); ++aByte) - { - aCopyImage->ChangeRawValue (y, x)[aByte] = anImage->RawValue (y, x)[aByte]; - } - } + theCtx->core11fwd->glPixelStorei (GL_UNPACK_ROW_LENGTH, aRowLength); } - anImage = aCopyImage; - const GLint anAligment = Min((GLint)anImage->MaxRowAligmentBytes(), 8); // OpenGL supports alignment upto 8 bytes - theCtx->core11fwd->glPixelStorei (GL_UNPACK_ALIGNMENT, anAligment); -#endif + + if (aRowLength > 0 + && !theCtx->hasUnpackRowLength) + { + 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(); } else @@ -1118,7 +1126,7 @@ bool OpenGl_Texture::InitCubeMap (const Handle(OpenGl_Context)& theCtx, 0, aFormat.PixelFormat(), aFormat.DataType(), aData); - OpenGl_UnpackAlignmentSentry::Reset(); + OpenGl_UnpackAlignmentSentry::Reset (*theCtx); const GLenum anErr = theCtx->core11fwd->glGetError(); 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 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... //if (theCtx->core45 != NULL) { theCtx->core45->glGetTextureImage (myTextureId, theLevel, aFormat.PixelFormat(), aFormat.DataType(), (GLsizei )theImage.SizeBytes(), theImage.ChangeData()); } else {