Merge branch 'master' into osganimation

This commit is contained in:
Robert Osfield 2017-10-27 12:54:10 +01:00
commit 11f9bbf6ea
80 changed files with 3301 additions and 1032 deletions

View File

@ -4,6 +4,9 @@ env:
# via the "travis encrypt" command using the project repo's public key # 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=" - 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: matrix:
fast_finish: true fast_finish: true
include: include:
@ -18,8 +21,7 @@ matrix:
sudo: false sudo: false
cache: cache:
apt: true apt: true
directories: ccache: true
- $HOME/.ccache
compiler: compiler:
#- clang #- clang
- gcc - gcc
@ -43,11 +45,19 @@ matrix:
# OSX build # OSX build
- os: osx - os: osx
language: cpp before_install:
- brew update
install:
- brew install ccache
- export PATH="/usr/local/opt/ccache/libexec:$PATH"
env: env:
- CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON" - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON"
- os: osx - os: osx
language: cpp before_install:
- brew update
install:
- brew install ccache
- export PATH="/usr/local/opt/ccache/libexec:$PATH"
env: env:
- CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF" - CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF"

View File

@ -1,6 +1,6 @@
OpenSceneGraph Library 3.5.7 OpenSceneGraph Library 3.5.7
566 Contributors: 568 Contributors:
Firstname Surname Firstname Surname
----------------- -----------------
@ -175,6 +175,7 @@ John Ivar
Gustav Haapalahti Gustav Haapalahti
Erik den Dekker Erik den Dekker
Emmanuel Roche Emmanuel Roche
Don Burns
Domenico Mangieri Domenico Mangieri
Daniel Larimer Daniel Larimer
Colin Dunlop Colin Dunlop
@ -226,7 +227,6 @@ Fabio Mierlo
Doug McCorkle Doug McCorkle
Donald Cipperly Donald Cipperly
Don Leich Don Leich
Don Burns
Dietmar Funck Dietmar Funck
Colin Cochran Colin Cochran
Christian Ruzicka Christian Ruzicka
@ -362,6 +362,7 @@ Shuxing Xiao
Shane Arnott Shane Arnott
Sergey Kurdakov Sergey Kurdakov
Sebastien Kuntz Sebastien Kuntz
Sandro Mani
Ruth Lang Ruth Lang
Ruben The Ruben The
Ruben Smelik Ruben Smelik
@ -538,6 +539,7 @@ Christian Noon
Christian Kaser Christian Kaser
Christian Ehrlicher Christian Ehrlicher
Chris McGlone Chris McGlone
Chris Djali
Carlos Garcea Carlos Garcea
Bryce Eldridge Bryce Eldridge
Bruno Herbelin Bruno Herbelin

View File

@ -115,7 +115,7 @@ PROJECT(OpenSceneGraph)
SET(OPENSCENEGRAPH_MAJOR_VERSION 3) SET(OPENSCENEGRAPH_MAJOR_VERSION 3)
SET(OPENSCENEGRAPH_MINOR_VERSION 5) SET(OPENSCENEGRAPH_MINOR_VERSION 5)
SET(OPENSCENEGRAPH_PATCH_VERSION 7) SET(OPENSCENEGRAPH_PATCH_VERSION 8)
SET(OPENSCENEGRAPH_SOVERSION 150) SET(OPENSCENEGRAPH_SOVERSION 150)
# set to 0 when not a release candidate, non zero means that any generated # set to 0 when not a release candidate, non zero means that any generated

View File

@ -94,14 +94,12 @@ macro(FIND_LIBLAS_LIBRARY MYLIBRARY MYLIBRARYNAME)
endmacro(FIND_LIBLAS_LIBRARY LIBRARY LIBRARYNAME) endmacro(FIND_LIBLAS_LIBRARY LIBRARY LIBRARYNAME)
FIND_LIBLAS_LIBRARY(LIBLAS_LIBRARY las) FIND_LIBLAS_LIBRARY(LIBLAS_LIBRARY las)
FIND_LIBLAS_LIBRARY(LIBLASC_LIBRARY las_c)
set(LIBLAS_FOUND "NO") 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 FIND_PACKAGE(Boost) # used by LIBLAS
if(Boost_FOUND) if(Boost_FOUND)
set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} ${LIBLASC_LIBRARY} ) set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} )
set(LIBLAS_FOUND "YES") set(LIBLAS_FOUND "YES")
endif() endif()
endif() endif()

375
ChangeLog
View File

@ -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 Tue, 22 Aug 2017 09:04:49 +0100
Author : Robert Osfield Author : Robert Osfield
Added catch for controbutors list Added catch for controbutors list
@ -165,18 +436,122 @@ Mon, 7 Aug 2017 16:32:44 +0100
Author : Robert Osfield Author : Robert Osfield
Added link to ABI tracker 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 Mon, 31 Jul 2017 13:38:18 +0100
Author : Robert Osfield Author : Robert Osfield
Merged #pragmatic shader fix from OpenSceneGraph-3.4 branch. 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 Fri, 28 Jul 2017 17:17:25 +0100
Author : Robert Osfield Author : Robert Osfield
Updated version number, ChangeLog and AUTHORS file for 3.5.7 developer release 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 Fri, 28 Jul 2017 10:27:47 +0100
Author : OpenSceneGraph git repository Author : OpenSceneGraph git repository
Merge pull request #267 from kornerr/masterAdd osgemscripten example 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 Wed, 26 Jul 2017 12:54:37 +0100
Author : Robert Osfield Author : Robert Osfield
Replaced FindOurDCMTK.cmake usage with FindDCMTK.cmake Replaced FindOurDCMTK.cmake usage with FindDCMTK.cmake

View File

@ -699,7 +699,9 @@ NameCorrection nameCorrections[] =
{"WeSee", "", {"WeSee", "",
"Alois", "Wismer"}, "Alois", "Wismer"},
{"We", "See", {"We", "See",
"Alois", "Wismer"} "Alois", "Wismer"},
{"AnyOldName3", "",
"Chris", "Djali"}
}; };

View File

@ -74,14 +74,10 @@ int main(int argc, char** argv)
std::string url, username, password; std::string url, username, password;
while(arguments.read("--login",url, username, password)) while(arguments.read("--login",url, username, password))
{ {
if (!osgDB::Registry::instance()->getAuthenticationMap()) osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails(
{ url,
osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); new osgDB::AuthenticationDetails(username, password)
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails( );
url,
new osgDB::AuthenticationDetails(username, password)
);
}
} }
std::string device; std::string device;

View File

@ -336,14 +336,10 @@ int main( int argc, char **argv )
std::string url, username, password; std::string url, username, password;
while(arguments.read("--login",url, username, password)) while(arguments.read("--login",url, username, password))
{ {
if (!osgDB::Registry::instance()->getAuthenticationMap()) osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails(
{ url,
osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); new osgDB::AuthenticationDetails(username, password)
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails( );
url,
new osgDB::AuthenticationDetails(username, password)
);
}
} }

View File

@ -473,7 +473,6 @@ void ComputeNode::addDataMonitor(osg::Vec3 placement, osg::Vec3 relativePlacemen
pat->setName(labelCaption); pat->setName(labelCaption);
text->setText(pat->getName()); text->setText(pat->getName());
text->setBackdropType(osgText::Text::OUTLINE); text->setBackdropType(osgText::Text::OUTLINE);
text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET);
text->setBackdropOffset(0.05f); text->setBackdropOffset(0.05f);
text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
@ -773,7 +772,7 @@ void ComputeNode::initComputingSetup()
_dataArray->setBufferObject(_ssbo.get()); _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); statesetComputation->setAttributeAndModes(_ssbb.get(), osg::StateAttribute::ON);

View File

@ -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<osgText::Text*>(&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. // construct the viewer.
osgViewer::Viewer viewer; osgViewer::Viewer viewer(arguments);
viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES); viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
viewer.getCamera()->setNearFarRatio(0.00001f); viewer.getCamera()->setNearFarRatio(0.00001f);
@ -144,6 +204,12 @@ int main(int, char**)
csn->addChild(createFadeText(csn->getEllipsoidModel())); csn->addChild(createFadeText(csn->getEllipsoidModel()));
} }
if (arguments.argc()>1)
{
TextSettings textSettings(arguments);
root->accept(textSettings);
}
viewer.setCameraManipulator(new osgGA::TerrainManipulator); viewer.setCameraManipulator(new osgGA::TerrainManipulator);
return viewer.run(); return viewer.run();

View File

@ -3,6 +3,9 @@
#include <osg/io_utils> #include <osg/io_utils>
#include <osg/ArgumentParser> #include <osg/ArgumentParser>
#include <osg/Geode> #include <osg/Geode>
#include <osg/MatrixTransform>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgViewer/Viewer> #include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers> #include <osgViewer/ViewerEventHandlers>
#include <osgGA/StateSetManipulator> #include <osgGA/StateSetManipulator>
@ -56,80 +59,367 @@ osg::Camera* createOrthoCamera(double width, double height)
return camera; return camera;
} }
osgText::Text* createLabel(const std::string& l, const char* f, unsigned int size) typedef std::list<unsigned int> 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()"<<std::endl;
osg::ref_ptr<osgText::Font> 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(); osgText::Text* label = new osgText::Text();
osg::ref_ptr<osgText::Font> font = osgText::readRefFontFile(f);
label->setFont(font); settings.setText(*label);
label->setCharacterSize(size);
if (settings.scaleFontSizeToFontResolution)
{
label->setCharacterSize(size);
}
label->setFontResolution(size, size); label->setFontResolution(size, size);
label->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
label->setPosition(pos); label->setPosition(pos);
label->setAlignment(osgText::Text::LEFT_BOTTOM); label->setAlignment(osgText::Text::LEFT_BOTTOM);
// It seems to be important we do this last to get best results? // It seems to be important we do this last to get best results?
label->setText(l); label->setText(l);
textInfo(label); // textInfo(label);
pos.y() += size + 10.0f; pos.y() += label->getCharacterHeight()*2.0;
return label; return label;
} }
typedef std::list<unsigned int> Sizes; class KeyHandler : public osgGA::GUIEventHandler
{
public:
KeyHandler() {}
~KeyHandler() {}
bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
{
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&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 "<<define<<std::endl;
stateset->removeDefine(define);
}
else
{
OSG_NOTICE<<"Enabling "<<define<<std::endl;
stateset->setDefine(define);
}
}
};
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
osgViewer::Viewer viewer;
osg::ArgumentParser args(&argc, argv); osg::ArgumentParser args(&argc, argv);
osgViewer::Viewer viewer(args);
// Make sure we have the minimum args...
if(argc <= 2)
{
osg::notify(osg::FATAL) << "usage: " << args[0] << " fontfile size1 [size2 ...]" << std::endl;
return 1;
}
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::StatsHandler());
viewer.addEventHandler(new osgViewer::WindowSizeHandler()); viewer.addEventHandler(new osgViewer::WindowSizeHandler());
viewer.addEventHandler(new KeyHandler());
osg::Group* group = new osg::Group(); TextSettings settings;
osg::Camera* camera = createOrthoCamera(1280.0f, 1024.0f); settings.backgroundColor = viewer.getCamera()->getClearColor();
// Create the list of desired sizes. settings.read(args);
Sizes sizes;
for(int i = 2; i < argc; i++) viewer.getCamera()->setClearColor(settings.backgroundColor);
osg::ref_ptr<osg::Group> 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<osg::GraphicsContext> gc = viewer.getCamera()->getGraphicsContext();
osg::ref_ptr<const osg::GraphicsContext::Traits> traits = gc->getTraits();
// left half
{
osg::ref_ptr<osg::Camera> 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<osg::Camera> 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<osg::MatrixTransform> 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<osg::Program> program = new osg::Program;
std::string shaderFilename;
while(args.read("--shader", shaderFilename))
{
osg::ref_ptr<osg::Shader> shader = osgDB::readRefShaderFile(shaderFilename);
if (shader.get())
{
OSG_NOTICE<<"Loading shader "<<shaderFilename<<std::endl;
program->addShader(shader.get());
}
}
if (program->getNumShaders()>0)
{
OSG_NOTICE<<"Using shaders"<<std::endl;
root->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<osg::Geode> geode = new osg::Geode();
osg::Vec3 pos(0.0f, 0.0f, 0.0f);
// Add all of our osgText drawables. // 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; std::stringstream ss;
ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 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<osg::Geode> 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(); return viewer.run();
} }

View File

@ -188,7 +188,7 @@ struct IndirectTarget
} }
void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect ) 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->setInternalFormat( GL_R32I );
indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE); indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE);
indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false); indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false);
@ -199,11 +199,12 @@ struct IndirectTarget
{ {
std::vector<osg::DrawArraysIndirect*> newPrimitiveSets; std::vector<osg::DrawArraysIndirect*> newPrimitiveSets;
for(unsigned int j=0;j<indirectCommands->size(); ++j){ for(unsigned int j=0;j<indirectCommands->size(); ++j)
{
osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j ); osg::DrawArraysIndirect *ipr=new osg::DrawArraysIndirect( GL_TRIANGLES, j );
ipr->setIndirectCommandArray( indirectCommands); ipr->setIndirectCommandArray( indirectCommands.get());
newPrimitiveSets.push_back(ipr); newPrimitiveSets.push_back(ipr);
} }
geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() );
@ -215,7 +216,7 @@ struct IndirectTarget
else // use glMultiDrawArraysIndirect() else // use glMultiDrawArraysIndirect()
{ {
osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES ); osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES );
ipr->setIndirectCommandArray( indirectCommands ); ipr->setIndirectCommandArray( indirectCommands.get() );
geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() ); geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() );
geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr ); geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr );
} }
@ -236,6 +237,7 @@ struct IndirectTarget
instanceTarget->bindToImageUnit(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, osg::Texture::READ_WRITE); instanceTarget->bindToImageUnit(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, osg::Texture::READ_WRITE);
} }
void addIndirectCommandData( const std::string& uniformNamePrefix, int index, osg::StateSet* stateset ) void addIndirectCommandData( const std::string& uniformNamePrefix, int index, osg::StateSet* stateset )
{ {
std::string uniformName = uniformNamePrefix + char( '0' + index ); 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 ) void addIndirectTargetData( bool cullPhase, const std::string& uniformNamePrefix, int index, osg::StateSet* stateset )
{ {
std::string uniformName; std::string uniformName;
@ -257,6 +260,7 @@ struct IndirectTarget
stateset->addUniform( uniform ); stateset->addUniform( uniform );
stateset->setTextureAttribute( OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, instanceTarget.get() ); stateset->setTextureAttribute( OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, instanceTarget.get() );
} }
void addDrawProgram( const std::string& uniformBlockName, osg::StateSet* stateset ) void addDrawProgram( const std::string& uniformBlockName, osg::StateSet* stateset )
{ {
drawProgram->addBindUniformBlock(uniformBlockName, 1); drawProgram->addBindUniformBlock(uniformBlockName, 1);
@ -286,6 +290,7 @@ struct GPUCullData
instanceTypesUBB = new osg::UniformBufferBinding(1, instanceTypes.get(), 0, 0); instanceTypesUBB = new osg::UniformBufferBinding(1, instanceTypes.get(), 0, 0);
} }
void setUseMultiDrawArraysIndirect( bool value ) void setUseMultiDrawArraysIndirect( bool value )
{ {
useMultiDrawArraysIndirect = value; useMultiDrawArraysIndirect = value;
@ -297,6 +302,7 @@ struct GPUCullData
return; return;
targets[index] = IndirectTarget( agv, targetDrawProgram ); targets[index] = IndirectTarget( agv, targetDrawProgram );
} }
bool registerType(unsigned int typeID, unsigned int targetID, osg::Node* node, const osg::Vec4& lodDistances, float maxDensityPerSquareKilometer ) bool registerType(unsigned int typeID, unsigned int targetID, osg::Node* node, const osg::Vec4& lodDistances, float maxDensityPerSquareKilometer )
{ {
if( typeID >= instanceTypes->getData().size() ) if( typeID >= instanceTypes->getData().size() )
@ -328,6 +334,7 @@ struct GPUCullData
target->second.maxTargetQuantity += maxQuantity; target->second.maxTargetQuantity += maxQuantity;
return true; return true;
} }
// endRegister() method is called after all indirect targets and instance types are registered. // 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 // 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 // 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) : position(m), extraParams(params), idParams(typeID,id,0,0)
{ {
} }
osg::Vec3d getPosition() const osg::Vec3d getPosition() const
{ {
return position.getTrans(); return position.getTrans();
} }
osg::Matrixf position; osg::Matrixf position;
osg::Vec4f extraParams; osg::Vec4f extraParams;
osg::Vec4i idParams; osg::Vec4i idParams;
@ -705,10 +714,12 @@ struct ResetTexturesCallback : public osg::StateSet::Callback
ResetTexturesCallback() ResetTexturesCallback()
{ {
} }
void addTextureDirty( unsigned int texUnit ) void addTextureDirty( unsigned int texUnit )
{ {
texUnitsDirty.push_back(texUnit); texUnitsDirty.push_back(texUnit);
} }
void addTextureDirtyParams( unsigned int texUnit ) void addTextureDirtyParams( unsigned int texUnit )
{ {
texUnitsDirtyParams.push_back(texUnit); texUnitsDirtyParams.push_back(texUnit);
@ -748,6 +759,7 @@ struct InvokeMemoryBarrier : public osg::Drawable::DrawCallback
: _barriers(barriers) : _barriers(barriers)
{ {
} }
virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const
{ {
//DrawIndirectGLExtensions *ext = DrawIndirectGLExtensions::getExtensions( renderInfo.getContextID(), true ); //DrawIndirectGLExtensions *ext = DrawIndirectGLExtensions::getExtensions( renderInfo.getContextID(), true );
@ -836,11 +848,13 @@ osg::Group* createSimpleHouse( float detailRatio, const osg::Vec4& buildingColor
osg::ref_ptr<osg::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); osg::ref_ptr<osg::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor );
root->addChild( chimneyGeode.get() ); root->addChild( chimneyGeode.get() );
} }
{ {
osg::ref_ptr<osg::Cylinder> chimney = new osg::Cylinder( osg::Vec3( -5.5, 3.0, 16.5 ), 0.1, 1.0 ); osg::ref_ptr<osg::Cylinder> chimney = new osg::Cylinder( osg::Vec3( -5.5, 3.0, 16.5 ), 0.1, 1.0 );
osg::ref_ptr<osg::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); osg::ref_ptr<osg::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor );
root->addChild( chimneyGeode.get() ); root->addChild( chimneyGeode.get() );
} }
{ {
osg::ref_ptr<osg::Cylinder> chimney = new osg::Cylinder( osg::Vec3( -5.0, 3.0, 16.25 ), 0.1, 0.5 ); osg::ref_ptr<osg::Cylinder> chimney = new osg::Cylinder( osg::Vec3( -5.0, 3.0, 16.25 ), 0.1, 0.5 );
osg::ref_ptr<osg::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor ); osg::ref_ptr<osg::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor );
@ -1183,6 +1197,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback
for(; i<3*_quantityPerType; ++i) // speed of airplanes for(; i<3*_quantityPerType; ++i) // speed of airplanes
_speed.push_back( random( 10.0, 16.0 ) ); _speed.push_back( random( 10.0, 16.0 ) );
} }
virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable) virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)
{ {
if( nv->getVisitorType() != osg::NodeVisitor::UPDATE_VISITOR ) 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, 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 ); 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 for(;i<2*_quantityPerType;++i) //update cars
{ {
nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) ); 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, 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 ); 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 for(;i<3*_quantityPerType;++i) // update airplanes
{ {
nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) ); nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) );
@ -1251,6 +1268,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback
(*vertexArray)[index] = newPosition; (*vertexArray)[index] = newPosition;
return newPosition; return newPosition;
} }
void setRotationUsingRotSpeed( unsigned int index, unsigned int boneIndex, const osg::Matrix& zeroMatrix, double currentTime, double rotSpeed ) 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() ), // 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") ) if ( arguments.read("--skip-static") )
showStaticRendering = false; showStaticRendering = false;
if ( arguments.read("--skip-dynamic") ) if ( arguments.read("--skip-dynamic") )
showDynamicRendering = false; showDynamicRendering = false;
if ( arguments.read("--export-objects") ) if ( arguments.read("--export-objects") )
exportInstanceObjects = true; exportInstanceObjects = true;
if ( arguments.read("--use-multi-draw") ) if ( arguments.read("--use-multi-draw") )
useMultiDrawArraysIndirect = true; useMultiDrawArraysIndirect = true;
arguments.read("--instances-per-cell",instancesPerCell); arguments.read("--instances-per-cell",instancesPerCell);
arguments.read("--static-area-size",staticAreaSize); arguments.read("--static-area-size",staticAreaSize);
arguments.read("--dynamic-area-size",dynamicAreaSize); arguments.read("--dynamic-area-size",dynamicAreaSize);

View File

