This commit is contained in:
d-a-heitbrink
2017-03-01 16:12:49 -06:00
59 changed files with 1001 additions and 874 deletions

View File

@@ -26,13 +26,15 @@ FOREACH( mylibfolder
osgTerrain
osgWidget
osgPresentation
osgWrappers/serializers
osgWrappers/deprecated-dotosg
osgPlugins
)
ADD_SUBDIRECTORY(${mylibfolder})
ENDFOREACH()
IF(BUILD_OSG_PLUGINS)
ADD_SUBDIRECTORY(osgWrappers/serializers)
ADD_SUBDIRECTORY(osgWrappers/deprecated-dotosg)
ADD_SUBDIRECTORY(osgPlugins)
ENDIF(BUILD_OSG_PLUGINS)

View File

@@ -246,7 +246,7 @@ void GLBufferObject::compileBuffer()
void GLBufferObject::deleteGLObject()
{
OSG_INFO<<"GLBufferObject::deleteGLObject() "<<_glObjectID<<std::endl;
OSG_DEBUG<<"GLBufferObject::deleteGLObject() "<<_glObjectID<<std::endl;
if (_glObjectID!=0)
{
_extensions->glDeleteBuffers(1, &_glObjectID);
@@ -1104,7 +1104,7 @@ void BufferObject::resizeGLObjectBuffers(unsigned int maxSize)
void BufferObject::releaseGLObjects(State* state) const
{
OSG_INFO<<"BufferObject::releaseGLObjects("<<state<<")"<<std::endl;
OSG_DEBUG<<"BufferObject::releaseGLObjects("<<state<<")"<<std::endl;
if (state)
{
unsigned int contextID = state->getContextID();
@@ -1260,7 +1260,7 @@ void BufferData::resizeGLObjectBuffers(unsigned int maxSize)
void BufferData::releaseGLObjects(State* state) const
{
OSG_INFO<<"BufferData::releaseGLObjects("<<state<<")"<<std::endl;
OSG_DEBUG<<"BufferData::releaseGLObjects("<<state<<")"<<std::endl;
if (_bufferObject.valid())
{
_bufferObject->releaseGLObjects(state);
@@ -1369,7 +1369,7 @@ PixelBufferObject::PixelBufferObject(osg::Image* image):
setTarget(GL_PIXEL_UNPACK_BUFFER_ARB);
setUsage(GL_STREAM_DRAW_ARB);
OSG_INFO<<"Constructing PixelBufferObject for image="<<image<<std::endl;
OSG_DEBUG<<"Constructing PixelBufferObject for image="<<image<<std::endl;
if (image) setBufferData(0, image);
}

View File

@@ -477,8 +477,9 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
isGLExtensionSupported(contextID,"GL_EXT_texture_cube_map") ||
(glVersion >= 1.3f));
isClipControlSupported = isGLExtensionSupported(contextID,"GL_ARB_clip_control") ||
(glVersion >= 4.5f);
isClipControlSupported = validContext &&
(isGLExtensionSupported(contextID,"GL_ARB_clip_control") ||
(glVersion >= 4.5f));
isGlslSupported = validContext &&
@@ -561,45 +562,47 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
setGLExtensionFuncPtr(glUniformMatrix3fv, "glUniformMatrix3fv", "glUniformMatrix3fvARB", validContext);
setGLExtensionFuncPtr(glUniformMatrix4fv, "glUniformMatrix4fv", "glUniformMatrix4fvARB", validContext);
setGLExtensionFuncPtr(glValidateProgram, "glValidateProgram", "glValidateProgramARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d", validContext);
setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d", "glVertexAttrib1dARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1dv, "glVertexAttrib1dv", validContext);
setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f", validContext);
setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv", validContext);
setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s", validContext);
setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f", "glVertexAttrib1fARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv", "glVertexAttrib1fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s", "glVertexAttrib1sARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1sv, "glVertexAttrib1sv", validContext);
setGLExtensionFuncPtr(glVertexAttrib2d, "glVertexAttrib2d", validContext);
setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv", validContext);
setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv", "glVertexAttrib2dvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib2f, "glVertexAttrib2f", validContext);
setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv", validContext);
setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv", "glVertexAttrib2fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib2s, "glVertexAttrib2s", validContext);
setGLExtensionFuncPtr(glVertexAttrib2sv, "glVertexAttrib2sv", validContext);
setGLExtensionFuncPtr(glVertexAttrib3d, "glVertexAttrib3d", validContext);
setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv", validContext);
setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv", "glVertexAttrib3dvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib3f, "glVertexAttrib3f", validContext);
setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv", validContext);
setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv", "glVertexAttrib3fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib3s, "glVertexAttrib3s", validContext);
setGLExtensionFuncPtr(glVertexAttrib3sv, "glVertexAttrib3sv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nbv, "glVertexAttrib4Nbv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Niv, "glVertexAttrib4Niv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nsv, "glVertexAttrib4Nsv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nub, "glVertexAttrib4Nub", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv", "glVertexAttrib4NubvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nuiv, "glVertexAttrib4Nuiv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nusv, "glVertexAttrib4Nusv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4bv, "glVertexAttrib4bv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4d, "glVertexAttrib4d", validContext);
setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv", "glVertexAttrib4dvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4f, "glVertexAttrib4f", validContext);
setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv", "glVertexAttrib4fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4iv, "glVertexAttrib4iv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4s, "glVertexAttrib4s", validContext);
setGLExtensionFuncPtr(glVertexAttrib4sv, "glVertexAttrib4sv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv", "glVertexAttrib4ubvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4uiv, "glVertexAttrib4uiv", validContext);
setGLExtensionFuncPtr(glVertexAttrib4usv, "glVertexAttrib4usv", validContext);
setGLExtensionFuncPtr(glVertexAttribPointer, "glVertexAttribPointer","glVertexAttribPointerARB", validContext);
setGLExtensionFuncPtr(glVertexAttribIPointer, "glVertexAttribIPointer","glVertexAttribIPointerARB", validContext);
setGLExtensionFuncPtr(glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribPointerARB", validContext);
setGLExtensionFuncPtr(glVertexAttribLPointer, "glVertexAttribLPointer","glVertexAttribLPointerARB", validContext);
setGLExtensionFuncPtr(glVertexAttribDivisor, "glVertexAttribDivisor", validContext);
// v1.5-only ARB entry points, in case they're needed for fallback
@@ -717,7 +720,6 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
isVBOSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_vertex_buffer_object"));
isPBOSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID,"GL_ARB_pixel_buffer_object"));
isUniformBufferObjectSupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_uniform_buffer_object");
isTBOSupported = validContext && osg::isGLExtensionSupported(contextID,"GL_ARB_texture_buffer_object");
isVAOSupported = validContext && (OSG_GL3_FEATURES || osg::isGLExtensionSupported(contextID, "GL_ARB_vertex_array_object", "GL_OES_vertex_array_object"));
isTransformFeedbackSupported = validContext && osg::isGLExtensionSupported(contextID, "GL_ARB_transform_feedback2");
@@ -736,7 +738,6 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
setGLExtensionFuncPtr(glBlendFuncSeparatei, "glBlendFuncSeparatei", "glBlendFuncSeparateiARB", validContext);
// Vertex Array extensions
isSecondaryColorSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_secondary_color");
isFogCoordSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_fog_coord");
isMultiTexSupported = validContext && isGLExtensionSupported(contextID,"GL_ARB_multitexture");
@@ -764,40 +765,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
setGLExtensionFuncPtr(glMultiTexCoord4fv, "glMultiTexCoord4fv","glMultiTexCoord4fvARB", validContext);
setGLExtensionFuncPtr(glMultiTexCoord1d, "glMultiTexCoord1d","glMultiTexCoorddfARB", validContext);
setGLExtensionFuncPtr(glMultiTexCoord1d, "glMultiTexCoord1d","glMultiTexCoord1dARB", validContext);
setGLExtensionFuncPtr(glMultiTexCoord1dv, "glMultiTexCoord1dv","glMultiTexCoord1dvARB", validContext);
setGLExtensionFuncPtr(glMultiTexCoord2dv, "glMultiTexCoord2dv","glMultiTexCoord2dvARB", validContext);
setGLExtensionFuncPtr(glMultiTexCoord3dv, "glMultiTexCoord3dv","glMultiTexCoord3dvARB", validContext);
setGLExtensionFuncPtr(glMultiTexCoord4dv, "glMultiTexCoord4dv","glMultiTexCoord4dvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1s, "glVertexAttrib1s","glVertexAttrib1sARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1f, "glVertexAttrib1f","glVertexAttrib1fARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1d, "glVertexAttrib1d","glVertexAttrib1dARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib1fv, "glVertexAttrib1fv","glVertexAttrib1fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib2fv, "glVertexAttrib2fv","glVertexAttrib2fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib3fv, "glVertexAttrib3fv","glVertexAttrib3fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4fv, "glVertexAttrib4fv","glVertexAttrib4fvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib2dv, "glVertexAttrib2dv","glVertexAttrib2dvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib3dv, "glVertexAttrib3dv","glVertexAttrib3dvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4dv, "glVertexAttrib4dv","glVertexAttrib4dvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4ubv, "glVertexAttrib4ubv","glVertexAttrib4ubvARB", validContext);
setGLExtensionFuncPtr(glVertexAttrib4Nubv, "glVertexAttrib4Nubv","glVertexAttrib4NubvARB", validContext);
setGLExtensionFuncPtr(glGenBuffers, "glGenBuffers","glGenBuffersARB", validContext);
setGLExtensionFuncPtr(glBindBuffer, "glBindBuffer","glBindBufferARB", validContext);
setGLExtensionFuncPtr(glBufferData, "glBufferData","glBufferDataARB", validContext);
setGLExtensionFuncPtr(glBufferSubData, "glBufferSubData","glBufferSubDataARB", validContext);
setGLExtensionFuncPtr(glDeleteBuffers, "glDeleteBuffers","glDeleteBuffersARB", validContext);
setGLExtensionFuncPtr(glIsBuffer, "glIsBuffer","glIsBufferARB", validContext);
setGLExtensionFuncPtr(glGetBufferSubData, "glGetBufferSubData","glGetBufferSubDataARB", validContext);
setGLExtensionFuncPtr(glMapBuffer, "glMapBuffer","glMapBufferARB", validContext);
setGLExtensionFuncPtr(glUnmapBuffer, "glUnmapBuffer","glUnmapBufferARB", validContext);
setGLExtensionFuncPtr(glGetBufferParameteriv, "glGetBufferParameteriv","glGetBufferParameterivARB", validContext);
setGLExtensionFuncPtr(glGetBufferPointerv, "glGetBufferPointerv","glGetBufferPointervARB", validContext);
setGLExtensionFuncPtr(glGenOcclusionQueries, "glGenOcclusionQueries","glGenOcclusionQueriesNV", validContext);
setGLExtensionFuncPtr(glDeleteOcclusionQueries, "glDeleteOcclusionQueries","glDeleteOcclusionQueriesNV", validContext);
setGLExtensionFuncPtr(glIsOcclusionQuery, "glIsOcclusionQuery","_glIsOcclusionQueryNV", validContext);
setGLExtensionFuncPtr(glIsOcclusionQuery, "glIsOcclusionQuery","glIsOcclusionQueryNV", validContext);
setGLExtensionFuncPtr(glBeginOcclusionQuery, "glBeginOcclusionQuery","glBeginOcclusionQueryNV", validContext);
setGLExtensionFuncPtr(glEndOcclusionQuery, "glEndOcclusionQuery","glEndOcclusionQueryNV", validContext);
setGLExtensionFuncPtr(glGetOcclusionQueryiv, "glGetOcclusionQueryiv","glGetOcclusionQueryivNV", validContext);
@@ -822,9 +798,7 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
// function pointers
setGLExtensionFuncPtr(glSampleMaski, "glSampleMaski", validContext);
// protect against buggy drivers (maybe not necessary)
isSampleMaskiSupported = glSampleMaski!=0;
isSampleMaskiSupported = validContext && (isOpenGL32upported || isGLExtensionSupported(contextID,"ARB_texture_multisample"));
// old styple Vertex/Fragment Programs
@@ -859,33 +833,36 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
isTextureCompressionS3TCSupported = validContext && (isGLExtensionSupported(contextID,"GL_EXT_texture_compression_s3tc") || isGLExtensionSupported(contextID, "GL_S3_s3tc"));
isTextureCompressionPVRTC2BPPSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
isTextureCompressionPVRTC4BPPSupported = isTextureCompressionPVRTC2BPPSupported;//covered by same extension
isTextureCompressionETCSupported = isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture");
isTextureCompressionETC2Supported = isGLExtensionSupported(contextID,"GL_ARB_ES3_compatibility");
isTextureCompressionRGTCSupported = isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc");
isTextureCompressionPVRTCSupported = isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
isTextureCompressionETCSupported = validContext && isGLExtensionSupported(contextID,"GL_OES_compressed_ETC1_RGB8_texture");
isTextureCompressionETC2Supported = validContext && isGLExtensionSupported(contextID,"GL_ARB_ES3_compatibility");
isTextureCompressionRGTCSupported = validContext && isGLExtensionSupported(contextID,"GL_EXT_texture_compression_rgtc");
isTextureCompressionPVRTCSupported = validContext && isGLExtensionSupported(contextID,"GL_IMG_texture_compression_pvrtc");
isTextureMirroredRepeatSupported = builtInSupport ||
isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4f) ||
isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4f);
isTextureMirroredRepeatSupported = validContext &&
(builtInSupport ||
isGLExtensionOrVersionSupported(contextID,"GL_IBM_texture_mirrored_repeat", 1.4f) ||
isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_mirrored_repeat", 1.4f));
isTextureEdgeClampSupported = builtInSupport ||
isTextureEdgeClampSupported = validContext &&
(builtInSupport ||
isGLExtensionOrVersionSupported(contextID,"GL_EXT_texture_edge_clamp", 1.2f) ||
isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f);
isGLExtensionOrVersionSupported(contextID,"GL_SGIS_texture_edge_clamp", 1.2f));
isTextureBorderClampSupported = OSG_GL3_FEATURES ||
((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f)) ||
(OSG_GLES2_FEATURES && isGLExtensionSupported(contextID,"GL_EXT_texture_border_clamp"));
isTextureBorderClampSupported = validContext &&
(OSG_GL3_FEATURES ||
((OSG_GL1_FEATURES || OSG_GL2_FEATURES) && isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_border_clamp", 1.3f)) ||
(OSG_GLES2_FEATURES && isGLExtensionSupported(contextID,"GL_EXT_texture_border_clamp")));
isGenerateMipMapSupported = builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f);
isGenerateMipMapSupported = validContext && (builtInSupport || isGLExtensionOrVersionSupported(contextID,"GL_SGIS_generate_mipmap", 1.4f));
preferGenerateMipmapSGISForPowerOfTwo = (radeonHardwareDetected||fireGLHardwareDetected) ? false : true;
isTextureMultisampledSupported = isGLExtensionSupported(contextID,"GL_ARB_texture_multisample");
isShadowSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow");
isShadowAmbientSupported = isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient");
isClientStorageSupported = isGLExtensionSupported(contextID,"GL_APPLE_client_storage");
isNonPowerOfTwoTextureNonMipMappedSupported = builtInSupport || isGLExtensionSupported(contextID,"GL_OES_texture_npot") || isGLExtensionOrVersionSupported(contextID,"GL_ARB_texture_non_power_of_two", 2.0) || isGLExtensionSupported(contextID,"GL_APPLE_texture_2D_limited_npot");
isNonPowerOfTwoTextureMipMappedSupported = builtInSupport || isNonPowerOfTwoTextureNonMipMappedSupported;
isTextureIntegerEXTSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer");
isTextureMultisampledSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_texture_multisample"));
isShadowSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_shadow"));
isShadowAmbientSupported = validContext && (isGLExtensionSupported(contextID,"GL_ARB_shadow_ambient"));
isClientStorageSupported = validContext && (isGLExtensionSupported(contextID,"GL_APPLE_client_storage"));
isNonPowerOfTwoTextureMipMappedSupported = validContext && (builtInSupport || isGLExtensionSupported(contextID, "GL_OES_texture_npot") || isGLExtensionOrVersionSupported(contextID, "GL_ARB_texture_non_power_of_two", 2.0));
isNonPowerOfTwoTextureNonMipMappedSupported = validContext && (isNonPowerOfTwoTextureMipMappedSupported || isGLExtensionSupported(contextID, "GL_APPLE_texture_2D_limited_npot"));
isTextureIntegerEXTSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_EXT_texture_integer"));
if (rendererString.find("GeForce FX")!=std::string::npos)
{
@@ -914,19 +891,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
setGLExtensionFuncPtr(glGetCompressedTexImage,"glGetCompressedTexImage","glGetCompressedTexImageARB", validContext);;
setGLExtensionFuncPtr(glTexImage2DMultisample, "glTexImage2DMultisample", "glTexImage2DMultisampleARB", validContext);
setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB", validContext);
setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB", validContext);
if (glTexParameterIiv == NULL) setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIivEXT", validContext);
if (glTexParameterIuiv == NULL) setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuivEXT", validContext);
setGLExtensionFuncPtr(glTexParameterIiv, "glTexParameterIiv", "glTexParameterIivARB", "glTexParameterIivEXT", validContext);
setGLExtensionFuncPtr(glTexParameterIuiv, "glTexParameterIuiv", "glTexParameterIuivARB", "glTexParameterIuivEXT", validContext);
setGLExtensionFuncPtr(glBindImageTexture, "glBindImageTexture", "glBindImageTextureARB", validContext);
isTextureMaxLevelSupported = (glVersion >= 1.2f);
isTextureStorageEnabled = isTexStorage2DSupported();
if ( (ptr = getenv("OSG_GL_TEXTURE_STORAGE")) != 0 && isTexStorage2DSupported())
isTextureStorageEnabled = validContext && ((glVersion >= 4.2f) || isGLExtensionSupported(contextID, "GL_ARB_texture_storage"));
if ( (ptr = getenv("OSG_GL_TEXTURE_STORAGE")) != 0 && isTextureStorageEnabled)
{
if (strcmp(ptr,"OFF")==0 || strcmp(ptr,"DISABLE")==0 ) isTextureStorageEnabled = false;
else isTextureStorageEnabled = true;
@@ -934,10 +907,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
// Texture3D extensions
isTexture3DFast = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D");
isTexture3DFast = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture3D"));
if (isTexture3DFast) isTexture3DSupported = true;
else isTexture3DSupported = (glVersion >= 1.2f);
else isTexture3DSupported = validContext && (glVersion >= 1.2f);
maxTexture3DSize = 0;
if (validContext) glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &maxTexture3DSize);
@@ -950,7 +923,7 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
// Texture2DArray extensions
isTexture2DArraySupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture_array");
isTexture2DArraySupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_EXT_texture_array"));
max2DSize = 0;
if (validContext) glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max2DSize);
@@ -965,25 +938,28 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
setGLExtensionFuncPtr(glIsTextureHandleResident, "glIsTextureHandleResident","glIsTextureHandleResidentARB", "glIsTextureHandleResidentNV", validContext);
// Blending
isBlendColorSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES ||
isGLExtensionSupported(contextID,"GL_EXT_blend_color") ||
(glVersion >= 1.2f);
isBlendColorSupported = validContext &&
(OSG_GLES2_FEATURES || OSG_GL3_FEATURES ||
isGLExtensionSupported(contextID,"GL_EXT_blend_color") ||
(glVersion >= 1.2f));
setGLExtensionFuncPtr(glBlendColor, "glBlendColor", "glBlendColorEXT", validContext);
bool bultInSupport = OSG_GLES2_FEATURES || OSG_GL3_FEATURES;
isBlendEquationSupported = bultInSupport ||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation") ||
(glVersion >= 1.2f);
isBlendEquationSupported = validContext &&
(bultInSupport ||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation") ||
(glVersion >= 1.2f));
isBlendEquationSeparateSupported = bultInSupport ||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") ||
(glVersion >= 2.0f);
isBlendEquationSeparateSupported = validContext &&
(bultInSupport ||
isGLExtensionSupported(contextID, "GL_EXT_blend_equation_separate") ||
(glVersion >= 2.0f));
isSGIXMinMaxSupported = isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax");
isLogicOpSupported = isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op");
isSGIXMinMaxSupported = validContext && isGLExtensionSupported(contextID, "GL_SGIX_blend_alpha_minmax");
isLogicOpSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_blend_logic_op");
setGLExtensionFuncPtr(glBlendEquation, "glBlendEquation", "glBlendEquationEXT", validContext);
setGLExtensionFuncPtr(glBlendEquationSeparate, "glBlendEquationSeparate", "glBlendEquationSeparateEXT", validContext);
@@ -998,10 +974,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
// Stencil`
isStencilWrapSupported = isGLExtensionOrVersionSupported(contextID, "GL_EXT_stencil_wrap", 1.4f);
isStencilTwoSidedSupported = isGLExtensionSupported(contextID, "GL_EXT_stencil_two_side");
isOpenGL20Supported = (glVersion >= 2.0f);
isSeparateStencilSupported = isGLExtensionSupported(contextID, "GL_ATI_separate_stencil");
isStencilWrapSupported = validContext && isGLExtensionOrVersionSupported(contextID, "GL_EXT_stencil_wrap", 1.4f);
isStencilTwoSidedSupported = validContext && isGLExtensionSupported(contextID, "GL_EXT_stencil_two_side");
isOpenGL20Supported = validContext && (glVersion >= 2.0f);
isSeparateStencilSupported = validContext && isGLExtensionSupported(contextID, "GL_ATI_separate_stencil");
// function pointers
setGLExtensionFuncPtr(glActiveStencilFace, "glActiveStencilFaceEXT", validContext);
@@ -1016,9 +992,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
// ClampColor
isClampColorSupported = OSG_GL3_FEATURES ||
isClampColorSupported = validContext &&
(OSG_GL3_FEATURES ||
isGLExtensionSupported(contextID,"GL_ARB_color_buffer_float") ||
(glVersion >= 2.0f);
(glVersion >= 2.0f));
setGLExtensionFuncPtr(glClampColor, "glClampColor", "glClampColorARB", validContext);
@@ -1028,14 +1005,15 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
// Point
isPointParametersSupported = OSG_GL3_FEATURES || (glVersion >= 1.4f) ||
isPointParametersSupported = validContext &&
(OSG_GL3_FEATURES || (glVersion >= 1.4f) ||
isGLExtensionSupported(contextID,"GL_ARB_point_parameters") ||
isGLExtensionSupported(contextID,"GL_EXT_point_parameters") ||
isGLExtensionSupported(contextID,"GL_SGIS_point_parameters");
isGLExtensionSupported(contextID,"GL_SGIS_point_parameters"));
isPointSpriteSupported = OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_ARB_point_sprite") || isGLExtensionSupported(contextID, "GL_OES_point_sprite") || isGLExtensionSupported(contextID, "GL_NV_point_sprite");
isPointSpriteCoordOriginSupported = OSG_GL3_FEATURES || (glVersion >= 2.0f);
isPointSpriteSupported = validContext && (OSG_GL3_FEATURES || isGLExtensionSupported(contextID, "GL_ARB_point_sprite") || isGLExtensionSupported(contextID, "GL_OES_point_sprite") || isGLExtensionSupported(contextID, "GL_NV_point_sprite"));
isPointSpriteCoordOriginSupported = validContext && (OSG_GL3_FEATURES || (glVersion >= 2.0f));
setGLExtensionFuncPtr(glPointParameteri, "glPointParameteri", "glPointParameteriARB", validContext);
@@ -1049,10 +1027,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
// Multisample
isMultisampleSupported = OSG_GLES2_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_multisample");
isMultisampleFilterHintSupported = isGLExtensionSupported(contextID, "GL_NV_multisample_filter_hint");
isMultisampleSupported = validContext && (OSG_GLES2_FEATURES || OSG_GL3_FEATURES || isGLExtensionSupported(contextID,"GL_ARB_multisample"));
isMultisampleFilterHintSupported = validContext && isGLExtensionSupported(contextID, "GL_NV_multisample_filter_hint");
setGLExtensionFuncPtr(glSampleCoverage, "glSampleCoverageARB", validContext);
setGLExtensionFuncPtr(glSampleCoverage, "glSampleCoverage", "glSampleCoverageARB", validContext);
// FrameBufferObject
@@ -1095,9 +1073,10 @@ GLExtensions::GLExtensions(unsigned int in_contextID):
( OSG_GLES1_FEATURES || isGLExtensionOrVersionSupported(contextID, "GL_EXT_framebuffer_object",3.0f) );
isPackedDepthStencilSupported = OSG_GL3_FEATURES ||
(isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) ||
(isGLExtensionSupported(contextID, "GL_OES_packed_depth_stencil"));
isPackedDepthStencilSupported = validContext &&
(OSG_GL3_FEATURES ||
(isGLExtensionSupported(contextID, "GL_EXT_packed_depth_stencil")) ||
(isGLExtensionSupported(contextID, "GL_OES_packed_depth_stencil")));
//subroutine
osg::setGLExtensionFuncPtr(glGetSubroutineUniformLocation, "glGetSubroutineUniformLocation", validContext);

