Hi,
we have some problems, actually crashes, on client laptop that use Intel HD chips. The problems are linked to the usage of BlendChunk's and I think we have narrowed it down to the BlendEquation.
It seems Intel HD chips and their drivers do not support GL_ARB_imaging extension, which is necessary for glBlendEquation. This problem arised with the switch from 1.8 to 2.0. I checked the BlendChunk implementation for differences and I've got a presumption what may be the problem. In 1.8 the BlendChunk uses ::hasExtension() to check for GL_ARB_imaging. 2.0 uses hasExtOrVersion(). So I guess that the GL version is large enough to get a true here even if the extension is not supported. What is the reason why this check was changed?
Furthermore I've improved some other things:
1.) TextureBuffer::processPreDeactivate(): Check if image is assigned to TextureObj, before accessing it..
2.) OSGGeoSplitVertexArrayPumpGroup/OSGGeoVertexArrayPumpGroup: We had some Geometries that had at certain times no vertices. Calling glDrawArray with vertexCount 0 caused crashes on some graphics cards. I added a check here.
3.) OSGImage: Added simple hash calculation to be able to compare images faster.
4.) OSGBlendChunk: In some cases glBlendEquation was used where glBlendEquationEXT should have be used.
Patch is attached...
Thanks,
Michael
Source/Base/Base/OSGGLFuncProtos.h | 1 + Source/Base/Base/OSGVector.h | 4 +++- Source/Base/Base/OSGVector.inl | 18 +++++++++++++++ Source/System/Image/OSGImage.cpp | 10 ++++++-- Source/System/Image/OSGImage.h | 5 ++++ Source/System/Image/OSGImage.inl | 21 +++++++++++++++++ .../Base/OSGGeoSplitVertexArrayPumpGroup.cpp | 27 +++++++++++++++++----- .../Geometry/Base/OSGGeoVertexArrayPumpGroup.cpp | 18 +++++++++++---- .../Effects/ShadowStage/OSGShadowStageBase.cpp | 2 +- Source/System/State/Base/OSGBlendChunk.cpp | 22 +++++++++--------- .../System/State/Shader/SHL/OSGSimpleSHLChunk.cpp | 10 +++++--- Source/System/State/Shader/SHL/OSGSimpleSHLChunk.h | 3 ++- .../Window/FrameBufferObjects/OSGTextureBuffer.cpp | 5 +++- 13 files changed, 116 insertions(+), 30 deletions(-)
diff --git a/Source/Base/Base/OSGGLFuncProtos.h b/Source/Base/Base/OSGGLFuncProtos.h index 750ea73..bd45043 100644 --- a/Source/Base/Base/OSGGLFuncProtos.h +++ b/Source/Base/Base/OSGGLFuncProtos.h @@ -679,6 +679,7 @@ typedef void (OSG_APIENTRY *osgGlBlendColorProc )(GLclampf, GLclampf, GLclampf); typedef void (OSG_APIENTRY *osgGlBlendEquationProc )(GLenum); +typedef void (OSG_APIENTRY *osgGlBlendEquationExtProc )(GLenum); typedef void (OSG_APIENTRY *osgGlBlendFuncSeparateProc)(GLenum, GLenum, GLenum, diff --git a/Source/Base/Base/OSGVector.h b/Source/Base/Base/OSGVector.h index 86d747a..7ba09fd 100644 --- a/Source/Base/Base/OSGVector.h +++ b/Source/Base/Base/OSGVector.h @@ -505,7 +505,9 @@ class Point : public SelectVecStorage<ValueTypeT, SizeI>::Type Point operator + (const VectorType &vec) const; - Point operator - (const VectorType &vec) const; + Point operator - (const VectorType &vec) const; + + Point operator + (const PointType &vec) const; Point operator * (const ValueType val) const; diff --git a/Source/Base/Base/OSGVector.inl b/Source/Base/Base/OSGVector.inl index 02f4a78..4942851 100644 --- a/Source/Base/Base/OSGVector.inl +++ b/Source/Base/Base/OSGVector.inl @@ -1045,6 +1045,24 @@ Point<ValueTypeT, SizeI> return returnValue; } +//! Component wise binary point addition operator + +template <class ValueTypeT, + UInt32 SizeI > inline + Point<ValueTypeT, SizeI> + Point<ValueTypeT, SizeI>::operator + (const PointType &pnt) const +{ + Point<ValueTypeT, SizeI> returnValue; + + for(UInt32 i = 0; i < Self::_uiSize; i++) + { + returnValue[i] = Self::_values[i] + pnt[i]; + } + + return returnValue; +} + + //! Component wise binary scalar multiplication template <class ValueTypeT, diff --git a/Source/System/Image/OSGImage.cpp b/Source/System/Image/OSGImage.cpp index 2f55100..0470fbb 100644 --- a/Source/System/Image/OSGImage.cpp +++ b/Source/System/Image/OSGImage.cpp @@ -186,6 +186,8 @@ void Image::changed(ConstFieldMaskArg whichField, calcMipmapOffsets(); + this->_hashCodeValid = false; + Inherited::changed(whichField, origin, details); } @@ -3764,7 +3766,9 @@ UInt64 Image::restore(const UChar8 *mem, Int32 memSize) Image::Image(void) : Inherited (), - _mipmapOffset() + _mipmapOffset(), + _hashCode(0), + _hashCodeValid(false) { } @@ -3773,7 +3777,9 @@ Image::Image(void) : Image::Image(const Image &obj) : Inherited (obj ), - _mipmapOffset(obj._mipmapOffset) + _mipmapOffset(obj._mipmapOffset), + _hashCode(obj._hashCode), + _hashCodeValid(obj._hashCodeValid) { } diff --git a/Source/System/Image/OSGImage.h b/Source/System/Image/OSGImage.h index 7987842..0ba1f88 100644 --- a/Source/System/Image/OSGImage.h +++ b/Source/System/Image/OSGImage.h @@ -320,6 +320,8 @@ class OSG_SYSTEM_DLLMAPPING Image : public ImageBase bool operator == (const Image &image); bool operator != (const Image &image); + OSG::Int32 getHash(); + /*! \} */ /*---------------------------------------------------------------------*/ /*! \name Get Methods */ @@ -498,6 +500,9 @@ class OSG_SYSTEM_DLLMAPPING Image : public ImageBase /*! \} */ /*---------------------------------------------------------------------*/ + Int32 _hashCode; + bool _hashCodeValid; + friend class FieldContainer; friend class ImageBase; }; diff --git a/Source/System/Image/OSGImage.inl b/Source/System/Image/OSGImage.inl index fd8573b..144826c 100644 --- a/Source/System/Image/OSGImage.inl +++ b/Source/System/Image/OSGImage.inl @@ -152,6 +152,27 @@ UInt8 *Image::editDataFast(UInt32 mipmapNum, return data; } +inline +OSG::Int32 Image::getHash() +{ + if(!this->_hashCodeValid) + { + // recalculate hash.. + Int32 seed = 173; + Int32 prime = 37; + + this->_hashCode = seed; + for(UInt32 i=0; i<_mfPixel.size(); ++i) + { + this->_hashCode = this->_hashCode * prime + (Int32)(&(_mfPixel[i])); + } + + this->_hashCode = seed; + this->_hashCodeValid = true; + } + + return this->_hashCode; +} #ifdef CHECK_GV // Specialization for Image we need this to support VRML PixelTextures. diff --git a/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoSplitVertexArrayPumpGroup.cpp b/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoSplitVertexArrayPumpGroup.cpp index e7a8e99..5ea8e22 100644 --- a/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoSplitVertexArrayPumpGroup.cpp +++ b/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoSplitVertexArrayPumpGroup.cpp @@ -574,8 +574,13 @@ void GeoSplitVertexArrayPumpGroup::masterClassicGeoDrawPump( if(primindex < lengths->size()) curlen = lengths->getValue<UInt32>(primindex); - glDrawArrays(types->getValue<UInt16>(primindex), vertindex, - curlen); + // glDrawArrays with vertex count of 0 may cause crashes + if(curlen>0) + { + glDrawArrays(types->getValue<UInt16>(primindex), vertindex, + curlen); + } + vertindex += curlen; } } @@ -861,8 +866,13 @@ void GeoSplitVertexArrayPumpGroup::masterClassicGeoJustDrawPump( if(primindex < lengths->size()) curlen = lengths->getValue<UInt32>(primindex); - glDrawArrays(types->getValue<UInt16>(primindex), vertindex, - curlen); + // glDrawArrays with vertex count of 0 may cause crashes + if(curlen>0) + { + glDrawArrays(types->getValue<UInt16>(primindex), vertindex, + curlen); + } + vertindex += curlen; } } @@ -1216,8 +1226,13 @@ void GeoSplitVertexArrayPumpGroup::masterAttribGeoDrawPump( if(primindex < lengths->size()) curlen = lengths->getValue<UInt32>(primindex); - glDrawArrays(types->getValue<UInt16>(primindex), vertindex, - curlen); + // glDrawArrays with vertex count of 0 may cause crashes + if(curlen>0) + { + glDrawArrays(types->getValue<UInt16>(primindex), vertindex, + curlen); + } + vertindex += curlen; } } diff --git a/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoVertexArrayPumpGroup.cpp b/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoVertexArrayPumpGroup.cpp index ed8059a..ac91c1a 100644 --- a/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoVertexArrayPumpGroup.cpp +++ b/Source/System/NodeCores/Drawables/Geometry/Base/OSGGeoVertexArrayPumpGroup.cpp @@ -587,8 +587,13 @@ void GeoVertexArrayPumpGroup::masterClassicGeoPump( if(primindex < lengths->size()) curlen = lengths->getValue<UInt32>(primindex); - glDrawArrays(types->getValue<UInt16>(primindex), vertindex, - curlen); + // glDrawArrays with vertex count of 0 may cause crashes + if(curlen>0) + { + glDrawArrays(types->getValue<UInt16>(primindex), vertindex, + curlen); + } + vertindex += curlen; } } @@ -883,8 +888,13 @@ void GeoVertexArrayPumpGroup::masterAttribGeoPump( if(primindex < lengths->size()) curlen = lengths->getValue<UInt32>(primindex); - glDrawArrays(types->getValue<UInt16>(primindex), vertindex, - curlen); + // glDrawArrays with vertex count of 0 may cause crashes + if(curlen>0) + { + glDrawArrays(types->getValue<UInt16>(primindex), vertindex, + curlen); + } + vertindex += curlen; } } diff --git a/Source/System/NodeCores/Groups/Effects/ShadowStage/OSGShadowStageBase.cpp b/Source/System/NodeCores/Groups/Effects/ShadowStage/OSGShadowStageBase.cpp index 449cb4a..e1570be 100644 --- a/Source/System/NodeCores/Groups/Effects/ShadowStage/OSGShadowStageBase.cpp +++ b/Source/System/NodeCores/Groups/Effects/ShadowStage/OSGShadowStageBase.cpp @@ -799,7 +799,7 @@ ShadowStageBase::TypeObject ShadowStageBase::_type( " access=\"public\"\n" " defaultValue=\"false\"\n" " >\n" - "\tUse multisampling when rendering color map and shadow factor map.\n" + " Use multisampling when rendering color map and shadow factor map.\n" " </Field>\n" " <Field\n" " name=\"colorSamples\"\n" diff --git a/Source/System/State/Base/OSGBlendChunk.cpp b/Source/System/State/Base/OSGBlendChunk.cpp index b4d50d5..3b5d84d 100644 --- a/Source/System/State/Base/OSGBlendChunk.cpp +++ b/Source/System/State/Base/OSGBlendChunk.cpp @@ -263,12 +263,12 @@ void BlendChunk::activate(DrawEnv *pEnv, UInt32) pWin->hasExtOrVersion(_extBlendLogicOp, 0x0101, 0x0200) ) { // get "glBlendEquationEXT" function pointer - OSGGETGLFUNCBYID_GL3_ES( glBlendEquation, - osgGlBlendEquation, - _funcBlendEquation, + OSGGETGLFUNCBYID_GL3_ES( glBlendEquationEXT, + osgGlBlendEquationExt, + _funcBlendEquationExt, pWin); - osgGlBlendEquation(_sfEquation.getValue()); + osgGlBlendEquationExt(_sfEquation.getValue()); } } @@ -398,12 +398,12 @@ void BlendChunk::changeFrom(DrawEnv *pEnv, pWin->hasExtOrVersion(_extBlendLogicOp, 0x0101, 0x0200)) { // get "glBlendEquationEXT" function pointer - OSGGETGLFUNCBYID_GL3_ES( glBlendEquation, - osgGlBlendEquation, - _funcBlendEquation, + OSGGETGLFUNCBYID_GL3_ES( glBlendEquationEXT, + osgGlBlendEquationExt, + _funcBlendEquationExt, pWin); - osgGlBlendEquation(_sfEquation.getValue()); + osgGlBlendEquationExt(_sfEquation.getValue()); } } @@ -460,12 +460,12 @@ void BlendChunk::deactivate(DrawEnv *pEnv, UInt32 ) pWin->hasExtOrVersion(_extBlendLogicOp, 0x0101, 0x0200) ) { // get "glBlendEquationEXT" function pointer - OSGGETGLFUNCBYID_GL3_ES( glBlendEquation, - osgGlBlendEquation, + OSGGETGLFUNCBYID_GL3_ES( glBlendEquationEXT, + osgGlBlendEquationExt, _funcBlendEquationExt, pWin); - osgGlBlendEquation(GL_FUNC_ADD_EXT); + osgGlBlendEquationExt(GL_FUNC_ADD_EXT); } } diff --git a/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.cpp b/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.cpp index 9699a75..c58a084 100644 --- a/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.cpp +++ b/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.cpp @@ -105,6 +105,7 @@ UInt32 SimpleSHLChunk::handleGL(DrawEnv *pEnv, { GLuint uiProgram = GLuint(pWin->getGLObjectId(getGLId()));; + bool forceVariableUpdate = false; if(mode != Window::needrefresh) { if(uiProgram != 0) @@ -276,6 +277,8 @@ UInt32 SimpleSHLChunk::handleGL(DrawEnv *pEnv, pWin->setGLObjectId(getGLId(), uiProgram); updateVariableLocations(pEnv, uiProgram); + + forceVariableUpdate = true; } if(uiProgram != 0) @@ -287,7 +290,7 @@ UInt32 SimpleSHLChunk::handleGL(DrawEnv *pEnv, osgGlUseProgram(uiProgram); - updateVariables(pEnv, uiProgram); + updateVariables(pEnv, uiProgram, forceVariableUpdate); if(0x0000 == (uiOptions & KeepProgActive)) { @@ -1295,7 +1298,8 @@ void SimpleSHLChunk::updateVariableLocations(DrawEnv *pEnv, } void SimpleSHLChunk::updateVariables(DrawEnv *pEnv, - UInt32 uiProgram) + UInt32 uiProgram, + bool forceUpdate ) { if(uiProgram == 0) return; @@ -1339,7 +1343,7 @@ void SimpleSHLChunk::updateVariables(DrawEnv *pEnv, if(pVar == NULL) continue; - if(*mVarChgIt == false) + if(*mVarChgIt == false && !forceUpdate) continue; *mVarChgIt = false; diff --git a/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.h b/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.h index 1dcdc27..dfd5e8f 100644 --- a/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.h +++ b/Source/System/State/Shader/SHL/OSGSimpleSHLChunk.h @@ -354,7 +354,8 @@ class OSG_SYSTEM_DLLMAPPING SimpleSHLChunk : public SimpleSHLChunkBase void updateVariableLocations (DrawEnv *pEnv, UInt32 uiProgram); void updateVariables (DrawEnv *pEnv, - UInt32 uiProgram); + UInt32 uiProgram, + bool forceUpdate = false); void updateParameters (DrawEnv *pEnv, UInt32 uiProgram); void updateProceduralVariables(DrawEnv *pEnv, diff --git a/Source/System/Window/FrameBufferObjects/OSGTextureBuffer.cpp b/Source/System/Window/FrameBufferObjects/OSGTextureBuffer.cpp index 57554d7..c33003d 100644 --- a/Source/System/Window/FrameBufferObjects/OSGTextureBuffer.cpp +++ b/Source/System/Window/FrameBufferObjects/OSGTextureBuffer.cpp @@ -215,7 +215,10 @@ void TextureBuffer::processPreDeactivate(DrawEnv *pEnv, UInt32 index) return; Image *pTexImg = pTexObj->getImage(); - + + if(pTexImg == NULL) + return; + if(pTexImg->getData() == NULL) { SINFO << "TextureBuffer::render: (Re)Allocating image "
------------------------------------------------------------------------------ Infragistics Professional Build stunning WinForms apps today! Reboot your WinForms applications with our WinForms controls. Build a bridge from your legacy apps to the future. http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk
_______________________________________________ Opensg-users mailing list Opensg-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensg-users