@ -44,6 +44,7 @@
#include <osgGA/TrackballManipulator> #include <osgGA/TrackballManipulator>
#include <osgViewer/Viewer> #include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgDB/ReadFile> #include <osgDB/ReadFile>
#include <osgDB/FileUtils> #include <osgDB/FileUtils>
@ -424,6 +425,9 @@ int main( int argc, char **argv )
// add the handler for doing the picking // add the handler for doing the picking
viewer.addEventHandler(new PickHandler(&viewer,updateText.get())); viewer.addEventHandler(new PickHandler(&viewer,updateText.get()));
// add the stats handler
viewer.addEventHandler(new osgViewer::StatsHandler);
osg::Group* root = new osg::Group(); osg::Group* root = new osg::Group();
root->addChild( setupGraph() ); root->addChild( setupGraph() );

View File

@ -41,6 +41,9 @@
#include <iostream> #include <iostream>
static bool s_useSDF = false;
class MyBillboardTransform : public osg::PositionAttitudeTransform class MyBillboardTransform : public osg::PositionAttitudeTransform
{ {
public: public:
@ -147,6 +150,12 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label
text->setFont(font); text->setFont(font);
text->setFontResolution(64,64); text->setFontResolution(64,64);
if (s_useSDF)
{
text->setShaderTechnique(osgText::ALL_FEATURES);
}
text->setAlignment(osgText::Text::CENTER_CENTER); text->setAlignment(osgText::Text::CENTER_CENTER);
text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setAxisAlignment(osgText::Text::XZ_PLANE);
text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin()))); 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->setFont(font);
text->setFontResolution(110,120); text->setFontResolution(110,120);
if (s_useSDF)
{
text->setShaderTechnique(osgText::ALL_FEATURES);
}
text->setAlignment(osgText::Text::RIGHT_CENTER); text->setAlignment(osgText::Text::RIGHT_CENTER);
text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setAxisAlignment(osgText::Text::XZ_PLANE);
text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f); 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->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->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::OUTLINE);
// text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); text->setBackdropOffset(0.03f);
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->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f)); text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f));
#endif
#if 1
text->setColorGradientMode(osgText::Text::OVERALL); text->setColorGradientMode(osgText::Text::OVERALL);
osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f); osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f);
osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f); osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f);
text->setColorGradientCorners(lightblue, blue, blue, lightblue); text->setColorGradientCorners(lightblue, blue, blue, lightblue);
#else
text->setColorGradientMode(osgText::Text::OVERALL); text->setText(label);
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
geode->addDrawable( text ); geode->addDrawable( text );
if (!subscript.empty()) if (!subscript.empty())
{ {
//osgText::Text* subscript = new osgText::Text(new osgText::TextureFont(font,45));
osgText::Text* subscriptText = new osgText::Text; osgText::Text* subscriptText = new osgText::Text;
subscriptText->setFont(font); subscriptText->setFont(font);
subscriptText->setText(subscript); 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:: Node* createBackdrop(const osg::Vec3& corner,const osg::Vec3& top,const osg::Vec3& right)
{ {
osg::Geometry* geom = new osg::Geometry; osg::Geometry* geom = new osg::Geometry;
osg::Vec3 normal = (corner-top)^(right-corner); osg::Vec3 normal = (corner-top)^(right-corner);
@ -475,6 +468,9 @@ int main( int argc, char **argv )
return 1; return 1;
} }
while(arguments.read("--sdf")) { s_useSDF = true; }
std::string label = "OpenSceneGraph"; std::string label = "OpenSceneGraph";
std::string subscript = ""; std::string subscript = "";

View File

@ -69,10 +69,24 @@ int main( int argc, char**argv )
arguments.read("--numX",MAXX); arguments.read("--numX",MAXX);
arguments.read("--numY",MAXY); arguments.read("--numY",MAXY);
bool MDIenable=true; enum PrimtiveSetUsage
{
MultiDraw,
MultiplePrimitiveSets,
SinglePrimitiveSet
};
PrimtiveSetUsage usage = MultiDraw;
if(arguments.read("--classic")) if(arguments.read("--classic"))
{ MDIenable=false; {
OSG_WARN<<"disabling MDI"<<std::endl; usage = MultiplePrimitiveSets;
OSG_WARN<<"disabling MDI, using multiple PrimitiveSet"<<std::endl;
}
if(arguments.read("--single"))
{
usage = SinglePrimitiveSet;
OSG_WARN<<"disabling MDI, using single PrimitiveSet"<<std::endl;
} }
osg::Geode* root( new osg::Geode ); osg::Geode* root( new osg::Geode );
@ -86,6 +100,7 @@ int main( int argc, char**argv )
osg::ref_ptr<osg::Geometry> geom=new osg::Geometry(); osg::ref_ptr<osg::Geometry> geom=new osg::Geometry();
geom->setUseVertexBufferObjects(true); geom->setUseVertexBufferObjects(true);
osg::BoundingBox bb; osg::BoundingBox bb;
bb.set(0,0,0,MAXX,0,MAXY); bb.set(0,0,0,MAXX,0,MAXY);
//set bounds by hand cause of the lack of support of basevertex in PrimitiveFunctors //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(); osg::Vec3Array * verts=new osg::Vec3Array();
for(int j =0 ; j<MAXY; ++j)
for(int j =0 ; j<MAXY; ++j) { {
for(int i =0 ; i<MAXX; ++i) { for(int i =0 ; i<MAXX; ++i)
{
///create indirect command ///create indirect command
osg::DrawElementsIndirectCommand cmd; osg::DrawElementsIndirectCommand cmd;
cmd.count=4; cmd.count=4;
@ -116,24 +131,58 @@ int main( int argc, char**argv )
cmd.baseVertex=verts->size(); cmd.baseVertex=verts->size();
mdicommands->push_back(cmd); 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]); verts->push_back(osg::Vec3(i,0,j)+myCoords[z]);
mdi->addElement(myIndices[z]); mdi->addElement(myIndices[z]);
} }
} }
} }
geom->setVertexArray(verts);
if(MDIenable) {
geom->addPrimitiveSet(mdi);
} else geom->setVertexArray(verts);
for(int i=0; i<MAXY*MAXX; ++i) {
osg::DrawElementsUInt *dre=new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP,4,myIndicesUI) ; switch(usage)
dre->setElementBufferObject(ebo); {
geom->addPrimitiveSet(dre); case(MultiDraw):
for(int z=0; z<4; z++)myIndicesUI[z]+=4; {
geom->addPrimitiveSet(mdi);
break;
} }
case(MultiplePrimitiveSets):
{
for(int i=0; i<MAXY*MAXX; ++i)
{
osg::ref_ptr<osg::DrawElementsUInt> 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<osg::DrawElementsUInt> primitives = new osg::DrawElementsUInt(GL_TRIANGLES);
primitives->setElementBufferObject(ebo.get());
geom->addPrimitiveSet(primitives.get());
unsigned int vi = 0;
for(int i=0; i<MAXY*MAXX; ++i)
{
primitives->push_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); root->addChild(geom);
osgViewer::Viewer viewer; osgViewer::Viewer viewer;
viewer.addEventHandler(new osgViewer::StatsHandler); viewer.addEventHandler(new osgViewer::StatsHandler);
viewer.setSceneData( root ); viewer.setSceneData( root );

View File

@ -621,8 +621,8 @@ struct TextCounterCallback : public osg::NodeCallback
if (text) if (text)
{ {
std::stringstream str; std::stringstream str;
str <<"Text Counter "<<_textCounter<<std::endl; str <<"Text Counter "<<_textCounter;
OSG_NOTICE<<"Udating text"<<str.str()<<std::endl; OSG_NOTICE<<"Updating text : "<<str.str()<<std::endl;
text->setText(str.str()); text->setText(str.str());
@ -670,7 +670,7 @@ int main(int argc, char** argv)
text->setUpdateCallback(new TextCounterCallback()); text->setUpdateCallback(new TextCounterCallback());
text->setFont("fonts/times.ttf"); text->setFont("fonts/times.ttf");
text->setAxisAlignment(osgText::Text::XZ_PLANE); text->setAxisAlignment(osgText::Text::XZ_PLANE);
text->setText("This is a counter test"); text->setText("Text Counter :");
viewer.setSceneData(text.get()); viewer.setSceneData(text.get());
} }

View File

@ -49,23 +49,34 @@ public:
{ {
if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up) if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Up)
{ {
m_Text3D->setCharacterSize(m_Text3D->getCharacterHeight() + 0.1); // failed m_Text3D->setCharacterSize(m_Text3D->getCharacterHeight() + 0.1);
OSG_NOTICE<<"m_Text3D->getCharacterHeight()="<<m_Text3D->getCharacterHeight()<<std::endl; OSG_NOTICE<<"m_Text3D->getCharacterHeight() = " << m_Text3D->getCharacterHeight() << std::endl;
} }
else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Down) else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Down)
{ {
m_Text3D->setCharacterDepth(m_Text3D->getCharacterDepth() + 0.1); // ok m_Text3D->setCharacterDepth(m_Text3D->getCharacterDepth() + 0.1);
OSG_NOTICE<<"m_Text3D->getCharacterDepth()="<<m_Text3D->getCharacterDepth()<<std::endl; OSG_NOTICE<<"m_Text3D->getCharacterDepth() = " << m_Text3D->getCharacterDepth() << std::endl;
} }
else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left) else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)
{ {
m_Text3D->setText("setText\nworks!", osgText::String::ENCODING_UTF8); // ok static int counter = 1;
OSG_NOTICE<<"m_Text3D->getText()="<<m_Text3D->getText().size()<<std::endl; if (counter%3 == 0)
m_Text3D->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) else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Right)
{ {
m_Text3D->setLineSpacing(m_Text3D->getLineSpacing() + 0.1); m_Text3D->setLineSpacing(m_Text3D->getLineSpacing() + 0.1);
OSG_NOTICE<<"m_Text3D->getLineSpacing()="<<m_Text3D->getLineSpacing()<<std::endl; OSG_NOTICE<<"m_Text3D->getLineSpacing() = " << m_Text3D->getLineSpacing() << std::endl;
} }
} }
@ -90,7 +101,7 @@ int main(int argc, char** argv)
if (!font) return 1; if (!font) return 1;
OSG_NOTICE<<"Read font "<<fontFile<<" font="<<font.get()<<std::endl; OSG_NOTICE<<"Read font "<<fontFile<<" font="<<font.get()<<std::endl;
std::string word("This is a new test."); std::string word("Press arrow keys.");
while (arguments.read("-w",word)) {} while (arguments.read("-w",word)) {}
osg::ref_ptr<osgText::Style> style = new osgText::Style; osg::ref_ptr<osgText::Style> 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) ); 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")) if (arguments.read("--add-axes"))
group->addChild(osgDB::readNodeFile("axes.osgt")); group->addChild(osgDB::readNodeFile("axes.osgt"));
std::string mode; std::string mode;
if (arguments.read("--character-size-mode", mode)) if (arguments.read("--character-size-mode", mode))
{ {
if (mode == "screen_coords") if (mode == "screen_coords")
{ {
text3D->setCharacterSizeMode(osgText::TextBase::SCREEN_COORDS); text3D->setCharacterSizeMode(osgText::TextBase::SCREEN_COORDS);
text3D->setCharacterSize(1080/4); text3D->setCharacterSize(1080/4);
} }
} }
viewer.addEventHandler(new Text3DAttributeHandler(text3D)); viewer.addEventHandler(new Text3DAttributeHandler(text3D));
} }

View File

@ -432,7 +432,6 @@ static void Internal_SetAlpha(NSBitmapImageRep *imageRep, unsigned char alpha_va
default_text->setAlignment(osgText::Text::CENTER_CENTER); default_text->setAlignment(osgText::Text::CENTER_CENTER);
default_text->setBackdropType(osgText::Text::OUTLINE); 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->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->setBackdropColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
default_text->setAxisAlignment(osgText::Text::XZ_PLANE); default_text->setAxisAlignment(osgText::Text::XZ_PLANE);

View File

@ -7,7 +7,7 @@
class EscapeHandler : public osgGA::GUIEventHandler class EscapeHandler : public osgGA::GUIEventHandler
{ {
public: public:
EscapeHandler() {} EscapeHandler() {}
bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) bool handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa)
@ -22,7 +22,7 @@ class EscapeHandler : public osgGA::GUIEventHandler
{ {
osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa); osgViewer::View* view = dynamic_cast<osgViewer::View*>(&aa);
if (view) view->getViewerBase()->setDone(true); if (view) view->getViewerBase()->setDone(true);
return true; return true;
} }
} }
@ -37,6 +37,8 @@ class EscapeHandler : public osgGA::GUIEventHandler
int main(int argc,char** argv) int main(int argc,char** argv)
{ {
osg::ArgumentParser arguments(&argc, argv); osg::ArgumentParser arguments(&argc, argv);
arguments.getApplicationUsage()->addCommandLineOption("--login <url> <username> <password>", "Provide authentication information for http file access.");
arguments.getApplicationUsage()->addCommandLineOption("--password <password>", "Provide password for any vnc url on command line not mentioned in --login.");
osgViewer::Viewer viewer(arguments); osgViewer::Viewer viewer(arguments);
osgWidget::GeometryHints hints(osg::Vec3(0.0f,0.0f,0.0f), 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; i<arguments.argc(); ++i) for(int i=1; i<arguments.argc(); ++i)
{ {
if (!arguments.isOption(i)) if (!arguments.isOption(i))
@ -60,15 +71,19 @@ int main(int argc,char** argv)
if (!password.empty()) if (!password.empty())
{ {
if (!osgDB::Registry::instance()->getAuthenticationMap()) osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap); const osgDB::AuthenticationMap* authenticationMap = osgDB::Registry::instance()->getOrCreateAuthenticationMap();
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password)); const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname);
if (details == NULL)
{
authenticationMap->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password));
}
} }
osg::ref_ptr<osgWidget::VncClient> vncClient = new osgWidget::VncClient; osg::ref_ptr<osgWidget::VncClient> vncClient = new osgWidget::VncClient;
if (vncClient->connect(arguments[i], hints)) if (vncClient->connect(arguments[i], hints))
{ {
group->addChild(vncClient.get()); group->addChild(vncClient.get());
hints.position.x() += 1.1f; hints.position.x() += 1.1f;
} }
} }

View File

@ -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->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
label->setLabel(l); label->setLabel(l);
/*
text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
text->setBackdropOffset(0.2f);
*/
return label; return label;
} }

View File

@ -20,6 +20,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <map>
namespace osg { namespace osg {
@ -319,9 +320,15 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
SHADER_GLES3 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; } 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; } void setKeystoneHint(bool enabled) { _keystoneHint = enabled; }
bool getKeystoneHint() const { return _keystoneHint; } 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.*/ /** helper function for computing the right eye view matrix.*/
virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const; 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: protected:
virtual ~DisplaySettings(); virtual ~DisplaySettings();
@ -415,6 +427,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
VertexBufferHint _vertexBufferHint; VertexBufferHint _vertexBufferHint;
ShaderHint _shaderHint; ShaderHint _shaderHint;
std::string _textShaderTechnique;
bool _keystoneHint; bool _keystoneHint;
FileNames _keystoneFileNames; FileNames _keystoneFileNames;
@ -422,6 +435,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
OSXMenubarBehavior _OSXMenubarBehavior; OSXMenubarBehavior _OSXMenubarBehavior;
typedef std::map<std::string, std::string> ValueMap;
mutable OpenThreads::Mutex _valueMapMutex;
mutable ValueMap _valueMap;
}; };
} }

View File

@ -17,6 +17,7 @@
#include <osg/BufferObject> #include <osg/BufferObject>
#include <osg/Vec2> #include <osg/Vec2>
#include <osg/Vec3> #include <osg/Vec3>
#include <osg/Vec3i>
#include <osg/Vec4> #include <osg/Vec4>
#include <osg/FrameStamp> #include <osg/FrameStamp>
#include <osg/StateAttribute> #include <osg/StateAttribute>
@ -68,6 +69,10 @@
#endif #endif
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE) #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_BITMAP 0x1A00
#define GL_COLOR_INDEX 0x1900 #define GL_COLOR_INDEX 0x1900
#define GL_INTENSITY12 0x804C #define GL_INTENSITY12 0x804C
@ -114,6 +119,38 @@
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273 #define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
#endif #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 #ifndef GL_DEPTH_COMPONENT
#define GL_DEPTH_COMPONENT 0x1902 #define GL_DEPTH_COMPONENT 0x1902
#endif #endif
@ -404,11 +441,17 @@ class OSG_EXPORT Image : public BufferData
static bool isPackedType(GLenum type); static bool isPackedType(GLenum type);
static GLenum computePixelFormat(GLenum pixelFormat); static GLenum computePixelFormat(GLenum pixelFormat);
static GLenum computeFormatDataType(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 computeBlockSize(GLenum pixelFormat, GLenum packing);
static unsigned int computeNumComponents(GLenum pixelFormat); static unsigned int computeNumComponents(GLenum pixelFormat);
static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type); static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type);
static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing); 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 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 computeNearestPowerOfTwo(int s,float bias=0.5f);
static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1); static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1);

View File

@ -168,8 +168,8 @@ public:
} }
/// get command array of this indirect primitive set /// get command array of this indirect primitive set
inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; } inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray.get(); }
inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray; } inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray.get(); }
///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride) ///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) ///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw)
@ -616,8 +616,8 @@ public:
if(!dynamic_cast<DrawIndirectBufferObject* >(_indirectCommandArray->getBufferObject())) if(!dynamic_cast<DrawIndirectBufferObject* >(_indirectCommandArray->getBufferObject()))
_indirectCommandArray->setBufferObject(new DrawIndirectBufferObject()); _indirectCommandArray->setBufferObject(new DrawIndirectBufferObject());
} }
inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray; } inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray.get(); }
inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray; } inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray.get(); }
protected: protected:

View File

@ -823,9 +823,12 @@ class OSG_EXPORT State : public Referenced
* during rendering. */ * during rendering. */
inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; } inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; }
/** Get the DisplaySettings */ /** Get the const DisplaySettings */
inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); } 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.*/ /** Set flag for early termination of the draw traversal.*/

View File

@ -34,6 +34,8 @@ public:
modifiedCount(0xffffffff), modifiedCount(0xffffffff),
active(false) {} 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*/) {} // = 0;
virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0; virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;

View File

@ -50,6 +50,7 @@ class OSG_EXPORT VertexAttribDivisor : public StateAttribute
COMPARE_StateAttribute_Types(VertexAttribDivisor,sa) COMPARE_StateAttribute_Types(VertexAttribDivisor,sa)
// compare each parameter in turn against the rhs. // compare each parameter in turn against the rhs.
COMPARE_StateAttribute_Parameter(_index)
COMPARE_StateAttribute_Parameter(_divisor) COMPARE_StateAttribute_Parameter(_divisor)
return 0; // passed all the above comparison macros, must be equal. return 0; // passed all the above comparison macros, must be equal.

View File

@ -134,7 +134,7 @@ public:
: _name(copy._name), _indentDelta(copy._indentDelta) {} : _name(copy._name), _indentDelta(copy._indentDelta) {}
void set( const char* name, int delta=0 ) void set( const char* name, int delta=0 )
{ _name = name, _indentDelta = delta; } { _name = name; _indentDelta = delta; }
std::string _name; std::string _name;
int _indentDelta; int _indentDelta;

View File

@ -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.*/ /** Set the password map to be used by plugins when access files from secure locations.*/
void setAuthenticationMap(AuthenticationMap* authenticationMap) { _authenticationMap = authenticationMap; } 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.*/ /** Get the password map to be used by plugins when access files from secure locations.*/
AuthenticationMap* getAuthenticationMap() { return _authenticationMap.get(); } AuthenticationMap* getAuthenticationMap() { return _authenticationMap.get(); }

View File