View File

@@ -205,15 +205,10 @@ public:
traverse(node);
}
virtual void apply(osg::Geode& geode)
virtual void apply(osg::Geometry& geom)
{
apply(geode.getStateSet());
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
apply(geode.getDrawable(i)->getStateSet());
osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
if (geometry) apply(geometry);
}
apply(geom.getStateSet());
apply(&geom);
}
void apply(osg::StateSet* stateset)
@@ -282,15 +277,10 @@ public:
traverse(node);
}
virtual void apply(osg::Geode& geode)
virtual void apply(osg::Geometry& geom)
{
apply(geode.getStateSet());
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
apply(geode.getDrawable(i)->getStateSet());
osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
if (geometry) apply(geometry);
}
apply(geom.getStateSet());
apply(&geom);
}
void apply(osg::StateSet* stateset)

View File

@@ -732,26 +732,42 @@ void Program::PerContextProgram::linkProgram(osg::State& state)
if (!_loadedBinary)
{
// Detach removed shaders
for( unsigned int i=0; i < _shadersToDetach.size(); ++i )
const GLsizei shaderMaxCount = 20;
GLsizei shadersCount;
GLuint shaderObjectHandle[shaderMaxCount];
_extensions->glGetAttachedShaders(_glProgramHandle, shaderMaxCount, &shadersCount, shaderObjectHandle);
typedef std::map<GLuint, int> ShaderSet;
ShaderSet shadersRequired;
for(GLsizei i=0; i<shadersCount; ++i)
{
Shader::PerContextShader* pcs = _shadersToDetach[i]->getPCS(state);
if (pcs) _extensions->glDetachShader( _glProgramHandle, pcs->getHandle() );
shadersRequired[shaderObjectHandle[i]]--;
}
for(unsigned int i=0; i < getProgram()->getNumShaders(); ++i)
{
const Shader* shader = getProgram()->getShader( i );
Shader::PerContextShader* pcs = shader->getPCS(state);
if (pcs) shadersRequired[ pcs->getHandle() ]++;
}
for(ShaderSet::iterator itr = shadersRequired.begin();
itr != shadersRequired.end();
++itr)
{
if (itr->second>0)
{
_extensions->glAttachShader( _glProgramHandle, itr->first );
}
else if (itr->second<0)
{
_extensions->glDetachShader( _glProgramHandle, itr->first );
}
}
}
_shadersToDetach.clear();
if (!_loadedBinary)
{
// Attach new shaders
for( unsigned int i=0; i < _shadersToAttach.size(); ++i )
{
Shader::PerContextShader* pcs = _shadersToAttach[i]->getPCS(state);
if (pcs) _extensions->glAttachShader( _glProgramHandle, pcs->getHandle() );
}
}
//state.checkGLErrors("After attaching shaders.");
_shadersToAttach.clear();
_uniformInfoMap.clear();
@@ -805,12 +821,12 @@ void Program::PerContextProgram::linkProgram(osg::State& state)
if( ! _isLinked )
{
OSG_WARN << "glLinkProgram \""<< _program->getName() << "\" FAILED" << std::endl;
OSG_NOTICE << "glLinkProgram "<<this<<"\""<< _program->getName() << "\" FAILED" << std::endl;
std::string infoLog;
if( getInfoLog(infoLog) )
{
OSG_WARN << "Program \""<< _program->getName() << "\" "
OSG_NOTICE << "Program \""<< _program->getName() << "\" "
"infolog:\n" << infoLog << std::endl;
}

View File

@@ -142,8 +142,12 @@ State::~State()
// delete the GLExtensions object associated with this osg::State.
if (_glExtensions)
{
GLExtensions::Set(_contextID, 0);
_glExtensions = 0;
GLExtensions* glExtensions = GLExtensions::Get(_contextID, false);
if (glExtensions && glExtensions->referenceCount() == 1) {
// the only reference left to the extension is in the static map itself, so we clean it up now
GLExtensions::Set(_contextID, 0);
}
}
//_texCoordArrayList.clear();
@@ -166,8 +170,7 @@ void State::initializeExtensionProcs()
_defineMap.changed = true;
}
_glExtensions = new GLExtensions(_contextID);
GLExtensions::Set(_contextID, _glExtensions.get());
_glExtensions = GLExtensions::Get(_contextID, true);
_isSecondaryColorSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_secondary_color");
_isFogCoordSupported = osg::isGLExtensionSupported(_contextID,"GL_EXT_fog_coord");

