Merge branch 'master' into osganimation
This commit is contained in:
commit
11f9bbf6ea
18
.travis.yml
18
.travis.yml
@ -4,6 +4,9 @@ env:
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "0ROQiFbsZo33ce2v5VjBxNljemh/HU70ntSSPygYwaDFymubts/62SixXVkbKNIFdrs3uYD6qeA/eMmpqXxLcs+PXNq5NrH7eSWw9oDIKMhq3NQH/IZLdRfXwihHimZ1qEs/TXyWlT2aC4rpBi1py3cJeTh1aBMlz4V/nm16iRAgc596ThNTuPDHa0F9/gZnwccI/Rr9VpiYn7vEBbuY9lYr43D0G3NuuQyvvlHShroH09fh6KyFOWIY38AQtnuVGNC1fIiAUk7TUqDqSBwhIrUV5saHbP0kca6DP32REkv//h4JwM76UHv+ntVEoK/UiztJHMkrw71gXYTyvIvlDBpT+IDoeIwUW2QFNQ5zJZI7FM8k0+oeK+F7k/mkffDzr1zww/PQoxqFBF0PoxAni/L9qkA4X2o1A6mRDbe9besp2LQG6Vniwj3bHpCId2QiiMrANVg0EAqkcL2mVFEaqZsh90qCkr1UDq4WQoYbXh0Fy3UnQpbuxDvCME8u03lwuv6ds/SBxc5cgKv7oWXgezaDg7/OCR+0lIAGuLqmNRD8Xw7a0WZGmSbYCHIZmeyFja2KuUvMiVCt8+QsyZr3e523DwBwnSj1BIYFRstMaSEJgu9B8rfTRRllOOKJXCQtdFVuGu8VI6PniSAkI6c535yOWzsuS8HwIkN2ll+Wn7E="
|
||||
|
||||
language: cpp
|
||||
cache: ccache
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
include:
|
||||
@ -18,8 +21,7 @@ matrix:
|
||||
sudo: false
|
||||
cache:
|
||||
apt: true
|
||||
directories:
|
||||
- $HOME/.ccache
|
||||
ccache: true
|
||||
compiler:
|
||||
#- clang
|
||||
- gcc
|
||||
@ -43,11 +45,19 @@ matrix:
|
||||
|
||||
# OSX build
|
||||
- os: osx
|
||||
language: cpp
|
||||
before_install:
|
||||
- brew update
|
||||
install:
|
||||
- brew install ccache
|
||||
- export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
env:
|
||||
- CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=OFF -DBUILD_OSG_PLUGINS_BY_DEFAULT=ON -DBUILD_OSG_APPLICATIONS=ON"
|
||||
- os: osx
|
||||
language: cpp
|
||||
before_install:
|
||||
- brew update
|
||||
install:
|
||||
- brew install ccache
|
||||
- export PATH="/usr/local/opt/ccache/libexec:$PATH"
|
||||
env:
|
||||
- CMAKECMD_ARGS="-DBUILD_OSG_EXAMPLES=ON -DBUILD_OSG_PLUGINS_BY_DEFAULT=OFF -DBUILD_OSG_APPLICATIONS=OFF"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
OpenSceneGraph Library 3.5.7
|
||||
|
||||
566 Contributors:
|
||||
568 Contributors:
|
||||
|
||||
Firstname Surname
|
||||
-----------------
|
||||
@ -175,6 +175,7 @@ John Ivar
|
||||
Gustav Haapalahti
|
||||
Erik den Dekker
|
||||
Emmanuel Roche
|
||||
Don Burns
|
||||
Domenico Mangieri
|
||||
Daniel Larimer
|
||||
Colin Dunlop
|
||||
@ -226,7 +227,6 @@ Fabio Mierlo
|
||||
Doug McCorkle
|
||||
Donald Cipperly
|
||||
Don Leich
|
||||
Don Burns
|
||||
Dietmar Funck
|
||||
Colin Cochran
|
||||
Christian Ruzicka
|
||||
@ -362,6 +362,7 @@ Shuxing Xiao
|
||||
Shane Arnott
|
||||
Sergey Kurdakov
|
||||
Sebastien Kuntz
|
||||
Sandro Mani
|
||||
Ruth Lang
|
||||
Ruben The
|
||||
Ruben Smelik
|
||||
@ -538,6 +539,7 @@ Christian Noon
|
||||
Christian Kaser
|
||||
Christian Ehrlicher
|
||||
Chris McGlone
|
||||
Chris Djali
|
||||
Carlos Garcea
|
||||
Bryce Eldridge
|
||||
Bruno Herbelin
|
||||
|
@ -115,7 +115,7 @@ PROJECT(OpenSceneGraph)
|
||||
|
||||
SET(OPENSCENEGRAPH_MAJOR_VERSION 3)
|
||||
SET(OPENSCENEGRAPH_MINOR_VERSION 5)
|
||||
SET(OPENSCENEGRAPH_PATCH_VERSION 7)
|
||||
SET(OPENSCENEGRAPH_PATCH_VERSION 8)
|
||||
SET(OPENSCENEGRAPH_SOVERSION 150)
|
||||
|
||||
# set to 0 when not a release candidate, non zero means that any generated
|
||||
|
@ -94,14 +94,12 @@ macro(FIND_LIBLAS_LIBRARY MYLIBRARY MYLIBRARYNAME)
|
||||
endmacro(FIND_LIBLAS_LIBRARY LIBRARY LIBRARYNAME)
|
||||
|
||||
FIND_LIBLAS_LIBRARY(LIBLAS_LIBRARY las)
|
||||
FIND_LIBLAS_LIBRARY(LIBLASC_LIBRARY las_c)
|
||||
|
||||
set(LIBLAS_FOUND "NO")
|
||||
if(LIBLAS_LIBRARY AND LIBLASC_LIBRARY AND LIBLAS_INCLUDE_DIR)
|
||||
|
||||
if(LIBLAS_LIBRARY AND LIBLAS_INCLUDE_DIR)
|
||||
FIND_PACKAGE(Boost) # used by LIBLAS
|
||||
if(Boost_FOUND)
|
||||
set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} ${LIBLASC_LIBRARY} )
|
||||
set(LIBLAS_LIBRARIES ${LIBLAS_LIBRARY} )
|
||||
set(LIBLAS_FOUND "YES")
|
||||
endif()
|
||||
endif()
|
||||
|
375
ChangeLog
375
ChangeLog
@ -1,3 +1,274 @@
|
||||
Mon, 9 Oct 2017 12:25:40 +0100
|
||||
Author : Robert Osfield
|
||||
Updated version number
|
||||
|
||||
Mon, 9 Oct 2017 12:23:45 +0100
|
||||
Author : Robert Osfield
|
||||
Updated AUTHORS
|
||||
|
||||
Mon, 9 Oct 2017 10:03:21 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #359 from eligovision/OpenSceneGraph_glesAdded defines: GL_ALPHA4/8/12/16 in osg/Image, this will fix compilat…
|
||||
|
||||
Mon, 9 Oct 2017 10:02:51 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #358 from eligovision/OpenSceneGraph_optimizerVertexAttribDivisor compare function fix: index must be compared
|
||||
|
||||
Fri, 6 Oct 2017 18:03:36 +0100
|
||||
Author : Robert Osfield
|
||||
Added explictly unbinding of VBO for setInterleavedArrays().
|
||||
|
||||
Fri, 6 Oct 2017 17:47:19 +0100
|
||||
Author : Robert Osfield
|
||||
Added VertexArrayState::ArrayDispatch::className() method and implementation for each ArrayDispatch subclass to help with debugging
|
||||
|
||||
Fri, 6 Oct 2017 17:37:50 +0300
|
||||
Author : Konstantin S. Matveyev
|
||||
Added defines: GL_ALPHA4/8/12/16 in osg/Image, this will fix compilation error while building for GLES2
|
||||
|
||||
Fri, 6 Oct 2017 14:33:07 +0300
|
||||
Author : Konstantin S. Matveyev
|
||||
VertexAttribDivisor compare function fix: index must be compared
|
||||
|
||||
Thu, 5 Oct 2017 16:31:45 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #354 from eligovision/OpenSceneGraph_intersectionLineSegmentIntersector fixed: intersection ratio remaped to the range…
|
||||
|
||||
Thu, 5 Oct 2017 16:30:21 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #353 from eligovision/OpenSceneGraph_iotellg call removed from StreamOperator's checkStream function, becaus…
|
||||
|
||||
Thu, 5 Oct 2017 16:29:37 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #355 from denyskoch/patch-1Fix loading of 16bit PNG images
|
||||
|
||||
Thu, 5 Oct 2017 15:59:26 +0100
|
||||
Author : Robert Osfield
|
||||
Fixed spacing to make it consistent with the rest of the OSG and make it easier to read.
|
||||
|
||||
Thu, 5 Oct 2017 15:57:02 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #351 from LaurensVoerman/vncHostPwVNC: try to find password for host if no password for host:port is found
|
||||
|
||||
Thu, 5 Oct 2017 15:37:03 +0100
|
||||
Author : Robert Osfield
|
||||
Added support for multiple --login url username password entries to osgviewer
|
||||
|
||||
Thu, 5 Oct 2017 15:02:17 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #348 from eligovision/OpenSceneGraph_serializersosg serializers fixed for static build, ShaderAttribute wrapper added
|
||||
|
||||
Thu, 5 Oct 2017 12:45:47 +0100
|
||||
Author : Robert Osfield
|
||||
Steamlined the handling of osg::Geometry
|
||||
|
||||
Thu, 5 Oct 2017 12:15:23 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #346 from LaurensVoerman/FindLIBLASremoved las_c library from FindLIBLAS.cmake, it's not used by the osgplugin.
|
||||
|
||||
Thu, 28 Sep 2017 11:09:18 +0200
|
||||
Author : Denys Koch
|
||||
Fix loading of 16bit PNG imagesWhen a 16bit PNG image is loaded, the internalTextureFormat is set to unsized (i.e pixelFormat) constant. This results in 8 Bit Texture2D
|
||||
|
||||
Fri, 22 Sep 2017 11:38:43 +0300
|
||||
Author : Konstantin S. Matveyev
|
||||
LineSegmentIntersector fixed: intersection ratio remaped to the range of LineSegment => correct order in multiset of intersections
|
||||
|
||||
Sun, 17 Sep 2017 18:48:32 +0300
|
||||
Author : konstantin.matveyev
|
||||
tellg call removed from StreamOperator's checkStream function, because reading of files (readNodeFile etc.) with tellg on 'every iter' is approximately 100 times slower on Emscripten platform
|
||||
|
||||
Thu, 21 Sep 2017 16:33:14 +0200
|
||||
Author : Laurens Voerman
|
||||
VNC: try to find password for host if no password for host:port is found
|
||||
|
||||
Fri, 15 Sep 2017 12:14:37 +0300
|
||||
Author : Konstantin S. Matveyev
|
||||
osg serializers fixed for static build, ShaderAttribute wrapper added
|
||||
|
||||
Tue, 12 Sep 2017 09:19:33 +0200
|
||||
Author : Laurens Voerman
|
||||
removed las_c library from FindLIBLAS.cmake, it's not used by the osg plugin.
|
||||
|
||||
Mon, 4 Sep 2017 15:21:26 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #344 from eligovision/OpenSceneGraph_text3dText3D dynamic changing fix
|
||||
|
||||
Mon, 4 Sep 2017 15:20:54 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #345 from eligovision/OpenSceneGraph_example_text3dexample_osgtext3d: more options for testing
|
||||
|
||||
Mon, 4 Sep 2017 11:44:30 +0300
|
||||
Author : Konstantin S. Matveyev
|
||||
example_osgtext3d: more options for testing
|
||||
|
||||
Mon, 4 Sep 2017 11:29:50 +0300
|
||||
Author : Konstantin S. Matveyev
|
||||
Text3D dynamic changing fix
|
||||
|
||||
Mon, 4 Sep 2017 08:36:49 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #341 from scrawl/cullingactive_fixLineSegmentIntersector: respect the 'cullingActive' flag for bounding box check
|
||||
|
||||
Sun, 3 Sep 2017 14:15:36 +0000
|
||||
Author : scrawl
|
||||
LineSegmentIntersector: respect the 'cullingActive' flag when testing drawable bounding box
|
||||
|
||||
Fri, 1 Sep 2017 15:50:47 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #337 from mp3butcher/osganimbugfixfix a bug in how vertexattributes are filled
|
||||
|
||||
Wed, 30 Aug 2017 23:15:01 +0200
|
||||
Author : Julien Valentin
|
||||
fix a bug in how vertexattributes are filled
|
||||
|
||||
Tue, 29 Aug 2017 10:51:06 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #334 from mathieu/ValidateProgramTooEarlyUnder macOS the glValidateProgram reports too many errors
|
||||
|
||||
Tue, 29 Aug 2017 11:34:27 +0200
|
||||
Author : Mathieu MARACHE
|
||||
Under macOS the glValidateProgram reports too many false negatives (errors) about missing buffers, etc..From the internet https://stackoverflow.com/questions/15335510/opengl-glvalidateprogram-error-on-mac-os-x :
|
||||
« […] The purpose of glValidateProgram is not to use it as an added "check" step after linking the program, because the GL and application state is hardly ready for actually using that program at this point, probably it's even before we get around to initializing the default framebuffer (its bitdepth, its multisample buffers, etc), and that's what the error hints at.
|
||||
|
||||
An appropriate place to call glValidateProgram would be right before you make a real render call. »
|
||||
|
||||
Mon, 28 Aug 2017 16:28:30 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #332 from denyskoch/fix-boundingsphere-inequality-operatorFix flawed BoundingSphere inequality operator
|
||||
|
||||
Mon, 28 Aug 2017 14:34:39 +0200
|
||||
Author : Denys Koch
|
||||
Fix flawed BoundingSphere inequality operator
|
||||
|
||||
Mon, 28 Aug 2017 10:02:27 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #330 from mathieu/ProgramFixFunctionAvailableCoreProfileosg::Program::isFixedFunction() should'nt return true if fixed function unavailable
|
||||
|
||||
Mon, 28 Aug 2017 09:44:10 +0200
|
||||
Author : Mathieu MARACHE
|
||||
osg::Program::isFixedFunction() should'nt return true fixed function is unavailable, even if _shaderList.empty() is true
|
||||
|
||||
Sun, 27 Aug 2017 18:08:09 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #327 from kornerr/masterFix Emscripten build errors
|
||||
|
||||
Sun, 27 Aug 2017 18:07:21 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #328 from scrawl/group-docsFix docs for Group::addChild to match implementation
|
||||
|
||||
Sat, 26 Aug 2017 19:25:00 +0300
|
||||
Author : Michael Kapelko
|
||||
Fix Emscripten build errors
|
||||
|
||||
Sat, 26 Aug 2017 11:30:55 +0000
|
||||
Author : scrawl
|
||||
Fix docs for Group::addChild to match implementationChecking for duplicates is only done if ENSURE_CHILD_IS_UNIQUE is defined, but this is never defined anywhere.
|
||||
|
||||
Fri, 25 Aug 2017 14:49:38 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #326 from emminizer/glcore3_cmakefixSETUP_EXE in CMake now uses same define for including the GLCORE head…
|
||||
|
||||
Fri, 25 Aug 2017 14:48:42 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #325 from emminizer/msvc2015_exportfixRemoved inappropriate use of OSG_EXPORT on DefaultIndirectCommandDrawArrays and De…
|
||||
|
||||
Fri, 25 Aug 2017 09:04:05 -0400
|
||||
Author : Daniel Emminizer
|
||||
SETUP_EXE in CMake now uses same define for including the GLCORE headers as SETUP_LIBRARY and SETUP_PLUGIN. Fixes Windows build errors for applications.
|
||||
|
||||
Fri, 25 Aug 2017 08:55:25 -0400
|
||||
Author : Daniel Emminizer
|
||||
No longer using OSG_EXPORT on DefaultIndirectCommandDrawArrays and DefaultIndirectCommandDrawElements, fixing compile errors in MSVC 2015.
|
||||
|
||||
Fri, 25 Aug 2017 10:04:40 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #324 from mp3butcher/osganimationAdd extensions
|
||||
|
||||
Fri, 25 Aug 2017 00:19:22 +0200
|
||||
Author : Julien Valentin
|
||||
Add extensions
|
||||
|
||||
Thu, 24 Aug 2017 15:13:14 +0100
|
||||
Author : Robert Osfield
|
||||
Cleaned up warnings and removed assorts.
|
||||
|
||||
Thu, 24 Aug 2017 13:55:56 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #322 from mp3butcher/MDI7fix osggpucull to fit both new BIB and MDI
|
||||
|
||||
Thu, 24 Aug 2017 14:15:09 +0200
|
||||
Author : Julien Valentin
|
||||
fix osggpucull to fit both new BIB and MDI
|
||||
|
||||
Thu, 24 Aug 2017 11:17:43 +0100
|
||||
Author : Robert Osfield
|
||||
Bumped SO version to reflect changes in ABI
|
||||
|
||||
Thu, 24 Aug 2017 11:08:38 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #321 from LaurensVoerman/tgaMissingColormapfix gcc/VC compile warnings, reject color mapped tga files with missing colormap.
|
||||
|
||||
Thu, 24 Aug 2017 11:33:23 +0200
|
||||
Author : Laurens Voerman
|
||||
fix gcc/VC compile warnings, reject color mapped tga files with missing colormap.
|
||||
|
||||
Thu, 24 Aug 2017 10:33:44 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #320 from mp3butcher/MDI7MultiDrawIndirect
|
||||
|
||||
Thu, 24 Aug 2017 11:26:23 +0200
|
||||
Author : Julien Valentin
|
||||
Merge remote-tracking branch 'upstream/master' into MDI7
|
||||
|
||||
Thu, 24 Aug 2017 09:53:32 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #318 from mp3butcher/osganimationchange the design of BufferIndexBinding to work with BufferData instead of BufferObject +matrix transpose
|
||||
|
||||
Thu, 24 Aug 2017 10:29:19 +0200
|
||||
Author : Julien Valentin
|
||||
comply with osg::BufferIndexBinding new design (a miss)
|
||||
|
||||
Wed, 23 Aug 2017 23:42:12 +0200
|
||||
Author : Julien Valentin
|
||||
change the design of BufferIndexBinding to work with BufferData instead of BufferObject allow convenient BufferData abstraction + serialization of BufferIndexBinding
|
||||
|
||||
Wed, 23 Aug 2017 19:06:25 +0200
|
||||
Author : Julien Valentin
|
||||
add a transpose method for 4x4 and a transpose3x3 to transpose only orthogonal part of a mat4x4
|
||||
|
||||
Wed, 23 Aug 2017 15:26:07 +0100
|
||||
Author : Robert Osfield
|
||||
Fixed underflow issue
|
||||
|
||||
Wed, 23 Aug 2017 14:51:18 +0100
|
||||
Author : Robert Osfield
|
||||
Fixed comparison to properly handle texture coordinates being assigned
|
||||
|
||||
Wed, 23 Aug 2017 14:48:04 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #314 from LaurensVoerman/notify2reduce the need to reallocate the std::ostream buffer behind osg::Notify
|
||||
|
||||
Wed, 23 Aug 2017 14:39:35 +0100
|
||||
Author : Robert Osfield
|
||||
Warning fixes
|
||||
|
||||
Tue, 22 Aug 2017 15:23:47 +0200
|
||||
Author : Laurens Voerman
|
||||
reduce the need to reallocate the std::ostream buffer behind osg::Notify (causing multitreading issues) by pre-allocating 4095 bytes.
|
||||
|
||||
Wed, 23 Aug 2017 08:54:10 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #315 from kornerr/masterFix stat64 build issue with NDK 15 by definining it as stat for Android
|
||||
|
||||
Tue, 22 Aug 2017 22:49:56 +0300
|
||||
Author : Michael Kapelko
|
||||
Fix stat64 build issue with NDK 15 by definining at stat for Android
|
||||
|
||||
Tue, 22 Aug 2017 12:04:18 +0100
|
||||
Author : Robert Osfield
|
||||
Updated ChangeLog
|
||||
|
||||
Tue, 22 Aug 2017 09:04:49 +0100
|
||||
Author : Robert Osfield
|
||||
Added catch for controbutors list
|
||||
@ -165,18 +436,122 @@ Mon, 7 Aug 2017 16:32:44 +0100
|
||||
Author : Robert Osfield
|
||||
Added link to ABI tracker
|
||||
|
||||
Sun, 6 Aug 2017 15:30:27 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #294 from mp3butcher/MDI6add resize methods method in IndirectCommandArrays ..etc..
|
||||
|
||||
Sat, 5 Aug 2017 18:03:27 +0200
|
||||
Author : Julien Valentin
|
||||
update IndirectCommandArrays interfaces and default impl to use DrawElements like semantic
|
||||
|
||||
Wed, 2 Aug 2017 22:10:02 +0200
|
||||
Author : Julien Valentin
|
||||
add MDI support
|
||||
|
||||
Wed, 2 Aug 2017 21:50:25 +0200
|
||||
Author : Julien Valentin
|
||||
add resize methods method in CommandArrays (it allows user to work without casting to the concrete class result of MDI.getCommandArray()) move getTotalDataSize in CommandArrays interfaces comply with other DrawElementsXXX removing parameters in mdi constructors and add several method ( allow use of osgUtil::DrawElementTypeSimplifer on these)
|
||||
|
||||
Tue, 1 Aug 2017 07:54:37 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #293 from mp3butcher/MDI6fix a bug in MDI serializer
|
||||
|
||||
Tue, 1 Aug 2017 02:18:15 +0200
|
||||
Author : Julien Valentin
|
||||
fix a bug in MDI serializer
|
||||
|
||||
Mon, 31 Jul 2017 13:38:18 +0100
|
||||
Author : Robert Osfield
|
||||
Merged #pragmatic shader fix from OpenSceneGraph-3.4 branch.
|
||||
|
||||
Mon, 31 Jul 2017 08:09:16 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #287 from mp3butcher/MDI6correct a bug and make MDI example more conservative
|
||||
|
||||
Mon, 31 Jul 2017 03:15:03 +0200
|
||||
Author : Julien Valentin
|
||||
fix a bug : indices pre incremented should be post
|
||||
|
||||
Mon, 31 Jul 2017 03:08:52 +0200
|
||||
Author : Julien Valentin
|
||||
Add arguments, command line usage and use DrawElementsUInt for classic case
|
||||
|
||||
Mon, 31 Jul 2017 02:43:50 +0200
|
||||
Author : Julien Valentin
|
||||
correct a bug and make it more conservative
|
||||
|
||||
Sun, 30 Jul 2017 15:40:17 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #285 from mp3butcher/MDI6add a very simple example for mdi with basevertex
|
||||
|
||||
Sun, 30 Jul 2017 10:15:32 +0200
|
||||
Author : Julien Valentin
|
||||
add a very simple example for mdi with basevertex
|
||||
|
||||
Fri, 28 Jul 2017 17:17:25 +0100
|
||||
Author : Robert Osfield
|
||||
Updated version number, ChangeLog and AUTHORS file for 3.5.7 developer release
|
||||
|
||||
Fri, 28 Jul 2017 14:34:59 +0100
|
||||
Author : Robert Osfield
|
||||
Added missing break statements
|
||||
|
||||
Fri, 28 Jul 2017 14:32:56 +0100
|
||||
Author : Robert Osfield
|
||||
Improved readability and consistency with the rest OSG by adding/removing spaces and brackets where appropriate.
|
||||
|
||||
Fri, 28 Jul 2017 13:30:36 +0100
|
||||
Author : Robert Osfield
|
||||
Improved the readability and consistency with the rest of the OSG by inserting/removing spaces and line spacing.
|
||||
|
||||
Fri, 28 Jul 2017 10:27:47 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #267 from kornerr/masterAdd osgemscripten example
|
||||
|
||||
Fri, 28 Jul 2017 08:46:30 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #278 from mp3butcher/MDI2Mdi
|
||||
|
||||
Thu, 27 Jul 2017 12:27:55 +0200
|
||||
Author : mp3butcher
|
||||
set DIBO of the drawcommandarray directly in their interface constructor it makes osggpu use case lighter + drawcommandarray can't exist without a BO
|
||||
|
||||
Thu, 27 Jul 2017 12:00:41 +0200
|
||||
Author : mp3butcher
|
||||
Promote PrimitiveSetIndirect's VBO to a target explicited DIBO (in order to benefit from BOSet queue management)
|
||||
|
||||
Thu, 27 Jul 2017 10:26:43 +0100
|
||||
Author : OpenSceneGraph git repository
|
||||
Merge pull request #277 from mp3butcher/MDI2PrimitiveSetIndirect cleanup + serializers
|
||||
|
||||
Thu, 27 Jul 2017 01:54:25 +0200
|
||||
Author : mp3butcher
|
||||
add DrawIndirectBufferObject as State variable in order to minimize call to glBindBuffer(GL_DRAW_INDIRECT_BUFFER,X) TODO: Promote PrimitiveSetIndirect's VBO to target explicited DIBO (in order to benefit from BOSet queue management)
|
||||
|
||||
Thu, 27 Jul 2017 01:40:04 +0200
|
||||
Author : mp3butcher
|
||||
remove deprecated DrawIndirectBufferBinding
|
||||
|
||||
Thu, 27 Jul 2017 01:08:37 +0200
|
||||
Author : mp3butcher
|
||||
fix some errors during renaming and cleanup code
|
||||
|
||||
Wed, 26 Jul 2017 23:38:20 +0200
|
||||
Author : mp3butcher
|
||||
add untested serializers for PrimitiveSetIndirect
|
||||
|
||||
Wed, 26 Jul 2017 23:36:55 +0200
|
||||
Author : mp3butcher
|
||||
some renaming and harmonisations with osg metamodel convention
|
||||
|
||||
Wed, 26 Jul 2017 20:46:09 +0100
|
||||
Author : Robert Osfield
|
||||
Merge branch 'MDI2' of https://github.com/mp3butcher/OpenSceneGraph into MultiDrawIndirect
|
||||
|
||||
Wed, 26 Jul 2017 20:25:41 +0200
|
||||
Author : mp3butcher
|
||||
first commit for Indirect Draw integration in osg users will have to implement interfaces for their custom drawcommandarrays add a lot of new primitive set + few defines integration is made in osggpucull
|
||||
|
||||
Wed, 26 Jul 2017 12:54:37 +0100
|
||||
Author : Robert Osfield
|
||||
Replaced FindOurDCMTK.cmake usage with FindDCMTK.cmake
|
||||
|
@ -699,7 +699,9 @@ NameCorrection nameCorrections[] =
|
||||
{"WeSee", "",
|
||||
"Alois", "Wismer"},
|
||||
{"We", "See",
|
||||
"Alois", "Wismer"}
|
||||
"Alois", "Wismer"},
|
||||
{"AnyOldName3", "",
|
||||
"Chris", "Djali"}
|
||||
};
|
||||
|
||||
|
||||
|
@ -74,15 +74,11 @@ int main(int argc, char** argv)
|
||||
std::string url, username, password;
|
||||
while(arguments.read("--login",url, username, password))
|
||||
{
|
||||
if (!osgDB::Registry::instance()->getAuthenticationMap())
|
||||
{
|
||||
osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap);
|
||||
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(
|
||||
osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails(
|
||||
url,
|
||||
new osgDB::AuthenticationDetails(username, password)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
std::string device;
|
||||
while(arguments.read("--device", device))
|
||||
|
@ -336,15 +336,11 @@ int main( int argc, char **argv )
|
||||
std::string url, username, password;
|
||||
while(arguments.read("--login",url, username, password))
|
||||
{
|
||||
if (!osgDB::Registry::instance()->getAuthenticationMap())
|
||||
{
|
||||
osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap);
|
||||
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(
|
||||
osgDB::Registry::instance()->getOrCreateAuthenticationMap()->addAuthenticationDetails(
|
||||
url,
|
||||
new osgDB::AuthenticationDetails(username, password)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -473,7 +473,6 @@ void ComputeNode::addDataMonitor(osg::Vec3 placement, osg::Vec3 relativePlacemen
|
||||
pat->setName(labelCaption);
|
||||
text->setText(pat->getName());
|
||||
text->setBackdropType(osgText::Text::OUTLINE);
|
||||
text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET);
|
||||
text->setBackdropOffset(0.05f);
|
||||
text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
@ -773,7 +772,7 @@ void ComputeNode::initComputingSetup()
|
||||
_dataArray->setBufferObject(_ssbo.get());
|
||||
|
||||
|
||||
_ssbb = new osg::ShaderStorageBufferBinding(0, _dataArray, 0, blockSize);
|
||||
_ssbb = new osg::ShaderStorageBufferBinding(0, _dataArray.get(), 0, blockSize);
|
||||
statesetComputation->setAttributeAndModes(_ssbb.get(), osg::StateAttribute::ON);
|
||||
|
||||
|
||||
|
@ -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.
|
||||
osgViewer::Viewer viewer;
|
||||
osgViewer::Viewer viewer(arguments);
|
||||
|
||||
viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_FAR_USING_PRIMITIVES);
|
||||
viewer.getCamera()->setNearFarRatio(0.00001f);
|
||||
@ -144,6 +204,12 @@ int main(int, char**)
|
||||
csn->addChild(createFadeText(csn->getEllipsoidModel()));
|
||||
}
|
||||
|
||||
if (arguments.argc()>1)
|
||||
{
|
||||
TextSettings textSettings(arguments);
|
||||
root->accept(textSettings);
|
||||
}
|
||||
|
||||
viewer.setCameraManipulator(new osgGA::TerrainManipulator);
|
||||
|
||||
return viewer.run();
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include <osg/io_utils>
|
||||
#include <osg/ArgumentParser>
|
||||
#include <osg/Geode>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/WriteFile>
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
#include <osgGA/StateSetManipulator>
|
||||
@ -56,80 +59,367 @@ osg::Camera* createOrthoCamera(double width, double height)
|
||||
return camera;
|
||||
}
|
||||
|
||||
osgText::Text* createLabel(const std::string& l, const char* f, unsigned int size)
|
||||
typedef std::list<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();
|
||||
osg::ref_ptr<osgText::Font> font = osgText::readRefFontFile(f);
|
||||
|
||||
label->setFont(font);
|
||||
settings.setText(*label);
|
||||
|
||||
if (settings.scaleFontSizeToFontResolution)
|
||||
{
|
||||
label->setCharacterSize(size);
|
||||
}
|
||||
|
||||
label->setFontResolution(size, size);
|
||||
label->setColor(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));
|
||||
label->setPosition(pos);
|
||||
label->setAlignment(osgText::Text::LEFT_BOTTOM);
|
||||
|
||||
// It seems to be important we do this last to get best results?
|
||||
label->setText(l);
|
||||
|
||||
textInfo(label);
|
||||
// textInfo(label);
|
||||
|
||||
pos.y() += size + 10.0f;
|
||||
pos.y() += label->getCharacterHeight()*2.0;
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
typedef std::list<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)
|
||||
{
|
||||
osgViewer::Viewer viewer;
|
||||
osg::ArgumentParser args(&argc, argv);
|
||||
|
||||
// Make sure we have the minimum args...
|
||||
if(argc <= 2)
|
||||
{
|
||||
osg::notify(osg::FATAL) << "usage: " << args[0] << " fontfile size1 [size2 ...]" << std::endl;
|
||||
|
||||
return 1;
|
||||
}
|
||||
osgViewer::Viewer viewer(args);
|
||||
|
||||
|
||||
viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler());
|
||||
viewer.addEventHandler(new osgViewer::WindowSizeHandler());
|
||||
viewer.addEventHandler(new KeyHandler());
|
||||
|
||||
osg::Group* group = new osg::Group();
|
||||
osg::Camera* camera = createOrthoCamera(1280.0f, 1024.0f);
|
||||
TextSettings settings;
|
||||
settings.backgroundColor = viewer.getCamera()->getClearColor();
|
||||
|
||||
settings.read(args);
|
||||
|
||||
viewer.getCamera()->setClearColor(settings.backgroundColor);
|
||||
|
||||
osg::ref_ptr<osg::Group> root = new osg::Group;
|
||||
|
||||
bool split_screen = args.read("--split");
|
||||
|
||||
if (split_screen)
|
||||
{
|
||||
viewer.realize();
|
||||
|
||||
// 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::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.
|
||||
Sizes sizes;
|
||||
|
||||
for(int i = 2; i < argc; i++)
|
||||
for(int i = 2; i < args.argc(); i++)
|
||||
{
|
||||
if(!args.isNumber(i)) continue;
|
||||
|
||||
sizes.push_back(std::atoi(args[i]));
|
||||
settings.sizes.push_back(std::atoi(args[i]));
|
||||
}
|
||||
}
|
||||
|
||||
osg::Geode* geode = new osg::Geode();
|
||||
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.
|
||||
for(Sizes::const_iterator i = sizes.begin(); i != sizes.end(); i++)
|
||||
for(Sizes::const_iterator i = settings.sizes.begin(); i != settings.sizes.end(); i++)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
ss << *i << " 1234567890 abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
|
||||
geode->addDrawable(createLabel(ss.str(), args[1], *i));
|
||||
geode->addDrawable(createLabel(ss.str(), settings, *i, pos));
|
||||
}
|
||||
|
||||
camera->addChild(geode);
|
||||
root->addChild(geode.get());
|
||||
|
||||
group->addChild(camera);
|
||||
if (split_screen)
|
||||
{
|
||||
geode->setNodeMask(0x1);
|
||||
|
||||
viewer.setSceneData(group);
|
||||
osg::ref_ptr<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();
|
||||
}
|
||||
|
@ -188,7 +188,7 @@ struct IndirectTarget
|
||||
}
|
||||
void endRegister(unsigned int index, unsigned int rowsPerInstance, GLenum pixelFormat, GLenum type, GLint internalFormat, bool useMultiDrawArraysIndirect )
|
||||
{
|
||||
indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands);
|
||||
indirectCommandTextureBuffer = new osg::TextureBuffer(indirectCommands.get());
|
||||
indirectCommandTextureBuffer->setInternalFormat( GL_R32I );
|
||||
indirectCommandTextureBuffer->bindToImageUnit(index, osg::Texture::READ_WRITE);
|
||||
indirectCommandTextureBuffer->setUnRefImageDataAfterApply(false);
|
||||
@ -199,9 +199,10 @@ struct IndirectTarget
|
||||
{
|
||||
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 );
|
||||
ipr->setIndirectCommandArray( indirectCommands);
|
||||
ipr->setIndirectCommandArray( indirectCommands.get());
|
||||
newPrimitiveSets.push_back(ipr);
|
||||
}
|
||||
|
||||
@ -215,7 +216,7 @@ struct IndirectTarget
|
||||
else // use glMultiDrawArraysIndirect()
|
||||
{
|
||||
osg::MultiDrawArraysIndirect *ipr=new osg::MultiDrawArraysIndirect( GL_TRIANGLES );
|
||||
ipr->setIndirectCommandArray( indirectCommands );
|
||||
ipr->setIndirectCommandArray( indirectCommands.get() );
|
||||
geometryAggregator->getAggregatedGeometry()->removePrimitiveSet(0,geometryAggregator->getAggregatedGeometry()->getNumPrimitiveSets() );
|
||||
geometryAggregator->getAggregatedGeometry()->addPrimitiveSet( ipr );
|
||||
}
|
||||
@ -236,6 +237,7 @@ struct IndirectTarget
|
||||
instanceTarget->bindToImageUnit(OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, osg::Texture::READ_WRITE);
|
||||
|
||||
}
|
||||
|
||||
void addIndirectCommandData( const std::string& uniformNamePrefix, int index, osg::StateSet* stateset )
|
||||
{
|
||||
std::string uniformName = uniformNamePrefix + char( '0' + index );
|
||||
@ -245,6 +247,7 @@ struct IndirectTarget
|
||||
|
||||
|
||||
}
|
||||
|
||||
void addIndirectTargetData( bool cullPhase, const std::string& uniformNamePrefix, int index, osg::StateSet* stateset )
|
||||
{
|
||||
std::string uniformName;
|
||||
@ -257,6 +260,7 @@ struct IndirectTarget
|
||||
stateset->addUniform( uniform );
|
||||
stateset->setTextureAttribute( OSGGPUCULL_MAXIMUM_INDIRECT_TARGET_NUMBER+index, instanceTarget.get() );
|
||||
}
|
||||
|
||||
void addDrawProgram( const std::string& uniformBlockName, osg::StateSet* stateset )
|
||||
{
|
||||
drawProgram->addBindUniformBlock(uniformBlockName, 1);
|
||||
@ -286,6 +290,7 @@ struct GPUCullData
|
||||
instanceTypesUBB = new osg::UniformBufferBinding(1, instanceTypes.get(), 0, 0);
|
||||
|
||||
}
|
||||
|
||||
void setUseMultiDrawArraysIndirect( bool value )
|
||||
{
|
||||
useMultiDrawArraysIndirect = value;
|
||||
@ -297,6 +302,7 @@ struct GPUCullData
|
||||
return;
|
||||
targets[index] = IndirectTarget( agv, targetDrawProgram );
|
||||
}
|
||||
|
||||
bool registerType(unsigned int typeID, unsigned int targetID, osg::Node* node, const osg::Vec4& lodDistances, float maxDensityPerSquareKilometer )
|
||||
{
|
||||
if( typeID >= instanceTypes->getData().size() )
|
||||
@ -328,6 +334,7 @@ struct GPUCullData
|
||||
target->second.maxTargetQuantity += maxQuantity;
|
||||
return true;
|
||||
}
|
||||
|
||||
// endRegister() method is called after all indirect targets and instance types are registered.
|
||||
// It creates indirect targets with pixel format and data type provided by user ( indirect targets may hold
|
||||
// different information about single instance depending on user's needs ( in our example : static rendering
|
||||
@ -388,10 +395,12 @@ struct StaticInstance
|
||||
: position(m), extraParams(params), idParams(typeID,id,0,0)
|
||||
{
|
||||
}
|
||||
|
||||
osg::Vec3d getPosition() const
|
||||
{
|
||||
return position.getTrans();
|
||||
}
|
||||
|
||||
osg::Matrixf position;
|
||||
osg::Vec4f extraParams;
|
||||
osg::Vec4i idParams;
|
||||
@ -705,10 +714,12 @@ struct ResetTexturesCallback : public osg::StateSet::Callback
|
||||
ResetTexturesCallback()
|
||||
{
|
||||
}
|
||||
|
||||
void addTextureDirty( unsigned int texUnit )
|
||||
{
|
||||
texUnitsDirty.push_back(texUnit);
|
||||
}
|
||||
|
||||
void addTextureDirtyParams( unsigned int texUnit )
|
||||
{
|
||||
texUnitsDirtyParams.push_back(texUnit);
|
||||
@ -748,6 +759,7 @@ struct InvokeMemoryBarrier : public osg::Drawable::DrawCallback
|
||||
: _barriers(barriers)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void drawImplementation(osg::RenderInfo& renderInfo,const osg::Drawable* drawable) const
|
||||
{
|
||||
//DrawIndirectGLExtensions *ext = DrawIndirectGLExtensions::getExtensions( renderInfo.getContextID(), true );
|
||||
@ -836,11 +848,13 @@ osg::Group* createSimpleHouse( float detailRatio, const osg::Vec4& buildingColor
|
||||
osg::ref_ptr<osg::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor );
|
||||
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::Geode> chimneyGeode = convertShapeToGeode( *chimney.get(), tessHints.get(), chimneyColor );
|
||||
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::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
|
||||
_speed.push_back( random( 10.0, 16.0 ) );
|
||||
}
|
||||
|
||||
virtual void update(osg::NodeVisitor* nv, osg::Drawable* drawable)
|
||||
{
|
||||
if( nv->getVisitorType() != osg::NodeVisitor::UPDATE_VISITOR )
|
||||
@ -1213,6 +1228,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback
|
||||
setRotationUsingRotSpeed( i, 5, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(0.0,1.0,0.0)) * osg::Matrix::translate(0.0,2.0,-6.0), currentTime, 0.5 );
|
||||
setRotationUsingRotSpeed( i, 6, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(0.0,1.0,0.0)) * osg::Matrix::translate(0.0,-2.0,-6.0), currentTime, -0.5 );
|
||||
}
|
||||
|
||||
for(;i<2*_quantityPerType;++i) //update cars
|
||||
{
|
||||
nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) );
|
||||
@ -1223,6 +1239,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback
|
||||
setRotationUsingRotSpeed( i, 3, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(1.0,0.0,0.0)) * osg::Matrix::translate(2.0,-1.8,1.0), currentTime, wheelRotSpeed );
|
||||
setRotationUsingRotSpeed( i, 4, osg::Matrix::rotate( osg::DegreesToRadians(90.0), osg::Vec3(1.0,0.0,0.0)) * osg::Matrix::translate(-2.0,-1.8,1.0), currentTime, wheelRotSpeed );
|
||||
}
|
||||
|
||||
for(;i<3*_quantityPerType;++i) // update airplanes
|
||||
{
|
||||
nbbox.expandBy( updateObjectPosition( vertexArray, i, deltaTime ) );
|
||||
@ -1251,6 +1268,7 @@ struct AnimateObjectsCallback : public osg::DrawableUpdateCallback
|
||||
(*vertexArray)[index] = newPosition;
|
||||
return newPosition;
|
||||
}
|
||||
|
||||
void setRotationUsingRotSpeed( unsigned int index, unsigned int boneIndex, const osg::Matrix& zeroMatrix, double currentTime, double rotSpeed )
|
||||
{
|
||||
// setRotationUsingRotSpeed() is a very unoptimally written ( because it uses osg::Matrix::inverse() ),
|
||||
@ -1473,12 +1491,16 @@ int main( int argc, char **argv )
|
||||
|
||||
if ( arguments.read("--skip-static") )
|
||||
showStaticRendering = false;
|
||||
|
||||
if ( arguments.read("--skip-dynamic") )
|
||||
showDynamicRendering = false;
|
||||
|
||||
if ( arguments.read("--export-objects") )
|
||||
exportInstanceObjects = true;
|
||||
|
||||
if ( arguments.read("--use-multi-draw") )
|
||||
useMultiDrawArraysIndirect = true;
|
||||
|
||||
arguments.read("--instances-per-cell",instancesPerCell);
|
||||
arguments.read("--static-area-size",staticAreaSize);
|
||||
arguments.read("--dynamic-area-size",dynamicAreaSize);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <osgGA/TrackballManipulator>
|
||||
|
||||
#include <osgViewer/Viewer>
|
||||
#include <osgViewer/ViewerEventHandlers>
|
||||
|
||||
#include <osgDB/ReadFile>
|
||||
#include <osgDB/FileUtils>
|
||||
@ -424,6 +425,9 @@ int main( int argc, char **argv )
|
||||
// add the handler for doing the picking
|
||||
viewer.addEventHandler(new PickHandler(&viewer,updateText.get()));
|
||||
|
||||
// add the stats handler
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler);
|
||||
|
||||
osg::Group* root = new osg::Group();
|
||||
|
||||
root->addChild( setupGraph() );
|
||||
|
@ -41,6 +41,9 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
static bool s_useSDF = false;
|
||||
|
||||
class MyBillboardTransform : public osg::PositionAttitudeTransform
|
||||
{
|
||||
public:
|
||||
@ -147,6 +150,12 @@ osg:: Node* createTextBelow(const osg::BoundingBox& bb, const std::string& label
|
||||
|
||||
text->setFont(font);
|
||||
text->setFontResolution(64,64);
|
||||
|
||||
if (s_useSDF)
|
||||
{
|
||||
text->setShaderTechnique(osgText::ALL_FEATURES);
|
||||
}
|
||||
|
||||
text->setAlignment(osgText::Text::CENTER_CENTER);
|
||||
text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
text->setPosition(bb.center()-osg::Vec3(0.0f,0.0f,(bb.zMax()-bb.zMin())));
|
||||
@ -174,48 +183,35 @@ osg:: Node* createTextLeft(const osg::BoundingBox& bb, const std::string& label,
|
||||
|
||||
text->setFont(font);
|
||||
text->setFontResolution(110,120);
|
||||
|
||||
if (s_useSDF)
|
||||
{
|
||||
text->setShaderTechnique(osgText::ALL_FEATURES);
|
||||
}
|
||||
|
||||
text->setAlignment(osgText::Text::RIGHT_CENTER);
|
||||
text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
text->setCharacterSize((bb.zMax()-bb.zMin())*1.0f);
|
||||
|
||||
text->setPosition(bb.center()-osg::Vec3((bb.xMax()-bb.xMin()),-(bb.yMax()-bb.yMin())*0.5f,(bb.zMax()-bb.zMin())*0.1f));
|
||||
//text->setColor(osg::Vec4(0.37f,0.48f,0.67f,1.0f)); // Neil's original OSG colour
|
||||
text->setColor(osg::Vec4(0.20f,0.45f,0.60f,1.0f)); // OGL logo colour
|
||||
text->setText(label);
|
||||
|
||||
#if 1
|
||||
text->setBackdropType(osgText::Text::OUTLINE);
|
||||
// text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
|
||||
|
||||
text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET);
|
||||
// text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
|
||||
// text->setBackdropImplementation(osgText::Text::DEPTH_RANGE);
|
||||
// text->setBackdropImplementation(osgText::Text::STENCIL_BUFFER);
|
||||
|
||||
text->setBackdropOffset(0.05f);
|
||||
text->setBackdropOffset(0.03f);
|
||||
text->setBackdropColor(osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f));
|
||||
#endif
|
||||
|
||||
|
||||
#if 1
|
||||
text->setColorGradientMode(osgText::Text::OVERALL);
|
||||
osg::Vec4 lightblue(0.30f,0.6f,0.90f,1.0f);
|
||||
osg::Vec4 blue(0.10f,0.30f,0.40f,1.0f);
|
||||
text->setColorGradientCorners(lightblue, blue, blue, lightblue);
|
||||
#else
|
||||
text->setColorGradientMode(osgText::Text::OVERALL);
|
||||
osg::Vec4 light = osg::Vec4(0.0f, 1.0f, 1.0f, 1.0f);
|
||||
osg::Vec4 dark = osg::Vec4(0.0f, 0.0f, 0.5f, 1.0f);
|
||||
text->setColorGradientCorners(light, dark, dark, light);
|
||||
// text->setColorGradientCorners(dark, light, light, dark);
|
||||
#endif
|
||||
|
||||
text->setText(label);
|
||||
|
||||
geode->addDrawable( text );
|
||||
|
||||
|
||||
if (!subscript.empty())
|
||||
{
|
||||
//osgText::Text* subscript = new osgText::Text(new osgText::TextureFont(font,45));
|
||||
|
||||
osgText::Text* subscriptText = new osgText::Text;
|
||||
subscriptText->setFont(font);
|
||||
subscriptText->setText(subscript);
|
||||
@ -353,9 +349,6 @@ osg:: Node* createBoxNo5No2(const osg::BoundingBox& bb,float chordRatio)
|
||||
|
||||
osg:: Node* createBackdrop(const osg::Vec3& corner,const osg::Vec3& top,const osg::Vec3& right)
|
||||
{
|
||||
|
||||
|
||||
|
||||
osg::Geometry* geom = new osg::Geometry;
|
||||
|
||||
osg::Vec3 normal = (corner-top)^(right-corner);
|
||||
@ -475,6 +468,9 @@ int main( int argc, char **argv )
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
while(arguments.read("--sdf")) { s_useSDF = true; }
|
||||
|
||||
std::string label = "OpenSceneGraph";
|
||||
std::string subscript = "";
|
||||
|
||||
|
@ -69,10 +69,24 @@ int main( int argc, char**argv )
|
||||
arguments.read("--numX",MAXX);
|
||||
arguments.read("--numY",MAXY);
|
||||
|
||||
bool MDIenable=true;
|
||||
enum PrimtiveSetUsage
|
||||
{
|
||||
MultiDraw,
|
||||
MultiplePrimitiveSets,
|
||||
SinglePrimitiveSet
|
||||
};
|
||||
|
||||
PrimtiveSetUsage usage = MultiDraw;
|
||||
if(arguments.read("--classic"))
|
||||
{ MDIenable=false;
|
||||
OSG_WARN<<"disabling MDI"<<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 );
|
||||
@ -86,6 +100,7 @@ int main( int argc, char**argv )
|
||||
|
||||
osg::ref_ptr<osg::Geometry> geom=new osg::Geometry();
|
||||
geom->setUseVertexBufferObjects(true);
|
||||
|
||||
osg::BoundingBox bb;
|
||||
bb.set(0,0,0,MAXX,0,MAXY);
|
||||
//set bounds by hand cause of the lack of support of basevertex in PrimitiveFunctors
|
||||
@ -104,10 +119,10 @@ int main( int argc, char**argv )
|
||||
|
||||
osg::Vec3Array * verts=new osg::Vec3Array();
|
||||
|
||||
|
||||
for(int j =0 ; j<MAXY; ++j) {
|
||||
for(int i =0 ; i<MAXX; ++i) {
|
||||
|
||||
for(int j =0 ; j<MAXY; ++j)
|
||||
{
|
||||
for(int i =0 ; i<MAXX; ++i)
|
||||
{
|
||||
///create indirect command
|
||||
osg::DrawElementsIndirectCommand cmd;
|
||||
cmd.count=4;
|
||||
@ -116,24 +131,58 @@ int main( int argc, char**argv )
|
||||
cmd.baseVertex=verts->size();
|
||||
mdicommands->push_back(cmd);
|
||||
|
||||
for(int z=0; z<4; z++) {
|
||||
for(int z=0; z<4; z++)
|
||||
{
|
||||
verts->push_back(osg::Vec3(i,0,j)+myCoords[z]);
|
||||
mdi->addElement(myIndices[z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
geom->setVertexArray(verts);
|
||||
if(MDIenable) {
|
||||
geom->addPrimitiveSet(mdi);
|
||||
|
||||
} else
|
||||
for(int i=0; i<MAXY*MAXX; ++i) {
|
||||
osg::DrawElementsUInt *dre=new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLE_STRIP,4,myIndicesUI) ;
|
||||
dre->setElementBufferObject(ebo);
|
||||
geom->addPrimitiveSet(dre);
|
||||
geom->setVertexArray(verts);
|
||||
|
||||
switch(usage)
|
||||
{
|
||||
case(MultiDraw):
|
||||
{
|
||||
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);
|
||||
|
||||
osgViewer::Viewer viewer;
|
||||
viewer.addEventHandler(new osgViewer::StatsHandler);
|
||||
viewer.setSceneData( root );
|
||||
|
@ -621,8 +621,8 @@ struct TextCounterCallback : public osg::NodeCallback
|
||||
if (text)
|
||||
{
|
||||
std::stringstream str;
|
||||
str <<"Text Counter "<<_textCounter<<std::endl;
|
||||
OSG_NOTICE<<"Udating text"<<str.str()<<std::endl;
|
||||
str <<"Text Counter "<<_textCounter;
|
||||
OSG_NOTICE<<"Updating text : "<<str.str()<<std::endl;
|
||||
|
||||
text->setText(str.str());
|
||||
|
||||
@ -670,7 +670,7 @@ int main(int argc, char** argv)
|
||||
text->setUpdateCallback(new TextCounterCallback());
|
||||
text->setFont("fonts/times.ttf");
|
||||
text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
text->setText("This is a counter test");
|
||||
text->setText("Text Counter :");
|
||||
|
||||
viewer.setSceneData(text.get());
|
||||
}
|
||||
|
@ -49,18 +49,29 @@ public:
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else if (ea.getKey() == osgGA::GUIEventAdapter::KEY_Left)
|
||||
{
|
||||
m_Text3D->setText("setText\nworks!", osgText::String::ENCODING_UTF8); // ok
|
||||
OSG_NOTICE<<"m_Text3D->getText()="<<m_Text3D->getText().size()<<std::endl;
|
||||
static int counter = 1;
|
||||
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)
|
||||
{
|
||||
@ -90,7 +101,7 @@ int main(int argc, char** argv)
|
||||
if (!font) return 1;
|
||||
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)) {}
|
||||
|
||||
osg::ref_ptr<osgText::Style> style = new osgText::Style;
|
||||
|
@ -432,7 +432,6 @@ static void Internal_SetAlpha(NSBitmapImageRep *imageRep, unsigned char alpha_va
|
||||
|
||||
default_text->setAlignment(osgText::Text::CENTER_CENTER);
|
||||
default_text->setBackdropType(osgText::Text::OUTLINE);
|
||||
// default_text->setBackdropImplementation(osgText::Text::POLYGON_OFFSET);
|
||||
default_text->setColor(osg::Vec4(1.0, 1.0, 0.0, 1.0));
|
||||
default_text->setBackdropColor(osg::Vec4(0.0, 0.0, 0.0, 1.0));
|
||||
default_text->setAxisAlignment(osgText::Text::XZ_PLANE);
|
||||
|
@ -37,6 +37,8 @@ class EscapeHandler : public osgGA::GUIEventHandler
|
||||
int main(int argc,char** 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);
|
||||
|
||||
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)
|
||||
{
|
||||
if (!arguments.isOption(i))
|
||||
@ -60,8 +71,12 @@ int main(int argc,char** argv)
|
||||
|
||||
if (!password.empty())
|
||||
{
|
||||
if (!osgDB::Registry::instance()->getAuthenticationMap()) osgDB::Registry::instance()->setAuthenticationMap(new osgDB::AuthenticationMap);
|
||||
osgDB::Registry::instance()->getAuthenticationMap()->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password));
|
||||
const osgDB::AuthenticationMap* authenticationMap = osgDB::Registry::instance()->getOrCreateAuthenticationMap();
|
||||
const osgDB::AuthenticationDetails* details = authenticationMap->getAuthenticationDetails(hostname);
|
||||
if (details == NULL)
|
||||
{
|
||||
authenticationMap->addAuthenticationDetails(hostname, new osgDB::AuthenticationDetails("", password));
|
||||
}
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgWidget::VncClient> vncClient = new osgWidget::VncClient;
|
||||
|
@ -30,12 +30,6 @@ osgWidget::Label* createLabel(const std::string& l, unsigned int size=13) {
|
||||
label->setFontColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
label->setLabel(l);
|
||||
|
||||
/*
|
||||
text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
|
||||
text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
|
||||
text->setBackdropOffset(0.2f);
|
||||
*/
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
namespace osg {
|
||||
|
||||
@ -319,9 +320,15 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
|
||||
SHADER_GLES3
|
||||
};
|
||||
|
||||
void setShaderHint(ShaderHint hint) { _shaderHint = hint; }
|
||||
/** set the ShaderHint to tells shader generating cdoes version to create.
|
||||
* By default also OSG_GLSL_VERSION and OSG_PRECISION_FLOAT values that can get use directly in shaders using $OSG_GLSL_VERSION and $OSG_PRECISION_FLOAT respectively.*/
|
||||
void setShaderHint(ShaderHint hint, bool setShaderValues=true);
|
||||
ShaderHint getShaderHint() const { return _shaderHint; }
|
||||
|
||||
/** Set the TextShaderTechnique that is used in the Text default constructor to choose which osgText::ShaderTechnique to use.*/
|
||||
void setTextShaderTechnique(const std::string& str) { _textShaderTechnique = str; }
|
||||
const std::string& getTextShaderTechnique() const { return _textShaderTechnique; }
|
||||
|
||||
|
||||
void setKeystoneHint(bool enabled) { _keystoneHint = enabled; }
|
||||
bool getKeystoneHint() const { return _keystoneHint; }
|
||||
@ -358,6 +365,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
|
||||
/** helper function for computing the right eye view matrix.*/
|
||||
virtual osg::Matrixd computeRightEyeViewImplementation(const osg::Matrixd& view, double eyeSeperationScale=1.0) const;
|
||||
|
||||
|
||||
void setValue(const std::string& name, const std::string& value);
|
||||
|
||||
bool getValue(const std::string& name, std::string& value, bool use_getenv_fallback=true) const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~DisplaySettings();
|
||||
@ -415,6 +427,7 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
|
||||
|
||||
VertexBufferHint _vertexBufferHint;
|
||||
ShaderHint _shaderHint;
|
||||
std::string _textShaderTechnique;
|
||||
|
||||
bool _keystoneHint;
|
||||
FileNames _keystoneFileNames;
|
||||
@ -422,6 +435,11 @@ class OSG_EXPORT DisplaySettings : public osg::Referenced
|
||||
|
||||
OSXMenubarBehavior _OSXMenubarBehavior;
|
||||
|
||||
typedef std::map<std::string, std::string> ValueMap;
|
||||
|
||||
mutable OpenThreads::Mutex _valueMapMutex;
|
||||
mutable ValueMap _valueMap;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <osg/BufferObject>
|
||||
#include <osg/Vec2>
|
||||
#include <osg/Vec3>
|
||||
#include <osg/Vec3i>
|
||||
#include <osg/Vec4>
|
||||
#include <osg/FrameStamp>
|
||||
#include <osg/StateAttribute>
|
||||
@ -68,6 +69,10 @@
|
||||
#endif
|
||||
|
||||
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE) || defined(OSG_GLES3_AVAILABLE) || defined(OSG_GL3_AVAILABLE)
|
||||
#define GL_ALPHA4 0x803B
|
||||
#define GL_ALPHA8 0x803C
|
||||
#define GL_ALPHA12 0x803D
|
||||
#define GL_ALPHA16 0x803E
|
||||
#define GL_BITMAP 0x1A00
|
||||
#define GL_COLOR_INDEX 0x1900
|
||||
#define GL_INTENSITY12 0x804C
|
||||
@ -114,6 +119,38 @@
|
||||
#define GL_COMPRESSED_SIGNED_RG11_EAC 0x9273
|
||||
#endif
|
||||
|
||||
#ifndef GL_KHR_texture_compression_astc_hdr
|
||||
#define GL_KHR_texture_compression_astc_hdr 1
|
||||
#define GL_COMPRESSED_RGBA_ASTC_4x4_KHR 0x93B0
|
||||
#define GL_COMPRESSED_RGBA_ASTC_5x4_KHR 0x93B1
|
||||
#define GL_COMPRESSED_RGBA_ASTC_5x5_KHR 0x93B2
|
||||
#define GL_COMPRESSED_RGBA_ASTC_6x5_KHR 0x93B3
|
||||
#define GL_COMPRESSED_RGBA_ASTC_6x6_KHR 0x93B4
|
||||
#define GL_COMPRESSED_RGBA_ASTC_8x5_KHR 0x93B5
|
||||
#define GL_COMPRESSED_RGBA_ASTC_8x6_KHR 0x93B6
|
||||
#define GL_COMPRESSED_RGBA_ASTC_8x8_KHR 0x93B7
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x5_KHR 0x93B8
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x6_KHR 0x93B9
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x8_KHR 0x93BA
|
||||
#define GL_COMPRESSED_RGBA_ASTC_10x10_KHR 0x93BB
|
||||
#define GL_COMPRESSED_RGBA_ASTC_12x10_KHR 0x93BC
|
||||
#define GL_COMPRESSED_RGBA_ASTC_12x12_KHR 0x93BD
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR 0x93D0
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR 0x93D1
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR 0x93D2
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR 0x93D3
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR 0x93D4
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR 0x93D5
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR 0x93D6
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR 0x93D7
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR 0x93D8
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR 0x93D9
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR 0x93DA
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR 0x93DB
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR 0x93DC
|
||||
#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR 0x93DD
|
||||
#endif /* GL_KHR_texture_compression_astc_hdr */
|
||||
|
||||
#ifndef GL_DEPTH_COMPONENT
|
||||
#define GL_DEPTH_COMPONENT 0x1902
|
||||
#endif
|
||||
@ -404,11 +441,17 @@ class OSG_EXPORT Image : public BufferData
|
||||
static bool isPackedType(GLenum type);
|
||||
static GLenum computePixelFormat(GLenum pixelFormat);
|
||||
static GLenum computeFormatDataType(GLenum pixelFormat);
|
||||
|
||||
/** return the dimensions of a block of compressed pixels */
|
||||
static osg::Vec3i computeBlockFootprint(GLenum pixelFormat);
|
||||
|
||||
/** return the size in bytes of a block of compressed pixels */
|
||||
static unsigned int computeBlockSize(GLenum pixelFormat, GLenum packing);
|
||||
static unsigned int computeNumComponents(GLenum pixelFormat);
|
||||
static unsigned int computePixelSizeInBits(GLenum pixelFormat,GLenum type);
|
||||
static unsigned int computeRowWidthInBytes(int width,GLenum pixelFormat,GLenum type,int packing);
|
||||
static unsigned int computeImageSizeInBytes(int width,int height, int depth, GLenum pixelFormat, GLenum type, int packing = 1, int slice_packing = 1, int image_packing = 1);
|
||||
static int roudUpToMultiple(int s, int pack);
|
||||
static int computeNearestPowerOfTwo(int s,float bias=0.5f);
|
||||
static int computeNumberOfMipmapLevels(int s,int t = 1, int r = 1);
|
||||
|
||||
|
@ -168,8 +168,8 @@ public:
|
||||
}
|
||||
|
||||
/// get command array of this indirect primitive set
|
||||
inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray; }
|
||||
inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray; }
|
||||
inline IndirectCommandDrawElements* getIndirectCommandArray() { return _indirectCommandArray.get(); }
|
||||
inline const IndirectCommandDrawElements* getIndirectCommandArray() const { return _indirectCommandArray.get(); }
|
||||
|
||||
///Further methods are for advanced DI when you plan to use your own IndirectCommandElement (stride)
|
||||
///or if you want to draw a particular command index of the IndirectCommandElement(FirstCommandToDraw)
|
||||
@ -616,8 +616,8 @@ public:
|
||||
if(!dynamic_cast<DrawIndirectBufferObject* >(_indirectCommandArray->getBufferObject()))
|
||||
_indirectCommandArray->setBufferObject(new DrawIndirectBufferObject());
|
||||
}
|
||||
inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray; }
|
||||
inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray; }
|
||||
inline const IndirectCommandDrawArrays* getIndirectCommandArray() const { return _indirectCommandArray.get(); }
|
||||
inline IndirectCommandDrawArrays* getIndirectCommandArray() { return _indirectCommandArray.get(); }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -823,9 +823,12 @@ class OSG_EXPORT State : public Referenced
|
||||
* during rendering. */
|
||||
inline void setDisplaySettings(DisplaySettings* vs) { _displaySettings = vs; }
|
||||
|
||||
/** Get the DisplaySettings */
|
||||
/** Get the const DisplaySettings */
|
||||
inline const DisplaySettings* getDisplaySettings() const { return _displaySettings.get(); }
|
||||
|
||||
/** Get the const DisplaySettings that is current active DisplaySettings to be used by osg::State, - if DisplaySettings is not directly assigned then fallback to DisplaySettings::instance(). */
|
||||
inline const DisplaySettings* getActiveDisplaySettings() const { return _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get(); }
|
||||
|
||||
|
||||
|
||||
/** Set flag for early termination of the draw traversal.*/
|
||||
|
@ -34,6 +34,8 @@ public:
|
||||
modifiedCount(0xffffffff),
|
||||
active(false) {}
|
||||
|
||||
virtual const char* className() const = 0; // { return "ArrayDispatch"; }
|
||||
|
||||
virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/) {} // = 0;
|
||||
|
||||
virtual void enable_and_dispatch(osg::State& /*state*/, const osg::Array* /*new_array*/, const osg::GLBufferObject* /*vbo*/) {} // = 0;
|
||||
|
@ -50,6 +50,7 @@ class OSG_EXPORT VertexAttribDivisor : public StateAttribute
|
||||
COMPARE_StateAttribute_Types(VertexAttribDivisor,sa)
|
||||
|
||||
// compare each parameter in turn against the rhs.
|
||||
COMPARE_StateAttribute_Parameter(_index)
|
||||
COMPARE_StateAttribute_Parameter(_divisor)
|
||||
|
||||
return 0; // passed all the above comparison macros, must be equal.
|
||||
|
@ -134,7 +134,7 @@ public:
|
||||
: _name(copy._name), _indentDelta(copy._indentDelta) {}
|
||||
|
||||
void set( const char* name, int delta=0 )
|
||||
{ _name = name, _indentDelta = delta; }
|
||||
{ _name = name; _indentDelta = delta; }
|
||||
|
||||
std::string _name;
|
||||
int _indentDelta;
|
||||
|
@ -366,6 +366,13 @@ class OSGDB_EXPORT Registry : public osg::Referenced
|
||||
/** Set the password map to be used by plugins when access files from secure locations.*/
|
||||
void setAuthenticationMap(AuthenticationMap* authenticationMap) { _authenticationMap = authenticationMap; }
|
||||
|
||||
/** Get the password map to be used by plugins when access files from secure locations. Create a AuthenticationMap if one isn't already assigned.*/
|
||||
AuthenticationMap* getOrCreateAuthenticationMap()
|
||||
{
|
||||
if (!_authenticationMap) _authenticationMap = new AuthenticationMap;
|
||||
return _authenticationMap.get();
|
||||
}
|
||||
|
||||
/** Get the password map to be used by plugins when access files from secure locations.*/
|
||||
AuthenticationMap* getAuthenticationMap() { return _authenticationMap.get(); }
|
||||
|
||||
|
@ -27,6 +27,7 @@ namespace osgText {
|
||||
|
||||
// forward declare Font
|
||||
class Font;
|
||||
class TextBase;
|
||||
|
||||
#ifdef OSG_PROVIDE_READFILE
|
||||
/** Read a font from specified file. The filename may contain a path.
|
||||
@ -84,13 +85,9 @@ public:
|
||||
|
||||
static osg::ref_ptr<Font>& getDefaultFont();
|
||||
|
||||
void setTexEnv(osg::TexEnv* texenv) { if (texenv) _texenv = texenv; }
|
||||
inline osg::TexEnv* getTexEnv() { return _texenv.get(); }
|
||||
inline const osg::TexEnv* getTexEnv() const { return _texenv.get(); }
|
||||
|
||||
void setStateSet(osg::StateSet* stateset) { _stateset = stateset; }
|
||||
osg::StateSet* getStateSet() { return _stateset.get(); }
|
||||
const osg::StateSet* getStateSet() const { return _stateset.get(); }
|
||||
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSets;
|
||||
StateSets& getCachedStateSets() { return _statesets; }
|
||||
const StateSets& getCachedStateSets() const { return _statesets; }
|
||||
|
||||
|
||||
/** Get a kerning (adjustment of spacing of two adjacent character) for specified charcodes and a font resolution.*/
|
||||
@ -110,19 +107,6 @@ public:
|
||||
* return true on success, return false when not supported.*/
|
||||
virtual bool getVerticalSize(float& ascender, float& descender) const { return _implementation ? _implementation->getVerticalSize(ascender, descender) : false; }
|
||||
|
||||
/** Set the margin around each glyph,
|
||||
* to ensure that texture filtering doesn't bleed adjacent glyph's into each other.
|
||||
* Default margin is 1 texels.*/
|
||||
void setGlyphImageMargin(unsigned int margin);
|
||||
unsigned int getGlyphImageMargin() const;
|
||||
|
||||
/** Set the margin ratio around each glyph, relative to the glyph's size.
|
||||
* to ensure that texture filtering doesn't bleed adjacent glyph's into each other.
|
||||
* Default margin is 0.05.*/
|
||||
void setGlyphImageMarginRatio(float margin);
|
||||
float getGlyphImageMarginRatio() const;
|
||||
|
||||
|
||||
/** Set the size of texture to create to store the glyph images when rendering.
|
||||
* Note, this doesn't affect already created Texture Glhph's.*/
|
||||
void setTextureSizeHint(unsigned int width,unsigned int height);
|
||||
@ -140,6 +124,9 @@ public:
|
||||
void setMagFilterHint(osg::Texture::FilterMode mode);
|
||||
osg::Texture::FilterMode getMagFilterHint() const;
|
||||
|
||||
void setMaxAnisotropy(float anis) { _maxAnisotropy = anis; }
|
||||
float getMaxAnisotropy() const { return _maxAnisotropy; }
|
||||
|
||||
unsigned int getFontDepth() const { return _depth; }
|
||||
|
||||
void setNumberCurveSamples(unsigned int numSamples) { _numCurveSamples = numSamples; }
|
||||
@ -170,13 +157,14 @@ public:
|
||||
typedef std::vector< osg::ref_ptr<GlyphTexture> > GlyphTextureList;
|
||||
GlyphTextureList& getGlyphTextureList() { return _glyphTextureList; }
|
||||
|
||||
void assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~Font();
|
||||
|
||||
void addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph* glyph);
|
||||
|
||||
typedef std::vector< osg::ref_ptr<osg::StateSet> > StateSetList;
|
||||
typedef std::map< unsigned int, osg::ref_ptr<Glyph> > GlyphMap;
|
||||
typedef std::map< unsigned int, osg::ref_ptr<Glyph3D> > Glyph3DMap;
|
||||
|
||||
@ -185,8 +173,7 @@ protected:
|
||||
|
||||
mutable OpenThreads::Mutex _glyphMapMutex;
|
||||
|
||||
osg::ref_ptr<osg::TexEnv> _texenv;
|
||||
osg::ref_ptr<osg::StateSet> _stateset;
|
||||
StateSets _statesets;
|
||||
FontSizeGlyphMap _sizeGlyphMap;
|
||||
GlyphTextureList _glyphTextureList;
|
||||
|
||||
@ -195,13 +182,12 @@ protected:
|
||||
|
||||
// current active size of font
|
||||
FontResolution _fontSize;
|
||||
unsigned int _margin;
|
||||
float _marginRatio;
|
||||
|
||||
unsigned int _textureWidthHint;
|
||||
unsigned int _textureHeightHint;
|
||||
osg::Texture::FilterMode _minFilterHint;
|
||||
osg::Texture::FilterMode _magFilterHint;
|
||||
float _maxAnisotropy;
|
||||
|
||||
unsigned int _depth;
|
||||
unsigned int _numCurveSamples;
|
||||
@ -247,8 +233,6 @@ public:
|
||||
virtual bool getVerticalSize(float & /*ascender*/, float & /*descender*/) const { return false; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -30,15 +30,6 @@
|
||||
|
||||
#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 {
|
||||
|
||||
class Font;
|
||||
@ -47,6 +38,14 @@ class Glyph3D;
|
||||
class GlyphGeometry;
|
||||
class GlyphTexture;
|
||||
|
||||
enum ShaderTechnique
|
||||
{
|
||||
NO_TEXT_SHADER = 0x0,
|
||||
GREYSCALE = 0x1,
|
||||
SIGNED_DISTANCE_FIELD = 0x2,
|
||||
ALL_FEATURES = GREYSCALE | SIGNED_DISTANCE_FIELD
|
||||
};
|
||||
|
||||
class OSGTEXT_EXPORT Glyph : public osg::Image
|
||||
{
|
||||
public:
|
||||
@ -58,6 +57,9 @@ public:
|
||||
|
||||
unsigned int getGlyphCode() const { return _glyphCode; }
|
||||
|
||||
void setFontResolution(const FontResolution& fontRes) { _fontResolution = fontRes; }
|
||||
const FontResolution& getFontResolution() const { return _fontResolution; }
|
||||
|
||||
void setWidth(float width) { _width = width; }
|
||||
float getWidth() const { return _width; }
|
||||
|
||||
@ -76,21 +78,33 @@ public:
|
||||
void setVerticalAdvance(float advance);
|
||||
float getVerticalAdvance() const;
|
||||
|
||||
void setTexture(GlyphTexture* texture);
|
||||
GlyphTexture* getTexture();
|
||||
const GlyphTexture* getTexture() const;
|
||||
struct TextureInfo : public osg::Referenced
|
||||
{
|
||||
TextureInfo():
|
||||
texture(0),
|
||||
texelMargin(0.0f) {}
|
||||
|
||||
void setTexturePosition(int posX,int posY);
|
||||
int getTexturePositionX() const;
|
||||
int getTexturePositionY() const;
|
||||
TextureInfo(GlyphTexture* tex, int x, int y, const osg::Vec2& mintc, const osg::Vec2& maxtc, float margin):
|
||||
texture(tex),
|
||||
texturePositionX(x),
|
||||
texturePositionY(y),
|
||||
minTexCoord(mintc),
|
||||
maxTexCoord(maxtc),
|
||||
texelMargin(margin) {}
|
||||
|
||||
void setMinTexCoord(const osg::Vec2& coord);
|
||||
const osg::Vec2& getMinTexCoord() const;
|
||||
GlyphTexture* texture;
|
||||
int texturePositionX;
|
||||
int texturePositionY;
|
||||
osg::Vec2 minTexCoord;
|
||||
osg::Vec2 maxTexCoord;
|
||||
float texelMargin;
|
||||
};
|
||||
|
||||
void setMaxTexCoord(const osg::Vec2& coord);
|
||||
const osg::Vec2& getMaxTexCoord() const;
|
||||
void setTextureInfo(ShaderTechnique technique, TextureInfo* info);
|
||||
|
||||
void subload() const;
|
||||
const TextureInfo* getTextureInfo(ShaderTechnique technique) const;
|
||||
|
||||
TextureInfo* getOrCreateTextureInfo(ShaderTechnique technique);
|
||||
|
||||
protected:
|
||||
|
||||
@ -99,6 +113,8 @@ protected:
|
||||
Font* _font;
|
||||
unsigned int _glyphCode;
|
||||
|
||||
FontResolution _fontResolution;
|
||||
|
||||
float _width;
|
||||
float _height;
|
||||
|
||||
@ -108,15 +124,8 @@ protected:
|
||||
osg::Vec2 _verticalBearing;
|
||||
float _verticalAdvance;
|
||||
|
||||
GlyphTexture* _texture;
|
||||
int _texturePosX;
|
||||
int _texturePosY;
|
||||
osg::Vec2 _minTexCoord;
|
||||
osg::Vec2 _maxTexCoord;
|
||||
|
||||
typedef osg::buffered_value<GLuint> GLObjectList;
|
||||
mutable GLObjectList _globjList;
|
||||
|
||||
typedef std::vector< osg::ref_ptr<TextureInfo> > TextureInfoList;
|
||||
TextureInfoList _textureInfoList;
|
||||
};
|
||||
|
||||
class OSGTEXT_EXPORT GlyphGeometry : public osg::Referenced
|
||||
@ -253,12 +262,13 @@ public:
|
||||
/** return -1 if *this < *rhs, 0 if *this==*rhs, 1 if *this>*rhs.*/
|
||||
virtual int compare(const osg::StateAttribute& rhs) const;
|
||||
|
||||
/** Set the margin around each glyph, to ensure that texture filtering doesn't bleed adjacent glyph's into each other.*/
|
||||
void setGlyphImageMargin(unsigned int margin) { _margin = margin; }
|
||||
unsigned int getGlyphImageMargin() const { return _margin; }
|
||||
void setShaderTechnique(ShaderTechnique technique) { _shaderTechnique = technique; }
|
||||
|
||||
void setGlyphImageMarginRatio(float margin) { _marginRatio = margin; }
|
||||
float getGlyphImageMarginRatio() const { return _marginRatio; }
|
||||
ShaderTechnique getShaderTechnique() const { return _shaderTechnique; }
|
||||
|
||||
|
||||
int getEffectMargin(const Glyph* glyph);
|
||||
int getTexelMargin(const Glyph* glyph);
|
||||
|
||||
bool getSpaceForGlyph(Glyph* glyph, int& posX, int& posY);
|
||||
|
||||
@ -277,11 +287,10 @@ protected:
|
||||
|
||||
virtual ~GlyphTexture();
|
||||
|
||||
void copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info);
|
||||
|
||||
ShaderTechnique _shaderTechnique;
|
||||
|
||||
// parameter used to compute the size and position of empty space
|
||||
// in the texture which could accommodate new glyphs.
|
||||
int _margin;
|
||||
float _marginRatio;
|
||||
int _usedY;
|
||||
int _partUsedX;
|
||||
int _partUsedY;
|
||||
|
@ -36,15 +36,12 @@ public:
|
||||
virtual const char* className() const { return "Text"; }
|
||||
virtual const char* libraryName() const { return "osgText"; }
|
||||
|
||||
virtual void setFont(Font* font=0) { setFont(osg::ref_ptr<Font>(font)); };
|
||||
/** Set the ShaderTechnique hint to specify what fatures in the text shaders to enable.*/
|
||||
void setShaderTechnique(ShaderTechnique technique);
|
||||
|
||||
/** Set the Font to use to render the text.*/
|
||||
virtual void setFont(osg::ref_ptr<Font> font);
|
||||
/** Get the ShaderTechnique hint.*/
|
||||
ShaderTechnique getShaderTechnique() { return _shaderTechnique; }
|
||||
|
||||
/** Set the font, loaded from the specified front file, to use to render the text,
|
||||
* setFont("") sets the use of the default font.
|
||||
* See the osgText::readFontFile function for how the font file will be located. */
|
||||
virtual void setFont(const std::string& fontfile) { TextBase::setFont(fontfile); }
|
||||
|
||||
/**
|
||||
* Turns off writing to the depth buffer when rendering text. This only affects text
|
||||
@ -70,31 +67,6 @@ public:
|
||||
NONE
|
||||
};
|
||||
|
||||
enum BackdropImplementation
|
||||
{
|
||||
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
|
||||
POLYGON_OFFSET = 0,
|
||||
|
||||
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
|
||||
NO_DEPTH_BUFFER,
|
||||
|
||||
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
|
||||
DEPTH_RANGE,
|
||||
|
||||
/* No longer supported, naps to DELAYED_DEPTH_WRITES.*/
|
||||
STENCIL_BUFFER,
|
||||
|
||||
/* DELAYED_DEPTH_WRITES
|
||||
* This mode renders all text with depth writes turned off, then
|
||||
* again with depth writes on, but with the color buffer disabled.
|
||||
* This should render text accurately for all graphics cards. The
|
||||
* only downside is the additional pass to render to the depth
|
||||
* buffer. But if you don't need the depth buffer updated for
|
||||
* your, this extra pass can be disabled by calling
|
||||
* enableDepthWrites(false).*/
|
||||
DELAYED_DEPTH_WRITES
|
||||
};
|
||||
|
||||
/**
|
||||
* BackdropType gives you a background shadow text behind your regular
|
||||
* text. This helps give text extra contrast which can be useful when
|
||||
@ -149,18 +121,6 @@ public:
|
||||
|
||||
const osg::Vec4& getBackdropColor() const { return _backdropColor; }
|
||||
|
||||
/**
|
||||
* This specifies the underlying backdrop rendering implementation.
|
||||
* Unfortunately, at this time, there is no "perfect" rendering solution
|
||||
* so this function is provided to let you 'pick your poison'. Each
|
||||
* implementation has trade-offs. See BackdropImplementation enum
|
||||
* docs for details.*/
|
||||
void setBackdropImplementation(BackdropImplementation implementation);
|
||||
|
||||
BackdropImplementation getBackdropImplementation() const { return _backdropImplementation; }
|
||||
|
||||
|
||||
|
||||
enum ColorGradientMode
|
||||
{
|
||||
SOLID = 0, // a.k.a. ColorGradients off
|
||||
@ -232,6 +192,20 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
/** deprecated, value ignored.*/
|
||||
enum BackdropImplementation
|
||||
{
|
||||
POLYGON_OFFSET = 0,
|
||||
NO_DEPTH_BUFFER,
|
||||
DEPTH_RANGE,
|
||||
STENCIL_BUFFER,
|
||||
DELAYED_DEPTH_WRITES
|
||||
};
|
||||
|
||||
/** deprecated, value ignored.*/
|
||||
void setBackdropImplementation(BackdropImplementation) {}
|
||||
/** deprecated, value should be ignored.*/
|
||||
BackdropImplementation getBackdropImplementation() const { return DELAYED_DEPTH_WRITES; }
|
||||
|
||||
// internal structures, variable and methods used for rendering of characters.
|
||||
struct OSGTEXT_EXPORT GlyphQuads
|
||||
@ -239,7 +213,7 @@ public:
|
||||
typedef std::vector<Glyph*> Glyphs;
|
||||
|
||||
Glyphs _glyphs;
|
||||
Primitives _primitives;
|
||||
osg::ref_ptr<osg::DrawElements> _primitives;
|
||||
|
||||
GlyphQuads();
|
||||
GlyphQuads(const GlyphQuads& gq);
|
||||
@ -284,6 +258,8 @@ protected:
|
||||
|
||||
virtual ~Text();
|
||||
|
||||
virtual osg::StateSet* createStateSet();
|
||||
|
||||
Font* getActiveFont();
|
||||
const Font* getActiveFont() const;
|
||||
|
||||
@ -302,7 +278,6 @@ protected:
|
||||
|
||||
virtual void computePositionsImplementation();
|
||||
|
||||
void computeBackdropPositions();
|
||||
void computeBackdropBoundingBox();
|
||||
void computeBoundingBoxMargin();
|
||||
|
||||
@ -314,10 +289,10 @@ protected:
|
||||
|
||||
void drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const;
|
||||
|
||||
ShaderTechnique _shaderTechnique;
|
||||
bool _enableDepthWrites;
|
||||
|
||||
BackdropType _backdropType;
|
||||
BackdropImplementation _backdropImplementation;
|
||||
|
||||
float _backdropHorizontalOffset;
|
||||
float _backdropVerticalOffset;
|
||||
|
@ -53,6 +53,9 @@ public:
|
||||
virtual void setFont(const std::string& fontfile);
|
||||
|
||||
/** Get the font. Return 0 if default is being used.*/
|
||||
Font* getFont() { return _font.get(); }
|
||||
|
||||
/** Get the const font. Return 0 if default is being used.*/
|
||||
const Font* getFont() const { return _font.get(); }
|
||||
|
||||
|
||||
@ -284,6 +287,10 @@ protected:
|
||||
|
||||
virtual ~TextBase();
|
||||
|
||||
virtual osg::StateSet* createStateSet();
|
||||
|
||||
virtual void assignStateSet();
|
||||
|
||||
void initArraysAndBuffers();
|
||||
|
||||
osg::VertexArrayState* createVertexArrayState(osg::RenderInfo& renderInfo) const;
|
||||
|
@ -97,6 +97,9 @@ class OSGUTIL_EXPORT GLObjectsVisitor : public osg::NodeVisitor
|
||||
void apply(osg::Drawable& drawable);
|
||||
void apply(osg::StateSet& stateset);
|
||||
|
||||
/** Do a compile traversal and then reset any state,*/
|
||||
void compile(osg::Node& node);
|
||||
|
||||
protected:
|
||||
|
||||
typedef std::set<osg::Drawable*> DrawableAppliedSet;
|
||||
|
@ -52,8 +52,8 @@ class OSGUTIL_EXPORT RenderLeaf : public osg::Referenced
|
||||
{
|
||||
_parent = 0;
|
||||
_drawable = drawable;
|
||||
_projection = projection,
|
||||
_modelview = modelview,
|
||||
_projection = projection;
|
||||
_modelview = modelview;
|
||||
_depth = depth;
|
||||
_dynamic = (drawable->getDataVariance()==osg::Object::DYNAMIC);
|
||||
_traversalNumber = traversalNumber;
|
||||
|
@ -37,10 +37,11 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub
|
||||
_parent(0),
|
||||
_window(0),
|
||||
_visualInfo(0),
|
||||
_fbConfig(0),
|
||||
#ifdef OSG_USE_EGL
|
||||
_eglDisplay(0),
|
||||
_eglSurface(0),
|
||||
#else
|
||||
_fbConfig(0),
|
||||
#endif
|
||||
_currentCursor(0),
|
||||
_initialized(false),
|
||||
@ -177,11 +178,12 @@ class OSGVIEWER_EXPORT GraphicsWindowX11 : public osgViewer::GraphicsWindow, pub
|
||||
Window _parent;
|
||||
Window _window;
|
||||
XVisualInfo* _visualInfo;
|
||||
GLXFBConfig _fbConfig;
|
||||
|
||||
#ifdef OSG_USE_EGL
|
||||
EGLDisplay _eglDisplay;
|
||||
EGLSurface _eglSurface;
|
||||
#else
|
||||
GLXFBConfig _fbConfig;
|
||||
#endif
|
||||
|
||||
Cursor _currentCursor;
|
||||
|
@ -118,7 +118,8 @@ void DisplaySettings::setDisplaySettings(const DisplaySettings& vs)
|
||||
_swapMethod = vs._swapMethod;
|
||||
|
||||
_vertexBufferHint = vs._vertexBufferHint;
|
||||
_shaderHint = vs._shaderHint;
|
||||
|
||||
setShaderHint(_shaderHint);
|
||||
|
||||
_keystoneHint = vs._keystoneHint;
|
||||
_keystoneFileNames = vs._keystoneFileNames;
|
||||
@ -250,23 +251,17 @@ void DisplaySettings::setDefaults()
|
||||
// _vertexBufferHint = VERTEX_ARRAY_OBJECT;
|
||||
|
||||
#if defined(OSG_GLES3_AVAILABLE)
|
||||
_shaderHint = SHADER_GLES3;
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GLES3"<<std::endl;
|
||||
setShaderHint(SHADER_GLES3);
|
||||
#elif defined(OSG_GLES2_AVAILABLE)
|
||||
_shaderHint = SHADER_GLES2;
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GLES2"<<std::endl;
|
||||
setShaderHint(SHADER_GLES2);
|
||||
#elif defined(OSG_GL3_AVAILABLE)
|
||||
_shaderHint = SHADER_GL3;
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GL3"<<std::endl;
|
||||
setShaderHint(SHADER_GL3);
|
||||
#elif defined(OSG_GL_VERTEX_ARRAY_FUNCS_AVAILABLE)
|
||||
OSG_INFO<<"DisplaySettings::SHADER_NONE"<<std::endl;
|
||||
_shaderHint = SHADER_NONE;
|
||||
setShaderHint(SHADER_NONE);
|
||||
#else
|
||||
OSG_INFO<<"DisplaySettings::SHADER_GL2"<<std::endl;
|
||||
_shaderHint = SHADER_GL2;
|
||||
setShaderHint(SHADER_GL2);
|
||||
#endif
|
||||
|
||||
|
||||
_keystoneHint = false;
|
||||
|
||||
_OSXMenubarBehavior = MENUBAR_AUTO_HIDE;
|
||||
@ -390,6 +385,9 @@ static ApplicationUsageProxy DisplaySetting_e31(ApplicationUsage::ENVIRONMENTAL_
|
||||
static ApplicationUsageProxy DisplaySetting_e32(ApplicationUsage::ENVIRONMENTAL_VARIABLE,
|
||||
"OSG_VERTEX_BUFFER_HINT <value>",
|
||||
"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()
|
||||
{
|
||||
@ -725,26 +723,30 @@ void DisplaySettings::readEnvironmentalVariables()
|
||||
{
|
||||
if (strcmp(ptr,"GL2")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GL2;
|
||||
setShaderHint(SHADER_GL2);
|
||||
}
|
||||
else if (strcmp(ptr,"GL3")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GL3;
|
||||
setShaderHint(SHADER_GL3);
|
||||
}
|
||||
else if (strcmp(ptr,"GLES2")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GLES2;
|
||||
setShaderHint(SHADER_GLES2);
|
||||
}
|
||||
else if (strcmp(ptr,"GLES3")==0)
|
||||
{
|
||||
_shaderHint = SHADER_GLES3;
|
||||
setShaderHint(SHADER_GLES3);
|
||||
}
|
||||
else if (strcmp(ptr,"NONE")==0)
|
||||
{
|
||||
_shaderHint = SHADER_NONE;
|
||||
setShaderHint(SHADER_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
if ((ptr = getenv("OSG_TEXT_SHADER_TECHNIQUE")) != 0)
|
||||
{
|
||||
setTextShaderTechnique(ptr);
|
||||
}
|
||||
|
||||
if( (ptr = getenv("OSG_KEYSTONE")) != 0)
|
||||
{
|
||||
@ -1098,3 +1100,84 @@ osg::Matrixd DisplaySettings::computeRightEyeViewImplementation(const osg::Matri
|
||||
0.0,0.0,1.0,0.0,
|
||||
-es,0.0,0.0,1.0);
|
||||
}
|
||||
|
||||
void DisplaySettings::setShaderHint(ShaderHint hint, bool setShaderValues)
|
||||
{
|
||||
_shaderHint = hint;
|
||||
if (setShaderValues)
|
||||
{
|
||||
switch(_shaderHint)
|
||||
{
|
||||
case(SHADER_GLES3) :
|
||||
setValue("OSG_GLSL_VERSION", "#version 300 es");
|
||||
setValue("OSG_PRECISION_FLOAT", "precision highp float;");
|
||||
setValue("OSG_VARYING_IN", "in");
|
||||
setValue("OSG_VARYING_OUT", "out");
|
||||
OSG_NOTICE<<"DisplaySettings::SHADER_GLES3"<<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;
|
||||
}
|
||||
}
|
||||
|
@ -241,13 +241,19 @@ Image::Image(const Image& image,const CopyOp& copyop):
|
||||
{
|
||||
unsigned int size = image.getTotalSizeInBytesIncludingMipmaps();
|
||||
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());
|
||||
dest_ptr += itr.size();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
OSG_WARN<<"Warning: Image::Image(const Image&, const CopyOp&) out of memory, no image copy made."<<std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image::~Image()
|
||||
@ -602,7 +608,36 @@ unsigned int Image::computeNumComponents(GLenum pixelFormat)
|
||||
case(GL_BGRA_INTEGER_EXT): return 4;
|
||||
case(GL_LUMINANCE_INTEGER_EXT): return 1;
|
||||
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:
|
||||
{
|
||||
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;
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
switch(pixelFormat)
|
||||
@ -761,6 +906,35 @@ unsigned int Image::computeBlockSize(GLenum pixelFormat, GLenum packing)
|
||||
case(GL_COMPRESSED_RG11_EAC):
|
||||
case(GL_COMPRESSED_SIGNED_RG11_EAC):
|
||||
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:
|
||||
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;
|
||||
|
||||
// Taking advantage of the fact that
|
||||
// DXT formats are defined as 4 successive numbers:
|
||||
// GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0
|
||||
// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1
|
||||
// GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2
|
||||
// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3
|
||||
if( pixelFormat >= GL_COMPRESSED_RGB_S3TC_DXT1_EXT &&
|
||||
pixelFormat <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT )
|
||||
{
|
||||
width = (width + 3) & ~3;
|
||||
height = (height + 3) & ~3;
|
||||
}
|
||||
|
||||
// 3dc ATI formats
|
||||
// GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB
|
||||
// GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC
|
||||
// GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD
|
||||
// GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE
|
||||
if( pixelFormat >= GL_COMPRESSED_RED_RGTC1_EXT &&
|
||||
pixelFormat <= GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT )
|
||||
{
|
||||
width = (width + 3) & ~3;
|
||||
height = (height + 3) & ~3;
|
||||
int blockSize = computeBlockSize(pixelFormat, 0);
|
||||
if (blockSize > 0) {
|
||||
osg::Vec3i footprint = computeBlockFootprint(pixelFormat);
|
||||
width = (width + footprint.x() - 1) / footprint.x();
|
||||
height = (height + footprint.y() - 1) / footprint.y();
|
||||
unsigned int size = blockSize * width;
|
||||
size = roudUpToMultiple(size, packing);
|
||||
size *= height;
|
||||
size = roudUpToMultiple(size, slice_packing);
|
||||
size *= depth;
|
||||
size = roudUpToMultiple(size, image_packing);
|
||||
return size;
|
||||
}
|
||||
|
||||
// compute size of one row
|
||||
@ -821,6 +984,13 @@ unsigned int Image::computeImageSizeInBytes(int width,int height, int depth, GLe
|
||||
return osg::maximum( size, computeBlockSize(pixelFormat, packing) );
|
||||
}
|
||||
|
||||
int Image::roudUpToMultiple(int s, int pack) {
|
||||
if (pack < 2) return s;
|
||||
s += pack - 1;
|
||||
s -= s % pack;
|
||||
return s;
|
||||
}
|
||||
|
||||
int Image::computeNearestPowerOfTwo(int s,float bias)
|
||||
{
|
||||
if ((s & (s-1))!=0)
|
||||
@ -880,6 +1050,34 @@ bool Image::isCompressed() const
|
||||
case(GL_COMPRESSED_SIGNED_R11_EAC):
|
||||
case(GL_COMPRESSED_RG11_EAC):
|
||||
case(GL_COMPRESSED_SIGNED_RG11_EAC):
|
||||
case (GL_COMPRESSED_RGBA_ASTC_4x4_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_5x4_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_5x5_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_6x5_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_6x6_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_8x5_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_8x6_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_8x8_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_10x5_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_10x6_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_10x8_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_10x10_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_12x10_KHR) :
|
||||
case (GL_COMPRESSED_RGBA_ASTC_12x12_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR) :
|
||||
case (GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR) :
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
@ -1189,7 +1387,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
|
||||
unsigned char* data = new unsigned char[total_size];
|
||||
if (!data)
|
||||
{
|
||||
OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, now image read."<<std::endl;
|
||||
OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, no image read."<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1256,7 +1454,7 @@ void Image::readImageFromCurrentTexture(unsigned int contextID, bool copyMipMaps
|
||||
unsigned char* data = new unsigned char[total_size];
|
||||
if (!data)
|
||||
{
|
||||
OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, now image read."<<std::endl;
|
||||
OSG_WARN<<"Warning: Image::readImageFromCurrentTexture(..) out of memory, no image read."<<std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1409,8 +1607,38 @@ void Image::copySubImage(int s_offset, int t_offset, int r_offset, const osg::Im
|
||||
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;
|
||||
psm.pack_alignment = _packing;
|
||||
psm.pack_row_length = _rowLength!=0 ? _rowLength : _s;
|
||||
@ -1719,7 +1947,7 @@ bool Image::isImageTranslucent() const
|
||||
case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT):
|
||||
case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT):
|
||||
case(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT):
|
||||
return dxtc_tool::CompressedImageTranslucent(_s, _t, _pixelFormat, _data);
|
||||
return dxtc_tool::isCompressedImageTranslucent(_s, _t, _pixelFormat, _data);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@ -1918,9 +2146,19 @@ Vec4 _readColor(GLenum pixelFormat, T* data,float scale)
|
||||
}
|
||||
|
||||
Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const
|
||||
{
|
||||
if (isCompressed())
|
||||
{
|
||||
if (dxtc_tool::isDXTC(_pixelFormat)) {
|
||||
unsigned char color[4];
|
||||
if (dxtc_tool::CompressedImageGetColor(color, s, t, r, _s, _t, _r, _pixelFormat, _data)) {
|
||||
return Vec4(((float)color[0]) / 255.0f, ((float)color[1]) / 255.0f, ((float)color[2]) / 255.0f, ((float)color[3]) / 255.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned char* ptr = data(s,t,r);
|
||||
|
||||
switch(_dataType)
|
||||
{
|
||||
case(GL_BYTE): return _readColor(_pixelFormat, (char*)ptr, 1.0f/128.0f);
|
||||
@ -1932,6 +2170,7 @@ Vec4 Image::getColor(unsigned int s,unsigned t,unsigned r) const
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <osg/Notify>
|
||||
#include <osg/io_utils>
|
||||
#include "dxtctool.h"
|
||||
|
||||
namespace osg
|
||||
{
|
||||
@ -716,6 +717,49 @@ OSG_EXPORT osg::Image* createImageWithOrientationConversion(const osg::Image* sr
|
||||
unsigned int pixelSizeInBits = srcImage->getPixelSizeInBits();
|
||||
unsigned int pixelSizeInBytes = pixelSizeInBits/8;
|
||||
unsigned int pixelSizeRemainder = pixelSizeInBits%8;
|
||||
if (dxtc_tool::isDXTC(srcImage->getPixelFormat()))
|
||||
{
|
||||
unsigned int DXTblockSize = 8;
|
||||
if ((srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) || (srcImage->getPixelFormat() == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) DXTblockSize = 16;
|
||||
unsigned int DXTblocksWidht = (srcImage->s() + 3) / 4;//width in 4x4 blocks
|
||||
unsigned int DXTblocksHeight = (srcImage->t() + 3) / 4;//height in 4x4 blocks
|
||||
unsigned int dst_DXTblocksWidht = (width + 3) / 4;//width in 4x4 blocks
|
||||
unsigned int dst_DXTblocksHeight = (height + 3) / 4;//height in 4x4 blocks
|
||||
|
||||
dstImage->allocateImage(width, height, depth, srcImage->getPixelFormat(), srcImage->getDataType());
|
||||
// copy across the pixels from the source image to the destination image.
|
||||
if (depth != 1)
|
||||
{
|
||||
OSG_NOTICE << "Warning: createImageWithOrientationConversion(..) cannot handle dxt-compressed images with depth." << std::endl;
|
||||
return const_cast<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)
|
||||
{
|
||||
OSG_NOTICE<<"Warning: createImageWithOrientationConversion(..) cannot handle non byte aligned pixel formats."<<std::endl;
|
||||
|
@ -89,6 +89,19 @@ struct NoneOf
|
||||
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;
|
||||
@ -618,30 +631,32 @@ void Shader::PerContextShader::compileShader(osg::State& state)
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
if (osg::getNotifyLevel()>=osg::INFO)
|
||||
{
|
||||
std::string sourceWithLineNumbers = insertLineNumbers(source);
|
||||
OSG_INFO << "\nCompiling " << _shader->getTypename()
|
||||
<< " source:\n" << sourceWithLineNumbers << std::endl;
|
||||
}
|
||||
|
||||
GLint compiled = GL_FALSE;
|
||||
|
||||
// OSG_NOTICE<<"Compiling PerContextShader "<<this<<" ShaderDefine="<<getDefineString()<<std::endl;
|
||||
// OSG_NOTICE<<"Compiling PerContextShader "<<this<<" DefineString="<<getDefineString()<<std::endl;
|
||||
|
||||
if (_defineStr.empty())
|
||||
{
|
||||
const GLchar* sourceText = reinterpret_cast<const GLchar*>(source.c_str());
|
||||
_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
|
||||
{
|
||||
// Convert all windows line endings to \n
|
||||
replaceAll(source, "\r\n", " \n");
|
||||
|
||||
std::string versionLine;
|
||||
unsigned int lineNum = 0;
|
||||
@ -675,21 +690,40 @@ void Shader::PerContextShader::compileShader(osg::State& state)
|
||||
|
||||
if (!versionLine.empty())
|
||||
{
|
||||
// OSG_NOTICE<<"Shader::PerContextShader::compileShader() : Found #version, lineNum = "<<lineNum<<" ["<<versionLine<<"] new source = ["<<source<<"]"<<std::endl;
|
||||
const GLchar* sourceText[3];
|
||||
//OSG_NOTICE<<"glShaderSource() ["<<versionLine<<"] "<<std::endl<<"["<<_defineStr<<"], ["<<sourceText<<"]"<<std::endl;
|
||||
sourceText[0] = reinterpret_cast<const GLchar*>(versionLine.c_str());
|
||||
sourceText[1] = reinterpret_cast<const GLchar*>(_defineStr.c_str());
|
||||
sourceText[2] = reinterpret_cast<const GLchar*>(source.c_str());
|
||||
_extensions->glShaderSource( _glShaderHandle, 3, sourceText, NULL );
|
||||
|
||||
if (osg::getNotifyLevel()>=osg::INFO)
|
||||
{
|
||||
std::string sourceWithLineNumbers = insertLineNumbers(versionLine+_defineStr+source);
|
||||
OSG_INFO << "\nCompiling B: " << _shader->getTypename()
|
||||
<< " source:\n" << sourceWithLineNumbers << std::endl;
|
||||
}
|
||||
|
||||
// OSG_NOTICE<<" Version Line : ["<<std::endl<<versionLine<<"]"<<std::endl;
|
||||
// OSG_NOTICE<<" DefineStr : ["<<std::endl<<_defineStr<<"]"<<std::endl;
|
||||
// OSG_NOTICE<<" Source : ["<<std::endl<<source<<"]"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
const GLchar* sourceText[2];
|
||||
//OSG_NOTICE<<"glShaderSource() ["<<_defineStr<<"], ["<<sourceText<<"]"<<std::endl;
|
||||
sourceText[0] = reinterpret_cast<const GLchar*>(_defineStr.c_str());
|
||||
sourceText[1] = reinterpret_cast<const GLchar*>(source.c_str());
|
||||
_extensions->glShaderSource( _glShaderHandle, 2, sourceText, NULL );
|
||||
|
||||
|
||||
if (osg::getNotifyLevel()>=osg::INFO)
|
||||
{
|
||||
std::string sourceWithLineNumbers = insertLineNumbers(_defineStr+source);
|
||||
OSG_INFO << "\nCompiling C: " << _shader->getTypename()
|
||||
<< " source:\n" << sourceWithLineNumbers << std::endl;
|
||||
}
|
||||
|
||||
// OSG_NOTICE<<" DefineStr : ["<<std::endl<<_defineStr<<"]"<<std::endl;
|
||||
// OSG_NOTICE<<" Source : ["<<std::endl<<source<<"]"<<std::endl;
|
||||
}
|
||||
}
|
||||
_extensions->glCompileShader( _glShaderHandle );
|
||||
|
@ -1216,13 +1216,69 @@ namespace State_Utils
|
||||
source.insert(declPos, qualifier + declarationPrefix + newStr + std::string(";\n"));
|
||||
}
|
||||
}
|
||||
|
||||
void replaceVar(const osg::State& state, std::string& str, std::string::size_type start_pos, std::string::size_type num_chars)
|
||||
{
|
||||
std::string var_str(str.substr(start_pos+1, num_chars-1));
|
||||
std::string value;
|
||||
if (state.getActiveDisplaySettings()->getValue(var_str, value))
|
||||
{
|
||||
str.replace(start_pos, num_chars, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
str.erase(start_pos, num_chars);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void substitudeEnvVars(const osg::State& state, std::string& str)
|
||||
{
|
||||
std::string::size_type pos = 0;
|
||||
while (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
|
||||
{
|
||||
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 ");
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
@ -168,10 +168,10 @@ void Texture1D::apply(State& state) const
|
||||
}
|
||||
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.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels);
|
||||
}
|
||||
|
||||
}
|
||||
@ -206,13 +206,13 @@ void Texture1D::apply(State& state) const
|
||||
|
||||
applyTexParameters(GL_TEXTURE_1D,state);
|
||||
|
||||
// update the modified count to show that it is upto date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
applyTexImage1D(GL_TEXTURE_1D,_image.get(),state, _textureWidth, _numMipmapLevels);
|
||||
|
||||
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,1,1,0);
|
||||
|
||||
// update the modified count to show that it is up to date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
_textureObjectBuffer[contextID] = textureObject;
|
||||
|
||||
// unref image data?
|
||||
|
@ -202,12 +202,11 @@ void Texture2D::apply(State& state) const
|
||||
}
|
||||
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(),
|
||||
_textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
|
||||
|
||||
// update the modified tag to show that it is up to date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
applyTexImage2D_subload(state,GL_TEXTURE_2D,_image.get(),
|
||||
_textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
|
||||
}
|
||||
else if (_readPBuffer.valid())
|
||||
{
|
||||
@ -224,6 +223,8 @@ void Texture2D::apply(State& state) const
|
||||
|
||||
applyTexParameters(GL_TEXTURE_2D,state);
|
||||
|
||||
if (_image.valid()) getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
_subloadCallback->load(*this,state);
|
||||
|
||||
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,1,_borderWidth);
|
||||
@ -235,7 +236,6 @@ void Texture2D::apply(State& state) const
|
||||
//glBindTexture( GL_TEXTURE_2D, handle );
|
||||
|
||||
// update the modified tag to show that it is up to date.
|
||||
if (_image.valid()) getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
}
|
||||
else if (_image.valid() && _image->data())
|
||||
{
|
||||
@ -255,6 +255,9 @@ void Texture2D::apply(State& state) const
|
||||
|
||||
applyTexParameters(GL_TEXTURE_2D,state);
|
||||
|
||||
// update the modified tag to show that it is up to date.
|
||||
getModifiedCount(contextID) = image->getModifiedCount();
|
||||
|
||||
if (textureObject->isAllocated() && image->supportsTextureSubloading())
|
||||
{
|
||||
//OSG_NOTICE<<"Reusing texture object"<<std::endl;
|
||||
@ -270,9 +273,6 @@ void Texture2D::apply(State& state) const
|
||||
textureObject->setAllocated(true);
|
||||
}
|
||||
|
||||
// update the modified tag to show that it is up to date.
|
||||
getModifiedCount(contextID) = image->getModifiedCount();
|
||||
|
||||
// unref image data?
|
||||
if (isSafeToUnrefImageData(state) && image->getDataVariance()==STATIC)
|
||||
{
|
||||
|
@ -297,8 +297,8 @@ void Texture2DArray::apply(State& state) const
|
||||
{
|
||||
if (getModifiedCount(n,contextID) != image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
|
||||
getModifiedCount(n,contextID) = image->getModifiedCount();
|
||||
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
|
||||
}
|
||||
n += image->r();
|
||||
}
|
||||
@ -380,8 +380,8 @@ void Texture2DArray::apply(State& state) const
|
||||
{
|
||||
if (getModifiedCount(n,contextID) != image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
|
||||
getModifiedCount(n,contextID) = image->getModifiedCount();
|
||||
applyTexImage2DArray_subload(state, image, n, _textureWidth, _textureHeight, image->r(), _internalFormat, _numMipmapLevels);
|
||||
}
|
||||
n += image->r();
|
||||
}
|
||||
|
@ -249,12 +249,12 @@ void Texture3D::apply(State& state) const
|
||||
}
|
||||
else if (_image.get() && getModifiedCount(contextID) != _image->getModifiedCount())
|
||||
{
|
||||
// update the modified count to show that it is up to date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
computeRequiredTextureDimensions(state,*_image,_textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
|
||||
|
||||
applyTexImage3D(GL_TEXTURE_3D,_image.get(),state, _textureWidth, _textureHeight, _textureDepth,_numMipmapLevels);
|
||||
|
||||
// update the modified count to show that it is up to date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
}
|
||||
|
||||
}
|
||||
@ -291,6 +291,8 @@ void Texture3D::apply(State& state) const
|
||||
|
||||
textureObject->bind();
|
||||
|
||||
// update the modified count to show that it is up to date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
applyTexParameters(GL_TEXTURE_3D,state);
|
||||
|
||||
@ -298,9 +300,6 @@ void Texture3D::apply(State& state) const
|
||||
|
||||
textureObject->setAllocated(_numMipmapLevels,_internalFormat,_textureWidth,_textureHeight,_textureDepth,0);
|
||||
|
||||
// update the modified count to show that it is up to date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
// unref image data?
|
||||
if (isSafeToUnrefImageData(state) && _image->getDataVariance()==STATIC)
|
||||
{
|
||||
|
@ -163,6 +163,8 @@ void TextureBuffer::apply(State& state) const
|
||||
const GLExtensions* extensions = state.get<GLExtensions>();
|
||||
if(_bufferData.valid() &&_modifiedCount[contextID]!=_bufferData->getModifiedCount() )
|
||||
{
|
||||
_modifiedCount[contextID]=_bufferData->getModifiedCount() ;
|
||||
|
||||
GLBufferObject* glBufferObject = _bufferData->getBufferObject()->getOrCreateGLBufferObject(contextID);
|
||||
if (glBufferObject)
|
||||
{
|
||||
@ -174,7 +176,6 @@ void TextureBuffer::apply(State& state) const
|
||||
|
||||
}
|
||||
|
||||
_modifiedCount[contextID]=_bufferData->getModifiedCount() ;
|
||||
}
|
||||
textureObject->bind();
|
||||
|
||||
@ -198,6 +199,8 @@ void TextureBuffer::apply(State& state) const
|
||||
{
|
||||
const GLExtensions* extensions = state.get<GLExtensions>();
|
||||
|
||||
_modifiedCount[contextID] = _bufferData->getModifiedCount();
|
||||
|
||||
textureObject = generateAndAssignTextureObject(contextID, GL_TEXTURE_BUFFER);
|
||||
textureObject->_profile._internalFormat=_internalFormat;
|
||||
textureObject->bind();
|
||||
@ -221,7 +224,6 @@ void TextureBuffer::apply(State& state) const
|
||||
|
||||
textureObject->bind();
|
||||
extensions->glTexBuffer(GL_TEXTURE_BUFFER, _internalFormat, glBufferObject->getGLObjectID());
|
||||
_modifiedCount[contextID] = _bufferData->getModifiedCount();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -246,8 +246,8 @@ void TextureCubeMap::apply(State& state) const
|
||||
const osg::Image* image = _images[n].get();
|
||||
if (image && getModifiedCount((Face)n,contextID) != image->getModifiedCount())
|
||||
{
|
||||
applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
|
||||
getModifiedCount((Face)n,contextID) = image->getModifiedCount();
|
||||
applyTexImage2D_subload( state, faceTarget[n], _images[n].get(), _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -297,6 +297,7 @@ void TextureCubeMap::apply(State& state) const
|
||||
const osg::Image* image = _images[n].get();
|
||||
if (image)
|
||||
{
|
||||
getModifiedCount((Face)n,contextID) = image->getModifiedCount();
|
||||
if (textureObject->isAllocated())
|
||||
{
|
||||
applyTexImage2D_subload( state, faceTarget[n], image, _textureWidth, _textureHeight, _internalFormat, _numMipmapLevels);
|
||||
@ -305,7 +306,6 @@ void TextureCubeMap::apply(State& state) const
|
||||
{
|
||||
applyTexImage2D_load( state, faceTarget[n], image, _textureWidth, _textureHeight, _numMipmapLevels);
|
||||
}
|
||||
getModifiedCount((Face)n,contextID) = image->getModifiedCount();
|
||||
}
|
||||
|
||||
|
||||
|
@ -204,10 +204,10 @@ void TextureRectangle::apply(State& state) const
|
||||
}
|
||||
else if (_image.valid() && getModifiedCount(contextID) != _image->getModifiedCount())
|
||||
{
|
||||
applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat);
|
||||
|
||||
// update the modified count to show that it is up to date.
|
||||
getModifiedCount(contextID) = _image->getModifiedCount();
|
||||
|
||||
applyTexImage_subload(GL_TEXTURE_RECTANGLE, _image.get(), state, _textureWidth, _textureHeight, _internalFormat);
|
||||
}
|
||||
}
|
||||
else if (_subloadCallback.valid())
|
||||
|
@ -118,6 +118,8 @@ struct VertexArrayDispatch : public VertexArrayState::ArrayDispatch
|
||||
{
|
||||
VertexArrayDispatch() {}
|
||||
|
||||
virtual const char* className() const { return "VertexArrayDispatch"; }
|
||||
|
||||
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
|
||||
{
|
||||
VAS_NOTICE<<" VertexArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
||||
@ -171,6 +173,8 @@ struct ColorArrayDispatch : public VertexArrayState::ArrayDispatch
|
||||
{
|
||||
ColorArrayDispatch() {}
|
||||
|
||||
virtual const char* className() const { return "ColorArrayDispatch"; }
|
||||
|
||||
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
|
||||
{
|
||||
VAS_NOTICE<<" ColorArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
||||
@ -225,6 +229,8 @@ struct NormalArrayDispatch : public VertexArrayState::ArrayDispatch
|
||||
{
|
||||
NormalArrayDispatch() {}
|
||||
|
||||
virtual const char* className() const { return "NormalArrayDispatch"; }
|
||||
|
||||
virtual void enable_and_dispatch(osg::State&, const osg::Array* new_array)
|
||||
{
|
||||
VAS_NOTICE<<" NormalArrayDispatch::enable_and_dispatch("<<new_array->getNumElements()<<")"<<std::endl;
|
||||
@ -286,6 +292,8 @@ struct SecondaryColorArrayDispatch : public VertexArrayState::ArrayDispatch
|
||||
{
|
||||
SecondaryColorArrayDispatch() {}
|
||||
|
||||
virtual const char* className() const { return "SecondaryColorArrayDispatch"; }
|
||||
|
||||
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
|
||||
{
|
||||
glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
|
||||
@ -331,6 +339,8 @@ struct FogCoordArrayDispatch : public VertexArrayState::ArrayDispatch
|
||||
{
|
||||
FogCoordArrayDispatch() {}
|
||||
|
||||
virtual const char* className() const { return "FogCoordArrayDispatch"; }
|
||||
|
||||
virtual void enable_and_dispatch(osg::State& state, const osg::Array* new_array)
|
||||
{
|
||||
glEnableClientState(GL_FOG_COORDINATE_ARRAY);
|
||||
@ -367,6 +377,8 @@ struct TexCoordArrayDispatch : public VertexArrayState::ArrayDispatch
|
||||
{
|
||||
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)
|
||||
{
|
||||
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) {}
|
||||
|
||||
virtual const char* className() const { return "VertexAttribArrayDispatch"; }
|
||||
|
||||
inline void callVertexAttribPointer(GLExtensions* ext, const osg::Array* new_array, const GLvoid * ptr)
|
||||
{
|
||||
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)
|
||||
lazyDisablingOfVertexAttributes();
|
||||
applyDisablingOfVertexAttributes(state);
|
||||
unbindVertexBufferObject();
|
||||
|
||||
//lazyDisablingOfVertexAttributes();
|
||||
//applyDisablingOfVertexAttributes(state);
|
||||
|
||||
glInterleavedArrays( format, stride, pointer);
|
||||
#else
|
||||
|
@ -166,11 +166,28 @@ struct DXT1TexelsBlock
|
||||
unsigned short color_1; // extreme
|
||||
unsigned int texels4x4; // interpolated colors (2 bits per texel)
|
||||
};
|
||||
|
||||
bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void * imageData)
|
||||
struct DXT3TexelsBlock
|
||||
{
|
||||
// OSG_NOTICE<<"CompressedImageTranslucent("<<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)
|
||||
{
|
||||
case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT):
|
||||
@ -182,9 +199,8 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void
|
||||
|
||||
// Only do the check on the first mipmap level, and stop when we
|
||||
// see the first alpha texel
|
||||
int i = (width*height)/16;
|
||||
bool foundAlpha = false;
|
||||
while ((!foundAlpha) && (i>0))
|
||||
int i = blockCount;
|
||||
while (i>0)
|
||||
{
|
||||
// See if this block might contain transparent texels
|
||||
if (texelsBlock->color_0<=texelsBlock->color_1)
|
||||
@ -192,7 +208,7 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void
|
||||
// Scan the texels block for the '11' bit pattern that
|
||||
// indicates a transparent texel
|
||||
int j = 0;
|
||||
while ((!foundAlpha) && (j < 32))
|
||||
while (j < 32)
|
||||
{
|
||||
// Check for the '11' bit pattern on this texel
|
||||
if ( ((texelsBlock->texels4x4 >> j) & 0x03) == 0x03)
|
||||
@ -214,11 +230,67 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void
|
||||
}
|
||||
|
||||
case(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT):
|
||||
return true;
|
||||
|
||||
{
|
||||
const DXT3TexelsBlock *texelsBlock = reinterpret_cast<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):
|
||||
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:
|
||||
break;
|
||||
}
|
||||
@ -226,4 +298,361 @@ bool CompressedImageTranslucent(size_t width, size_t height, GLenum format, void
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned short interpolateColors21(unsigned short color1, unsigned short color2) {
|
||||
unsigned short result = (((color1 >> 11) * 2 + (color2 >> 11) + 1) / 3) << 11;
|
||||
result += (((color1 >> 5 & 0x3F) * 2 + (color2 >> 5 & 0x3F) + 1) / 3) << 5;
|
||||
result += (((color1 & 0x1F) * 2 + (color2 & 0x1F) + 1) / 3);
|
||||
return result;
|
||||
}
|
||||
unsigned short interpolateColors11(unsigned short color1, unsigned short color2) {
|
||||
unsigned short result = (((color1 >> 11) + (color2 >> 11) ) / 2) << 11;
|
||||
result += (((color1 >> 5 & 0x3F) + (color2 >> 5 & 0x3F)) / 2) << 5;
|
||||
result += (((color1 & 0x1F) + (color2 & 0x1F) ) / 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CompressedImageGetColor(unsigned char color[4], unsigned int s, unsigned int t, unsigned int r, int width, int height, int depth, GLenum format, unsigned char *imageData)
|
||||
{
|
||||
unsigned short color16 = 0;//RGB 5:6:5 format
|
||||
|
||||
|
||||
unsigned int slab4Count = (depth & ~0x3); //4*floor(d/4)
|
||||
unsigned int col = (s >> 2);//(floor(x/4)
|
||||
unsigned int row = (t >> 2);//(floor(y/4)
|
||||
unsigned int blockWidth = (width + 3) >> 2;//ceil(w/4)
|
||||
unsigned int blockHeight = (height + 3) >> 2;//ceil(h/4)
|
||||
int blockNumber = col + blockWidth * row ; // block to jump to
|
||||
|
||||
if (depth > 1) {
|
||||
// https://www.opengl.org/registry/specs/NV/texture_compression_vtc.txt
|
||||
// if (z >= 4*floor(d/4)) {
|
||||
// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * (z-4*floor(d/4)) ));
|
||||
// } else {
|
||||
// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4)));
|
||||
// }
|
||||
// note floor(a/4) = (a >> 2)
|
||||
// note 4*floor(a/4) = a & ~0x3
|
||||
// note ceil(a/4) = ((a + 3) >> 2)
|
||||
//
|
||||
// rewrite: this describes the final blocks as consecutive 4x4x1 blocks - and thats not in the wording of the specs
|
||||
// if (r >= slab4Count) {
|
||||
// blockNumber = (blockWidth * blockHeight * slab4Count + col + blockWidth * (row + blockHeight * (r-slab4Count) ));
|
||||
// } else {
|
||||
// blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) );
|
||||
// }
|
||||
|
||||
// or in the version of the openGL specs:
|
||||
// if (z >= 4*floor(d/4)) {
|
||||
// blockIndex = blocksize * (ceil(w/4) * ceil(h/4) * 4*floor(d/4) + (z - 4*floor(d/4)) * ( (floor(x/4) + ceil(w/4) * (floor(y/4) );
|
||||
// } else {
|
||||
// blockIndex = blocksize * 4 * (floor(x/4) + ceil(w/4) * (floor(y/4) + ceil(h/4) * floor(z/4)));
|
||||
// }
|
||||
|
||||
unsigned int sub_r = r & 0x3;//(r-slab4Count)
|
||||
if (r >= slab4Count) { //slice number beyond 4x4x4 slabs
|
||||
unsigned int blockDepth = depth & 0x3;// equals: depth - slab4Count;//depth of this final block: 1/2/3 in case of 4x4x1; 4x4x2 or 4x4x3 bricks
|
||||
blockNumber = (blockWidth * blockHeight * slab4Count //jump full 4x4x4 slabs
|
||||
+ blockDepth * ( col + blockWidth * row )
|
||||
+ sub_r);
|
||||
} else {
|
||||
blockNumber = 4 * (col + blockWidth * (row + blockHeight * (r >> 2)) ) + sub_r;
|
||||
}
|
||||
}
|
||||
|
||||
int sub_s = s & 0x3;
|
||||
int sub_t = t & 0x3;
|
||||
switch (format)
|
||||
{
|
||||
case(GL_COMPRESSED_RGB_S3TC_DXT1_EXT) :
|
||||
case(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) :
|
||||
{
|
||||
const DXT1TexelsBlock *texelsBlock = reinterpret_cast<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
|
||||
|
@ -42,6 +42,7 @@
|
||||
|
||||
#include <osg/GL>
|
||||
#include <osg/Texture>
|
||||
#include <osg/Vec3i>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
@ -78,9 +79,18 @@ bool isDXTC(GLenum pixelFormat);
|
||||
|
||||
bool VerticalFlip(size_t Width, size_t Height, GLenum Format, void * pPixels);
|
||||
|
||||
bool CompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels);
|
||||
bool isCompressedImageTranslucent(size_t Width, size_t Height, GLenum Format, void * pPixels);
|
||||
|
||||
//interpolate RGB565 colors with 2/3 part color1 and 1/3 part color2
|
||||
unsigned short interpolateColors21(unsigned short color1, unsigned short color2);
|
||||
//interpolate RGB565 colors with equal weights
|
||||
unsigned short interpolateColors11(unsigned short color1, unsigned short color2);
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -16,21 +16,14 @@
|
||||
|
||||
using namespace osgDB;
|
||||
|
||||
static long long prev_tellg = 0;
|
||||
|
||||
void InputIterator::checkStream() const
|
||||
{
|
||||
if (_in->rdstate()&_in->failbit)
|
||||
{
|
||||
OSG_NOTICE<<"InputIterator::checkStream() : _in->rdstate() "<<_in->rdstate()<<", "<<_in->failbit<<std::endl;
|
||||
OSG_NOTICE<<" _in->tellg() = "<<_in->tellg()<<std::endl;
|
||||
OSG_NOTICE<<" prev_tellg = "<<prev_tellg<<std::endl;
|
||||
_failed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev_tellg = _in->tellg();
|
||||
}
|
||||
}
|
||||
|
||||
void InputIterator::readComponentArray( char* s, unsigned int numElements, unsigned int numComponentsPerElements, unsigned int componentSizeInBytes)
|
||||
|
@ -278,19 +278,6 @@ void FreeTypeFont::setFontResolution(const osgText::FontResolution& fontSize)
|
||||
|
||||
int width = fontSize.first;
|
||||
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 */
|
||||
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);
|
||||
|
||||
glyph->setFontResolution(fontRes);
|
||||
|
||||
unsigned int dataSize = width*height;
|
||||
unsigned char* data = new unsigned char[dataSize];
|
||||
|
||||
@ -359,14 +348,12 @@ osgText::Glyph* FreeTypeFont::getGlyph(const osgText::FontResolution& fontRes, u
|
||||
for(unsigned char* p=data;p<data+dataSize;) { *p++ = 0; }
|
||||
|
||||
glyph->setImage(width,height,1,
|
||||
OSGTEXT_GLYPH_INTERNALFORMAT,
|
||||
OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE,
|
||||
GL_ALPHA,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE,
|
||||
data,
|
||||
osg::Image::USE_NEW_DELETE,
|
||||
1);
|
||||
|
||||
glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT);
|
||||
|
||||
// copy image across to osgText::Glyph image.
|
||||
switch(glyphslot->bitmap.pixel_mode)
|
||||
{
|
||||
|
@ -90,7 +90,7 @@ void Text::write(DataOutputStream* out){
|
||||
out->writeFloat(getBackdropVerticalOffset());
|
||||
|
||||
out->writeVec4(getBackdropColor());
|
||||
out->writeUInt(getBackdropImplementation());
|
||||
out->writeUInt(4); // old DELAYED_DEPTH_WRITES
|
||||
|
||||
out->writeUInt(getColorGradientMode());
|
||||
out->writeVec4(getColorGradientTopLeft());
|
||||
@ -213,7 +213,7 @@ void Text::read(DataInputStream* in){
|
||||
setBackdropOffset(horizontalOffset,verticalOffset);
|
||||
|
||||
setBackdropColor(in->readVec4());
|
||||
setBackdropImplementation((osgText::Text::BackdropImplementation) in->readUInt());
|
||||
in->readUInt(); // read old BackdropImplementation value, no longer used
|
||||
setColorGradientMode((osgText::Text::ColorGradientMode) in->readUInt());
|
||||
|
||||
osg::Vec4 colorGradientTopLeft,colorGradientBottomLeft,colorGradientBottomRight,colorGradientTopRight;
|
||||
|
@ -546,26 +546,26 @@ void OBJWriterNodeVisitor::processGeometry(osg::Geometry* geo, osg::Matrix& m) {
|
||||
|
||||
}
|
||||
|
||||
void OBJWriterNodeVisitor::apply(osg::Geometry& geometry)
|
||||
{
|
||||
osg::Matrix m = osg::computeLocalToWorld(getNodePath());
|
||||
|
||||
pushStateSet(geometry.getStateSet());
|
||||
|
||||
processGeometry(&geometry,m);
|
||||
|
||||
popStateSet(geometry.getStateSet());
|
||||
}
|
||||
|
||||
void OBJWriterNodeVisitor::apply( osg::Geode &node )
|
||||
{
|
||||
|
||||
pushStateSet(node.getStateSet());
|
||||
_nameStack.push_back(node.getName());
|
||||
osg::Matrix m = osg::computeLocalToWorld(getNodePath());
|
||||
unsigned int count = node.getNumDrawables();
|
||||
for ( unsigned int i = 0; i < count; i++ )
|
||||
{
|
||||
osg::Geometry *g = node.getDrawable( i )->asGeometry();
|
||||
if ( g != NULL )
|
||||
{
|
||||
pushStateSet(g->getStateSet());
|
||||
|
||||
processGeometry(g,m);
|
||||
|
||||
popStateSet(g->getStateSet());
|
||||
node.getDrawable( i )->accept(*this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
popStateSet(node.getStateSet());
|
||||
_nameStack.pop_back();
|
||||
|
@ -65,6 +65,7 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void apply(osg::Geometry & geometry);
|
||||
virtual void apply(osg::Geode & node);
|
||||
|
||||
virtual void apply(osg::Group & node)
|
||||
@ -78,14 +79,6 @@ class OBJWriterNodeVisitor: public osg::NodeVisitor {
|
||||
traverse( node );
|
||||
|
||||
_nameStack.pop_back();
|
||||
popStateSet(node.getStateSet());
|
||||
}
|
||||
|
||||
void traverse (osg::Node &node)
|
||||
{
|
||||
pushStateSet(node.getStateSet());
|
||||
|
||||
osg::NodeVisitor::traverse( node );
|
||||
|
||||
popStateSet(node.getStateSet());
|
||||
}
|
||||
|
@ -142,7 +142,8 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
struct ObjOptionsStruct {
|
||||
class ObjOptionsStruct {
|
||||
public:
|
||||
bool rotate;
|
||||
bool noTesselateLargePolygons;
|
||||
bool noTriStripPolygons;
|
||||
@ -155,6 +156,17 @@ protected:
|
||||
TextureAllocationMap textureUnitAllocation;
|
||||
/// Coordinates precision.
|
||||
int precision;
|
||||
|
||||
ObjOptionsStruct()
|
||||
{
|
||||
rotate = true;
|
||||
noTesselateLargePolygons = false;
|
||||
noTriStripPolygons = false;
|
||||
generateFacetNormals = false;
|
||||
fixBlackMaterials = true;
|
||||
noReverseFaces = false;
|
||||
precision = std::numeric_limits<double>::digits10 + 2;
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -546,7 +546,7 @@ osg::Node* VertexData::readPlyFile( const char* filename, const bool ignoreColor
|
||||
}
|
||||
else if (_texcoord.valid())
|
||||
{
|
||||
geom->setTexCoordArray(0, _texcoord);
|
||||
geom->setTexCoordArray(0, _texcoord.get());
|
||||
}
|
||||
|
||||
// If the model has normals, add them to the geometry
|
||||
|
@ -307,6 +307,18 @@ class ReaderWriterPNG : public osgDB::ReaderWriter
|
||||
pixelFormat = GL_RGBA;
|
||||
|
||||
int internalFormat = pixelFormat;
|
||||
if (depth > 8)
|
||||
{
|
||||
switch(color)
|
||||
{
|
||||
case(GL_LUMINANCE): internalFormat = GL_LUMINANCE16; break;
|
||||
case(GL_ALPHA): internalFormat = GL_ALPHA16; break;
|
||||
case(GL_LUMINANCE_ALPHA): internalFormat = GL_LUMINANCE16_ALPHA16; break;
|
||||
case(GL_RGB): internalFormat = GL_RGB16; break;
|
||||
case(GL_RGBA): internalFormat = GL_RGBA16; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
png_destroy_read_struct(&png, &info, &endinfo);
|
||||
|
||||
|
@ -398,18 +398,27 @@ class ReaderWriterVNC : public osgDB::ReaderWriter
|
||||
options->getAuthenticationMap() :
|
||||
osgDB::Registry::instance()->getAuthenticationMap();
|
||||
|
||||
const osgDB::AuthenticationDetails* details = authenticationMap ?
|
||||
authenticationMap->getAuthenticationDetails(hostname) :
|
||||
0;
|
||||
if (authenticationMap != NULL)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
// configure authentication if required.
|
||||
if (details)
|
||||
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())
|
||||
{
|
||||
|
@ -554,7 +554,10 @@ osg::ref_ptr<osg::Program> GeometryPool::getOrCreateProgram(LayerTypes& layerTyp
|
||||
_programMap[layerTypes] = program;
|
||||
|
||||
// add shader that provides the lighting functions
|
||||
program->addShader(osgDB::readRefShaderFile("shaders/lighting.vert"));
|
||||
{
|
||||
#include "shaders/lighting_vert.cpp"
|
||||
program->addShader(osgDB::readRefShaderFileWithFallback(osg::Shader::VERTEX, "shaders/lighting.vert", lighting_vert));
|
||||
}
|
||||
|
||||
// OSG_NOTICE<<") creating new Program "<<program.get()<<std::endl;
|
||||
{
|
||||
|
25
src/osgTerrain/shaders/lighting_vert.cpp
Normal file
25
src/osgTerrain/shaders/lighting_vert.cpp
Normal 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";
|
@ -125,5 +125,5 @@ char terrain_displacement_mapping_vert[] = "#version 120\n"
|
||||
" vec3 position = gl_Vertex.xyz + gl_Normal.xyz * height_center;\n"
|
||||
" gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n"
|
||||
"\n"
|
||||
"};\n"
|
||||
"}\n"
|
||||
"\n";
|
||||
|
@ -24,8 +24,11 @@ using namespace osgText;
|
||||
|
||||
DefaultFont::DefaultFont()
|
||||
{
|
||||
_fontSize = FontResolution(8,12);
|
||||
|
||||
_minFilterHint = osg::Texture::LINEAR_MIPMAP_LINEAR;
|
||||
_magFilterHint = osg::Texture::NEAREST;
|
||||
_magFilterHint = osg::Texture::LINEAR;
|
||||
|
||||
constructGlyphs();
|
||||
}
|
||||
|
||||
@ -198,14 +201,12 @@ void DefaultFont::constructGlyphs()
|
||||
for(unsigned char* p=data;p<data+dataSize;) { *p++ = 0; }
|
||||
|
||||
glyph->setImage(sourceWidth,sourceHeight,1,
|
||||
OSGTEXT_GLYPH_INTERNALFORMAT,
|
||||
OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE,
|
||||
GL_ALPHA,
|
||||
GL_ALPHA, GL_UNSIGNED_BYTE,
|
||||
data,
|
||||
osg::Image::USE_NEW_DELETE,
|
||||
1);
|
||||
|
||||
glyph->setInternalTextureFormat(OSGTEXT_GLYPH_INTERNALFORMAT);
|
||||
|
||||
// now populate data array by converting bitmap into a luminance_alpha map.
|
||||
unsigned char* ptr = rasters[i-32];
|
||||
unsigned char value_on = 255;
|
||||
@ -233,6 +234,8 @@ void DefaultFont::constructGlyphs()
|
||||
glyph->setVerticalBearing(osg::Vec2(0.5f,1.0f)); // top middle.
|
||||
glyph->setVerticalAdvance(sourceHeight*coord_scale);
|
||||
|
||||
glyph->setFontResolution(fontRes);
|
||||
|
||||
addGlyph(fontRes,i,glyph.get());
|
||||
}
|
||||
}
|
||||
|
@ -32,81 +32,6 @@
|
||||
using namespace osgText;
|
||||
using namespace std;
|
||||
|
||||
#if (!defined(OSG_GLES2_AVAILABLE) && !defined(OSG_GLES3_AVAILABLE))
|
||||
#define GLSL_VERSION_STR "330 core"
|
||||
#define GLYPH_CMP "r"
|
||||
#else
|
||||
#define GLSL_VERSION_STR "300 es"
|
||||
#define GLYPH_CMP "a"
|
||||
#endif
|
||||
|
||||
static const char* gl3_TextVertexShader = {
|
||||
"#version " GLSL_VERSION_STR "\n"
|
||||
"// gl3_TextVertexShader\n"
|
||||
"#ifdef GL_ES\n"
|
||||
" precision highp float;\n"
|
||||
"#endif\n"
|
||||
"in vec4 osg_Vertex;\n"
|
||||
"in vec4 osg_Color;\n"
|
||||
"in vec4 osg_MultiTexCoord0;\n"
|
||||
"uniform mat4 osg_ModelViewProjectionMatrix;\n"
|
||||
"out vec2 texCoord;\n"
|
||||
"out vec4 vertexColor;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = osg_ModelViewProjectionMatrix * osg_Vertex;\n"
|
||||
" texCoord = osg_MultiTexCoord0.xy;\n"
|
||||
" vertexColor = osg_Color; \n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
static const char* gl3_TextFragmentShader = {
|
||||
"#version " GLSL_VERSION_STR "\n"
|
||||
"// gl3_TextFragmentShader\n"
|
||||
"#ifdef GL_ES\n"
|
||||
" precision highp float;\n"
|
||||
"#endif\n"
|
||||
"uniform sampler2D glyphTexture;\n"
|
||||
"in vec2 texCoord;\n"
|
||||
"in vec4 vertexColor;\n"
|
||||
"out vec4 color;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" if (texCoord.x>=0.0) color = vertexColor * vec4(1.0, 1.0, 1.0, texture(glyphTexture, texCoord)." GLYPH_CMP ");\n"
|
||||
" else color = vertexColor;\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
static const char* gl2_TextVertexShader = {
|
||||
"// gl2_TextVertexShader\n"
|
||||
"#ifdef GL_ES\n"
|
||||
" precision highp float;\n"
|
||||
"#endif\n"
|
||||
"varying vec2 texCoord;\n"
|
||||
"varying vec4 vertexColor;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
|
||||
" texCoord = gl_MultiTexCoord0.xy;\n"
|
||||
" vertexColor = gl_Color; \n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
static const char* gl2_TextFragmentShader = {
|
||||
"// gl2_TextFragmentShader\n"
|
||||
"#ifdef GL_ES\n"
|
||||
" precision highp float;\n"
|
||||
"#endif\n"
|
||||
"uniform sampler2D glyphTexture;\n"
|
||||
"varying vec2 texCoord;\n"
|
||||
"varying vec4 vertexColor;\n"
|
||||
"void main(void)\n"
|
||||
"{\n"
|
||||
" if (texCoord.x>=0.0) gl_FragColor = vertexColor * vec4(1.0, 1.0, 1.0, texture2D(glyphTexture, texCoord).a);\n"
|
||||
" else gl_FragColor = vertexColor;\n"
|
||||
"}\n"
|
||||
};
|
||||
|
||||
osg::ref_ptr<Font>& Font::getDefaultFont()
|
||||
{
|
||||
static OpenThreads::Mutex s_DefaultFontMutex;
|
||||
@ -299,58 +224,16 @@ osg::ref_ptr<Font> osgText::readRefFontStream(std::istream& stream, const osgDB:
|
||||
|
||||
Font::Font(FontImplementation* implementation):
|
||||
osg::Object(true),
|
||||
_margin(1),
|
||||
_marginRatio(0.02),
|
||||
_textureWidthHint(1024),
|
||||
_textureHeightHint(1024),
|
||||
_minFilterHint(osg::Texture::LINEAR_MIPMAP_LINEAR),
|
||||
_magFilterHint(osg::Texture::LINEAR),
|
||||
_maxAnisotropy(16),
|
||||
_depth(1),
|
||||
_numCurveSamples(10)
|
||||
{
|
||||
setImplementation(implementation);
|
||||
|
||||
_texenv = new osg::TexEnv;
|
||||
_stateset = new osg::StateSet;
|
||||
|
||||
_stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
_stateset->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
_stateset->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
|
||||
#if defined(OSG_GL_FIXED_FUNCTION_AVAILABLE)
|
||||
|
||||
OSG_INFO<<"Font::Font() Fixed function pipeline"<<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;
|
||||
if ((ptr = getenv("OSG_MAX_TEXTURE_SIZE")) != 0)
|
||||
{
|
||||
@ -359,7 +242,6 @@ Font::Font(FontImplementation* implementation):
|
||||
if (osg_max_size<_textureWidthHint) _textureWidthHint = osg_max_size;
|
||||
if (osg_max_size<_textureHeightHint) _textureHeightHint = osg_max_size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Font::~Font()
|
||||
@ -390,26 +272,6 @@ std::string Font::getFileName() const
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void Font::setGlyphImageMargin(unsigned int margin)
|
||||
{
|
||||
_margin = margin;
|
||||
}
|
||||
|
||||
unsigned int Font::getGlyphImageMargin() const
|
||||
{
|
||||
return _margin;
|
||||
}
|
||||
|
||||
void Font::setGlyphImageMarginRatio(float ratio)
|
||||
{
|
||||
_marginRatio = ratio;
|
||||
}
|
||||
|
||||
float Font::getGlyphImageMarginRatio() const
|
||||
{
|
||||
return _marginRatio;
|
||||
}
|
||||
|
||||
void Font::setTextureSizeHint(unsigned int width,unsigned int height)
|
||||
{
|
||||
_textureWidthHint = width;
|
||||
@ -518,9 +380,6 @@ void Font::setThreadSafeRefUnref(bool threadSafe)
|
||||
{
|
||||
osg::Object::setThreadSafeRefUnref(threadSafe);
|
||||
|
||||
if (_texenv.valid()) _texenv->setThreadSafeRefUnref(threadSafe);
|
||||
if (_stateset.valid()) _stateset->setThreadSafeRefUnref(threadSafe);
|
||||
|
||||
for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin();
|
||||
itr!=_glyphTextureList.end();
|
||||
++itr)
|
||||
@ -531,7 +390,12 @@ void Font::setThreadSafeRefUnref(bool threadSafe)
|
||||
|
||||
void Font::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
if (_stateset.valid()) _stateset->resizeGLObjectBuffers(maxSize);
|
||||
for(StateSets::iterator itr = _statesets.begin();
|
||||
itr != _statesets.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
|
||||
for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin();
|
||||
itr!=_glyphTextureList.end();
|
||||
@ -543,7 +407,12 @@ void Font::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
|
||||
void Font::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
if (_stateset.valid()) _stateset->releaseGLObjects(state);
|
||||
for(StateSets::const_iterator itr = _statesets.begin();
|
||||
itr != _statesets.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->releaseGLObjects(state);
|
||||
}
|
||||
|
||||
for(GlyphTextureList::const_iterator itr=_glyphTextureList.begin();
|
||||
itr!=_glyphTextureList.end();
|
||||
@ -576,6 +445,10 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
|
||||
|
||||
_sizeGlyphMap[fontRes][charcode]=glyph;
|
||||
|
||||
}
|
||||
|
||||
void Font::assignGlyphToGlyphTexture(Glyph* glyph, ShaderTechnique shaderTechnique)
|
||||
{
|
||||
int posX=0,posY=0;
|
||||
|
||||
GlyphTexture* glyphTexture = 0;
|
||||
@ -583,12 +456,12 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
|
||||
itr!=_glyphTextureList.end() && !glyphTexture;
|
||||
++itr)
|
||||
{
|
||||
if ((*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get();
|
||||
if ((*itr)->getShaderTechnique()==shaderTechnique && (*itr)->getSpaceForGlyph(glyph,posX,posY)) glyphTexture = itr->get();
|
||||
}
|
||||
|
||||
if (glyphTexture)
|
||||
{
|
||||
//cout << " found space for texture "<<glyphTexture<<" posX="<<posX<<" posY="<<posY<<endl;
|
||||
//cout << " Font::assignGlyphToGlyphTexture() found space for texture "<<glyphTexture<<" posX="<<posX<<" posY="<<posY<<endl;
|
||||
}
|
||||
|
||||
if (!glyphTexture)
|
||||
@ -602,12 +475,11 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
|
||||
OSG_INFO<< " Font " << this<< ", numberOfTexturesAllocated "<<numberOfTexturesAllocated<<std::endl;
|
||||
|
||||
// reserve enough space for the glyphs.
|
||||
glyphTexture->setGlyphImageMargin(_margin);
|
||||
glyphTexture->setGlyphImageMarginRatio(_marginRatio);
|
||||
glyphTexture->setShaderTechnique(shaderTechnique);
|
||||
glyphTexture->setTextureSize(_textureWidthHint,_textureHeightHint);
|
||||
glyphTexture->setFilter(osg::Texture::MIN_FILTER,_minFilterHint);
|
||||
glyphTexture->setFilter(osg::Texture::MAG_FILTER,_magFilterHint);
|
||||
glyphTexture->setMaxAnisotropy(8);
|
||||
glyphTexture->setMaxAnisotropy(_maxAnisotropy);
|
||||
|
||||
_glyphTextureList.push_back(glyphTexture);
|
||||
|
||||
@ -621,5 +493,4 @@ void Font::addGlyph(const FontResolution& fontRes, unsigned int charcode, Glyph*
|
||||
|
||||
// add the glyph into the texture.
|
||||
glyphTexture->addGlyph(glyph,posX,posY);
|
||||
|
||||
}
|
||||
|
@ -28,9 +28,34 @@
|
||||
using namespace osgText;
|
||||
using namespace std;
|
||||
|
||||
// GL_ALPHA and GL_LUMINANCE_ALPHA are deprecated in GL3/GL4 core profile, use GL_RED & GL_RB in this case.
|
||||
#if defined(OSG_GL3_AVAILABLE) && !defined(OSG_GL2_AVAILABLE) && !defined(OSG_GL1_AVAILABLE)
|
||||
#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_RED
|
||||
#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_R8
|
||||
#define OSGTEXT_GLYPH_SDF_FORMAT GL_RG
|
||||
#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_RG8
|
||||
#else
|
||||
#define OSGTEXT_GLYPH_ALPHA_FORMAT GL_ALPHA
|
||||
#define OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT GL_ALPHA
|
||||
#define OSGTEXT_GLYPH_SDF_FORMAT GL_LUMINANCE_ALPHA
|
||||
#define OSGTEXT_GLYPH_SDF_INTERNALFORMAT GL_LUMINANCE_ALPHA
|
||||
#endif
|
||||
|
||||
|
||||
#if 0
|
||||
#define TEXTURE_IMAGE_NUM_CHANNELS 1
|
||||
#define TEXTURE_IMAGE_FORMAT OSGTEXT_GLYPH_FORMAT
|
||||
#else
|
||||
#define TEXTURE_IMAGE_NUM_CHANNELS 2
|
||||
#define TEXTURE_IMAGE_FORMAT GL_RGBA
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GlyphTexture
|
||||
//
|
||||
GlyphTexture::GlyphTexture():
|
||||
_margin(1),
|
||||
_marginRatio(0.02f),
|
||||
_usedY(0),
|
||||
_partUsedX(0),
|
||||
_partUsedY(0)
|
||||
@ -51,27 +76,52 @@ int GlyphTexture::compare(const osg::StateAttribute& rhs) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GlyphTexture::getEffectMargin(const Glyph* glyph)
|
||||
{
|
||||
if (_shaderTechnique==GREYSCALE) return 0;
|
||||
else return osg::maximum(glyph->getFontResolution().second/6, 2u);
|
||||
}
|
||||
|
||||
int GlyphTexture::getTexelMargin(const Glyph* glyph)
|
||||
{
|
||||
int width = glyph->s();
|
||||
int height = glyph->t();
|
||||
int effect_margin = getEffectMargin(glyph);
|
||||
|
||||
int max_dimension = osg::maximum(width, height) + 2 * effect_margin;
|
||||
int margin = osg::maximum(max_dimension/4, 2) + effect_margin;
|
||||
|
||||
return margin;
|
||||
}
|
||||
|
||||
bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
||||
{
|
||||
int maxAxis = osg::maximum(glyph->s(), glyph->t());
|
||||
int margin = _margin + (int)((float)maxAxis * _marginRatio);
|
||||
int width = glyph->s();
|
||||
int height = glyph->t();
|
||||
|
||||
int width = glyph->s()+2*margin;
|
||||
int height = glyph->t()+2*margin;
|
||||
int margin = getTexelMargin(glyph);
|
||||
|
||||
// first check box (_partUsedX,_usedY) to (width,height)
|
||||
if (width <= (getTextureWidth()-_partUsedX) &&
|
||||
height <= (getTextureHeight()-_usedY))
|
||||
width += 2*margin;
|
||||
height += 2*margin;
|
||||
|
||||
int interval = 4;
|
||||
|
||||
int partUsedX = ((_partUsedX % interval) == 0) ? _partUsedX : (((_partUsedX/interval)+1)*interval);
|
||||
int partUsedY = ((_partUsedY % interval) == 0) ? _partUsedY : (((_partUsedY/interval)+1)*interval);
|
||||
int usedY = ((_usedY % interval) == 0) ? _usedY : (((_usedY/interval)+1)*interval);
|
||||
|
||||
// first check box (partUsedX, usedY) to (width,height)
|
||||
if (width <= (getTextureWidth()-partUsedX) &&
|
||||
height <= (getTextureHeight()-usedY))
|
||||
{
|
||||
// can fit in existing row.
|
||||
|
||||
// record the position in which the texture will be stored.
|
||||
posX = _partUsedX+margin;
|
||||
posY = _usedY+margin;
|
||||
posX = partUsedX+margin;
|
||||
posY = usedY+margin;
|
||||
|
||||
// move used markers on.
|
||||
_partUsedX += width;
|
||||
_partUsedX = posX+width;
|
||||
if (_usedY+height>_partUsedY) _partUsedY = _usedY+height;
|
||||
|
||||
return true;
|
||||
@ -83,14 +133,14 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
||||
{
|
||||
// can fit next row.
|
||||
_partUsedX = 0;
|
||||
_usedY = _partUsedY;
|
||||
_usedY = partUsedY;
|
||||
|
||||
posX = _partUsedX+margin;
|
||||
posY = _usedY+margin;
|
||||
|
||||
// move used markers on.
|
||||
_partUsedX += width;
|
||||
if (_usedY+height>_partUsedY) _partUsedY = _usedY+height;
|
||||
_partUsedX = posX+width;
|
||||
_partUsedY = _usedY+height;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -101,23 +151,237 @@ bool GlyphTexture::getSpaceForGlyph(Glyph* glyph, int& posX, int& posY)
|
||||
|
||||
void GlyphTexture::addGlyph(Glyph* glyph, int posX, int posY)
|
||||
{
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
|
||||
if (!_image.valid()) createImage();
|
||||
|
||||
_glyphs.push_back(glyph);
|
||||
|
||||
// set up the details of where to place glyph's image in the texture.
|
||||
glyph->setTexture(this);
|
||||
glyph->setTexturePosition(posX,posY);
|
||||
osg::ref_ptr<Glyph::TextureInfo> info = new Glyph::TextureInfo(
|
||||
this,
|
||||
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()),
|
||||
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()) ) );
|
||||
glyph->setTextureInfo(_shaderTechnique, info.get());
|
||||
|
||||
_image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph);
|
||||
copyGlyphImage(glyph, info);
|
||||
}
|
||||
|
||||
void GlyphTexture::copyGlyphImage(Glyph* glyph, Glyph::TextureInfo* info)
|
||||
{
|
||||
_image->dirty();
|
||||
|
||||
if (_shaderTechnique<=GREYSCALE)
|
||||
{
|
||||
// OSG_NOTICE<<"GlyphTexture::copyGlyphImage() greyscale copying. glyphTexture="<<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)
|
||||
@ -147,22 +411,26 @@ osg::Image* GlyphTexture::createImage()
|
||||
{
|
||||
if (!_image)
|
||||
{
|
||||
_image = new osg::Image;
|
||||
_image->allocateImage(getTextureWidth(), getTextureHeight(), 1, OSGTEXT_GLYPH_FORMAT, GL_UNSIGNED_BYTE);
|
||||
memset(_image->data(), 0, _image->getTotalSizeInBytes());
|
||||
OSG_INFO<<"GlyphTexture::createImage() : Creating image 0x"<<std::hex<<TEXTURE_IMAGE_FORMAT<<std::dec<<std::endl;
|
||||
|
||||
for(GlyphRefList::iterator itr = _glyphs.begin();
|
||||
itr != _glyphs.end();
|
||||
++itr)
|
||||
{
|
||||
Glyph* glyph = itr->get();
|
||||
_image->copySubImage(glyph->getTexturePositionX(), glyph->getTexturePositionY(), 0, glyph);
|
||||
}
|
||||
_image = new osg::Image;
|
||||
|
||||
GLenum imageFormat = (_shaderTechnique<=GREYSCALE) ? OSGTEXT_GLYPH_ALPHA_FORMAT : OSGTEXT_GLYPH_SDF_FORMAT;
|
||||
GLenum internalFormat = (_shaderTechnique<=GREYSCALE) ? OSGTEXT_GLYPH_ALPHA_INTERNALFORMAT : OSGTEXT_GLYPH_SDF_INTERNALFORMAT;
|
||||
|
||||
_image->allocateImage(getTextureWidth(), getTextureHeight(), 1, imageFormat, GL_UNSIGNED_BYTE);
|
||||
_image->setInternalTextureFormat(internalFormat);
|
||||
|
||||
memset(_image->data(), 0, _image->getTotalSizeInBytes());
|
||||
}
|
||||
|
||||
return _image.get();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Glyph
|
||||
//
|
||||
// all the methods in Font::Glyph have been made non inline because VisualStudio6.0 is STUPID, STUPID, STUPID PILE OF JUNK.
|
||||
Glyph::Glyph(Font* font, unsigned int glyphCode):
|
||||
_font(font),
|
||||
@ -172,12 +440,7 @@ Glyph::Glyph(Font* font, unsigned int glyphCode):
|
||||
_horizontalBearing(0.0f,0.f),
|
||||
_horizontalAdvance(0.f),
|
||||
_verticalBearing(0.0f,0.f),
|
||||
_verticalAdvance(0.f),
|
||||
_texture(0),
|
||||
_texturePosX(0),
|
||||
_texturePosY(0),
|
||||
_minTexCoord(0.0f,0.0f),
|
||||
_maxTexCoord(0.0f,0.0f)
|
||||
_verticalAdvance(0.f)
|
||||
{
|
||||
setThreadSafeRefUnref(true);
|
||||
}
|
||||
@ -198,67 +461,37 @@ const osg::Vec2& Glyph::getVerticalBearing() const { return _verticalBearing; }
|
||||
void Glyph::setVerticalAdvance(float advance) { _verticalAdvance=advance; }
|
||||
float Glyph::getVerticalAdvance() const { return _verticalAdvance; }
|
||||
|
||||
void Glyph::setTexture(GlyphTexture* texture) { _texture = texture; }
|
||||
GlyphTexture* Glyph::getTexture() { return _texture; }
|
||||
const GlyphTexture* Glyph::getTexture() const { return _texture; }
|
||||
|
||||
void Glyph::setTexturePosition(int posX,int posY) { _texturePosX = posX; _texturePosY = posY; }
|
||||
int Glyph::getTexturePositionX() const { return _texturePosX; }
|
||||
int Glyph::getTexturePositionY() const { return _texturePosY; }
|
||||
|
||||
void Glyph::setMinTexCoord(const osg::Vec2& coord) { _minTexCoord=coord; }
|
||||
const osg::Vec2& Glyph::getMinTexCoord() const { return _minTexCoord; }
|
||||
|
||||
void Glyph::setMaxTexCoord(const osg::Vec2& coord) { _maxTexCoord=coord; }
|
||||
const osg::Vec2& Glyph::getMaxTexCoord() const { return _maxTexCoord; }
|
||||
|
||||
void Glyph::subload() const
|
||||
void Glyph::setTextureInfo(ShaderTechnique technique, TextureInfo* info)
|
||||
{
|
||||
GLenum errorNo = glGetError();
|
||||
if (errorNo!=GL_NO_ERROR)
|
||||
if (technique>=_textureInfoList.size())
|
||||
{
|
||||
const GLubyte* msg = osg::gluErrorString(errorNo);
|
||||
if (msg) { OSG_WARN<<"before Glyph::subload(): detected OpenGL error: "<<msg<<std::endl; }
|
||||
else { OSG_WARN<<"before Glyph::subload(): detected OpenGL error number: "<<errorNo<<std::endl; }
|
||||
_textureInfoList.resize(technique+1);
|
||||
}
|
||||
_textureInfoList[technique] = info;
|
||||
}
|
||||
|
||||
if(s() <= 0 || t() <= 0)
|
||||
const Glyph::TextureInfo* Glyph::getTextureInfo(ShaderTechnique technique) const
|
||||
{
|
||||
OSG_INFO<<"Glyph::subload(): texture sub-image width and/or height of 0, ignoring operation."<<std::endl;
|
||||
return;
|
||||
return (technique<_textureInfoList.size()) ? _textureInfoList[technique].get() : 0;
|
||||
}
|
||||
|
||||
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)
|
||||
Glyph::TextureInfo* Glyph::getOrCreateTextureInfo(ShaderTechnique technique)
|
||||
{
|
||||
|
||||
|
||||
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;
|
||||
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):
|
||||
osg::Referenced(true),
|
||||
_font(font),
|
||||
|
@ -25,13 +25,19 @@
|
||||
|
||||
#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 osgText;
|
||||
|
||||
Text::Text():
|
||||
_shaderTechnique(GREYSCALE),
|
||||
_enableDepthWrites(true),
|
||||
_backdropType(NONE),
|
||||
_backdropImplementation(DELAYED_DEPTH_WRITES),
|
||||
_backdropHorizontalOffset(0.07f),
|
||||
_backdropVerticalOffset(0.07f),
|
||||
_backdropColor(0.0f, 0.0f, 0.0f, 1.0f),
|
||||
@ -42,13 +48,24 @@ Text::Text():
|
||||
_colorGradientTopRight(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
{
|
||||
_supportsVertexBufferObjects = true;
|
||||
|
||||
const std::string& str = osg::DisplaySettings::instance()->getTextShaderTechnique();
|
||||
if (!str.empty())
|
||||
{
|
||||
if (str=="ALL_FEATURES" || str=="ALL") _shaderTechnique = ALL_FEATURES;
|
||||
else if (str=="GREYSCALE") _shaderTechnique = GREYSCALE;
|
||||
else if (str=="SIGNED_DISTANCE_FIELD" || str=="SDF") _shaderTechnique = SIGNED_DISTANCE_FIELD;
|
||||
else if (str=="NO_TEXT_SHADER" || str=="NONE") _shaderTechnique = NO_TEXT_SHADER;
|
||||
}
|
||||
|
||||
assignStateSet();
|
||||
}
|
||||
|
||||
Text::Text(const Text& text,const osg::CopyOp& copyop):
|
||||
osgText::TextBase(text,copyop),
|
||||
_shaderTechnique(text._shaderTechnique),
|
||||
_enableDepthWrites(text._enableDepthWrites),
|
||||
_backdropType(text._backdropType),
|
||||
_backdropImplementation(text._backdropImplementation),
|
||||
_backdropHorizontalOffset(text._backdropHorizontalOffset),
|
||||
_backdropVerticalOffset(text._backdropVerticalOffset),
|
||||
_backdropColor(text._backdropColor),
|
||||
@ -65,21 +82,170 @@ Text::~Text()
|
||||
{
|
||||
}
|
||||
|
||||
void Text::setFont(osg::ref_ptr<Font> font)
|
||||
{
|
||||
if (_font==font) return;
|
||||
|
||||
osg::StateSet* previousFontStateSet = _font.valid() ? _font->getStateSet() : Font::getDefaultFont()->getStateSet();
|
||||
osg::StateSet* newFontStateSet = font.valid() ? font->getStateSet() : Font::getDefaultFont()->getStateSet();
|
||||
|
||||
if (getStateSet() == previousFontStateSet)
|
||||
void Text::setShaderTechnique(ShaderTechnique technique)
|
||||
{
|
||||
setStateSet( newFontStateSet );
|
||||
if (_shaderTechnique==technique) return;
|
||||
|
||||
_shaderTechnique = technique;
|
||||
|
||||
assignStateSet();
|
||||
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
TextBase::setFont(font);
|
||||
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()
|
||||
{
|
||||
@ -225,22 +391,20 @@ String::iterator Text::computeLastCharacterOnLine(osg::Vec2& cursor, String::ite
|
||||
void Text::addGlyphQuad(Glyph* glyph, const osg::Vec2& minc, const osg::Vec2& maxc, const osg::Vec2& mintc, const osg::Vec2& maxtc)
|
||||
{
|
||||
// set up the coords of the quad
|
||||
GlyphQuads& glyphquad = _textureGlyphQuadMap[glyph->getTexture()];
|
||||
const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique);
|
||||
GlyphTexture* glyphTexture = info ? info->texture : 0;
|
||||
GlyphQuads& glyphquad = _textureGlyphQuadMap[glyphTexture];
|
||||
|
||||
glyphquad._glyphs.push_back(glyph);
|
||||
|
||||
osg::DrawElements* primitives = 0;
|
||||
if (glyphquad._primitives.empty())
|
||||
osg::DrawElements* primitives = glyphquad._primitives.get();
|
||||
if (!primitives)
|
||||
{
|
||||
unsigned int maxIndices = _text.size()*4;
|
||||
if (maxIndices>=16384) primitives = new osg::DrawElementsUInt(GL_TRIANGLES);
|
||||
else primitives = new osg::DrawElementsUShort(GL_TRIANGLES);
|
||||
primitives->setBufferObject(_ebo.get());
|
||||
glyphquad._primitives.push_back(primitives);
|
||||
}
|
||||
else
|
||||
{
|
||||
primitives = glyphquad._primitives[0].get();
|
||||
glyphquad._primitives = primitives;
|
||||
}
|
||||
|
||||
|
||||
@ -280,25 +444,18 @@ void Text::computeGlyphRepresentation()
|
||||
if (!_texcoords) { _texcoords = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); _texcoords->setBufferObject(_vbo.get()); }
|
||||
else _texcoords->clear();
|
||||
|
||||
#if 0
|
||||
_textureGlyphQuadMap.clear();
|
||||
#else
|
||||
for(TextureGlyphQuadMap::iterator itr = _textureGlyphQuadMap.begin();
|
||||
itr != _textureGlyphQuadMap.end();
|
||||
++itr)
|
||||
{
|
||||
GlyphQuads& glyphquads = itr->second;
|
||||
glyphquads._glyphs.clear();
|
||||
for(Primitives::iterator pitr = glyphquads._primitives.begin();
|
||||
pitr != glyphquads._primitives.end();
|
||||
++pitr)
|
||||
if (glyphquads._primitives.valid())
|
||||
{
|
||||
(*pitr)->resizeElements(0);
|
||||
(*pitr)->dirty();
|
||||
glyphquads._primitives->resizeElements(0);
|
||||
glyphquads._primitives->dirty();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
_lineCount = 0;
|
||||
@ -487,15 +644,18 @@ void Text::computeGlyphRepresentation()
|
||||
local.x() += bearing.x() * wr;
|
||||
local.y() += bearing.y() * hr;
|
||||
|
||||
|
||||
const Glyph::TextureInfo* info = glyph->getOrCreateTextureInfo(_shaderTechnique);
|
||||
if (info)
|
||||
{
|
||||
// Adjust coordinates and texture coordinates to avoid
|
||||
// clipping the edges of antialiased characters.
|
||||
osg::Vec2 mintc = glyph->getMinTexCoord();
|
||||
osg::Vec2 maxtc = glyph->getMaxTexCoord();
|
||||
osg::Vec2 mintc = info->minTexCoord;
|
||||
osg::Vec2 maxtc = info->maxTexCoord;
|
||||
osg::Vec2 vDiff = maxtc - mintc;
|
||||
float texelMargin = info->texelMargin;
|
||||
|
||||
float fHorizTCMargin = 1.0f / glyph->getTexture()->getTextureWidth();
|
||||
float fVertTCMargin = 1.0f / glyph->getTexture()->getTextureHeight();
|
||||
float fHorizTCMargin = texelMargin / info->texture->getTextureWidth();
|
||||
float fVertTCMargin = texelMargin / info->texture->getTextureHeight();
|
||||
float fHorizQuadMargin = vDiff.x() == 0.0f ? 0.0f : width * fHorizTCMargin / vDiff.x();
|
||||
float fVertQuadMargin = vDiff.y() == 0.0f ? 0.0f : height * fVertTCMargin / vDiff.y();
|
||||
|
||||
@ -527,6 +687,11 @@ void Text::computeGlyphRepresentation()
|
||||
_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;
|
||||
}
|
||||
@ -622,153 +787,10 @@ void Text::computePositionsImplementation()
|
||||
{
|
||||
TextBase::computePositionsImplementation();
|
||||
|
||||
computeBackdropPositions();
|
||||
computeBackdropBoundingBox();
|
||||
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 assumes that the bounding box has already been computed for the text without the backdrop.
|
||||
void Text::computeBackdropBoundingBox()
|
||||
@ -1095,6 +1117,8 @@ void Text::drawImplementation(osg::RenderInfo& renderInfo) const
|
||||
|
||||
void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colorMultiplier) const
|
||||
{
|
||||
if (colorMultiplier.a()==0.0f || _color.a()==0.0f) return;
|
||||
|
||||
osg::VertexArrayState* vas = state.getCurrentVertexArrayState();
|
||||
bool usingVertexBufferObjects = state.useVertexBufferObject(_supportsVertexBufferObjects && _useVertexBufferObjects);
|
||||
bool usingVertexArrayObjects = usingVertexBufferObjects && state.useVertexArrayObject(_useVertexArrayObject);
|
||||
@ -1117,7 +1141,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo
|
||||
}
|
||||
|
||||
if (_drawMode & TEXT)
|
||||
// if (false)
|
||||
{
|
||||
for(TextureGlyphQuadMap::const_iterator titr=_textureGlyphQuadMap.begin();
|
||||
titr!=_textureGlyphQuadMap.end();
|
||||
@ -1128,33 +1151,6 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo
|
||||
|
||||
const GlyphQuads& glyphquad = titr->second;
|
||||
|
||||
#if 1
|
||||
if(_backdropType != NONE)
|
||||
{
|
||||
unsigned int backdrop_index;
|
||||
unsigned int max_backdrop_index;
|
||||
if(_backdropType == OUTLINE)
|
||||
{
|
||||
backdrop_index = 1;
|
||||
max_backdrop_index = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
backdrop_index = _backdropType+1;
|
||||
max_backdrop_index = backdrop_index+1;
|
||||
}
|
||||
|
||||
if (max_backdrop_index>glyphquad._primitives.size()) max_backdrop_index=glyphquad._primitives.size();
|
||||
|
||||
state.disableColorPointer();
|
||||
state.Color(_backdropColor.r(),_backdropColor.g(),_backdropColor.b(),_backdropColor.a());
|
||||
|
||||
for( ; backdrop_index < max_backdrop_index; backdrop_index++)
|
||||
{
|
||||
glyphquad._primitives[backdrop_index]->draw(state, usingVertexBufferObjects);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if(_colorGradientMode == SOLID)
|
||||
{
|
||||
vas->disableColorArray(state);
|
||||
@ -1168,7 +1164,7 @@ void Text::drawImplementationSinglePass(osg::State& state, const osg::Vec4& colo
|
||||
}
|
||||
}
|
||||
|
||||
glyphquad._primitives[0]->draw(state, usingVertexBufferObjects);
|
||||
glyphquad._primitives->draw(state, usingVertexBufferObjects);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1216,9 +1212,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie
|
||||
vas->applyDisablingOfVertexAttributes(state);
|
||||
}
|
||||
|
||||
#if 0
|
||||
drawImplementationSinglePass(state, colorMultiplier);
|
||||
#else
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
drawImplementationSinglePass(state, colorMultiplier);
|
||||
@ -1235,7 +1228,6 @@ void Text::drawImplementation(osg::State& state, const osg::Vec4& colorMultiplie
|
||||
}
|
||||
|
||||
state.haveAppliedAttribute(osg::StateAttribute::DEPTH);
|
||||
#endif
|
||||
|
||||
if (usingVertexBufferObjects && !usingVertexArrayObjects)
|
||||
{
|
||||
@ -1273,16 +1265,16 @@ void Text::accept(osg::PrimitiveFunctor& pf) const
|
||||
++titr)
|
||||
{
|
||||
const GlyphQuads& glyphquad = titr->second;
|
||||
if (!glyphquad._primitives.empty())
|
||||
if (glyphquad._primitives.valid())
|
||||
{
|
||||
const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast<const osg::DrawElementsUShort*>(glyphquad._primitives[0].get());
|
||||
const osg::DrawElementsUShort* drawElementsUShort = dynamic_cast<const osg::DrawElementsUShort*>(glyphquad._primitives.get());
|
||||
if (drawElementsUShort)
|
||||
{
|
||||
pf.drawElements(GL_TRIANGLES, drawElementsUShort->size(), &(drawElementsUShort->front()));
|
||||
}
|
||||
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)
|
||||
{
|
||||
pf.drawElements(GL_TRIANGLES, drawElementsUInt->size(), &(drawElementsUInt->front()));
|
||||
@ -1322,22 +1314,19 @@ void Text::setBackdropType(BackdropType type)
|
||||
if (_backdropType==type) return;
|
||||
|
||||
_backdropType = type;
|
||||
|
||||
assignStateSet();
|
||||
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
void Text::setBackdropImplementation(BackdropImplementation implementation)
|
||||
{
|
||||
if (_backdropImplementation==implementation) return;
|
||||
|
||||
_backdropImplementation = implementation;
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
|
||||
void Text::setBackdropOffset(float offset)
|
||||
{
|
||||
_backdropHorizontalOffset = offset;
|
||||
_backdropVerticalOffset = offset;
|
||||
|
||||
assignStateSet();
|
||||
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
@ -1345,12 +1334,17 @@ void Text::setBackdropOffset(float horizontal, float vertical)
|
||||
{
|
||||
_backdropHorizontalOffset = horizontal;
|
||||
_backdropVerticalOffset = vertical;
|
||||
|
||||
assignStateSet();
|
||||
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
void Text::setBackdropColor(const osg::Vec4& color)
|
||||
{
|
||||
_backdropColor = color;
|
||||
|
||||
assignStateSet();
|
||||
}
|
||||
|
||||
void Text::setColorGradientMode(ColorGradientMode mode)
|
||||
@ -1391,20 +1385,10 @@ Text::GlyphQuads::GlyphQuads(const GlyphQuads&)
|
||||
|
||||
void Text::GlyphQuads::resizeGLObjectBuffers(unsigned int maxSize)
|
||||
{
|
||||
for(Primitives::iterator itr = _primitives.begin();
|
||||
itr != _primitives.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
if (_primitives.valid()) _primitives->resizeGLObjectBuffers(maxSize);
|
||||
}
|
||||
|
||||
void Text::GlyphQuads::releaseGLObjects(osg::State* state) const
|
||||
{
|
||||
for(Primitives::const_iterator itr = _primitives.begin();
|
||||
itr != _primitives.end();
|
||||
++itr)
|
||||
{
|
||||
(*itr)->releaseGLObjects(state);
|
||||
}
|
||||
if (_primitives.valid()) _primitives->releaseGLObjects(state);
|
||||
}
|
||||
|
@ -438,9 +438,11 @@ void Text3D::computeGlyphRepresentation()
|
||||
{
|
||||
(*_coords)[i] += position;
|
||||
}
|
||||
_coords->dirty();
|
||||
|
||||
// copy normals
|
||||
_normals->insert(_normals->end(), src_normals->begin(), src_normals->end());
|
||||
_normals->dirty();
|
||||
|
||||
copyAndOffsetPrimitiveSets(_frontPrimitiveSetList, it->_glyphGeometry->getFrontPrimitiveSetList(), base);
|
||||
copyAndOffsetPrimitiveSets(_wallPrimitiveSetList, it->_glyphGeometry->getWallPrimitiveSetList(), base);
|
||||
|
@ -50,7 +50,6 @@ TextBase::TextBase():
|
||||
_lineCount(0),
|
||||
_glyphNormalized(false)
|
||||
{
|
||||
setStateSet(Font::getDefaultFont()->getStateSet());
|
||||
setUseDisplayList(false);
|
||||
setSupportsDisplayList(false);
|
||||
|
||||
@ -89,6 +88,11 @@ TextBase::~TextBase()
|
||||
{
|
||||
}
|
||||
|
||||
osg::StateSet* TextBase::createStateSet()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TextBase::initArraysAndBuffers()
|
||||
{
|
||||
_vbo = new osg::VertexBufferObject;
|
||||
@ -182,6 +186,10 @@ void TextBase::setColor(const osg::Vec4& color)
|
||||
_color = color;
|
||||
}
|
||||
|
||||
void TextBase::assignStateSet()
|
||||
{
|
||||
setStateSet(createStateSet());
|
||||
}
|
||||
|
||||
void TextBase::setFont(osg::ref_ptr<Font> font)
|
||||
{
|
||||
@ -189,6 +197,8 @@ void TextBase::setFont(osg::ref_ptr<Font> font)
|
||||
|
||||
_font = font;
|
||||
|
||||
assignStateSet();
|
||||
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
@ -203,6 +213,9 @@ void TextBase::setFontResolution(unsigned int width, unsigned int height)
|
||||
if (_fontSize==size) return;
|
||||
|
||||
_fontSize = size;
|
||||
|
||||
assignStateSet();
|
||||
|
||||
computeGlyphRepresentation();
|
||||
}
|
||||
|
||||
|
257
src/osgText/shaders/text_frag.cpp
Normal file
257
src/osgText/shaders/text_frag.cpp
Normal 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";
|
13
src/osgText/shaders/text_vert.cpp
Normal file
13
src/osgText/shaders/text_vert.cpp
Normal 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";
|
@ -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
|
||||
|
@ -299,13 +299,17 @@ struct IntersectFunctor
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 in = v0*r0 + v1*r1 + v2*r2;
|
||||
// Remap ratio into the range of LineSegment
|
||||
const osg::Vec3d& lsStart = _settings->_lineSegIntersector->getStart();
|
||||
const osg::Vec3d& lsEnd = _settings->_lineSegIntersector->getEnd();
|
||||
double remap_ratio = ((_start - lsStart).length() + r*_length)/(lsEnd - lsStart).length();
|
||||
|
||||
Vec3 in = lsStart*(1.0 - remap_ratio) + lsEnd*remap_ratio; // == v0*r0 + v1*r1 + v2*r2;
|
||||
Vec3 normal = E1^E2;
|
||||
normal.normalize();
|
||||
|
||||
|
||||
LineSegmentIntersector::Intersection hit;
|
||||
hit.ratio = r;
|
||||
hit.ratio = remap_ratio;
|
||||
hit.matrix = _settings->_iv->getModelMatrix();
|
||||
hit.nodePath = _settings->_iv->getNodePath();
|
||||
hit.drawable = _settings->_drawable;
|
||||
@ -500,7 +504,7 @@ void LineSegmentIntersector::intersect(osgUtil::IntersectionVisitor& iv, osg::Dr
|
||||
if (reachedLimit()) return;
|
||||
|
||||
osg::Vec3d s(_start), e(_end);
|
||||
if ( !intersectAndClip( s, e, drawable->getBoundingBox() ) ) return;
|
||||
if ( drawable->isCullingActive() && !intersectAndClip( s, e, drawable->getBoundingBox() ) ) return;
|
||||
|
||||
if (iv.getDoDummyTraversal()) return;
|
||||
|
||||
|
@ -1100,3 +1100,6 @@ public:
|
||||
REGISTER_WINDOWINGSYSTEMINTERFACE(Carbon, CarbonWindowingSystemInterface)
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -199,7 +199,7 @@ static NSRect convertToQuartzCoordinates(const NSRect& rect)
|
||||
// the app-delegate, handling quit-requests
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
@interface CocoaAppDelegate : NSObject
|
||||
@interface CocoaAppDelegate : NSObject <NSApplicationDelegate>
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -571,7 +571,6 @@ void Renderer::compile()
|
||||
{
|
||||
DEBUG_MESSAGE<<"Renderer::compile()"<<std::endl;
|
||||
|
||||
|
||||
_compileOnNextDraw = false;
|
||||
|
||||
osgUtil::SceneView* sceneView = _sceneView[0].get();
|
||||
@ -583,7 +582,7 @@ void Renderer::compile()
|
||||
{
|
||||
osgUtil::GLObjectsVisitor glov;
|
||||
glov.setState(sceneView->getState());
|
||||
sceneView->getSceneData()->accept(glov);
|
||||
glov.compile(*(sceneView->getSceneData()));
|
||||
}
|
||||
|
||||
sceneView->getState()->checkGLErrors("After Renderer::compile");
|
||||
|
@ -134,7 +134,6 @@ void Label::setFontColor(const Color& c) {
|
||||
|
||||
void Label::setShadow(point_type offset) {
|
||||
_text->setBackdropType(osgText::Text::DROP_SHADOW_BOTTOM_RIGHT);
|
||||
_text->setBackdropImplementation(osgText::Text::NO_DEPTH_BUFFER);
|
||||
_text->setBackdropOffset(offset);
|
||||
|
||||
_calculateSize(getTextSize());
|
||||
|
@ -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)
|
||||
{
|
||||
if (str=="SOLID") return osgText::Text::SOLID;
|
||||
@ -155,12 +134,6 @@ bool Text_readLocalData(osg::Object &obj, osgDB::Input &fr)
|
||||
// backdropImplementation
|
||||
if (fr[0].matchWord("backdropImplementation"))
|
||||
{
|
||||
std::string str = fr[1].getStr();
|
||||
osgText::Text::BackdropImplementation backdropImplementation = convertBackdropImplementationStringToEnum(str);
|
||||
|
||||
if (backdropImplementation != static_cast<osgText::Text::BackdropImplementation>(-1))
|
||||
text.setBackdropImplementation(backdropImplementation);
|
||||
|
||||
fr += 2;
|
||||
itAdvanced = true;
|
||||
}
|
||||
@ -254,9 +227,6 @@ bool Text_writeLocalData(const osg::Object &obj, osgDB::Output &fw)
|
||||
osg::Vec4 c = text.getBackdropColor();
|
||||
fw.indent() << "backdropColor " << c.x() << " " << c.y() << " " << c.z() << " " << c.w() << std::endl;
|
||||
|
||||
// backdropImplementation
|
||||
fw.indent() << "backdropImplementation " << convertBackdropImplementationEnumToString(text.getBackdropImplementation()) << std::endl;
|
||||
|
||||
// colorGradientMode
|
||||
fw.indent() << "colorGradientMode " << convertColorGradientModeEnumToString(text.getColorGradientMode()) << std::endl;
|
||||
|
||||
|
@ -3,25 +3,34 @@
|
||||
USE_SERIALIZER_WRAPPER(AlphaFunc)
|
||||
USE_SERIALIZER_WRAPPER(AnimationPath)
|
||||
USE_SERIALIZER_WRAPPER(AnimationPathCallback)
|
||||
USE_SERIALIZER_WRAPPER(AtomicCounterBufferBinding)
|
||||
USE_SERIALIZER_WRAPPER(AudioSink)
|
||||
USE_SERIALIZER_WRAPPER(AudioStream)
|
||||
USE_SERIALIZER_WRAPPER(AutoTransform)
|
||||
USE_SERIALIZER_WRAPPER(Billboard)
|
||||
USE_SERIALIZER_WRAPPER(BlendColor)
|
||||
USE_SERIALIZER_WRAPPER(BlendEquation)
|
||||
USE_SERIALIZER_WRAPPER(BlendEquationi)
|
||||
USE_SERIALIZER_WRAPPER(BlendFunc)
|
||||
USE_SERIALIZER_WRAPPER(BlendFunci)
|
||||
USE_SERIALIZER_WRAPPER(BoolValueObject)
|
||||
USE_SERIALIZER_WRAPPER(Box)
|
||||
USE_SERIALIZER_WRAPPER(BufferData)
|
||||
USE_SERIALIZER_WRAPPER(BufferIndexBinding)
|
||||
USE_SERIALIZER_WRAPPER(BufferObject)
|
||||
USE_SERIALIZER_WRAPPER(Callback)
|
||||
USE_SERIALIZER_WRAPPER(CallbackObject)
|
||||
USE_SERIALIZER_WRAPPER(Camera)
|
||||
USE_SERIALIZER_WRAPPER(CameraView)
|
||||
USE_SERIALIZER_WRAPPER(Capsule)
|
||||
USE_SERIALIZER_WRAPPER(ClampColor)
|
||||
USE_SERIALIZER_WRAPPER(ClearNode)
|
||||
USE_SERIALIZER_WRAPPER(ClipNode)
|
||||
USE_SERIALIZER_WRAPPER(ClipControl)
|
||||
USE_SERIALIZER_WRAPPER(ClipPlane)
|
||||
USE_SERIALIZER_WRAPPER(ClusterCullingCallback)
|
||||
USE_SERIALIZER_WRAPPER(ColorMask)
|
||||
USE_SERIALIZER_WRAPPER(ColorMaski)
|
||||
USE_SERIALIZER_WRAPPER(ColorMatrix)
|
||||
USE_SERIALIZER_WRAPPER(CompositeShape)
|
||||
USE_SERIALIZER_WRAPPER(ComputeBoundingBoxCallback)
|
||||
@ -32,9 +41,11 @@ USE_SERIALIZER_WRAPPER(ConvexPlanarOccluder)
|
||||
USE_SERIALIZER_WRAPPER(CoordinateSystemNode)
|
||||
USE_SERIALIZER_WRAPPER(CullFace)
|
||||
USE_SERIALIZER_WRAPPER(Cylinder)
|
||||
USE_SERIALIZER_WRAPPER(DefaultUserDataContainer)
|
||||
USE_SERIALIZER_WRAPPER(Depth)
|
||||
USE_SERIALIZER_WRAPPER(Drawable)
|
||||
USE_SERIALIZER_WRAPPER(DrawPixels)
|
||||
USE_SERIALIZER_WRAPPER(ElementBufferObject)
|
||||
USE_SERIALIZER_WRAPPER(EllipsoidModel)
|
||||
USE_SERIALIZER_WRAPPER(Fog)
|
||||
USE_SERIALIZER_WRAPPER(FragmentProgram)
|
||||
@ -77,10 +88,14 @@ USE_SERIALIZER_WRAPPER(Projection)
|
||||
USE_SERIALIZER_WRAPPER(ProxyNode)
|
||||
USE_SERIALIZER_WRAPPER(SampleMaski)
|
||||
USE_SERIALIZER_WRAPPER(Scissor)
|
||||
USE_SERIALIZER_WRAPPER(Script)
|
||||
USE_SERIALIZER_WRAPPER(ScriptNodeCallback)
|
||||
USE_SERIALIZER_WRAPPER(Sequence)
|
||||
USE_SERIALIZER_WRAPPER(ShadeModel)
|
||||
USE_SERIALIZER_WRAPPER(Shader)
|
||||
USE_SERIALIZER_WRAPPER(ShaderAttribute)
|
||||
USE_SERIALIZER_WRAPPER(ShaderBinary)
|
||||
USE_SERIALIZER_WRAPPER(ShaderStorageBufferBinding)
|
||||
USE_SERIALIZER_WRAPPER(Shape)
|
||||
USE_SERIALIZER_WRAPPER(ShapeDrawable)
|
||||
USE_SERIALIZER_WRAPPER(Sphere)
|
||||
@ -101,16 +116,21 @@ USE_SERIALIZER_WRAPPER(Texture1D)
|
||||
USE_SERIALIZER_WRAPPER(Texture2D)
|
||||
USE_SERIALIZER_WRAPPER(Texture2DArray)
|
||||
USE_SERIALIZER_WRAPPER(Texture3D)
|
||||
USE_SERIALIZER_WRAPPER(TextureBuffer)
|
||||
USE_SERIALIZER_WRAPPER(TextureCubeMap)
|
||||
USE_SERIALIZER_WRAPPER(TextureRectangle)
|
||||
USE_SERIALIZER_WRAPPER(TransferFunction)
|
||||
USE_SERIALIZER_WRAPPER(TransferFunction1D)
|
||||
USE_SERIALIZER_WRAPPER(Transform)
|
||||
USE_SERIALIZER_WRAPPER(TransformFeedbackBufferBinding)
|
||||
USE_SERIALIZER_WRAPPER(TriangleMesh)
|
||||
USE_SERIALIZER_WRAPPER(Uniform)
|
||||
USE_SERIALIZER_WRAPPER(UniformBufferBinding)
|
||||
USE_SERIALIZER_WRAPPER(UniformCallback)
|
||||
USE_SERIALIZER_WRAPPER(UpdateCallback)
|
||||
USE_SERIALIZER_WRAPPER(UserDataContainer)
|
||||
USE_SERIALIZER_WRAPPER(VertexAttribDivisor)
|
||||
USE_SERIALIZER_WRAPPER(VertexBufferObject)
|
||||
USE_SERIALIZER_WRAPPER(VertexProgram)
|
||||
USE_SERIALIZER_WRAPPER(Viewport)
|
||||
|
||||
@ -164,5 +184,21 @@ USE_SERIALIZER_WRAPPER(DrawElementsUByte)
|
||||
USE_SERIALIZER_WRAPPER(DrawElementsUShort)
|
||||
USE_SERIALIZER_WRAPPER(DrawElementsUInt)
|
||||
|
||||
#ifdef OSG_HAS_MULTIDRAWARRAYS
|
||||
USE_SERIALIZER_WRAPPER(MultiDrawArrays)
|
||||
#endif
|
||||
|
||||
// PrimitiveSetIndirect
|
||||
USE_SERIALIZER_WRAPPER(IndirectCommandDrawArrays)
|
||||
USE_SERIALIZER_WRAPPER(IndirectCommandDrawElements)
|
||||
USE_SERIALIZER_WRAPPER(osgDefaultIndirectCommandDrawArrays)
|
||||
USE_SERIALIZER_WRAPPER(osgDefaultIndirectCommandDrawElements)
|
||||
USE_SERIALIZER_WRAPPER(DrawArraysIndirect)
|
||||
USE_SERIALIZER_WRAPPER(MultiDrawArraysIndirect)
|
||||
USE_SERIALIZER_WRAPPER(DrawElementsIndirect)
|
||||
USE_SERIALIZER_WRAPPER(DrawElementsIndirectUByte)
|
||||
USE_SERIALIZER_WRAPPER(DrawElementsIndirectUShort)
|
||||
USE_SERIALIZER_WRAPPER(DrawElementsIndirectUInt)
|
||||
|
||||
extern "C" void wrapper_serializer_library_osg(void) {}
|
||||
|
||||
|
@ -145,6 +145,39 @@ static bool writeComputeGroups( osgDB::OutputStream& os, const osg::Program& att
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool checkBindUniformBlock( const osg::Program& node )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool readBindUniformBlock( osgDB::InputStream& is, osg::Program& p )
|
||||
{
|
||||
unsigned int size = 0; is >> size >> is.BEGIN_BRACKET;
|
||||
std::string name; unsigned int index;
|
||||
for ( unsigned int i=0; i<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,
|
||||
new osg::Program,
|
||||
osg::Program,
|
||||
@ -167,4 +200,8 @@ REGISTER_OBJECT_WRAPPER( Program,
|
||||
ADD_USER_SERIALIZER( FeedBackVaryingsName );
|
||||
ADD_USER_SERIALIZER( FeedBackMode );
|
||||
}
|
||||
{
|
||||
UPDATE_TO_VERSION_SCOPED( 150 )
|
||||
ADD_USER_SERIALIZER( BindUniformBlock );
|
||||
}
|
||||
}
|
||||
|
11
src/osgWrappers/serializers/osg/ShaderAttribute.cpp
Normal file
11
src/osgWrappers/serializers/osg/ShaderAttribute.cpp
Normal 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" )
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user