@ -27,6 +27,7 @@ namespace osgText {
// forward declare Font // forward declare Font
class Font; class Font;
class TextBase;
#ifdef OSG_PROVIDE_READFILE #ifdef OSG_PROVIDE_READFILE
/** Read a font from specified file. The filename may contain a path. /** Read a font from specified file. The filename may contain a path.
@ -84,13 +85,9 @@ public:
static osg::ref_ptr<Font>& getDefaultFont(); static osg::ref_ptr<Font>& getDefaultFont();
void setTexEnv(osg::TexEnv* texenv) { if (texenv) _texenv = texenv; } typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSets;
inline osg::TexEnv* getTexEnv() { return _texenv.get(); } StateSets& getCachedStateSets() { return _statesets; }
inline const osg::TexEnv* getTexEnv() const { return _texenv.get(); } const StateSets& getCachedStateSets() const { return _statesets; }
void setStateSet(osg::StateSet* stateset) { _stateset = stateset; }
osg::StateSet* getStateSet() { return _stateset.get(); }
const osg::StateSet* getStateSet() const { return _stateset.get(); }
/** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes and a font resolution.*/ /** 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.*/ * return true on success, return false when not supported.*/
virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; } 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. /** Set the size of texture to create to store the glyph images when rendering.
* Note, this doesn't affect already created Texture Glhph's.*/ * Note, this doesn't affect already created Texture Glhph's.*/
void setTextureSizeHint(unsigned int width,unsigned int height); void setTextureSizeHint(unsigned int width,unsigned int height);
@ -140,6 +124,9 @@ public:
void setMagFilterHint(osg::Texture::FilterMode mode); void setMagFilterHint(osg::Texture::FilterMode mode);
osg::Texture::FilterMode getMagFilterHint() const; osg::Texture::FilterMode getMagFilterHint() const;
void setMaxAnisotropy(float anis) { _maxAnisotropy = anis; }
float getMaxAnisotropy() const { return _maxAnisotropy; }
unsigned int getFontDepth() const { return _depth; } unsigned int getFontDepth() const { return _depth; }
void setNumberCurveSamples(unsigned int numSamples) { _numCurveSamples = numSamples; } void setNumberCurveSamples(unsigned int numSamples) { _numCurveSamples = numSamples; }
@ -170,13 +157,14 @@ public:
typedef std::vector< osg::ref_ptr<GlyphTexture> > GlyphTextureList; typedef std::vector< osg::ref_ptr<GlyphTexture> > GlyphTextureList;
GlyphTextureList& getGlyphTextureList() { return _glyphTextureList; } GlyphTextureList& getGlyphTextureList() { return _glyphTextureList; }
void assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique);
protected: protected:
virtual ~Font(); virtual ~Font();
void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph); void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph);
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList;
typedef std::map< unsigned int, osg::ref_ptr<Glyph> > GlyphMap; typedef std::map< unsigned int, osg::ref_ptr<Glyph> > GlyphMap;
typedef std::map< unsigned int, osg::ref_ptr<Glyph3D> > Glyph3DMap; typedef std::map< unsigned int, osg::ref_ptr<Glyph3D> > Glyph3DMap;
@ -185,8 +173,7 @@ protected:
mutable OpenThreads::Mutex _glyphMapMutex; mutable OpenThreads::Mutex _glyphMapMutex;
osg::ref_ptr<osg::TexEnv> _texenv; StateSets _statesets;
osg::ref_ptr<osg::StateSet> _stateset;
FontSizeGlyphMap _sizeGlyphMap; FontSizeGlyphMap _sizeGlyphMap;
GlyphTextureList _glyphTextureList; GlyphTextureList _glyphTextureList;
@ -195,13 +182,12 @@ protected:
// current active size of font // current active size of font
FontResolution _fontSize; FontResolution _fontSize;
unsigned int _margin;
float _marginRatio;
unsigned int _textureWidthHint; unsigned int _textureWidthHint;
unsigned int _textureHeightHint; unsigned int _textureHeightHint;
osg::Texture::FilterMode _minFilterHint; osg::Texture::FilterMode _minFilterHint;
osg::Texture::FilterMode _magFilterHint; osg::Texture::FilterMode _magFilterHint;
float _maxAnisotropy;
unsigned int _depth; unsigned int _depth;
unsigned int _numCurveSamples; unsigned int _numCurveSamples;
@ -247,8 +233,6 @@ public:
virtual bool getVerticalSize(float & /*ascender*/, float & /*descender*/) const { return false; } virtual bool getVerticalSize(float & /*ascender*/, float & /*descender*/) const { return false; }
}; };
}; };
} }

View File

@ -30,15 +30,6 @@
#include <OpenThreads/Mutex> #include <OpenThreads/Mutex>
// 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 { namespace osgText {
class Font; class Font;
@ -47,6 +38,14 @@ class Glyph3D;
class GlyphGeometry; class GlyphGeometry;
class GlyphTexture; 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 class OSGTEXT_EXPORT Glyph : public osg::Image
{ {
public: public:
@ -58,6 +57,9 @@ public:
unsigned int getGlyphCode() const { return _glyphCode; } 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; } void setWidth(float width) { _width = width; }
float getWidth() const { return _width; } float getWidth() const { return _width; }
@ -76,21 +78,33 @@ public:
void setVerticalAdvance(float advance); void setVerticalAdvance(float advance);
float getVerticalAdvance() const; float getVerticalAdvance() const;
void setTexture(GlyphTexture* texture); struct TextureInfo : public osg::Referenced
GlyphTexture* getTexture(); {
const GlyphTexture* getTexture() const; TextureInfo():
texture(0),
texelMargin(0.0f) {}
void setTexturePosition(int posX,int posY); TextureInfo(GlyphTexture* tex, int x, int y, const osg::Vec2& mintc, const osg::Vec2& maxtc, float margin):
int getTexturePositionX() const; texture(tex),
int getTexturePositionY() const; texturePositionX(x),
texturePositionY(y),
minTexCoord(mintc),
maxTexCoord(maxtc),
texelMargin(margin) {}
void setMinTexCoord(const osg::Vec2& coord); GlyphTexture* texture;
const osg::Vec2& getMinTexCoord() const; int texturePositionX;
int texturePositionY;
osg::Vec2 minTexCoord;
osg::Vec2 maxTexCoord;
float texelMargin;
};
void setMaxTexCoord(const osg::Vec2& coord); void setTextureInfo(ShaderTechnique technique, TextureInfo* info);
const osg::Vec2& getMaxTexCoord() const;
void subload() const; const TextureInfo* getTextureInfo(ShaderTechnique technique) const;
TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique);
protected: protected:
@ -99,6 +113,8 @@ protected:
Font* _font; Font* _font;
unsigned int _glyphCode; unsigned int _glyphCode;
FontResolution _fontResolution;
float _width; float _width;
float _height; float _height;
@ -108,15 +124,8 @@ protected:
osg::Vec2 _verticalBearing; osg::Vec2 _verticalBearing;
float _verticalAdvance; float _verticalAdvance;
GlyphTexture* _texture; typedef std::vector< osg::ref_ptr<TextureInfo> > TextureInfoList;
int _texturePosX; TextureInfoList _textureInfoList;
int _texturePosY;
osg::Vec2 _minTexCoord;
osg::Vec2 _maxTexCoord;
typedef osg::buffered_value<GLuint> GLObjectList;
mutable GLObjectList _globjList;
}; };
class OSGTEXT_EXPORT GlyphGeometry : public osg::Referenced 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.*/ /** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
virtual int compare(const osg::StateAttribute& rhs) const; 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 setShaderTechnique(ShaderTechnique technique) { _shaderTechnique = technique; }
void setGlyphImageMargin(unsigned int margin) { _margin = margin; }
unsigned int getGlyphImageMargin() const { return _margin; }
void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; } ShaderTechnique getShaderTechnique() const { return _shaderTechnique; }
float getGlyphImageMarginRatio() const { return _marginRatio; }
int getEffectMargin(const Glyph* glyph);
int getTexelMargin(const Glyph* glyph);
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY); bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
@ -277,14 +287,13 @@ protected:
virtual ~GlyphTexture(); virtual ~GlyphTexture();
void copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info);
// parameter used to compute the size and position of empty space ShaderTechnique _shaderTechnique;
// in the texture which could accommodate new glyphs.
int _margin; int _usedY;
float _marginRatio; int _partUsedX;
int _usedY; int _partUsedY;
int _partUsedX;
int _partUsedY;
typedef std::vector< osg::ref_ptr<Glyph> > GlyphRefList; typedef std::vector< osg::ref_ptr<Glyph> > GlyphRefList;
typedef std::vector< const Glyph* > GlyphPtrList; typedef std::vector< const Glyph* > GlyphPtrList;

View File

@ -36,15 +36,12 @@ public:
virtual const char* className() const { return "Text"; } virtual const char* className() const { return "Text"; }
virtual const char* libraryName() const { return "osgText"; } virtual const char* libraryName() const { return "osgText"; }
virtual void setFont(Font* font=0) { setFont(osg::ref_ptr<Font>(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.*/ /** Get the ShaderTechnique hint.*/
virtual void setFont(osg::ref_ptr<Font> font); 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 * Turns off writing to the depth buffer when rendering text. This only affects text
@ -70,31 +67,6 @@ public:
NONE 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 * BackdropType gives you a background shadow text behind your regular
* text. This helps give text extra contrast which can be useful when * text. This helps give text extra contrast which can be useful when
@ -149,18 +121,6 @@ public:
const osg::Vec4& getBackdropColor() const { return _backdropColor; } 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 enum ColorGradientMode
{ {
SOLID = 0, // a.k.a. ColorGradients off SOLID = 0, // a.k.a. ColorGradients off
@ -232,6 +192,20 @@ public:
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. // internal structures, variable and methods used for rendering of characters.
struct OSGTEXT_EXPORT GlyphQuads struct OSGTEXT_EXPORT GlyphQuads
@ -239,7 +213,7 @@ public:
typedef std::vector<Glyph*> Glyphs; typedef std::vector<Glyph*> Glyphs;
Glyphs _glyphs; Glyphs _glyphs;
Primitives _primitives; osg::ref_ptr<osg::DrawElements> _primitives;
GlyphQuads(); GlyphQuads();
GlyphQuads(const GlyphQuads& gq); GlyphQuads(const GlyphQuads& gq);
@ -284,6 +258,8 @@ protected:
virtual ~Text(); virtual ~Text();
virtual osg::StateSet* createStateSet();
Font* getActiveFont(); Font* getActiveFont();
const Font* getActiveFont() const; const Font* getActiveFont() const;
@ -302,7 +278,6 @@ protected:
virtual void computePositionsImplementation(); virtual void computePositionsImplementation();
void computeBackdropPositions();
void computeBackdropBoundingBox(); void computeBackdropBoundingBox();
void computeBoundingBoxMargin(); void computeBoundingBoxMargin();
@ -314,10 +289,10 @@ protected:
void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const; void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const;
ShaderTechnique _shaderTechnique;
bool _enableDepthWrites; bool _enableDepthWrites;
BackdropType _backdropType; BackdropType _backdropType;
BackdropImplementation _backdropImplementation;
float _backdropHorizontalOffset; float _backdropHorizontalOffset;
float _backdropVerticalOffset; float _backdropVerticalOffset;

View File

@ -53,6 +53,9 @@ public:
virtual void setFont(const std::string& fontfile); virtual void setFont(const std::string& fontfile);
/** Get the font. Return 0 if default is being used.*/ /** 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(); } const Font* getFont() const { return _font.get(); }
@ -284,6 +287,10 @@ protected:
virtual ~TextBase(); virtual ~TextBase();
virtual osg::StateSet* createStateSet();
virtual void assignStateSet();
void initArraysAndBuffers(); void initArraysAndBuffers();
osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const; osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const;

View File

@ -97,6 +97,9 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor
void apply(osg::Drawable& drawable); void apply(osg::Drawable& drawable);
void apply(osg::StateSet& stateset); void apply(osg::StateSet& stateset);
/** Do a compile traversal and then reset any state,*/
void compile(osg::Node& node);
protected: protected:
typedef std::set<osg::Drawable*> DrawableAppliedSet; typedef std::set<osg::Drawable*> DrawableAppliedSet;

View File

@ -52,8 +52,8 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
{ {
_parent = 0; _parent = 0;
_drawable = drawable; _drawable = drawable;
_projection = projection, _projection = projection;
_modelview = modelview, _modelview = modelview;
_depth = depth; _depth = depth;
_dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC); _dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC);
_traversalNumber = traversalNumber; _traversalNumber = traversalNumber;

View File

@ -37,10 +37,11 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub
_parent(0), _parent(0),
_window(0), _window(0),
_visualInfo(0), _visualInfo(0),
_fbConfig(0),
#ifdef OSG_USE_EGL #ifdef OSG_USE_EGL
_eglDisplay(0), _eglDisplay(0),
_eglSurface(0), _eglSurface(0),
#else
_fbConfig(0),
#endif #endif
_currentCursor(0), _currentCursor(0),
_initialized(false), _initialized(false),
@ -54,7 +55,7 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub
memset(_keyMap, 0, 32); memset(_keyMap, 0, 32);
init(); init();
if (valid()) if (valid())
{ {
setState( new osg::State ); 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<const GraphicsWindowX11*>(object)!=0; } virtual bool isSameKindAs(const Object* object) const { return dynamic_cast<const GraphicsWindowX11*>(object)!=0; }
virtual const char* libraryName() const { return "osgViewer"; } virtual const char* libraryName() const { return "osgViewer"; }
virtual const char* className() const { return "GraphicsWindowX11"; } virtual const char* className() const { return "GraphicsWindowX11"; }
@ -129,35 +130,35 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub
{ {
WindowData(Window window): WindowData(Window window):
_window(window) {} _window(window) {}
Window _window; Window _window;
}; };
public: public:
// X11 specific access functions // X11 specific access functions
Display* getEventDisplay() const { return _eventDisplay; } Display* getEventDisplay() const { return _eventDisplay; }
Display* getDisplayToUse() const ; Display* getDisplayToUse() const ;
Window& getParent() { return _parent; } Window& getParent() { return _parent; }
Window& getWindow() { return _window; } Window& getWindow() { return _window; }
Cursor getCurrentCursor() { return _currentCursor; } Cursor getCurrentCursor() { return _currentCursor; }
protected: protected:
~GraphicsWindowX11(); ~GraphicsWindowX11();
Cursor getOrCreateCursor(MouseCursor mouseShape); Cursor getOrCreateCursor(MouseCursor mouseShape);
bool createVisualInfo(); bool createVisualInfo();
bool createWindow(); bool createWindow();
bool setWindow(Window window); bool setWindow(Window window);
void init(); void init();
bool checkAndSendEventFullScreenIfNeeded(Display* display, int x, int y, int width, int height, bool windowDecoration); 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; int getModifierMask() const;
void syncLocks(); void syncLocks();
void flushKeyEvents(); void flushKeyEvents();
bool _valid; bool _valid;
Display* _eventDisplay; Display* _eventDisplay;
Window _parent; Window _parent;
Window _window; Window _window;
XVisualInfo* _visualInfo; XVisualInfo* _visualInfo;
GLXFBConfig _fbConfig;
#ifdef OSG_USE_EGL #ifdef OSG_USE_EGL
EGLDisplay _eglDisplay; EGLDisplay _eglDisplay;
EGLSurface _eglSurface; EGLSurface _eglSurface;
#else
GLXFBConfig _fbConfig;
#endif #endif
Cursor _currentCursor; Cursor _currentCursor;
Atom _deleteWindow; Atom _deleteWindow;
bool _initialized; bool _initialized;
bool _realized; bool _realized;
bool _ownsWindow; bool _ownsWindow;

View File

@ -118,7 +118,8 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
_swapMethod = vs._swapMethod; _swapMethod = vs._swapMethod;
_vertexBufferHint = vs._vertexBufferHint; _vertexBufferHint = vs._vertexBufferHint;
_shaderHint = vs._shaderHint;
setShaderHint(_shaderHint);
_keystoneHint = vs._keystoneHint; _keystoneHint = vs._keystoneHint;
_keystoneFileNames = vs._keystoneFileNames; _keystoneFileNames = vs._keystoneFileNames;
@ -250,23 +251,17 @@ void DisplaySettings::setDefaults()
// _vertexBufferHint = VERTEX_ARRAY_OBJECT; // _vertexBufferHint = VERTEX_ARRAY_OBJECT;
#if defined(OSG_GLES3_AVAILABLE) #if defined(OSG_GLES3_AVAILABLE)
_shaderHint = SHADER_GLES3; setShaderHint(SHADER_GLES3);
OSG_INFO<<"DisplaySettings::SHADER_GLES3"<<std::endl;
#elif defined(OSG_GLES2_AVAILABLE) #elif defined(OSG_GLES2_AVAILABLE)
_shaderHint = SHADER_GLES2; setShaderHint(SHADER_GLES2);
OSG_INFO<<"DisplaySettings::SHADER_GLES2"<<std::endl;
#elif defined(OSG_GL3_AVAILABLE) #elif defined(OSG_GL3_AVAILABLE)
_shaderHint = SHADER_GL3; setShaderHint(SHADER_GL3);
OSG_INFO<<"DisplaySettings::SHADER_GL3"<<std::endl;
#elif defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE) #elif defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE)
OSG_INFO<<"DisplaySettings::SHADER_NONE"<<std::endl; setShaderHint(SHADER_NONE);
_shaderHint = SHADER_NONE;
#else #else
OSG_INFO<<"DisplaySettings::SHADER_GL2"<<std::endl; setShaderHint(SHADER_GL2);
_shaderHint = SHADER_GL2;
#endif #endif
_keystoneHint = false; _keystoneHint = false;
_OSXMenubarBehavior = MENUBAR_AUTO_HIDE; _OSXMenubarBehavior = MENUBAR_AUTO_HIDE;
@ -390,6 +385,9 @@ static ApplicationUsageProxy DisplaySetting_e31(ApplicationUsage::ENVIRONMENTAL_
static ApplicationUsageProxy DisplaySetting_e32(ApplicationUsage::ENVIRONMENTAL_VARIABLE, static ApplicationUsageProxy DisplaySetting_e32(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
"OSG_VERTEX_BUFFER_HINT <value>", "OSG_VERTEX_BUFFER_HINT <value>",
"Set the hint to what backend osg::Geometry implementation to use. NO_PREFERENCE | VERTEX_BUFFER_OBJECT | VERTEX_ARRAY_OBJECT"); "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 <value>",
"Set the defafult osgText::ShaderTechnique. ALL_FEATURES | ALL | GREYSCALE | SIGNED_DISTANCE_FIELD | SDF | NO_TEXT_SHADER | NONE");
void DisplaySettings::readEnvironmentalVariables() void DisplaySettings::readEnvironmentalVariables()
{ {
@ -725,26 +723,30 @@ void DisplaySettings::readEnvironmentalVariables()
{ {
if (strcmp(ptr,"GL2")==0) if (strcmp(ptr,"GL2")==0)
{ {
_shaderHint = SHADER_GL2; setShaderHint(SHADER_GL2);
} }
else if (strcmp(ptr,"GL3")==0) else if (strcmp(ptr,"GL3")==0)
{ {
_shaderHint = SHADER_GL3; setShaderHint(SHADER_GL3);
} }
else if (strcmp(ptr,"GLES2")==0) else if (strcmp(ptr,"GLES2")==0)
{ {
_shaderHint = SHADER_GLES2; setShaderHint(SHADER_GLES2);
} }
else if (strcmp(ptr,"GLES3")==0) else if (strcmp(ptr,"GLES3")==0)
{ {
_shaderHint = SHADER_GLES3; setShaderHint(SHADER_GLES3);
} }
else if (strcmp(ptr,"NONE")==0) 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) 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, 0.0,0.0,1.0,0.0,
-es,0.0,0.0,1.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"<<std::endl;
break;
case(SHADER_GLES2) :
setValue("OSG_GLSL_VERSION", "");
setValue("OSG_PRECISION_FLOAT", "precision highp float;");
setValue("OSG_VARYING_IN", "varying");
setValue("OSG_VARYING_OUT", "varying");
OSG_NOTICE<<"DisplaySettings::SHADER_GLES2"<<std::endl;
break;
case(SHADER_GL3) :
setValue("OSG_GLSL_VERSION", "#version 330");
setValue("OSG_PRECISION_FLOAT", "");
setValue("OSG_VARYING_IN", "in");
setValue("OSG_VARYING_OUT", "out");
OSG_NOTICE<<"DisplaySettings::SHADER_GL3"<<std::endl;
break;
case(SHADER_GL2) :
setValue("OSG_GLSL_VERSION", "");
setValue("OSG_PRECISION_FLOAT", "");
setValue("OSG_VARYING_IN", "varying");
setValue("OSG_VARYING_OUT", "varying");
OSG_NOTICE<<"DisplaySettings::SHADER_GL2"<<std::endl;
break;
case(SHADER_NONE) :
setValue("OSG_GLSL_VERSION", "");
setValue("OSG_PRECISION_FLOAT", "");
setValue("OSG_VARYING_IN", "varying");
setValue("OSG_VARYING_OUT", "varying");
OSG_NOTICE<<"DisplaySettings::NONE"<<std::endl;
break;
}
}
}
void DisplaySettings::setValue(const std::string& name, const std::string& value)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_valueMapMutex);
_valueMap[name] = value;
}
bool DisplaySettings::getValue(const std::string& name, std::string& value, bool use_getenv_fallback) const
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_valueMapMutex);
ValueMap::iterator itr = _valueMap.find(name);
if (itr!=_valueMap.end())
{
value = itr->second;
OSG_INFO<<"DisplaySettings::getValue("<<name<<") found existing value = ["<<value<<"]"<<std::endl;
return true;
}
if (!use_getenv_fallback) return false;
const char* str = getenv(name.c_str());
if (str)
{
OSG_INFO<<"DisplaySettings::getValue("<<name<<") found getenv value = ["<<value<<"]"<<std::endl;
_valueMap[name] = value = str;
return true;
}
else
{
return false;
}
}

View File