View File

@@ -44,7 +44,7 @@ void StateAttribute::removeParent(osg::StateSet* object)
void StateAttribute::setUpdateCallback(StateAttributeCallback* uc)
{
OSG_INFO<<"StateAttribute::Setting Update callbacks"<<std::endl;
OSG_DEBUG<<"StateAttribute::Setting Update callbacks"<<std::endl;
if (_updateCallback==uc) return;
@@ -56,14 +56,10 @@ void StateAttribute::setUpdateCallback(StateAttributeCallback* uc)
if (delta!=0)
{
OSG_INFO<<"Going to set StateAttribute parents"<<std::endl;
for(ParentList::iterator itr=_parents.begin();
itr!=_parents.end();
++itr)
{
OSG_INFO<<" Setting StateAttribute parent"<<std::endl;
(*itr)->setNumChildrenRequiringUpdateTraversal((*itr)->getNumChildrenRequiringUpdateTraversal()+delta);
}
}
@@ -71,7 +67,7 @@ void StateAttribute::setUpdateCallback(StateAttributeCallback* uc)
void StateAttribute::setEventCallback(StateAttributeCallback* ec)
{
OSG_INFO<<"StateAttribute::Setting Event callbacks"<<std::endl;
OSG_DEBUG<<"StateAttribute::Setting Event callbacks"<<std::endl;
if (_eventCallback==ec) return;

View File

@@ -313,7 +313,7 @@ void Texture2D::apply(State& state) const
glBindTexture( GL_TEXTURE_2D, 0 );
}
// if texture object is now valid and we have to allocate mipmap levels, then
// if texture object is now valid and we have to allocate mipmap levels, then
if (textureObject != 0 && _texMipmapGenerationDirtyList[contextID])
{
generateMipmap(state);

View File

@@ -18,7 +18,7 @@
using namespace osg;
#if 1
#define VAS_NOTICE OSG_INFO
#define VAS_NOTICE OSG_DEBUG
#else
#define VAS_NOTICE OSG_NOTICE
#endif

View File

@@ -93,20 +93,6 @@ void SharedStateManager::apply(osg::Node& node)
if(ss) process(ss, &node);
traverse(node);
}
void SharedStateManager::apply(osg::Geode& geode)
{
osg::StateSet* ss = geode.getStateSet();
if(ss) process(ss, &geode);
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
osg::Drawable* drawable = geode.getDrawable(i);
if(drawable)
{
ss = drawable->getStateSet();
if(ss) process(ss, drawable);
}
}
}
bool SharedStateManager::isShared(osg::StateSet* ss)
{

View File

@@ -33,7 +33,7 @@ osg::Vec3d snap_point_to_grid(const osg::Vec3d& point, const osg::Vec3d& origin,
scale[1] = spacing[1] ? round_to_nearest_int((point[1] - origin[1]) / spacing[1]) : 1.0;
scale[2] = spacing[2] ? round_to_nearest_int((point[2] - origin[2]) / spacing[2]) : 1.0;
osg::Vec3d snappedPoint = origin;
snappedPoint += osg::Vec3(scale[0]*spacing[0],scale[1]*spacing[1],scale[2]*spacing[2]);
snappedPoint += osg::Vec3d(scale[0]*spacing[0],scale[1]*spacing[1],scale[2]*spacing[2]);
return snappedPoint;
}

View File

@@ -62,7 +62,7 @@ void ComputeAABBOnBoneVisitor::computeBoundingBoxOnBones() {
}
// Compare initial and actual boundingBox if (no change) => no box on bone
if(bb == osg::BoundingBox() || bb._min.x() == bb._max.x() || bb._min.y() == bb._max.y() || bb._min.z() == bb._max.z()) {
if(bb == osg::BoundingBox() || (bb._min.x() == bb._max.x() && bb._min.y() == bb._max.y() && bb._min.z() == bb._max.z())) {
continue;
}

View File

@@ -5,9 +5,9 @@ SET(TARGET_SRC
BindPerVertexVisitor.cpp
DetachPrimitiveVisitor.cpp
GeometryIndexSplitter.cpp
GeometrySplitterVisitor.cpp
SubGeometry.cpp
OpenGLESGeometryOptimizer.cpp
RemapGeometryVisitor.cpp
RigAnimationVisitor.cpp
RigAttributesVisitor.cpp
TriangleMeshSmoother.cpp
@@ -25,9 +25,11 @@ SET(TARGET_H
DrawArrayVisitor
EdgeIndexFunctor
GeometryArray
GeometryCleaner
GeometryIndexSplitter
GeometryInspector
GeometrySplitterVisitor
GeometryMapper
RemapGeometryVisitor
GeometryUniqueVisitor
glesUtil
IndexMeshVisitor

View File

@@ -0,0 +1,138 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commercial and non commercial
* applications, as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef GEOMETRY_CLEANER
#define GEOMETRY_CLEANER
#include <osg/Geometry>
#include <osgAnimation/RigGeometry>
#include <osgAnimation/MorphGeometry>
#include "GeometryMapper"
#include "SubGeometry"
class GeometryCleaner : public GeometryMapper
{
public:
const GeometryList& process(osg::Geometry& geometry) {
_clean.clear();
if(dynamic_cast<osgAnimation::MorphGeometry*>(&geometry)) {
// a morph geometry may have a degenerated primitive in one target but not all targets
// let's leave them unmodified
_clean.push_back(&geometry);
}
else if(dynamic_cast<osgAnimation::RigGeometry*>(&geometry)) {
// skipping rigged geometry for now
_clean.push_back(&geometry);
}
else {
osg::Vec3Array* positions = dynamic_cast<osg::Vec3Array*>(geometry.getVertexArray());
SubGeometry cleaned(geometry,
clean(*positions, getTriangles(geometry), 3),
clean(*positions, getLines(geometry), 2),
clean(*positions, getWireframe(geometry), 2),
clean(*positions, getPoints(geometry), 1));
_clean.push_back(cleaned.geometry());
}
return _clean;
}
osg::DrawElements* getTriangles(osg::Geometry& geometry) {
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
if(primitive && primitive->getMode() == osg::PrimitiveSet::TRIANGLES) {
return primitive;
}
}
return 0;
}
osg::DrawElements* getLines(osg::Geometry& geometry) {
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
if(primitive && primitive->getMode() == osg::PrimitiveSet::LINES) {
bool wireframe(false);
if(!primitive->getUserValue("wireframe", wireframe) || !wireframe)
return primitive;
}
}
return 0;
}
osg::DrawElements* getWireframe(osg::Geometry& geometry) {
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
if(primitive && primitive->getMode() == osg::PrimitiveSet::LINES) {
bool wireframe(false);
if(primitive->getUserValue("wireframe", wireframe) && wireframe)
return primitive;
}
}
return 0;
}
osg::DrawElements* getPoints(osg::Geometry& geometry) {
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
osg::DrawElements* primitive = geometry.getPrimitiveSet(i)->getDrawElements();
if(primitive && primitive->getMode() == osg::PrimitiveSet::POINTS) {
return primitive;
}
}
return 0;
}
std::vector<unsigned int> clean(const osg::Vec3Array& positions, osg::DrawElements* elements, const unsigned int size) {
std::vector<unsigned int> indices;
if(!elements) return indices;
for(unsigned int i = 0 ; i < elements->getNumIndices() ; i += size) {
if(size == 3) {
unsigned int v1 = elements->index(i),
v2 = elements->index(i + 1),
v3 = elements->index(i + 2);
osg::Vec3 p1 = positions[v1],
p2 = positions[v2],
p3 = positions[v3];
osg::Vec3f cross = (p2 - p1) ^ (p3 - p1);
if(cross.length()) {
indices.push_back(v1);
indices.push_back(v2);
indices.push_back(v3);
}
}
else if (size == 2) {
unsigned int v1 = elements->index(i),
v2 = elements->index(i + 1);
if(!(positions[v1] == positions[v2])) {
indices.push_back(v1);
indices.push_back(v2);
}
}
else {
indices.push_back(elements->index(i));
}
}
return indices;
}
GeometryList _clean;
};
#endif

View File

