diff --git a/.travis.yml b/.travis.yml index 687c7c43d..27f0fc6f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ env: # via the "travis encrypt" command using the project repo's public key - secure: "0ROQiFbsZo33ce2v5VjBxNljemh/HU70ntSSPygYwaDFymubts/62SixXVkbKNIFdrs3uYD6qeA/eMmpqXxLcs+PXNq5NrH7eSWw9oDIKMhq3NQH/IZLdRfXwihHimZ1qEs/TXyWlT2aC4rpBi1py3cJeTh1aBMlz4V/nm16iRAgc596ThNTuPDHa0F9/gZnwccI/Rr9VpiYn7vEBbuY9lYr43D0G3NuuQyvvlHShroH09fh6KyFOWIY38AQtnuVGNC1fIiAUk7TUqDqSBwhIrUV5saHbP0kca6DP32REkv//h4JwM76UHv+ntVEoK/UiztJHMkrw71gXYTyvIvlDBpT+IDoeIwUW2QFNQ5zJZI7FM8k0+oeK+F7k/mkffDzr1zww/PQoxqFBF0PoxAni/L9qkA4X2o1A6mRDbe9besp2LQG6Vniwj3bHpCId2QiiMrANVg0EAqkcL2mVFEaqZsh90qCkr1UDq4WQoYbXh0Fy3UnQpbuxDvCME8u03lwuv6ds/SBxc5cgKv7oWXgezaDg7/OCR+0lIAGuLqmNRD8Xw7a0WZGmSbYCHIZmeyFja2KuUvMiVCt8+QsyZr3e523DwBwnSj1BIYFRstMaSEJgu9B8rfTRRllOOKJXCQtdFVuGu8VI6PniSAkI6c535yOWzsuS8HwIkN2ll+Wn7E=" +language: cpp +cache: ccache + matrix: fast_finish: true include: @@ -18,8 +21,7 @@ matrix: sudo: false cache: apt: true - directories: - - $HOME/.ccache + ccache: true compiler: #- clang - gcc @@ -43,11 +45,19 @@ matrix: # OSX build - os: osx - language: cpp + before_install: + - brew update + install: + - brew install ccache + - export PATH="/usr/local/opt/ccache/libexec:$PATH" env: - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" - os: osx - language: cpp + before_install: + - brew update + install: + - brew install ccache + - export PATH="/usr/local/opt/ccache/libexec:$PATH" env: - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF" diff --git a/AUTHORS.txt b/AUTHORS.txt index 720da1a06..58628fdd5 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -1,6 +1,6 @@ OpenSceneGraph Library 3.5.7 -566 Contributors: +568 Contributors: Firstname Surname ----------------- @@ -175,6 +175,7 @@ John Ivar Gustav Haapalahti Erik den Dekker Emmanuel Roche +Don Burns Domenico Mangieri Daniel Larimer Colin Dunlop @@ -226,7 +227,6 @@ Fabio Mierlo Doug McCorkle Donald Cipperly Don Leich -Don Burns Dietmar Funck Colin Cochran Christian Ruzicka @@ -362,6 +362,7 @@ Shuxing Xiao Shane Arnott Sergey Kurdakov Sebastien Kuntz +Sandro Mani Ruth Lang Ruben The Ruben Smelik @@ -538,6 +539,7 @@ Christian Noon Christian Kaser Christian Ehrlicher Chris McGlone +Chris Djali Carlos Garcea Bryce Eldridge Bruno Herbelin diff --git a/CMakeLists.txt b/CMakeLists.txt index 8f9645210..6625f0f86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,7 +115,7 @@ PROJECT(OpenSceneGraph) SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MINOR_VERSION 5) -SET(OPENSCENEGRAPH_PATCH_VERSION 7) +SET(OPENSCENEGRAPH_PATCH_VERSION 8) SET(OPENSCENEGRAPH_SOVERSION 150) # set to 0 when not a release candidate, non zero means that any generated diff --git a/CMakeModules/FindLIBLAS.cmake b/CMakeModules/FindLIBLAS.cmake index 5b2236cb4..1c9a7ee01 100644 --- a/CMakeModules/FindLIBLAS.cmake +++ b/CMakeModules/FindLIBLAS.cmake @@ -94,14 +94,12 @@ macro(FIND_LIBLAS_LIBRARY MYLIBRARY MYLIBRARYNAME) endmacro(FIND_LIBLAS_LIBRARY LIBRARY LIBRARYNAME) FIND_LIBLAS_LIBRARY(LIBLAS_LIBRARY las) -FIND_LIBLAS_LIBRARY(LIBLASC_LIBRARY las_c) set(LIBLAS_FOUND "NO") -if(LIBLAS_LIBRARY AND LIBLASC_LIBRARY AND LIBLAS_INCLUDE_DIR) - +if(LIBLAS_LIBRARY AND LIBLAS_INCLUDE_DIR) FIND_PACKAGE(Boost) # used by LIBLAS if(Boost_FOUND) - set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} ${LIBLASC_LIBRARY} ) + set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} ) set(LIBLAS_FOUND "YES") endif() endif() diff --git a/ChangeLog b/ChangeLog index 277fa4301..01ff512e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,274 @@ +Mon, 9 Oct 2017 12:25:40 +0100 +Author : Robert Osfield +Updated version number + +Mon, 9 Oct 2017 12:23:45 +0100 +Author : Robert Osfield +Updated AUTHORS + +Mon, 9 Oct 2017 10:03:21 +0100 +Author : OpenSceneGraph git repository +Merge pull request #359 from eligovision/OpenSceneGraph_glesAdded defines: GL_ALPHA4/8/12/16 in osg/Image, this will fix compilat… + +Mon, 9 Oct 2017 10:02:51 +0100 +Author : OpenSceneGraph git repository +Merge pull request #358 from eligovision/OpenSceneGraph_optimizerVertexAttribDivisor compare function fix: index must be compared + +Fri, 6 Oct 2017 18:03:36 +0100 +Author : Robert Osfield +Added explictly unbinding of VBO for setInterleavedArrays(). + +Fri, 6 Oct 2017 17:47:19 +0100 +Author : Robert Osfield +Added VertexArrayState::ArrayDispatch::className() method and implementation for each ArrayDispatch subclass to help with debugging + +Fri, 6 Oct 2017 17:37:50 +0300 +Author : Konstantin S. Matveyev +Added defines: GL_ALPHA4/8/12/16 in osg/Image, this will fix compilation error while building for GLES2 + +Fri, 6 Oct 2017 14:33:07 +0300 +Author : Konstantin S. Matveyev +VertexAttribDivisor compare function fix: index must be compared + +Thu, 5 Oct 2017 16:31:45 +0100 +Author : OpenSceneGraph git repository +Merge pull request #354 from eligovision/OpenSceneGraph_intersectionLineSegmentIntersector fixed: intersection ratio remaped to the range… + +Thu, 5 Oct 2017 16:30:21 +0100 +Author : OpenSceneGraph git repository +Merge pull request #353 from eligovision/OpenSceneGraph_iotellg call removed from StreamOperator's checkStream function, becaus… + +Thu, 5 Oct 2017 16:29:37 +0100 +Author : OpenSceneGraph git repository +Merge pull request #355 from denyskoch/patch-1Fix loading of 16bit PNG images + +Thu, 5 Oct 2017 15:59:26 +0100 +Author : Robert Osfield +Fixed spacing to make it consistent with the rest of the OSG and make it easier to read. + +Thu, 5 Oct 2017 15:57:02 +0100 +Author : OpenSceneGraph git repository +Merge pull request #351 from LaurensVoerman/vncHostPwVNC: try to find password for host if no password for host:port is found + +Thu, 5 Oct 2017 15:37:03 +0100 +Author : Robert Osfield +Added support for multiple --login url username password entries to osgviewer + +Thu, 5 Oct 2017 15:02:17 +0100 +Author : OpenSceneGraph git repository +Merge pull request #348 from eligovision/OpenSceneGraph_serializersosg serializers fixed for static build, ShaderAttribute wrapper added + +Thu, 5 Oct 2017 12:45:47 +0100 +Author : Robert Osfield +Steamlined the handling of osg::Geometry + +Thu, 5 Oct 2017 12:15:23 +0100 +Author : OpenSceneGraph git repository +Merge pull request #346 from LaurensVoerman/FindLIBLASremoved las_c library from FindLIBLAS.cmake, it's not used by the osgplugin. + +Thu, 28 Sep 2017 11:09:18 +0200 +Author : Denys Koch +Fix loading of 16bit PNG imagesWhen a 16bit PNG image is loaded, the internalTextureFormat is set to unsized (i.e pixelFormat) constant. This results in 8 Bit Texture2D + +Fri, 22 Sep 2017 11:38:43 +0300 +Author : Konstantin S. Matveyev +LineSegmentIntersector fixed: intersection ratio remaped to the range of LineSegment => correct order in multiset of intersections + +Sun, 17 Sep 2017 18:48:32 +0300 +Author : konstantin.matveyev +tellg call removed from StreamOperator's checkStream function, because reading of files (readNodeFile etc.) with tellg on 'every iter' is approximately 100 times slower on Emscripten platform + +Thu, 21 Sep 2017 16:33:14 +0200 +Author : Laurens Voerman +VNC: try to find password for host if no password for host:port is found + +Fri, 15 Sep 2017 12:14:37 +0300 +Author : Konstantin S. Matveyev +osg serializers fixed for static build, ShaderAttribute wrapper added + +Tue, 12 Sep 2017 09:19:33 +0200 +Author : Laurens Voerman +removed las_c library from FindLIBLAS.cmake, it's not used by the osg plugin. + +Mon, 4 Sep 2017 15:21:26 +0100 +Author : OpenSceneGraph git repository +Merge pull request #344 from eligovision/OpenSceneGraph_text3dText3D dynamic changing fix + +Mon, 4 Sep 2017 15:20:54 +0100 +Author : OpenSceneGraph git repository +Merge pull request #345 from eligovision/OpenSceneGraph_example_text3dexample_osgtext3d: more options for testing + +Mon, 4 Sep 2017 11:44:30 +0300 +Author : Konstantin S. Matveyev +example_osgtext3d: more options for testing + +Mon, 4 Sep 2017 11:29:50 +0300 +Author : Konstantin S. Matveyev +Text3D dynamic changing fix + +Mon, 4 Sep 2017 08:36:49 +0100 +Author : OpenSceneGraph git repository +Merge pull request #341 from scrawl/cullingactive_fixLineSegmentIntersector: respect the 'cullingActive' flag for bounding box check + +Sun, 3 Sep 2017 14:15:36 +0000 +Author : scrawl +LineSegmentIntersector: respect the 'cullingActive' flag when testing drawable bounding box + +Fri, 1 Sep 2017 15:50:47 +0100 +Author : OpenSceneGraph git repository +Merge pull request #337 from mp3butcher/osganimbugfixfix a bug in how vertexattributes are filled + +Wed, 30 Aug 2017 23:15:01 +0200 +Author : Julien Valentin +fix a bug in how vertexattributes are filled + +Tue, 29 Aug 2017 10:51:06 +0100 +Author : OpenSceneGraph git repository +Merge pull request #334 from mathieu/ValidateProgramTooEarlyUnder macOS the glValidateProgram reports too many errors + +Tue, 29 Aug 2017 11:34:27 +0200 +Author : Mathieu MARACHE +Under macOS the glValidateProgram reports too many false negatives (errors) about missing buffers, etc..From the internet https://stackoverflow.com/questions/15335510/opengl-glvalidateprogram-error-on-mac-os-x : +« […] The purpose of glValidateProgram is not to use it as an added "check" step after linking the program, because the GL and application state is hardly ready for actually using that program at this point, probably it's even before we get around to initializing the default framebuffer (its bitdepth, its multisample buffers, etc), and that's what the error hints at. + +An appropriate place to call glValidateProgram would be right before you make a real render call. » + +Mon, 28 Aug 2017 16:28:30 +0100 +Author : OpenSceneGraph git repository +Merge pull request #332 from denyskoch/fix-boundingsphere-inequality-operatorFix flawed BoundingSphere inequality operator + +Mon, 28 Aug 2017 14:34:39 +0200 +Author : Denys Koch +Fix flawed BoundingSphere inequality operator + +Mon, 28 Aug 2017 10:02:27 +0100 +Author : OpenSceneGraph git repository +Merge pull request #330 from mathieu/ProgramFixFunctionAvailableCoreProfileosg::Program::isFixedFunction() should'nt return true if fixed function unavailable + +Mon, 28 Aug 2017 09:44:10 +0200 +Author : Mathieu MARACHE +osg::Program::isFixedFunction() should'nt return true fixed function is unavailable, even if _shaderList.empty() is true + +Sun, 27 Aug 2017 18:08:09 +0100 +Author : OpenSceneGraph git repository +Merge pull request #327 from kornerr/masterFix Emscripten build errors + +Sun, 27 Aug 2017 18:07:21 +0100 +Author : OpenSceneGraph git repository +Merge pull request #328 from scrawl/group-docsFix docs for Group::addChild to match implementation + +Sat, 26 Aug 2017 19:25:00 +0300 +Author : Michael Kapelko +Fix Emscripten build errors + +Sat, 26 Aug 2017 11:30:55 +0000 +Author : scrawl +Fix docs for Group::addChild to match implementationChecking for duplicates is only done if ENSURE_CHILD_IS_UNIQUE is defined, but this is never defined anywhere. + +Fri, 25 Aug 2017 14:49:38 +0100 +Author : OpenSceneGraph git repository +Merge pull request #326 from emminizer/glcore3_cmakefixSETUP_EXE in CMake now uses same define for including the GLCORE head… + +Fri, 25 Aug 2017 14:48:42 +0100 +Author : OpenSceneGraph git repository +Merge pull request #325 from emminizer/msvc2015_exportfixRemoved inappropriate use of OSG_EXPORT on DefaultIndirectCommandDrawArrays and De… + +Fri, 25 Aug 2017 09:04:05 -0400 +Author : Daniel Emminizer +SETUP_EXE in CMake now uses same define for including the GLCORE headers as SETUP_LIBRARY and SETUP_PLUGIN. Fixes Windows build errors for applications. + +Fri, 25 Aug 2017 08:55:25 -0400 +Author : Daniel Emminizer +No longer using OSG_EXPORT on DefaultIndirectCommandDrawArrays and DefaultIndirectCommandDrawElements, fixing compile errors in MSVC 2015. + +Fri, 25 Aug 2017 10:04:40 +0100 +Author : OpenSceneGraph git repository +Merge pull request #324 from mp3butcher/osganimationAdd extensions + +Fri, 25 Aug 2017 00:19:22 +0200 +Author : Julien Valentin +Add extensions + +Thu, 24 Aug 2017 15:13:14 +0100 +Author : Robert Osfield +Cleaned up warnings and removed assorts. + +Thu, 24 Aug 2017 13:55:56 +0100 +Author : OpenSceneGraph git repository +Merge pull request #322 from mp3butcher/MDI7fix osggpucull to fit both new BIB and MDI + +Thu, 24 Aug 2017 14:15:09 +0200 +Author : Julien Valentin +fix osggpucull to fit both new BIB and MDI + +Thu, 24 Aug 2017 11:17:43 +0100 +Author : Robert Osfield +Bumped SO version to reflect changes in ABI + +Thu, 24 Aug 2017 11:08:38 +0100 +Author : OpenSceneGraph git repository +Merge pull request #321 from LaurensVoerman/tgaMissingColormapfix gcc/VC compile warnings, reject color mapped tga files with missing colormap. + +Thu, 24 Aug 2017 11:33:23 +0200 +Author : Laurens Voerman +fix gcc/VC compile warnings, reject color mapped tga files with missing colormap. + +Thu, 24 Aug 2017 10:33:44 +0100 +Author : OpenSceneGraph git repository +Merge pull request #320 from mp3butcher/MDI7MultiDrawIndirect + +Thu, 24 Aug 2017 11:26:23 +0200 +Author : Julien Valentin +Merge remote-tracking branch 'upstream/master' into MDI7 + +Thu, 24 Aug 2017 09:53:32 +0100 +Author : OpenSceneGraph git repository +Merge pull request #318 from mp3butcher/osganimationchange the design of BufferIndexBinding to work with BufferData instead of BufferObject +matrix transpose + +Thu, 24 Aug 2017 10:29:19 +0200 +Author : Julien Valentin +comply with osg::BufferIndexBinding new design (a miss) + +Wed, 23 Aug 2017 23:42:12 +0200 +Author : Julien Valentin +change the design of BufferIndexBinding to work with BufferData instead of BufferObject allow convenient BufferData abstraction + serialization of BufferIndexBinding + +Wed, 23 Aug 2017 19:06:25 +0200 +Author : Julien Valentin +add a transpose method for 4x4 and a transpose3x3 to transpose only orthogonal part of a mat4x4 + +Wed, 23 Aug 2017 15:26:07 +0100 +Author : Robert Osfield +Fixed underflow issue + +Wed, 23 Aug 2017 14:51:18 +0100 +Author : Robert Osfield +Fixed comparison to properly handle texture coordinates being assigned + +Wed, 23 Aug 2017 14:48:04 +0100 +Author : OpenSceneGraph git repository +Merge pull request #314 from LaurensVoerman/notify2reduce the need to reallocate the std::ostream buffer behind osg::Notify + +Wed, 23 Aug 2017 14:39:35 +0100 +Author : Robert Osfield +Warning fixes + +Tue, 22 Aug 2017 15:23:47 +0200 +Author : Laurens Voerman +reduce the need to reallocate the std::ostream buffer behind osg::Notify (causing multitreading issues) by pre-allocating 4095 bytes. + +Wed, 23 Aug 2017 08:54:10 +0100 +Author : OpenSceneGraph git repository +Merge pull request #315 from kornerr/masterFix stat64 build issue with NDK 15 by definining it as stat for Android + +Tue, 22 Aug 2017 22:49:56 +0300 +Author : Michael Kapelko +Fix stat64 build issue with NDK 15 by definining at stat for Android + +Tue, 22 Aug 2017 12:04:18 +0100 +Author : Robert Osfield +Updated ChangeLog + Tue, 22 Aug 2017 09:04:49 +0100 Author : Robert Osfield Added catch for controbutors list @@ -165,18 +436,122 @@ Mon, 7 Aug 2017 16:32:44 +0100 Author : Robert Osfield Added link to ABI tracker +Sun, 6 Aug 2017 15:30:27 +0100 +Author : OpenSceneGraph git repository +Merge pull request #294 from mp3butcher/MDI6add resize methods method in IndirectCommandArrays ..etc.. + +Sat, 5 Aug 2017 18:03:27 +0200 +Author : Julien Valentin +update IndirectCommandArrays interfaces and default impl to use DrawElements like semantic + +Wed, 2 Aug 2017 22:10:02 +0200 +Author : Julien Valentin +add MDI support + +Wed, 2 Aug 2017 21:50:25 +0200 +Author : Julien Valentin +add resize methods method in CommandArrays (it allows user to work without casting to the concrete class result of MDI.getCommandArray()) move getTotalDataSize in CommandArrays interfaces comply with other DrawElementsXXX removing parameters in mdi constructors and add several method ( allow use of osgUtil::DrawElementTypeSimplifer on these) + +Tue, 1 Aug 2017 07:54:37 +0100 +Author : OpenSceneGraph git repository +Merge pull request #293 from mp3butcher/MDI6fix a bug in MDI serializer + +Tue, 1 Aug 2017 02:18:15 +0200 +Author : Julien Valentin +fix a bug in MDI serializer + Mon, 31 Jul 2017 13:38:18 +0100 Author : Robert Osfield Merged #pragmatic shader fix from OpenSceneGraph-3.4 branch. +Mon, 31 Jul 2017 08:09:16 +0100 +Author : OpenSceneGraph git repository +Merge pull request #287 from mp3butcher/MDI6correct a bug and make MDI example more conservative + +Mon, 31 Jul 2017 03:15:03 +0200 +Author : Julien Valentin +fix a bug : indices pre incremented should be post + +Mon, 31 Jul 2017 03:08:52 +0200 +Author : Julien Valentin +Add arguments, command line usage and use DrawElementsUInt for classic case + +Mon, 31 Jul 2017 02:43:50 +0200 +Author : Julien Valentin +correct a bug and make it more conservative + +Sun, 30 Jul 2017 15:40:17 +0100 +Author : OpenSceneGraph git repository +Merge pull request #285 from mp3butcher/MDI6add a very simple example for mdi with basevertex + +Sun, 30 Jul 2017 10:15:32 +0200 +Author : Julien Valentin +add a very simple example for mdi with basevertex + Fri, 28 Jul 2017 17:17:25 +0100 Author : Robert Osfield Updated version number, ChangeLog and AUTHORS file for 3.5.7 developer release +Fri, 28 Jul 2017 14:34:59 +0100 +Author : Robert Osfield +Added missing break statements + +Fri, 28 Jul 2017 14:32:56 +0100 +Author : Robert Osfield +Improved readability and consistency with the rest OSG by adding/removing spaces and brackets where appropriate. + +Fri, 28 Jul 2017 13:30:36 +0100 +Author : Robert Osfield +Improved the readability and consistency with the rest of the OSG by inserting/removing spaces and line spacing. + Fri, 28 Jul 2017 10:27:47 +0100 Author : OpenSceneGraph git repository Merge pull request #267 from kornerr/masterAdd osgemscripten example +Fri, 28 Jul 2017 08:46:30 +0100 +Author : OpenSceneGraph git repository +Merge pull request #278 from mp3butcher/MDI2Mdi + +Thu, 27 Jul 2017 12:27:55 +0200 +Author : mp3butcher +set DIBO of the drawcommandarray directly in their interface constructor it makes osggpu use case lighter + drawcommandarray can't exist without a BO + +Thu, 27 Jul 2017 12:00:41 +0200 +Author : mp3butcher +Promote PrimitiveSetIndirect's VBO to a target explicited DIBO (in order to benefit from BOSet queue management) + +Thu, 27 Jul 2017 10:26:43 +0100 +Author : OpenSceneGraph git repository +Merge pull request #277 from mp3butcher/MDI2PrimitiveSetIndirect cleanup + serializers + +Thu, 27 Jul 2017 01:54:25 +0200 +Author : mp3butcher +add DrawIndirectBufferObject as State variable in order to minimize call to glBindBuffer(GL_DRAW_INDIRECT_BUFFER,X) TODO: Promote PrimitiveSetIndirect's VBO to target explicited DIBO (in order to benefit from BOSet queue management) + +Thu, 27 Jul 2017 01:40:04 +0200 +Author : mp3butcher +remove deprecated DrawIndirectBufferBinding + +Thu, 27 Jul 2017 01:08:37 +0200 +Author : mp3butcher +fix some errors during renaming and cleanup code + +Wed, 26 Jul 2017 23:38:20 +0200 +Author : mp3butcher +add untested serializers for PrimitiveSetIndirect + +Wed, 26 Jul 2017 23:36:55 +0200 +Author : mp3butcher +some renaming and harmonisations with osg metamodel convention + +Wed, 26 Jul 2017 20:46:09 +0100 +Author : Robert Osfield +Merge branch 'MDI2' of https://github.com/mp3butcher/OpenSceneGraph into MultiDrawIndirect + +Wed, 26 Jul 2017 20:25:41 +0200 +Author : mp3butcher +first commit for Indirect Draw integration in osg users will have to implement interfaces for their custom drawcommandarrays add a lot of new primitive set + few defines integration is made in osggpucull + Wed, 26 Jul 2017 12:54:37 +0100 Author : Robert Osfield Replaced FindOurDCMTK.cmake usage with FindDCMTK.cmake diff --git a/applications/osgversion/Contributors.cpp b/applications/osgversion/Contributors.cpp index 86a585b87..a5a495536 100644 --- a/applications/osgversion/Contributors.cpp +++ b/applications/osgversion/Contributors.cpp @@ -699,7 +699,9 @@ NameCorrection nameCorrections[] = {"WeSee", "", "Alois", "Wismer"}, {"We", "See", - "Alois", "Wismer"} + "Alois", "Wismer"}, + {"AnyOldName3", "", + "Chris", "Djali"} }; diff --git a/applications/osgviewer/osgviewer.cpp b/applications/osgviewer/osgviewer.cpp index d790d3873..0d7919687 100644 --- a/applications/osgviewer/osgviewer.cpp +++ b/applications/osgviewer/osgviewer.cpp @@ -74,14 +74,10 @@ int main(int argc, char** argv) std::string url, username, password; while(arguments.read("--login",url, username, password)) { - if (!osgDB::Registry::instance()->getAuthenticationMap()) - { - osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); - osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails( - url, - new osgDB::AuthenticationDetails(username, password) - ); - } + osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( + url, + new osgDB::AuthenticationDetails(username, password) + ); } std::string device; diff --git a/applications/present3D/present3D.cpp b/applications/present3D/present3D.cpp index 0e0c6abec..24318d9ec 100644 --- a/applications/present3D/present3D.cpp +++ b/applications/present3D/present3D.cpp @@ -336,14 +336,10 @@ int main( int argc, char **argv ) std::string url, username, password; while(arguments.read("--login",url, username, password)) { - if (!osgDB::Registry::instance()->getAuthenticationMap()) - { - osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); - osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails( - url, - new osgDB::AuthenticationDetails(username, password) - ); - } + osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( + url, + new osgDB::AuthenticationDetails(username, password) + ); } diff --git a/examples/osgSSBO/osgSSBO.cpp b/examples/osgSSBO/osgSSBO.cpp index 9db8161dc..e357acac8 100644 --- a/examples/osgSSBO/osgSSBO.cpp +++ b/examples/osgSSBO/osgSSBO.cpp @@ -473,7 +473,6 @@ void ComputeNode::addDataMonitor(osg::Vec3 placement, osg::Vec3 relativePlacemen pat->setName(labelCaption); text->setText(pat->getName()); text->setBackdropType(osgText::Text::OUTLINE); - text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); text->setBackdropOffset(0.05f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); @@ -773,7 +772,7 @@ void ComputeNode::initComputingSetup() _dataArray->setBufferObject(_ssbo.get()); - _ssbb = new osg::ShaderStorageBufferBinding(0, _dataArray, 0, blockSize); + _ssbb = new osg::ShaderStorageBufferBinding(0, _dataArray.get(), 0, blockSize); statesetComputation->setAttributeAndModes(_ssbb.get(), osg::StateAttribute::ON); diff --git a/examples/osgfadetext/osgfadetext.cpp b/examples/osgfadetext/osgfadetext.cpp index 37b0eafe2..308b482b6 100644 --- a/examples/osgfadetext/osgfadetext.cpp +++ b/examples/osgfadetext/osgfadetext.cpp @@ -121,10 +121,70 @@ osg::Node* createFadeText(osg::EllipsoidModel* ellipsoid) } -int main(int, char**) +class TextSettings : public osg::NodeVisitor { +public: + TextSettings(osg::ArgumentParser& arguments): + osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN), + _backdropTypeSet(false), + _backdropType(osgText::Text::NONE), + _shaderTechniqueSet(false), + _shaderTechnique(osgText::GREYSCALE) + { + if (arguments.read("--outline")) + { + _backdropTypeSet = true; + _backdropType = osgText::Text::OUTLINE; + } + if (arguments.read("--sdf")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::SIGNED_DISTANCE_FIELD; + } + if (arguments.read("--all")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::ALL_FEATURES; + } + if (arguments.read("--greyscale")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::GREYSCALE; + } + if (arguments.read("--no-shader")) + { + _shaderTechniqueSet = true; + _shaderTechnique = osgText::NO_TEXT_SHADER; + } + } + + void apply(osg::Drawable& drawable) + { + osgText::Text* text = dynamic_cast(&drawable); + if (text) + { + if (_backdropTypeSet) + { + text->setBackdropType(_backdropType); + text->setBackdropOffset(0.1f); + text->setBackdropColor(osg::Vec4(1.0f, 0.0f, 0.0f, 1.0f)); + } + if (_shaderTechniqueSet) text->setShaderTechnique(_shaderTechnique); + } + } + + bool _backdropTypeSet; + osgText::Text::BackdropType _backdropType; + bool _shaderTechniqueSet; + osgText::ShaderTechnique _shaderTechnique; +}; + +int main(int argc, char** argv) +{ + osg::ArgumentParser arguments(&argc, argv); + // construct the viewer. - osgViewer::Viewer viewer; + osgViewer::Viewer viewer(arguments); viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); viewer.getCamera()->setNearFarRatio(0.00001f); @@ -144,6 +204,12 @@ int main(int, char**) csn->addChild(createFadeText(csn->getEllipsoidModel())); } + if (arguments.argc()>1) + { + TextSettings textSettings(arguments); + root->accept(textSettings); + } + viewer.setCameraManipulator(new osgGA::TerrainManipulator); return viewer.run(); diff --git a/examples/osgfont/osgfont.cpp b/examples/osgfont/osgfont.cpp index 9255bea0c..bad750798 100644 --- a/examples/osgfont/osgfont.cpp +++ b/examples/osgfont/osgfont.cpp @@ -3,6 +3,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -56,80 +59,367 @@ osg::Camera* createOrthoCamera(double width, double height) return camera; } -osgText::Text* createLabel(const std::string& l, const char* f, unsigned int size) +typedef std::list Sizes; + +struct TextSettings { - static osg::Vec3 pos(10.0f, 10.0f, 0.0f); + TextSettings(): + fontFilename("fonts/arial.ttf"), + minFilter(osg::Texture::LINEAR_MIPMAP_LINEAR), + magFilter(osg::Texture::LINEAR), + maxAnisotropy(16.0f), + shaderTechnique(osgText::GREYSCALE), + textColor(1.0f, 1.0f, 1.0f, 1.0f), + backdropType(osgText::Text::NONE), + backdropOffset(0.07f, 0.07f), + backdropColor(0.0f, 0.0f, 0.0f, 1.0f), + scaleFontSizeToFontResolution(false) + { + } + + void readFilterMode(const std::string& value, osg::Texture::FilterMode& filterMode) + { + if (value=="LINEAR") filterMode = osg::Texture::LINEAR; + else if (value=="NEAREST") filterMode = osg::Texture::NEAREST; + else if (value=="LINEAR_MIPMAP_LINEAR") filterMode = osg::Texture::LINEAR_MIPMAP_LINEAR; + } + + void read(osg::ArgumentParser& arguments) + { + if (arguments.read("--test")) + { + backgroundColor = osg::Vec4(1.0, 1.0, 1.0, 1.0); + + fontFilename = "fonts/arialbd.ttf"; + backdropType = osgText::Text::OUTLINE; + + sizes.clear(); + sizes.push_back(8); + sizes.push_back(16); + sizes.push_back(32); + sizes.push_back(64); + sizes.push_back(128); + } + + if (arguments.read("--GREYSCALE")) { shaderTechnique = osgText::GREYSCALE; } + if (arguments.read("--SIGNED_DISTANCE_FIELD")) { shaderTechnique = osgText::SIGNED_DISTANCE_FIELD; } + if (arguments.read("--ALL_FEATURES")) { shaderTechnique = osgText::ALL_FEATURES; } + + if (arguments.read("--font",fontFilename)) {} + + std::string value; + if (arguments.read("--min", value)) { readFilterMode(value, minFilter); } + if (arguments.read("--mag", value)) { readFilterMode(value, magFilter); } + + if (arguments.read("--anisotropy",maxAnisotropy)) {} + + + if (arguments.read("--outline")) backdropType = osgText::Text::OUTLINE; + if (arguments.read("--shadow")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + if (arguments.read("--shadow-br")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_RIGHT; + if (arguments.read("--shadow-cr")) backdropType = osgText::Text::DROP_SHADOW_CENTER_RIGHT; + if (arguments.read("--shadow-tr")) backdropType = osgText::Text::DROP_SHADOW_TOP_RIGHT; + if (arguments.read("--shadow-bc")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_CENTER; + if (arguments.read("--shadow-tc")) backdropType = osgText::Text::DROP_SHADOW_TOP_CENTER; + if (arguments.read("--shadow-bl")) backdropType = osgText::Text::DROP_SHADOW_BOTTOM_LEFT; + if (arguments.read("--shadow-cl")) backdropType = osgText::Text::DROP_SHADOW_CENTER_LEFT; + if (arguments.read("--shadow-tl")) backdropType = osgText::Text::DROP_SHADOW_TOP_LEFT; + + + + float offset; + if (arguments.read("--offset", offset)) backdropOffset.set(offset, offset); + + if (arguments.read("--text-color", textColor.r(), textColor.g(), textColor.b(), textColor.a())) {} + if (arguments.read("--bd-color", backdropColor.r(), backdropColor.g(), backdropColor.b(), backdropColor.a())) {} + if (arguments.read("--bg-color", backgroundColor.r(), backgroundColor.g(), backgroundColor.b(), backgroundColor.a())) {} + + if (arguments.read("--constant-size")) scaleFontSizeToFontResolution = false; + if (arguments.read("--scale-size")) scaleFontSizeToFontResolution = true; + + } + + void setText(osgText::Text& text) + { + OSG_NOTICE<<"Settings::setText()"< font; + + if (fontFilename!="default") font = osgText::readRefFontFile(fontFilename); + + if (!font) font = osgText::Font::getDefaultFont(); + + font->setMinFilterHint(minFilter); + font->setMagFilterHint(magFilter); + font->setMaxAnisotropy(maxAnisotropy); + + text.setColor(textColor); + text.setBackdropType(backdropType); + text.setBackdropOffset(backdropOffset.x(), backdropOffset.y()); + text.setBackdropColor(backdropColor); + text.setShaderTechnique(shaderTechnique); + + text.setFont(font.get()); + + } + + std::string fontFilename; + osg::Texture::FilterMode minFilter; + osg::Texture::FilterMode magFilter; + float maxAnisotropy; + osgText::ShaderTechnique shaderTechnique; + + osg::Vec4 textColor; + osgText::Text::BackdropType backdropType; + osg::Vec2 backdropOffset; + osg::Vec4 backdropColor; + osg::Vec4 backgroundColor; + Sizes sizes; + bool scaleFontSizeToFontResolution; +}; + +osgText::Text* createLabel(const std::string& l, TextSettings& settings, unsigned int size, osg::Vec3& pos) +{ osgText::Text* label = new osgText::Text(); - osg::ref_ptr font = osgText::readRefFontFile(f); - label->setFont(font); - label->setCharacterSize(size); + settings.setText(*label); + + if (settings.scaleFontSizeToFontResolution) + { + label->setCharacterSize(size); + } + label->setFontResolution(size, size); - label->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); label->setPosition(pos); label->setAlignment(osgText::Text::LEFT_BOTTOM); // It seems to be important we do this last to get best results? label->setText(l); - textInfo(label); + // textInfo(label); - pos.y() += size + 10.0f; + pos.y() += label->getCharacterHeight()*2.0; return label; } -typedef std::list Sizes; +class KeyHandler : public osgGA::GUIEventHandler +{ +public: + + KeyHandler() {} + + ~KeyHandler() {} + + bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) + { + osgViewer::View* view = dynamic_cast(&aa); + if (!view) return false; + +#if 1 + osg::StateSet* stateset = view->getSceneData()->getOrCreateStateSet(); +#else + osg::StateSet* stateset = view->getCamera()->getOrCreateStateSet(); +#endif + switch(ea.getEventType()) + { + case(osgGA::GUIEventAdapter::KEYUP): + { + if (ea.getKey()=='d') + { + toggleDefine(stateset, "SIGNED_DISTANCE_FIELD"); + return true; + } + else if (ea.getKey()=='o') + { + toggleDefine(stateset, "OUTLINE"); + return true; + } + break; + } + default: + break; + } + return false; + } + + void toggleDefine(osg::StateSet* stateset, const std::string& define) + { + osg::StateSet::DefinePair* dp = stateset->getDefinePair(define); + if (dp) + { + OSG_NOTICE<<"Disabling "<removeDefine(define); + } + else + { + OSG_NOTICE<<"Enabling "<setDefine(define); + } + } +}; + int main(int argc, char** argv) { - osgViewer::Viewer viewer; osg::ArgumentParser args(&argc, argv); - - // Make sure we have the minimum args... - if(argc <= 2) - { - osg::notify(osg::FATAL) << "usage: " << args[0] << " fontfile size1 [size2 ...]" << std::endl; - - return 1; - } + osgViewer::Viewer viewer(args); - viewer.addEventHandler( new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()) ); + viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet())); viewer.addEventHandler(new osgViewer::StatsHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler()); + viewer.addEventHandler(new KeyHandler()); - osg::Group* group = new osg::Group(); - osg::Camera* camera = createOrthoCamera(1280.0f, 1024.0f); + TextSettings settings; + settings.backgroundColor = viewer.getCamera()->getClearColor(); - // Create the list of desired sizes. - Sizes sizes; + settings.read(args); - for(int i = 2; i < argc; i++) + viewer.getCamera()->setClearColor(settings.backgroundColor); + + osg::ref_ptr root = new osg::Group; + + bool split_screen = args.read("--split"); + + if (split_screen) { - if(!args.isNumber(i)) continue; + viewer.realize(); - sizes.push_back(std::atoi(args[i])); + // quite an dirty divusion of the master Camera's window if one is assigned. + if (viewer.getCamera()->getGraphicsContext()) + { + viewer.stopThreading(); + + osg::ref_ptr gc = viewer.getCamera()->getGraphicsContext(); + osg::ref_ptr traits = gc->getTraits(); + + // left half + { + osg::ref_ptr camera = new osg::Camera; + camera->setCullMask(0x1); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(0,0, traits->width/2, traits->height)); + viewer.addSlave(camera.get(), osg::Matrixd::translate(1.0,0.0,0.0), osg::Matrixd::scale(2.0, 1.0, 1.0)); + } + + { + osg::ref_ptr camera = new osg::Camera; + camera->setCullMask(0x2); + camera->setGraphicsContext(gc.get()); + camera->setViewport(new osg::Viewport(traits->width/2+2,0, traits->width/2, traits->height)); + viewer.addSlave(camera.get(), osg::Matrixd::translate(-1.0,0.0,0.0), osg::Matrixd::scale(2.0, 1.0, 1.0)); + } + + viewer.getCamera()->setGraphicsContext(0); + + viewer.startThreading(); + } + else + { + split_screen = false; + } } - osg::Geode* geode = new osg::Geode(); + osg::ref_ptr transform = new osg::MatrixTransform; + transform->setMatrix(osg::Matrixd::rotate(osg::DegreesToRadians(90.0), 1.0, 0.0, 0.0)); + root->addChild(transform.get()); + root = transform; + + osg::ref_ptr program = new osg::Program; + std::string shaderFilename; + while(args.read("--shader", shaderFilename)) + { + osg::ref_ptr shader = osgDB::readRefShaderFile(shaderFilename); + if (shader.get()) + { + OSG_NOTICE<<"Loading shader "<addShader(shader.get()); + } + } + + if (program->getNumShaders()>0) + { + OSG_NOTICE<<"Using shaders"<getOrCreateStateSet()->setAttribute(program.get(), osg::StateAttribute::OVERRIDE | osg::StateAttribute::ON); + root->getOrCreateStateSet()->addUniform(new osg::Uniform("glyphTexture", 0)); + + settings.shaderTechnique = osgText::ALL_FEATURES; + } + + + std::string outputFilename; + if (args.read("-o", outputFilename)) {} + + if (args.argc() > 1) + { + settings.fontFilename = argv[1]; + + // Create the list of desired sizes. + for(int i = 2; i < args.argc(); i++) + { + if(!args.isNumber(i)) continue; + + settings.sizes.push_back(std::atoi(args[i])); + } + } + + if (settings.sizes.empty()) + { + settings.sizes.push_back(8); + settings.sizes.push_back(16); + settings.sizes.push_back(32); + settings.sizes.push_back(64); + } + + osg::ref_ptr geode = new osg::Geode(); + + osg::Vec3 pos(0.0f, 0.0f, 0.0f); // Add all of our osgText drawables. - for(Sizes::const_iterator i = sizes.begin(); i != sizes.end(); i++) + for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) { std::stringstream ss; ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - geode->addDrawable(createLabel(ss.str(), args[1], *i)); + geode->addDrawable(createLabel(ss.str(), settings, *i, pos)); } - camera->addChild(geode); + root->addChild(geode.get()); - group->addChild(camera); + if (split_screen) + { + geode->setNodeMask(0x1); - viewer.setSceneData(group); + osg::ref_ptr right_geode = new osg::Geode; + right_geode->setNodeMask(0x2); + + settings.shaderTechnique = osgText::GREYSCALE; + + pos.set(0.0f, 0.0f, 0.0f); + + for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++) + { + std::stringstream ss; + + ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + right_geode->addDrawable(createLabel(ss.str(), settings, *i, pos)); + } + + root->addChild(right_geode); + } + + + if (!outputFilename.empty()) + { + osgDB::writeNodeFile(*root, outputFilename); + return 0; + } + + viewer.setSceneData(root.get()); return viewer.run(); } diff --git a/examples/osggpucull/osggpucull.cpp b/examples/osggpucull/osggpucull.cpp index 78650cc16..4b87433b6 100644 --- a/examples/osggpucull/osggpucull.cpp +++ b/examples/osggpucull/osggpucull.cpp @@ -188,7 +188,7 @@ struct IndirectTarget } void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect ) { - indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands); + indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands.get()); indirectCommandTextureBuffer->setInternalFormat( GL_R32I ); indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE); indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false); @@ -199,11 +199,12 @@ struct IndirectTarget { std::vector newPrimitiveSets; - for(unsigned int j=0;jsize(); ++j){ + for(unsigned int j=0;jsize(); ++j) + { osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j ); - ipr->setIndirectCommandArray( indirectCommands); + ipr->setIndirectCommandArray( indirectCommands.get()); newPrimitiveSets.push_back(ipr); - } + } geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); @@ -215,7 +216,7 @@ struct IndirectTarget else // use glMultiDrawArraysIndirect() { osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES ); - ipr->setIndirectCommandArray( indirectCommands ); + ipr->setIndirectCommandArray( indirectCommands.get() ); geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr ); } @@ -236,6 +237,7 @@ struct IndirectTarget instanceTarget->bindToImageUnit(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, osg::Texture::READ_WRITE); } + void addIndirectCommandData( const std::string& uniformNamePrefix, int index, osg::StateSet* stateset ) { std::string uniformName = uniformNamePrefix + char( '0' + index ); @@ -245,6 +247,7 @@ struct IndirectTarget } + void addIndirectTargetData( bool cullPhase, const std::string& uniformNamePrefix, int index, osg::StateSet* stateset ) { std::string uniformName; @@ -257,6 +260,7 @@ struct IndirectTarget stateset->addUniform( uniform ); stateset->setTextureAttribute( OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, instanceTarget.get() ); } + void addDrawProgram( const std::string& uniformBlockName, osg::StateSet* stateset ) { drawProgram->addBindUniformBlock(uniformBlockName, 1); @@ -286,6 +290,7 @@ struct GPUCullData instanceTypesUBB = new osg::UniformBufferBinding(1, instanceTypes.get(), 0, 0); } + void setUseMultiDrawArraysIndirect( bool value ) { useMultiDrawArraysIndirect = value; @@ -297,6 +302,7 @@ struct GPUCullData return; targets[index] = IndirectTarget( agv, targetDrawProgram ); } + bool registerType(unsigned int typeID, unsigned int targetID, osg::Node* node, const osg::Vec4& lodDistances, float maxDensityPerSquareKilometer ) { if( typeID >= instanceTypes->getData().size() ) @@ -328,6 +334,7 @@ struct GPUCullData target->second.maxTargetQuantity += maxQuantity; return true; } + // endRegister() method is called after all indirect targets and instance types are registered. // It creates indirect targets with pixel format and data type provided by user ( indirect targets may hold // different information about single instance depending on user's needs ( in our example : static rendering @@ -388,10 +395,12 @@ struct StaticInstance : position(m), extraParams(params), idParams(typeID,id,0,0) { } + osg::Vec3d getPosition() const { return position.getTrans(); } + osg::Matrixf position; osg::Vec4f extraParams; osg::Vec4i idParams; @@ -705,10 +714,12 @@ struct ResetTexturesCallback : public osg::StateSet::Callback ResetTexturesCallback() { } + void addTextureDirty( unsigned int texUnit ) { texUnitsDirty.push_back(texUnit); } + void addTextureDirtyParams( unsigned int texUnit ) { texUnitsDirtyParams.push_back(texUnit); @@ -748,6 +759,7 @@ struct InvokeMemoryBarrier : public osg::Drawable::DrawCallback : _barriers(barriers) { } + virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const { //DrawIndirectGLExtensions *ext = DrawIndirectGLExtensions::getExtensions( renderInfo.getContextID(), true ); @@ -836,11 +848,13 @@ osg::Group* createSimpleHouse( float detailRatio, const osg::Vec4& buildingColor osg::ref_ptr chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); root->addChild( chimneyGeode.get() ); } + { osg::ref_ptr chimney = new osg::Cylinder( osg::Vec3( -5.5, 3.0, 16.5 ), 0.1, 1.0 ); osg::ref_ptr chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); root->addChild( chimneyGeode.get() ); } + { osg::ref_ptr chimney = new osg::Cylinder( osg::Vec3( -5.0, 3.0, 16.25 ), 0.1, 0.5 ); osg::ref_ptr chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); @@ -1183,6 +1197,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback for(; i<3*_quantityPerType; ++i) // speed of airplanes _speed.push_back( random( 10.0, 16.0 ) ); } + virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable) { if( nv->getVisitorType() != osg::NodeVisitor::UPDATE_VISITOR ) @@ -1213,6 +1228,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback setRotationUsingRotSpeed( i, 5, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(0.0,1.0,0.0)) * osg::Matrix::translate(0.0,2.0,-6.0), currentTime, 0.5 ); setRotationUsingRotSpeed( i, 6, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(0.0,1.0,0.0)) * osg::Matrix::translate(0.0,-2.0,-6.0), currentTime, -0.5 ); } + for(;i<2*_quantityPerType;++i) //update cars { nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) ); @@ -1223,6 +1239,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback setRotationUsingRotSpeed( i, 3, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(1.0,0.0,0.0)) * osg::Matrix::translate(2.0,-1.8,1.0), currentTime, wheelRotSpeed ); setRotationUsingRotSpeed( i, 4, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(1.0,0.0,0.0)) * osg::Matrix::translate(-2.0,-1.8,1.0), currentTime, wheelRotSpeed ); } + for(;i<3*_quantityPerType;++i) // update airplanes { nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) ); @@ -1251,6 +1268,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback (*vertexArray)[index] = newPosition; return newPosition; } + void setRotationUsingRotSpeed( unsigned int index, unsigned int boneIndex, const osg::Matrix& zeroMatrix, double currentTime, double rotSpeed ) { // setRotationUsingRotSpeed() is a very unoptimally written ( because it uses osg::Matrix::inverse() ), @@ -1473,12 +1491,16 @@ int main( int argc, char **argv ) if ( arguments.read("--skip-static") ) showStaticRendering = false; + if ( arguments.read("--skip-dynamic") ) showDynamicRendering = false; + if ( arguments.read("--export-objects") ) exportInstanceObjects = true; + if ( arguments.read("--use-multi-draw") ) useMultiDrawArraysIndirect = true; + arguments.read("--instances-per-cell",instancesPerCell); arguments.read("--static-area-size",staticAreaSize); arguments.read("--dynamic-area-size",dynamicAreaSize); diff --git a/examples/osglauncher/osglauncher.cpp b/examples/osglauncher/osglauncher.cpp index 00c98b42c..ce7e4c553 100644 --- a/examples/osglauncher/osglauncher.cpp +++ b/examples/osglauncher/osglauncher.cpp @@ -44,6 +44,7 @@ #include #include +#include #include #include @@ -424,6 +425,9 @@ int main( int argc, char **argv ) // add the handler for doing the picking viewer.addEventHandler(new PickHandler(&viewer,updateText.get())); + // add the stats handler + viewer.addEventHandler(new osgViewer::StatsHandler); + osg::Group* root = new osg::Group(); root->addChild( setupGraph() ); diff --git a/examples/osglogo/osglogo.cpp b/examples/osglogo/osglogo.cpp index 18699462d..f5161c041 100644 --- a/examples/osglogo/osglogo.cpp +++ b/examples/osglogo/osglogo.cpp @@ -41,6 +41,9 @@ #include + +static bool s_useSDF = false; + class MyBillboardTransform : public osg::PositionAttitudeTransform { public: @@ -147,6 +150,12 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label text->setFont(font); text->setFontResolution(64,64); + + if (s_useSDF) + { + text->setShaderTechnique(osgText::ALL_FEATURES); + } + text->setAlignment(osgText::Text::CENTER_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin()))); @@ -174,48 +183,35 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label, text->setFont(font); text->setFontResolution(110,120); + + if (s_useSDF) + { + text->setShaderTechnique(osgText::ALL_FEATURES); + } + text->setAlignment(osgText::Text::RIGHT_CENTER); text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); + text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f)); - //text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour - text->setText(label); -#if 1 text->setBackdropType(osgText::Text::OUTLINE); -// text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - - text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); -// text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); -// text->setBackdropImplementation(osgText::Text::DEPTH_RANGE); -// text->setBackdropImplementation(osgText::Text::STENCIL_BUFFER); - - text->setBackdropOffset(0.05f); + text->setBackdropOffset(0.03f); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); -#endif - -#if 1 text->setColorGradientMode(osgText::Text::OVERALL); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); text->setColorGradientCorners(lightblue, blue, blue, lightblue); -#else - text->setColorGradientMode(osgText::Text::OVERALL); - osg::Vec4 light = osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f); - osg::Vec4 dark = osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f); - text->setColorGradientCorners(light, dark, dark, light); -// text->setColorGradientCorners(dark, light, light, dark); -#endif + + text->setText(label); geode->addDrawable( text ); if (!subscript.empty()) { - //osgText::Text* subscript = new osgText::Text(new osgText::TextureFont(font,45)); - osgText::Text* subscriptText = new osgText::Text; subscriptText->setFont(font); subscriptText->setText(subscript); @@ -353,9 +349,6 @@ osg:: Node* createBoxNo5No2(const osg::BoundingBox& bb,float chordRatio) osg:: Node* createBackdrop(const osg::Vec3& corner,const osg::Vec3& top,const osg::Vec3& right) { - - - osg::Geometry* geom = new osg::Geometry; osg::Vec3 normal = (corner-top)^(right-corner); @@ -475,6 +468,9 @@ int main( int argc, char **argv ) return 1; } + + while(arguments.read("--sdf")) { s_useSDF = true; } + std::string label = "OpenSceneGraph"; std::string subscript = ""; diff --git a/examples/osgsimpleMDI/osgsimpleMDI.cpp b/examples/osgsimpleMDI/osgsimpleMDI.cpp index be7bd2c31..94309b56b 100644 --- a/examples/osgsimpleMDI/osgsimpleMDI.cpp +++ b/examples/osgsimpleMDI/osgsimpleMDI.cpp @@ -69,10 +69,24 @@ int main( int argc, char**argv ) arguments.read("--numX",MAXX); arguments.read("--numY",MAXY); - bool MDIenable=true; + enum PrimtiveSetUsage + { + MultiDraw, + MultiplePrimitiveSets, + SinglePrimitiveSet + }; + + PrimtiveSetUsage usage = MultiDraw; if(arguments.read("--classic")) - { MDIenable=false; - OSG_WARN<<"disabling MDI"< geom=new osg::Geometry(); geom->setUseVertexBufferObjects(true); + osg::BoundingBox bb; bb.set(0,0,0,MAXX,0,MAXY); //set bounds by hand cause of the lack of support of basevertex in PrimitiveFunctors @@ -104,10 +119,10 @@ int main( int argc, char**argv ) osg::Vec3Array * verts=new osg::Vec3Array(); - - for(int j =0 ; jsize(); mdicommands->push_back(cmd); - for(int z=0; z<4; z++) { + for(int z=0; z<4; z++) + { verts->push_back(osg::Vec3(i,0,j)+myCoords[z]); mdi->addElement(myIndices[z]); } } } - geom->setVertexArray(verts); - if(MDIenable) { - geom->addPrimitiveSet(mdi); - } else - for(int i=0; isetElementBufferObject(ebo); - geom->addPrimitiveSet(dre); - for(int z=0; z<4; z++)myIndicesUI[z]+=4; + geom->setVertexArray(verts); + + switch(usage) + { + case(MultiDraw): + { + geom->addPrimitiveSet(mdi); + break; + } + case(MultiplePrimitiveSets): + { + for(int i=0; i dre = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP,4,myIndicesUI); + dre->setElementBufferObject(ebo.get()); + geom->addPrimitiveSet(dre.get()); + for(int z=0; z<4; z++) myIndicesUI[z]+=4; + } + break; + } + case(SinglePrimitiveSet): + { + osg::ref_ptr primitives = new osg::DrawElementsUInt(GL_TRIANGLES); + primitives->setElementBufferObject(ebo.get()); + geom->addPrimitiveSet(primitives.get()); + + unsigned int vi = 0; + for(int i=0; ipush_back(vi); + primitives->push_back(vi+2); + primitives->push_back(vi+1); + primitives->push_back(vi+1); + primitives->push_back(vi+2); + primitives->push_back(vi+3); + vi += 4; + } + break; + } + } + root->addChild(geom); + osgViewer::Viewer viewer; viewer.addEventHandler(new osgViewer::StatsHandler); viewer.setSceneData( root ); diff --git a/examples/osgtext/osgtext.cpp b/examples/osgtext/osgtext.cpp index b576dc76b..4f7972fe3 100644 --- a/examples/osgtext/osgtext.cpp +++ b/examples/osgtext/osgtext.cpp @@ -621,8 +621,8 @@ struct TextCounterCallback : public osg::NodeCallback if (text) { std::stringstream str; - str <<"Text Counter "<<_textCounter<setText(str.str()); @@ -670,7 +670,7 @@ int main(int argc, char** argv) text->setUpdateCallback(new TextCounterCallback()); text->setFont("fonts/times.ttf"); text->setAxisAlignment(osgText::Text::XZ_PLANE); - text->setText("This is a counter test"); + text->setText("Text Counter :"); viewer.setSceneData(text.get()); } diff --git a/examples/osgtext3D/osgtext3D.cpp b/examples/osgtext3D/osgtext3D.cpp index 24178d039..62197139b 100644 --- a/examples/osgtext3D/osgtext3D.cpp +++ b/examples/osgtext3D/osgtext3D.cpp @@ -49,23 +49,34 @@ public: { if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up) { - m_Text3D->setCharacterSize(m_Text3D->getCharacterHeight() + 0.1); // failed - OSG_NOTICE<<"m_Text3D->getCharacterHeight()="<getCharacterHeight()<setCharacterSize(m_Text3D->getCharacterHeight() + 0.1); + OSG_NOTICE<<"m_Text3D->getCharacterHeight() = " << m_Text3D->getCharacterHeight() << std::endl; } else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Down) { - m_Text3D->setCharacterDepth(m_Text3D->getCharacterDepth() + 0.1); // ok - OSG_NOTICE<<"m_Text3D->getCharacterDepth()="<getCharacterDepth()<setCharacterDepth(m_Text3D->getCharacterDepth() + 0.1); + OSG_NOTICE<<"m_Text3D->getCharacterDepth() = " << m_Text3D->getCharacterDepth() << std::endl; } else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left) { - m_Text3D->setText("setText\nworks!", osgText::String::ENCODING_UTF8); // ok - OSG_NOTICE<<"m_Text3D->getText()="<getText().size()<setText("Press arrow keys.", osgText::String::ENCODING_UTF8); + else if (counter%3 == 1) + m_Text3D->setText("setText\nworks!", osgText::String::ENCODING_UTF8); + else if (counter%3 == 2) + m_Text3D->setText("setText really works?", osgText::String::ENCODING_UTF8); + else if (counter%3 == 3) + m_Text3D->setText("setText works, really!", osgText::String::ENCODING_UTF8); + + ++counter; + + OSG_NOTICE<<"m_Text3D->getText().size() = " << m_Text3D->getText().size() << std::endl; } else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right) { m_Text3D->setLineSpacing(m_Text3D->getLineSpacing() + 0.1); - OSG_NOTICE<<"m_Text3D->getLineSpacing()="<getLineSpacing()<getLineSpacing() = " << m_Text3D->getLineSpacing() << std::endl; } } @@ -90,7 +101,7 @@ int main(int argc, char** argv) if (!font) return 1; OSG_NOTICE<<"Read font "< style = new osgText::Style; @@ -238,18 +249,18 @@ int main(int argc, char** argv) geode->addDrawable( osg::createTexturedQuadGeometry(osg::Vec3(0.0f,characterSize*thickness,0.0f),osg::Vec3(characterSize,0.0,0.0),osg::Vec3(0.0f,0.0,characterSize), 0.0, 0.0, 1.0, 1.0) ); } - if (arguments.read("--add-axes")) - group->addChild(osgDB::readNodeFile("axes.osgt")); + if (arguments.read("--add-axes")) + group->addChild(osgDB::readNodeFile("axes.osgt")); - std::string mode; - if (arguments.read("--character-size-mode", mode)) - { - if (mode == "screen_coords") - { - text3D->setCharacterSizeMode(osgText::TextBase::SCREEN_COORDS); - text3D->setCharacterSize(1080/4); - } - } + std::string mode; + if (arguments.read("--character-size-mode", mode)) + { + if (mode == "screen_coords") + { + text3D->setCharacterSizeMode(osgText::TextBase::SCREEN_COORDS); + text3D->setCharacterSize(1080/4); + } + } viewer.addEventHandler(new Text3DAttributeHandler(text3D)); } diff --git a/examples/osgviewerCocoa/ViewerCocoa.mm b/examples/osgviewerCocoa/ViewerCocoa.mm index aded53820..84333c449 100644 --- a/examples/osgviewerCocoa/ViewerCocoa.mm +++ b/examples/osgviewerCocoa/ViewerCocoa.mm @@ -432,7 +432,6 @@ static void Internal_SetAlpha(NSBitmapImageRep *imageRep, unsigned char alpha_va default_text->setAlignment(osgText::Text::CENTER_CENTER); default_text->setBackdropType(osgText::Text::OUTLINE); -// default_text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET); default_text->setColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); default_text->setBackdropColor(osg::Vec4(0.0, 0.0, 0.0, 1.0)); default_text->setAxisAlignment(osgText::Text::XZ_PLANE); diff --git a/examples/osgvnc/osgvnc.cpp b/examples/osgvnc/osgvnc.cpp index a286b59b0..35089afb9 100644 --- a/examples/osgvnc/osgvnc.cpp +++ b/examples/osgvnc/osgvnc.cpp @@ -7,7 +7,7 @@ class EscapeHandler : public osgGA::GUIEventHandler { public: - + EscapeHandler() {} bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) @@ -22,7 +22,7 @@ class EscapeHandler : public osgGA::GUIEventHandler { osgViewer::View* view = dynamic_cast(&aa); if (view) view->getViewerBase()->setDone(true); - + return true; } } @@ -37,6 +37,8 @@ class EscapeHandler : public osgGA::GUIEventHandler int main(int argc,char** argv) { osg::ArgumentParser arguments(&argc, argv); + arguments.getApplicationUsage()->addCommandLineOption("--login ", "Provide authentication information for http file access."); + arguments.getApplicationUsage()->addCommandLineOption("--password ", "Provide password for any vnc url on command line not mentioned in --login."); osgViewer::Viewer viewer(arguments); osgWidget::GeometryHints hints(osg::Vec3(0.0f,0.0f,0.0f), @@ -52,6 +54,15 @@ int main(int argc,char** argv) { } + std::string url, username, password; + while (arguments.read("--login", url, username, password)) + { + osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails( + url, + new osgDB::AuthenticationDetails(username, password) + ); + } + for(int i=1; igetAuthenticationMap()) osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); - osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password)); + const osgDB::AuthenticationMap* authenticationMap = osgDB::Registry::instance()->getOrCreateAuthenticationMap(); + const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname); + if (details == NULL) + { + authenticationMap->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password)); + } } osg::ref_ptr vncClient = new osgWidget::VncClient; if (vncClient->connect(arguments[i], hints)) - { + { group->addChild(vncClient.get()); - + hints.position.x() += 1.1f; } } diff --git a/examples/osgwidgetlabel/osgwidgetlabel.cpp b/examples/osgwidgetlabel/osgwidgetlabel.cpp index 39d86fefe..a29320cdf 100644 --- a/examples/osgwidgetlabel/osgwidgetlabel.cpp +++ b/examples/osgwidgetlabel/osgwidgetlabel.cpp @@ -30,12 +30,6 @@ osgWidget::Label* createLabel(const std::string& l, unsigned int size=13) { label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f); label->setLabel(l); - /* - text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); - text->setBackdropOffset(0.2f); - */ - return label; } diff --git a/include/osg/DisplaySettings b/include/osg/DisplaySettings index 6821d14e9..0609cf0c6 100644 --- a/include/osg/DisplaySettings +++ b/include/osg/DisplaySettings @@ -20,6 +20,7 @@ #include #include +#include namespace osg { @@ -319,9 +320,15 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced SHADER_GLES3 }; - void setShaderHint(ShaderHint hint) { _shaderHint = hint; } + /** set the ShaderHint to tells shader generating cdoes version to create. + * By default also OSG_GLSL_VERSION and OSG_PRECISION_FLOAT values that can get use directly in shaders using $OSG_GLSL_VERSION and $OSG_PRECISION_FLOAT respectively.*/ + void setShaderHint(ShaderHint hint, bool setShaderValues=true); ShaderHint getShaderHint() const { return _shaderHint; } + /** Set the TextShaderTechnique that is used in the Text default constructor to choose which osgText::ShaderTechnique to use.*/ + void setTextShaderTechnique(const std::string& str) { _textShaderTechnique = str; } + const std::string& getTextShaderTechnique() const { return _textShaderTechnique; } + void setKeystoneHint(bool enabled) { _keystoneHint = enabled; } bool getKeystoneHint() const { return _keystoneHint; } @@ -358,6 +365,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced /** helper function for computing the right eye view matrix.*/ virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const; + + void setValue(const std::string& name, const std::string& value); + + bool getValue(const std::string& name, std::string& value, bool use_getenv_fallback=true) const; + protected: virtual ~DisplaySettings(); @@ -415,6 +427,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced VertexBufferHint _vertexBufferHint; ShaderHint _shaderHint; + std::string _textShaderTechnique; bool _keystoneHint; FileNames _keystoneFileNames; @@ -422,6 +435,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced OSXMenubarBehavior _OSXMenubarBehavior; + typedef std::map ValueMap; + + mutable OpenThreads::Mutex _valueMapMutex; + mutable ValueMap _valueMap; + }; } diff --git a/include/osg/Image b/include/osg/Image index 3a90175ea..4bf7df74b 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -68,6 +69,10 @@ #endif #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE) + #define GL_ALPHA4 0x803B + #define GL_ALPHA8 0x803C + #define GL_ALPHA12 0x803D + #define GL_ALPHA16 0x803E #define GL_BITMAP 0x1A00 #define GL_COLOR_INDEX 0x1900 #define GL_INTENSITY12 0x804C @@ -114,6 +119,38 @@ #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 #endif +#ifndef GL_KHR_texture_compression_astc_hdr +#define GL_KHR_texture_compression_astc_hdr 1 +#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0 +#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1 +#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2 +#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3 +#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4 +#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5 +#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6 +#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7 +#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8 +#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9 +#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA +#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB +#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC +#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9 +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC +#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD +#endif /* GL_KHR_texture_compression_astc_hdr */ + #ifndef GL_DEPTH_COMPONENT #define GL_DEPTH_COMPONENT 0x1902 #endif @@ -404,11 +441,17 @@ class OSG_EXPORT Image : public BufferData static bool isPackedType(GLenum type); static GLenum computePixelFormat(GLenum pixelFormat); static GLenum computeFormatDataType(GLenum pixelFormat); + + /** return the dimensions of a block of compressed pixels */ + static osg::Vec3i computeBlockFootprint(GLenum pixelFormat); + + /** return the size in bytes of a block of compressed pixels */ static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing); static unsigned int computeNumComponents(GLenum pixelFormat); static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type); static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing); static unsigned int computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat, GLenum type, int packing = 1, int slice_packing = 1, int image_packing = 1); + static int roudUpToMultiple(int s, int pack); static int computeNearestPowerOfTwo(int s,float bias=0.5f); static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1); diff --git a/include/osg/PrimitiveSetIndirect b/include/osg/PrimitiveSetIndirect index bf7b1a5ce..8ede4471c 100644 --- a/include/osg/PrimitiveSetIndirect +++ b/include/osg/PrimitiveSetIndirect @@ -168,8 +168,8 @@ public: } /// get command array of this indirect primitive set - inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } - inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray; } + inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray.get(); } + inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray.get(); } ///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride) ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw) @@ -616,8 +616,8 @@ public: if(!dynamic_cast(_indirectCommandArray->getBufferObject())) _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject()); } - inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray; } - inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray; } + inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray.get(); } + inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray.get(); } protected: diff --git a/include/osg/State b/include/osg/State index ee5415660..97b6fec2a 100644 --- a/include/osg/State +++ b/include/osg/State @@ -823,9 +823,12 @@ class OSG_EXPORT State : public Referenced * during rendering. */ inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; } - /** Get the DisplaySettings */ + /** Get the const DisplaySettings */ inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); } + /** Get the const DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */ + inline const DisplaySettings* getActiveDisplaySettings() const { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); } + /** Set flag for early termination of the draw traversal.*/ diff --git a/include/osg/VertexArrayState b/include/osg/VertexArrayState index cfd8dae86..ce5956315 100644 --- a/include/osg/VertexArrayState +++ b/include/osg/VertexArrayState @@ -34,6 +34,8 @@ public: modifiedCount(0xffffffff), active(false) {} + virtual const char* className() const = 0; // { return "ArrayDispatch"; } + virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0; virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0; diff --git a/include/osg/VertexAttribDivisor b/include/osg/VertexAttribDivisor index 7b222cd38..a38b31da5 100644 --- a/include/osg/VertexAttribDivisor +++ b/include/osg/VertexAttribDivisor @@ -50,6 +50,7 @@ class OSG_EXPORT VertexAttribDivisor : public StateAttribute COMPARE_StateAttribute_Types(VertexAttribDivisor,sa) // compare each parameter in turn against the rhs. + COMPARE_StateAttribute_Parameter(_index) COMPARE_StateAttribute_Parameter(_divisor) return 0; // passed all the above comparison macros, must be equal. diff --git a/include/osgDB/DataTypes b/include/osgDB/DataTypes index 8d319e806..4b6a8bbca 100644 --- a/include/osgDB/DataTypes +++ b/include/osgDB/DataTypes @@ -134,7 +134,7 @@ public: : _name(copy._name), _indentDelta(copy._indentDelta) {} void set( const char* name, int delta=0 ) - { _name = name, _indentDelta = delta; } + { _name = name; _indentDelta = delta; } std::string _name; int _indentDelta; diff --git a/include/osgDB/Registry b/include/osgDB/Registry index 62d4ac884..87076dc81 100644 --- a/include/osgDB/Registry +++ b/include/osgDB/Registry @@ -366,6 +366,13 @@ class OSGDB_EXPORT Registry : public osg::Referenced /** Set the password map to be used by plugins when access files from secure locations.*/ void setAuthenticationMap(AuthenticationMap* authenticationMap) { _authenticationMap = authenticationMap; } + /** Get the password map to be used by plugins when access files from secure locations. Create a AuthenticationMap if one isn't already assigned.*/ + AuthenticationMap* getOrCreateAuthenticationMap() + { + if (!_authenticationMap) _authenticationMap = new AuthenticationMap; + return _authenticationMap.get(); + } + /** Get the password map to be used by plugins when access files from secure locations.*/ AuthenticationMap* getAuthenticationMap() { return _authenticationMap.get(); } diff --git a/include/osgText/Font b/include/osgText/Font index 952a6fda4..ab4641c93 100644 --- a/include/osgText/Font +++ b/include/osgText/Font @@ -27,6 +27,7 @@ namespace osgText { // forward declare Font class Font; +class TextBase; #ifdef OSG_PROVIDE_READFILE /** Read a font from specified file. The filename may contain a path. @@ -84,13 +85,9 @@ public: static osg::ref_ptr& getDefaultFont(); - void setTexEnv(osg::TexEnv* texenv) { if (texenv) _texenv = texenv; } - inline osg::TexEnv* getTexEnv() { return _texenv.get(); } - inline const osg::TexEnv* getTexEnv() const { return _texenv.get(); } - - void setStateSet(osg::StateSet* stateset) { _stateset = stateset; } - osg::StateSet* getStateSet() { return _stateset.get(); } - const osg::StateSet* getStateSet() const { return _stateset.get(); } + typedef std::vector< osg::ref_ptr > StateSets; + StateSets& getCachedStateSets() { return _statesets; } + const StateSets& getCachedStateSets() const { return _statesets; } /** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes and a font resolution.*/ @@ -110,19 +107,6 @@ public: * return true on success, return false when not supported.*/ virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } - /** Set the margin around each glyph, - * to ensure that texture filtering doesn't bleed adjacent glyph's into each other. - * Default margin is 1 texels.*/ - void setGlyphImageMargin(unsigned int margin); - unsigned int getGlyphImageMargin() const; - - /** Set the margin ratio around each glyph, relative to the glyph's size. - * to ensure that texture filtering doesn't bleed adjacent glyph's into each other. - * Default margin is 0.05.*/ - void setGlyphImageMarginRatio(float margin); - float getGlyphImageMarginRatio() const; - - /** Set the size of texture to create to store the glyph images when rendering. * Note, this doesn't affect already created Texture Glhph's.*/ void setTextureSizeHint(unsigned int width,unsigned int height); @@ -140,6 +124,9 @@ public: void setMagFilterHint(osg::Texture::FilterMode mode); osg::Texture::FilterMode getMagFilterHint() const; + void setMaxAnisotropy(float anis) { _maxAnisotropy = anis; } + float getMaxAnisotropy() const { return _maxAnisotropy; } + unsigned int getFontDepth() const { return _depth; } void setNumberCurveSamples(unsigned int numSamples) { _numCurveSamples = numSamples; } @@ -170,13 +157,14 @@ public: typedef std::vector< osg::ref_ptr > GlyphTextureList; GlyphTextureList& getGlyphTextureList() { return _glyphTextureList; } + void assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique); + protected: virtual ~Font(); void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph); - typedef std::vector< osg::ref_ptr > StateSetList; typedef std::map< unsigned int, osg::ref_ptr > GlyphMap; typedef std::map< unsigned int, osg::ref_ptr > Glyph3DMap; @@ -185,8 +173,7 @@ protected: mutable OpenThreads::Mutex _glyphMapMutex; - osg::ref_ptr _texenv; - osg::ref_ptr _stateset; + StateSets _statesets; FontSizeGlyphMap _sizeGlyphMap; GlyphTextureList _glyphTextureList; @@ -195,13 +182,12 @@ protected: // current active size of font FontResolution _fontSize; - unsigned int _margin; - float _marginRatio; unsigned int _textureWidthHint; unsigned int _textureHeightHint; osg::Texture::FilterMode _minFilterHint; osg::Texture::FilterMode _magFilterHint; + float _maxAnisotropy; unsigned int _depth; unsigned int _numCurveSamples; @@ -247,8 +233,6 @@ public: virtual bool getVerticalSize(float & /*ascender*/, float & /*descender*/) const { return false; } }; - - }; } diff --git a/include/osgText/Glyph b/include/osgText/Glyph index f08686841..2d1eafa05 100644 --- a/include/osgText/Glyph +++ b/include/osgText/Glyph @@ -30,15 +30,6 @@ #include -// GL_ALPHA is deprecated in GL3/GL4 core profile, use GL_RED and a shader in this case. See osgText example. -#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) -#define OSGTEXT_GLYPH_FORMAT GL_RED -#define OSGTEXT_GLYPH_INTERNALFORMAT GL_R8 -#else -#define OSGTEXT_GLYPH_FORMAT GL_ALPHA -#define OSGTEXT_GLYPH_INTERNALFORMAT GL_ALPHA -#endif - namespace osgText { class Font; @@ -47,6 +38,14 @@ class Glyph3D; class GlyphGeometry; class GlyphTexture; +enum ShaderTechnique +{ + NO_TEXT_SHADER = 0x0, + GREYSCALE = 0x1, + SIGNED_DISTANCE_FIELD = 0x2, + ALL_FEATURES = GREYSCALE | SIGNED_DISTANCE_FIELD +}; + class OSGTEXT_EXPORT Glyph : public osg::Image { public: @@ -58,6 +57,9 @@ public: unsigned int getGlyphCode() const { return _glyphCode; } + void setFontResolution(const FontResolution& fontRes) { _fontResolution = fontRes; } + const FontResolution& getFontResolution() const { return _fontResolution; } + void setWidth(float width) { _width = width; } float getWidth() const { return _width; } @@ -76,21 +78,33 @@ public: void setVerticalAdvance(float advance); float getVerticalAdvance() const; - void setTexture(GlyphTexture* texture); - GlyphTexture* getTexture(); - const GlyphTexture* getTexture() const; + struct TextureInfo : public osg::Referenced + { + TextureInfo(): + texture(0), + texelMargin(0.0f) {} - void setTexturePosition(int posX,int posY); - int getTexturePositionX() const; - int getTexturePositionY() const; + TextureInfo(GlyphTexture* tex, int x, int y, const osg::Vec2& mintc, const osg::Vec2& maxtc, float margin): + texture(tex), + texturePositionX(x), + texturePositionY(y), + minTexCoord(mintc), + maxTexCoord(maxtc), + texelMargin(margin) {} - void setMinTexCoord(const osg::Vec2& coord); - const osg::Vec2& getMinTexCoord() const; + GlyphTexture* texture; + int texturePositionX; + int texturePositionY; + osg::Vec2 minTexCoord; + osg::Vec2 maxTexCoord; + float texelMargin; + }; - void setMaxTexCoord(const osg::Vec2& coord); - const osg::Vec2& getMaxTexCoord() const; + void setTextureInfo(ShaderTechnique technique, TextureInfo* info); - void subload() const; + const TextureInfo* getTextureInfo(ShaderTechnique technique) const; + + TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique); protected: @@ -99,6 +113,8 @@ protected: Font* _font; unsigned int _glyphCode; + FontResolution _fontResolution; + float _width; float _height; @@ -108,15 +124,8 @@ protected: osg::Vec2 _verticalBearing; float _verticalAdvance; - GlyphTexture* _texture; - int _texturePosX; - int _texturePosY; - osg::Vec2 _minTexCoord; - osg::Vec2 _maxTexCoord; - - typedef osg::buffered_value GLObjectList; - mutable GLObjectList _globjList; - + typedef std::vector< osg::ref_ptr > TextureInfoList; + TextureInfoList _textureInfoList; }; class OSGTEXT_EXPORT GlyphGeometry : public osg::Referenced @@ -253,12 +262,13 @@ public: /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/ virtual int compare(const osg::StateAttribute& rhs) const; - /** Set the margin around each glyph, to ensure that texture filtering doesn't bleed adjacent glyph's into each other.*/ - void setGlyphImageMargin(unsigned int margin) { _margin = margin; } - unsigned int getGlyphImageMargin() const { return _margin; } + void setShaderTechnique(ShaderTechnique technique) { _shaderTechnique = technique; } - void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; } - float getGlyphImageMarginRatio() const { return _marginRatio; } + ShaderTechnique getShaderTechnique() const { return _shaderTechnique; } + + + int getEffectMargin(const Glyph* glyph); + int getTexelMargin(const Glyph* glyph); bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); @@ -277,14 +287,13 @@ protected: virtual ~GlyphTexture(); + void copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info); - // parameter used to compute the size and position of empty space - // in the texture which could accommodate new glyphs. - int _margin; - float _marginRatio; - int _usedY; - int _partUsedX; - int _partUsedY; + ShaderTechnique _shaderTechnique; + + int _usedY; + int _partUsedX; + int _partUsedY; typedef std::vector< osg::ref_ptr > GlyphRefList; typedef std::vector< const Glyph* > GlyphPtrList; diff --git a/include/osgText/Text b/include/osgText/Text index db497792f..ab5e547a0 100644 --- a/include/osgText/Text +++ b/include/osgText/Text @@ -36,15 +36,12 @@ public: virtual const char* className() const { return "Text"; } virtual const char* libraryName() const { return "osgText"; } - virtual void setFont(Font* font=0) { setFont(osg::ref_ptr(font)); }; + /** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/ + void setShaderTechnique(ShaderTechnique technique); - /** Set the Font to use to render the text.*/ - virtual void setFont(osg::ref_ptr font); + /** Get the ShaderTechnique hint.*/ + ShaderTechnique getShaderTechnique() { return _shaderTechnique; } - /** Set the font, loaded from the specified front file, to use to render the text, - * setFont("") sets the use of the default font. - * See the osgText::readFontFile function for how the font file will be located. */ - virtual void setFont(const std::string& fontfile) { TextBase::setFont(fontfile); } /** * Turns off writing to the depth buffer when rendering text. This only affects text @@ -70,31 +67,6 @@ public: NONE }; - enum BackdropImplementation - { - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - POLYGON_OFFSET = 0, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - NO_DEPTH_BUFFER, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - DEPTH_RANGE, - - /* No longer supported, naps to DELAYED_DEPTH_WRITES.*/ - STENCIL_BUFFER, - - /* DELAYED_DEPTH_WRITES - * This mode renders all text with depth writes turned off, then - * again with depth writes on, but with the color buffer disabled. - * This should render text accurately for all graphics cards. The - * only downside is the additional pass to render to the depth - * buffer. But if you don't need the depth buffer updated for - * your, this extra pass can be disabled by calling - * enableDepthWrites(false).*/ - DELAYED_DEPTH_WRITES - }; - /** * BackdropType gives you a background shadow text behind your regular * text. This helps give text extra contrast which can be useful when @@ -149,18 +121,6 @@ public: const osg::Vec4& getBackdropColor() const { return _backdropColor; } - /** - * This specifies the underlying backdrop rendering implementation. - * Unfortunately, at this time, there is no "perfect" rendering solution - * so this function is provided to let you 'pick your poison'. Each - * implementation has trade-offs. See BackdropImplementation enum - * docs for details.*/ - void setBackdropImplementation(BackdropImplementation implementation); - - BackdropImplementation getBackdropImplementation() const { return _backdropImplementation; } - - - enum ColorGradientMode { SOLID = 0, // a.k.a. ColorGradients off @@ -232,6 +192,20 @@ public: public: + /** deprecated, value ignored.*/ + enum BackdropImplementation + { + POLYGON_OFFSET = 0, + NO_DEPTH_BUFFER, + DEPTH_RANGE, + STENCIL_BUFFER, + DELAYED_DEPTH_WRITES + }; + + /** deprecated, value ignored.*/ + void setBackdropImplementation(BackdropImplementation) {} + /** deprecated, value should be ignored.*/ + BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; } // internal structures, variable and methods used for rendering of characters. struct OSGTEXT_EXPORT GlyphQuads @@ -239,7 +213,7 @@ public: typedef std::vector Glyphs; Glyphs _glyphs; - Primitives _primitives; + osg::ref_ptr _primitives; GlyphQuads(); GlyphQuads(const GlyphQuads& gq); @@ -284,6 +258,8 @@ protected: virtual ~Text(); + virtual osg::StateSet* createStateSet(); + Font* getActiveFont(); const Font* getActiveFont() const; @@ -302,7 +278,6 @@ protected: virtual void computePositionsImplementation(); - void computeBackdropPositions(); void computeBackdropBoundingBox(); void computeBoundingBoxMargin(); @@ -314,10 +289,10 @@ protected: void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const; + ShaderTechnique _shaderTechnique; bool _enableDepthWrites; BackdropType _backdropType; - BackdropImplementation _backdropImplementation; float _backdropHorizontalOffset; float _backdropVerticalOffset; diff --git a/include/osgText/TextBase b/include/osgText/TextBase index 64fe785f1..d75e41ff2 100644 --- a/include/osgText/TextBase +++ b/include/osgText/TextBase @@ -53,6 +53,9 @@ public: virtual void setFont(const std::string& fontfile); /** Get the font. Return 0 if default is being used.*/ + Font* getFont() { return _font.get(); } + + /** Get the const font. Return 0 if default is being used.*/ const Font* getFont() const { return _font.get(); } @@ -284,6 +287,10 @@ protected: virtual ~TextBase(); + virtual osg::StateSet* createStateSet(); + + virtual void assignStateSet(); + void initArraysAndBuffers(); osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; diff --git a/include/osgUtil/GLObjectsVisitor b/include/osgUtil/GLObjectsVisitor index b9a130f3e..c52d6cce6 100644 --- a/include/osgUtil/GLObjectsVisitor +++ b/include/osgUtil/GLObjectsVisitor @@ -97,6 +97,9 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor void apply(osg::Drawable& drawable); void apply(osg::StateSet& stateset); + /** Do a compile traversal and then reset any state,*/ + void compile(osg::Node& node); + protected: typedef std::set DrawableAppliedSet; diff --git a/include/osgUtil/RenderLeaf b/include/osgUtil/RenderLeaf index b1d36fb03..6e699602a 100644 --- a/include/osgUtil/RenderLeaf +++ b/include/osgUtil/RenderLeaf @@ -52,8 +52,8 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced { _parent = 0; _drawable = drawable; - _projection = projection, - _modelview = modelview, + _projection = projection; + _modelview = modelview; _depth = depth; _dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC); _traversalNumber = traversalNumber; diff --git a/include/osgViewer/api/X11/GraphicsWindowX11 b/include/osgViewer/api/X11/GraphicsWindowX11 index 1efb990fe..0af24fdb1 100644 --- a/include/osgViewer/api/X11/GraphicsWindowX11 +++ b/include/osgViewer/api/X11/GraphicsWindowX11 @@ -37,10 +37,11 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub _parent(0), _window(0), _visualInfo(0), - _fbConfig(0), #ifdef OSG_USE_EGL _eglDisplay(0), _eglSurface(0), + #else + _fbConfig(0), #endif _currentCursor(0), _initialized(false), @@ -54,7 +55,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub memset(_keyMap, 0, 32); init(); - + if (valid()) { setState( new osg::State ); @@ -72,7 +73,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub } } - + virtual bool isSameKindAs(const Object* object) const { return dynamic_cast(object)!=0; } virtual const char* libraryName() const { return "osgViewer"; } virtual const char* className() const { return "GraphicsWindowX11"; } @@ -129,35 +130,35 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub { WindowData(Window window): _window(window) {} - + Window _window; }; public: - + // X11 specific access functions Display* getEventDisplay() const { return _eventDisplay; } Display* getDisplayToUse() const ; - + Window& getParent() { return _parent; } Window& getWindow() { return _window; } Cursor getCurrentCursor() { return _currentCursor; } protected: - + ~GraphicsWindowX11(); - + Cursor getOrCreateCursor(MouseCursor mouseShape); - + bool createVisualInfo(); bool createWindow(); bool setWindow(Window window); - + void init(); bool checkAndSendEventFullScreenIfNeeded(Display* display, int x, int y, int width, int height, bool windowDecoration); @@ -171,23 +172,24 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub int getModifierMask() const; void syncLocks(); void flushKeyEvents(); - + bool _valid; Display* _eventDisplay; Window _parent; Window _window; XVisualInfo* _visualInfo; - GLXFBConfig _fbConfig; #ifdef OSG_USE_EGL EGLDisplay _eglDisplay; EGLSurface _eglSurface; + #else + GLXFBConfig _fbConfig; #endif Cursor _currentCursor; Atom _deleteWindow; - + bool _initialized; bool _realized; bool _ownsWindow; diff --git a/src/osg/DisplaySettings.cpp b/src/osg/DisplaySettings.cpp index 1df3e7e89..5e7259956 100644 --- a/src/osg/DisplaySettings.cpp +++ b/src/osg/DisplaySettings.cpp @@ -118,7 +118,8 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs) _swapMethod = vs._swapMethod; _vertexBufferHint = vs._vertexBufferHint; - _shaderHint = vs._shaderHint; + + setShaderHint(_shaderHint); _keystoneHint = vs._keystoneHint; _keystoneFileNames = vs._keystoneFileNames; @@ -250,23 +251,17 @@ void DisplaySettings::setDefaults() // _vertexBufferHint = VERTEX_ARRAY_OBJECT; #if defined(OSG_GLES3_AVAILABLE) - _shaderHint = SHADER_GLES3; - OSG_INFO<<"DisplaySettings::SHADER_GLES3"<", "Set the hint to what backend osg::Geometry implementation to use. NO_PREFERENCE | VERTEX_BUFFER_OBJECT | VERTEX_ARRAY_OBJECT"); +static ApplicationUsageProxy DisplaySetting_e33(ApplicationUsage::ENVIRONMENTAL_VARIABLE, + "OSG_TEXT_SHADER_TECHNIQUE ", + "Set the defafult osgText::ShaderTechnique. ALL_FEATURES | ALL | GREYSCALE | SIGNED_DISTANCE_FIELD | SDF | NO_TEXT_SHADER | NONE"); void DisplaySettings::readEnvironmentalVariables() { @@ -725,26 +723,30 @@ void DisplaySettings::readEnvironmentalVariables() { if (strcmp(ptr,"GL2")==0) { - _shaderHint = SHADER_GL2; + setShaderHint(SHADER_GL2); } else if (strcmp(ptr,"GL3")==0) { - _shaderHint = SHADER_GL3; + setShaderHint(SHADER_GL3); } else if (strcmp(ptr,"GLES2")==0) { - _shaderHint = SHADER_GLES2; + setShaderHint(SHADER_GLES2); } else if (strcmp(ptr,"GLES3")==0) { - _shaderHint = SHADER_GLES3; + setShaderHint(SHADER_GLES3); } else if (strcmp(ptr,"NONE")==0) { - _shaderHint = SHADER_NONE; + setShaderHint(SHADER_NONE); } } + if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0) + { + setTextShaderTechnique(ptr); + } if( (ptr = getenv("OSG_KEYSTONE")) != 0) { @@ -1098,3 +1100,84 @@ osg::Matrixd DisplaySettings::computeRightEyeViewImplementation(const osg::Matri 0.0,0.0,1.0,0.0, -es,0.0,0.0,1.0); } + +void DisplaySettings::setShaderHint(ShaderHint hint, bool setShaderValues) +{ + _shaderHint = hint; + if (setShaderValues) + { + switch(_shaderHint) + { + case(SHADER_GLES3) : + setValue("OSG_GLSL_VERSION", "#version 300 es"); + setValue("OSG_PRECISION_FLOAT", "precision highp float;"); + setValue("OSG_VARYING_IN", "in"); + setValue("OSG_VARYING_OUT", "out"); + OSG_NOTICE<<"DisplaySettings::SHADER_GLES3"< lock(_valueMapMutex); + + _valueMap[name] = value; +} + +bool DisplaySettings::getValue(const std::string& name, std::string& value, bool use_getenv_fallback) const +{ + OpenThreads::ScopedLock lock(_valueMapMutex); + + ValueMap::iterator itr = _valueMap.find(name); + if (itr!=_valueMap.end()) + { + value = itr->second; + OSG_INFO<<"DisplaySettings::getValue("<= GL_COMPRESSED_RGB_S3TC_DXT1_EXT && - pixelFormat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) - { - width = (width + 3) & ~3; - height = (height + 3) & ~3; - } - - // 3dc ATI formats - // GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB - // GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC - // GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD - // GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE - if( pixelFormat >= GL_COMPRESSED_RED_RGTC1_EXT && - pixelFormat <= GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT ) - { - width = (width + 3) & ~3; - height = (height + 3) & ~3; + int blockSize = computeBlockSize(pixelFormat, 0); + if (blockSize > 0) { + osg::Vec3i footprint = computeBlockFootprint(pixelFormat); + width = (width + footprint.x() - 1) / footprint.x(); + height = (height + footprint.y() - 1) / footprint.y(); + unsigned int size = blockSize * width; + size = roudUpToMultiple(size, packing); + size *= height; + size = roudUpToMultiple(size, slice_packing); + size *= depth; + size = roudUpToMultiple(size, image_packing); + return size; } // compute size of one row @@ -821,6 +984,13 @@ unsigned int Image::computeImageSizeInBytes(int width,int height, int depth, GLe return osg::maximum( size, computeBlockSize(pixelFormat, packing) ); } +int Image::roudUpToMultiple(int s, int pack) { + if (pack < 2) return s; + s += pack - 1; + s -= s % pack; + return s; +} + int Image::computeNearestPowerOfTwo(int s,float bias) { if ((s & (s-1))!=0) @@ -880,6 +1050,34 @@ bool Image::isCompressed() const case(GL_COMPRESSED_SIGNED_R11_EAC): case(GL_COMPRESSED_RG11_EAC): case(GL_COMPRESSED_SIGNED_RG11_EAC): + case (GL_COMPRESSED_RGBA_ASTC_4x4_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_5x4_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_5x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_6x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_6x6_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_8x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_8x6_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_8x8_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x5_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x6_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x8_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_10x10_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_12x10_KHR) : + case (GL_COMPRESSED_RGBA_ASTC_12x12_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) : + case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) : return true; default: return false; @@ -1189,7 +1387,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps unsigned char* data = new unsigned char[total_size]; if (!data) { - OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, now image read."<s() & 0x3) || (source->t() & 0x3) || (s_offset & 0x3) || (t_offset & 0x3)) + { + OSG_WARN << "Error Image::copySubImage() did not succeed : size " << source->s() << "x" << source->t() << " or offset " << s_offset<< "," << t_offset << " not multiple of 4." << std::endl; + return; + } + } else { + if ((source->s() % footprint.x()) || (source->t() % footprint.y()) || (s_offset % footprint.x()) || (t_offset% footprint.y())) + { + OSG_WARN << "Error Image::copySubImage() did not succeed : size " << source->s() << "x" << source->t() << " or offset " << s_offset << "," << t_offset << " not multiple of footprint " << footprint.x() << "x" << footprint.y() << std::endl; + return; + } + } + unsigned int rowWidthInBlocks = (_s + footprint.x() - 1) / footprint.x(); + unsigned int blockSize = computeBlockSize(_pixelFormat, 0); + data_destination = _data + blockSize * (rowWidthInBlocks * t_offset + (s_offset / footprint.x())); + unsigned int copy_width = (osg::minimum(source->s(), _s - s_offset) + footprint.x() - 1) / footprint.x(); + unsigned int copy_height = (osg::minimum(source->t(), _t - t_offset) + footprint.y() - 1) / footprint.y(); + unsigned int dstRowStep = blockSize * rowWidthInBlocks; + unsigned int srcRowStep = blockSize * (source->_s + footprint.x() - 1) / footprint.x(); + const unsigned char* data_source = source->data(0, 0, 0); + for (unsigned int row = 0; row < copy_height; row += 1) { //copy blocks in a row, footprint.y() rows at a time + memcpy(data_destination, data_source, copy_width * blockSize); + data_source += srcRowStep; + data_destination += dstRowStep; + } + return; + } PixelStorageModes psm; psm.pack_alignment = _packing; psm.pack_row_length = _rowLength!=0 ? _rowLength : _s; @@ -1719,7 +1947,7 @@ bool Image::isImageTranslucent() const case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): - return dxtc_tool::CompressedImageTranslucent(_s, _t, _pixelFormat, _data); + return dxtc_tool::isCompressedImageTranslucent(_s, _t, _pixelFormat, _data); default: return false; } @@ -1919,18 +2147,29 @@ Vec4 _readColor(GLenum pixelFormat, T* data,float scale) Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const { - const unsigned char* ptr = data(s,t,r); - - switch(_dataType) + if (isCompressed()) { - case(GL_BYTE): return _readColor(_pixelFormat, (char*)ptr, 1.0f/128.0f); - case(GL_UNSIGNED_BYTE): return _readColor(_pixelFormat, (unsigned char*)ptr, 1.0f/255.0f); - case(GL_SHORT): return _readColor(_pixelFormat, (short*)ptr, 1.0f/32768.0f); - case(GL_UNSIGNED_SHORT): return _readColor(_pixelFormat, (unsigned short*)ptr, 1.0f/65535.0f); - case(GL_INT): return _readColor(_pixelFormat, (int*)ptr, 1.0f/2147483648.0f); - case(GL_UNSIGNED_INT): return _readColor(_pixelFormat, (unsigned int*)ptr, 1.0f/4294967295.0f); - case(GL_FLOAT): return _readColor(_pixelFormat, (float*)ptr, 1.0f); - case(GL_DOUBLE): return _readColor(_pixelFormat, (double*)ptr, 1.0f); + if (dxtc_tool::isDXTC(_pixelFormat)) { + unsigned char color[4]; + if (dxtc_tool::CompressedImageGetColor(color, s, t, r, _s, _t, _r, _pixelFormat, _data)) { + return Vec4(((float)color[0]) / 255.0f, ((float)color[1]) / 255.0f, ((float)color[2]) / 255.0f, ((float)color[3]) / 255.0f ); + } + } + } + else + { + const unsigned char* ptr = data(s,t,r); + switch(_dataType) + { + case(GL_BYTE): return _readColor(_pixelFormat, (char*)ptr, 1.0f/128.0f); + case(GL_UNSIGNED_BYTE): return _readColor(_pixelFormat, (unsigned char*)ptr, 1.0f/255.0f); + case(GL_SHORT): return _readColor(_pixelFormat, (short*)ptr, 1.0f/32768.0f); + case(GL_UNSIGNED_SHORT): return _readColor(_pixelFormat, (unsigned short*)ptr, 1.0f/65535.0f); + case(GL_INT): return _readColor(_pixelFormat, (int*)ptr, 1.0f/2147483648.0f); + case(GL_UNSIGNED_INT): return _readColor(_pixelFormat, (unsigned int*)ptr, 1.0f/4294967295.0f); + case(GL_FLOAT): return _readColor(_pixelFormat, (float*)ptr, 1.0f); + case(GL_DOUBLE): return _readColor(_pixelFormat, (double*)ptr, 1.0f); + } } return Vec4(1.0f,1.0f,1.0f,1.0f); } diff --git a/src/osg/ImageUtils.cpp b/src/osg/ImageUtils.cpp index 6131630f6..de965b230 100644 --- a/src/osg/ImageUtils.cpp +++ b/src/osg/ImageUtils.cpp @@ -20,6 +20,7 @@ #include #include +#include "dxtctool.h" namespace osg { @@ -716,6 +717,49 @@ OSG_EXPORT osg::Image* createImageWithOrientationConversion(const osg::Image* sr unsigned int pixelSizeInBits = srcImage->getPixelSizeInBits(); unsigned int pixelSizeInBytes = pixelSizeInBits/8; unsigned int pixelSizeRemainder = pixelSizeInBits%8; + if (dxtc_tool::isDXTC(srcImage->getPixelFormat())) + { + unsigned int DXTblockSize = 8; + if ((srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || (srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) DXTblockSize = 16; + unsigned int DXTblocksWidht = (srcImage->s() + 3) / 4;//width in 4x4 blocks + unsigned int DXTblocksHeight = (srcImage->t() + 3) / 4;//height in 4x4 blocks + unsigned int dst_DXTblocksWidht = (width + 3) / 4;//width in 4x4 blocks + unsigned int dst_DXTblocksHeight = (height + 3) / 4;//height in 4x4 blocks + + dstImage->allocateImage(width, height, depth, srcImage->getPixelFormat(), srcImage->getDataType()); + // copy across the pixels from the source image to the destination image. + if (depth != 1) + { + OSG_NOTICE << "Warning: createImageWithOrientationConversion(..) cannot handle dxt-compressed images with depth." << std::endl; + return const_cast(srcImage); + } + for (int l = 0; l> 2) + DXTblocksWidht * ((cp.y() >> 2) + (cp.z() >> 2) * DXTblocksHeight); + const unsigned char *src_block = srcImage->data() + src_blockIndex * DXTblockSize; + + unsigned int dst_blockIndex = (c >> 2) + dst_DXTblocksWidht * ((r >> 2) + (l >> 2) * dst_DXTblocksHeight); + unsigned char *dst_block = dstImage->data() + dst_blockIndex * DXTblockSize; + + memcpy((void *)dst_block, (void *)src_block, DXTblockSize); + osg::Vec3i srcSubOrigin(cp.x() & 0x7, cp.y() & 0x7, cp.z() & 0x7); + dxtc_tool::compressedBlockOrientationConversion(srcImage->getPixelFormat(),src_block, dst_block, srcSubOrigin, rowDelta, columnDelta); + + cp.x() += 4 * rowDelta.x(); + cp.y() += 4 * rowDelta.y(); + cp.z() += 4 * rowDelta.z(); + } + } + } + return dstImage.release(); + } if (pixelSizeRemainder!=0) { OSG_NOTICE<<"Warning: createImageWithOrientationConversion(..) cannot handle non byte aligned pixel formats."<getShaderSource(); - if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) + // if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) { state.convertVertexShaderSourceToOsgBuiltIns(source); } - if (osg::getNotifyLevel()>=osg::INFO) - { - std::string sourceWithLineNumbers = insertLineNumbers(source); - OSG_INFO << "\nCompiling " << _shader->getTypename() - << " source:\n" << sourceWithLineNumbers << std::endl; - } - GLint compiled = GL_FALSE; - // OSG_NOTICE<<"Compiling PerContextShader "<getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } } else { + // Convert all windows line endings to \n + replaceAll(source, "\r\n", " \n"); std::string versionLine; unsigned int lineNum = 0; @@ -675,21 +690,40 @@ void Shader::PerContextShader::compileShader(osg::State& state) if (!versionLine.empty()) { - // OSG_NOTICE<<"Shader::PerContextShader::compileShader() : Found #version, lineNum = "<(versionLine.c_str()); sourceText[1] = reinterpret_cast(_defineStr.c_str()); sourceText[2] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL ); + + if (osg::getNotifyLevel()>=osg::INFO) + { + std::string sourceWithLineNumbers = insertLineNumbers(versionLine+_defineStr+source); + OSG_INFO << "\nCompiling B: " << _shader->getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } + + // OSG_NOTICE<<" Version Line : ["<(_defineStr.c_str()); sourceText[1] = reinterpret_cast(source.c_str()); _extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL ); + + + if (osg::getNotifyLevel()>=osg::INFO) + { + std::string sourceWithLineNumbers = insertLineNumbers(_defineStr+source); + OSG_INFO << "\nCompiling C: " << _shader->getTypename() + << " source:\n" << sourceWithLineNumbers << std::endl; + } + + // OSG_NOTICE<<" DefineStr : ["<glCompileShader( _glShaderHandle ); diff --git a/src/osg/State.cpp b/src/osg/State.cpp index c652d4cc6..05933aa30 100644 --- a/src/osg/State.cpp +++ b/src/osg/State.cpp @@ -1216,13 +1216,69 @@ namespace State_Utils source.insert(declPos, qualifier + declarationPrefix + newStr + std::string(";\n")); } } + + void replaceVar(const osg::State& state, std::string& str, std::string::size_type start_pos, std::string::size_type num_chars) + { + std::string var_str(str.substr(start_pos+1, num_chars-1)); + std::string value; + if (state.getActiveDisplaySettings()->getValue(var_str, value)) + { + str.replace(start_pos, num_chars, value); + } + else + { + str.erase(start_pos, num_chars); + } + } + + + void substitudeEnvVars(const osg::State& state, std::string& str) + { + std::string::size_type pos = 0; + while (posgetModifiedCount()) { - applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels); - // update the modified count to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + + applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels); } } @@ -206,13 +206,13 @@ void Texture1D::apply(State& state) const applyTexParameters(GL_TEXTURE_1D,state); + // update the modified count to show that it is upto date. + getModifiedCount(contextID) = _image->getModifiedCount(); + applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels); textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0); - // update the modified count to show that it is up to date. - getModifiedCount(contextID) = _image->getModifiedCount(); - _textureObjectBuffer[contextID] = textureObject; // unref image data? diff --git a/src/osg/Texture2D.cpp b/src/osg/Texture2D.cpp index d73cebc37..1090f64e1 100644 --- a/src/osg/Texture2D.cpp +++ b/src/osg/Texture2D.cpp @@ -202,12 +202,11 @@ void Texture2D::apply(State& state) const } else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) { - applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(), - _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); - // update the modified tag to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(), + _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); } else if (_readPBuffer.valid()) { @@ -224,6 +223,8 @@ void Texture2D::apply(State& state) const applyTexParameters(GL_TEXTURE_2D,state); + if (_image.valid()) getModifiedCount(contextID) = _image->getModifiedCount(); + _subloadCallback->load(*this,state); textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,_borderWidth); @@ -235,7 +236,6 @@ void Texture2D::apply(State& state) const //glBindTexture( GL_TEXTURE_2D, handle ); // update the modified tag to show that it is up to date. - if (_image.valid()) getModifiedCount(contextID) = _image->getModifiedCount(); } else if (_image.valid() && _image->data()) { @@ -255,6 +255,9 @@ void Texture2D::apply(State& state) const applyTexParameters(GL_TEXTURE_2D,state); + // update the modified tag to show that it is up to date. + getModifiedCount(contextID) = image->getModifiedCount(); + if (textureObject->isAllocated() && image->supportsTextureSubloading()) { //OSG_NOTICE<<"Reusing texture object"<setAllocated(true); } - // update the modified tag to show that it is up to date. - getModifiedCount(contextID) = image->getModifiedCount(); - // unref image data? if (isSafeToUnrefImageData(state) && image->getDataVariance()==STATIC) { diff --git a/src/osg/Texture2DArray.cpp b/src/osg/Texture2DArray.cpp index 2f55e596c..b37051167 100644 --- a/src/osg/Texture2DArray.cpp +++ b/src/osg/Texture2DArray.cpp @@ -297,8 +297,8 @@ void Texture2DArray::apply(State& state) const { if (getModifiedCount(n,contextID) != image->getModifiedCount()) { - applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); getModifiedCount(n,contextID) = image->getModifiedCount(); + applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); } n += image->r(); } @@ -380,8 +380,8 @@ void Texture2DArray::apply(State& state) const { if (getModifiedCount(n,contextID) != image->getModifiedCount()) { - applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); getModifiedCount(n,contextID) = image->getModifiedCount(); + applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels); } n += image->r(); } diff --git a/src/osg/Texture3D.cpp b/src/osg/Texture3D.cpp index 68e42fe42..5294b5a38 100644 --- a/src/osg/Texture3D.cpp +++ b/src/osg/Texture3D.cpp @@ -249,12 +249,12 @@ void Texture3D::apply(State& state) const } else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount()) { - computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); - - applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); - // update the modified count to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + + computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); + + applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels); } } @@ -291,6 +291,8 @@ void Texture3D::apply(State& state) const textureObject->bind(); + // update the modified count to show that it is up to date. + getModifiedCount(contextID) = _image->getModifiedCount(); applyTexParameters(GL_TEXTURE_3D,state); @@ -298,9 +300,6 @@ void Texture3D::apply(State& state) const textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0); - // update the modified count to show that it is up to date. - getModifiedCount(contextID) = _image->getModifiedCount(); - // unref image data? if (isSafeToUnrefImageData(state) && _image->getDataVariance()==STATIC) { diff --git a/src/osg/TextureBuffer.cpp b/src/osg/TextureBuffer.cpp index d88646f3a..349b6e0bf 100644 --- a/src/osg/TextureBuffer.cpp +++ b/src/osg/TextureBuffer.cpp @@ -163,6 +163,8 @@ void TextureBuffer::apply(State& state) const const GLExtensions* extensions = state.get(); if(_bufferData.valid() &&_modifiedCount[contextID]!=_bufferData->getModifiedCount() ) { + _modifiedCount[contextID]=_bufferData->getModifiedCount() ; + GLBufferObject* glBufferObject = _bufferData->getBufferObject()->getOrCreateGLBufferObject(contextID); if (glBufferObject) { @@ -174,7 +176,6 @@ void TextureBuffer::apply(State& state) const } - _modifiedCount[contextID]=_bufferData->getModifiedCount() ; } textureObject->bind(); @@ -198,6 +199,8 @@ void TextureBuffer::apply(State& state) const { const GLExtensions* extensions = state.get(); + _modifiedCount[contextID] = _bufferData->getModifiedCount(); + textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_BUFFER); textureObject->_profile._internalFormat=_internalFormat; textureObject->bind(); @@ -221,7 +224,6 @@ void TextureBuffer::apply(State& state) const textureObject->bind(); extensions->glTexBuffer(GL_TEXTURE_BUFFER, _internalFormat, glBufferObject->getGLObjectID()); - _modifiedCount[contextID] = _bufferData->getModifiedCount(); } } diff --git a/src/osg/TextureCubeMap.cpp b/src/osg/TextureCubeMap.cpp index 6e447e2e8..6618958a9 100644 --- a/src/osg/TextureCubeMap.cpp +++ b/src/osg/TextureCubeMap.cpp @@ -246,8 +246,8 @@ void TextureCubeMap::apply(State& state) const const osg::Image* image = _images[n].get(); if (image && getModifiedCount((Face)n,contextID) != image->getModifiedCount()) { - applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); getModifiedCount((Face)n,contextID) = image->getModifiedCount(); + applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); } } } @@ -297,6 +297,7 @@ void TextureCubeMap::apply(State& state) const const osg::Image* image = _images[n].get(); if (image) { + getModifiedCount((Face)n,contextID) = image->getModifiedCount(); if (textureObject->isAllocated()) { applyTexImage2D_subload( state, faceTarget[n], image, _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); @@ -305,7 +306,6 @@ void TextureCubeMap::apply(State& state) const { applyTexImage2D_load( state, faceTarget[n], image, _textureWidth, _textureHeight, _numMipmapLevels); } - getModifiedCount((Face)n,contextID) = image->getModifiedCount(); } diff --git a/src/osg/TextureRectangle.cpp b/src/osg/TextureRectangle.cpp index 87dbf6f9c..4a60e166d 100644 --- a/src/osg/TextureRectangle.cpp +++ b/src/osg/TextureRectangle.cpp @@ -204,10 +204,10 @@ void TextureRectangle::apply(State& state) const } else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) { - applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat); - // update the modified count to show that it is up to date. getModifiedCount(contextID) = _image->getModifiedCount(); + + applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat); } } else if (_subloadCallback.valid()) diff --git a/src/osg/VertexArrayState.cpp b/src/osg/VertexArrayState.cpp index 9f474fc0f..7af9bec4a 100644 --- a/src/osg/VertexArrayState.cpp +++ b/src/osg/VertexArrayState.cpp @@ -118,6 +118,8 @@ struct VertexArrayDispatch : public VertexArrayState::ArrayDispatch { VertexArrayDispatch() {} + virtual const char* className() const { return "VertexArrayDispatch"; } + virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array) { VAS_NOTICE<<" VertexArrayDispatch::enable_and_dispatch("<getNumElements()<<")"<getNumElements()<<")"<getNumElements()<<")"<getNumElements()<<") unit="<getPreserveDataType()) @@ -728,11 +742,13 @@ void VertexArrayState::setArray(ArrayDispatch* vad, osg::State& state, GLint siz } } -void VertexArrayState::setInterleavedArrays( osg::State& state, GLenum format, GLsizei stride, const GLvoid* pointer) +void VertexArrayState::setInterleavedArrays(osg::State& /*state*/, GLenum format, GLsizei stride, const GLvoid* pointer) { #if defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE) - lazyDisablingOfVertexAttributes(); - applyDisablingOfVertexAttributes(state); + unbindVertexBufferObject(); + + //lazyDisablingOfVertexAttributes(); + //applyDisablingOfVertexAttributes(state); glInterleavedArrays( format, stride, pointer); #else diff --git a/src/osg/dxtctool.cpp b/src/osg/dxtctool.cpp index 7e486972a..b8f9ed2b6 100644 --- a/src/osg/dxtctool.cpp +++ b/src/osg/dxtctool.cpp @@ -166,11 +166,28 @@ struct DXT1TexelsBlock unsigned short color_1; // extreme unsigned int texels4x4; // interpolated colors (2 bits per texel) }; - -bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void * imageData) +struct DXT3TexelsBlock { - // OSG_NOTICE<<"CompressedImageTranslucent("<> 2) * ((height + 3) >> 2); switch(format) { case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): @@ -182,9 +199,8 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void // Only do the check on the first mipmap level, and stop when we // see the first alpha texel - int i = (width*height)/16; - bool foundAlpha = false; - while ((!foundAlpha) && (i>0)) + int i = blockCount; + while (i>0) { // See if this block might contain transparent texels if (texelsBlock->color_0<=texelsBlock->color_1) @@ -192,7 +208,7 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void // Scan the texels block for the '11' bit pattern that // indicates a transparent texel int j = 0; - while ((!foundAlpha) && (j < 32)) + while (j < 32) { // Check for the '11' bit pattern on this texel if ( ((texelsBlock->texels4x4 >> j) & 0x03) == 0x03) @@ -214,11 +230,67 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void } case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): - return true; - + { + const DXT3TexelsBlock *texelsBlock = reinterpret_cast(imageData); + // Only do the check on the first mipmap level, and stop when we see the first alpha texel + int i = blockCount; + while (i>0) + { + for (int j =0; j < 4; ++j) + if ( texelsBlock->alpha4[j] != 0xFFFF) //4 pixels at once + return true; //not fully opaque + // Next block + --i; + ++texelsBlock; + } + return false; + } case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT): - return true; + { + const DXT5TexelsBlock *texelsBlock = reinterpret_cast(imageData); + // Only do the check on the first mipmap level, and stop when we see the first alpha texel + int i = blockCount; + unsigned char alphaBlock[8]; + while (i>0) + { + bool eightStep = texelsBlock->alpha_0 > texelsBlock->alpha_1; + alphaBlock[0] = texelsBlock->alpha_0; + alphaBlock[1] = texelsBlock->alpha_1; + if (eightStep) { + if (texelsBlock->alpha_0 < 255) return true; //not fully opaque + alphaBlock[2] = (6 * alphaBlock[0] + 1 * alphaBlock[1] + 3) / 7; // bit code 010 + alphaBlock[3] = (5 * alphaBlock[0] + 2 * alphaBlock[1] + 3) / 7; // bit code 011 + alphaBlock[4] = (4 * alphaBlock[0] + 3 * alphaBlock[1] + 3) / 7; // bit code 100 + alphaBlock[5] = (3 * alphaBlock[0] + 4 * alphaBlock[1] + 3) / 7; // bit code 101 + alphaBlock[6] = (2 * alphaBlock[0] + 5 * alphaBlock[1] + 3) / 7; // bit code 110 + alphaBlock[7] = (1 * alphaBlock[0] + 6 * alphaBlock[1] + 3) / 7; // bit code 111 + } else { + alphaBlock[2] = (4 * alphaBlock[0] + 1 * alphaBlock[1] + 2) / 5; // bit code 010 + alphaBlock[3] = (3 * alphaBlock[0] + 2 * alphaBlock[1] + 2) / 5; // bit code 011 + alphaBlock[4] = (2 * alphaBlock[0] + 3 * alphaBlock[1] + 2) / 5; // bit code 100 + alphaBlock[5] = (1 * alphaBlock[0] + 4 * alphaBlock[1] + 2) / 5; // bit code 101 + alphaBlock[6] = 0; // bit code 110 + alphaBlock[7] = 255; // bit code 111 + } + int last_added_byte = 1; + unsigned short running_a_index = texelsBlock->alpha3[0] + (((unsigned short)texelsBlock->alpha3[last_added_byte]) << 8); + for (int j = 0; j < 16; ++j) { + unsigned char alphaIndex = running_a_index & 0x7; + if (alphaBlock[alphaIndex] < 255) return true; //not fully opaque + running_a_index >>= 3; + if ((3 * j / 8) == last_added_byte) { + ++last_added_byte; + //(&texelsBlock->alpha3[0]) to avoid gcc warning: array subscript is above array bounds [-Warray-bounds] + running_a_index += (((unsigned short)(&(texelsBlock->alpha3[0]))[last_added_byte]) << (8 - (3 * j & 0x7))); + } + } + // Next block + --i; + ++texelsBlock; + } + return false; + } default: break; } @@ -226,4 +298,361 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void return false; } +unsigned short interpolateColors21(unsigned short color1, unsigned short color2) { + unsigned short result = (((color1 >> 11) * 2 + (color2 >> 11) + 1) / 3) << 11; + result += (((color1 >> 5 & 0x3F) * 2 + (color2 >> 5 & 0x3F) + 1) / 3) << 5; + result += (((color1 & 0x1F) * 2 + (color2 & 0x1F) + 1) / 3); + return result; +} +unsigned short interpolateColors11(unsigned short color1, unsigned short color2) { + unsigned short result = (((color1 >> 11) + (color2 >> 11) ) / 2) << 11; + result += (((color1 >> 5 & 0x3F) + (color2 >> 5 & 0x3F)) / 2) << 5; + result += (((color1 & 0x1F) + (color2 & 0x1F) ) / 2); + return result; +} + +bool CompressedImageGetColor(unsigned char color[4], unsigned int s, unsigned int t, unsigned int r, int width, int height, int depth, GLenum format, unsigned char *imageData) +{ + unsigned short color16 = 0;//RGB 5:6:5 format + + + unsigned int slab4Count = (depth & ~0x3); //4*floor(d/4) + unsigned int col = (s >> 2);//(floor(x/4) + unsigned int row = (t >> 2);//(floor(y/4) + unsigned int blockWidth = (width + 3) >> 2;//ceil(w/4) + unsigned int blockHeight = (height + 3) >> 2;//ceil(h/4) + int blockNumber = col + blockWidth * row ; // block to jump to + + if (depth > 1) { +// https://www.opengl.org/registry/specs/NV/texture_compression_vtc.txt +// if (z >= 4*floor(d/4)) { +// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * (z-4*floor(d/4)) )); +// } else { +// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4))); +// } +// note floor(a/4) = (a >> 2) +// note 4*floor(a/4) = a & ~0x3 +// note ceil(a/4) = ((a + 3) >> 2) +// +// rewrite: this describes the final blocks as consecutive 4x4x1 blocks - and thats not in the wording of the specs +// if (r >= slab4Count) { +// blockNumber = (blockWidth * blockHeight * slab4Count + col + blockWidth * (row + blockHeight * (r-slab4Count) )); +// } else { +// blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) ); +// } + +// or in the version of the openGL specs: +// if (z >= 4*floor(d/4)) { +// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + (z - 4*floor(d/4)) * ( (floor(x/4) + ceil(w/4) * (floor(y/4) ); +// } else { +// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4))); +// } + + unsigned int sub_r = r & 0x3;//(r-slab4Count) + if (r >= slab4Count) { //slice number beyond 4x4x4 slabs + unsigned int blockDepth = depth & 0x3;// equals: depth - slab4Count;//depth of this final block: 1/2/3 in case of 4x4x1; 4x4x2 or 4x4x3 bricks + blockNumber = (blockWidth * blockHeight * slab4Count //jump full 4x4x4 slabs + + blockDepth * ( col + blockWidth * row ) + + sub_r); + } else { + blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) ) + sub_r; + } + } + + int sub_s = s & 0x3; + int sub_t = t & 0x3; + switch (format) + { + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : + { + const DXT1TexelsBlock *texelsBlock = reinterpret_cast(imageData); + texelsBlock += blockNumber; //jump to block + char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" + color[3] = 255; + switch (index) { + case 0: + color16 = texelsBlock->color_0; + break; + case 1: + color16 = texelsBlock->color_1; + break; + case 2: + if (texelsBlock->color_0 > texelsBlock->color_1) { + color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); + } + else { + color16 = interpolateColors11(texelsBlock->color_0, texelsBlock->color_1); + } + break; + case 3: + if (texelsBlock->color_0 > texelsBlock->color_1) { + color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); + } + else { + color16 = 0;//black + if (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) color[3] = 0;//transparent + } + break; + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : + { + const DXT3TexelsBlock *texelsBlock = reinterpret_cast(imageData); + texelsBlock += blockNumber; //jump to block + color[3] = 17 * (texelsBlock->alpha4[sub_t] >> 4 * sub_s & 0xF); + char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" + switch (index) { + case 0: + color16 = texelsBlock->color_0; + break; + case 1: + color16 = texelsBlock->color_1; + break; + case 2: + color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); + break; + case 3: + color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); + break; + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : + { + const DXT5TexelsBlock *texelsBlock = reinterpret_cast(imageData); + texelsBlock += blockNumber; //jump to block + char index = (texelsBlock->texels4x4 >> (2 * sub_s + 8 * sub_t)) & 0x3; //two bit "index value" + switch (index) { + case 0: + color16 = texelsBlock->color_0; + break; + case 1: + color16 = texelsBlock->color_1; + break; + case 2: + color16 = interpolateColors21(texelsBlock->color_0, texelsBlock->color_1); + break; + case 3: + color16 = interpolateColors21(texelsBlock->color_1, texelsBlock->color_0); + break; + } + char pixel = sub_s + 4 * sub_t;//pixel number in block: 0 - 15 + char firstBit = 3 * pixel;//least significant bit: range 0 - 45 + unsigned char alpha_index; + if ((firstBit & 0x7) < 6) { + alpha_index = texelsBlock->alpha3[firstBit >> 3] >> (firstBit & 0x7) & 0x7;//grab byte containing least significant bit; shift and get 3 bits + } else { + alpha_index = texelsBlock->alpha3[firstBit >> 3] >> (firstBit & 0x7); + alpha_index |= texelsBlock->alpha3[1 + (firstBit >> 3)] << (8 - (firstBit & 0x7)); + alpha_index &= 0x7; + } + if (alpha_index == 0) { + color[3] = texelsBlock->alpha_0; + } else { + if (alpha_index == 1) { + color[3] = texelsBlock->alpha_1; + } else { + if (texelsBlock->alpha_0 > texelsBlock->alpha_1) { + color[3] = ((unsigned short)texelsBlock->alpha_0 * (8 - alpha_index) + (unsigned short)texelsBlock->alpha_1 * (alpha_index - 1) + 3) / 7; + } else { + if (alpha_index < 6) { + color[3] = ((unsigned short)texelsBlock->alpha_0 * (6 - alpha_index) + (unsigned short)texelsBlock->alpha_1 * (alpha_index - 1) + 3) / 5; + } else { + if (alpha_index == 6) { + color[3] = 0; + } else { + color[3] = 255; + } + } + } + } + } + break; + } + default: + return false; + } + unsigned short colorChannel = color16 >> 11;//red - 5 bits + color[0] = colorChannel << 3 | colorChannel >> 2 ; + colorChannel = color16 >> 5 & 0x3F;//green - 6 bits + color[1] = colorChannel << 2 | colorChannel >> 3; + colorChannel = color16 & 0x1F;//blue - 5 bits + color[2] = colorChannel << 3 | colorChannel >> 2; + return true; +} +void compressedBlockOrientationConversion(const GLenum format, const unsigned char *src_block, unsigned char *dst_block, const osg::Vec3i& srcOrigin, const osg::Vec3i& rowDelta, const osg::Vec3i& columnDelta) +{ + unsigned int src_texels4x4; + unsigned int *dst_texels4x4 = NULL; + switch (format) + { + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : + { + const DXT1TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + dst_texels4x4 = &dst_texelsBlock->texels4x4; + + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : + { + const DXT3TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT3TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + dst_texels4x4 = &dst_texelsBlock->texels4x4; + unsigned short src_alpha4[4]; // alpha values (4 bits per texel) - 64 bits + + memcpy(src_alpha4, src_texelsBlock->alpha4, 4 * sizeof(unsigned short));//make a copy as source might be equal to destination + + memset(dst_texelsBlock->alpha4, 0, 4 * sizeof(unsigned short)); //clear + osg::Vec3i source_pixel(srcOrigin); + for (int r = 0; r<4; r++)//rows + { + for (int c = 0; c<4; c++)//columns + { + int sub_s = source_pixel.x() & 0x3; + int sub_t = source_pixel.y() & 0x3; + int shiftBits = 4 * sub_s; + unsigned int alpha_value = src_alpha4[sub_t] >> shiftBits & 0xf; //four bit alpha values + + shiftBits = 4 * c;//destination + alpha_value <<= shiftBits; + dst_texelsBlock->alpha4[r] |= alpha_value; + + source_pixel = source_pixel + rowDelta; + } + source_pixel = source_pixel + columnDelta; + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : + { + const DXT5TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT5TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + dst_texels4x4 = &dst_texelsBlock->texels4x4; + + unsigned char src_alpha3[6]; // alpha index values (3 bits per texel) + + memcpy(src_alpha3, src_texelsBlock->alpha3, 6 * sizeof(unsigned char));//make a copy as source might be equal to destination + + memset(dst_texelsBlock->alpha3, 0, 6 * sizeof(unsigned char)); //clear + osg::Vec3i source_pixel(srcOrigin); + unsigned int last_added_byte = 1; + unsigned short running_a_index = src_texelsBlock->alpha3[0] + (((unsigned short)src_texelsBlock->alpha3[last_added_byte]) << 8); + unsigned int j = 0; + for (int r = 0; r<4; r++)//rows + { + for (int c = 0; c<4; c++)//columns + { + int sub_s = source_pixel.x() & 0x3; + int sub_t = source_pixel.y() & 0x3; + + unsigned char alphaIndex = running_a_index & 0x7; + //store alphaIndex in output position: + int shiftBits = 3 * sub_s + 12 * sub_t;//LSB + dst_texelsBlock->alpha3[shiftBits >> 3] |= alphaIndex << (shiftBits & 0x7); + if ((shiftBits & 0x7) > 5) { + dst_texelsBlock->alpha3[1 + (shiftBits >> 3)] |= alphaIndex >> (8 - (shiftBits & 0x7)); + } + + running_a_index >>= 3; + if ((3 * ++j / 8) == last_added_byte) { + ++last_added_byte; + //(&texelsBlock->alpha3[0]) to avoid gcc warning: array subscript is above array bounds [-Warray-bounds] + running_a_index += (((unsigned short)(&(src_texelsBlock->alpha3[0]))[last_added_byte]) << (8 - (3 * j & 0x7))); + } + source_pixel = source_pixel + rowDelta; + } + source_pixel = source_pixel + columnDelta; + } + break; + } + default: + return; + }//switch + + //all formats: rearrange the colors + *dst_texels4x4 = 0;//clear + osg::Vec3i source_pixel(srcOrigin); + for (int r = 0; r<4; r++)//rows + { + for (int c = 0; c<4; c++)//columns + { + int sub_s = source_pixel.x() & 0x3; + int sub_t = source_pixel.y() & 0x3; + int shiftBits = 2 * sub_s + 8 * sub_t; + unsigned int index = (src_texels4x4 >> (shiftBits)) & 0x3; //two bit "index value" + + shiftBits = 2 * c + 8 * r;//destination + index <<= shiftBits; + *dst_texels4x4 |= index; + + source_pixel = source_pixel + rowDelta; + } + source_pixel = source_pixel + columnDelta; + } +} + +void compressedBlockStripAlhpa(const GLenum format, const unsigned char *src_block, unsigned char *dst_block) { + unsigned int src_texels4x4; + char reshuffle[4] = { 1, 0, 3, 2 }; + switch (format) + { + default: + case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) : + { + const DXT1TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + if (src_texelsBlock->color_0 > src_texelsBlock->color_1) { + // Four-color block + memcpy(dst_texelsBlock, src_texelsBlock, sizeof(DXT1TexelsBlock)); + } else { + dst_texelsBlock->color_0 = src_texelsBlock->color_1; + dst_texelsBlock->color_1 = src_texelsBlock->color_0; + dst_texelsBlock->texels4x4 = 0; + for (unsigned int shiftBits = 0; shiftBits < 32; shiftBits += 2) { + unsigned char index = src_texels4x4 >> shiftBits & 0x3; //two bit "index value" + dst_texelsBlock->texels4x4 |= reshuffle[index] << shiftBits; + } + + } + break; + } + case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) : + case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) : + { + const DXT3TexelsBlock *src_texelsBlock = reinterpret_cast(src_block); + //make a copy as source might be equal to destination + src_texels4x4 = src_texelsBlock->texels4x4; // interpolated colors (2 bits per texel) + DXT1TexelsBlock *dst_texelsBlock = reinterpret_cast(dst_block); + if (src_texelsBlock->color_0 > src_texelsBlock->color_1) { + // Four-color block + memcpy(dst_texelsBlock, src_texelsBlock, sizeof(DXT3TexelsBlock)); + } + else { + dst_texelsBlock->color_0 = src_texelsBlock->color_1; + dst_texelsBlock->color_1 = src_texelsBlock->color_0; + dst_texelsBlock->texels4x4 = 0; + for (unsigned int shiftBits = 0; shiftBits < 32; shiftBits += 2) { + unsigned char index = src_texels4x4 >> shiftBits & 0x3; //two bit "index value" + dst_texelsBlock->texels4x4 |= reshuffle[index] << shiftBits; + + } + + } + break; + } + } +} } // namespace dxtc_tool diff --git a/src/osg/dxtctool.h b/src/osg/dxtctool.h index f24cf9c90..304399d99 100644 --- a/src/osg/dxtctool.h +++ b/src/osg/dxtctool.h @@ -31,17 +31,18 @@ // Current version: 1.00 BETA 1 (27/08/2002) // // Comment: Only works with DXTC mode supported by OpenGL. -// (currently: DXT1/DXT3/DXT5) +// (currently: DXT1/DXT3/DXT5) // // History: - // ////////////////////////////////////////////////////////////////////// #ifndef DXTCTOOL_H -#define DXTCTOOL_H +#define DXTCTOOL_H #include #include +#include #if defined(_MSC_VER) @@ -78,10 +79,19 @@ bool isDXTC(GLenum pixelFormat); bool VerticalFlip(size_t Width, size_t Height, GLenum Format, void * pPixels); -bool CompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels); +bool isCompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels); +//interpolate RGB565 colors with 2/3 part color1 and 1/3 part color2 +unsigned short interpolateColors21(unsigned short color1, unsigned short color2); +//interpolate RGB565 colors with equal weights +unsigned short interpolateColors11(unsigned short color1, unsigned short color2); -// Class holding reference to DXTC image pixels +bool CompressedImageGetColor(unsigned char color[4], unsigned int s, unsigned int t, unsigned int r, int width, int height, int depth, GLenum format, unsigned char *imageData); + +void compressedBlockOrientationConversion(const GLenum format, const unsigned char *src_block, unsigned char *dst_block, const osg::Vec3i& srcOrigin, const osg::Vec3i& rowDelta, const osg::Vec3i& columnDelta); + +void compressedBlockStripAlhpa(const GLenum format, const unsigned char *src_block, unsigned char *dst_block); +// Class holding reference to DXTC image pixels class dxtc_pixels { public: @@ -102,7 +112,7 @@ protected: inline bool SupportedFormat() const; // Vertical flipping functions - void VFlip_DXT1() const; + void VFlip_DXT1() const; void VFlip_DXT3() const; void VFlip_DXT5() const; @@ -116,7 +126,7 @@ protected: inline void BVF_Alpha_DXT5_H2(void * const pBlock) const; // V. flip one alpha (DXT5) block with its virtual height == 2 inline void BVF_Alpha_DXT5_H4(void * const pBlock) const; // V. flip one alpha (DXT5) block with its virtual height == 4 inline void BVF_Alpha_DXT5(void * const pBlock1, void * const pBlock2) const; // V. flip and swap two alpha (DXT5) blocks, with their virtual height == 4 - + // Block localization functions inline void * GetBlock(size_t i, size_t j, size_t BlockSize) const; @@ -155,7 +165,7 @@ inline bool isDXTC(GLenum pixelFormat) } inline bool VerticalFlip(size_t Width, size_t Height, GLenum Format, void * pPixels) { - return (dxtc_pixels(Width, Height, Format, pPixels)).VFlip(); + return (dxtc_pixels(Width, Height, Format, pPixels)).VFlip(); } diff --git a/src/osgDB/StreamOperator.cpp b/src/osgDB/StreamOperator.cpp index a1ee9a749..d46eef4e9 100644 --- a/src/osgDB/StreamOperator.cpp +++ b/src/osgDB/StreamOperator.cpp @@ -16,21 +16,14 @@ using namespace osgDB; -static long long prev_tellg = 0; - void InputIterator::checkStream() const { if (_in->rdstate()&_in->failbit) { OSG_NOTICE<<"InputIterator::checkStream() : _in->rdstate() "<<_in->rdstate()<<", "<<_in->failbit<tellg() = "<<_in->tellg()<getTextureWidthHint()-2*margin; - height = _facade->getTextureHeightHint()-2*margin; - - OSG_WARN<<" sizes capped ("< glyph = new osgText::Glyph(_facade, charcode); + glyph->setFontResolution(fontRes); + unsigned int dataSize = width*height; unsigned char* data = new unsigned char[dataSize]; @@ -359,14 +348,12 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u for(unsigned char* p=data;psetImage(width,height,1, - OSGTEXT_GLYPH_INTERNALFORMAT, - OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, + GL_ALPHA, + GL_ALPHA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1); - glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT); - // copy image across to osgText::Glyph image. switch(glyphslot->bitmap.pixel_mode) { diff --git a/src/osgPlugins/ive/Text.cpp b/src/osgPlugins/ive/Text.cpp index ae9da298f..0139695c5 100644 --- a/src/osgPlugins/ive/Text.cpp +++ b/src/osgPlugins/ive/Text.cpp @@ -90,7 +90,7 @@ void Text::write(DataOutputStream* out){ out->writeFloat(getBackdropVerticalOffset()); out->writeVec4(getBackdropColor()); - out->writeUInt(getBackdropImplementation()); + out->writeUInt(4); // old DELAYED_DEPTH_WRITES out->writeUInt(getColorGradientMode()); out->writeVec4(getColorGradientTopLeft()); @@ -213,7 +213,7 @@ void Text::read(DataInputStream* in){ setBackdropOffset(horizontalOffset,verticalOffset); setBackdropColor(in->readVec4()); - setBackdropImplementation((osgText::Text::BackdropImplementation) in->readUInt()); + in->readUInt(); // read old BackdropImplementation value, no longer used setColorGradientMode((osgText::Text::ColorGradientMode) in->readUInt()); osg::Vec4 colorGradientTopLeft,colorGradientBottomLeft,colorGradientBottomRight,colorGradientTopRight; diff --git a/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp b/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp index 74dda31ea..3437a60b9 100644 --- a/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp +++ b/src/osgPlugins/obj/OBJWriterNodeVisitor.cpp @@ -546,27 +546,27 @@ void OBJWriterNodeVisitor::processGeometry(osg::Geometry* geo, osg::Matrix& m) { } +void OBJWriterNodeVisitor::apply(osg::Geometry& geometry) +{ + osg::Matrix m = osg::computeLocalToWorld(getNodePath()); + + pushStateSet(geometry.getStateSet()); + + processGeometry(&geometry,m); + + popStateSet(geometry.getStateSet()); +} + void OBJWriterNodeVisitor::apply( osg::Geode &node ) { - pushStateSet(node.getStateSet()); _nameStack.push_back(node.getName()); - osg::Matrix m = osg::computeLocalToWorld(getNodePath()); unsigned int count = node.getNumDrawables(); for ( unsigned int i = 0; i < count; i++ ) { - osg::Geometry *g = node.getDrawable( i )->asGeometry(); - if ( g != NULL ) - { - pushStateSet(g->getStateSet()); - - processGeometry(g,m); - - popStateSet(g->getStateSet()); - } + node.getDrawable( i )->accept(*this); } - popStateSet(node.getStateSet()); _nameStack.pop_back(); } diff --git a/src/osgPlugins/obj/OBJWriterNodeVisitor.h b/src/osgPlugins/obj/OBJWriterNodeVisitor.h index be4c8cabd..8dc16a0d5 100644 --- a/src/osgPlugins/obj/OBJWriterNodeVisitor.h +++ b/src/osgPlugins/obj/OBJWriterNodeVisitor.h @@ -65,9 +65,10 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor { } } - virtual void apply(osg::Geode &node); + virtual void apply(osg::Geometry & geometry); + virtual void apply(osg::Geode & node); - virtual void apply(osg::Group &node) + virtual void apply(osg::Group & node) { pushStateSet(node.getStateSet()); _nameStack.push_back( node.getName().empty() ? node.className() : node.getName() ); @@ -78,14 +79,6 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor { traverse( node ); _nameStack.pop_back(); - popStateSet(node.getStateSet()); - } - - void traverse (osg::Node &node) - { - pushStateSet(node.getStateSet()); - - osg::NodeVisitor::traverse( node ); popStateSet(node.getStateSet()); } diff --git a/src/osgPlugins/obj/ReaderWriterOBJ.cpp b/src/osgPlugins/obj/ReaderWriterOBJ.cpp index 5c14abddf..137996ea8 100644 --- a/src/osgPlugins/obj/ReaderWriterOBJ.cpp +++ b/src/osgPlugins/obj/ReaderWriterOBJ.cpp @@ -142,7 +142,8 @@ public: protected: - struct ObjOptionsStruct { + class ObjOptionsStruct { + public: bool rotate; bool noTesselateLargePolygons; bool noTriStripPolygons; @@ -155,6 +156,17 @@ protected: TextureAllocationMap textureUnitAllocation; /// Coordinates precision. int precision; + + ObjOptionsStruct() + { + rotate = true; + noTesselateLargePolygons = false; + noTriStripPolygons = false; + generateFacetNormals = false; + fixBlackMaterials = true; + noReverseFaces = false; + precision = std::numeric_limits::digits10 + 2; + } }; typedef std::map< std::string, osg::ref_ptr > MaterialToStateSetMap; @@ -831,13 +843,6 @@ osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptio ReaderWriterOBJ::ObjOptionsStruct ReaderWriterOBJ::parseOptions(const osgDB::ReaderWriter::Options* options) const { ObjOptionsStruct localOptions; - localOptions.rotate = true; - localOptions.noTesselateLargePolygons = false; - localOptions.noTriStripPolygons = false; - localOptions.generateFacetNormals = false; - localOptions.fixBlackMaterials = true; - localOptions.noReverseFaces = false; - localOptions.precision = std::numeric_limits::digits10 + 2; if (options!=NULL) { diff --git a/src/osgPlugins/ply/vertexData.cpp b/src/osgPlugins/ply/vertexData.cpp index 00ce08758..faeca766b 100644 --- a/src/osgPlugins/ply/vertexData.cpp +++ b/src/osgPlugins/ply/vertexData.cpp @@ -546,7 +546,7 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor } else if (_texcoord.valid()) { - geom->setTexCoordArray(0, _texcoord); + geom->setTexCoordArray(0, _texcoord.get()); } // If the model has normals, add them to the geometry diff --git a/src/osgPlugins/png/ReaderWriterPNG.cpp b/src/osgPlugins/png/ReaderWriterPNG.cpp index 8190a4b4d..fdd2a891b 100644 --- a/src/osgPlugins/png/ReaderWriterPNG.cpp +++ b/src/osgPlugins/png/ReaderWriterPNG.cpp @@ -307,6 +307,18 @@ class ReaderWriterPNG : public osgDB::ReaderWriter pixelFormat = GL_RGBA; int internalFormat = pixelFormat; + if (depth > 8) + { + switch(color) + { + case(GL_LUMINANCE): internalFormat = GL_LUMINANCE16; break; + case(GL_ALPHA): internalFormat = GL_ALPHA16; break; + case(GL_LUMINANCE_ALPHA): internalFormat = GL_LUMINANCE16_ALPHA16; break; + case(GL_RGB): internalFormat = GL_RGB16; break; + case(GL_RGBA): internalFormat = GL_RGBA16; break; + default: break; + } + } png_destroy_read_struct(&png, &info, &endinfo); diff --git a/src/osgPlugins/vnc/ReaderWriterVNC.cpp b/src/osgPlugins/vnc/ReaderWriterVNC.cpp index 6da3ccbc3..ce68fd688 100644 --- a/src/osgPlugins/vnc/ReaderWriterVNC.cpp +++ b/src/osgPlugins/vnc/ReaderWriterVNC.cpp @@ -398,17 +398,26 @@ class ReaderWriterVNC : public osgDB::ReaderWriter options->getAuthenticationMap() : osgDB::Registry::instance()->getAuthenticationMap(); - const osgDB::AuthenticationDetails* details = authenticationMap ? - authenticationMap->getAuthenticationDetails(hostname) : - 0; - - // configure authentication if required. - if (details) + if (authenticationMap != NULL) { - OSG_NOTICE<<"Passing in password = "<password<getAuthenticationDetails(hostname); + if (details == NULL) + { + size_t pos = hostname.find(":"); + if (pos != std::string::npos) + { + details = authenticationMap->getAuthenticationDetails(hostname.substr(0, pos)); + } + } - image->_username = details->username; - image->_password = details->password; + // configure authentication if required. + if (details != NULL) + { + OSG_NOTICE << "Passing in password = " << details->password << std::endl; + + image->_username = details->username; + image->_password = details->password; + } } if (options && !options->getOptionString().empty()) diff --git a/src/osgTerrain/GeometryPool.cpp b/src/osgTerrain/GeometryPool.cpp index c7fb3c5f8..e028aa99d 100644 --- a/src/osgTerrain/GeometryPool.cpp +++ b/src/osgTerrain/GeometryPool.cpp @@ -554,7 +554,10 @@ osg::ref_ptr GeometryPool::getOrCreateProgram(LayerTypes& layerTyp _programMap[layerTypes] = program; // add shader that provides the lighting functions - program->addShader(osgDB::readRefShaderFile("shaders/lighting.vert")); + { + #include "shaders/lighting_vert.cpp" + program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/lighting.vert", lighting_vert)); + } // OSG_NOTICE<<") creating new Program "< 0.0 )\n" + " color += gl_FrontLightProduct[lightNum].specular * pow( NdotHV, gl_FrontMaterial.shininess );\n" + "#endif\n" + "}\n" + "\n"; diff --git a/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp b/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp index b3b0ce5d9..a052d4dc1 100644 --- a/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp +++ b/src/osgTerrain/shaders/terrain_displacement_mapping_vert.cpp @@ -125,5 +125,5 @@ char terrain_displacement_mapping_vert[] = "#version 120\n" " vec3 position = gl_Vertex.xyz + gl_Normal.xyz * height_center;\n" " gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n" "\n" - "};\n" + "}\n" "\n"; diff --git a/src/osgText/DefaultFont.cpp b/src/osgText/DefaultFont.cpp index cf0b55cc4..dfc9b5945 100644 --- a/src/osgText/DefaultFont.cpp +++ b/src/osgText/DefaultFont.cpp @@ -24,8 +24,11 @@ using namespace osgText; DefaultFont::DefaultFont() { + _fontSize = FontResolution(8,12); + _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; - _magFilterHint = osg::Texture::NEAREST; + _magFilterHint = osg::Texture::LINEAR; + constructGlyphs(); } @@ -198,14 +201,12 @@ void DefaultFont::constructGlyphs() for(unsigned char* p=data;psetImage(sourceWidth,sourceHeight,1, - OSGTEXT_GLYPH_INTERNALFORMAT, - OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, + GL_ALPHA, + GL_ALPHA, GL_UNSIGNED_BYTE, data, osg::Image::USE_NEW_DELETE, 1); - glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT); - // now populate data array by converting bitmap into a luminance_alpha map. unsigned char* ptr = rasters[i-32]; unsigned char value_on = 255; @@ -233,6 +234,8 @@ void DefaultFont::constructGlyphs() glyph->setVerticalBearing(osg::Vec2(0.5f,1.0f)); // top middle. glyph->setVerticalAdvance(sourceHeight*coord_scale); + glyph->setFontResolution(fontRes); + addGlyph(fontRes,i,glyph.get()); } } diff --git a/src/osgText/Font.cpp b/src/osgText/Font.cpp index c06392640..599dd6f6e 100644 --- a/src/osgText/Font.cpp +++ b/src/osgText/Font.cpp @@ -32,81 +32,6 @@ using namespace osgText; using namespace std; -#if (!defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GLES3_AVAILABLE)) - #define GLSL_VERSION_STR "330 core" - #define GLYPH_CMP "r" -#else - #define GLSL_VERSION_STR "300 es" - #define GLYPH_CMP "a" -#endif - -static const char* gl3_TextVertexShader = { - "#version " GLSL_VERSION_STR "\n" - "// gl3_TextVertexShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "in vec4 osg_Vertex;\n" - "in vec4 osg_Color;\n" - "in vec4 osg_MultiTexCoord0;\n" - "uniform mat4 osg_ModelViewProjectionMatrix;\n" - "out vec2 texCoord;\n" - "out vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n" - " texCoord = osg_MultiTexCoord0.xy;\n" - " vertexColor = osg_Color; \n" - "}\n" -}; - -static const char* gl3_TextFragmentShader = { - "#version " GLSL_VERSION_STR "\n" - "// gl3_TextFragmentShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "uniform sampler2D glyphTexture;\n" - "in vec2 texCoord;\n" - "in vec4 vertexColor;\n" - "out vec4 color;\n" - "void main(void)\n" - "{\n" - " if (texCoord.x>=0.0) color = vertexColor * vec4(1.0, 1.0, 1.0, texture(glyphTexture, texCoord)." GLYPH_CMP ");\n" - " else color = vertexColor;\n" - "}\n" -}; - -static const char* gl2_TextVertexShader = { - "// gl2_TextVertexShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "varying vec2 texCoord;\n" - "varying vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" - " texCoord = gl_MultiTexCoord0.xy;\n" - " vertexColor = gl_Color; \n" - "}\n" -}; - -static const char* gl2_TextFragmentShader = { - "// gl2_TextFragmentShader\n" - "#ifdef GL_ES\n" - " precision highp float;\n" - "#endif\n" - "uniform sampler2D glyphTexture;\n" - "varying vec2 texCoord;\n" - "varying vec4 vertexColor;\n" - "void main(void)\n" - "{\n" - " if (texCoord.x>=0.0) gl_FragColor = vertexColor * vec4(1.0, 1.0, 1.0, texture2D(glyphTexture, texCoord).a);\n" - " else gl_FragColor = vertexColor;\n" - "}\n" -}; - osg::ref_ptr& Font::getDefaultFont() { static OpenThreads::Mutex s_DefaultFontMutex; @@ -299,67 +224,24 @@ osg::ref_ptr osgText::readRefFontStream(std::istream& stream, const osgDB: Font::Font(FontImplementation* implementation): osg::Object(true), - _margin(1), - _marginRatio(0.02), _textureWidthHint(1024), _textureHeightHint(1024), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), _magFilterHint(osg::Texture::LINEAR), + _maxAnisotropy(16), _depth(1), _numCurveSamples(10) { setImplementation(implementation); - _texenv = new osg::TexEnv; - _stateset = new osg::StateSet; - - _stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); - _stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); - _stateset->setMode(GL_BLEND, osg::StateAttribute::ON); - -#if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) - - OSG_INFO<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); -#endif - - osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); - if (shaderHint==osg::DisplaySettings::SHADER_GL3 || shaderHint==osg::DisplaySettings::SHADER_GLES3) - { - - OSG_INFO<<"Font::Font() Setting up GL3 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl3_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl3_TextFragmentShader)); - _stateset->setAttributeAndModes(program.get()); - _stateset->addUniform(new osg::Uniform("glyphTexture", 0)); - - } - else if (shaderHint==osg::DisplaySettings::SHADER_GL2 || shaderHint==osg::DisplaySettings::SHADER_GLES2) - { - - - OSG_INFO<<"Font::Font() Setting up GL2 compatible shaders"< program = new osg::Program; - program->addShader(new osg::Shader(osg::Shader::VERTEX, gl2_TextVertexShader)); - program->addShader(new osg::Shader(osg::Shader::FRAGMENT, gl2_TextFragmentShader)); - _stateset->setAttributeAndModes(program.get()); - _stateset->addUniform(new osg::Uniform("glyphTexture", 0)); - - } - char *ptr; - if( (ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) + if ((ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0) { unsigned int osg_max_size = atoi(ptr); if (osg_max_size<_textureWidthHint) _textureWidthHint = osg_max_size; if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size; } - } Font::~Font() @@ -390,26 +272,6 @@ std::string Font::getFileName() const return std::string(); } -void Font::setGlyphImageMargin(unsigned int margin) -{ - _margin = margin; -} - -unsigned int Font::getGlyphImageMargin() const -{ - return _margin; -} - -void Font::setGlyphImageMarginRatio(float ratio) -{ - _marginRatio = ratio; -} - -float Font::getGlyphImageMarginRatio() const -{ - return _marginRatio; -} - void Font::setTextureSizeHint(unsigned int width,unsigned int height) { _textureWidthHint = width; @@ -518,9 +380,6 @@ void Font::setThreadSafeRefUnref(bool threadSafe) { osg::Object::setThreadSafeRefUnref(threadSafe); - if (_texenv.valid()) _texenv->setThreadSafeRefUnref(threadSafe); - if (_stateset.valid()) _stateset->setThreadSafeRefUnref(threadSafe); - for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); ++itr) @@ -531,7 +390,12 @@ void Font::setThreadSafeRefUnref(bool threadSafe) void Font::resizeGLObjectBuffers(unsigned int maxSize) { - if (_stateset.valid()) _stateset->resizeGLObjectBuffers(maxSize); + for(StateSets::iterator itr = _statesets.begin(); + itr != _statesets.end(); + ++itr) + { + (*itr)->resizeGLObjectBuffers(maxSize); + } for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); @@ -543,7 +407,12 @@ void Font::resizeGLObjectBuffers(unsigned int maxSize) void Font::releaseGLObjects(osg::State* state) const { - if (_stateset.valid()) _stateset->releaseGLObjects(state); + for(StateSets::const_iterator itr = _statesets.begin(); + itr != _statesets.end(); + ++itr) + { + (*itr)->releaseGLObjects(state); + } for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); itr!=_glyphTextureList.end(); @@ -576,6 +445,10 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* _sizeGlyphMap[fontRes][charcode]=glyph; +} + +void Font::assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique) +{ int posX=0,posY=0; GlyphTexture* glyphTexture = 0; @@ -583,12 +456,12 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* itr!=_glyphTextureList.end() && !glyphTexture; ++itr) { - if ((*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get(); + if ((*itr)->getShaderTechnique()==shaderTechnique && (*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get(); } if (glyphTexture) { - //cout << " found space for texture "<setGlyphImageMargin(_margin); - glyphTexture->setGlyphImageMarginRatio(_marginRatio); + glyphTexture->setShaderTechnique(shaderTechnique); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); - glyphTexture->setMaxAnisotropy(8); + glyphTexture->setMaxAnisotropy(_maxAnisotropy); _glyphTextureList.push_back(glyphTexture); @@ -621,5 +493,4 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* // add the glyph into the texture. glyphTexture->addGlyph(glyph,posX,posY); - } diff --git a/src/osgText/Glyph.cpp b/src/osgText/Glyph.cpp index 3bc346c8f..17776780c 100644 --- a/src/osgText/Glyph.cpp +++ b/src/osgText/Glyph.cpp @@ -28,9 +28,34 @@ using namespace osgText; using namespace std; +// GL_ALPHA and GL_LUMINANCE_ALPHA are deprecated in GL3/GL4 core profile, use GL_RED & GL_RB in this case. +#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE) +#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_RED +#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_R8 +#define OSGTEXT_GLYPH_SDF_FORMAT GL_RG +#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_RG8 +#else +#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_ALPHA +#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_ALPHA +#define OSGTEXT_GLYPH_SDF_FORMAT GL_LUMINANCE_ALPHA +#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_LUMINANCE_ALPHA +#endif + + +#if 0 + #define TEXTURE_IMAGE_NUM_CHANNELS 1 + #define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT +#else + #define TEXTURE_IMAGE_NUM_CHANNELS 2 + #define TEXTURE_IMAGE_FORMAT GL_RGBA +#endif + + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// GlyphTexture +// GlyphTexture::GlyphTexture(): - _margin(1), - _marginRatio(0.02f), _usedY(0), _partUsedX(0), _partUsedY(0) @@ -51,27 +76,52 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const return 0; } +int GlyphTexture::getEffectMargin(const Glyph* glyph) +{ + if (_shaderTechnique==GREYSCALE) return 0; + else return osg::maximum(glyph->getFontResolution().second/6, 2u); +} + +int GlyphTexture::getTexelMargin(const Glyph* glyph) +{ + int width = glyph->s(); + int height = glyph->t(); + int effect_margin = getEffectMargin(glyph); + + int max_dimension = osg::maximum(width, height) + 2 * effect_margin; + int margin = osg::maximum(max_dimension/4, 2) + effect_margin; + + return margin; +} bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { - int maxAxis = osg::maximum(glyph->s(), glyph->t()); - int margin = _margin + (int)((float)maxAxis * _marginRatio); + int width = glyph->s(); + int height = glyph->t(); - int width = glyph->s()+2*margin; - int height = glyph->t()+2*margin; + int margin = getTexelMargin(glyph); - // first check box (_partUsedX,_usedY) to (width,height) - if (width <= (getTextureWidth()-_partUsedX) && - height <= (getTextureHeight()-_usedY)) + width += 2*margin; + height += 2*margin; + + int interval = 4; + + int partUsedX = ((_partUsedX % interval) == 0) ? _partUsedX : (((_partUsedX/interval)+1)*interval); + int partUsedY = ((_partUsedY % interval) == 0) ? _partUsedY : (((_partUsedY/interval)+1)*interval); + int usedY = ((_usedY % interval) == 0) ? _usedY : (((_usedY/interval)+1)*interval); + + // first check box (partUsedX, usedY) to (width,height) + if (width <= (getTextureWidth()-partUsedX) && + height <= (getTextureHeight()-usedY)) { // can fit in existing row. // record the position in which the texture will be stored. - posX = _partUsedX+margin; - posY = _usedY+margin; + posX = partUsedX+margin; + posY = usedY+margin; // move used markers on. - _partUsedX += width; + _partUsedX = posX+width; if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; return true; @@ -83,14 +133,14 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) { // can fit next row. _partUsedX = 0; - _usedY = _partUsedY; + _usedY = partUsedY; posX = _partUsedX+margin; posY = _usedY+margin; // move used markers on. - _partUsedX += width; - if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; + _partUsedX = posX+width; + _partUsedY = _usedY+height; return true; } @@ -101,23 +151,237 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY) void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) { + OpenThreads::ScopedLock lock(_mutex); if (!_image.valid()) createImage(); _glyphs.push_back(glyph); - // set up the details of where to place glyph's image in the texture. - glyph->setTexture(this); - glyph->setTexturePosition(posX,posY); + osg::ref_ptr info = new Glyph::TextureInfo( + this, + posX, posY, + osg::Vec2( static_cast(posX)/static_cast(getTextureWidth()), static_cast(posY)/static_cast(getTextureHeight()) ), // minTexCoord + osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ), // maxTexCoord + float(getTexelMargin(glyph))); // margin - glyph->setMinTexCoord( osg::Vec2( static_cast(posX)/static_cast(getTextureWidth()), - static_cast(posY)/static_cast(getTextureHeight()) ) ); - glyph->setMaxTexCoord( osg::Vec2( static_cast(posX+glyph->s())/static_cast(getTextureWidth()), - static_cast(posY+glyph->t())/static_cast(getTextureHeight()) ) ); + glyph->setTextureInfo(_shaderTechnique, info.get()); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); + copyGlyphImage(glyph, info); +} + +void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info) +{ _image->dirty(); + + if (_shaderTechnique<=GREYSCALE) + { + // OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<get(); - _image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); - } + _image = new osg::Image; + + GLenum imageFormat = (_shaderTechnique<=GREYSCALE) ? OSGTEXT_GLYPH_ALPHA_FORMAT : OSGTEXT_GLYPH_SDF_FORMAT; + GLenum internalFormat = (_shaderTechnique<=GREYSCALE) ? OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT : OSGTEXT_GLYPH_SDF_INTERNALFORMAT; + + _image->allocateImage(getTextureWidth(), getTextureHeight(), 1, imageFormat, GL_UNSIGNED_BYTE); + _image->setInternalTextureFormat(internalFormat); + + memset(_image->data(), 0, _image->getTotalSizeInBytes()); } return _image.get(); } +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Glyph +// // all the methods in Font::Glyph have been made non inline because VisualStudio6.0 is STUPID, STUPID, STUPID PILE OF JUNK. Glyph::Glyph(Font* font, unsigned int glyphCode): _font(font), @@ -172,12 +440,7 @@ Glyph::Glyph(Font* font, unsigned int glyphCode): _horizontalBearing(0.0f,0.f), _horizontalAdvance(0.f), _verticalBearing(0.0f,0.f), - _verticalAdvance(0.f), - _texture(0), - _texturePosX(0), - _texturePosY(0), - _minTexCoord(0.0f,0.0f), - _maxTexCoord(0.0f,0.0f) + _verticalAdvance(0.f) { setThreadSafeRefUnref(true); } @@ -198,67 +461,37 @@ const osg::Vec2& Glyph::getVerticalBearing() const { return _verticalBearing; } void Glyph::setVerticalAdvance(float advance) { _verticalAdvance=advance; } float Glyph::getVerticalAdvance() const { return _verticalAdvance; } -void Glyph::setTexture(GlyphTexture* texture) { _texture = texture; } -GlyphTexture* Glyph::getTexture() { return _texture; } -const GlyphTexture* Glyph::getTexture() const { return _texture; } - -void Glyph::setTexturePosition(int posX,int posY) { _texturePosX = posX; _texturePosY = posY; } -int Glyph::getTexturePositionX() const { return _texturePosX; } -int Glyph::getTexturePositionY() const { return _texturePosY; } - -void Glyph::setMinTexCoord(const osg::Vec2& coord) { _minTexCoord=coord; } -const osg::Vec2& Glyph::getMinTexCoord() const { return _minTexCoord; } - -void Glyph::setMaxTexCoord(const osg::Vec2& coord) { _maxTexCoord=coord; } -const osg::Vec2& Glyph::getMaxTexCoord() const { return _maxTexCoord; } - -void Glyph::subload() const +void Glyph::setTextureInfo(ShaderTechnique technique, TextureInfo* info) { - GLenum errorNo = glGetError(); - if (errorNo!=GL_NO_ERROR) + if (technique>=_textureInfoList.size()) { - const GLubyte* msg = osg::gluErrorString(errorNo); - if (msg) { OSG_WARN<<"before Glyph::subload(): detected OpenGL error: "<(data())<<");"<=_textureInfoList.size()) + { + _textureInfoList.resize(technique+1); + } + if (!_textureInfoList[technique]) + { + _font->assignGlyphToGlyphTexture(this, technique); + } + return _textureInfoList[technique].get(); +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Glyph3D +// Glyph3D::Glyph3D(Font* font, unsigned int glyphCode): osg::Referenced(true), _font(font), diff --git a/src/osgText/Text.cpp b/src/osgText/Text.cpp index 53a5d3b1a..46c857639 100644 --- a/src/osgText/Text.cpp +++ b/src/osgText/Text.cpp @@ -25,13 +25,19 @@ #include +#include +#include + +#define DEBUG_MESSAGE_LEVEL osg::INFO +#define DEBUG_MESSAGE osg::notify(DEBUG_MESSAGE_LEVEL) + using namespace osg; using namespace osgText; Text::Text(): + _shaderTechnique(GREYSCALE), _enableDepthWrites(true), _backdropType(NONE), - _backdropImplementation(DELAYED_DEPTH_WRITES), _backdropHorizontalOffset(0.07f), _backdropVerticalOffset(0.07f), _backdropColor(0.0f, 0.0f, 0.0f, 1.0f), @@ -42,13 +48,24 @@ Text::Text(): _colorGradientTopRight(1.0f, 1.0f, 1.0f, 1.0f) { _supportsVertexBufferObjects = true; + + const std::string& str = osg::DisplaySettings::instance()->getTextShaderTechnique(); + if (!str.empty()) + { + if (str=="ALL_FEATURES" || str=="ALL") _shaderTechnique = ALL_FEATURES; + else if (str=="GREYSCALE") _shaderTechnique = GREYSCALE; + else if (str=="SIGNED_DISTANCE_FIELD" || str=="SDF") _shaderTechnique = SIGNED_DISTANCE_FIELD; + else if (str=="NO_TEXT_SHADER" || str=="NONE") _shaderTechnique = NO_TEXT_SHADER; + } + + assignStateSet(); } Text::Text(const Text& text,const osg::CopyOp& copyop): osgText::TextBase(text,copyop), + _shaderTechnique(text._shaderTechnique), _enableDepthWrites(text._enableDepthWrites), _backdropType(text._backdropType), - _backdropImplementation(text._backdropImplementation), _backdropHorizontalOffset(text._backdropHorizontalOffset), _backdropVerticalOffset(text._backdropVerticalOffset), _backdropColor(text._backdropColor), @@ -65,21 +82,170 @@ Text::~Text() { } -void Text::setFont(osg::ref_ptr font) + +void Text::setShaderTechnique(ShaderTechnique technique) { - if (_font==font) return; + if (_shaderTechnique==technique) return; - osg::StateSet* previousFontStateSet = _font.valid() ? _font->getStateSet() : Font::getDefaultFont()->getStateSet(); - osg::StateSet* newFontStateSet = font.valid() ? font->getStateSet() : Font::getDefaultFont()->getStateSet(); + _shaderTechnique = technique; - if (getStateSet() == previousFontStateSet) - { - setStateSet( newFontStateSet ); - } + assignStateSet(); - TextBase::setFont(font); + computeGlyphRepresentation(); } +osg::StateSet* Text::createStateSet() +{ + Font* activeFont = getActiveFont(); + if (!activeFont) return 0; + + Font::StateSets& statesets = activeFont->getCachedStateSets(); + + std::stringstream ss; + ss<getTextureWidthHint()); + defineList["TEXTURE_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON); + } + + if (_shaderTechnique>GREYSCALE) + { + defineList["SIGNED_DISTNACE_FIELD"] = osg::StateSet::DefinePair("1", osg::StateAttribute::ON); + } + +#if 0 + OSG_NOTICE<<"Text::createStateSet() defines:"<first<<"] = "<second.first<getDefineList()==defineList) + { + // OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<get()<get(); + } + else + { + } + } + } + + + if (osg::isNotifyEnabled(DEBUG_MESSAGE_LEVEL)) + { + DEBUG_MESSAGE<<"Text::createStateSet() ShaderTechnique "; + switch(_shaderTechnique) + { + case(NO_TEXT_SHADER) : DEBUG_MESSAGE<<"NO_TEXT_SHADER"< stateset = new osg::StateSet; + + stateset->setDefineList(defineList); + + statesets.push_back(stateset.get()); + + stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); + stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + stateset->setMode(GL_BLEND, osg::StateAttribute::ON); + + + #if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE) + osg::DisplaySettings::ShaderHint shaderHint = osg::DisplaySettings::instance()->getShaderHint(); + if (_shaderTechnique==NO_TEXT_SHADER && shaderHint==osg::DisplaySettings::SHADER_NONE) + { + DEBUG_MESSAGE<<"Font::Font() Fixed function pipeline"<setTextureMode(0, GL_TEXTURE_2D, osg::StateAttribute::ON); + return stateset.release(); + } + #endif + + // set up the StateSet to use shaders + stateset->addUniform(new osg::Uniform("glyphTexture", 0)); + + osg::ref_ptr program = new osg::Program; + stateset->setAttributeAndModes(program.get()); + + { + DEBUG_MESSAGE<<"Using shaders/text.vert"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert)); + } + + { + DEBUG_MESSAGE<<"Using shaders/text.frag"<addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag)); + } + + return stateset.release(); +} Font* Text::getActiveFont() { @@ -225,22 +391,20 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite void Text::addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& maxc, const osg::Vec2& mintc, const osg::Vec2& maxtc) { // set up the coords of the quad - GlyphQuads& glyphquad = _textureGlyphQuadMap[glyph->getTexture()]; + const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique); + GlyphTexture* glyphTexture = info ? info->texture : 0; + GlyphQuads& glyphquad = _textureGlyphQuadMap[glyphTexture]; glyphquad._glyphs.push_back(glyph); - osg::DrawElements* primitives = 0; - if (glyphquad._primitives.empty()) + osg::DrawElements* primitives = glyphquad._primitives.get(); + if (!primitives) { unsigned int maxIndices = _text.size()*4; if (maxIndices>=16384) primitives = new osg::DrawElementsUInt(GL_TRIANGLES); else primitives = new osg::DrawElementsUShort(GL_TRIANGLES); primitives->setBufferObject(_ebo.get()); - glyphquad._primitives.push_back(primitives); - } - else - { - primitives = glyphquad._primitives[0].get(); + glyphquad._primitives = primitives; } @@ -280,25 +444,18 @@ void Text::computeGlyphRepresentation() if (!_texcoords) { _texcoords = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); _texcoords->setBufferObject(_vbo.get()); } else _texcoords->clear(); -#if 0 - _textureGlyphQuadMap.clear(); -#else for(TextureGlyphQuadMap::iterator itr = _textureGlyphQuadMap.begin(); itr != _textureGlyphQuadMap.end(); ++itr) { GlyphQuads& glyphquads = itr->second; glyphquads._glyphs.clear(); - for(Primitives::iterator pitr = glyphquads._primitives.begin(); - pitr != glyphquads._primitives.end(); - ++pitr) + if (glyphquads._primitives.valid()) { - (*pitr)->resizeElements(0); - (*pitr)->dirty(); + glyphquads._primitives->resizeElements(0); + glyphquads._primitives->dirty(); } } -#endif - _lineCount = 0; @@ -487,45 +644,53 @@ void Text::computeGlyphRepresentation() local.x() += bearing.x() * wr; local.y() += bearing.y() * hr; - - // Adjust coordinates and texture coordinates to avoid - // clipping the edges of antialiased characters. - osg::Vec2 mintc = glyph->getMinTexCoord(); - osg::Vec2 maxtc = glyph->getMaxTexCoord(); - osg::Vec2 vDiff = maxtc - mintc; - - float fHorizTCMargin = 1.0f / glyph->getTexture()->getTextureWidth(); - float fVertTCMargin = 1.0f / glyph->getTexture()->getTextureHeight(); - float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); - float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); - - mintc.x() -= fHorizTCMargin; - mintc.y() -= fVertTCMargin; - maxtc.x() += fHorizTCMargin; - maxtc.y() += fVertTCMargin; - osg::Vec2 minc = local+osg::Vec2(0.0f-fHorizQuadMargin,0.0f-fVertQuadMargin); - osg::Vec2 maxc = local+osg::Vec2(width+fHorizQuadMargin,height+fVertQuadMargin); - - addGlyphQuad(glyph, minc, maxc, mintc, maxtc); - - // move the cursor onto the next character. - // also expand bounding box - switch(_layout) + const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique); + if (info) { - case LEFT_TO_RIGHT: - cursor.x() += glyph->getHorizontalAdvance() * wr; - _textBB.expandBy(osg::Vec3(minc.x(), minc.y(), 0.0f)); //lower left corner - _textBB.expandBy(osg::Vec3(maxc.x(), maxc.y(), 0.0f)); //upper right corner - break; - case VERTICAL: - cursor.y() -= glyph->getVerticalAdvance() * hr; - _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner - _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner - break; - case RIGHT_TO_LEFT: - _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner - _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner - break; + // Adjust coordinates and texture coordinates to avoid + // clipping the edges of antialiased characters. + osg::Vec2 mintc = info->minTexCoord; + osg::Vec2 maxtc = info->maxTexCoord; + osg::Vec2 vDiff = maxtc - mintc; + float texelMargin = info->texelMargin; + + float fHorizTCMargin = texelMargin / info->texture->getTextureWidth(); + float fVertTCMargin = texelMargin / info->texture->getTextureHeight(); + float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x(); + float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y(); + + mintc.x() -= fHorizTCMargin; + mintc.y() -= fVertTCMargin; + maxtc.x() += fHorizTCMargin; + maxtc.y() += fVertTCMargin; + osg::Vec2 minc = local+osg::Vec2(0.0f-fHorizQuadMargin,0.0f-fVertQuadMargin); + osg::Vec2 maxc = local+osg::Vec2(width+fHorizQuadMargin,height+fVertQuadMargin); + + addGlyphQuad(glyph, minc, maxc, mintc, maxtc); + + // move the cursor onto the next character. + // also expand bounding box + switch(_layout) + { + case LEFT_TO_RIGHT: + cursor.x() += glyph->getHorizontalAdvance() * wr; + _textBB.expandBy(osg::Vec3(minc.x(), minc.y(), 0.0f)); //lower left corner + _textBB.expandBy(osg::Vec3(maxc.x(), maxc.y(), 0.0f)); //upper right corner + break; + case VERTICAL: + cursor.y() -= glyph->getVerticalAdvance() * hr; + _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner + _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner + break; + case RIGHT_TO_LEFT: + _textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner + _textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner + break; + } + } + else + { + OSG_NOTICE<<"No TextureInfo for "<second; - - osg::DrawElements* src_primitives = glyphquad._primitives[0].get(); - - for(unsigned int i=glyphquad._primitives.size(); i<=backdrop_index; ++i) - { - osg::DrawElementsUShort* dst_primitives = new osg::DrawElementsUShort(GL_TRIANGLES); - dst_primitives->setBufferObject(src_primitives->getBufferObject()); - glyphquad._primitives.push_back(dst_primitives); - } - - osg::DrawElements* dst_primitives = glyphquad._primitives[backdrop_index].get(); - dst_primitives->resizeElements(0); - - unsigned int numCoords = src_primitives->getNumIndices(); - - Coords& src_coords = _coords; - TexCoords& src_texcoords = _texcoords; - - Coords& dst_coords = _coords; - TexCoords& dst_texcoords = _texcoords; - - for(unsigned int i=0;isize(); - (*dst_primitives).addElement(di); - (*dst_coords).push_back(v); - (*dst_texcoords).push_back((*src_texcoords)[si]); - } - } - } -} - // This method adjusts the bounding box to account for the expanded area caused by the backdrop. // This assumes that the bounding box has already been computed for the text without the backdrop. void Text::computeBackdropBoundingBox() @@ -1095,6 +1117,8 @@ void Text::drawImplementation(osg::RenderInfo& renderInfo) const void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const { + if (colorMultiplier.a()==0.0f || _color.a()==0.0f) return; + osg::VertexArrayState* vas = state.getCurrentVertexArrayState(); bool usingVertexBufferObjects = state.useVertexBufferObject(_supportsVertexBufferObjects && _useVertexBufferObjects); bool usingVertexArrayObjects = usingVertexBufferObjects && state.useVertexArrayObject(_useVertexArrayObject); @@ -1117,7 +1141,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } if (_drawMode & TEXT) -// if (false) { for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); titr!=_textureGlyphQuadMap.end(); @@ -1128,33 +1151,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo const GlyphQuads& glyphquad = titr->second; -#if 1 - if(_backdropType != NONE) - { - unsigned int backdrop_index; - unsigned int max_backdrop_index; - if(_backdropType == OUTLINE) - { - backdrop_index = 1; - max_backdrop_index = 8; - } - else - { - backdrop_index = _backdropType+1; - max_backdrop_index = backdrop_index+1; - } - - if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size(); - - state.disableColorPointer(); - state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a()); - - for( ; backdrop_index < max_backdrop_index; backdrop_index++) - { - glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects); - } - } -#endif if(_colorGradientMode == SOLID) { vas->disableColorArray(state); @@ -1168,7 +1164,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo } } - glyphquad._primitives[0]->draw(state, usingVertexBufferObjects); + glyphquad._primitives->draw(state, usingVertexBufferObjects); } } } @@ -1216,9 +1212,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie vas->applyDisablingOfVertexAttributes(state); } -#if 0 - drawImplementationSinglePass(state, colorMultiplier); -#else glDepthMask(GL_FALSE); drawImplementationSinglePass(state, colorMultiplier); @@ -1235,7 +1228,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie } state.haveAppliedAttribute(osg::StateAttribute::DEPTH); -#endif if (usingVertexBufferObjects && !usingVertexArrayObjects) { @@ -1273,16 +1265,16 @@ void Text::accept(osg::PrimitiveFunctor& pf) const ++titr) { const GlyphQuads& glyphquad = titr->second; - if (!glyphquad._primitives.empty()) + if (glyphquad._primitives.valid()) { - const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast(glyphquad._primitives[0].get()); + const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast(glyphquad._primitives.get()); if (drawElementsUShort) { pf.drawElements(GL_TRIANGLES, drawElementsUShort->size(), &(drawElementsUShort->front())); } else { - const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast(glyphquad._primitives[0].get()); + const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast(glyphquad._primitives.get()); if (drawElementsUInt) { pf.drawElements(GL_TRIANGLES, drawElementsUInt->size(), &(drawElementsUInt->front())); @@ -1322,22 +1314,19 @@ void Text::setBackdropType(BackdropType type) if (_backdropType==type) return; _backdropType = type; + + assignStateSet(); + computeGlyphRepresentation(); } -void Text::setBackdropImplementation(BackdropImplementation implementation) -{ - if (_backdropImplementation==implementation) return; - - _backdropImplementation = implementation; - computeGlyphRepresentation(); -} - - void Text::setBackdropOffset(float offset) { _backdropHorizontalOffset = offset; _backdropVerticalOffset = offset; + + assignStateSet(); + computeGlyphRepresentation(); } @@ -1345,12 +1334,17 @@ void Text::setBackdropOffset(float horizontal, float vertical) { _backdropHorizontalOffset = horizontal; _backdropVerticalOffset = vertical; + + assignStateSet(); + computeGlyphRepresentation(); } void Text::setBackdropColor(const osg::Vec4& color) { _backdropColor = color; + + assignStateSet(); } void Text::setColorGradientMode(ColorGradientMode mode) @@ -1391,20 +1385,10 @@ Text::GlyphQuads::GlyphQuads(const GlyphQuads&) void Text::GlyphQuads::resizeGLObjectBuffers(unsigned int maxSize) { - for(Primitives::iterator itr = _primitives.begin(); - itr != _primitives.end(); - ++itr) - { - (*itr)->resizeGLObjectBuffers(maxSize); - } + if (_primitives.valid()) _primitives->resizeGLObjectBuffers(maxSize); } void Text::GlyphQuads::releaseGLObjects(osg::State* state) const { - for(Primitives::const_iterator itr = _primitives.begin(); - itr != _primitives.end(); - ++itr) - { - (*itr)->releaseGLObjects(state); - } + if (_primitives.valid()) _primitives->releaseGLObjects(state); } diff --git a/src/osgText/Text3D.cpp b/src/osgText/Text3D.cpp index 98056db58..ef9561422 100644 --- a/src/osgText/Text3D.cpp +++ b/src/osgText/Text3D.cpp @@ -438,9 +438,11 @@ void Text3D::computeGlyphRepresentation() { (*_coords)[i] += position; } + _coords->dirty(); // copy normals _normals->insert(_normals->end(), src_normals->begin(), src_normals->end()); + _normals->dirty(); copyAndOffsetPrimitiveSets(_frontPrimitiveSetList, it->_glyphGeometry->getFrontPrimitiveSetList(), base); copyAndOffsetPrimitiveSets(_wallPrimitiveSetList, it->_glyphGeometry->getWallPrimitiveSetList(), base); diff --git a/src/osgText/TextBase.cpp b/src/osgText/TextBase.cpp index 5c5e5460e..6fbf2e5ba 100644 --- a/src/osgText/TextBase.cpp +++ b/src/osgText/TextBase.cpp @@ -50,7 +50,6 @@ TextBase::TextBase(): _lineCount(0), _glyphNormalized(false) { - setStateSet(Font::getDefaultFont()->getStateSet()); setUseDisplayList(false); setSupportsDisplayList(false); @@ -89,6 +88,11 @@ TextBase::~TextBase() { } +osg::StateSet* TextBase::createStateSet() +{ + return 0; +} + void TextBase::initArraysAndBuffers() { _vbo = new osg::VertexBufferObject; @@ -182,6 +186,10 @@ void TextBase::setColor(const osg::Vec4& color) _color = color; } +void TextBase::assignStateSet() +{ + setStateSet(createStateSet()); +} void TextBase::setFont(osg::ref_ptr font) { @@ -189,6 +197,8 @@ void TextBase::setFont(osg::ref_ptr font) _font = font; + assignStateSet(); + computeGlyphRepresentation(); } @@ -203,6 +213,9 @@ void TextBase::setFontResolution(unsigned int width, unsigned int height) if (_fontSize==size) return; _fontSize = size; + + assignStateSet(); + computeGlyphRepresentation(); } diff --git a/src/osgText/shaders/text_frag.cpp b/src/osgText/shaders/text_frag.cpp new file mode 100644 index 000000000..02c253100 --- /dev/null +++ b/src/osgText/shaders/text_frag.cpp @@ -0,0 +1,257 @@ +char text_frag[] = "$OSG_GLSL_VERSION\n" + "\n" + "#pragma import_defines( BACKDROP_COLOR, SHADOW, OUTLINE, SIGNED_DISTNACE_FIELD, TEXTURE_DIMENSION, GLYPH_DIMENSION)\n" + "\n" + "#ifdef GL_ES\n" + " #extension GL_OES_standard_derivatives : enable\n" + " #ifndef GL_OES_standard_derivatives\n" + " #undef SIGNED_DISTNACE_FIELD\n" + " #endif\n" + "#endif\n" + "\n" + "#if !defined(GL_ES)\n" + " #if __VERSION__>=400\n" + " #define osg_TextureQueryLOD textureQueryLod\n" + " #else\n" + " #extension GL_ARB_texture_query_lod : enable\n" + " #ifdef GL_ARB_texture_query_lod\n" + " #define osg_TextureQueryLOD textureQueryLOD\n" + " #endif\n" + " #endif\n" + "#endif\n" + "\n" + "$OSG_PRECISION_FLOAT\n" + "\n" + "#if __VERSION__>=130\n" + " #define TEXTURE texture\n" + " #define TEXTURELOD textureLod\n" + " out vec4 osg_FragColor;\n" + "#else\n" + " #define TEXTURE texture2D\n" + " #define TEXTURELOD texture2DLod\n" + " #define osg_FragColor gl_FragColor\n" + "#endif\n" + "\n" + "\n" + "#if !defined(GL_ES) && __VERSION__>=130\n" + " #define ALPHA r\n" + " #define SDF g\n" + "#else\n" + " #define ALPHA a\n" + " #define SDF r\n" + "#endif\n" + "\n" + "\n" + "uniform sampler2D glyphTexture;\n" + "\n" + "$OSG_VARYING_IN vec2 texCoord;\n" + "$OSG_VARYING_IN vec4 vertexColor;\n" + "\n" + "#ifndef TEXTURE_DIMENSION\n" + "const float TEXTURE_DIMENSION = 1024.0;\n" + "#endif\n" + "\n" + "#ifndef GLYPH_DIMENSION\n" + "const float GLYPH_DIMENSION = 32.0;\n" + "#endif\n" + "\n" + "#ifdef SIGNED_DISTNACE_FIELD\n" + "\n" + "float distanceFromEdge(vec2 tc)\n" + "{\n" + " float center_alpha = TEXTURELOD(glyphTexture, tc, 0.0).SDF;\n" + " if (center_alpha==0.0) return -1.0;\n" + "\n" + " //float distance_scale = (1.0/4.0)*1.41;\n" + " float distance_scale = (1.0/6.0)*1.41;\n" + " //float distance_scale = (1.0/8.0)*1.41;\n" + "\n" + " return (center_alpha-0.5)*distance_scale;\n" + "}\n" + "\n" + "vec4 distanceFieldColorSample(float edge_distance, float blend_width, float blend_half_width)\n" + "{\n" + "#ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return mix(vertexColor, vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a), smoothstep(0.0, 1.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else if (edge_distance>(blend_half_width-outline_width))\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, BACKDROP_COLOR.a*vertexColor.a);\n" + " }\n" + " else if (edge_distance>-(outline_width+blend_half_width))\n" + " {\n" + " return vec4(BACKDROP_COLOR.rgb, vertexColor.a * ((blend_half_width+outline_width+edge_distance)/blend_width));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#else\n" + " if (edge_distance>blend_half_width)\n" + " {\n" + " return vertexColor;\n" + " }\n" + " else if (edge_distance>-blend_half_width)\n" + " {\n" + " return vec4(vertexColor.rgb, vertexColor.a * smoothstep(1.0, 0.0, (blend_half_width-edge_distance)/(blend_width)));\n" + " }\n" + " else\n" + " {\n" + " return vec4(0.0, 0.0, 0.0, 0.0);\n" + " }\n" + "#endif\n" + "}\n" + "\n" + "vec4 textColor(vec2 src_texCoord)\n" + "{\n" + " float sample_distance_scale = 0.75;\n" + " vec2 dx = dFdx(src_texCoord)*sample_distance_scale;\n" + " vec2 dy = dFdy(src_texCoord)*sample_distance_scale;\n" + "\n" + "\n" + " float distance_across_pixel = length(dx+dy)*(TEXTURE_DIMENSION/GLYPH_DIMENSION);\n" + "\n" + " // compute the appropriate number of samples required to avoid aliasing.\n" + " int maxNumSamplesAcrossSide = 4;\n" + "\n" + " int numSamplesX = int(TEXTURE_DIMENSION * length(dx));\n" + " int numSamplesY = int(TEXTURE_DIMENSION * length(dy));\n" + " if (numSamplesX<2) numSamplesX = 2;\n" + " if (numSamplesY<2) numSamplesY = 2;\n" + " if (numSamplesX>maxNumSamplesAcrossSide) numSamplesX = maxNumSamplesAcrossSide;\n" + " if (numSamplesY>maxNumSamplesAcrossSide) numSamplesY = maxNumSamplesAcrossSide;\n" + "\n" + "\n" + " vec2 delta_tx = dx/float(numSamplesX-1);\n" + " vec2 delta_ty = dy/float(numSamplesY-1);\n" + "\n" + " float numSamples = float(numSamplesX)*float(numSamplesY);\n" + " float scale = 1.0/numSamples;\n" + " vec4 total_color = vec4(0.0,0.0,0.0,0.0);\n" + "\n" + " float blend_width = 1.5*distance_across_pixel/numSamples;\n" + " float blend_half_width = blend_width*0.5;\n" + "\n" + " // check whether fragment is wholly within or outwith glyph body+outline\n" + " float cd = distanceFromEdge(src_texCoord); // central distance (distance from center to edge)\n" + " if (cd-blend_half_width>distance_across_pixel) return vertexColor; // pixel fully within glyph body\n" + "\n" + " #ifdef OUTLINE\n" + " float outline_width = OUTLINE*0.5;\n" + " if ((-cd-outline_width-blend_half_width)>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside outline+glyph body\n" + " #else\n" + " if (-cd-blend_half_width>distance_across_pixel) return vec4(0.0, 0.0, 0.0, 0.0); // pixel fully outside glyph body\n" + " #endif\n" + "\n" + "\n" + " // use multi-sampling to provide high quality antialised fragments\n" + " vec2 origin = src_texCoord - dx*0.5 - dy*0.5;\n" + " for(;numSamplesY>0; --numSamplesY)\n" + " {\n" + " vec2 pos = origin;\n" + " int numX = numSamplesX;\n" + " for(;numX>0; --numX)\n" + " {\n" + " vec4 c = distanceFieldColorSample(distanceFromEdge(pos), blend_width, blend_half_width);\n" + " total_color = total_color + c * c.a;\n" + " pos += delta_tx;\n" + " }\n" + " origin += delta_ty;\n" + " }\n" + "\n" + " total_color.rgb /= total_color.a;\n" + " total_color.a *= scale;\n" + "\n" + " return total_color;\n" + "}\n" + "\n" + "#else\n" + "\n" + "vec4 textColor(vec2 src_texCoord)\n" + "{\n" + "\n" + "#ifdef OUTLINE\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" + " float delta_tc = 1.6*OUTLINE*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + "\n" + " float outline_alpha = alpha;\n" + " vec2 origin = src_texCoord-vec2(delta_tc*0.5, delta_tc*0.5);\n" + "\n" + " float numSamples = 3.0;\n" + " delta_tc = delta_tc/(numSamples-1.0);\n" + "\n" + " float background_alpha = 1.0;\n" + "\n" + " for(float i=0.0; i1.0) outline_alpha = 1.0;\n" + "\n" + " if (outline_alpha==0.0) return vec4(0.0, 0.0, 0.0, 0.0); // outside glyph and outline\n" + "\n" + " vec4 color = mix(BACKDROP_COLOR, vertexColor, smoothstep(0.0, 1.0, alpha));\n" + " color.a = vertexColor.a * smoothstep(0.0, 1.0, outline_alpha);\n" + "\n" + " return color;\n" + "\n" + "#else\n" + "\n" + " float alpha = TEXTURE(glyphTexture, src_texCoord).ALPHA;\n" + " if (alpha==0.0) vec4(0.0, 0.0, 0.0, 0.0);\n" + " return vec4(vertexColor.rgb, vertexColor.a * alpha);\n" + "\n" + "#endif\n" + "}\n" + "\n" + "#endif\n" + "\n" + "\n" + "void main(void)\n" + "{\n" + " if (texCoord.x<0.0 && texCoord.y<0.0)\n" + " {\n" + " osg_FragColor = vertexColor;\n" + " return;\n" + " }\n" + "\n" + "#ifdef SHADOW\n" + " float scale = -1.0*GLYPH_DIMENSION/TEXTURE_DIMENSION;\n" + " vec2 delta_tc = SHADOW*scale;\n" + " vec4 shadow_color = textColor(texCoord+delta_tc);\n" + " shadow_color.rgb = BACKDROP_COLOR.rgb;\n" + "\n" + " vec4 glyph_color = textColor(texCoord);\n" + " vec4 color = mix(shadow_color, glyph_color, glyph_color.a);\n" + "#else\n" + " vec4 color = textColor(texCoord);\n" + "#endif\n" + "\n" + " if (color.a==0.0) discard;\n" + "\n" + " osg_FragColor = color;\n" + "}\n" + "\n"; diff --git a/src/osgText/shaders/text_vert.cpp b/src/osgText/shaders/text_vert.cpp new file mode 100644 index 000000000..72506284f --- /dev/null +++ b/src/osgText/shaders/text_vert.cpp @@ -0,0 +1,13 @@ +char text_vert[] = "$OSG_GLSL_VERSION\n" + "$OSG_PRECISION_FLOAT\n" + "\n" + "$OSG_VARYING_OUT vec2 texCoord;\n" + "$OSG_VARYING_OUT vec4 vertexColor;\n" + "\n" + "void main(void)\n" + "{\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " texCoord = gl_MultiTexCoord0.xy;\n" + " vertexColor = gl_Color;\n" + "}\n" + "\n"; diff --git a/src/osgUtil/GLObjectsVisitor.cpp b/src/osgUtil/GLObjectsVisitor.cpp index b194b7990..25aa8c896 100644 --- a/src/osgUtil/GLObjectsVisitor.cpp +++ b/src/osgUtil/GLObjectsVisitor.cpp @@ -153,6 +153,23 @@ void GLObjectsVisitor::apply(osg::StateSet& stateset) } } +void GLObjectsVisitor::compile(osg::Node& node) +{ + if (_renderInfo.getState()) + { + node.accept(*this); + + if (_lastCompiledProgram.valid()) + { + osg::State* state = _renderInfo.getState(); + osg::GLExtensions* extensions = state->get(); + extensions->glUseProgram(0); + _renderInfo.getState()->setLastAppliedProgramObject(0); + } + } +} + + ///////////////////////////////////////////////////////////////// // // GLObjectsOperation diff --git a/src/osgUtil/LineSegmentIntersector.cpp b/src/osgUtil/LineSegmentIntersector.cpp index 63cb30366..08faade5e 100644 --- a/src/osgUtil/LineSegmentIntersector.cpp +++ b/src/osgUtil/LineSegmentIntersector.cpp @@ -299,13 +299,17 @@ struct IntersectFunctor return; } - Vec3 in = v0*r0 + v1*r1 + v2*r2; + // Remap ratio into the range of LineSegment + const osg::Vec3d& lsStart = _settings->_lineSegIntersector->getStart(); + const osg::Vec3d& lsEnd = _settings->_lineSegIntersector->getEnd(); + double remap_ratio = ((_start - lsStart).length() + r*_length)/(lsEnd - lsStart).length(); + + Vec3 in = lsStart*(1.0 - remap_ratio) + lsEnd*remap_ratio; // == v0*r0 + v1*r1 + v2*r2; Vec3 normal = E1^E2; normal.normalize(); - LineSegmentIntersector::Intersection hit; - hit.ratio = r; + hit.ratio = remap_ratio; hit.matrix = _settings->_iv->getModelMatrix(); hit.nodePath = _settings->_iv->getNodePath(); hit.drawable = _settings->_drawable; @@ -500,7 +504,7 @@ void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Dr if (reachedLimit()) return; osg::Vec3d s(_start), e(_end); - if ( !intersectAndClip( s, e, drawable->getBoundingBox() ) ) return; + if ( drawable->isCullingActive() && !intersectAndClip( s, e, drawable->getBoundingBox() ) ) return; if (iv.getDoDummyTraversal()) return; diff --git a/src/osgViewer/GraphicsWindowCarbon.cpp b/src/osgViewer/GraphicsWindowCarbon.cpp index 0fbb6f21c..18169b3f0 100644 --- a/src/osgViewer/GraphicsWindowCarbon.cpp +++ b/src/osgViewer/GraphicsWindowCarbon.cpp @@ -1100,3 +1100,6 @@ public: REGISTER_WINDOWINGSYSTEMINTERFACE(Carbon, CarbonWindowingSystemInterface) } + +#endif + diff --git a/src/osgViewer/GraphicsWindowCocoa.mm b/src/osgViewer/GraphicsWindowCocoa.mm index bbca00de9..14f6fcb5f 100644 --- a/src/osgViewer/GraphicsWindowCocoa.mm +++ b/src/osgViewer/GraphicsWindowCocoa.mm @@ -199,7 +199,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect) // the app-delegate, handling quit-requests // ---------------------------------------------------------------------------------------------------------- -@interface CocoaAppDelegate : NSObject +@interface CocoaAppDelegate : NSObject { } diff --git a/src/osgViewer/Renderer.cpp b/src/osgViewer/Renderer.cpp index 71f93ccc5..06620af32 100644 --- a/src/osgViewer/Renderer.cpp +++ b/src/osgViewer/Renderer.cpp @@ -571,7 +571,6 @@ void Renderer::compile() { DEBUG_MESSAGE<<"Renderer::compile()"<getState()); - sceneView->getSceneData()->accept(glov); + glov.compile(*(sceneView->getSceneData())); } sceneView->getState()->checkGLErrors("After Renderer::compile"); diff --git a/src/osgWidget/Label.cpp b/src/osgWidget/Label.cpp index 3731bca8c..6c7e9ebc4 100644 --- a/src/osgWidget/Label.cpp +++ b/src/osgWidget/Label.cpp @@ -134,7 +134,6 @@ void Label::setFontColor(const Color& c) { void Label::setShadow(point_type offset) { _text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); - _text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER); _text->setBackdropOffset(offset); _calculateSize(getTextSize()); diff --git a/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp b/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp index e34c1d46e..c2bb99e6a 100644 --- a/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp +++ b/src/osgWrappers/deprecated-dotosg/osgText/IO_Text.cpp @@ -57,27 +57,6 @@ std::string convertBackdropTypeEnumToString(osgText::Text::BackdropType backdrop } } - -osgText::Text::BackdropImplementation convertBackdropImplementationStringToEnum(std::string & str) -{ - if (str=="POLYGON_OFFSET") return osgText::Text::POLYGON_OFFSET; - else if (str=="NO_DEPTH_BUFFER") return osgText::Text::NO_DEPTH_BUFFER; - else if (str=="DEPTH_RANGE") return osgText::Text::DEPTH_RANGE; - else if (str=="STENCIL_BUFFER") return osgText::Text::STENCIL_BUFFER; - else return static_cast(-1); -} -std::string convertBackdropImplementationEnumToString(osgText::Text::BackdropImplementation backdropImplementation) -{ - switch (backdropImplementation) - { - case osgText::Text::POLYGON_OFFSET: return "POLYGON_OFFSET"; - case osgText::Text::NO_DEPTH_BUFFER: return "NO_DEPTH_BUFFER"; - case osgText::Text::DEPTH_RANGE: return "DEPTH_RANGE"; - case osgText::Text::STENCIL_BUFFER: return "STENCIL_BUFFER"; - default : return ""; - } -} - osgText::Text::ColorGradientMode convertColorGradientModeStringToEnum(std::string & str) { if (str=="SOLID") return osgText::Text::SOLID; @@ -155,12 +134,6 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr) // backdropImplementation if (fr[0].matchWord("backdropImplementation")) { - std::string str = fr[1].getStr(); - osgText::Text::BackdropImplementation backdropImplementation = convertBackdropImplementationStringToEnum(str); - - if (backdropImplementation != static_cast(-1)) - text.setBackdropImplementation(backdropImplementation); - fr += 2; itAdvanced = true; } @@ -254,9 +227,6 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw) osg::Vec4 c = text.getBackdropColor(); fw.indent() << "backdropColor " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl; - // backdropImplementation - fw.indent() << "backdropImplementation " << convertBackdropImplementationEnumToString(text.getBackdropImplementation()) << std::endl; - // colorGradientMode fw.indent() << "colorGradientMode " << convertColorGradientModeEnumToString(text.getColorGradientMode()) << std::endl; diff --git a/src/osgWrappers/serializers/osg/LibraryWrapper.cpp b/src/osgWrappers/serializers/osg/LibraryWrapper.cpp index 8d0993807..b6b99b8f3 100644 --- a/src/osgWrappers/serializers/osg/LibraryWrapper.cpp +++ b/src/osgWrappers/serializers/osg/LibraryWrapper.cpp @@ -3,25 +3,34 @@ USE_SERIALIZER_WRAPPER(AlphaFunc) USE_SERIALIZER_WRAPPER(AnimationPath) USE_SERIALIZER_WRAPPER(AnimationPathCallback) +USE_SERIALIZER_WRAPPER(AtomicCounterBufferBinding) USE_SERIALIZER_WRAPPER(AudioSink) USE_SERIALIZER_WRAPPER(AudioStream) USE_SERIALIZER_WRAPPER(AutoTransform) USE_SERIALIZER_WRAPPER(Billboard) USE_SERIALIZER_WRAPPER(BlendColor) USE_SERIALIZER_WRAPPER(BlendEquation) +USE_SERIALIZER_WRAPPER(BlendEquationi) USE_SERIALIZER_WRAPPER(BlendFunc) +USE_SERIALIZER_WRAPPER(BlendFunci) USE_SERIALIZER_WRAPPER(BoolValueObject) USE_SERIALIZER_WRAPPER(Box) +USE_SERIALIZER_WRAPPER(BufferData) +USE_SERIALIZER_WRAPPER(BufferIndexBinding) +USE_SERIALIZER_WRAPPER(BufferObject) USE_SERIALIZER_WRAPPER(Callback) +USE_SERIALIZER_WRAPPER(CallbackObject) USE_SERIALIZER_WRAPPER(Camera) USE_SERIALIZER_WRAPPER(CameraView) USE_SERIALIZER_WRAPPER(Capsule) USE_SERIALIZER_WRAPPER(ClampColor) USE_SERIALIZER_WRAPPER(ClearNode) USE_SERIALIZER_WRAPPER(ClipNode) +USE_SERIALIZER_WRAPPER(ClipControl) USE_SERIALIZER_WRAPPER(ClipPlane) USE_SERIALIZER_WRAPPER(ClusterCullingCallback) USE_SERIALIZER_WRAPPER(ColorMask) +USE_SERIALIZER_WRAPPER(ColorMaski) USE_SERIALIZER_WRAPPER(ColorMatrix) USE_SERIALIZER_WRAPPER(CompositeShape) USE_SERIALIZER_WRAPPER(ComputeBoundingBoxCallback) @@ -32,9 +41,11 @@ USE_SERIALIZER_WRAPPER(ConvexPlanarOccluder) USE_SERIALIZER_WRAPPER(CoordinateSystemNode) USE_SERIALIZER_WRAPPER(CullFace) USE_SERIALIZER_WRAPPER(Cylinder) +USE_SERIALIZER_WRAPPER(DefaultUserDataContainer) USE_SERIALIZER_WRAPPER(Depth) USE_SERIALIZER_WRAPPER(Drawable) USE_SERIALIZER_WRAPPER(DrawPixels) +USE_SERIALIZER_WRAPPER(ElementBufferObject) USE_SERIALIZER_WRAPPER(EllipsoidModel) USE_SERIALIZER_WRAPPER(Fog) USE_SERIALIZER_WRAPPER(FragmentProgram) @@ -77,10 +88,14 @@ USE_SERIALIZER_WRAPPER(Projection) USE_SERIALIZER_WRAPPER(ProxyNode) USE_SERIALIZER_WRAPPER(SampleMaski) USE_SERIALIZER_WRAPPER(Scissor) +USE_SERIALIZER_WRAPPER(Script) +USE_SERIALIZER_WRAPPER(ScriptNodeCallback) USE_SERIALIZER_WRAPPER(Sequence) USE_SERIALIZER_WRAPPER(ShadeModel) USE_SERIALIZER_WRAPPER(Shader) +USE_SERIALIZER_WRAPPER(ShaderAttribute) USE_SERIALIZER_WRAPPER(ShaderBinary) +USE_SERIALIZER_WRAPPER(ShaderStorageBufferBinding) USE_SERIALIZER_WRAPPER(Shape) USE_SERIALIZER_WRAPPER(ShapeDrawable) USE_SERIALIZER_WRAPPER(Sphere) @@ -101,16 +116,21 @@ USE_SERIALIZER_WRAPPER(Texture1D) USE_SERIALIZER_WRAPPER(Texture2D) USE_SERIALIZER_WRAPPER(Texture2DArray) USE_SERIALIZER_WRAPPER(Texture3D) +USE_SERIALIZER_WRAPPER(TextureBuffer) USE_SERIALIZER_WRAPPER(TextureCubeMap) USE_SERIALIZER_WRAPPER(TextureRectangle) USE_SERIALIZER_WRAPPER(TransferFunction) USE_SERIALIZER_WRAPPER(TransferFunction1D) USE_SERIALIZER_WRAPPER(Transform) +USE_SERIALIZER_WRAPPER(TransformFeedbackBufferBinding) USE_SERIALIZER_WRAPPER(TriangleMesh) USE_SERIALIZER_WRAPPER(Uniform) +USE_SERIALIZER_WRAPPER(UniformBufferBinding) USE_SERIALIZER_WRAPPER(UniformCallback) USE_SERIALIZER_WRAPPER(UpdateCallback) USE_SERIALIZER_WRAPPER(UserDataContainer) +USE_SERIALIZER_WRAPPER(VertexAttribDivisor) +USE_SERIALIZER_WRAPPER(VertexBufferObject) USE_SERIALIZER_WRAPPER(VertexProgram) USE_SERIALIZER_WRAPPER(Viewport) @@ -164,5 +184,21 @@ USE_SERIALIZER_WRAPPER(DrawElementsUByte) USE_SERIALIZER_WRAPPER(DrawElementsUShort) USE_SERIALIZER_WRAPPER(DrawElementsUInt) +#ifdef OSG_HAS_MULTIDRAWARRAYS +USE_SERIALIZER_WRAPPER(MultiDrawArrays) +#endif + +// PrimitiveSetIndirect +USE_SERIALIZER_WRAPPER(IndirectCommandDrawArrays) +USE_SERIALIZER_WRAPPER(IndirectCommandDrawElements) +USE_SERIALIZER_WRAPPER(osgDefaultIndirectCommandDrawArrays) +USE_SERIALIZER_WRAPPER(osgDefaultIndirectCommandDrawElements) +USE_SERIALIZER_WRAPPER(DrawArraysIndirect) +USE_SERIALIZER_WRAPPER(MultiDrawArraysIndirect) +USE_SERIALIZER_WRAPPER(DrawElementsIndirect) +USE_SERIALIZER_WRAPPER(DrawElementsIndirectUByte) +USE_SERIALIZER_WRAPPER(DrawElementsIndirectUShort) +USE_SERIALIZER_WRAPPER(DrawElementsIndirectUInt) + extern "C" void wrapper_serializer_library_osg(void) {} diff --git a/src/osgWrappers/serializers/osg/Program.cpp b/src/osgWrappers/serializers/osg/Program.cpp index d00096d5c..1513aa484 100644 --- a/src/osgWrappers/serializers/osg/Program.cpp +++ b/src/osgWrappers/serializers/osg/Program.cpp @@ -145,6 +145,39 @@ static bool writeComputeGroups( osgDB::OutputStream& os, const osg::Program& att return true; } +static bool checkBindUniformBlock( const osg::Program& node ) +{ + return true; +} + +static bool readBindUniformBlock( osgDB::InputStream& is, osg::Program& p ) +{ + unsigned int size = 0; is >> size >> is.BEGIN_BRACKET; + std::string name; unsigned int index; + for ( unsigned int i=0; i>name; is >>index; + p.addBindUniformBlock(name, index); + } + is >> is.END_BRACKET; + return true; +} + + +static bool writeBindUniformBlock( osgDB::OutputStream& os, const osg::Program& p ) +{ + unsigned int size = p.getUniformBlockBindingList().size(); + os << size << os.BEGIN_BRACKET << std::endl; + for(osg::Program::UniformBlockBindingList::const_iterator bbit = p.getUniformBlockBindingList().begin(); + bbit != p.getUniformBlockBindingList().end(); ++bbit) + { + os << bbit->first; + os << bbit->second; + } + os << os.END_BRACKET << std::endl; + return true; +} + REGISTER_OBJECT_WRAPPER( Program, new osg::Program, osg::Program, @@ -167,4 +200,8 @@ REGISTER_OBJECT_WRAPPER( Program, ADD_USER_SERIALIZER( FeedBackVaryingsName ); ADD_USER_SERIALIZER( FeedBackMode ); } + { + UPDATE_TO_VERSION_SCOPED( 150 ) + ADD_USER_SERIALIZER( BindUniformBlock ); + } } diff --git a/src/osgWrappers/serializers/osg/ShaderAttribute.cpp b/src/osgWrappers/serializers/osg/ShaderAttribute.cpp new file mode 100644 index 000000000..b99747432 --- /dev/null +++ b/src/osgWrappers/serializers/osg/ShaderAttribute.cpp @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +REGISTER_OBJECT_WRAPPER( ShaderAttribute, + /*new osg::ShaderAttribute*/NULL, + osg::ShaderAttribute, + "osg::Object osg::StateAttribute osg::ShaderAttribute" ) +{ +}