@ -241,11 +241,17 @@ Image::Image(const Image& image,const CopyOp& copyop):
{ {
unsigned int size = image.getTotalSizeInBytesIncludingMipmaps(); unsigned int size = image.getTotalSizeInBytesIncludingMipmaps();
setData(new unsigned char [size],USE_NEW_DELETE); setData(new unsigned char [size],USE_NEW_DELETE);
unsigned char* dest_ptr = _data; if (unsigned char* dest_ptr = _data)
for(DataIterator itr(&image); itr.valid(); ++itr)
{ {
memcpy(dest_ptr, itr.data(), itr.size()); for(DataIterator itr(&image); itr.valid(); ++itr)
dest_ptr += itr.size(); {
memcpy(dest_ptr, itr.data(), itr.size());
dest_ptr += itr.size();
}
}
else
{
OSG_WARN<<"Warning: Image::Image(const Image&, const CopyOp&) out of memory, no image copy made."<<std::endl;
} }
} }
} }
@ -602,7 +608,36 @@ unsigned int Image::computeNumComponents(GLenum pixelFormat)
case(GL_BGRA_INTEGER_EXT): return 4; case(GL_BGRA_INTEGER_EXT): return 4;
case(GL_LUMINANCE_INTEGER_EXT): return 1; case(GL_LUMINANCE_INTEGER_EXT): return 1;
case(GL_LUMINANCE_ALPHA_INTEGER_EXT): return 2; case(GL_LUMINANCE_ALPHA_INTEGER_EXT): return 2;
case(GL_SRGB8) : return 3;
case(GL_SRGB8_ALPHA8) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_4x4_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_5x4_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_5x5_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_6x5_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_6x6_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_8x5_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_8x6_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_8x8_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_10x5_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_10x6_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_10x8_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_10x10_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_12x10_KHR) : return 4;
case (GL_COMPRESSED_RGBA_ASTC_12x12_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) : return 4;
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) : return 4;
default: default:
{ {
OSG_WARN<<"error pixelFormat = "<<std::hex<<pixelFormat<<std::dec<<std::endl; OSG_WARN<<"error pixelFormat = "<<std::hex<<pixelFormat<<std::dec<<std::endl;
@ -665,6 +700,51 @@ unsigned int Image::computePixelSizeInBits(GLenum format,GLenum type)
return 0; return 0;
default: break; default: break;
} }
switch (format)
{//handle GL_KHR_texture_compression_astc_hdr
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) :
{
osg::Vec3i footprint = computeBlockFootprint(format);
unsigned int pixelsPerBlock = footprint.x() * footprint.y();
unsigned int bitsPerBlock = computeBlockSize(format, 0);//16 x 8 = 128
unsigned int bitsPerPixel = bitsPerBlock / pixelsPerBlock;
if (bitsPerBlock == bitsPerPixel * pixelsPerBlock) {
OSG_WARN << "Image::computePixelSizeInBits(format,type) : bits per pixel (" << bitsPerPixel << ") is not an integer for GL_KHR_texture_compression_astc_hdr sizes other than 4x4 and 8x8." << std::endl;
return bitsPerPixel;
} else {
OSG_WARN << "Image::computePixelSizeInBits(format,type) : bits per pixel (" << bitsPerBlock << "/" << pixelsPerBlock << ") is not an integer for GL_KHR_texture_compression_astc_hdr size" << footprint.x() << "x" << footprint.y() << "." << std::endl;
}
return 0;
}
default: break;
}
switch(format) switch(format)
{ {
@ -725,6 +805,71 @@ unsigned int Image::computePixelSizeInBits(GLenum format,GLenum type)
} }
osg::Vec3i Image::computeBlockFootprint(GLenum pixelFormat) {
switch (pixelFormat)
{
case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) :
case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) :
case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) :
case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) :
return osg::Vec3i(4,4,4);//opengl 3d dxt: r value means (max)4 consecutive blocks in r direction packed into a slab.
case(GL_COMPRESSED_SIGNED_RED_RGTC1_EXT) :
case(GL_COMPRESSED_RED_RGTC1_EXT) :
case(GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT) :
case(GL_COMPRESSED_RED_GREEN_RGTC2_EXT) :
case(GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG) :
case(GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG) :
case(GL_ETC1_RGB8_OES) :
case(GL_COMPRESSED_RGB8_ETC2) :
case(GL_COMPRESSED_SRGB8_ETC2) :
case(GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2) :
case(GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2) :
case(GL_COMPRESSED_RGBA8_ETC2_EAC) :
case(GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC) :
case(GL_COMPRESSED_R11_EAC) :
case(GL_COMPRESSED_SIGNED_R11_EAC) :
case(GL_COMPRESSED_RG11_EAC) :
case(GL_COMPRESSED_SIGNED_RG11_EAC) :
return osg::Vec3i(4, 4, 1);//not sure about r
case(GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG) :
case(GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG) :
return osg::Vec3i(8, 4, 1);//no 3d texture support in pvrtc at all
case (GL_COMPRESSED_RGBA_ASTC_4x4_KHR) : return osg::Vec3i(4, 4, 1);
case (GL_COMPRESSED_RGBA_ASTC_5x4_KHR) : return osg::Vec3i(5, 4, 1);
case (GL_COMPRESSED_RGBA_ASTC_5x5_KHR) : return osg::Vec3i(5, 5, 1);
case (GL_COMPRESSED_RGBA_ASTC_6x5_KHR) : return osg::Vec3i(6, 5, 1);
case (GL_COMPRESSED_RGBA_ASTC_6x6_KHR) : return osg::Vec3i(6, 6, 1);
case (GL_COMPRESSED_RGBA_ASTC_8x5_KHR) : return osg::Vec3i(8, 5, 1);
case (GL_COMPRESSED_RGBA_ASTC_8x6_KHR) : return osg::Vec3i(8, 6, 1);
case (GL_COMPRESSED_RGBA_ASTC_8x8_KHR) : return osg::Vec3i(8, 8, 1);
case (GL_COMPRESSED_RGBA_ASTC_10x5_KHR) : return osg::Vec3i(10, 5, 1);
case (GL_COMPRESSED_RGBA_ASTC_10x6_KHR) : return osg::Vec3i(10, 6, 1);
case (GL_COMPRESSED_RGBA_ASTC_10x8_KHR) : return osg::Vec3i(10, 8, 1);
case (GL_COMPRESSED_RGBA_ASTC_10x10_KHR) : return osg::Vec3i(10, 10, 1);
case (GL_COMPRESSED_RGBA_ASTC_12x10_KHR) : return osg::Vec3i(12, 10, 1);
case (GL_COMPRESSED_RGBA_ASTC_12x12_KHR) : return osg::Vec3i(12, 12, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) : return osg::Vec3i(4, 4, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) : return osg::Vec3i(5, 4, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) : return osg::Vec3i(5, 5, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) : return osg::Vec3i(6, 5, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) : return osg::Vec3i(6, 6, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) : return osg::Vec3i(8, 5, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) : return osg::Vec3i(8, 6, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) : return osg::Vec3i(8, 8, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) : return osg::Vec3i(10, 5, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) : return osg::Vec3i(10, 6, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) : return osg::Vec3i(10, 8, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) : return osg::Vec3i(10, 10, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) : return osg::Vec3i(12, 10, 1);
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) : return osg::Vec3i(12, 12, 1);
default:
break;
}
return osg::Vec3i(1,1,1);
}
//returns the max(size of a 2D block in bytes,packing)
unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing) unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing)
{ {
switch(pixelFormat) switch(pixelFormat)
@ -761,6 +906,35 @@ unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing)
case(GL_COMPRESSED_RG11_EAC): case(GL_COMPRESSED_RG11_EAC):
case(GL_COMPRESSED_SIGNED_RG11_EAC): case(GL_COMPRESSED_SIGNED_RG11_EAC):
return osg::maximum(16u,packing); // block size of 16 return osg::maximum(16u,packing); // block size of 16
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 osg::maximum(16u, packing); // block size of 16
default: default:
break; break;
} }
@ -780,29 +954,18 @@ unsigned int Image::computeImageSizeInBytes(int width,int height, int depth, GLe
{ {
if (width<=0 || height<=0 || depth<=0) return 0; if (width<=0 || height<=0 || depth<=0) return 0;
// Taking advantage of the fact that int blockSize = computeBlockSize(pixelFormat, 0);
// DXT formats are defined as 4 successive numbers: if (blockSize > 0) {
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 osg::Vec3i footprint = computeBlockFootprint(pixelFormat);
// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 width = (width + footprint.x() - 1) / footprint.x();
// GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 height = (height + footprint.y() - 1) / footprint.y();
// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 unsigned int size = blockSize * width;
if( pixelFormat >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT && size = roudUpToMultiple(size, packing);
pixelFormat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ) size *= height;
{ size = roudUpToMultiple(size, slice_packing);
width = (width + 3) & ~3; size *= depth;
height = (height + 3) & ~3; size = roudUpToMultiple(size, image_packing);
} return size;
// 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;
} }
// compute size of one row // 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) ); 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) int Image::computeNearestPowerOfTwo(int s,float bias)
{ {
if ((s & (s-1))!=0) if ((s & (s-1))!=0)
@ -880,6 +1050,34 @@ bool Image::isCompressed() const
case(GL_COMPRESSED_SIGNED_R11_EAC): case(GL_COMPRESSED_SIGNED_R11_EAC):
case(GL_COMPRESSED_RG11_EAC): case(GL_COMPRESSED_RG11_EAC):
case(GL_COMPRESSED_SIGNED_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; return true;
default: default:
return false; return false;
@ -1189,7 +1387,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
unsigned char* data = new unsigned char[total_size]; unsigned char* data = new unsigned char[total_size];
if (!data) if (!data)
{ {
OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, now image read."<<std::endl; OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, no image read."<<std::endl;
return; return;
} }
@ -1256,7 +1454,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
unsigned char* data = new unsigned char[total_size]; unsigned char* data = new unsigned char[total_size];
if (!data) if (!data)
{ {
OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, now image read."<<std::endl; OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, no image read."<<std::endl;
return; return;
} }
@ -1409,8 +1607,38 @@ void Image::copySubImage(int s_offset, int t_offset, int r_offset, const osg::Im
return; return;
} }
void* data_destination = data(s_offset,t_offset,r_offset); unsigned char* data_destination = data(s_offset, t_offset, r_offset);
if (isCompressed())
{
osg::Vec3i footprint = computeBlockFootprint(_pixelFormat);
if (footprint.x() == 4 && footprint.y() == 4) {
if ((source->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; PixelStorageModes psm;
psm.pack_alignment = _packing; psm.pack_alignment = _packing;
psm.pack_row_length = _rowLength!=0 ? _rowLength : _s; 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_DXT1_EXT):
case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT): case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT):
case(GL_COMPRESSED_RGBA_S3TC_DXT5_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: default:
return false; 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 Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const
{ {
const unsigned char* ptr = data(s,t,r); if (isCompressed())
switch(_dataType)
{ {
case(GL_BYTE): return _readColor(_pixelFormat, (char*)ptr, 1.0f/128.0f); if (dxtc_tool::isDXTC(_pixelFormat)) {
case(GL_UNSIGNED_BYTE): return _readColor(_pixelFormat, (unsigned char*)ptr, 1.0f/255.0f); unsigned char color[4];
case(GL_SHORT): return _readColor(_pixelFormat, (short*)ptr, 1.0f/32768.0f); if (dxtc_tool::CompressedImageGetColor(color, s, t, r, _s, _t, _r, _pixelFormat, _data)) {
case(GL_UNSIGNED_SHORT): return _readColor(_pixelFormat, (unsigned short*)ptr, 1.0f/65535.0f); return Vec4(((float)color[0]) / 255.0f, ((float)color[1]) / 255.0f, ((float)color[2]) / 255.0f, ((float)color[3]) / 255.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); 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); return Vec4(1.0f,1.0f,1.0f,1.0f);
} }

View File

@ -20,6 +20,7 @@
#include <osg/Notify> #include <osg/Notify>
#include <osg/io_utils> #include <osg/io_utils>
#include "dxtctool.h"
namespace osg namespace osg
{ {
@ -716,6 +717,49 @@ OSG_EXPORT osg::Image* createImageWithOrientationConversion(const osg::Image* sr
unsigned int pixelSizeInBits = srcImage->getPixelSizeInBits(); unsigned int pixelSizeInBits = srcImage->getPixelSizeInBits();
unsigned int pixelSizeInBytes = pixelSizeInBits/8; unsigned int pixelSizeInBytes = pixelSizeInBits/8;
unsigned int pixelSizeRemainder = 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<osg::Image*>(srcImage);
}
for (int l = 0; l<depth; l+=4)
{
for (int r = 0; r<height; r+=4)
{
osg::Vec3i cp(srcOrigin.x() + columnDelta.x()*r + layerDelta.x()*l,
srcOrigin.y() + columnDelta.y()*r + layerDelta.y()*l,
srcOrigin.z() + columnDelta.z()*r + layerDelta.z()*l);
for (int c = 0; c<width; c+=4)
{
unsigned int src_blockIndex = (cp.x() >> 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) if (pixelSizeRemainder!=0)
{ {
OSG_NOTICE<<"Warning: createImageWithOrientationConversion(..) cannot handle non byte aligned pixel formats."<<std::endl; OSG_NOTICE<<"Warning: createImageWithOrientationConversion(..) cannot handle non byte aligned pixel formats."<<std::endl;

View File

@ -89,6 +89,19 @@ struct NoneOf
const char* _str; const char* _str;
}; };
// Replaces all occurrences of "from" with the contents of "to"
// It does only one pass, i.e. new matches created in a position before the current match are not replaced
void replaceAll(std::string& str, const std::string& from, const std::string& to)
{
std::string::size_type pos = 0;
while ((pos = str.find(from, pos)) != std::string::npos)
{
str.replace(pos, from.length(), to);
pos += to.length();
}
}
} }
using namespace osg; using namespace osg;
@ -618,30 +631,32 @@ void Shader::PerContextShader::compileShader(osg::State& state)
#endif #endif
std::string source = _shader->getShaderSource(); std::string source = _shader->getShaderSource();
if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms())) // if (_shader->getType()==osg::Shader::VERTEX && (state.getUseVertexAttributeAliasing() || state.getUseModelViewAndProjectionUniforms()))
{ {
state.convertVertexShaderSourceToOsgBuiltIns(source); 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; GLint compiled = GL_FALSE;
// OSG_NOTICE<<"Compiling PerContextShader "<<this<<" ShaderDefine="<<getDefineString()<<std::endl; // OSG_NOTICE<<"Compiling PerContextShader "<<this<<" DefineString="<<getDefineString()<<std::endl;
if (_defineStr.empty()) if (_defineStr.empty())
{ {
const GLchar* sourceText = reinterpret_cast<const GLchar*>(source.c_str()); const GLchar* sourceText = reinterpret_cast<const GLchar*>(source.c_str());
_extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL ); _extensions->glShaderSource( _glShaderHandle, 1, &sourceText, NULL );
if (osg::getNotifyLevel()>=osg::INFO)
{
std::string sourceWithLineNumbers = insertLineNumbers(source);
OSG_INFO << "\nCompiling A :" << _shader->getTypename()
<< " source:\n" << sourceWithLineNumbers << std::endl;
}
} }
else else
{ {
// Convert all windows line endings to \n
replaceAll(source, "\r\n", " \n");
std::string versionLine; std::string versionLine;
unsigned int lineNum = 0; unsigned int lineNum = 0;
@ -675,21 +690,40 @@ void Shader::PerContextShader::compileShader(osg::State& state)
if (!versionLine.empty()) if (!versionLine.empty())
{ {
// OSG_NOTICE<<"Shader::PerContextShader::compileShader() : Found #version, lineNum = "<<lineNum<<" ["<<versionLine<<"] new source = ["<<source<<"]"<<std::endl;
const GLchar* sourceText[3]; const GLchar* sourceText[3];
//OSG_NOTICE<<"glShaderSource() ["<<versionLine<<"] "<<std::endl<<"["<<_defineStr<<"], ["<<sourceText<<"]"<<std::endl;
sourceText[0] = reinterpret_cast<const GLchar*>(versionLine.c_str()); sourceText[0] = reinterpret_cast<const GLchar*>(versionLine.c_str());
sourceText[1] = reinterpret_cast<const GLchar*>(_defineStr.c_str()); sourceText[1] = reinterpret_cast<const GLchar*>(_defineStr.c_str());
sourceText[2] = reinterpret_cast<const GLchar*>(source.c_str()); sourceText[2] = reinterpret_cast<const GLchar*>(source.c_str());
_extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL ); _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 : ["<<std::endl<<versionLine<<"]"<<std::endl;
// OSG_NOTICE<<" DefineStr : ["<<std::endl<<_defineStr<<"]"<<std::endl;
// OSG_NOTICE<<" Source : ["<<std::endl<<source<<"]"<<std::endl;
} }
else else
{ {
const GLchar* sourceText[2]; const GLchar* sourceText[2];
//OSG_NOTICE<<"glShaderSource() ["<<_defineStr<<"], ["<<sourceText<<"]"<<std::endl;
sourceText[0] = reinterpret_cast<const GLchar*>(_defineStr.c_str()); sourceText[0] = reinterpret_cast<const GLchar*>(_defineStr.c_str());
sourceText[1] = reinterpret_cast<const GLchar*>(source.c_str()); sourceText[1] = reinterpret_cast<const GLchar*>(source.c_str());
_extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL ); _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 : ["<<std::endl<<_defineStr<<"]"<<std::endl;
// OSG_NOTICE<<" Source : ["<<std::endl<<source<<"]"<<std::endl;
} }
} }
_extensions->glCompileShader( _glShaderHandle ); _extensions->glCompileShader( _glShaderHandle );

View File

@ -1216,13 +1216,69 @@ namespace State_Utils
source.insert(declPos, qualifier + declarationPrefix + newStr + std::string(";\n")); 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 (pos<str.size() && ((pos=str.find_first_of("$'\"", pos)) != std::string::npos))
{
if (pos==str.size())
{
break;
}
if (str[pos]=='"' || str[pos]=='\'')
{
std::string::size_type start_quote = pos;
++pos;
pos = str.find(str[start_quote], pos);
}
else
{
std::string::size_type start_var = pos;
++pos;
pos = str.find_first_not_of("ABCDEFGHIJKLMNOPQRTSUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_", pos);
std::string var_str;
if (pos != std::string::npos)
{
replaceVar(state, str, start_var, pos-start_var);
pos = start_var;
}
else
{
replaceVar(state, str, start_var, str.size()-start_var);
pos = start_var;
}
}
}
}
} }
bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const
{ {
OSG_INFO<<"State::convertShaderSourceToOsgBuiltIns()"<<std::endl; OSG_DEBUG<<"State::convertShaderSourceToOsgBuiltIns()"<<std::endl;
OSG_DEBUG<<"++Before Converted source "<<std::endl<<source<<std::endl<<"++++++++"<<std::endl;
State_Utils::substitudeEnvVars(*this, source);
OSG_INFO<<"++Before Converted source "<<std::endl<<source<<std::endl<<"++++++++"<<std::endl;
std::string attributeQualifier("attribute "); std::string attributeQualifier("attribute ");
@ -1279,7 +1335,7 @@ bool State::convertVertexShaderSourceToOsgBuiltIns(std::string& source) const
} }
} }
OSG_INFO<<"-------- Converted source "<<std::endl<<source<<std::endl<<"----------------"<<std::endl; OSG_DEBUG<<"-------- Converted source "<<std::endl<<source<<std::endl<<"----------------"<<std::endl;
return true; return true;
} }

View File

@ -168,10 +168,10 @@ void Texture1D::apply(State& state) const
} }
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
{ {
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels);
// update the modified count to show that it is up to date. // update the modified count to show that it is up to date.
getModifiedCount(contextID) = _image->getModifiedCount(); 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); 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); applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels);
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0); 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; _textureObjectBuffer[contextID] = textureObject;
// unref image data? // unref image data?

View File