@@ -25,15 +25,81 @@
#include <osgAnimation/RigGeometry>
#include "glesUtil"
#include "GeometryMapper"
#include "GeometryArray"
#include "TriangleMeshGraph"
#include "SubGeometry"
#include "Line"
class GeometryIndexSplitter
class GeometryIndexSplitter : public GeometryMapper
{
protected:
class Cluster {
public:
Cluster(unsigned int maxAllowedIndex):
maxIndex(maxAllowedIndex)
{
}
bool full() const {
return subvertices.size() >= maxIndex;
}
bool fullOfTriangles() const {
// consider worse case i.e. no triangle vertex is already in the cluster
// so need room for 3 indices
return subvertices.size() + 3 >= maxIndex;
}
bool fullOfLines() const {
return subvertices.size() + 2 >= maxIndex;
}
bool contains(unsigned int v1, unsigned int v2) const {
return contains(v1) && contains(v2);
}
bool contains(unsigned int v1) const {
return subvertices.count(v1);
}
void addTriangle(unsigned int v1, unsigned int v2, unsigned v3) {
subtriangles.push_back(v1);
subtriangles.push_back(v2);
subtriangles.push_back(v3);
subvertices.insert(v1);
subvertices.insert(v2);
subvertices.insert(v3);
}
void addLine(unsigned int v1, unsigned int v2) {
sublines.push_back(v1);
sublines.push_back(v2);
subvertices.insert(v1);
subvertices.insert(v2);
}
void addPoint(unsigned int v1) {
subpoints.push_back(v1);
subvertices.insert(v1);
}
void addWire(unsigned int v1, unsigned int v2) {
subwireframe.push_back(v1);
subwireframe.push_back(v2);
}
public:
const unsigned int maxIndex;
IndexVector subtriangles, subwireframe, sublines, subpoints;
IndexSet subvertices;
};
class IndexCache : public IndexDeque {
public:
IndexCache(unsigned int size=64) : _size(size)
@@ -48,18 +114,29 @@ protected:
};
public:
typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryList;
GeometryIndexSplitter(unsigned int maxAllowedIndex):
_maxAllowedIndex(maxAllowedIndex)
{}
const GeometryList& process(osg::Geometry& geometry) {
_geometryList.clear();
split(geometry);
return _geometryList;
}
bool split(osg::Geometry&);
unsigned int findCandidate(const IndexVector&);
unsigned int findCandidate(const IndexVector&, const IndexVector&);
void setTriangleCluster(const TriangleMeshGraph&, unsigned int, unsigned int, IndexVector&, IndexSet&, unsigned int&);
void extract_primitives(const IndexSet&, const osg::DrawElements*, IndexVector&, unsigned int);
template<typename C>
typename C::value_type getNext(C& primitives, typename C::value_type default_value) {
if(primitives.empty()) {
return default_value;
}
typename C::value_type next = *primitives.begin();
primitives.erase(primitives.begin());
return next;
}
unsigned int findCandidate(IndexSet&, const IndexCache&, const TriangleMeshGraph&);
protected:
bool needToSplit(const osg::Geometry&) const;
@@ -68,7 +145,6 @@ protected:
template<typename T>
void setBufferBoundingBox(T*) const;
void setValidIndices(std::set<unsigned int>&, const osg::DrawElements*) const;
public:
const unsigned int _maxAllowedIndex;

View File

@@ -11,8 +11,8 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
attachBufferBoundingBox(geometry);
osg::DrawElements *wire_primitive = 0,
*line_primitive = 0,
*point_primitive = 0;
*line_primitive = 0,
*point_primitive = 0;
for(unsigned int i = 0 ; i < geometry.getNumPrimitiveSets() ; ++ i) {
osg::DrawElements* primitive = (geometry.getPrimitiveSet(i) ? geometry.getPrimitiveSet(i)->getDrawElements() : 0);
if(primitive) {
@@ -31,29 +31,34 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
}
}
TriangleMeshGraph graph(geometry, false);
// only wireframe can be processed directly as they simply "duplicate" triangle or edge data;
// lines/points may reference points not used for triangles so we keep a set of primitives
// that remain to process
LineSet source_lines;
IndexSet source_points;
IndexSet triangles;
LineSet lines, wires;
IndexSet points;
for(unsigned int i = 0 ; i < graph.getNumTriangles() ; ++ i) {
triangles.insert(i);
}
if(line_primitive) {
for(unsigned int i = 0 ; i < line_primitive->getNumIndices() ; i += 2) {
source_lines.insert(Line(line_primitive->index(i), line_primitive->index(i + 1)));
lines.insert(Line(line_primitive->index(i), line_primitive->index(i + 1)));
}
}
if(wire_primitive) {
for(unsigned int i = 0 ; i < wire_primitive->getNumIndices() ; i += 2) {
wires.insert(Line(wire_primitive->index(i), wire_primitive->index(i + 1)));
}
}
if(point_primitive) {
for(unsigned int i = 0 ; i < point_primitive->getNumIndices() ; ++ i) {
source_points.insert(point_primitive->index(i));
points.insert(point_primitive->index(i));
}
}
TriangleMeshGraph graph(geometry, false);
unsigned int remaining_triangles = graph.getNumTriangles(),
cluster = 0;
IndexVector clusters(remaining_triangles, 0);
IndexCache cache;
// assign a cluster id for each triangle
// 1. bootstrap cluster by selecting first remaining triangle
// 2. while cluster size is < max cluster size
@@ -64,95 +69,75 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
// 3. insert wireframe edges corresponding to selected triangles
// 4. extract subgeometry
while(remaining_triangles || !source_lines.empty() || !source_points.empty()) {
IndexVector subtriangles, subwireframe, sublines, subpoints;
IndexSet cluster_vertices;
while(triangles.size() || lines.size() || points.size()) {
Cluster cluster(_maxAllowedIndex);
IndexCache cache;
unsigned int candidate = std::numeric_limits<unsigned int>::max();
++ cluster;
// let's consider that every insert needs the place for a full new primitive for simplicity
while(!cluster.fullOfTriangles() &&
(candidate = findCandidate(triangles, cache, graph)) != std::numeric_limits<unsigned int>::max()) {
cache.push_back(candidate);
Triangle t = graph.triangle(candidate);
cluster.addTriangle(t.v1(), t.v2(), t.v3());
}
if(remaining_triangles) {
// find first unmarked triangle (as remaining_triangles > 0 there *must* be at least one)
cache.push_back(findCandidate(clusters));
setTriangleCluster(graph, cache.back(), cluster, clusters, cluster_vertices, remaining_triangles);
while(!cluster.fullOfLines() && lines.size()) {
Line line = getNext(lines, Line(std::numeric_limits<unsigned int>::max(), std::numeric_limits<unsigned int>::max()));
cluster.addLine(line._a, line._b);
}
while(remaining_triangles && cluster_vertices.size() < _maxAllowedIndex) {
unsigned int candidate = std::numeric_limits<unsigned int>::max();
while(!cluster.full() && points.size()) {
unsigned int point = getNext(points, std::numeric_limits<unsigned int>::max());
cluster.addPoint(point);
}
for(IndexCache::const_reverse_iterator cached = cache.rbegin() ; cached != cache.rend() ; ++ cached) {
candidate = findCandidate(graph.triangleNeighbors(*cached), clusters);
if(candidate != std::numeric_limits<unsigned int>::max()) break;
// update lines/points: if all vertices referenced by a point/line primitive are
// already extracted, let's insert it in the subgeometry and update the set of
// primitives still remaining Lines may e.g. reference one vertex in cluster A and
// the other in cluster B hence need specific care
if(line_primitive) {
for(LineSet::iterator line = lines.begin() ; line != lines.end() ; ) {
if(cluster.contains(line->_a, line->_b)) {
cluster.addLine(line->_a, line->_b);
lines.erase(line ++);
}
if(candidate == std::numeric_limits<unsigned int>::max()) {
// do we have room for a triangle having all vertices not in the cluster?
if(!(cluster_vertices.size() + 2 < _maxAllowedIndex)) {
break;
}
candidate = findCandidate(clusters);
}
cache.push_back(candidate);
setTriangleCluster(graph, candidate, cluster, clusters, cluster_vertices, remaining_triangles);
}
// build list of cluster triangles
for(unsigned int triangle = 0 ; triangle < clusters.size() ; ++ triangle) {
if(clusters[triangle] == cluster) {
const Triangle& t = graph.triangle(triangle);
subtriangles.push_back(t.v1());
subtriangles.push_back(t.v2());
subtriangles.push_back(t.v3());
}
}
// update lines/points: if all vertices referenced by a point/line primitive are
// already extracted, let's insert it in the subgeometry and update the set of
// primitives still remaining Lines may e.g. reference one vertex in cluster A and
// the other in cluster B hence need specific care
if(line_primitive) {
extract_primitives(cluster_vertices, line_primitive, sublines, 2);
for(unsigned int i = 0 ; i < sublines.size() / 2 ; i += 2) {
source_lines.erase(Line(sublines[i], sublines[i + 1]));
}
}
if(point_primitive) {
extract_primitives(cluster_vertices, point_primitive, subpoints, 1);
for(unsigned int i = 0 ; i < subpoints.size() ; ++ i) {
source_points.erase(subpoints[i]);
else {
++ line;
}
}
}
// let's consider that every new lines adds 2 vertices for simplicity
while(!source_lines.empty() && cluster_vertices.size() - 1 < _maxAllowedIndex) {
Line line = *source_lines.begin();
source_lines.erase(source_lines.begin());
cluster_vertices.insert(line._a);
cluster_vertices.insert(line._b);
sublines.push_back(line._a);
sublines.push_back(line._b);
}
while(!source_points.empty() && cluster_vertices.size() < _maxAllowedIndex) {
unsigned int point = *source_points.begin();
source_points.erase(source_points.begin());
cluster_vertices.insert(point);
subpoints.push_back(point);
if(point_primitive) {
// find all cluster vertices that should also have a point primitive
for(IndexSet::iterator subvertex = cluster.subvertices.begin() ; subvertex != cluster.subvertices.end() ; ++ subvertex) {
unsigned int index = *subvertex;
if(points.find(index) != points.end()) {
cluster.addPoint(index);
points.erase(index);
}
}
}
// finally extract wireframe (may originate from triangles or lines but necessarily have
// to reference vertices that are *all* in the geometry)
if(wire_primitive) {
extract_primitives(cluster_vertices, wire_primitive, subwireframe, 2);
for(LineSet::iterator wire = wires.begin() ; wire != wires.end() ; ) {
if(cluster.contains(wire->_a, wire->_b)) {
cluster.addWire(wire->_a, wire->_b);
wires.erase(wire ++);
}
else {
++ wire;
}
}
}
_geometryList.push_back(SubGeometry(geometry,
subtriangles,
sublines,
subwireframe,
subpoints).geometry());
cluster.subtriangles,
cluster.sublines,
cluster.subwireframe,
cluster.subpoints).geometry());
}
osg::notify(osg::NOTICE) << "geometry " << &geometry << " " << geometry.getName()
@@ -164,60 +149,20 @@ bool GeometryIndexSplitter::split(osg::Geometry& geometry) {
}
unsigned int GeometryIndexSplitter::findCandidate(const IndexVector& clusters) {
for(unsigned int i = 0 ; i < clusters.size() ; ++ i) {
if(!clusters[i]) {
return i;
}
}
return std::numeric_limits<unsigned int>::max();
}
unsigned int GeometryIndexSplitter::findCandidate(const IndexVector& candidates, const IndexVector& clusters) {
for(IndexVector::const_iterator candidate = candidates.begin() ; candidate != candidates.end() ; ++ candidate) {
if(!clusters[*candidate]) {
return *candidate;
}
}
return std::numeric_limits<unsigned int>::max();
}
void GeometryIndexSplitter::setTriangleCluster(const TriangleMeshGraph& graph,
unsigned int triangle,
unsigned int cluster,
IndexVector& clusters,
IndexSet& cluster_vertices,
unsigned int& remaining) {
clusters[triangle] = cluster;
const Triangle& t = graph.triangle(triangle);
cluster_vertices.insert(t.v1());
cluster_vertices.insert(t.v2());
cluster_vertices.insert(t.v3());
remaining --;
}
void GeometryIndexSplitter::extract_primitives(const IndexSet& vertices,
const osg::DrawElements* elements,
IndexVector& indices,
unsigned int primitive_size) {
for(unsigned int i = 0 ; i < elements->getNumIndices() ; i += primitive_size) {
bool is_included = true;
for(unsigned int j = 0 ; j < primitive_size ; ++ j) {
if(!vertices.count(elements->index(i + j))) {
is_included = false;
break;
}
}
if(is_included) {
for(unsigned int j = 0 ; j < primitive_size ; ++ j) {
indices.push_back(elements->index(i + j));
unsigned int GeometryIndexSplitter::findCandidate(IndexSet& triangles, const IndexCache& cache, const TriangleMeshGraph& graph) {
// look for unclustered neighboring triangles
for(IndexCache::const_reverse_iterator cached = cache.rbegin() ; cached != cache.rend() ; ++ cached) {
IndexVector candidates = graph.triangleNeighbors(*cached);
for(IndexVector::const_iterator candidate = candidates.begin() ; candidate != candidates.end() ; ++ candidate) {
if(triangles.count(*candidate)) {
triangles.erase(*candidate);
return *candidate;
}
}
}
//fallback on any unclustered triangle
return getNext(triangles, std::numeric_limits<unsigned int>::max());
}
@@ -276,10 +221,3 @@ void GeometryIndexSplitter::setBufferBoundingBox(T* buffer) const {
buffer->setUserValue("ufr", ufr);
}
}
void GeometryIndexSplitter::setValidIndices(std::set<unsigned int>& indices, const osg::DrawElements* primitive) const {
for(unsigned int j = 0 ; j < primitive->getNumIndices() ; ++ j) {
indices.insert(primitive->index(j));
}
}

View File

@@ -7,6 +7,7 @@
#include <sstream>
#include "GeometryUniqueVisitor"
#include "glesUtil"
#include <osg/Geode>
#include <osgDB/ReaderWriter>
@@ -34,8 +35,7 @@ public:
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
unsigned int count = 0;
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target, ++ count) {
osg::ref_ptr<osg::Geometry> geometry = new osg::Geometry(*target->getGeometry());
geometry->setPrimitiveSetList(morphGeometry.getPrimitiveSetList());
glesUtil::TargetGeometry geometry(*target, morphGeometry);
std::ostringstream oss;
if(geometry->getName().empty()) {
oss << "/tmp/noname_" << _processed.size();

View File

@@ -0,0 +1,31 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commercial and non commercial
* applications, as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef GEOMETRY_MAPPER
#define GEOMETRY_MAPPER
#include <vector>
#include <osg/ref_ptr>
#include <osg/Geometry>
typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryList;
class GeometryMapper {
public:
// map one geometry to a list of geometries
// to be used with RemapGeometryVisitor
virtual const GeometryList& process(osg::Geometry&) = 0;
};
#endif

View File

@@ -16,26 +16,32 @@
#include <osg/Node>
#include <algorithm> //std::max
#include "AnimationCleanerVisitor"
#include "RigAnimationVisitor"
//animation:
#include "AABBonBoneVisitor"
#include "AnimationCleanerVisitor"
#include "DisableAnimationVisitor"
#include "LimitMorphTargetCount"
#include "MostInfluencedGeometryByBone"
#include "RigAnimationVisitor"
#include "RigAttributesVisitor"
// geometry:
#include "BindPerVertexVisitor"
#include "DetachPrimitiveVisitor"
#include "DrawArrayVisitor"
#include "GeometrySplitterVisitor"
#include "IndexMeshVisitor"
#include "PreTransformVisitor"
#include "RemapGeometryVisitor"
#include "SmoothNormalVisitor"
#include "TangentSpaceVisitor"
#include "TriangleStripVisitor"
#include "UnIndexMeshVisitor"
#include "WireframeVisitor"
#include "AABBonBoneVisitor"
#include "AnimationCleanerVisitor"
#include "MostInfluencedGeometryByBone"
#include "LimitMorphTargetCount"
#include "RigAttributesVisitor"
#include "GeometryIndexSplitter"
#include "GeometryCleaner"
// debug
#include "GeometryInspector"
@@ -165,6 +171,12 @@ protected:
node->accept(indexer);
}
void makeCleanGeometry(osg::Node* node) {
GeometryCleaner cleaner;
RemapGeometryVisitor remapper(cleaner, _exportNonGeometryDrawables);
node->accept(remapper);
}
void makeSmoothNormal(osg::Node* node) {
SmoothNormalVisitor smoother(osg::PI / 4.f, true);
node->accept(smoother);
@@ -176,8 +188,9 @@ protected:
}
void makeSplit(osg::Node* node) {
GeometrySplitterVisitor splitter(_maxIndexValue, _exportNonGeometryDrawables );
node->accept(splitter);
GeometryIndexSplitter splitter(_maxIndexValue);
RemapGeometryVisitor remapper(splitter, _exportNonGeometryDrawables);
node->accept(remapper);
}
void makeTriStrip(osg::Node* node) {

View File

@@ -26,6 +26,12 @@ osg::Node* OpenGLESGeometryOptimizer::optimize(osg::Node& node) {
// index (merge exact duplicates + uses simple triangles & lines i.e. no strip/fan/loop)
makeIndexMesh(model.get());
// clean (remove degenerated data)
std::string authoringTool;
if(model->getUserValue("authoring_tool", authoringTool) && authoringTool == "Tilt Brush") {
makeCleanGeometry(model.get());
}
// smooth vertex normals (if geometry has no normal compute smooth normals)
makeSmoothNormal(model.get());

View File

@@ -0,0 +1,51 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commercial and non commercial
* applications, as long as this copyright notice is maintained.
*
* This application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef REMAP_GEOMETRY_VISITOR
#define REMAP_GEOMETRY_VISITOR
#include <map>
#include <osg/ref_ptr>
#include <osg/Geometry>
#include <osgAnimation/RigGeometry>
#include "GeometryUniqueVisitor"
#include "GeometryMapper"
class RemapGeometryVisitor : public GeometryUniqueVisitor {
public:
typedef std::vector< osg::ref_ptr<osg::Geometry> > GeometryList;
typedef std::vector< osg::ref_ptr<osg::Drawable> > DrawableList;
typedef std::map<osg::Geometry*, GeometryList> GeometryMap;
RemapGeometryVisitor(GeometryMapper& mapper, bool exportNonGeometryDrawables=false):
GeometryUniqueVisitor("RemapGeometryVisitor"),
_mapper(mapper),
_exportNonGeometryDrawables(exportNonGeometryDrawables)
{}
void apply(osg::Geode&);
void process(osg::Geometry&);
protected:
bool isProcessed(osg::Geometry*);
void setProcessed(osg::Geometry*, const GeometryList&);
protected:
GeometryMapper& _mapper;
std::map<osg::Geometry*, GeometryList> _remap;
bool _exportNonGeometryDrawables;
};
#endif

View File

@@ -0,0 +1,72 @@
#include "RemapGeometryVisitor"
#include "glesUtil"
void RemapGeometryVisitor::apply(osg::Geode& geode) {
GeometryUniqueVisitor::apply(geode);
GeometryList remappedGeometries;
DrawableList nonGeometryDrawables;
for(unsigned int i = 0 ; i < geode.getNumDrawables() ; ++ i) {
osg::Geometry* geometry = geode.getDrawable(i)->asGeometry();
if(geometry) {
if(osgAnimation::RigGeometry* rigGeometry = dynamic_cast<osgAnimation::RigGeometry*>(geometry)) {
GeometryMap::iterator lookup = _remap.find(rigGeometry->getSourceGeometry());
if(lookup != _remap.end() && !lookup->second.empty()) {
// convert now static rigGeometry into simple Geometry
for(GeometryList::iterator mapped = lookup->second.begin() ; mapped != lookup->second.end() ; ++ mapped) {
if(glesUtil::hasPositiveWeights(mapped->get())) {
osgAnimation::RigGeometry* mappedRig = new osgAnimation::RigGeometry(*rigGeometry);
mappedRig->setSourceGeometry(mapped->get());
remappedGeometries.push_back(mappedRig);
}
else {
remappedGeometries.push_back(mapped->get());
}
}
}
}
else {
GeometryMap::iterator lookup = _remap.find(geometry);
if(lookup != _remap.end() && !lookup->second.empty()) {
remappedGeometries.insert(remappedGeometries.end(), lookup->second.begin(), lookup->second.end());
}
}
}
else {
nonGeometryDrawables.push_back(geode.getDrawable(i));
}
}
// remove all drawables
geode.removeDrawables(0, geode.getNumDrawables());
// insert splitted geometries
for(unsigned int i = 0 ; i < remappedGeometries.size() ; ++ i) {
geode.addDrawable(remappedGeometries[i].get());
}
if(_exportNonGeometryDrawables) {
// insert other drawables (e.g. osgText)
for(unsigned int i = 0 ; i < nonGeometryDrawables.size() ; ++ i) {
geode.addDrawable(nonGeometryDrawables[i].get());
}
}
}
void RemapGeometryVisitor::process(osg::Geometry& geometry) {
const GeometryList& mapped = _mapper.process(geometry);
setProcessed(&geometry, mapped);
}
bool RemapGeometryVisitor::isProcessed(osg::Geometry* node) {
return _remap.find(node) != _remap.end();
}
void RemapGeometryVisitor::setProcessed(osg::Geometry* node, const GeometryList& list) {
_remap.insert(std::pair<osg::Geometry*, GeometryList>(node, GeometryList(list)));
}

View File

@@ -5,6 +5,7 @@
#include "GeometryUniqueVisitor"
#include "TriangleMeshSmoother"
#include "glesUtil"
class SmoothNormalVisitor : public GeometryUniqueVisitor {
@@ -25,20 +26,41 @@ public:
}
void process(osgAnimation::MorphGeometry& morphGeometry) {
TriangleMeshSmoother(morphGeometry, 0, true, TriangleMeshSmoother::smooth_all);
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
// check normal orientation using the same primitives as parent geometry
osg::Geometry::PrimitiveSetList& primitives = target->getGeometry()->getPrimitiveSetList();
target->getGeometry()->setPrimitiveSetList(morphGeometry.getPrimitiveSetList());
bool needSmoothing = needMorphGeometrySmoothing(morphGeometry);
TriangleMeshSmoother(*target->getGeometry(), 0, true, TriangleMeshSmoother::smooth_all);
if(needSmoothing) {
TriangleMeshSmoother(morphGeometry, 0, true, TriangleMeshSmoother::smooth_all);
target->getGeometry()->setPrimitiveSetList(primitives);
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
// check normal orientation using the same primitives as parent geometry
glesUtil::TargetGeometry geometry(*target, morphGeometry);
if(geometry && !geometry->getNormalArray()) {
TriangleMeshSmoother(*geometry, 0, true, TriangleMeshSmoother::smooth_all);
}
}
}
}
protected:
bool needMorphGeometrySmoothing(osgAnimation::MorphGeometry& morphGeometry) {
if(!morphGeometry.getNormalArray()) {
return true;
}
osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
osg::Geometry* geometry = target->getGeometry();
if(geometry && !geometry->getNormalArray()) {
return true;
}
}
return false;
}
float _creaseAngle;
bool _comparePosition;
};

View File

@@ -1,26 +1,13 @@
#include "TangentSpaceVisitor"
#include "glesUtil"
void TangentSpaceVisitor::process(osgAnimation::MorphGeometry& morphGeometry) {
process(static_cast<osg::Geometry&>(morphGeometry));
osgAnimation::MorphGeometry::MorphTargetList& targets = morphGeometry.getMorphTargetList();
for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
osg::Geometry* geometry = target->getGeometry();
bool useParentMorphTexCoord = geometry->getTexCoordArrayList().empty();
if(useParentMorphTexCoord) {
// tangent space require tex coords; in case a target has no tex coords, we try to
// bind the parent geometry tex coords
geometry->setTexCoordArrayList(morphGeometry.getTexCoordArrayList());
}
glesUtil::TargetGeometry geometry(*target, morphGeometry);
process(*geometry);
if(useParentMorphTexCoord) {
// drop parent tex coords after tangent space computation
geometry->setTexCoordArrayList(osg::Geometry::ArrayList());
}
}
}
@@ -36,6 +23,9 @@ void TangentSpaceVisitor::process(osg::Geometry& geometry) {
geometry.getVertexAttribArray(tangentIndex)->setUserValue("tangent", true);
return;
}
else {
OSG_WARN << "Anomaly: [TangentSpaceVisitor] Missing tangent array at specificied index." << std::endl;
}
}
if (!geometry.getTexCoordArray(_textureUnit)){
@@ -56,21 +46,6 @@ void TangentSpaceVisitor::process(osg::Geometry& geometry) {
osg::ref_ptr<osgUtil::TangentSpaceGenerator> generator = new osgUtil::TangentSpaceGenerator;
generator->generate(&geometry, _textureUnit);
// keep original normal array
if (!geometry.getNormalArray()) {
if (generator->getNormalArray()) {
osg::Vec3Array* vec3Normals = new osg::Vec3Array();
osg::Vec4Array* vec4Normals = generator->getNormalArray();
for (unsigned int i = 0; i < vec4Normals->size(); i++) {
osg::Vec3 n = osg::Vec3((*vec4Normals)[i][0],
(*vec4Normals)[i][1],
(*vec4Normals)[i][2]);
vec3Normals->push_back(n);
}
geometry.setNormalArray(vec3Normals, osg::Array::BIND_PER_VERTEX);
}
}
if (generator->getTangentArray()) {
osg::Vec4Array* normal = generator->getNormalArray();
osg::Vec4Array* tangent = generator->getTangentArray();

View File

@@ -244,14 +244,16 @@ void TriangleMeshSmoother::updateGeometryPrimitives() {
}
}
osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
for(unsigned int i = 0 ; i < _graph->getNumTriangles() ; ++ i) {
const Triangle& triangle = _graph->triangle(i);
triangles->push_back(triangle.v1());
triangles->push_back(triangle.v2());
triangles->push_back(triangle.v3());
if(_graph->getNumTriangles()) {
osg::DrawElementsUInt* triangles = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES);
for(unsigned int i = 0 ; i < _graph->getNumTriangles() ; ++ i) {
const Triangle& triangle = _graph->triangle(i);
triangles->push_back(triangle.v1());
triangles->push_back(triangle.v2());
triangles->push_back(triangle.v3());
}
primitives.push_back(triangles);
}
primitives.push_back(triangles);
_geometry.setPrimitiveSetList(primitives);
}

View File

@@ -25,7 +25,7 @@ namespace glesUtil {
using namespace std;
using namespace osg;
typedef std::vector<unsigned int> IndexList;
typedef osgAnimation::MorphGeometry::MorphTargetList MorphTargetList;
inline bool hasPositiveWeights(const osg::Geometry* geometry) {
const osg::Vec4Array* weights = 0;
@@ -53,6 +53,52 @@ namespace glesUtil {
}
class TargetGeometry {
public:
TargetGeometry(osgAnimation::MorphGeometry::MorphTarget& target,
osgAnimation::MorphGeometry& morph):
_geometry(0)
{
_geometry = target.getGeometry();
_geometry->setPrimitiveSetList(morph.getPrimitiveSetList());
_hasTexCoord = _geometry->getTexCoordArrayList().size();
if(!_hasTexCoord) {
_geometry->setTexCoordArrayList(morph.getTexCoordArrayList());
}
}
osg::Geometry* operator->() {
return _geometry;
}
operator osg::Geometry*() {
return _geometry;
}
operator osg::Geometry&() {
return *_geometry;
}
operator bool() {
return _geometry != 0;
}
~TargetGeometry() {
if(!_hasTexCoord) {
// drop parent tex coords after tangent space computation
_geometry->setTexCoordArrayList(osg::Geometry::ArrayList());
}
_geometry->setPrimitiveSetList(osg::Geometry::PrimitiveSetList());
}
protected:
osg::Geometry* _geometry;
bool _hasTexCoord;
};
// A helper class that gathers up all the attribute arrays of an
// osg::Geometry object that are BIND_PER_VERTEX and runs an
// ArrayVisitor on them.
@@ -61,6 +107,20 @@ namespace glesUtil {
typedef std::vector<osg::Array*> ArrayList;
GeometryArrayGatherer(osg::Geometry& geometry) {
addGeometryVertexAttributes(geometry);
_targetAttributesIndex = _arrayList.size();
if(osgAnimation::MorphGeometry* morphGeometry = dynamic_cast<osgAnimation::MorphGeometry*>(&geometry)) {
MorphTargetList targets = morphGeometry->getMorphTargetList();
for (MorphTargetList::iterator iterator = targets.begin(); iterator != targets.end(); ++ iterator) {
if(iterator->getGeometry()) {
addTargetVertexAttributes(*iterator->getGeometry());
}
}
}
}
void addGeometryVertexAttributes(osg::Geometry& geometry) {
add(geometry.getVertexArray());
add(geometry.getNormalArray());
add(geometry.getColorArray());
@@ -74,6 +134,10 @@ namespace glesUtil {
}
}
void addTargetVertexAttributes(osg::Geometry& target) {
add(target.getVertexArray());
}
void add(osg::Array* array) {
if (array) {
_arrayList.push_back(array);
@@ -81,12 +145,16 @@ namespace glesUtil {
}
void accept(osg::ArrayVisitor& av) {
for(ArrayList::iterator itr = _arrayList.begin() ; itr != _arrayList.end(); ++ itr) {
unsigned int geometryAttributesIndex = 0;
for(ArrayList::iterator itr = _arrayList.begin() ;
geometryAttributesIndex < _targetAttributesIndex && itr != _arrayList.end();
++ geometryAttributesIndex, ++ itr) {
(*itr)->accept(av);
}
}
ArrayList _arrayList;
unsigned int _targetAttributesIndex;
};
@@ -349,8 +417,8 @@ namespace glesUtil {
void remapTargetVertices(Remapper remapper, Geometry& geom)
{
if(osgAnimation::MorphGeometry *morphGeometry = dynamic_cast<osgAnimation::MorphGeometry*>(&geom)) {
osgAnimation::MorphGeometry::MorphTargetList targetList = morphGeometry->getMorphTargetList();
for (osgAnimation::MorphGeometry::MorphTargetList::iterator ti = targetList.begin(); ti != targetList.end(); ++ti) {
MorphTargetList targetList = morphGeometry->getMorphTargetList();
for (MorphTargetList::iterator ti = targetList.begin(); ti != targetList.end(); ++ti) {
osgAnimation::MorphGeometry::MorphTarget *morphTarget = &(*ti);
osg::Geometry *target = morphTarget->getGeometry();
GeometryArrayGatherer gatherer(*target);

View File

@@ -45,7 +45,7 @@ bool addJSONChannel(const std::string& channelType, T* channel, bool packByCoord
osg::ref_ptr<JSONObject> json = new JSONObject;
std::string jsonType = channelType + (packByCoords ? "Packed" : "");
translateObject(json.get(), channel);
writer->translateObject(json.get(), channel);
json->getMaps()["Name"] = new JSONValue<std::string>(channel->getName());
json->getMaps()["TargetName"] = new JSONValue<std::string>(channel->getTargetName());

View File

@@ -125,7 +125,7 @@ public:
writer.setBaseName(basename);
writer.useExternalBinaryArray(options.useExternalBinaryArray);
writer.mergeAllBinaryFiles(options.mergeAllBinaryFiles);
writer.inlineImages(options.inlineImages);
writer.setInlineImages(options.inlineImages);
writer.setMaxTextureDimension(options.resizeTextureUpToPowerOf2);
writer.setVarint(options.varint);
writer.setBaseLodURL(options.baseLodURL);

View File

@@ -29,8 +29,10 @@
#include <osgAnimation/Bone>
#include <osgAnimation/UpdateBone>
#include <osgSim/ShapeAttribute>
#include <osgText/Text>
#
#include <fstream>
#include <sstream>
#include <vector>
@@ -47,8 +49,9 @@
#define WRITER_VERSION 9
class WriteVisitor;
osg::Array* getTangentSpaceArray(osg::Geometry& geometry);
void translateObject(JSONObject* json, osg::Object* osg);
void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value);
template<typename T>
bool getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value);
@@ -59,8 +62,9 @@ class WriteVisitor : public osg::NodeVisitor
public:
typedef std::vector<osg::ref_ptr<osg::StateSet> > StateSetStack;
typedef std::pair<std::string, std::string> KeyValue;
typedef std::map<osg::ref_ptr<osg::Object>, osg::ref_ptr<JSONObject> > OsgObjectToJSONObject;
std::map<osg::ref_ptr<osg::Object>, osg::ref_ptr<JSONObject> > _maps;
OsgObjectToJSONObject _maps;
std::vector<osg::ref_ptr<JSONObject> > _parents;
osg::ref_ptr<JSONObject> _root;
StateSetStack _stateset;
@@ -74,6 +78,20 @@ public:
std::map<KeyValue, std::string> _specificBuffers;
std::map<std::string, std::ofstream*> _buffers;
JSONObject* getJSON(osg::Object* object) const {
OsgObjectToJSONObject::const_iterator lookup = _maps.find(object);
if(lookup != _maps.end()) {
return lookup->second->getShadowObject();
}
return 0;
}
void setJSON(osg::Object* object, JSONObject* json) {
if(json) {
_maps[object] = json;
}
}
std::ofstream& getBufferFile(const std::string& name) {
if(_buffers.find(name) == _buffers.end()) {
_buffers[name] = new std::ofstream(name.c_str(), std::ios::binary);
@@ -238,6 +256,10 @@ public:
return getBinaryFilename(flag);
}
void translateObject(JSONObject* json, osg::Object* osg);
JSONObject* createJSONOsgSimUserData(osgSim::ShapeAttributeList*);
JSONObject* createJSONUserDataContainer(osg::UserDataContainer*);
JSONObject* createJSONPagedLOD(osg::PagedLOD* plod);
JSONObject* createJSONStateSet(osg::StateSet* ss);
JSONObject* createJSONTexture(osg::Texture* sa);
@@ -650,10 +672,14 @@ public:
_parents.pop_back();
}
std::string getBaseName() const { return _baseName; }
bool getInlineImages() const { return _inlineImages; }
int getMaxTextureDimension() const { return _maxTextureDimension; }
void setBaseName(const std::string& basename) { _baseName = basename; }
void useExternalBinaryArray(bool use) { _useExternalBinaryArray = use; }
void mergeAllBinaryFiles(bool use) { _mergeAllBinaryFiles = use; }
void inlineImages(bool use) { _inlineImages = use; }
void setInlineImages(bool use) { _inlineImages = use; }
void setVarint(bool use) { _varint = use; }
void setMaxTextureDimension(int use) { _maxTextureDimension = use; }
void addSpecificBuffer(const std::string& bufferFlag) {

View File

@@ -11,8 +11,6 @@
#include <osg/Material>
#include <osg/BlendFunc>
#include <osgSim/ShapeAttribute>
#include <osgText/Text>
#include <osgAnimation/MorphGeometry>
@@ -76,82 +74,6 @@ osg::ref_ptr<JSONObject> buildRigBoneMap(osgAnimation::RigGeometry& rigGeometry)
}
void translateObject(JSONObject* json, osg::Object* osg)
{
if (!osg->getName().empty()) {
json->getMaps()["Name"] = new JSONValue<std::string>(osg->getName());
}
osgSim::ShapeAttributeList* osgSim_userdata = dynamic_cast<osgSim::ShapeAttributeList* >(osg->getUserData());
if (osgSim_userdata) {
JSONObject* jsonUDC = new JSONObject();
jsonUDC->addUniqueID();
JSONArray* jsonUDCArray = new JSONArray();
jsonUDC->getMaps()["Values"] = jsonUDCArray;
for (unsigned int i = 0; i < osgSim_userdata->size(); i++) {
const osgSim::ShapeAttribute& attr = (*osgSim_userdata)[i];
JSONObject* jsonEntry = new JSONObject();
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(attr.getName());
osg::ref_ptr<JSONValue<std::string> > value;
switch(attr.getType()) {
case osgSim::ShapeAttribute::INTEGER:
{
std::stringstream ss;
ss << attr.getInt();
value = new JSONValue<std::string>(ss.str());
}
break;
case osgSim::ShapeAttribute::DOUBLE:
{
std::stringstream ss;
ss << attr.getDouble();
value = new JSONValue<std::string>(ss.str());
}
break;
case osgSim::ShapeAttribute::STRING:
{
std::stringstream ss;
ss << attr.getString();
value = new JSONValue<std::string>(ss.str());
}
break;
case osgSim::ShapeAttribute::UNKNOWN:
default:
break;
}
jsonEntry->getMaps()["Value"] = value;
jsonUDCArray->getArray().push_back(jsonEntry);
}
json->getMaps()["UserDataContainer"] = jsonUDC;
} else if (osg->getUserDataContainer()) {
JSONObject* jsonUDC = new JSONObject();
jsonUDC->addUniqueID();
if (!osg->getUserDataContainer()->getName().empty()) {
jsonUDC->getMaps()["Name"] = new JSONValue<std::string>(osg->getUserDataContainer()->getName());
}
JSONArray* jsonUDCArray = new JSONArray();
jsonUDC->getMaps()["Values"] = jsonUDCArray;
for (unsigned int i = 0; i < osg->getUserDataContainer()->getNumUserObjects(); i++) {
osg::Object* o = osg->getUserDataContainer()->getUserObject(i);
std::string name, value;
getStringifiedUserValue(o, name, value);
if(!name.empty() && !value.empty())
{
JSONObject* jsonEntry = new JSONObject();
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(name);
jsonEntry->getMaps()["Value"] = new JSONValue<std::string>(value);
jsonUDCArray->getArray().push_back(jsonEntry);
}
}
json->getMaps()["UserDataContainer"] = jsonUDC;
}
}
void getStringifiedUserValue(osg::Object* o, std::string& name, std::string& value) {
if(getStringifiedUserValue<std::string>(o, name, value)) return;
if(getStringifiedUserValue<char>(o, name, value)) return;
@@ -352,6 +274,108 @@ JSONObject* createImage(osg::Image* image, bool inlineImages, int maxTextureDime
}
JSONObject* WriteVisitor::createJSONOsgSimUserData(osgSim::ShapeAttributeList* osgSimData) {
JSONObject* jsonUDC = new JSONObject();
jsonUDC->addUniqueID();
JSONArray* jsonUDCArray = new JSONArray();
jsonUDC->getMaps()["Values"] = jsonUDCArray;
for (unsigned int i = 0; i < osgSimData->size(); i++) {
const osgSim::ShapeAttribute& attr = (*osgSimData)[i];
JSONObject* jsonEntry = new JSONObject();
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(attr.getName());
osg::ref_ptr<JSONValue<std::string> > value;
switch(attr.getType()) {
case osgSim::ShapeAttribute::INTEGER:
{
std::stringstream ss;
ss << attr.getInt();
value = new JSONValue<std::string>(ss.str());
}
break;
case osgSim::ShapeAttribute::DOUBLE:
{
std::stringstream ss;
ss << attr.getDouble();
value = new JSONValue<std::string>(ss.str());
}
break;
case osgSim::ShapeAttribute::STRING:
{
std::stringstream ss;
ss << attr.getString();
value = new JSONValue<std::string>(ss.str());
}
break;
case osgSim::ShapeAttribute::UNKNOWN:
default:
break;
}
jsonEntry->getMaps()["Value"] = value;
jsonUDCArray->getArray().push_back(jsonEntry);
}
return jsonUDC;
}
JSONObject* WriteVisitor::createJSONUserDataContainer(osg::UserDataContainer* container) {
JSONObject* jsonUDC = new JSONObject();
jsonUDC->addUniqueID();
if (!container->getName().empty()) {
jsonUDC->getMaps()["Name"] = new JSONValue<std::string>(container->getName());
}
JSONArray* jsonUDCArray = new JSONArray();
jsonUDC->getMaps()["Values"] = jsonUDCArray;
for (unsigned int i = 0; i < container->getNumUserObjects(); i++) {
osg::Object* o = container->getUserObject(i);
std::string name, value;
getStringifiedUserValue(o, name, value);
if(!name.empty() && !value.empty())
{
JSONObject* jsonEntry = new JSONObject();
jsonEntry->getMaps()["Name"] = new JSONValue<std::string>(name);
jsonEntry->getMaps()["Value"] = new JSONValue<std::string>(value);
jsonUDCArray->getArray().push_back(jsonEntry);
}
}
return jsonUDC;
}
void WriteVisitor::translateObject(JSONObject* json, osg::Object* osg)
{
if (!osg->getName().empty()) {
json->getMaps()["Name"] = new JSONValue<std::string>(osg->getName());
}
JSONObject* jsonUDC = 0;
osgSim::ShapeAttributeList* osgSimData = dynamic_cast<osgSim::ShapeAttributeList* >(osg->getUserData());
if (osgSimData) {
jsonUDC = this->getJSON(osgSimData);
if(!jsonUDC) {
jsonUDC = createJSONOsgSimUserData(osgSimData);
this->setJSON(osgSimData, jsonUDC);
}
}
else if (osg::UserDataContainer* container = osg->getUserDataContainer()) {
jsonUDC = this->getJSON(container);
if(!jsonUDC) {
jsonUDC = createJSONUserDataContainer(container);
this->setJSON(container, jsonUDC);
}
}
if(jsonUDC) {
json->getMaps()["UserDataContainer"] = jsonUDC;
}
}
JSONObject* WriteVisitor::createJSONBufferArray(osg::Array* array, osg::Object* parent)
{
if (_maps.find(array) != _maps.end())
@@ -765,12 +789,16 @@ JSONObject* WriteVisitor::createJSONLight(osg::Light* light)
return jsonLight.release();
}
template <class T> JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, bool inlineImages,
int maxTextureDimension, const std::string &baseName = "")
template <class T>
JSONObject* createImageFromTexture(osg::Texture* texture, JSONObject* jsonTexture, WriteVisitor* writer)
{
bool inlineImages = writer->getInlineImages();
int maxTextureDimension = writer->getMaxTextureDimension();
const std::string baseName = writer->getBaseName();
T* text = dynamic_cast<T*>( texture);
if (text) {
translateObject(jsonTexture,text);
writer->translateObject(jsonTexture,text);
JSONObject* image = createImage(text->getImage(), inlineImages, maxTextureDimension, baseName);
if (image)
jsonTexture->getMaps()["File"] = image;
@@ -902,24 +930,21 @@ JSONObject* WriteVisitor::createJSONTexture(osg::Texture* texture)
{
JSONObject* obj = createImageFromTexture<osg::Texture1D>(texture, jsonTexture.get(), this->_inlineImages,
this->_maxTextureDimension, this->_baseName);
JSONObject* obj = createImageFromTexture<osg::Texture1D>(texture, jsonTexture.get(), this);
if (obj) {
return obj;
}
}
{
JSONObject* obj = createImageFromTexture<osg::Texture2D>(texture, jsonTexture.get(), this->_inlineImages,
this->_maxTextureDimension, this->_baseName);
JSONObject* obj = createImageFromTexture<osg::Texture2D>(texture, jsonTexture.get(), this);
if (obj) {
return obj;
}
}
{
JSONObject* obj = createImageFromTexture<osg::TextureRectangle>(texture, jsonTexture.get(), this->_inlineImages,
this->_maxTextureDimension, this->_baseName);
JSONObject* obj = createImageFromTexture<osg::TextureRectangle>(texture, jsonTexture.get(), this);
if (obj) {
return obj;
}

View File

@@ -210,10 +210,10 @@ class ReaderWriterPNG : public osgDB::ReaderWriter
pinfo->Depth = depth;
}
OSG_INFO<<"width="<<width<<" height="<<height<<" depth="<<depth<<std::endl;
if ( color == PNG_COLOR_TYPE_RGB) { OSG_INFO << "color == PNG_COLOR_TYPE_RGB "<<std::endl; }
if ( color == PNG_COLOR_TYPE_GRAY) { OSG_INFO << "color == PNG_COLOR_TYPE_GRAY "<<std::endl; }
if ( color == PNG_COLOR_TYPE_GRAY_ALPHA) { OSG_INFO << "color == PNG_COLOR_TYPE_GRAY_ALPHA"<<std::endl; }
OSG_DEBUG<<"width="<<width<<" height="<<height<<" depth="<<depth<<std::endl;
if ( color == PNG_COLOR_TYPE_RGB) { OSG_DEBUG << "color == PNG_COLOR_TYPE_RGB "<<std::endl; }
if ( color == PNG_COLOR_TYPE_GRAY) { OSG_DEBUG << "color == PNG_COLOR_TYPE_GRAY "<<std::endl; }
if ( color == PNG_COLOR_TYPE_GRAY_ALPHA) { OSG_DEBUG << "color == PNG_COLOR_TYPE_GRAY_ALPHA"<<std::endl; }
// png default to big endian, so we'll need to swap bytes if on a little endian machine.
if (depth>8 && getCpuByteOrder()==osg::LittleEndian)

View File

@@ -22,7 +22,7 @@ class ReaderWriterSDL : public osgDB::ReaderWriter
virtual const char* className() const { return "SDL Device Integration plugin"; }
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* options =NULL) const
virtual ReadResult readObject(const std::string& file, const osgDB::ReaderWriter::Options* =NULL) const
{
if (file=="joystick.sdl")
{

View File

@@ -77,22 +77,13 @@ public:
if (transform.getStateSet()) popState();
}
void apply(osg::Geode& geode)
void apply(osg::Drawable& drawable)
{
if (geode.getStateSet()) pushState(geode.getStateSet());
if (drawable.getStateSet()) pushState(drawable.getStateSet());
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
osg::Drawable* drawable = geode.getDrawable(i);
apply(&drawable);
if (drawable->getStateSet()) pushState(drawable->getStateSet());
apply(geode.getDrawable(i));
if (drawable->getStateSet()) popState();
}
if (geode.getStateSet()) popState();
if (drawable.getStateSet()) popState();
}
void pushState(osg::StateSet* stateset)

View File

@@ -274,20 +274,14 @@ public:
popCurrentMask();
}
void apply(osg::Geode& node)
void apply(osg::Drawable& drawable)
{
if (isCulled(node)) return;
if (isCulled(drawable)) return;
// push the culling mode.
pushCurrentMask();
for(unsigned int i=0; i<node.getNumDrawables();++i)
{
if (node.getDrawable(i))
{
updateBound(node.getDrawable(i)->getBoundingBox());
}
}
updateBound(drawable.getBoundingBox());
// pop the culling mode.
popCurrentMask();

View File

@@ -71,15 +71,3 @@ void DisplayRequirementsVisitor::apply(Node& node)
traverse(node);
}
void DisplayRequirementsVisitor::apply(Geode& geode)
{
osg::StateSet* geode_stateset = geode.getStateSet();
if (geode_stateset) applyStateSet(*geode_stateset);
for(unsigned int i = 0; i < geode.getNumDrawables(); i++ )
{
osg::StateSet* stateset = geode.getDrawable(i)->getStateSet();
if (stateset) applyStateSet(*stateset);
}
}

View File

@@ -66,18 +66,10 @@ void DrawElementTypeSimplifier::simplify(osg::Geometry & geometry) const
}
}
void DrawElementTypeSimplifierVisitor::apply(osg::Geode& node)
void DrawElementTypeSimplifierVisitor::apply(osg::Geometry& geom)
{
DrawElementTypeSimplifier dets;
unsigned int numDrawables = node.getNumDrawables();
for (unsigned int i = 0; i != numDrawables; ++i)
{
osg::Geometry * geom = dynamic_cast<osg::Geometry*>(node.getDrawable(i));
if (geom) dets.simplify(*geom);
}
osg::NodeVisitor::apply((osg::Node&)node);
dets.simplify(geom);
}
}

View File

@@ -53,28 +53,6 @@ void GLObjectsVisitor::apply(osg::Node& node)
}
}
void GLObjectsVisitor::apply(osg::Geode& node)
{
bool programSetBefore = _lastCompiledProgram.valid();
if (node.getStateSet())
{
apply(*(node.getStateSet()));
}
traverse(node);
bool programSetAfter = _lastCompiledProgram.valid();
if (!programSetBefore && programSetAfter)
{
osg::State* state = _renderInfo.getState();
osg::GLExtensions* extensions = state->get<osg::GLExtensions>();
extensions->glUseProgram(0);
state->setLastAppliedProgramObject(0);
_lastCompiledProgram = 0;
}
}
void GLObjectsVisitor::apply(osg::Drawable& drawable)
{
if (_drawablesAppliedSet.count(&drawable)!=0) return;

View File

@@ -38,13 +38,9 @@ void GeometryCollector::reset()
_geometryList.clear();
}
void GeometryCollector::apply(Geode& geode)
void GeometryCollector::apply(Geometry& geom)
{
for(unsigned int i = 0; i < geode.getNumDrawables(); ++i )
{
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom) _geometryList.insert(geom);
}
_geometryList.insert(&geom);
}
namespace
@@ -890,14 +886,9 @@ void VertexCacheMissVisitor::reset()
triangles = 0;
}
void VertexCacheMissVisitor::apply(Geode& geode)
void VertexCacheMissVisitor::apply(Geometry& geom)
{
for(unsigned int i = 0; i < geode.getNumDrawables(); ++i )
{
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom)
doGeometry(*geom);
}
doGeometry(geom);
}
namespace

View File

@@ -50,8 +50,6 @@
using namespace osgUtil;
// #define GEOMETRYDEPRECATED
void Optimizer::reset()
{
}
@@ -290,14 +288,6 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
OSG_INFO<<"MERGE_GEODES took "<<osg::Timer::instance()->delta_s(startTick,endTick)<<std::endl;
}
if (options & CHECK_GEOMETRY)
{
OSG_INFO<<"Optimizer::optimize() doing CHECK_GEOMETRY"<<std::endl;
CheckGeometryVisitor mgv(this);
node->accept(mgv);
}
if (options & MAKE_FAST_GEOMETRY)
{
OSG_INFO<<"Optimizer::optimize() doing MAKE_FAST_GEOMETRY"<<std::endl;
@@ -405,17 +395,10 @@ void Optimizer::optimize(osg::Node* node, unsigned int options)
////////////////////////////////////////////////////////////////////////////
// Tessellate geometry - eg break complex POLYGONS into triangles, strips, fans..
////////////////////////////////////////////////////////////////////////////
void Optimizer::TessellateVisitor::apply(osg::Geode& geode)
void Optimizer::TessellateVisitor::apply(osg::Geometry &geom)
{
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom) {
osgUtil::Tessellator Tessellator;
Tessellator.retessellatePolygons(*geom);
}
}
traverse(geode);
osgUtil::Tessellator Tessellator;
Tessellator.retessellatePolygons(geom);
}
@@ -468,38 +451,6 @@ void Optimizer::StateVisitor::apply(osg::Node& node)
traverse(node);
}
void Optimizer::StateVisitor::apply(osg::Geode& geode)
{
if (!isOperationPermissibleForObject(&geode)) return;
osg::StateSet* ss = geode.getStateSet();
if (ss && ss->getDataVariance()==osg::Object::STATIC)
{
if (isOperationPermissibleForObject(ss))
{
addStateSet(ss,&geode);
}
}
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
osg::Drawable* drawable = geode.getDrawable(i);
if (drawable)
{
ss = drawable->getStateSet();
if (ss && ss->getDataVariance()==osg::Object::STATIC)
{
if (isOperationPermissibleForObject(drawable) &&
isOperationPermissibleForObject(ss))
{
addStateSet(ss,drawable);
}
}
}
}
}
void Optimizer::StateVisitor::optimize()
{
OSG_INFO << "Num of StateSet="<<_statesets.size()<< std::endl;
@@ -1173,26 +1124,19 @@ void Optimizer::FlattenStaticTransformsVisitor::apply(osg::PagedLOD& node)
traverse(node);
}
void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Geode& geode)
void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Drawable& drawable)
{
if (!_transformStack.empty())
osg::Geometry *geometry = drawable.asGeometry();
if((geometry) && (isOperationPermissibleForObject(&drawable)))
{
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
osg::Geometry *geometry = geode.getDrawable(i)->asGeometry();
if((geometry) && (isOperationPermissibleForObject(&geode)) && (isOperationPermissibleForObject(geometry)))
{
if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) {
geometry->setVertexArray(dynamic_cast<osg::Array*>(geometry->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
}
if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) {
geometry->setNormalArray(dynamic_cast<osg::Array*>(geometry->getNormalArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
}
}
_drawableSet.insert(geode.getDrawable(i));
if(geometry->getVertexArray() && geometry->getVertexArray()->referenceCount() > 1) {
geometry->setVertexArray(dynamic_cast<osg::Array*>(geometry->getVertexArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
}
if(geometry->getNormalArray() && geometry->getNormalArray()->referenceCount() > 1) {
geometry->setNormalArray(dynamic_cast<osg::Array*>(geometry->getNormalArray()->clone(osg::CopyOp::DEEP_COPY_ALL)));
}
}
_drawableSet.insert(&drawable);
}
void Optimizer::FlattenStaticTransformsVisitor::apply(osg::Billboard& billboard)
@@ -1329,23 +1273,6 @@ bool Optimizer::CombineStaticTransformsVisitor::removeTransforms(osg::Node* node
// RemoveEmptyNodes.
////////////////////////////////////////////////////////////////////////////
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Geode& geode)
{
for(int i=geode.getNumDrawables()-1;i>=0;--i)
{
osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
if (geom && geom->empty() && isOperationPermissibleForObject(geom))
{
geode.removeDrawables(i,1);
}
}
if (geode.getNumParents()>0)
{
if (geode.getNumDrawables()==0 && isOperationPermissibleForObject(&geode)) _redundantNodeList.insert(&geode);
}
}
void Optimizer::RemoveEmptyNodesVisitor::apply(osg::Group& group)
{
if (group.getNumParents()>0)
@@ -1389,7 +1316,7 @@ void Optimizer::RemoveEmptyNodesVisitor::removeEmptyNodes()
strcmp(parent->className(),"MultiSwitch")!=0)
{
parent->removeChild(nodeToRemove.get());
if (parent->getNumChildren()==0) newEmptyGroups.insert(*pitr);
if (parent->getNumChildren()==0 && isOperationPermissibleForObject(parent)) newEmptyGroups.insert(parent);
}
}
}
@@ -1795,39 +1722,13 @@ struct LessGeometryPrimitiveType
}
};
void Optimizer::CheckGeometryVisitor::checkGeode(osg::Geode& geode)
void Optimizer::MakeFastGeometryVisitor::apply(osg::Geometry& geom)
{
if (isOperationPermissibleForObject(&geode))
if (isOperationPermissibleForObject(&geom))
{
for(unsigned int i=0;i<geode.getNumDrawables();++i)
if (geom.checkForDeprecatedData())
{
osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
if (geom && isOperationPermissibleForObject(geom))
{
#ifdef GEOMETRYDEPRECATED
geom1829
->computeCorrectBindingsAndArraySizes();
#endif
}
}
}
}
void Optimizer::MakeFastGeometryVisitor::checkGeode(osg::Geode& geode)
{
// GeometryDeprecated CAN REMOVED
if (isOperationPermissibleForObject(&geode))
{
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
osg::Geometry* geom = geode.getDrawable(i)->asGeometry();
if (geom && isOperationPermissibleForObject(geom))
{
if (geom->checkForDeprecatedData())
{
geom->fixDeprecatedData();
}
}
geom.fixDeprecatedData();
}
}
}
@@ -2985,33 +2886,6 @@ void Optimizer::TextureVisitor::apply(osg::Node& node)
traverse(node);
}
void Optimizer::TextureVisitor::apply(osg::Geode& geode)
{
if (!isOperationPermissibleForObject(&geode)) return;
osg::StateSet* ss = geode.getStateSet();
if (ss && isOperationPermissibleForObject(ss))
{
apply(*ss);
}
for(unsigned int i=0;i<geode.getNumDrawables();++i)
{
osg::Drawable* drawable = geode.getDrawable(i);
if (drawable)
{
ss = drawable->getStateSet();
if (ss &&
isOperationPermissibleForObject(drawable) &&
isOperationPermissibleForObject(ss))
{
apply(*ss);
}
}
}
}
void Optimizer::TextureVisitor::apply(osg::StateSet& stateset)
{
for(unsigned int i=0;i<stateset.getTextureAttributeList().size();++i)
@@ -4137,56 +4011,31 @@ void Optimizer::TextureAtlasVisitor::apply(osg::Node& node)
if (pushedStateState) popStateSet();
}
void Optimizer::TextureAtlasVisitor::apply(osg::Geode& geode)
void Optimizer::TextureAtlasVisitor::apply(osg::Drawable& node)
{
if (!isOperationPermissibleForObject(&geode)) return;
osg::StateSet* ss = geode.getStateSet();
bool pushedGeodeStateState = false;
bool pushedStateState = false;
osg::StateSet* ss = node.getStateSet();
if (ss && ss->getDataVariance()==osg::Object::STATIC)
{
if (isOperationPermissibleForObject(ss))
if (isOperationPermissibleForObject(&node) &&
isOperationPermissibleForObject(ss))
{
pushedGeodeStateState = pushStateSet(ss);
pushedStateState = pushStateSet(ss);
}
}
for(unsigned int i=0;i<geode.getNumDrawables();++i)
if (!_statesetStack.empty())
{
osg::Drawable* drawable = geode.getDrawable(i);
if (drawable)
for(StateSetStack::iterator ssitr = _statesetStack.begin();
ssitr != _statesetStack.end();
++ssitr)
{
bool pushedDrawableStateState = false;
ss = drawable->getStateSet();
if (ss && ss->getDataVariance()==osg::Object::STATIC)
{
if (isOperationPermissibleForObject(drawable) &&
isOperationPermissibleForObject(ss))
{
pushedDrawableStateState = pushStateSet(ss);
}
}
if (!_statesetStack.empty())
{
for(StateSetStack::iterator ssitr = _statesetStack.begin();
ssitr != _statesetStack.end();
++ssitr)
{
_statesetMap[*ssitr].insert(drawable);
}
}
if (pushedDrawableStateState) popStateSet();
_statesetMap[*ssitr].insert(&node);
}
}
if (pushedGeodeStateState) popStateSet();
if (pushedStateState) popStateSet();
}
void Optimizer::TextureAtlasVisitor::optimize()
@@ -4474,14 +4323,11 @@ void Optimizer::StaticObjectDetectionVisitor::apply(osg::Node& node)
traverse(node);
}
void Optimizer::StaticObjectDetectionVisitor::apply(osg::Geode& geode)
void Optimizer::StaticObjectDetectionVisitor::apply(osg::Drawable& drawable)
{
if (geode.getStateSet()) applyStateSet(*geode.getStateSet());
if (drawable.getStateSet()) applyStateSet(*drawable.getStateSet());
for(unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
applyDrawable(*geode.getDrawable(i));
}
drawable.computeDataVariance();
}
void Optimizer::StaticObjectDetectionVisitor::applyStateSet(osg::StateSet& stateset)
@@ -4490,15 +4336,6 @@ void Optimizer::StaticObjectDetectionVisitor::applyStateSet(osg::StateSet& state
}
void Optimizer::StaticObjectDetectionVisitor::applyDrawable(osg::Drawable& drawable)
{
if (drawable.getStateSet()) applyStateSet(*drawable.getStateSet());
drawable.computeDataVariance();
}
////////////////////////////////////////////////////////////////////////////
// FlattenStaticTransformsDuplicatingSharedSubgraphsVisitor