@ -202,12 +202,11 @@ void Texture2D::apply(State& state) const
} }
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) 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. // update the modified tag to show that it is up to date.
getModifiedCount(contextID) = _image->getModifiedCount(); getModifiedCount(contextID) = _image->getModifiedCount();
applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(),
_textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
} }
else if (_readPBuffer.valid()) else if (_readPBuffer.valid())
{ {
@ -224,6 +223,8 @@ void Texture2D::apply(State& state) const
applyTexParameters(GL_TEXTURE_2D,state); applyTexParameters(GL_TEXTURE_2D,state);
if (_image.valid()) getModifiedCount(contextID) = _image->getModifiedCount();
_subloadCallback->load(*this,state); _subloadCallback->load(*this,state);
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,_borderWidth); textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,_borderWidth);
@ -235,7 +236,6 @@ void Texture2D::apply(State& state) const
//glBindTexture( GL_TEXTURE_2D, handle ); //glBindTexture( GL_TEXTURE_2D, handle );
// update the modified tag to show that it is up to date. // 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()) else if (_image.valid() && _image->data())
{ {
@ -255,6 +255,9 @@ void Texture2D::apply(State& state) const
applyTexParameters(GL_TEXTURE_2D,state); 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()) if (textureObject->isAllocated() && image->supportsTextureSubloading())
{ {
//OSG_NOTICE<<"Reusing texture object"<<std::endl; //OSG_NOTICE<<"Reusing texture object"<<std::endl;
@ -270,9 +273,6 @@ void Texture2D::apply(State& state) const
textureObject->setAllocated(true); textureObject->setAllocated(true);
} }
// update the modified tag to show that it is up to date.
getModifiedCount(contextID) = image->getModifiedCount();
// unref image data? // unref image data?
if (isSafeToUnrefImageData(state) && image->getDataVariance()==STATIC) if (isSafeToUnrefImageData(state) && image->getDataVariance()==STATIC)
{ {

View File

@ -297,8 +297,8 @@ void Texture2DArray::apply(State& state) const
{ {
if (getModifiedCount(n,contextID) != image->getModifiedCount()) if (getModifiedCount(n,contextID) != image->getModifiedCount())
{ {
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
getModifiedCount(n,contextID) = image->getModifiedCount(); getModifiedCount(n,contextID) = image->getModifiedCount();
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
} }
n += image->r(); n += image->r();
} }
@ -380,8 +380,8 @@ void Texture2DArray::apply(State& state) const
{ {
if (getModifiedCount(n,contextID) != image->getModifiedCount()) if (getModifiedCount(n,contextID) != image->getModifiedCount())
{ {
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
getModifiedCount(n,contextID) = image->getModifiedCount(); getModifiedCount(n,contextID) = image->getModifiedCount();
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
} }
n += image->r(); n += image->r();
} }

View File

@ -249,12 +249,12 @@ void Texture3D::apply(State& state) const
} }
else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount()) 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. // update the modified count to show that it is up to date.
getModifiedCount(contextID) = _image->getModifiedCount(); 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(); textureObject->bind();
// update the modified count to show that it is up to date.
getModifiedCount(contextID) = _image->getModifiedCount();
applyTexParameters(GL_TEXTURE_3D,state); applyTexParameters(GL_TEXTURE_3D,state);
@ -298,9 +300,6 @@ void Texture3D::apply(State& state) const
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0); 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? // unref image data?
if (isSafeToUnrefImageData(state) && _image->getDataVariance()==STATIC) if (isSafeToUnrefImageData(state) && _image->getDataVariance()==STATIC)
{ {

View File

@ -163,6 +163,8 @@ void TextureBuffer::apply(State& state) const
const GLExtensions* extensions = state.get<GLExtensions>(); const GLExtensions* extensions = state.get<GLExtensions>();
if(_bufferData.valid() &&_modifiedCount[contextID]!=_bufferData->getModifiedCount() ) if(_bufferData.valid() &&_modifiedCount[contextID]!=_bufferData->getModifiedCount() )
{ {
_modifiedCount[contextID]=_bufferData->getModifiedCount() ;
GLBufferObject* glBufferObject = _bufferData->getBufferObject()->getOrCreateGLBufferObject(contextID); GLBufferObject* glBufferObject = _bufferData->getBufferObject()->getOrCreateGLBufferObject(contextID);
if (glBufferObject) if (glBufferObject)
{ {
@ -174,7 +176,6 @@ void TextureBuffer::apply(State& state) const
} }
_modifiedCount[contextID]=_bufferData->getModifiedCount() ;
} }
textureObject->bind(); textureObject->bind();
@ -198,6 +199,8 @@ void TextureBuffer::apply(State& state) const
{ {
const GLExtensions* extensions = state.get<GLExtensions>(); const GLExtensions* extensions = state.get<GLExtensions>();
_modifiedCount[contextID] = _bufferData->getModifiedCount();
textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_BUFFER); textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_BUFFER);
textureObject->_profile._internalFormat=_internalFormat; textureObject->_profile._internalFormat=_internalFormat;
textureObject->bind(); textureObject->bind();
@ -221,7 +224,6 @@ void TextureBuffer::apply(State& state) const
textureObject->bind(); textureObject->bind();
extensions->glTexBuffer(GL_TEXTURE_BUFFER, _internalFormat, glBufferObject->getGLObjectID()); extensions->glTexBuffer(GL_TEXTURE_BUFFER, _internalFormat, glBufferObject->getGLObjectID());
_modifiedCount[contextID] = _bufferData->getModifiedCount();
} }
} }

View File

@ -246,8 +246,8 @@ void TextureCubeMap::apply(State& state) const
const osg::Image* image = _images[n].get(); const osg::Image* image = _images[n].get();
if (image && getModifiedCount((Face)n,contextID) != image->getModifiedCount()) 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(); 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(); const osg::Image* image = _images[n].get();
if (image) if (image)
{ {
getModifiedCount((Face)n,contextID) = image->getModifiedCount();
if (textureObject->isAllocated()) if (textureObject->isAllocated())
{ {
applyTexImage2D_subload( state, faceTarget[n], image, _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels); 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); applyTexImage2D_load( state, faceTarget[n], image, _textureWidth, _textureHeight, _numMipmapLevels);
} }
getModifiedCount((Face)n,contextID) = image->getModifiedCount();
} }

View File

@ -204,10 +204,10 @@ void TextureRectangle::apply(State& state) const
} }
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount()) 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. // update the modified count to show that it is up to date.
getModifiedCount(contextID) = _image->getModifiedCount(); getModifiedCount(contextID) = _image->getModifiedCount();
applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat);
} }
} }
else if (_subloadCallback.valid()) else if (_subloadCallback.valid())

View File