View File

@@ -322,24 +322,13 @@ void ShaderGenVisitor::apply(osg::Node &node)
_state->popStateSet();
}
void ShaderGenVisitor::apply(osg::Geode &geode)
void ShaderGenVisitor::apply(osg::Drawable &drawable)
{
osg::StateSet *stateSet = geode.getStateSet();
osg::StateSet *stateSet = drawable.getStateSet();
if (stateSet)
_state->pushStateSet(stateSet);
for (unsigned int i=0; i<geode.getNumDrawables(); ++i)
{
osg::Drawable *drawable = geode.getDrawable(i);
osg::StateSet *ss = drawable->getStateSet();
if (ss)
_state->pushStateSet(ss);
update(drawable);
if (ss)
_state->popStateSet();
}
update(&drawable);
if (stateSet)
_state->popStateSet();

View File

@@ -702,11 +702,7 @@ void SmoothingVisitor::smooth(osg::Geometry& geom, double creaseAngle)
}
void SmoothingVisitor::apply(osg::Geode& geode)
void SmoothingVisitor::apply(osg::Geometry& geom)
{
for(unsigned int i = 0; i < geode.getNumDrawables(); i++ )
{
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom) smooth(*geom, _creaseAngle);
}
smooth(geom, _creaseAngle);
}