@ -118,6 +118,8 @@ struct VertexArrayDispatch : public VertexArrayState::ArrayDispatch
{ {
VertexArrayDispatch() {} VertexArrayDispatch() {}
virtual const char* className() const { return "VertexArrayDispatch"; }
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array) virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
{ {
VAS_NOTICE<<" VertexArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl; VAS_NOTICE<<" VertexArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
@ -171,6 +173,8 @@ struct ColorArrayDispatch : public VertexArrayState::ArrayDispatch
{ {
ColorArrayDispatch() {} ColorArrayDispatch() {}
virtual const char* className() const { return "ColorArrayDispatch"; }
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array) virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
{ {
VAS_NOTICE<<" ColorArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl; VAS_NOTICE<<" ColorArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
@ -225,6 +229,8 @@ struct NormalArrayDispatch : public VertexArrayState::ArrayDispatch
{ {
NormalArrayDispatch() {} NormalArrayDispatch() {}
virtual const char* className() const { return "NormalArrayDispatch"; }
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array) virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
{ {
VAS_NOTICE<<" NormalArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl; VAS_NOTICE<<" NormalArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
@ -286,6 +292,8 @@ struct SecondaryColorArrayDispatch : public VertexArrayState::ArrayDispatch
{ {
SecondaryColorArrayDispatch() {} SecondaryColorArrayDispatch() {}
virtual const char* className() const { return "SecondaryColorArrayDispatch"; }
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array) virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
{ {
glEnableClientState(GL_SECONDARY_COLOR_ARRAY); glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
@ -331,6 +339,8 @@ struct FogCoordArrayDispatch : public VertexArrayState::ArrayDispatch
{ {
FogCoordArrayDispatch() {} FogCoordArrayDispatch() {}
virtual const char* className() const { return "FogCoordArrayDispatch"; }
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array) virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
{ {
glEnableClientState(GL_FOG_COORDINATE_ARRAY); glEnableClientState(GL_FOG_COORDINATE_ARRAY);
@ -367,6 +377,8 @@ struct TexCoordArrayDispatch : public VertexArrayState::ArrayDispatch
{ {
TexCoordArrayDispatch(unsigned int in_unit) : unit(in_unit) {} TexCoordArrayDispatch(unsigned int in_unit) : unit(in_unit) {}
virtual const char* className() const { return "TexCoordArrayDispatch"; }
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array) virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
{ {
VAS_NOTICE<<" TexCoordArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<") unit="<<unit<<std::endl; VAS_NOTICE<<" TexCoordArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<") unit="<<unit<<std::endl;
@ -436,6 +448,8 @@ struct VertexAttribArrayDispatch : public VertexArrayState::ArrayDispatch
{ {
VertexAttribArrayDispatch(unsigned int in_unit) : unit(in_unit) {} VertexAttribArrayDispatch(unsigned int in_unit) : unit(in_unit) {}
virtual const char* className() const { return "VertexAttribArrayDispatch"; }
inline void callVertexAttribPointer(GLExtensions* ext, const osg::Array* new_array, const GLvoid * ptr) inline void callVertexAttribPointer(GLExtensions* ext, const osg::Array* new_array, const GLvoid * ptr)
{ {
if (new_array->getPreserveDataType()) if (new_array->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) #if defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE) && !defined(OSG_GLES1_AVAILABLE)
lazyDisablingOfVertexAttributes(); unbindVertexBufferObject();
applyDisablingOfVertexAttributes(state);
//lazyDisablingOfVertexAttributes();
//applyDisablingOfVertexAttributes(state);
glInterleavedArrays( format, stride, pointer); glInterleavedArrays( format, stride, pointer);
#else #else

View File

@ -166,11 +166,28 @@ struct DXT1TexelsBlock
unsigned short color_1; // extreme unsigned short color_1; // extreme
unsigned int texels4x4; // interpolated colors (2 bits per texel) unsigned int texels4x4; // interpolated colors (2 bits per texel)
}; };
struct DXT3TexelsBlock
bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void * imageData)
{ {
// OSG_NOTICE<<"CompressedImageTranslucent("<<width<<", "<<height<<", "<<format<<", "<<imageData<<")"<<std::endl; unsigned short alpha4[4]; // alpha values (4 bits per texel) - 64 bits
unsigned short color_0; // colors at their
unsigned short color_1; // extreme
unsigned int texels4x4; // interpolated colors (2 bits per texel)
};
struct DXT5TexelsBlock
{
unsigned char alpha_0; // alpha at their
unsigned char alpha_1; // extreme
unsigned char alpha3[6]; // alpha index values (3 bits per texel)
unsigned short color_0; // colors at their
unsigned short color_1; // extreme
unsigned int texels4x4; // interpolated colors (2 bits per texel)
};
bool isCompressedImageTranslucent(size_t width, size_t height, GLenum format, void * imageData)
{
// OSG_NOTICE<<"isCompressedImageTranslucent("<<width<<", "<<height<<", "<<format<<", "<<imageData<<")"<<std::endl;
int blockCount = ((width + 3) >> 2) * ((height + 3) >> 2);
switch(format) switch(format)
{ {
case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT): 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 // Only do the check on the first mipmap level, and stop when we
// see the first alpha texel // see the first alpha texel
int i = (width*height)/16; int i = blockCount;
bool foundAlpha = false; while (i>0)
while ((!foundAlpha) && (i>0))
{ {
// See if this block might contain transparent texels // See if this block might contain transparent texels
if (texelsBlock->color_0<=texelsBlock->color_1) 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 // Scan the texels block for the '11' bit pattern that
// indicates a transparent texel // indicates a transparent texel
int j = 0; int j = 0;
while ((!foundAlpha) && (j < 32)) while (j < 32)
{ {
// Check for the '11' bit pattern on this texel // Check for the '11' bit pattern on this texel
if ( ((texelsBlock->texels4x4 >> j) & 0x03) == 0x03) 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): case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT):
return true; {
const DXT3TexelsBlock *texelsBlock = reinterpret_cast<const DXT3TexelsBlock*>(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): case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT):
return true; {
const DXT5TexelsBlock *texelsBlock = reinterpret_cast<const DXT5TexelsBlock*>(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: default:
break; break;
} }
@ -226,4 +298,361 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void
return false; 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<const DXT1TexelsBlock*>(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<const DXT3TexelsBlock*>(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<const DXT5TexelsBlock*>(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<const DXT1TexelsBlock*>(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<DXT1TexelsBlock*>(dst_block);
dst_texels4x4 = &dst_texelsBlock->texels4x4;
break;
}
case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) :
{
const DXT3TexelsBlock *src_texelsBlock = reinterpret_cast<const DXT3TexelsBlock*>(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<DXT3TexelsBlock*>(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<const DXT5TexelsBlock*>(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<DXT5TexelsBlock*>(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<const DXT1TexelsBlock*>(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<DXT1TexelsBlock*>(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<const DXT3TexelsBlock*>(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<DXT1TexelsBlock*>(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 } // namespace dxtc_tool

View File

@ -31,17 +31,18 @@
// Current version: 1.00 BETA 1 (27/08/2002) // Current version: 1.00 BETA 1 (27/08/2002)
// //
// Comment: Only works with DXTC mode supported by OpenGL. // Comment: Only works with DXTC mode supported by OpenGL.
// (currently: DXT1/DXT3/DXT5) // (currently: DXT1/DXT3/DXT5)
// //
// History: - // History: -
// //
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#ifndef DXTCTOOL_H #ifndef DXTCTOOL_H
#define DXTCTOOL_H #define DXTCTOOL_H
#include <osg/GL> #include <osg/GL>
#include <osg/Texture> #include <osg/Texture>
#include <osg/Vec3i>
#if defined(_MSC_VER) #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 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 class dxtc_pixels
{ {
public: public:
@ -102,7 +112,7 @@ protected:
inline bool SupportedFormat() const; inline bool SupportedFormat() const;
// Vertical flipping functions // Vertical flipping functions
void VFlip_DXT1() const; void VFlip_DXT1() const;
void VFlip_DXT3() const; void VFlip_DXT3() const;
void VFlip_DXT5() 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_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_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 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 // Block localization functions
inline void * GetBlock(size_t i, size_t j, size_t BlockSize) const; 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) { 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();
} }

View File

@ -16,21 +16,14 @@
using namespace osgDB; using namespace osgDB;
static long long prev_tellg = 0;
void InputIterator::checkStream() const void InputIterator::checkStream() const
{ {
if (_in->rdstate()&_in->failbit) if (_in->rdstate()&_in->failbit)
{ {
OSG_NOTICE<<"InputIterator::checkStream() : _in->rdstate() "<<_in->rdstate()<<", "<<_in->failbit<<std::endl; OSG_NOTICE<<"InputIterator::checkStream() : _in->rdstate() "<<_in->rdstate()<<", "<<_in->failbit<<std::endl;
OSG_NOTICE<<" _in->tellg() = "<<_in->tellg()<<std::endl; OSG_NOTICE<<" _in->tellg() = "<<_in->tellg()<<std::endl;
OSG_NOTICE<<" prev_tellg = "<<prev_tellg<<std::endl;
_failed = true; _failed = true;
} }
else
{
prev_tellg = _in->tellg();
}
} }
void InputIterator::readComponentArray( char* s, unsigned int numElements, unsigned int numComponentsPerElements, unsigned int componentSizeInBytes) void InputIterator::readComponentArray( char* s, unsigned int numElements, unsigned int numComponentsPerElements, unsigned int componentSizeInBytes)

View File

@ -278,19 +278,6 @@ void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize)
int width = fontSize.first; int width = fontSize.first;
int height = fontSize.second; int height = fontSize.second;
int maxAxis = std::max(width, height);
int margin = _facade->getGlyphImageMargin() + (int)((float)maxAxis * _facade->getGlyphImageMarginRatio());
if ((unsigned int)(width+2*margin) > _facade->getTextureWidthHint() ||
(unsigned int)(width+2*margin) > _facade->getTextureHeightHint())
{
OSG_WARN<<"Warning: FreeTypeFont::setSize("<<width<<","<<height<<") sizes too large,"<<std::endl;
width = _facade->getTextureWidthHint()-2*margin;
height = _facade->getTextureHeightHint()-2*margin;
OSG_WARN<<" sizes capped ("<<width<<","<<height<<") to fit int current glyph texture size."<<std::endl;
}
FT_Error error = FT_Set_Pixel_Sizes( _face, /* handle to face object */ FT_Error error = FT_Set_Pixel_Sizes( _face, /* handle to face object */
width, /* pixel_width */ width, /* pixel_width */
@ -351,6 +338,8 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u
osg::ref_ptr<osgText::Glyph> glyph = new osgText::Glyph(_facade, charcode); osg::ref_ptr<osgText::Glyph> glyph = new osgText::Glyph(_facade, charcode);
glyph->setFontResolution(fontRes);
unsigned int dataSize = width*height; unsigned int dataSize = width*height;
unsigned char* data = new unsigned char[dataSize]; 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;p<data+dataSize;) { *p++ = 0; } for(unsigned char* p=data;p<data+dataSize;) { *p++ = 0; }
glyph->setImage(width,height,1, glyph->setImage(width,height,1,
OSGTEXT_GLYPH_INTERNALFORMAT, GL_ALPHA,
OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, GL_ALPHA, GL_UNSIGNED_BYTE,
data, data,
osg::Image::USE_NEW_DELETE, osg::Image::USE_NEW_DELETE,
1); 1);
glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT);
// copy image across to osgText::Glyph image. // copy image across to osgText::Glyph image.
switch(glyphslot->bitmap.pixel_mode) switch(glyphslot->bitmap.pixel_mode)
{ {

View File

@ -90,7 +90,7 @@ void Text::write(DataOutputStream* out){
out->writeFloat(getBackdropVerticalOffset()); out->writeFloat(getBackdropVerticalOffset());
out->writeVec4(getBackdropColor()); out->writeVec4(getBackdropColor());
out->writeUInt(getBackdropImplementation()); out->writeUInt(4); // old DELAYED_DEPTH_WRITES
out->writeUInt(getColorGradientMode()); out->writeUInt(getColorGradientMode());
out->writeVec4(getColorGradientTopLeft()); out->writeVec4(getColorGradientTopLeft());
@ -213,7 +213,7 @@ void Text::read(DataInputStream* in){
setBackdropOffset(horizontalOffset,verticalOffset); setBackdropOffset(horizontalOffset,verticalOffset);
setBackdropColor(in->readVec4()); setBackdropColor(in->readVec4());
setBackdropImplementation((osgText::Text::BackdropImplementation) in->readUInt()); in->readUInt(); // read old BackdropImplementation value, no longer used
setColorGradientMode((osgText::Text::ColorGradientMode) in->readUInt()); setColorGradientMode((osgText::Text::ColorGradientMode) in->readUInt());
osg::Vec4 colorGradientTopLeft,colorGradientBottomLeft,colorGradientBottomRight,colorGradientTopRight; osg::Vec4 colorGradientTopLeft,colorGradientBottomLeft,colorGradientBottomRight,colorGradientTopRight;

View File

@ -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 ) void OBJWriterNodeVisitor::apply( osg::Geode &node )
{ {
pushStateSet(node.getStateSet()); pushStateSet(node.getStateSet());
_nameStack.push_back(node.getName()); _nameStack.push_back(node.getName());
osg::Matrix m = osg::computeLocalToWorld(getNodePath());
unsigned int count = node.getNumDrawables(); unsigned int count = node.getNumDrawables();
for ( unsigned int i = 0; i < count; i++ ) for ( unsigned int i = 0; i < count; i++ )
{ {
osg::Geometry *g = node.getDrawable( i )->asGeometry(); node.getDrawable( i )->accept(*this);
if ( g != NULL )
{
pushStateSet(g->getStateSet());
processGeometry(g,m);
popStateSet(g->getStateSet());
}
} }
popStateSet(node.getStateSet()); popStateSet(node.getStateSet());
_nameStack.pop_back(); _nameStack.pop_back();
} }

View File

@ -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()); pushStateSet(node.getStateSet());
_nameStack.push_back( node.getName().empty() ? node.className() : node.getName() ); _nameStack.push_back( node.getName().empty() ? node.className() : node.getName() );
@ -78,14 +79,6 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor {
traverse( node ); traverse( node );
_nameStack.pop_back(); _nameStack.pop_back();
popStateSet(node.getStateSet());
}
void traverse (osg::Node &node)
{
pushStateSet(node.getStateSet());
osg::NodeVisitor::traverse( node );
popStateSet(node.getStateSet()); popStateSet(node.getStateSet());
} }

View File

@ -142,7 +142,8 @@ public:
protected: protected:
struct ObjOptionsStruct { class ObjOptionsStruct {
public:
bool rotate; bool rotate;
bool noTesselateLargePolygons; bool noTesselateLargePolygons;
bool noTriStripPolygons; bool noTriStripPolygons;
@ -155,6 +156,17 @@ protected:
TextureAllocationMap textureUnitAllocation; TextureAllocationMap textureUnitAllocation;
/// Coordinates precision. /// Coordinates precision.
int precision; int precision;
ObjOptionsStruct()
{
rotate = true;
noTesselateLargePolygons = false;
noTriStripPolygons = false;
generateFacetNormals = false;
fixBlackMaterials = true;
noReverseFaces = false;
precision = std::numeric_limits<double>::digits10 + 2;
}
}; };
typedef std::map< std::string, osg::ref_ptr<osg::StateSet> > MaterialToStateSetMap; typedef std::map< std::string, osg::ref_ptr<osg::StateSet> > MaterialToStateSetMap;
@ -831,13 +843,6 @@ osg::Node* ReaderWriterOBJ::convertModelToSceneGraph(obj::Model& model, ObjOptio
ReaderWriterOBJ::ObjOptionsStruct ReaderWriterOBJ::parseOptions(const osgDB::ReaderWriter::Options* options) const ReaderWriterOBJ::ObjOptionsStruct ReaderWriterOBJ::parseOptions(const osgDB::ReaderWriter::Options* options) const
{ {
ObjOptionsStruct localOptions; 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<double>::digits10 + 2;
if (options!=NULL) if (options!=NULL)
{ {

View File

@ -546,7 +546,7 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor
} }
else if (_texcoord.valid()) else if (_texcoord.valid())
{ {
geom->setTexCoordArray(0, _texcoord); geom->setTexCoordArray(0, _texcoord.get());
} }
// If the model has normals, add them to the geometry // If the model has normals, add them to the geometry

View File

@ -307,6 +307,18 @@ class ReaderWriterPNG : public osgDB::ReaderWriter
pixelFormat = GL_RGBA; pixelFormat = GL_RGBA;
int internalFormat = pixelFormat; 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); png_destroy_read_struct(&png, &info, &endinfo);

View File

@ -398,17 +398,26 @@ class ReaderWriterVNC : public osgDB::ReaderWriter
options->getAuthenticationMap() : options->getAuthenticationMap() :
osgDB::Registry::instance()->getAuthenticationMap(); osgDB::Registry::instance()->getAuthenticationMap();
const osgDB::AuthenticationDetails* details = authenticationMap ? if (authenticationMap != NULL)
authenticationMap->getAuthenticationDetails(hostname) :
0;
// configure authentication if required.
if (details)
{ {
OSG_NOTICE<<"Passing in password = "<<details->password<<std::endl; const osgDB::AuthenticationDetails* details = authenticationMap->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; // configure authentication if required.
image->_password = details->password; 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()) if (options && !options->getOptionString().empty())

View File

@ -554,7 +554,10 @@ osg::ref_ptr<osg::Program> GeometryPool::getOrCreateProgram(LayerTypes& layerTyp
_programMap[layerTypes] = program; _programMap[layerTypes] = program;
// add shader that provides the lighting functions // 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 "<<program.get()<<std::endl; // OSG_NOTICE<<") creating new Program "<<program.get()<<std::endl;
{ {

View File

@ -0,0 +1,25 @@
char lighting_vert[] = "#pragma requires(LIGHTING)\n"
"\n"
"void directionalLight( int lightNum, vec3 normal, inout vec4 color )\n"
"{\n"
" vec3 n = normalize(gl_NormalMatrix * normal);\n"
"\n"
" float NdotL = dot( n, normalize(gl_LightSource[lightNum].position.xyz) );\n"
" NdotL = max( 0.0, NdotL );\n"
"\n"
" float NdotHV = dot( n, gl_LightSource[lightNum].halfVector.xyz );\n"
" NdotHV = max( 0.0, NdotHV );\n"
"#if 1\n"
" color *= gl_LightSource[lightNum].ambient +\n"
" gl_LightSource[lightNum].diffuse * NdotL;\n"
"#else\n"
" color *= gl_FrontLightModelProduct.sceneColor +\n"
" gl_FrontLightProduct[lightNum].ambient +\n"
" gl_FrontLightProduct[lightNum].diffuse * NdotL;\n"
"#endif\n"
"#if 0\n"
" if ( NdotL * NdotHV > 0.0 )\n"
" color += gl_FrontLightProduct[lightNum].specular * pow( NdotHV, gl_FrontMaterial.shininess );\n"
"#endif\n"
"}\n"
"\n";

View File

@ -125,5 +125,5 @@ char terrain_displacement_mapping_vert[] = "#version 120\n"
" vec3 position = gl_Vertex.xyz + gl_Normal.xyz * height_center;\n" " vec3 position = gl_Vertex.xyz + gl_Normal.xyz * height_center;\n"
" gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n" " gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n"
"\n" "\n"
"};\n" "}\n"
"\n"; "\n";

View File

@ -24,8 +24,11 @@ using namespace osgText;
DefaultFont::DefaultFont() DefaultFont::DefaultFont()
{ {
_fontSize = FontResolution(8,12);
_minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR; _minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR;
_magFilterHint = osg::Texture::NEAREST; _magFilterHint = osg::Texture::LINEAR;
constructGlyphs(); constructGlyphs();
} }
@ -198,14 +201,12 @@ void DefaultFont::constructGlyphs()
for(unsigned char* p=data;p<data+dataSize;) { *p++ = 0; } for(unsigned char* p=data;p<data+dataSize;) { *p++ = 0; }
glyph->setImage(sourceWidth,sourceHeight,1, glyph->setImage(sourceWidth,sourceHeight,1,
OSGTEXT_GLYPH_INTERNALFORMAT, GL_ALPHA,
OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE, GL_ALPHA, GL_UNSIGNED_BYTE,
data, data,
osg::Image::USE_NEW_DELETE, osg::Image::USE_NEW_DELETE,
1); 1);
glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT);
// now populate data array by converting bitmap into a luminance_alpha map. // now populate data array by converting bitmap into a luminance_alpha map.
unsigned char* ptr = rasters[i-32]; unsigned char* ptr = rasters[i-32];
unsigned char value_on = 255; unsigned char value_on = 255;
@ -233,6 +234,8 @@ void DefaultFont::constructGlyphs()
glyph->setVerticalBearing(osg::Vec2(0.5f,1.0f)); // top middle. glyph->setVerticalBearing(osg::Vec2(0.5f,1.0f)); // top middle.
glyph->setVerticalAdvance(sourceHeight*coord_scale); glyph->setVerticalAdvance(sourceHeight*coord_scale);
glyph->setFontResolution(fontRes);
addGlyph(fontRes,i,glyph.get()); addGlyph(fontRes,i,glyph.get());
} }
} }

View File

@ -32,81 +32,6 @@
using namespace osgText; using namespace osgText;
using namespace std; 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>& Font::getDefaultFont() osg::ref_ptr<Font>& Font::getDefaultFont()
{ {
static OpenThreads::Mutex s_DefaultFontMutex; static OpenThreads::Mutex s_DefaultFontMutex;
@ -299,67 +224,24 @@ osg::ref_ptr<Font> osgText::readRefFontStream(std::istream& stream, const osgDB:
Font::Font(FontImplementation* implementation): Font::Font(FontImplementation* implementation):
osg::Object(true), osg::Object(true),
_margin(1),
_marginRatio(0.02),
_textureWidthHint(1024), _textureWidthHint(1024),
_textureHeightHint(1024), _textureHeightHint(1024),
_minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR), _minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR),
_magFilterHint(osg::Texture::LINEAR), _magFilterHint(osg::Texture::LINEAR),
_maxAnisotropy(16),
_depth(1), _depth(1),
_numCurveSamples(10) _numCurveSamples(10)
{ {
setImplementation(implementation); 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"<<std::endl;
_stateset->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"<<std::endl;
osg::ref_ptr<osg::Program> 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"<<std::endl;
osg::ref_ptr<osg::Program> 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; 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); unsigned int osg_max_size = atoi(ptr);
if (osg_max_size<_textureWidthHint) _textureWidthHint = osg_max_size; if (osg_max_size<_textureWidthHint) _textureWidthHint = osg_max_size;
if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size; if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size;
} }
} }
Font::~Font() Font::~Font()
@ -390,26 +272,6 @@ std::string Font::getFileName() const
return std::string(); 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) void Font::setTextureSizeHint(unsigned int width,unsigned int height)
{ {
_textureWidthHint = width; _textureWidthHint = width;
@ -518,9 +380,6 @@ void Font::setThreadSafeRefUnref(bool threadSafe)
{ {
osg::Object::setThreadSafeRefUnref(threadSafe); osg::Object::setThreadSafeRefUnref(threadSafe);
if (_texenv.valid()) _texenv->setThreadSafeRefUnref(threadSafe);
if (_stateset.valid()) _stateset->setThreadSafeRefUnref(threadSafe);
for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin(); for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin();
itr!=_glyphTextureList.end(); itr!=_glyphTextureList.end();
++itr) ++itr)
@ -531,7 +390,12 @@ void Font::setThreadSafeRefUnref(bool threadSafe)
void Font::resizeGLObjectBuffers(unsigned int maxSize) 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(); for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin();
itr!=_glyphTextureList.end(); itr!=_glyphTextureList.end();
@ -543,7 +407,12 @@ void Font::resizeGLObjectBuffers(unsigned int maxSize)
void Font::releaseGLObjects(osg::State* state) const 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(); for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin();
itr!=_glyphTextureList.end(); itr!=_glyphTextureList.end();
@ -576,6 +445,10 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
_sizeGlyphMap[fontRes][charcode]=glyph; _sizeGlyphMap[fontRes][charcode]=glyph;
}
void Font::assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique)
{
int posX=0,posY=0; int posX=0,posY=0;
GlyphTexture* glyphTexture = 0; GlyphTexture* glyphTexture = 0;
@ -583,12 +456,12 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
itr!=_glyphTextureList.end() && !glyphTexture; itr!=_glyphTextureList.end() && !glyphTexture;
++itr) ++itr)
{ {
if ((*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get(); if ((*itr)->getShaderTechnique()==shaderTechnique && (*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get();
} }
if (glyphTexture) if (glyphTexture)
{ {
//cout << " found space for texture "<<glyphTexture<<" posX="<<posX<<" posY="<<posY<<endl; //cout << " Font::assignGlyphToGlyphTexture() found space for texture "<<glyphTexture<<" posX="<<posX<<" posY="<<posY<<endl;
} }
if (!glyphTexture) if (!glyphTexture)
@ -602,12 +475,11 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<<numberOfTexturesAllocated<<std::endl; OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<<numberOfTexturesAllocated<<std::endl;
// reserve enough space for the glyphs. // reserve enough space for the glyphs.
glyphTexture->setGlyphImageMargin(_margin); glyphTexture->setShaderTechnique(shaderTechnique);
glyphTexture->setGlyphImageMarginRatio(_marginRatio);
glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint); glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint);
glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint); glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint);
glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint); glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint);
glyphTexture->setMaxAnisotropy(8); glyphTexture->setMaxAnisotropy(_maxAnisotropy);
_glyphTextureList.push_back(glyphTexture); _glyphTextureList.push_back(glyphTexture);
@ -621,5 +493,4 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
// add the glyph into the texture. // add the glyph into the texture.
glyphTexture->addGlyph(glyph,posX,posY); glyphTexture->addGlyph(glyph,posX,posY);
} }

View File

@ -28,9 +28,34 @@
using namespace osgText; using namespace osgText;
using namespace std; 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(): GlyphTexture::GlyphTexture():
_margin(1),
_marginRatio(0.02f),
_usedY(0), _usedY(0),
_partUsedX(0), _partUsedX(0),
_partUsedY(0) _partUsedY(0)
@ -51,27 +76,52 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const
return 0; 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) bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
{ {
int maxAxis = osg::maximum(glyph->s(), glyph->t()); int width = glyph->s();
int margin = _margin + (int)((float)maxAxis * _marginRatio); int height = glyph->t();
int width = glyph->s()+2*margin; int margin = getTexelMargin(glyph);
int height = glyph->t()+2*margin;
// first check box (_partUsedX,_usedY) to (width,height) width += 2*margin;
if (width <= (getTextureWidth()-_partUsedX) && height += 2*margin;
height <= (getTextureHeight()-_usedY))
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. // can fit in existing row.
// record the position in which the texture will be stored. // record the position in which the texture will be stored.
posX = _partUsedX+margin; posX = partUsedX+margin;
posY = _usedY+margin; posY = usedY+margin;
// move used markers on. // move used markers on.
_partUsedX += width; _partUsedX = posX+width;
if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; if (_usedY+height>_partUsedY) _partUsedY = _usedY+height;
return true; return true;
@ -83,14 +133,14 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
{ {
// can fit next row. // can fit next row.
_partUsedX = 0; _partUsedX = 0;
_usedY = _partUsedY; _usedY = partUsedY;
posX = _partUsedX+margin; posX = _partUsedX+margin;
posY = _usedY+margin; posY = _usedY+margin;
// move used markers on. // move used markers on.
_partUsedX += width; _partUsedX = posX+width;
if (_usedY+height>_partUsedY) _partUsedY = _usedY+height; _partUsedY = _usedY+height;
return true; return true;
} }
@ -101,23 +151,237 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY) void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
if (!_image.valid()) createImage(); if (!_image.valid()) createImage();
_glyphs.push_back(glyph); _glyphs.push_back(glyph);
// set up the details of where to place glyph's image in the texture. osg::ref_ptr<Glyph::TextureInfo> info = new Glyph::TextureInfo(
glyph->setTexture(this); this,
glyph->setTexturePosition(posX,posY); posX, posY,
osg::Vec2( static_cast<float>(posX)/static_cast<float>(getTextureWidth()), static_cast<float>(posY)/static_cast<float>(getTextureHeight()) ), // minTexCoord
osg::Vec2( static_cast<float>(posX+glyph->s())/static_cast<float>(getTextureWidth()), static_cast<float>(posY+glyph->t())/static_cast<float>(getTextureHeight()) ), // maxTexCoord
float(getTexelMargin(glyph))); // margin
glyph->setMinTexCoord( osg::Vec2( static_cast<float>(posX)/static_cast<float>(getTextureWidth()), glyph->setTextureInfo(_shaderTechnique, info.get());
static_cast<float>(posY)/static_cast<float>(getTextureHeight()) ) );
glyph->setMaxTexCoord( osg::Vec2( static_cast<float>(posX+glyph->s())/static_cast<float>(getTextureWidth()),
static_cast<float>(posY+glyph->t())/static_cast<float>(getTextureHeight()) ) );
_image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); copyGlyphImage(glyph, info);
}
void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info)
{
_image->dirty(); _image->dirty();
if (_shaderTechnique<=GREYSCALE)
{
// OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<<this<<", glyph="<<glyph->getGlyphCode()<<std::endl;
// make sure the glyph image settings and the target image are consisent before copying.
glyph->setPixelFormat(_image->getPixelFormat());
glyph->setInternalTextureFormat(_image->getPixelFormat());
_image->copySubImage(info->texturePositionX, info->texturePositionY, 0, glyph);
return;
}
// OSG_NOTICE<<"GlyphTexture::copyGlyphImage() generating signed distance field. glyphTexture="<<this<<", glyph="<<glyph->getGlyphCode()<<std::endl;
int src_columns = glyph->s();
int src_rows = glyph->t();
unsigned char* src_data = glyph->data();
int dest_columns = _image->s();
int dest_rows = _image->t();
unsigned char* dest_data = _image->data(info->texturePositionX, info->texturePositionY);
int search_distance = getEffectMargin(glyph);
int left = -search_distance;
int right = glyph->s()+search_distance;
int lower = -search_distance;
int upper = glyph->t()+search_distance;
float multiplier = 1.0/255.0f;
float max_distance = sqrtf(float(search_distance)*float(search_distance)*2.0);
if ((left+info->texturePositionX)<0) left = -info->texturePositionX;
if ((right+info->texturePositionX)>=dest_columns) right = dest_columns-info->texturePositionX-1;
if ((lower+info->texturePositionY)<0) lower = -info->texturePositionY;
if ((upper+info->texturePositionY)>=dest_rows) upper = dest_rows-info->texturePositionY-1;
int num_components = osg::Image::computeNumComponents(_image->getPixelFormat());
int bytes_per_pixel = osg::Image::computePixelSizeInBits(_image->getPixelFormat(),_image->getDataType())/8;
int alpha_offset = (_image->getPixelFormat()==GL_LUMINANCE_ALPHA) ? 1 : 0;
int sdf_offset = (_image->getPixelFormat()==GL_LUMINANCE_ALPHA) ? 0 : 1;
unsigned char full_on = 255;
unsigned char mid_point = full_on/2;
float mid_point_f = float(mid_point)*multiplier;
for(int dr=lower; dr<=upper; ++dr)
{
for(int dc=left; dc<=right; ++dc)
{
unsigned char value = 0;
unsigned char center_value = 0;
if (dr>=0 && dr<src_rows && dc>=0 && dc<src_columns) center_value = *(src_data + dr*src_columns + dc);
float center_value_f = center_value*multiplier;
float min_distance = max_distance;
if (center_value>0 && center_value<full_on)
{
if (center_value_f>=mid_point_f)
{
min_distance = center_value_f-mid_point_f;
value = 128+(min_distance/max_distance)*127;
}
else
{
min_distance = mid_point_f-center_value_f;
value = 127-(min_distance/max_distance)*127;
}
}
else
{
for(int radius=1; radius<search_distance; ++radius)
{
for(int span=-radius; span<=radius; ++span)
{
{
// left
int dx = -radius;
int dy = span;
int c = dc+dx;
int r = dr+dy;
unsigned char local_value = 0;
if (r>=0 && r<src_rows && c>=0 && c<src_columns) local_value = *(src_data + r*src_columns + c);
if (local_value!=center_value)
{
float local_value_f = float(local_value)*multiplier;
float D = sqrtf(float(dx*dx) + float(dy*dy));
float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy));
float local_distance = sqrtf(float(radius*radius)+float(span*span));
if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier;
else local_distance += (local_value_f - mid_point_f)*local_multiplier;
if (local_distance<min_distance) min_distance = local_distance;
}
}
{
// top
int dx = span;
int dy = radius;
int c = dc+dx;
int r = dr+dy;
unsigned char local_value = 0;
if (r>=0 && r<src_rows && c>=0 && c<src_columns) local_value = *(src_data + r*src_columns + c);
if (local_value!=center_value)
{
float local_value_f = float(local_value)*multiplier;
float D = sqrtf(float(dx*dx) + float(dy*dy));
float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy));
float local_distance = sqrtf(float(radius*radius)+float(span*span));
if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier;
else local_distance += (local_value_f - mid_point_f)*local_multiplier;
if (local_distance<min_distance) min_distance = local_distance;
}
}
{
// right
int dx = radius;
int dy = span;
int c = dc+dx;
int r = dr+dy;
unsigned char local_value = 0;
if (r>=0 && r<src_rows && c>=0 && c<src_columns) local_value = *(src_data + r*src_columns + c);
if (local_value!=center_value)
{
float local_value_f = float(local_value)*multiplier;
float D = sqrtf(float(dx*dx) + float(dy*dy));
float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy));
float local_distance = sqrtf(float(radius*radius)+float(span*span));
if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier;
else local_distance += (local_value_f - mid_point_f)*local_multiplier;
if (local_distance<min_distance) min_distance = local_distance;
}
}
{
// bottom
int dx = span;
int dy = -radius;
int c = dc+dx;
int r = dr+dy;
unsigned char local_value = 0;
if (r>=0 && r<src_rows && c>=0 && c<src_columns) local_value = *(src_data + r*src_columns + c);
if (local_value!=center_value)
{
float local_value_f = float(local_value)*multiplier;
float D = sqrtf(float(dx*dx) + float(dy*dy));
float local_multiplier = (abs(dx)>abs(dy)) ? D/float(abs(dx)) : D/float(abs(dy));
float local_distance = sqrtf(float(radius*radius)+float(span*span));
if (center_value==0) local_distance += (mid_point_f-local_value_f)*local_multiplier;
else local_distance += (local_value_f - mid_point_f)*local_multiplier;
if (local_distance<min_distance) min_distance = local_distance;
}
}
}
}
if (center_value_f>=0.5)
{
value = 128+(min_distance/max_distance)*127;
}
else
{
value = 127-(min_distance/max_distance)*127;
}
}
unsigned char* dest_ptr = dest_data + (dr*dest_columns + dc)*bytes_per_pixel;
if (num_components==2)
{
// signed distance field value
*(dest_ptr+sdf_offset) = value;
// original alpha value from glyph image
*(dest_ptr+alpha_offset) = center_value;
}
else
{
*(dest_ptr) = value;
}
}
}
} }
void GlyphTexture::setThreadSafeRefUnref(bool threadSafe) void GlyphTexture::setThreadSafeRefUnref(bool threadSafe)
@ -147,22 +411,26 @@ osg::Image* GlyphTexture::createImage()
{ {
if (!_image) if (!_image)
{ {
_image = new osg::Image; OSG_INFO<<"GlyphTexture::createImage() : Creating image 0x"<<std::hex<<TEXTURE_IMAGE_FORMAT<<std::dec<<std::endl;
_image->allocateImage(getTextureWidth(), getTextureHeight(), 1, OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE);
memset(_image->data(), 0, _image->getTotalSizeInBytes());
for(GlyphRefList::iterator itr = _glyphs.begin(); _image = new osg::Image;
itr != _glyphs.end();
++itr) GLenum imageFormat = (_shaderTechnique<=GREYSCALE) ? OSGTEXT_GLYPH_ALPHA_FORMAT : OSGTEXT_GLYPH_SDF_FORMAT;
{ GLenum internalFormat = (_shaderTechnique<=GREYSCALE) ? OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT : OSGTEXT_GLYPH_SDF_INTERNALFORMAT;
Glyph* glyph = itr->get();
_image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph); _image->allocateImage(getTextureWidth(), getTextureHeight(), 1, imageFormat, GL_UNSIGNED_BYTE);
} _image->setInternalTextureFormat(internalFormat);
memset(_image->data(), 0, _image->getTotalSizeInBytes());
} }
return _image.get(); 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. // 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): Glyph::Glyph(Font* font, unsigned int glyphCode):
_font(font), _font(font),
@ -172,12 +440,7 @@ Glyph::Glyph(Font* font, unsigned int glyphCode):
_horizontalBearing(0.0f,0.f), _horizontalBearing(0.0f,0.f),
_horizontalAdvance(0.f), _horizontalAdvance(0.f),
_verticalBearing(0.0f,0.f), _verticalBearing(0.0f,0.f),
_verticalAdvance(0.f), _verticalAdvance(0.f)
_texture(0),
_texturePosX(0),
_texturePosY(0),
_minTexCoord(0.0f,0.0f),
_maxTexCoord(0.0f,0.0f)
{ {
setThreadSafeRefUnref(true); setThreadSafeRefUnref(true);
} }
@ -198,67 +461,37 @@ const osg::Vec2& Glyph::getVerticalBearing() const { return _verticalBearing; }
void Glyph::setVerticalAdvance(float advance) { _verticalAdvance=advance; } void Glyph::setVerticalAdvance(float advance) { _verticalAdvance=advance; }
float Glyph::getVerticalAdvance() const { return _verticalAdvance; } float Glyph::getVerticalAdvance() const { return _verticalAdvance; }
void Glyph::setTexture(GlyphTexture* texture) { _texture = texture; } void Glyph::setTextureInfo(ShaderTechnique technique, TextureInfo* info)
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
{ {
GLenum errorNo = glGetError(); if (technique>=_textureInfoList.size())
if (errorNo!=GL_NO_ERROR)
{ {
const GLubyte* msg = osg::gluErrorString(errorNo); _textureInfoList.resize(technique+1);
if (msg) { OSG_WARN<<"before Glyph::subload(): detected OpenGL error: "<<msg<<std::endl; }
else { OSG_WARN<<"before Glyph::subload(): detected OpenGL error number: "<<errorNo<<std::endl; }
}
if(s() <= 0 || t() <= 0)
{
OSG_INFO<<"Glyph::subload(): texture sub-image width and/or height of 0, ignoring operation."<<std::endl;
return;
}
glPixelStorei(GL_UNPACK_ALIGNMENT,getPacking());
#if !defined(OSG_GLES1_AVAILABLE) && !defined(OSG_GLES2_AVAILABLE)
glPixelStorei(GL_UNPACK_ROW_LENGTH,getRowLength());
#endif
glTexSubImage2D(GL_TEXTURE_2D,0,
_texturePosX,_texturePosY,
s(),t(),
(GLenum)getPixelFormat(),
(GLenum)getDataType(),
data());
errorNo = glGetError();
if (errorNo!=GL_NO_ERROR)
{
const GLubyte* msg = osg::gluErrorString(errorNo);
if (msg) { OSG_WARN<<"after Glyph::subload() : detected OpenGL error: "<<msg<<std::endl; }
else { OSG_WARN<<"after Glyph::subload() : detected OpenGL error number: "<<errorNo<<std::endl; }
OSG_WARN<< "\tglTexSubImage2D(0x"<<hex<<GL_TEXTURE_2D<<dec<<" ,"<<0<<"\t"<<std::endl<<
"\t "<<_texturePosX<<" ,"<<_texturePosY<<std::endl<<
"\t "<<s()<<" ,"<<t()<<std::endl<<hex<<
"\t 0x"<<(GLenum)getPixelFormat()<<std::endl<<
"\t 0x"<<(GLenum)getDataType()<<std::endl<<
"\t "<<static_cast<const void*>(data())<<");"<<dec<<std::endl;
} }
_textureInfoList[technique] = info;
} }
const Glyph::TextureInfo* Glyph::getTextureInfo(ShaderTechnique technique) const
{
return (technique<_textureInfoList.size()) ? _textureInfoList[technique].get() : 0;
}
Glyph::TextureInfo* Glyph::getOrCreateTextureInfo(ShaderTechnique technique)
{
if (technique>=_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): Glyph3D::Glyph3D(Font* font, unsigned int glyphCode):
osg::Referenced(true), osg::Referenced(true),
_font(font), _font(font),

View File

@ -25,13 +25,19 @@
#include <osgDB/ReadFile> #include <osgDB/ReadFile>
#include <sstream>
#include <iomanip>
#define DEBUG_MESSAGE_LEVEL osg::INFO
#define DEBUG_MESSAGE osg::notify(DEBUG_MESSAGE_LEVEL)
using namespace osg; using namespace osg;
using namespace osgText; using namespace osgText;
Text::Text(): Text::Text():
_shaderTechnique(GREYSCALE),
_enableDepthWrites(true), _enableDepthWrites(true),
_backdropType(NONE), _backdropType(NONE),
_backdropImplementation(DELAYED_DEPTH_WRITES),
_backdropHorizontalOffset(0.07f), _backdropHorizontalOffset(0.07f),
_backdropVerticalOffset(0.07f), _backdropVerticalOffset(0.07f),
_backdropColor(0.0f, 0.0f, 0.0f, 1.0f), _backdropColor(0.0f, 0.0f, 0.0f, 1.0f),
@ -42,13 +48,24 @@ Text::Text():
_colorGradientTopRight(1.0f, 1.0f, 1.0f, 1.0f) _colorGradientTopRight(1.0f, 1.0f, 1.0f, 1.0f)
{ {
_supportsVertexBufferObjects = true; _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): Text::Text(const Text& text,const osg::CopyOp& copyop):
osgText::TextBase(text,copyop), osgText::TextBase(text,copyop),
_shaderTechnique(text._shaderTechnique),
_enableDepthWrites(text._enableDepthWrites), _enableDepthWrites(text._enableDepthWrites),
_backdropType(text._backdropType), _backdropType(text._backdropType),
_backdropImplementation(text._backdropImplementation),
_backdropHorizontalOffset(text._backdropHorizontalOffset), _backdropHorizontalOffset(text._backdropHorizontalOffset),
_backdropVerticalOffset(text._backdropVerticalOffset), _backdropVerticalOffset(text._backdropVerticalOffset),
_backdropColor(text._backdropColor), _backdropColor(text._backdropColor),
@ -65,21 +82,170 @@ Text::~Text()
{ {
} }
void Text::setFont(osg::ref_ptr<Font> font)
void Text::setShaderTechnique(ShaderTechnique technique)
{ {
if (_font==font) return; if (_shaderTechnique==technique) return;
osg::StateSet* previousFontStateSet = _font.valid() ? _font->getStateSet() : Font::getDefaultFont()->getStateSet(); _shaderTechnique = technique;
osg::StateSet* newFontStateSet = font.valid() ? font->getStateSet() : Font::getDefaultFont()->getStateSet();
if (getStateSet() == previousFontStateSet) assignStateSet();
{
setStateSet( newFontStateSet );
}
TextBase::setFont(font); computeGlyphRepresentation();
} }
osg::StateSet* Text::createStateSet()
{
Font* activeFont = getActiveFont();
if (!activeFont) return 0;
Font::StateSets& statesets = activeFont->getCachedStateSets();
std::stringstream ss;
ss<<std::fixed<<std::setprecision(3);
osg::StateSet::DefineList defineList;
if (_backdropType!=NONE)
{
ss.str("");
ss << "vec4("<<_backdropColor.r()<<", "<<_backdropColor.g()<<", "<<_backdropColor.b()<<", "<<_backdropColor.a()<<")";
defineList["BACKDROP_COLOR"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON);
if (_backdropType==OUTLINE)
{
ss.str("");
ss <<_backdropHorizontalOffset;
defineList["OUTLINE"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON);
}
else
{
osg::Vec2 offset(_backdropHorizontalOffset, _backdropVerticalOffset);
switch(_backdropType)
{
case(DROP_SHADOW_BOTTOM_RIGHT) : offset.set(_backdropHorizontalOffset, -_backdropVerticalOffset); break;
case(DROP_SHADOW_CENTER_RIGHT) : offset.set(_backdropHorizontalOffset, 0.0f); break;
case(DROP_SHADOW_TOP_RIGHT) : offset.set(_backdropHorizontalOffset, _backdropVerticalOffset); break;
case(DROP_SHADOW_BOTTOM_CENTER) : offset.set(0.0f, -_backdropVerticalOffset); break;
case(DROP_SHADOW_TOP_CENTER) : offset.set(0.0f, _backdropVerticalOffset); break;
case(DROP_SHADOW_BOTTOM_LEFT) : offset.set(-_backdropHorizontalOffset, -_backdropVerticalOffset); break;
case(DROP_SHADOW_CENTER_LEFT) : offset.set(-_backdropHorizontalOffset, 0.0f); break;
case(DROP_SHADOW_TOP_LEFT) : offset.set(-_backdropHorizontalOffset, _backdropVerticalOffset); break;
default : break;
}
ss.str("");
ss << "vec2("<<offset.x()<<", "<<offset.y()<<")";
defineList["SHADOW"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON);
}
}
{
ss<<std::fixed<<std::setprecision(1);
ss.str("");
ss << float(_fontSize.second);
defineList["GLYPH_DIMENSION"] = osg::StateSet::DefinePair(ss.str(), osg::StateAttribute::ON);
ss.str("");
ss << float(activeFont->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:"<<defineList.size()<<std::endl;
for(osg::StateSet::DefineList::iterator itr = defineList.begin();
itr != defineList.end();
++itr)
{
OSG_NOTICE<<" define["<<itr->first<<"] = "<<itr->second.first<<std::endl;
}
#endif
if (!statesets.empty())
{
for(Font::StateSets::iterator itr = statesets.begin();
itr != statesets.end();
++itr)
{
if ((*itr)->getDefineList()==defineList)
{
// OSG_NOTICE<<"Text::createStateSet() : Matched DefineList, return StateSet "<<itr->get()<<std::endl;
return itr->get();
}
else
{
}
}
}
if (osg::isNotifyEnabled(DEBUG_MESSAGE_LEVEL))
{
DEBUG_MESSAGE<<"Text::createStateSet() ShaderTechnique ";
switch(_shaderTechnique)
{
case(NO_TEXT_SHADER) : DEBUG_MESSAGE<<"NO_TEXT_SHADER"<<std::endl; break;
case(GREYSCALE) : DEBUG_MESSAGE<<"GREYSCALE"<<std::endl; break;
case(SIGNED_DISTANCE_FIELD) : DEBUG_MESSAGE<<"SIGNED_DISTANCE_FIELD"<<std::endl; break;
case(ALL_FEATURES) : DEBUG_MESSAGE<<"ALL_FEATURES"<<std::endl; break;
}
}
DEBUG_MESSAGE<<"Text::createStateSet() : Not Matched DefineList, creating new StateSet"<<std::endl;
osg::ref_ptr<osg::StateSet> 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"<<std::endl;
stateset->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<osg::Program> program = new osg::Program;
stateset->setAttributeAndModes(program.get());
{
DEBUG_MESSAGE<<"Using shaders/text.vert"<<std::endl;
#include "shaders/text_vert.cpp"
program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/text.vert", text_vert));
}
{
DEBUG_MESSAGE<<"Using shaders/text.frag"<<std::endl;
#include "shaders/text_frag.cpp"
program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::FRAGMENT, "shaders/text.frag", text_frag));
}
return stateset.release();
}
Font* Text::getActiveFont() 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) 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 // 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); glyphquad._glyphs.push_back(glyph);
osg::DrawElements* primitives = 0; osg::DrawElements* primitives = glyphquad._primitives.get();
if (glyphquad._primitives.empty()) if (!primitives)
{ {
unsigned int maxIndices = _text.size()*4; unsigned int maxIndices = _text.size()*4;
if (maxIndices>=16384) primitives = new osg::DrawElementsUInt(GL_TRIANGLES); if (maxIndices>=16384) primitives = new osg::DrawElementsUInt(GL_TRIANGLES);
else primitives = new osg::DrawElementsUShort(GL_TRIANGLES); else primitives = new osg::DrawElementsUShort(GL_TRIANGLES);
primitives->setBufferObject(_ebo.get()); primitives->setBufferObject(_ebo.get());
glyphquad._primitives.push_back(primitives); glyphquad._primitives = primitives;
}
else
{
primitives = glyphquad._primitives[0].get();
} }
@ -280,25 +444,18 @@ void Text::computeGlyphRepresentation()
if (!_texcoords) { _texcoords = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); _texcoords->setBufferObject(_vbo.get()); } if (!_texcoords) { _texcoords = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); _texcoords->setBufferObject(_vbo.get()); }
else _texcoords->clear(); else _texcoords->clear();
#if 0
_textureGlyphQuadMap.clear();
#else
for(TextureGlyphQuadMap::iterator itr = _textureGlyphQuadMap.begin(); for(TextureGlyphQuadMap::iterator itr = _textureGlyphQuadMap.begin();
itr != _textureGlyphQuadMap.end(); itr != _textureGlyphQuadMap.end();
++itr) ++itr)
{ {
GlyphQuads& glyphquads = itr->second; GlyphQuads& glyphquads = itr->second;
glyphquads._glyphs.clear(); glyphquads._glyphs.clear();
for(Primitives::iterator pitr = glyphquads._primitives.begin(); if (glyphquads._primitives.valid())
pitr != glyphquads._primitives.end();
++pitr)
{ {
(*pitr)->resizeElements(0); glyphquads._primitives->resizeElements(0);
(*pitr)->dirty(); glyphquads._primitives->dirty();
} }
} }
#endif
_lineCount = 0; _lineCount = 0;
@ -487,45 +644,53 @@ void Text::computeGlyphRepresentation()
local.x() += bearing.x() * wr; local.x() += bearing.x() * wr;
local.y() += bearing.y() * hr; local.y() += bearing.y() * hr;
const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique);
// Adjust coordinates and texture coordinates to avoid if (info)
// 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)
{ {
case LEFT_TO_RIGHT: // Adjust coordinates and texture coordinates to avoid
cursor.x() += glyph->getHorizontalAdvance() * wr; // clipping the edges of antialiased characters.
_textBB.expandBy(osg::Vec3(minc.x(), minc.y(), 0.0f)); //lower left corner osg::Vec2 mintc = info->minTexCoord;
_textBB.expandBy(osg::Vec3(maxc.x(), maxc.y(), 0.0f)); //upper right corner osg::Vec2 maxtc = info->maxTexCoord;
break; osg::Vec2 vDiff = maxtc - mintc;
case VERTICAL: float texelMargin = info->texelMargin;
cursor.y() -= glyph->getVerticalAdvance() * hr;
_textBB.expandBy(osg::Vec3(minc.x(),maxc.y(),0.0f)); //upper left corner float fHorizTCMargin = texelMargin / info->texture->getTextureWidth();
_textBB.expandBy(osg::Vec3(maxc.x(),minc.y(),0.0f)); //lower right corner float fVertTCMargin = texelMargin / info->texture->getTextureHeight();
break; float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x();
case RIGHT_TO_LEFT: float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y();
_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 mintc.x() -= fHorizTCMargin;
break; 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 "<<charcode<<std::endl;
} }
previous_charcode = charcode; previous_charcode = charcode;
@ -622,153 +787,10 @@ void Text::computePositionsImplementation()
{ {
TextBase::computePositionsImplementation(); TextBase::computePositionsImplementation();
computeBackdropPositions();
computeBackdropBoundingBox(); computeBackdropBoundingBox();
computeBoundingBoxMargin(); computeBoundingBoxMargin();
} }
// Presumes the atc matrix is already up-to-date
void Text::computeBackdropPositions()
{
if(_backdropType == NONE)
{
return;
}
float avg_width = 0.0f;
float avg_height = 0.0f;
// FIXME: OPTIMIZE: This function produces the same value regardless of contextID.
// Since we tend to loop over contextID, we should cache this value some how
// instead of recomputing it each time.
bool is_valid_size = computeAverageGlyphWidthAndHeight(avg_width, avg_height);
if (!is_valid_size) return;
unsigned int backdrop_index;
unsigned int max_backdrop_index;
if(_backdropType == OUTLINE)
{
// For outline, we want to draw the in every direction
backdrop_index = 1;
max_backdrop_index = backdrop_index+8;
}
else
{
// Yes, this may seem a little strange,
// but since the code is using references,
// I would have to duplicate the following code twice
// for each part of the if/else because I can't
// declare a reference without setting it immediately
// and it wouldn't survive the scope.
// So it happens that the _backdropType value matches
// the index in the array I want to store the coordinates
// in. So I'll just setup the for-loop so it only does
// the one direction I'm interested in.
backdrop_index = _backdropType+1;
max_backdrop_index = backdrop_index+1;
}
for( ; backdrop_index < max_backdrop_index; backdrop_index++)
{
float horizontal_shift_direction;
float vertical_shift_direction;
switch(backdrop_index)
{
case DROP_SHADOW_BOTTOM_RIGHT:
{
horizontal_shift_direction = 1.0f;
vertical_shift_direction = -1.0f;
break;
}
case DROP_SHADOW_CENTER_RIGHT:
{
horizontal_shift_direction = 1.0f;
vertical_shift_direction = 0.0f;
break;
}
case DROP_SHADOW_TOP_RIGHT:
{
horizontal_shift_direction = 1.0f;
vertical_shift_direction = 1.0f;
break;
}
case DROP_SHADOW_BOTTOM_CENTER:
{
horizontal_shift_direction = 0.0f;
vertical_shift_direction = -1.0f;
break;
}
case DROP_SHADOW_TOP_CENTER:
{
horizontal_shift_direction = 0.0f;
vertical_shift_direction = 1.0f;
break;
}
case DROP_SHADOW_BOTTOM_LEFT:
{
horizontal_shift_direction = -1.0f;
vertical_shift_direction = -1.0f;
break;
}
case DROP_SHADOW_CENTER_LEFT:
{
horizontal_shift_direction = -1.0f;
vertical_shift_direction = 0.0f;
break;
}
case DROP_SHADOW_TOP_LEFT:
{
horizontal_shift_direction = -1.0f;
vertical_shift_direction = 1.0f;
break;
}
default: // error
{
horizontal_shift_direction = 1.0f;
vertical_shift_direction = -1.0f;
}
}
// now apply matrix to the glyphs.
for(TextureGlyphQuadMap::iterator titr=_textureGlyphQuadMap.begin();
titr!=_textureGlyphQuadMap.end();
++titr)
{
GlyphQuads& glyphquad = titr->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;i<numCoords;++i)
{
unsigned int si = (*src_primitives).getElement(i);
osg::Vec3 v(horizontal_shift_direction * _backdropHorizontalOffset * avg_width + (*src_coords)[si].x(), vertical_shift_direction * _backdropVerticalOffset * avg_height + (*src_coords)[si].y(), 0.0f);
unsigned int di = dst_coords->size();
(*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 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. // This assumes that the bounding box has already been computed for the text without the backdrop.
void Text::computeBackdropBoundingBox() 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 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(); osg::VertexArrayState* vas = state.getCurrentVertexArrayState();
bool usingVertexBufferObjects = state.useVertexBufferObject(_supportsVertexBufferObjects && _useVertexBufferObjects); bool usingVertexBufferObjects = state.useVertexBufferObject(_supportsVertexBufferObjects && _useVertexBufferObjects);
bool usingVertexArrayObjects = usingVertexBufferObjects && state.useVertexArrayObject(_useVertexArrayObject); bool usingVertexArrayObjects = usingVertexBufferObjects && state.useVertexArrayObject(_useVertexArrayObject);
@ -1117,7 +1141,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo
} }
if (_drawMode & TEXT) if (_drawMode & TEXT)
// if (false)
{ {
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin(); for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
titr!=_textureGlyphQuadMap.end(); titr!=_textureGlyphQuadMap.end();
@ -1128,33 +1151,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo
const GlyphQuads& glyphquad = titr->second; 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) if(_colorGradientMode == SOLID)
{ {
vas->disableColorArray(state); 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); vas->applyDisablingOfVertexAttributes(state);
} }
#if 0
drawImplementationSinglePass(state, colorMultiplier);
#else
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
drawImplementationSinglePass(state, colorMultiplier); drawImplementationSinglePass(state, colorMultiplier);
@ -1235,7 +1228,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie
} }
state.haveAppliedAttribute(osg::StateAttribute::DEPTH); state.haveAppliedAttribute(osg::StateAttribute::DEPTH);
#endif
if (usingVertexBufferObjects && !usingVertexArrayObjects) if (usingVertexBufferObjects && !usingVertexArrayObjects)
{ {
@ -1273,16 +1265,16 @@ void Text::accept(osg::PrimitiveFunctor& pf) const
++titr) ++titr)
{ {
const GlyphQuads& glyphquad = titr->second; const GlyphQuads& glyphquad = titr->second;
if (!glyphquad._primitives.empty()) if (glyphquad._primitives.valid())
{ {
const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast<const osg::DrawElementsUShort*>(glyphquad._primitives[0].get()); const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast<const osg::DrawElementsUShort*>(glyphquad._primitives.get());
if (drawElementsUShort) if (drawElementsUShort)
{ {
pf.drawElements(GL_TRIANGLES, drawElementsUShort->size(), &(drawElementsUShort->front())); pf.drawElements(GL_TRIANGLES, drawElementsUShort->size(), &(drawElementsUShort->front()));
} }
else else
{ {
const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast<const osg::DrawElementsUInt*>(glyphquad._primitives[0].get()); const osg::DrawElementsUInt* drawElementsUInt = dynamic_cast<const osg::DrawElementsUInt*>(glyphquad._primitives.get());
if (drawElementsUInt) if (drawElementsUInt)
{ {
pf.drawElements(GL_TRIANGLES, drawElementsUInt->size(), &(drawElementsUInt->front())); pf.drawElements(GL_TRIANGLES, drawElementsUInt->size(), &(drawElementsUInt->front()));
@ -1322,22 +1314,19 @@ void Text::setBackdropType(BackdropType type)
if (_backdropType==type) return; if (_backdropType==type) return;
_backdropType = type; _backdropType = type;
assignStateSet();
computeGlyphRepresentation(); computeGlyphRepresentation();
} }
void Text::setBackdropImplementation(BackdropImplementation implementation)
{
if (_backdropImplementation==implementation) return;
_backdropImplementation = implementation;
computeGlyphRepresentation();
}
void Text::setBackdropOffset(float offset) void Text::setBackdropOffset(float offset)
{ {
_backdropHorizontalOffset = offset; _backdropHorizontalOffset = offset;
_backdropVerticalOffset = offset; _backdropVerticalOffset = offset;
assignStateSet();
computeGlyphRepresentation(); computeGlyphRepresentation();
} }
@ -1345,12 +1334,17 @@ void Text::setBackdropOffset(float horizontal, float vertical)
{ {
_backdropHorizontalOffset = horizontal; _backdropHorizontalOffset = horizontal;
_backdropVerticalOffset = vertical; _backdropVerticalOffset = vertical;
assignStateSet();
computeGlyphRepresentation(); computeGlyphRepresentation();
} }
void Text::setBackdropColor(const osg::Vec4& color) void Text::setBackdropColor(const osg::Vec4& color)
{ {
_backdropColor = color; _backdropColor = color;
assignStateSet();
} }
void Text::setColorGradientMode(ColorGradientMode mode) void Text::setColorGradientMode(ColorGradientMode mode)
@ -1391,20 +1385,10 @@ Text::GlyphQuads::GlyphQuads(const GlyphQuads&)
void Text::GlyphQuads::resizeGLObjectBuffers(unsigned int maxSize) void Text::GlyphQuads::resizeGLObjectBuffers(unsigned int maxSize)
{ {
for(Primitives::iterator itr = _primitives.begin(); if (_primitives.valid()) _primitives->resizeGLObjectBuffers(maxSize);
itr != _primitives.end();
++itr)
{
(*itr)->resizeGLObjectBuffers(maxSize);
}
} }
void Text::GlyphQuads::releaseGLObjects(osg::State* state) const void Text::GlyphQuads::releaseGLObjects(osg::State* state) const
{ {
for(Primitives::const_iterator itr = _primitives.begin(); if (_primitives.valid()) _primitives->releaseGLObjects(state);
itr != _primitives.end();
++itr)
{
(*itr)->releaseGLObjects(state);
}
} }

View File

@ -438,9 +438,11 @@ void Text3D::computeGlyphRepresentation()
{ {
(*_coords)[i] += position; (*_coords)[i] += position;
} }
_coords->dirty();
// copy normals // copy normals
_normals->insert(_normals->end(), src_normals->begin(), src_normals->end()); _normals->insert(_normals->end(), src_normals->begin(), src_normals->end());
_normals->dirty();
copyAndOffsetPrimitiveSets(_frontPrimitiveSetList, it->_glyphGeometry->getFrontPrimitiveSetList(), base); copyAndOffsetPrimitiveSets(_frontPrimitiveSetList, it->_glyphGeometry->getFrontPrimitiveSetList(), base);
copyAndOffsetPrimitiveSets(_wallPrimitiveSetList, it->_glyphGeometry->getWallPrimitiveSetList(), base); copyAndOffsetPrimitiveSets(_wallPrimitiveSetList, it->_glyphGeometry->getWallPrimitiveSetList(), base);

View File

@ -50,7 +50,6 @@ TextBase::TextBase():
_lineCount(0), _lineCount(0),
_glyphNormalized(false) _glyphNormalized(false)
{ {
setStateSet(Font::getDefaultFont()->getStateSet());
setUseDisplayList(false); setUseDisplayList(false);
setSupportsDisplayList(false); setSupportsDisplayList(false);
@ -89,6 +88,11 @@ TextBase::~TextBase()
{ {
} }
osg::StateSet* TextBase::createStateSet()
{
return 0;
}
void TextBase::initArraysAndBuffers() void TextBase::initArraysAndBuffers()
{ {
_vbo = new osg::VertexBufferObject; _vbo = new osg::VertexBufferObject;
@ -182,6 +186,10 @@ void TextBase::setColor(const osg::Vec4& color)
_color = color; _color = color;
} }
void TextBase::assignStateSet()
{
setStateSet(createStateSet());
}
void TextBase::setFont(osg::ref_ptr<Font> font) void TextBase::setFont(osg::ref_ptr<Font> font)
{ {
@ -189,6 +197,8 @@ void TextBase::setFont(osg::ref_ptr<Font> font)
_font = font; _font = font;
assignStateSet();
computeGlyphRepresentation(); computeGlyphRepresentation();
} }
@ -203,6 +213,9 @@ void TextBase::setFontResolution(unsigned int width, unsigned int height)
if (_fontSize==size) return; if (_fontSize==size) return;
_fontSize = size; _fontSize = size;
assignStateSet();
computeGlyphRepresentation(); computeGlyphRepresentation();
} }

View File

@ -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; i<numSamples; ++i)\n"
" {\n"
" for(float j=0.0; j<numSamples; ++j)\n"
" {\n"
" float local_alpha = TEXTURE(glyphTexture, origin + vec2(i*delta_tc, j*delta_tc)).ALPHA;\n"
" outline_alpha = max(outline_alpha, local_alpha);\n"
" background_alpha = background_alpha * (1.0-local_alpha);\n"
" }\n"
" }\n"
"\n"
" #ifdef osg_TextureQueryLOD\n"
" float mipmapLevel = osg_TextureQueryLOD(glyphTexture, src_texCoord).x;\n"
" if (mipmapLevel<1.0)\n"
" {\n"
" outline_alpha = mix(1.0-background_alpha, outline_alpha, mipmapLevel/1.0);\n"
" }\n"
" #endif\n"
"\n"
" if (outline_alpha<alpha) outline_alpha = alpha;\n"
" if (outline_alpha>1.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";

View File

@ -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";

View File

@ -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<osg::GLExtensions>();
extensions->glUseProgram(0);
_renderInfo.getState()->setLastAppliedProgramObject(0);
}
}
}
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// //
// GLObjectsOperation // GLObjectsOperation

View File

@ -299,13 +299,17 @@ struct IntersectFunctor
return; 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; Vec3 normal = E1^E2;
normal.normalize(); normal.normalize();
LineSegmentIntersector::Intersection hit; LineSegmentIntersector::Intersection hit;
hit.ratio = r; hit.ratio = remap_ratio;
hit.matrix = _settings->_iv->getModelMatrix(); hit.matrix = _settings->_iv->getModelMatrix();
hit.nodePath = _settings->_iv->getNodePath(); hit.nodePath = _settings->_iv->getNodePath();
hit.drawable = _settings->_drawable; hit.drawable = _settings->_drawable;
@ -500,7 +504,7 @@ void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Dr
if (reachedLimit()) return; if (reachedLimit()) return;
osg::Vec3d s(_start), e(_end); 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; if (iv.getDoDummyTraversal()) return;

View File

@ -1100,3 +1100,6 @@ public:
REGISTER_WINDOWINGSYSTEMINTERFACE(Carbon, CarbonWindowingSystemInterface) REGISTER_WINDOWINGSYSTEMINTERFACE(Carbon, CarbonWindowingSystemInterface)
} }
#endif

View File

@ -199,7 +199,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect)
// the app-delegate, handling quit-requests // the app-delegate, handling quit-requests
// ---------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------
@interface CocoaAppDelegate : NSObject @interface CocoaAppDelegate : NSObject <NSApplicationDelegate>
{ {
} }

View File

@ -571,7 +571,6 @@ void Renderer::compile()
{ {
DEBUG_MESSAGE<<"Renderer::compile()"<<std::endl; DEBUG_MESSAGE<<"Renderer::compile()"<<std::endl;
_compileOnNextDraw = false; _compileOnNextDraw = false;
osgUtil::SceneView* sceneView = _sceneView[0].get(); osgUtil::SceneView* sceneView = _sceneView[0].get();
@ -583,7 +582,7 @@ void Renderer::compile()
{ {
osgUtil::GLObjectsVisitor glov; osgUtil::GLObjectsVisitor glov;
glov.setState(sceneView->getState()); glov.setState(sceneView->getState());
sceneView->getSceneData()->accept(glov); glov.compile(*(sceneView->getSceneData()));
} }
sceneView->getState()->checkGLErrors("After Renderer::compile"); sceneView->getState()->checkGLErrors("After Renderer::compile");

View File

@ -134,7 +134,6 @@ void Label::setFontColor(const Color& c) {
void Label::setShadow(point_type offset) { void Label::setShadow(point_type offset) {
_text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT); _text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
_text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
_text->setBackdropOffset(offset); _text->setBackdropOffset(offset);
_calculateSize(getTextSize()); _calculateSize(getTextSize());

View File

@ -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<osgText::Text::BackdropImplementation>(-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) osgText::Text::ColorGradientMode convertColorGradientModeStringToEnum(std::string & str)
{ {
if (str=="SOLID") return osgText::Text::SOLID; if (str=="SOLID") return osgText::Text::SOLID;
@ -155,12 +134,6 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
// backdropImplementation // backdropImplementation
if (fr[0].matchWord("backdropImplementation")) if (fr[0].matchWord("backdropImplementation"))
{ {
std::string str = fr[1].getStr();
osgText::Text::BackdropImplementation backdropImplementation = convertBackdropImplementationStringToEnum(str);
if (backdropImplementation != static_cast<osgText::Text::BackdropImplementation>(-1))
text.setBackdropImplementation(backdropImplementation);
fr += 2; fr += 2;
itAdvanced = true; itAdvanced = true;
} }
@ -254,9 +227,6 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
osg::Vec4 c = text.getBackdropColor(); osg::Vec4 c = text.getBackdropColor();
fw.indent() << "backdropColor " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl; fw.indent() << "backdropColor " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl;
// backdropImplementation
fw.indent() << "backdropImplementation " << convertBackdropImplementationEnumToString(text.getBackdropImplementation()) << std::endl;
// colorGradientMode // colorGradientMode
fw.indent() << "colorGradientMode " << convertColorGradientModeEnumToString(text.getColorGradientMode()) << std::endl; fw.indent() << "colorGradientMode " << convertColorGradientModeEnumToString(text.getColorGradientMode()) << std::endl;

View File

@ -3,25 +3,34 @@
USE_SERIALIZER_WRAPPER(AlphaFunc) USE_SERIALIZER_WRAPPER(AlphaFunc)
USE_SERIALIZER_WRAPPER(AnimationPath) USE_SERIALIZER_WRAPPER(AnimationPath)
USE_SERIALIZER_WRAPPER(AnimationPathCallback) USE_SERIALIZER_WRAPPER(AnimationPathCallback)
USE_SERIALIZER_WRAPPER(AtomicCounterBufferBinding)
USE_SERIALIZER_WRAPPER(AudioSink) USE_SERIALIZER_WRAPPER(AudioSink)
USE_SERIALIZER_WRAPPER(AudioStream) USE_SERIALIZER_WRAPPER(AudioStream)
USE_SERIALIZER_WRAPPER(AutoTransform) USE_SERIALIZER_WRAPPER(AutoTransform)
USE_SERIALIZER_WRAPPER(Billboard) USE_SERIALIZER_WRAPPER(Billboard)
USE_SERIALIZER_WRAPPER(BlendColor) USE_SERIALIZER_WRAPPER(BlendColor)
USE_SERIALIZER_WRAPPER(BlendEquation) USE_SERIALIZER_WRAPPER(BlendEquation)
USE_SERIALIZER_WRAPPER(BlendEquationi)
USE_SERIALIZER_WRAPPER(BlendFunc) USE_SERIALIZER_WRAPPER(BlendFunc)
USE_SERIALIZER_WRAPPER(BlendFunci)
USE_SERIALIZER_WRAPPER(BoolValueObject) USE_SERIALIZER_WRAPPER(BoolValueObject)
USE_SERIALIZER_WRAPPER(Box) USE_SERIALIZER_WRAPPER(Box)
USE_SERIALIZER_WRAPPER(BufferData)
USE_SERIALIZER_WRAPPER(BufferIndexBinding)
USE_SERIALIZER_WRAPPER(BufferObject)
USE_SERIALIZER_WRAPPER(Callback) USE_SERIALIZER_WRAPPER(Callback)
USE_SERIALIZER_WRAPPER(CallbackObject)
USE_SERIALIZER_WRAPPER(Camera) USE_SERIALIZER_WRAPPER(Camera)
USE_SERIALIZER_WRAPPER(CameraView) USE_SERIALIZER_WRAPPER(CameraView)
USE_SERIALIZER_WRAPPER(Capsule) USE_SERIALIZER_WRAPPER(Capsule)
USE_SERIALIZER_WRAPPER(ClampColor) USE_SERIALIZER_WRAPPER(ClampColor)
USE_SERIALIZER_WRAPPER(ClearNode) USE_SERIALIZER_WRAPPER(ClearNode)
USE_SERIALIZER_WRAPPER(ClipNode) USE_SERIALIZER_WRAPPER(ClipNode)
USE_SERIALIZER_WRAPPER(ClipControl)
USE_SERIALIZER_WRAPPER(ClipPlane) USE_SERIALIZER_WRAPPER(ClipPlane)
USE_SERIALIZER_WRAPPER(ClusterCullingCallback) USE_SERIALIZER_WRAPPER(ClusterCullingCallback)
USE_SERIALIZER_WRAPPER(ColorMask) USE_SERIALIZER_WRAPPER(ColorMask)
USE_SERIALIZER_WRAPPER(ColorMaski)
USE_SERIALIZER_WRAPPER(ColorMatrix) USE_SERIALIZER_WRAPPER(ColorMatrix)
USE_SERIALIZER_WRAPPER(CompositeShape) USE_SERIALIZER_WRAPPER(CompositeShape)
USE_SERIALIZER_WRAPPER(ComputeBoundingBoxCallback) USE_SERIALIZER_WRAPPER(ComputeBoundingBoxCallback)
@ -32,9 +41,11 @@ USE_SERIALIZER_WRAPPER(ConvexPlanarOccluder)
USE_SERIALIZER_WRAPPER(CoordinateSystemNode) USE_SERIALIZER_WRAPPER(CoordinateSystemNode)
USE_SERIALIZER_WRAPPER(CullFace) USE_SERIALIZER_WRAPPER(CullFace)
USE_SERIALIZER_WRAPPER(Cylinder) USE_SERIALIZER_WRAPPER(Cylinder)
USE_SERIALIZER_WRAPPER(DefaultUserDataContainer)
USE_SERIALIZER_WRAPPER(Depth) USE_SERIALIZER_WRAPPER(Depth)
USE_SERIALIZER_WRAPPER(Drawable) USE_SERIALIZER_WRAPPER(Drawable)
USE_SERIALIZER_WRAPPER(DrawPixels) USE_SERIALIZER_WRAPPER(DrawPixels)
USE_SERIALIZER_WRAPPER(ElementBufferObject)
USE_SERIALIZER_WRAPPER(EllipsoidModel) USE_SERIALIZER_WRAPPER(EllipsoidModel)
USE_SERIALIZER_WRAPPER(Fog) USE_SERIALIZER_WRAPPER(Fog)
USE_SERIALIZER_WRAPPER(FragmentProgram) USE_SERIALIZER_WRAPPER(FragmentProgram)
@ -77,10 +88,14 @@ USE_SERIALIZER_WRAPPER(Projection)
USE_SERIALIZER_WRAPPER(ProxyNode) USE_SERIALIZER_WRAPPER(ProxyNode)
USE_SERIALIZER_WRAPPER(SampleMaski) USE_SERIALIZER_WRAPPER(SampleMaski)
USE_SERIALIZER_WRAPPER(Scissor) USE_SERIALIZER_WRAPPER(Scissor)
USE_SERIALIZER_WRAPPER(Script)
USE_SERIALIZER_WRAPPER(ScriptNodeCallback)
USE_SERIALIZER_WRAPPER(Sequence) USE_SERIALIZER_WRAPPER(Sequence)
USE_SERIALIZER_WRAPPER(ShadeModel) USE_SERIALIZER_WRAPPER(ShadeModel)
USE_SERIALIZER_WRAPPER(Shader) USE_SERIALIZER_WRAPPER(Shader)
USE_SERIALIZER_WRAPPER(ShaderAttribute)
USE_SERIALIZER_WRAPPER(ShaderBinary) USE_SERIALIZER_WRAPPER(ShaderBinary)
USE_SERIALIZER_WRAPPER(ShaderStorageBufferBinding)
USE_SERIALIZER_WRAPPER(Shape) USE_SERIALIZER_WRAPPER(Shape)
USE_SERIALIZER_WRAPPER(ShapeDrawable) USE_SERIALIZER_WRAPPER(ShapeDrawable)
USE_SERIALIZER_WRAPPER(Sphere) USE_SERIALIZER_WRAPPER(Sphere)
@ -101,16 +116,21 @@ USE_SERIALIZER_WRAPPER(Texture1D)
USE_SERIALIZER_WRAPPER(Texture2D) USE_SERIALIZER_WRAPPER(Texture2D)
USE_SERIALIZER_WRAPPER(Texture2DArray) USE_SERIALIZER_WRAPPER(Texture2DArray)
USE_SERIALIZER_WRAPPER(Texture3D) USE_SERIALIZER_WRAPPER(Texture3D)
USE_SERIALIZER_WRAPPER(TextureBuffer)
USE_SERIALIZER_WRAPPER(TextureCubeMap) USE_SERIALIZER_WRAPPER(TextureCubeMap)
USE_SERIALIZER_WRAPPER(TextureRectangle) USE_SERIALIZER_WRAPPER(TextureRectangle)
USE_SERIALIZER_WRAPPER(TransferFunction) USE_SERIALIZER_WRAPPER(TransferFunction)
USE_SERIALIZER_WRAPPER(TransferFunction1D) USE_SERIALIZER_WRAPPER(TransferFunction1D)
USE_SERIALIZER_WRAPPER(Transform) USE_SERIALIZER_WRAPPER(Transform)
USE_SERIALIZER_WRAPPER(TransformFeedbackBufferBinding)
USE_SERIALIZER_WRAPPER(TriangleMesh) USE_SERIALIZER_WRAPPER(TriangleMesh)
USE_SERIALIZER_WRAPPER(Uniform) USE_SERIALIZER_WRAPPER(Uniform)
USE_SERIALIZER_WRAPPER(UniformBufferBinding)
USE_SERIALIZER_WRAPPER(UniformCallback) USE_SERIALIZER_WRAPPER(UniformCallback)
USE_SERIALIZER_WRAPPER(UpdateCallback) USE_SERIALIZER_WRAPPER(UpdateCallback)
USE_SERIALIZER_WRAPPER(UserDataContainer) USE_SERIALIZER_WRAPPER(UserDataContainer)
USE_SERIALIZER_WRAPPER(VertexAttribDivisor)
USE_SERIALIZER_WRAPPER(VertexBufferObject)
USE_SERIALIZER_WRAPPER(VertexProgram) USE_SERIALIZER_WRAPPER(VertexProgram)
USE_SERIALIZER_WRAPPER(Viewport) USE_SERIALIZER_WRAPPER(Viewport)
@ -164,5 +184,21 @@ USE_SERIALIZER_WRAPPER(DrawElementsUByte)
USE_SERIALIZER_WRAPPER(DrawElementsUShort) USE_SERIALIZER_WRAPPER(DrawElementsUShort)
USE_SERIALIZER_WRAPPER(DrawElementsUInt) 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) {} extern "C" void wrapper_serializer_library_osg(void) {}

View File

@ -145,6 +145,39 @@ static bool writeComputeGroups( osgDB::OutputStream& os, const osg::Program& att
return true; 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<size; ++i )
{
is >>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, REGISTER_OBJECT_WRAPPER( Program,
new osg::Program, new osg::Program,
osg::Program, osg::Program,
@ -167,4 +200,8 @@ REGISTER_OBJECT_WRAPPER( Program,
ADD_USER_SERIALIZER( FeedBackVaryingsName ); ADD_USER_SERIALIZER( FeedBackVaryingsName );
ADD_USER_SERIALIZER( FeedBackMode ); ADD_USER_SERIALIZER( FeedBackMode );
} }
{
UPDATE_TO_VERSION_SCOPED( 150 )
ADD_USER_SERIALIZER( BindUniformBlock );
}
} }

View File

@ -0,0 +1,11 @@
#include <osg/ShaderAttribute>
#include <osgDB/ObjectWrapper>
#include <osgDB/InputStream>
#include <osgDB/OutputStream>
REGISTER_OBJECT_WRAPPER( ShaderAttribute,
/*new osg::ShaderAttribute*/NULL,
osg::ShaderAttribute,
"osg::Object osg::StateAttribute osg::ShaderAttribute" )
{
}