View File

@@ -629,11 +629,7 @@ void TriStripVisitor::stripify()
}
}
void TriStripVisitor::apply(Geode& geode)
void TriStripVisitor::apply(Geometry& geom)
{
for(unsigned int i = 0; i < geode.getNumDrawables(); ++i )
{
osg::Geometry* geom = dynamic_cast<osg::Geometry*>(geode.getDrawable(i));
if (geom) _geometryList.insert(geom);
}
_geometryList.insert(&geom);
}

View File

@@ -928,33 +928,6 @@ void MultipassTechnique::backfaceSubgraphCullTraversal(osgUtil::CullVisitor* cv)
cv->popStateSet();
}
class RTTBackfaceCameraCullCallback : public osg::NodeCallback
{
public:
RTTBackfaceCameraCullCallback(MultipassTechnique::MultipassTileData* tileData, MultipassTechnique* mt):
_tileData(tileData),
_mt(mt) {}
virtual void operator()(osg::Node* /*node*/, osg::NodeVisitor* nv)
{
osgUtil::CullVisitor* cv = nv->asCullVisitor();
cv->pushProjectionMatrix(_tileData->projectionMatrix.get());
_mt->backfaceSubgraphCullTraversal(cv);
cv->popProjectionMatrix();
}
protected:
virtual ~RTTBackfaceCameraCullCallback() {}
osg::observer_ptr<osgVolume::MultipassTechnique::MultipassTileData> _tileData;
osg::observer_ptr<osgVolume::MultipassTechnique> _mt;
};
class ShadingModelVisitor : public osgVolume::PropertyVisitor
{
public: