Compare commits

..
94 Commits
Author SHA1 Message Date
Tim Moore 9b0ba10b0b Merge branch 'jmt/ref_ptr-conv' into next 2010-05-05 10:42:41 +02:00
jmt 9f9c4cf32c Compile even if OSG_USE_REF_PTR_IMPLICIT_OUTPUT_CONVERSION is not set. 2010-05-05 10:42:29 +02:00
Tim Moore 536ebf604f Merge branch 'ehofman/framebuffer' into next 2010-05-05 10:39:32 +02:00
ehofman 03a616b737 Add support for EXT_framebuffer_object for Atlas 2010-05-05 10:39:18 +02:00
Tim Moore 0b05f67114 Merge branch 'master' into next 2010-05-05 10:38:26 +02:00
Tim Moore 0ede690580 Merge branch 'maint' 2010-05-05 10:38:18 +02:00
frohlich d81545a871 Add -ldl for newer ld defaults from fedora 13
Modified Files:
	simgear/screen/Makefile.am
2010-05-05 10:38:09 +02:00
Tim Moore 1cda1fc201 Merge branch 'mathias/intersect' into next 2010-05-05 09:43:40 +02:00
frohlich 490dad7838 Provide a more exact sphere/box test.
Modified Files:
	simgear/math/SGIntersect.hxx simgear/math/SGBox.hxx
2010-05-05 09:43:32 +02:00
Tim Moore 13ecbb8bce Merge branch 'master' into next 2010-05-05 09:40:31 +02:00
Tim Moore 3346bfc9a8 Merge branch 'maint' 2010-05-05 09:40:23 +02:00
frohlich c5de65f115 Make the bounding volume debug visitor compile again.
Modified Files:
	simgear/scene/bvh/BVHDebugCollectVisitor.hxx
2010-05-05 09:40:06 +02:00
Tim Moore 4fffcf9975 Merge branch 'ehofman/sound' into next 2010-05-05 09:05:35 +02:00
jmt 8962d9b293 Following discussion with Tat and Erik, update how we handle ALUT on Mac; specifically, switch to using an ALUT.framework built from FreeALUT. The ALUT framework is available (initially) from:
http://files.goneabitbursar.com/fg/alut-osx-universal.zip

for testing purposes; autoconf integration and an official home for the
framework will follow once this approach has been tested and confirmed as
sane by other Mac developers!
2010-05-05 09:05:23 +02:00
Tim Moore 050c1560e8 Merge branch 'fredb/msvc-cleanup' into next 2010-05-05 09:03:20 +02:00
fredb 68b3041f50 Remove obsolete file 2010-05-05 09:03:10 +02:00
fredb 1ddd153399 Cleanup MSVC projects 2010-05-05 09:02:58 +02:00
Tim Moore df0a60caae Merge branch 'ehofman/model' into next 2010-05-05 08:44:32 +02:00
fredb 675c86582d Stuart Buchanan: Fix a bug in the random object placement where the model selected in the case of multiple object definitions in material.xml was random, rather than seeded. 2010-05-05 08:44:18 +02:00
Tim Moore e6d01ed1a3 Merge branch 'fredb/effect-stuff' 2010-04-25 22:52:35 +02:00
Tim Moore d8d1064e05 Merge branch 'zan/cubemap' 2010-04-25 22:52:10 +02:00
Tim Moore 5d04cb81ba Merge branch 'fredb/geom-shader' 2010-04-25 22:52:02 +02:00
Tim Moore 5d5906e980 Merge branch 'ehofman/particles' 2010-04-25 22:36:06 +02:00
Tim Moore 2e7b862ad3 Merge branch 'timoore/aptsign' 2010-04-25 22:33:34 +02:00
Tim Moore ad86e22824 Merge branch 'jmt/magvar' 2010-04-25 22:33:18 +02:00
Tim Moore 536b8a213b Merge branch 'fred/precip' 2010-04-25 22:33:02 +02:00
Tim Moore 2e13877926 Merge branches 'ehofman/propfix' and 'ehofman/sound' 2010-04-25 22:32:44 +02:00
Tim Moore 967d63dec4 Merge branches 'ehofman/config' and 'ehofman/dlerror' 2010-04-25 22:32:14 +02:00
Tim Moore 573c4268b6 Merge branch 'fredb/effect-stuff' into next 2010-04-12 07:25:24 +02:00
fredb f19e83dcf1 Add a new node "float-property" to be used in float comparision in effect predicates 2010-04-12 07:25:13 +02:00
fredb caabe8fc87 Add a "scale" parameter that combine xsize and ysize in a vec3 property. There is no vec2 property, so the third component is zero 2010-04-12 07:25:13 +02:00
fredb 7c4e5309fc Declare some material parameters as implicit effect parameters 2010-04-12 07:25:13 +02:00
fredb 542124e90c materials.xml format update
Allow to declare sets of textures that can be used as parameters for effects. Syntax is:
  <texture-set>
   <texture>Terrain/city1.png</texture>
   <texture n="2">Terrain/city1-relief-light.png</texture>
  </texture-set>
  <texture-set>
   <texture>Terrain/city2.png</texture>
   <texture n="2">Terrain/city2-relief-light.png</texture>
  </texture-set>
2010-04-12 07:25:13 +02:00
Tim Moore e0d02be0f5 Merge branch 'zan/cubemap' into next 2010-04-03 22:49:07 +02:00
Tim Moore 461e6d1b5b Zan's cubemap patch 2010-04-03 22:48:58 +02:00
Tim Moore d767e6d7eb Merge branch 'fredb/geom-shader' into next 2010-03-30 12:07:50 +02:00
fredb bff1584012 Geometry shader support 2010-03-30 12:07:38 +02:00
Tim Moore 3d91a11b95 Merge branch 'zan/generate' 2010-03-30 12:04:09 +02:00
Tim Moore 1349b46a8c Merge branch 'jmt/waypt' 2010-03-30 11:53:13 +02:00
Tim Moore 74330ba1dd Merge branch 'timoore/clipgroup' 2010-03-30 11:46:01 +02:00
Tim Moore 64ab227f62 Merge branch 'timoore/effects-anim-rebase' 2010-03-30 11:41:37 +02:00
Tim Moore 1c51fbd1b4 Merge branch 'zan/cloudsort' 2010-03-30 11:40:45 +02:00
Tim Moore 4c2dd553f2 Merge branch 'ehofman/particles' into next 2010-03-27 13:39:55 +01:00
Tim Moore 2fb985afa4 Merge branch 'ehofman/dlerror' into next 2010-03-27 13:39:48 +01:00
ehofman 44c93d5074 Csaba Halasz: fix a compilation error for non-bsd systems that happen to return
const char* from dlerror().
2010-03-27 13:39:37 +01:00
ehofman dcf07a46aa Allow particles to be frozen on pause. 2010-03-27 13:38:59 +01:00
Tim Moore 284a9e0612 Merge branch 'ehofman/sound' into next 2010-03-16 17:15:34 +01:00
Tim Moore 60349a8690 Merge branch 'ehofman/propfix' into next 2010-03-16 17:15:29 +01:00
ehofman 64072be83c iprovide a slightly more helpfull exception message 2010-03-16 17:15:12 +01:00
ehofman 229abb8412 updated vendor test 2010-03-16 17:14:19 +01:00
Tim Moore 7b1d1fd288 Merge branch 'timoore/clipgroup' into next 2010-03-16 15:44:56 +01:00
Tim Moore 1ca1f6ad22 Remove reference to osgUtil::RegisterRenderBinProxy
This has gone away in recent OSG sources.
2010-03-16 15:42:54 +01:00
Tim Moore 0ad66f4bc4 Merge branch 'zan/generate' into next 2010-03-16 14:27:56 +01:00
fredb d5757c4fb8 Lauri Peltonen : add the ability to generate tangent vectors for model, terrain or ocean geometry inside the effect file 2010-03-16 14:27:21 +01:00
Tim Moore 7fe40bce86 Merge branch 'jmt/magvar' into next 2010-03-16 14:22:53 +01:00
jmt 5da3d64ede Overload the SGMagVar::update method to take an SGGeod. 2010-03-16 14:22:45 +01:00
Tim Moore 2e93b06ac0 Merge branch 'fred/precip' into next 2010-03-16 14:21:57 +01:00
fredb 1e6aa4b40f Precipitation inside cockpit temporary fix.
Needs a clip distance settable to take account of views and different cockpit size.
2010-03-16 14:21:45 +01:00
Tim Moore 262383395d Merge branch 'timoore/aptsign' into next 2010-03-12 14:32:11 +01:00
Tim Moore 127226c421 Assign texcoords and a color (black) to the backs of airport signs 2010-03-12 14:31:39 +01:00
Tim Moore fabcb021cb Merge branch 'timoore/effects-anim-rebase' into next 2010-03-11 08:46:22 +01:00
Tim Moore 60ab1ab83e bug fix to animated effect parameters
Some confusion in getting the right property node.
2010-03-11 08:45:58 +01:00
Tim Moore 1f37095087 Merge branch 'timoore/effects-anim-rebase' into next 2010-03-09 11:03:25 +01:00
Tim Moore 93c2f70b64 animate uniform parameters in effects 2010-03-09 11:02:57 +01:00
Tim Moore b0562df6bb Cleanup of effects parameter animation 2010-03-09 11:02:56 +01:00
Tim Moore 65d6a5c774 Prepare effects animation code to use general functor setters 2010-03-09 11:02:56 +01:00
Tim Moore 650af0f7b0 generalize support for initializing effect parameters from several properties 2010-03-09 11:02:56 +01:00
Tim Moore cf9de25c25 pass SGReaderWriterXMLOptions object to getGlobalProperty
This supports pathnames relative to a model in effect definitions.
2010-03-09 11:02:56 +01:00
Tim Moore fc4009aa50 change return value of SGPropertyNode::getPath to std::string
Also get rid of the cached value.
2010-03-09 11:02:56 +01:00
Tim Moore d04cf4d897 pass SGReaderWriterXMLOptions to effects
This will allow parameters to refer to properties in models, though
that doesn't work yet.
2010-03-09 11:02:56 +01:00
Tim Moore 2e45c67ef2 Merge branch 'zan/stencil' 2010-03-09 10:59:09 +01:00
Tim Moore b6d8e1f842 Merge branch 'zan/cloudsort' into next 2010-03-03 23:12:49 +01:00
ehofman 284bc364fe Lauri Peltonen: turn on clouds depth sorting 2010-03-03 23:11:01 +01:00
Tim Moore a050654b4c Merge branch 'jmt/waypt' into next 2010-02-22 09:42:36 +01:00
jmt 7311dae483 Allow a waypoint's target altitude to be modified in-place. 2010-02-22 09:42:28 +01:00
Tim Moore c57c3cd1d3 Merge branch 'curt/makefile' 2010-02-17 18:01:29 +01:00
Tim Moore 3ec5e85485 Merge branch 'curt/makefile' into next 2010-02-17 07:20:38 +01:00
curt ff95af0367 Add a missing source file so it will be included with "make dist". 2010-02-17 07:20:21 +01:00
curt aa9c7d5435 Add a missing .hxx file for "make dist" 2010-02-17 07:20:19 +01:00
Tim Moore dcc9f33357 Merge branch 'ehofman/sound' into next 2010-02-17 07:19:20 +01:00
ehofman 1ace645505 small fix for when sound is disabled 2010-02-17 07:19:02 +01:00
Tim Moore dc2b87dce1 Merge branch 'ehofman/config' into next 2010-02-17 07:18:30 +01:00
ehofman 8e47f5d494 John Denker: Fix sneaky bug: 'mylibdir' variable getting trampled. 2010-02-17 07:18:20 +01:00
Tim Moore 333d381f41 Merge branch 'ehofman/config' into next 2010-02-14 19:42:59 +01:00
ehofman f9b064cc19 Joe User updates by John Denker 2010-02-14 19:42:51 +01:00
Tim Moore 116a6c1b2e Merge branch 'zan/stencil' into next 2010-02-10 15:48:23 +01:00
Tim Moore c4506b8e6c Merge branch 'ehofman/config' into next 2010-02-10 14:56:36 +01:00
ehofman 6786a7be4a small MacOS fix 2010-02-10 14:55:57 +01:00
ehofman bb370a304d smnall update for MacOS without framework support 2010-02-10 14:55:57 +01:00
ehofman fdcf53c688 Properly test for OpenThreads and bail out if it isn't found 2010-02-10 14:55:57 +01:00
Tim Moore d3f575547c Merge branch 'durk/deadfiles' into next-new 2010-02-06 23:15:09 +01:00
ehofman 68797e51c6 implement a round-robin scheme for random objects to make sure the same type of object is placed at the same spot all the time 2010-02-06 23:12:40 +01:00
durk c76c55cdee - Remove reference to dead files. 2010-02-06 19:01:58 +01:00
Tim Moore acf19cebf8 Stencil operations for effects
From Lauri Peltonen
2010-01-29 19:07:53 +01:00
60 changed files with 1166 additions and 1776 deletions
+1 -4
View File
@@ -2,14 +2,11 @@ EXTRA_DIST = \
acinclude.m4 \ acinclude.m4 \
autogen.sh \ autogen.sh \
DoxygenMain.cxx \ DoxygenMain.cxx \
README.MSVC \
README.zlib \ README.zlib \
README.plib \ README.plib \
README.OpenAL \ README.OpenAL \
README.OSG \ README.OSG \
projects \ projects
SimGear.dsp \
SimGear.dsw
SUBDIRS = simgear SUBDIRS = simgear
-24
View File
@@ -1,24 +0,0 @@
This document describes how to build SimGear using the supplied workspace and
project files.
Unpack the SimGear source file into your work directory. This creates a new
subdirectory called SimGear-X.Y.Z. Rename this to SimGear. Before we can
build SimGear you must unpack and build the third party libraries metakit and
zlib. Sources for these are included in the SimGear/src-libs directory.
Unpack these into the top level SimGear directory. At this point your
directory structure should look something like this:
<work_dir>/
SimGear/
metakit-x.y.z/
simgear/
src-libs/
zlib-x.y.z/
Now open the SimGear workspace. This workspace file contains projects for
building metakit(mklib), SimGear and zlib. Select each project as the active
project and build all. Order is unimportant since there are no dependencies
between the projects.
The workspace and project files are generated by a perl script with extra
input from the am2dsp.cfg file.
+50 -30
View File
@@ -6,19 +6,25 @@ dnl
AC_DEFUN([wi_EXTRA_IDIR], [ AC_DEFUN([wi_EXTRA_IDIR], [
incdir="$1" incdir="$1"
if test -r $incdir ; then if test -r $incdir ; then
case "$CPPFLAGS" in already=""
*-I${incdir}*) for CPPflag in $CPPFLAGS ; do
# echo " + already had $incdir" 1>&6 if test "_$CPPflag" = "_-I${incdir}" ; then
;; already=yes
*) break
fi
done
if test -n "$already" ; then
echo " + already had -I$incdir" 1>&AS_MESSAGE_LOG_FD
else
if test "$CPPFLAGS" = "" ; then if test "$CPPFLAGS" = "" ; then
CPPFLAGS="-I$incdir" CPPFLAGS="-I$incdir"
else else
CPPFLAGS="$CPPFLAGS -I$incdir" CPPFLAGS="$CPPFLAGS -I$incdir"
fi fi
echo " + found $incdir" 1>&6 echo " + added -I$incdir" 1>&AS_MESSAGE_LOG_FD
;; fi
esac else
echo " + IDIR is not accessible: '$myincdir'" 1>&AS_MESSAGE_LOG_FD
fi fi
]) ])
dnl dnl
@@ -28,19 +34,25 @@ dnl
AC_DEFUN([wi_EXTRA_LDIR], [ AC_DEFUN([wi_EXTRA_LDIR], [
mylibdir="$1" mylibdir="$1"
if test -r $mylibdir ; then if test -r $mylibdir ; then
case "$LDFLAGS" in already=""
*-L${mylibdir}*) for LDflag in $LDFLAGS ; do
# echo " + already had $mylibdir" 1>&6 if test "_$LDflag" = "_-L${mylibdir}" ; then
;; already=yes
*) break
fi
done
if test -n "$already" ; then
echo " + already had -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
else
if test "$LDFLAGS" = "" ; then if test "$LDFLAGS" = "" ; then
LDFLAGS="-L$mylibdir" LDFLAGS="-L$mylibdir"
else else
LDFLAGS="$LDFLAGS -L$mylibdir" LDFLAGS="$LDFLAGS -L$mylibdir"
fi fi
echo " + found $mylibdir" 1>&6 echo " + added -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
;; fi
esac else
echo " + LDIR is not accessible: '$mylibdir'" 1>&AS_MESSAGE_LOG_FD
fi fi
]) ])
dnl dnl
@@ -50,12 +62,9 @@ dnl
AC_DEFUN([wi_EXTRA_PDIR], [ AC_DEFUN([wi_EXTRA_PDIR], [
progdir="$1" progdir="$1"
if test -r $progdir ; then if test -r $progdir ; then
case "$PATH" in case ":$PATH:" in
*:${progdir}*) *:${progdir}:*)
# echo " + already had $progdir" 1>&6 echo " + already had $progdir in \$PATH" 1>&AS_MESSAGE_LOG_FD
;;
*${progdir}:*)
# echo " + already had $progdir" 1>&6
;; ;;
*) *)
if test "$PATH" = "" ; then if test "$PATH" = "" ; then
@@ -63,9 +72,11 @@ if test -r $progdir ; then
else else
PATH="$PATH:$progdir" PATH="$PATH:$progdir"
fi fi
echo " + found $progdir" 1>&6 echo " + appended $progdir to \$PATH" 1>&AS_MESSAGE_LOG_FD
;; ;;
esac esac
else
echo " + PDIR is not accessible: '$progdir'" 1>&AS_MESSAGE_LOG_FD
fi fi
]) ])
dnl dnl
@@ -89,23 +100,32 @@ if test "$subexdirs" = "" ; then
subexdirs="-" subexdirs="-"
fi fi
for subexdir in $subexdirs ; do for subexdir in $subexdirs ; do
if test "$subexdir" = "-" ; then if test "$subexdir" = "-" ; then
subexdir="" subexdir=""
else else
subexdir="/$subexdir" subexdir="/$subexdir"
fi fi
for exdir in $exdirs ; do for exdir in $exdirs ; do
if test "$exdir" != "/usr" || test "$subexdir" != ""; then if test "$exdir" != "/usr" || test "$subexdir" != ""; then
incdir="${exdir}/include${subexdir}" incdir="${exdir}/include${subexdir}"
wi_EXTRA_IDIR($incdir) wi_EXTRA_IDIR($incdir)
mylibdir="${exdir}/lib${subexdir}" dnl On 64-bit machines, if lib64/ exists and is not identical to lib/
wi_EXTRA_LDIR($mylibdir) dnl then it should be listed here, listed ahead of lib/.
mylibdir64="${exdir}/lib64${subexdir}"
mylibdir32="${exdir}/lib${subexdir}"
if test "x86_64" = $(uname -m) \
-a ! ${mylibdir64} -ef ${mylibdir32} ; then
wi_EXTRA_LDIR($mylibdir64)
fi
wi_EXTRA_LDIR($mylibdir32)
progdir="${exdir}/bin${subexdir}" progdir="${exdir}/bin${subexdir}"
wi_EXTRA_PDIR($progdir) wi_EXTRA_PDIR($progdir)
fi fi
done done
done done
]) ])
dnl dnl
+42 -16
View File
@@ -437,11 +437,18 @@ esac
AM_CONDITIONAL(HAVE_FRAMEWORK_PLIB, test "x$ac_cv_framework_PLIB" != "x") AM_CONDITIONAL(HAVE_FRAMEWORK_PLIB, test "x$ac_cv_framework_PLIB" != "x")
AC_CHECK_HEADER(plib/ul.h) AC_CHECK_HEADER(plib/ul.h)
if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
AC_CHECK_LIB(plibul,ulInit)
if test "x$ac_cv_header_plib_ul_h" != "xyes" \
-o "x$ac_cv_lib_plibul_ulInit" != "xyes" ; then
echo echo
echo "You *must* have the plib library installed on your system to build" echo "You *must* have the plib library installed on your system to build"
echo "SimGear!" echo "SimGear!"
echo echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "Please see README.plib for more details." echo "Please see README.plib for more details."
echo echo
echo "configure aborted." echo "configure aborted."
@@ -475,18 +482,18 @@ LIBS="$saved_LIBS"
case "${host}" in case "${host}" in
*-apple-darwin*) *-apple-darwin*)
if test "x$with_osg_framework" != "x"; then if test "x$with_osg_framework" != "x"; then
AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgGA, [#include <osgGA/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgGA, [#include <osgGA/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgText, [#include <osgText/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgText, [#include <osgText/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgFX, [#include <osgFX/AnisotropicLighting>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgFX, [#include <osgFX/AnisotropicLighting>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgUtil, [#include <osgUtil/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgUtil, [#include <osgUtil/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgDB, [#include <osgDB/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgDB, [#include <osgDB/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgSim, [#include <osgSim/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgSim, [#include <osgSim/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework) # AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
osg_FRAMEWORKS="$FRAMEWORKS" # osg_FRAMEWORKS="$FRAMEWORKS"
FRAMEWORKS="" # FRAMEWORKS=""
AC_SUBST(osg_FRAMEWORKS) # AC_SUBST(osg_FRAMEWORKS)
AC_CHECK_FRAMEWORK(OpenThreads, [#include <OpenThreads/Version>], $with_osg_framework) AC_CHECK_FRAMEWORK(OpenThreads, [#include <OpenThreads/Version>], $with_osg_framework)
openthreads_FRAMEWORK="$FRAMEWORKS" openthreads_FRAMEWORK="$FRAMEWORKS"
FRAMEWORKS="" FRAMEWORKS=""
@@ -496,18 +503,33 @@ case "${host}" in
dnl This is needed when osg dynamic libs are specified dnl This is needed when osg dynamic libs are specified
dnl instead of OSG frameworks on Mac OS X dnl instead of OSG frameworks on Mac OS X
dnl dnl
LDFLAGS="$LDFLAGS -L$with_osg" AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
fi
;;
*)
if test "x$enable_osgdebug" = "xyes"; then
AC_CHECK_LIB(OpenThreadsd,OpenThreadsGetVersion)
else
AC_CHECK_LIB(OpenThreads,OpenThreadsGetVersion)
fi fi
;; ;;
esac esac
AM_CONDITIONAL(HAVE_FRAMEWORK_OSG, test "x$ac_cv_framework_osg" != "x") AM_CONDITIONAL(HAVE_FRAMEWORK_OSG, test "x$ac_cv_framework_osg" != "x")
AC_CHECK_HEADER(osg/Version) AC_CHECK_HEADER(osg/Version)
if test "x$ac_cv_header_osg_Version" != "xyes"; then
if test "x$ac_cv_header_osg_Version" != "xyes" -o "x$ac_cv_lib_OpenThreads_OpenThreadsGetVersion" != "xyes"; then
if test "x$ac_cv_framework_osg" != "xyes"; then if test "x$ac_cv_framework_osg" != "xyes"; then
echo echo
echo "You *must* have the OpenSceneGraph support library installed on your system" echo "You *must* have the OpenThreads library installed on your system"
echo "to build this version of SimGear!" echo "to build this version of SimGear!"
echo " Maybe you need to specify --with-osg=DIR."
echo " Maybe you need to specify some LDFLAGS to help the linker."
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo echo
echo "Please see README.OSG for more details." echo "Please see README.OSG for more details."
echo echo
@@ -522,6 +544,10 @@ if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
echo "You *must* have the Boost library installed on your system" echo "You *must* have the Boost library installed on your system"
echo "to build this version of SimGear!" echo "to build this version of SimGear!"
echo echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "configure aborted." echo "configure aborted."
exit exit
fi fi
-5
View File
@@ -1,5 +0,0 @@
Debug
Release
SimGear.ncb
SimGear.suo
*.user
-21
View File
@@ -1,21 +0,0 @@
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SimGear", "SimGear.vcproj", "{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Debug.ActiveCfg = Debug|Win32
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Debug.Build.0 = Debug|Win32
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release.ActiveCfg = Release|Win32
{22540CD3-D3CA-4C86-A773-80AEEE3ACDED}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal
File diff suppressed because it is too large Load Diff
+15 -1
View File
@@ -28,6 +28,7 @@
#include "visual_enviro.hxx" #include "visual_enviro.hxx"
#include <simgear/constants.h> #include <simgear/constants.h>
#include <osg/ClipNode>
/** /**
* @brief SGPrecipitation constructor * @brief SGPrecipitation constructor
@@ -35,7 +36,7 @@
* Build a new OSG object from osgParticle. * Build a new OSG object from osgParticle.
*/ */
SGPrecipitation::SGPrecipitation() : SGPrecipitation::SGPrecipitation() :
_freeze(false), _snow_intensity(0.0), _rain_intensity(0.0) _freeze(false), _snow_intensity(0.0), _rain_intensity(0.0), _clip_distance(5.0)
{ {
_precipitationEffect = new osgParticle::PrecipitationEffect; _precipitationEffect = new osgParticle::PrecipitationEffect;
} }
@@ -54,7 +55,20 @@ osg::Group* SGPrecipitation::build(void)
_precipitationEffect->snow(0); _precipitationEffect->snow(0);
_precipitationEffect->rain(0); _precipitationEffect->rain(0);
if (_clip_distance!=0.0)
{
osg::ref_ptr<osg::ClipNode> clipNode = new osg::ClipNode;
clipNode->addClipPlane( new osg::ClipPlane( 0 ) );
clipNode->getClipPlane(0)->setClipPlane( 0.0, 0.0, -1.0, -_clip_distance );
clipNode->setReferenceFrame(osg::ClipNode::ABSOLUTE_RF);
clipNode->addChild(_precipitationEffect.get());
group->addChild(clipNode.get());
}
else
{
group->addChild(_precipitationEffect.get()); group->addChild(_precipitationEffect.get());
}
return group; return group;
} }
+1
View File
@@ -39,6 +39,7 @@ private:
float _snow_intensity; float _snow_intensity;
float _rain_intensity; float _rain_intensity;
float _clip_distance;
int _wind_dir; int _wind_dir;
osg::Vec3 _wind_vec; osg::Vec3 _wind_vec;
+7
View File
@@ -24,6 +24,7 @@
#include <math.h> #include <math.h>
#include <simgear/magvar/magvar.hxx> #include <simgear/magvar/magvar.hxx>
#include <simgear/math/SGMath.hxx>
#include "coremag.hxx" #include "coremag.hxx"
#include "magvar.hxx" #include "magvar.hxx"
@@ -47,6 +48,12 @@ void SGMagVar::update( double lon, double lat, double alt_m, double jd ) {
magdip = atan(field[5]/sqrt(field[3]*field[3]+field[4]*field[4])); magdip = atan(field[5]/sqrt(field[3]*field[3]+field[4]*field[4]));
} }
void SGMagVar::update( const SGGeod& geod, double jd ) {
update(geod.getLongitudeDeg(), geod.getLatitudeDeg(),
geod.getElevationM(), jd);
}
double sgGetMagVar( double lon, double lat, double alt_m, double jd ) { double sgGetMagVar( double lon, double lat, double alt_m, double jd ) {
// cout << "lat = " << lat << " lon = " << lon << " elev = " << alt_m // cout << "lat = " << lat << " lon = " << lon << " elev = " << alt_m
+8
View File
@@ -33,6 +33,9 @@
#endif #endif
// forward decls
class SGGeod;
/** /**
* Magnetic variation wrapper class. * Magnetic variation wrapper class.
* *
@@ -78,6 +81,11 @@ public:
*/ */
void update( double lon, double lat, double alt_m, double jd ); void update( double lon, double lat, double alt_m, double jd );
/**
* overloaded variant taking an SGGeod to specify position
*/
void update( const SGGeod& geod, double jd );
/** @return the current magnetic variation in radians. */ /** @return the current magnetic variation in radians. */
double get_magvar() const { return magvar; } double get_magvar() const { return magvar; }
+8
View File
@@ -71,6 +71,14 @@ public:
(pt[2] > center[2]) ? _min[2] : _max[2]); (pt[2] > center[2]) ? _min[2] : _max[2]);
} }
// return the closest point to pt still in the box
template<typename S>
SGVec3<T> getClosestPoint(const SGVec3<S>& pt) const
{
return SGVec3<T>((pt[0] < _min[0]) ? _min[0] : ((_max[0] < pt[0]) ? _max[0] : T(pt[0])),
(pt[1] < _min[1]) ? _min[1] : ((_max[1] < pt[1]) ? _max[1] : T(pt[1])),
(pt[2] < _min[2]) ? _min[2] : ((_max[2] < pt[2]) ? _max[2] : T(pt[2])));
}
// Only works for floating point types // Only works for floating point types
SGVec3<T> getCenter() const SGVec3<T> getCenter() const
+3 -17
View File
@@ -38,25 +38,11 @@ intersects(const SGBox<T1>& box, const SGSphere<T2>& sphere)
{ {
if (sphere.empty()) if (sphere.empty())
return false; return false;
// Is more or less trivially included in the next tests if (box.empty())
// if (box.empty())
// return false;
if (sphere.getCenter().x() < box.getMin().x() - sphere.getRadius())
return false;
if (sphere.getCenter().y() < box.getMin().y() - sphere.getRadius())
return false;
if (sphere.getCenter().z() < box.getMin().z() - sphere.getRadius())
return false; return false;
if (box.getMax().x() + sphere.getRadius() < sphere.getCenter().x()) SGVec3<T1> closest = box.getClosestPoint(sphere.getCenter());
return false; return distSqr(closest, SGVec3<T1>(sphere.getCenter())) <= sphere.getRadius2();
if (box.getMax().y() + sphere.getRadius() < sphere.getCenter().y())
return false;
if (box.getMax().z() + sphere.getRadius() < sphere.getCenter().z())
return false;
return true;
} }
// make it symmetric // make it symmetric
template<typename T1, typename T2> template<typename T1, typename T2>
+1 -1
View File
@@ -15,7 +15,7 @@ libsgprops_a_SOURCES = \
props_io.cxx \ props_io.cxx \
AtomicChangeListener.cxx AtomicChangeListener.cxx
noinst_PROGRAMS = props_test check_PROGRAMS = props_test
props_test_SOURCES = props_test.cxx props_test_SOURCES = props_test.cxx
props_test_LDADD = \ props_test_LDADD = \
+27 -13
View File
@@ -94,7 +94,7 @@ public:
template<typename Range> template<typename Range>
inline Range inline Range
parse_name (const Range &path) parse_name (const SGPropertyNode *node, const Range &path)
{ {
typename Range::iterator i = path.begin(); typename Range::iterator i = path.begin();
typename Range::iterator max = path.end(); typename Range::iterator max = path.end();
@@ -118,15 +118,24 @@ parse_name (const Range &path)
} else if (*i == '[' || *i == '/') { } else if (*i == '[' || *i == '/') {
break; break;
} else { } else {
throw string("name may contain only ._- and alphanumeric characters"); string err = "'";
err.push_back(*i);
err.append("' found in propertyname after '"+node->getNameString()+"'");
err.append("\nname may contain only ._- and alphanumeric characters");
throw err;
} }
i++; i++;
} }
} }
else { else {
if (path.begin() == i) if (path.begin() == i) {
throw string("name must begin with alpha or '_'"); string err = "'";
err.push_back(*i);
err.append("' found in propertyname after '"+node->getNameString()+"'");
err.append("\nname must begin with alpha or '_'");
throw err;
}
} }
return Range(path.begin(), i); return Range(path.begin(), i);
} }
@@ -268,7 +277,7 @@ find_node_aux(SGPropertyNode * current, SplitItr& itr, bool create,
// Empty name at this point is empty, not root. // Empty name at this point is empty, not root.
if (token.empty()) if (token.empty())
return find_node_aux(current, ++itr, create, last_index); return find_node_aux(current, ++itr, create, last_index);
Range name = parse_name(token); Range name = parse_name(current, token);
if (equals(name, ".")) if (equals(name, "."))
return find_node_aux(current, ++itr, create, last_index); return find_node_aux(current, ++itr, create, last_index);
if (equals(name, "..")) { if (equals(name, "..")) {
@@ -1027,17 +1036,22 @@ SGPropertyNode::getDisplayName (bool simplify) const
} }
const char * string
SGPropertyNode::getPath (bool simplify) const SGPropertyNode::getPath (bool simplify) const
{ {
// Calculate the complete path only once. typedef std::vector<SGConstPropertyNode_ptr> PList;
if (_parent != 0 && _path.empty()) { PList pathList;
_path = _parent->getPath(simplify); for (const SGPropertyNode* node = this; node->_parent; node = node->_parent)
_path += '/'; pathList.push_back(node);
_path += getDisplayName(simplify); string result;
for (PList::reverse_iterator itr = pathList.rbegin(),
rend = pathList.rend();
itr != rend;
++itr) {
result += '/';
result += (*itr)->getDisplayName(simplify);
} }
return result;
return _path.c_str();
} }
props::Type props::Type
+1 -2
View File
@@ -994,7 +994,7 @@ public:
/** /**
* Get the path to this node from the root. * Get the path to this node from the root.
*/ */
const char * getPath (bool simplify = false) const; std::string getPath (bool simplify = false) const;
/** /**
@@ -1675,7 +1675,6 @@ private:
simgear::PropertyList _children; simgear::PropertyList _children;
simgear::PropertyList _removedChildren; simgear::PropertyList _removedChildren;
std::vector<hash_table *> _linkedNodes; std::vector<hash_table *> _linkedNodes;
mutable std::string _path;
mutable std::string _buffer; mutable std::string _buffer;
hash_table * _path_cache; hash_table * _path_cache;
simgear::props::Type _type; simgear::props::Type _type;
+6
View File
@@ -130,6 +130,12 @@ public:
inline const SGGeod& get_target() const { return pos; } inline const SGGeod& get_target() const { return pos; }
/**
*
*/
inline void setTargetAltFt(double elev)
{ pos.setElevationFt(elev); }
/** /**
* This value is not calculated by this class. It is simply a * This value is not calculated by this class. It is simply a
* placeholder for the user to stash a distance value. This is useful * placeholder for the user to stash a distance value. This is useful
+6 -6
View File
@@ -148,9 +148,9 @@ private:
osg::Geometry* geometry = new osg::Geometry; osg::Geometry* geometry = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array; osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(triangle.getVertex(0).osg()); vertices->push_back(toOsg(triangle.getVertex(0)));
vertices->push_back(triangle.getVertex(1).osg()); vertices->push_back(toOsg(triangle.getVertex(1)));
vertices->push_back(triangle.getVertex(2).osg()); vertices->push_back(toOsg(triangle.getVertex(2)));
osg::Vec4Array* colors = new osg::Vec4Array; osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(color); colors->push_back(color);
@@ -172,7 +172,7 @@ private:
return; return;
SGSphered sphere = node.getBoundingSphere(); SGSphered sphere = node.getBoundingSphere();
osg::Sphere* shape = new osg::Sphere; osg::Sphere* shape = new osg::Sphere;
shape->setCenter(SGVec3f(sphere.getCenter()).osg()); shape->setCenter(toOsg(sphere.getCenter()));
shape->setRadius(sphere.getRadius()); shape->setRadius(sphere.getRadius());
addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f)); addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f));
} }
@@ -184,8 +184,8 @@ private:
BVHBoundingBoxVisitor bbv; BVHBoundingBoxVisitor bbv;
node.accept(bbv, data); node.accept(bbv, data);
osg::Box* shape = new osg::Box; osg::Box* shape = new osg::Box;
shape->setCenter(bbv.getBox().getCenter().osg()); shape->setCenter(toOsg(bbv.getBox().getCenter()));
shape->setHalfLengths((0.5*bbv.getBox().getSize()).osg()); shape->setHalfLengths(toOsg((0.5*bbv.getBox().getSize())));
addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f)); addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f));
} }
+229 -34
View File
@@ -51,6 +51,7 @@
#include <osg/RenderInfo> #include <osg/RenderInfo>
#include <osg/ShadeModel> #include <osg/ShadeModel>
#include <osg/StateSet> #include <osg/StateSet>
#include <osg/Stencil>
#include <osg/TexEnv> #include <osg/TexEnv>
#include <osg/Texture1D> #include <osg/Texture1D>
#include <osg/Texture2D> #include <osg/Texture2D>
@@ -65,6 +66,7 @@
#include <osgDB/ReadFile> #include <osgDB/ReadFile>
#include <osgDB/Registry> #include <osgDB/Registry>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/tgdb/userdata.hxx> #include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
@@ -96,6 +98,8 @@ Effect::Effect(const Effect& rhs, const CopyOp& copyop)
itr != end; itr != end;
++itr) ++itr)
techniques.push_back(static_cast<Technique*>(copyop(itr->get()))); techniques.push_back(static_cast<Technique*>(copyop(itr->get())));
generator = rhs.generator;
} }
// Assume that the last technique is always valid. // Assume that the last technique is always valid.
@@ -108,6 +112,13 @@ StateSet* Effect::getDefaultStateSet()
return pass; return pass;
} }
int Effect::getGenerator(Effect::Generator what) const
{
std::map<Generator,int>::const_iterator it = generator.find(what);
if(it == generator.end()) return -1;
else return it->second;
}
// There should always be a valid technique in an effect. // There should always be a valid technique in an effect.
Technique* Effect::chooseTechnique(RenderInfo* info) Technique* Effect::chooseTechnique(RenderInfo* info)
@@ -142,7 +153,7 @@ Effect::~Effect()
} }
void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop, void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
Pass* pass = new Pass; Pass* pass = new Pass;
tniq->passes.push_back(pass); tniq->passes.push_back(pass);
@@ -158,6 +169,10 @@ void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
} }
} }
// Default names for vector property components
const char* vec3Names[] = {"x", "y", "z"};
const char* vec4Names[] = {"x", "y", "z", "w"};
osg::Vec4f getColor(const SGPropertyNode* prop) osg::Vec4f getColor(const SGPropertyNode* prop)
{ {
if (prop->nChildren() == 0) { if (prop->nChildren() == 0) {
@@ -187,12 +202,12 @@ osg::Vec4f getColor(const SGPropertyNode* prop)
struct LightingBuilder : public PassAttributeBuilder struct LightingBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
void LightingBuilder::buildAttribute(Effect* effect, Pass* pass, void LightingBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -206,7 +221,7 @@ InstallAttributeBuilder<LightingBuilder> installLighting("lighting");
struct ShadeModelBuilder : public PassAttributeBuilder struct ShadeModelBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -228,7 +243,7 @@ InstallAttributeBuilder<ShadeModelBuilder> installShadeModel("shade-model");
struct CullFaceBuilder : PassAttributeBuilder struct CullFaceBuilder : PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) { if (!realProp) {
@@ -253,6 +268,24 @@ struct CullFaceBuilder : PassAttributeBuilder
InstallAttributeBuilder<CullFaceBuilder> installCullFace("cull-face"); InstallAttributeBuilder<CullFaceBuilder> installCullFace("cull-face");
struct ColorMaskBuilder : PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const SGReaderWriterXMLOptions* options)
{
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp)
return;
ColorMask *mask = new ColorMask;
Vec4 m = getColor(realProp);
mask->setMask(m.r(), m.g(), m.b(), m.a());
pass->setAttributeAndModes(mask);
}
};
InstallAttributeBuilder<ColorMaskBuilder> installColorMask("color-mask");
EffectNameValue<StateSet::RenderingHint> renderingHintInit[] = EffectNameValue<StateSet::RenderingHint> renderingHintInit[] =
{ {
{ "default", StateSet::DEFAULT_BIN }, { "default", StateSet::DEFAULT_BIN },
@@ -265,7 +298,7 @@ EffectPropertyMap<StateSet::RenderingHint> renderingHints(renderingHintInit);
struct HintBuilder : public PassAttributeBuilder struct HintBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -281,7 +314,7 @@ InstallAttributeBuilder<HintBuilder> installHint("rendering-hint");
struct RenderBinBuilder : public PassAttributeBuilder struct RenderBinBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -308,7 +341,7 @@ InstallAttributeBuilder<RenderBinBuilder> installRenderBin("render-bin");
struct MaterialBuilder : public PassAttributeBuilder struct MaterialBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
EffectNameValue<Material::ColorMode> colorModeInit[] = EffectNameValue<Material::ColorMode> colorModeInit[] =
@@ -324,7 +357,7 @@ EffectPropertyMap<Material::ColorMode> colorModes(colorModeInit);
void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass, void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -394,7 +427,7 @@ EffectPropertyMap<BlendFunc::BlendFuncMode> blendFuncModes(blendFuncModesInit);
struct BlendBuilder : public PassAttributeBuilder struct BlendBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -475,6 +508,99 @@ struct BlendBuilder : public PassAttributeBuilder
InstallAttributeBuilder<BlendBuilder> installBlend("blend"); InstallAttributeBuilder<BlendBuilder> installBlend("blend");
EffectNameValue<Stencil::Function> stencilFunctionInit[] =
{
{"never", Stencil::NEVER },
{"less", Stencil::LESS},
{"equal", Stencil::EQUAL},
{"less-or-equal", Stencil::LEQUAL},
{"greater", Stencil::GREATER},
{"not-equal", Stencil::NOTEQUAL},
{"greater-or-equal", Stencil::GEQUAL},
{"always", Stencil::ALWAYS}
};
EffectPropertyMap<Stencil::Function> stencilFunction(stencilFunctionInit);
EffectNameValue<Stencil::Operation> stencilOperationInit[] =
{
{"keep", Stencil::KEEP},
{"zero", Stencil::ZERO},
{"replace", Stencil::REPLACE},
{"increase", Stencil::INCR},
{"decrease", Stencil::DECR},
{"invert", Stencil::INVERT},
{"increase-wrap", Stencil::INCR_WRAP},
{"decrease-wrap", Stencil::DECR_WRAP}
};
EffectPropertyMap<Stencil::Operation> stencilOperation(stencilOperationInit);
struct StencilBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
const SGPropertyNode* pmode = getEffectPropertyChild(effect, prop,
"mode");
if (pmode && !pmode->getValue<bool>()) {
pass->setMode(GL_STENCIL, StateAttribute::OFF);
return;
}
const SGPropertyNode* pfunction
= getEffectPropertyChild(effect, prop, "function");
const SGPropertyNode* pvalue
= getEffectPropertyChild(effect, prop, "value");
const SGPropertyNode* pmask
= getEffectPropertyChild(effect, prop, "mask");
const SGPropertyNode* psfail
= getEffectPropertyChild(effect, prop, "stencil-fail");
const SGPropertyNode* pzfail
= getEffectPropertyChild(effect, prop, "z-fail");
const SGPropertyNode* ppass
= getEffectPropertyChild(effect, prop, "pass");
Stencil::Function func = Stencil::ALWAYS; // Always pass
int ref = 0;
unsigned int mask = ~0u; // All bits on
Stencil::Operation sfailop = Stencil::KEEP; // Keep the old values as default
Stencil::Operation zfailop = Stencil::KEEP;
Stencil::Operation passop = Stencil::KEEP;
ref_ptr<Stencil> stencilFunc = new Stencil;
if (pfunction)
findAttr(stencilFunction, pfunction, func);
if (pvalue)
ref = pvalue->getIntValue();
if (pmask)
mask = pmask->getIntValue();
if (psfail)
findAttr(stencilOperation, psfail, sfailop);
if (pzfail)
findAttr(stencilOperation, pzfail, zfailop);
if (ppass)
findAttr(stencilOperation, ppass, passop);
// Set the stencil operation
stencilFunc->setFunction(func, ref, mask);
// Set the operation, s-fail, s-pass/z-fail, s-pass/z-pass
stencilFunc->setOperation(sfailop, zfailop, passop);
// Add the operation to pass
pass->setAttributeAndModes(stencilFunc.get());
}
};
InstallAttributeBuilder<StencilBuilder> installStencil("stencil");
EffectNameValue<AlphaFunc::ComparisonFunction> alphaComparisonInit[] = EffectNameValue<AlphaFunc::ComparisonFunction> alphaComparisonInit[] =
{ {
{"never", AlphaFunc::NEVER}, {"never", AlphaFunc::NEVER},
@@ -492,7 +618,7 @@ alphaComparison(alphaComparisonInit);
struct AlphaTestBuilder : public PassAttributeBuilder struct AlphaTestBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -603,18 +729,41 @@ void reload_shaders()
struct ShaderProgramBuilder : PassAttributeBuilder struct ShaderProgramBuilder : PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
EffectNameValue<GLint> geometryInputTypeInit[] =
{
{"points", GL_POINTS},
{"lines", GL_LINES},
{"lines-adjacency", GL_LINES_ADJACENCY_EXT},
{"triangles", GL_TRIANGLES},
{"triangles-adjacency", GL_TRIANGLES_ADJACENCY_EXT},
};
EffectPropertyMap<GLint>
geometryInputType(geometryInputTypeInit);
EffectNameValue<GLint> geometryOutputTypeInit[] =
{
{"points", GL_POINTS},
{"line-strip", GL_LINE_STRIP},
{"triangle-strip", GL_TRIANGLE_STRIP}
};
EffectPropertyMap<GLint>
geometryOutputType(geometryOutputTypeInit);
void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* const SGReaderWriterXMLOptions*
options) options)
{ {
using namespace boost; using namespace boost;
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
PropertyList pVertShaders = prop->getChildren("vertex-shader"); PropertyList pVertShaders = prop->getChildren("vertex-shader");
PropertyList pGeomShaders = prop->getChildren("geometry-shader");
PropertyList pFragShaders = prop->getChildren("fragment-shader"); PropertyList pFragShaders = prop->getChildren("fragment-shader");
PropertyList pAttributes = prop->getChildren("attribute"); PropertyList pAttributes = prop->getChildren("attribute");
ProgramKey prgKey; ProgramKey prgKey;
@@ -624,6 +773,12 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
++itr) ++itr)
prgKey.shaders.push_back(ShaderKey((*itr)->getStringValue(), prgKey.shaders.push_back(ShaderKey((*itr)->getStringValue(),
Shader::VERTEX)); Shader::VERTEX));
for (PropertyList::iterator itr = pGeomShaders.begin(),
e = pGeomShaders.end();
itr != e;
++itr)
prgKey.shaders.push_back(ShaderKey((*itr)->getStringValue(),
Shader::GEOMETRY));
for (PropertyList::iterator itr = pFragShaders.begin(), for (PropertyList::iterator itr = pFragShaders.begin(),
e = pFragShaders.end(); e = pFragShaders.end();
itr != e; itr != e;
@@ -655,7 +810,7 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
// Add vertex shaders, then fragment shaders // Add vertex shaders, then fragment shaders
PropertyList& pvec = pVertShaders; PropertyList& pvec = pVertShaders;
Shader::Type stype = Shader::VERTEX; Shader::Type stype = Shader::VERTEX;
for (int i = 0; i < 2; ++i) { for (int i = 0; i < 3; ++i) {
for (PropertyList::iterator nameItr = pvec.begin(), e = pvec.end(); for (PropertyList::iterator nameItr = pvec.begin(), e = pvec.end();
nameItr != e; nameItr != e;
++nameItr) { ++nameItr) {
@@ -676,12 +831,34 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
} }
} }
} }
if (i == 0) {
pvec = pGeomShaders;
stype = Shader::GEOMETRY;
} else {
pvec = pFragShaders; pvec = pFragShaders;
stype = Shader::FRAGMENT; stype = Shader::FRAGMENT;
} }
}
BOOST_FOREACH(const ProgramKey::AttribKey& key, prgKey.attributes) { BOOST_FOREACH(const ProgramKey::AttribKey& key, prgKey.attributes) {
program->addBindAttribLocation(key.first, key.second); program->addBindAttribLocation(key.first, key.second);
} }
const SGPropertyNode* pGeometryVerticesOut = getEffectPropertyChild(effect, prop, "geometry-vertices-out");
if ( pGeometryVerticesOut ) {
program->setParameter( GL_GEOMETRY_VERTICES_OUT_EXT, pGeometryVerticesOut->getIntValue() );
}
const SGPropertyNode* pGeometryInputType = getEffectPropertyChild(effect, prop, "geometry-input-type");
if ( pGeometryInputType ) {
GLint type;
findAttr( geometryInputType, pGeometryInputType->getStringValue(), type );
program->setParameter( GL_GEOMETRY_INPUT_TYPE_EXT, type );
}
const SGPropertyNode* pGeometryOutputType = getEffectPropertyChild(effect, prop, "geometry-output-type");
if ( pGeometryOutputType ) {
GLint type;
findAttr( geometryOutputType, pGeometryOutputType->getStringValue(), type );
program->setParameter( GL_GEOMETRY_OUTPUT_TYPE_EXT, type );
}
programMap.insert(ProgramMap::value_type(prgKey, program)); programMap.insert(ProgramMap::value_type(prgKey, program));
} }
pass->setAttributeAndModes(program); pass->setAttributeAndModes(program);
@@ -695,22 +872,24 @@ EffectNameValue<Uniform::Type> uniformTypesInit[] =
{"float-vec3", Uniform::FLOAT_VEC3}, {"float-vec3", Uniform::FLOAT_VEC3},
{"float-vec4", Uniform::FLOAT_VEC4}, {"float-vec4", Uniform::FLOAT_VEC4},
{"sampler-1d", Uniform::SAMPLER_1D}, {"sampler-1d", Uniform::SAMPLER_1D},
{"sampler-1d-shadow", Uniform::SAMPLER_1D_SHADOW},
{"sampler-2d", Uniform::SAMPLER_2D}, {"sampler-2d", Uniform::SAMPLER_2D},
{"sampler-3d", Uniform::SAMPLER_3D} {"sampler-2d-shadow", Uniform::SAMPLER_2D_SHADOW},
{"sampler-3d", Uniform::SAMPLER_3D},
{"sampler-cube", Uniform::SAMPLER_CUBE}
}; };
EffectPropertyMap<Uniform::Type> uniformTypes(uniformTypesInit); EffectPropertyMap<Uniform::Type> uniformTypes(uniformTypesInit);
struct UniformBuilder :public PassAttributeBuilder struct UniformBuilder :public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
const SGPropertyNode* nameProp = prop->getChild("name"); const SGPropertyNode* nameProp = prop->getChild("name");
const SGPropertyNode* typeProp = prop->getChild("type"); const SGPropertyNode* typeProp = prop->getChild("type");
const SGPropertyNode* valProp const SGPropertyNode* valProp = prop->getChild("value");
= getEffectPropertyChild(effect, prop, "value");
string name; string name;
Uniform::Type uniformType = Uniform::FLOAT; Uniform::Type uniformType = Uniform::FLOAT;
if (nameProp) { if (nameProp) {
@@ -749,18 +928,29 @@ struct UniformBuilder :public PassAttributeBuilder
uniform->setType(uniformType); uniform->setType(uniformType);
switch (uniformType) { switch (uniformType) {
case Uniform::FLOAT: case Uniform::FLOAT:
uniform->set(valProp->getValue<float>()); initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
options);
break; break;
case Uniform::FLOAT_VEC3: case Uniform::FLOAT_VEC3:
uniform->set(toOsg(valProp->getValue<SGVec3d>())); initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec3&)>(&Uniform::set),
vec3Names, options);
break; break;
case Uniform::FLOAT_VEC4: case Uniform::FLOAT_VEC4:
uniform->set(toOsg(valProp->getValue<SGVec4d>())); initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(const Vec4&)>(&Uniform::set),
vec4Names, options);
break; break;
case Uniform::SAMPLER_1D: case Uniform::SAMPLER_1D:
case Uniform::SAMPLER_2D: case Uniform::SAMPLER_2D:
case Uniform::SAMPLER_3D: case Uniform::SAMPLER_3D:
uniform->set(valProp->getValue<int>()); case Uniform::SAMPLER_1D_SHADOW:
case Uniform::SAMPLER_2D_SHADOW:
case Uniform::SAMPLER_CUBE:
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(int)>(&Uniform::set),
options);
break; break;
default: // avoid compiler warning default: // avoid compiler warning
break; break;
@@ -777,7 +967,7 @@ InstallAttributeBuilder<UniformBuilder> installUniform("uniform");
struct NameBuilder : public PassAttributeBuilder struct NameBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
// name can't use <use> // name can't use <use>
string name = prop->getStringValue(); string name = prop->getStringValue();
@@ -799,7 +989,7 @@ EffectPropertyMap<PolygonMode::Mode> polygonModeModes(polygonModeModesInit);
struct PolygonModeBuilder : public PassAttributeBuilder struct PolygonModeBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -827,7 +1017,7 @@ InstallAttributeBuilder<PolygonModeBuilder> installPolygonMode("polygon-mode");
struct VertexProgramTwoSideBuilder : public PassAttributeBuilder struct VertexProgramTwoSideBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -844,7 +1034,7 @@ installTwoSide("vertex-program-two-side");
struct VertexProgramPointSizeBuilder : public PassAttributeBuilder struct VertexProgramPointSizeBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) if (!realProp)
@@ -874,7 +1064,7 @@ EffectPropertyMap<Depth::Function> depthFunction(depthFunctionInit);
struct DepthBuilder : public PassAttributeBuilder struct DepthBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -905,7 +1095,7 @@ struct DepthBuilder : public PassAttributeBuilder
InstallAttributeBuilder<DepthBuilder> installDepth("depth"); InstallAttributeBuilder<DepthBuilder> installDepth("depth");
void buildTechnique(Effect* effect, const SGPropertyNode* prop, void buildTechnique(Effect* effect, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
Technique* tniq = new Technique; Technique* tniq = new Technique;
effect->techniques.push_back(tniq); effect->techniques.push_back(tniq);
@@ -1011,7 +1201,7 @@ bool makeParametersFromStateSet(SGPropertyNode* effectRoot, const StateSet* ss)
// Walk the techniques property tree, building techniques and // Walk the techniques property tree, building techniques and
// passes. // passes.
bool Effect::realizeTechniques(const osgDB::ReaderWriter::Options* options) bool Effect::realizeTechniques(const SGReaderWriterXMLOptions* options)
{ {
if (_isRealized) if (_isRealized)
return true; return true;
@@ -1089,14 +1279,15 @@ osgDB::RegisterDotOsgWrapperProxy effectProxy
} }
// Property expressions for technique predicates // Property expressions for technique predicates
class PropertyExpression : public SGExpression<bool> template<typename T>
class PropertyExpression : public SGExpression<T>
{ {
public: public:
PropertyExpression(SGPropertyNode* pnode) : _pnode(pnode) {} PropertyExpression(SGPropertyNode* pnode) : _pnode(pnode) {}
void eval(bool& value, const expression::Binding*) const void eval(T& value, const expression::Binding*) const
{ {
value = _pnode->getValue<bool>(); value = _pnode->getValue<T>();
} }
protected: protected:
SGPropertyNode_ptr _pnode; SGPropertyNode_ptr _pnode;
@@ -1115,12 +1306,13 @@ protected:
osg::ref_ptr<Technique> _tniq; osg::ref_ptr<Technique> _tniq;
}; };
template<typename T>
Expression* propertyExpressionParser(const SGPropertyNode* exp, Expression* propertyExpressionParser(const SGPropertyNode* exp,
expression::Parser* parser) expression::Parser* parser)
{ {
SGPropertyNode_ptr pnode = getPropertyRoot()->getNode(exp->getStringValue(), SGPropertyNode_ptr pnode = getPropertyRoot()->getNode(exp->getStringValue(),
true); true);
PropertyExpression* pexp = new PropertyExpression(pnode); PropertyExpression<T>* pexp = new PropertyExpression<T>(pnode);
TechniquePredParser* predParser TechniquePredParser* predParser
= dynamic_cast<TechniquePredParser*>(parser); = dynamic_cast<TechniquePredParser*>(parser);
if (predParser) if (predParser)
@@ -1130,6 +1322,9 @@ Expression* propertyExpressionParser(const SGPropertyNode* exp,
} }
expression::ExpParserRegistrar propertyRegistrar("property", expression::ExpParserRegistrar propertyRegistrar("property",
propertyExpressionParser); propertyExpressionParser<bool>);
expression::ExpParserRegistrar propvalueRegistrar("float-property",
propertyExpressionParser<float>);
} }
+17 -4
View File
@@ -45,6 +45,7 @@ namespace simgear
{ {
class Technique; class Technique;
class Effect; class Effect;
class SGReaderWriterXMLOptions;
/** /**
* Object to be initialized at some point after an effect -- and its * Object to be initialized at some point after an effect -- and its
@@ -79,6 +80,18 @@ public:
Effect(const Effect& rhs, Effect(const Effect& rhs,
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY); const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
osg::StateSet* getDefaultStateSet(); osg::StateSet* getDefaultStateSet();
// Define what needs to be generated for this effect
enum Generator
{
NORMAL,
TANGENT,
BINORMAL
};
void setGenerator(Generator what, int where) { generator[what] = where; }
int getGenerator(Generator what) const; // Returns -1 if generator should not be used
std::map<Generator, int> generator; // What is generated into which attribute location
std::vector<osg::ref_ptr<Technique> > techniques; std::vector<osg::ref_ptr<Technique> > techniques;
SGPropertyNode_ptr root; SGPropertyNode_ptr root;
// Pointer to the parameters node, if it exists // Pointer to the parameters node, if it exists
@@ -89,7 +102,7 @@ public:
/** /**
* Build the techniques from the effect properties. * Build the techniques from the effect properties.
*/ */
bool realizeTechniques(const osgDB::ReaderWriter::Options* options = 0); bool realizeTechniques(const SGReaderWriterXMLOptions* options = 0);
/** /**
* Updaters that should be derefed when the effect is * Updaters that should be derefed when the effect is
* deleted. Updaters arrange to be run by listening on properties * deleted. Updaters arrange to be run by listening on properties
@@ -144,7 +157,7 @@ protected:
Cache* _cache; Cache* _cache;
friend size_t hash_value(const Key& key); friend size_t hash_value(const Key& key);
friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques, friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
bool _isRealized; bool _isRealized;
}; };
// Automatic support for boost hash function // Automatic support for boost hash function
@@ -153,11 +166,11 @@ size_t hash_value(const Effect::Key&);
Effect* makeEffect(const std::string& name, Effect* makeEffect(const std::string& name,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options = 0); const SGReaderWriterXMLOptions* options = 0);
Effect* makeEffect(SGPropertyNode* prop, Effect* makeEffect(SGPropertyNode* prop,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options = 0); const SGReaderWriterXMLOptions* options = 0);
bool makeParametersFromStateSet(SGPropertyNode* paramRoot, bool makeParametersFromStateSet(SGPropertyNode* paramRoot,
const osg::StateSet* ss); const osg::StateSet* ss);
+18 -1
View File
@@ -2,6 +2,7 @@
# include <simgear_config.h> # include <simgear_config.h>
#endif #endif
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/tgdb/userdata.hxx> #include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
@@ -41,13 +42,29 @@ const SGPropertyNode* getEffectPropertyChild(Effect* effect,
return getEffectPropertyNode(effect, child); return getEffectPropertyNode(effect, child);
} }
string getGlobalProperty(const SGPropertyNode* prop) string getGlobalProperty(const SGPropertyNode* prop,
const SGReaderWriterXMLOptions* options)
{ {
if (!prop) if (!prop)
return string(); return string();
const SGPropertyNode* useProp = prop->getChild("use"); const SGPropertyNode* useProp = prop->getChild("use");
if (!useProp) if (!useProp)
return string(); return string();
string propName = useProp->getStringValue();
SGPropertyNode_ptr propRoot;
if (propName[0] == '/') {
return propName;
} else if ((propRoot = options->getPropRoot())) {
string result = propRoot->getPath();
result.append("/");
result.append(propName);
return result;
} else {
throw effect::
BuilderException("No property root to use with relative name "
+ propName);
}
return useProp->getStringValue(); return useProp->getStringValue();
} }
+260 -58
View File
@@ -33,6 +33,7 @@
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
#include <simgear/props/AtomicChangeListener.hxx> #include <simgear/props/AtomicChangeListener.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/Singleton.hxx> #include <simgear/structure/Singleton.hxx>
@@ -46,6 +47,7 @@ namespace simgear
{ {
class Effect; class Effect;
class Pass; class Pass;
class SGReaderWriterXMLOptions;
/** /**
* Builder that returns an object, probably an OSG object. * Builder that returns an object, probably an OSG object.
@@ -56,10 +58,10 @@ class EffectBuilder : public SGReferenced
public: public:
virtual ~EffectBuilder() {} virtual ~EffectBuilder() {}
virtual T* build(Effect* effect, const SGPropertyNode*, virtual T* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options) = 0; const SGReaderWriterXMLOptions* options) = 0;
static T* buildFromType(Effect* effect, const std::string& type, static T* buildFromType(Effect* effect, const std::string& type,
const SGPropertyNode*props, const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
BuilderMap& builderMap = getMap(); BuilderMap& builderMap = getMap();
typename BuilderMap::iterator iter = builderMap.find(type); typename BuilderMap::iterator iter = builderMap.find(type);
@@ -154,6 +156,21 @@ EffectPropertyMap<T>::EffectPropertyMap(const EffectNameValue<T> (&attrs)[N])
_map.insert(typename BMap::value_type(attrs[i].first, attrs[i].second)); _map.insert(typename BMap::value_type(attrs[i].first, attrs[i].second));
} }
// A one-way map that can be initialized using an array
template<typename T>
struct SimplePropertyMap
{
typedef std::map<string, T> map_type;
map_type _map;
template<int N>
SimplePropertyMap(const EffectNameValue<T> (&attrs)[N])
{
for (int i = 0; i < N; ++i)
_map.insert(typename map_type::value_type(attrs[i].first,
attrs[i].second));
}
};
class BuilderException : public sg_exception class BuilderException : public sg_exception
{ {
public: public:
@@ -201,6 +218,42 @@ void findAttr(const effect::EffectPropertyMap<T>& pMap,
findAttr(pMap, name, result); findAttr(pMap, name, result);
} }
// Versions that don't throw an error
template<typename T>
const T* findAttr(const effect::EffectPropertyMap<T>& pMap,
const char* name)
{
using namespace effect;
typename EffectPropertyMap<T>::BMap::iterator itr
= pMap._map.get<from>().find(name);
if (itr == pMap._map.end())
return 0;
else
return &itr->second;
}
template<typename T>
const T* findAttr(const effect::SimplePropertyMap<T>& pMap,
const char* name)
{
using namespace effect;
typename SimplePropertyMap<T>::map_type::const_iterator itr
= pMap._map.find(name);
if (itr == pMap._map.end())
return 0;
else
return &itr->second;
}
template<typename T, template<class> class Map>
const T* findAttr(const Map<T>& pMap,
const std::string& name)
{
return findAttr(pMap, name.c_str());
}
template<typename T> template<typename T>
std::string findName(const effect::EffectPropertyMap<T>& pMap, T value) std::string findName(const effect::EffectPropertyMap<T>& pMap, T value)
{ {
@@ -240,7 +293,45 @@ const SGPropertyNode* getEffectPropertyChild(Effect* effect,
* @return empty if prop doesn't contain a <use> clause; otherwise the * @return empty if prop doesn't contain a <use> clause; otherwise the
* mentioned node name. * mentioned node name.
*/ */
std::string getGlobalProperty(const SGPropertyNode* prop); std::string getGlobalProperty(const SGPropertyNode* prop,
const SGReaderWriterXMLOptions *);
template<typename NameItr>
std::vector<std::string>
getVectorProperties(const SGPropertyNode* prop,
const SGReaderWriterXMLOptions *options, size_t vecSize,
NameItr defaultNames)
{
using namespace std;
vector<string> result;
if (!prop)
return result;
PropertyList useProps = prop->getChildren("use");
if (useProps.size() == 1) {
string parentName = useProps[0]->getStringValue();
if (parentName.size() == 0 || parentName[0] != '/')
parentName = options->getPropRoot()->getPath() + "/" + parentName;
if (parentName[parentName.size() - 1] != '/')
parentName.append("/");
NameItr itr = defaultNames;
for (int i = 0; i < vecSize; ++i, ++itr)
result.push_back(parentName + *itr);
} else if (useProps.size() == vecSize) {
string parentName = useProps[0]->getStringValue();
parentName += "/";
for (PropertyList::const_iterator itr = useProps.begin(),
end = useProps.end();
itr != end;
++itr) {
string childName = (*itr)->getStringValue();
if (childName.size() == 0 || childName[0] != '/')
result.push_back(parentName + childName);
else
result.push_back(childName);
}
}
return result;
}
class PassAttributeBuilder : public SGReferenced class PassAttributeBuilder : public SGReferenced
{ {
@@ -255,7 +346,7 @@ protected:
public: public:
virtual void buildAttribute(Effect* effect, Pass* pass, virtual void buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
= 0; = 0;
static PassAttributeBuilder* find(const std::string& str) static PassAttributeBuilder* find(const std::string& str)
{ {
@@ -289,64 +380,116 @@ bool isAttributeActive(Effect* effect, const SGPropertyNode* prop);
namespace effect namespace effect
{ {
/** /**
* Bridge between types stored in properties and what OSG wants. * Bridge between types stored in properties and what OSG or the
* effects code want.
*/ */
template<typename T> struct OSGBridge; template<typename T> struct Bridge;
/**
* Default just passes on the same type.
*
*/
template<typename T>
struct Bridge
{
typedef T sg_type;
static T get(const T& val) { return val; }
};
template<typename T> template<typename T>
struct OSGBridge<const T> : public OSGBridge<T> struct Bridge<const T> : public Bridge<T>
{
};
// Save some typing...
template<typename InType, typename OutType>
struct BridgeOSGVec
{
typedef InType sg_type;
static OutType get(const InType& val) { return toOsg(val); }
};
template<>
struct Bridge<osg::Vec3f> : public BridgeOSGVec<SGVec3d, osg::Vec3f>
{ {
}; };
template<> template<>
struct OSGBridge<osg::Vec3f> struct Bridge<osg::Vec3d> : public BridgeOSGVec<SGVec3d, osg::Vec3d>
{ {
typedef SGVec3d sg_type;
static osg::Vec3f getOsgType(const SGVec3d& val) { return toOsg(val); }
}; };
template<> template<>
struct OSGBridge<osg::Vec3d> struct Bridge<osg::Vec4f> : public BridgeOSGVec<SGVec4d, osg::Vec4f>
{ {
typedef SGVec3d sg_type;
static osg::Vec3d getOsgType(const SGVec3d& val) { return toOsg(val); }
}; };
template<> template<>
struct OSGBridge<osg::Vec4f> struct Bridge<osg::Vec4d> : public BridgeOSGVec<SGVec4d, osg::Vec4d>
{ {
typedef SGVec4d sg_type;
static osg::Vec4f getOsgType(const SGVec4d& val) { return toOsg(val); }
}; };
template<> /**
struct OSGBridge<osg::Vec4d> * Functor for calling a function on an osg::Referenced object and a
* value (e.g., an SGVec4d from a property) which will be converted to
* the equivalent OSG type.
*
* General version, function takes obj, val
*/
template<typename OSGParam, typename Obj, typename Func>
struct OSGFunctor : public Bridge<OSGParam>
{ {
typedef SGVec4d sg_type; OSGFunctor(Obj* obj, const Func& func)
static osg::Vec4d getOsgType(const SGVec4d& val) { return toOsg(val); }
};
template<typename Obj, typename OSGParam>
struct OSGFunctor : public OSGBridge<OSGParam>
{
OSGFunctor(Obj* obj, void (Obj::*func)(const OSGParam&))
: _obj(obj), _func(func) {} : _obj(obj), _func(func) {}
void operator()(const typename OSGBridge<OSGParam>::sg_type& val) const void operator()(const typename Bridge<OSGParam>::sg_type& val) const
{ {
((_obj.get())->*_func)(this->getOsgType(val)); _func(_obj, this->get(val));
} }
osg::ref_ptr<Obj>_obj; osg::ref_ptr<Obj>_obj;
void (Obj::*_func)(const OSGParam&); const Func _func;
}; };
template<typename ObjType, typename OSGParamType> /**
* Version which uses a pointer to member function instead.
*/
template<typename OSGParam, typename Obj>
struct OSGFunctor<OSGParam, Obj, void (Obj::* const)(const OSGParam&)>
: public Bridge<OSGParam>
{
typedef void (Obj::*const MemFunc)(const OSGParam&);
OSGFunctor(Obj* obj, MemFunc func)
: _obj(obj), _func(func) {}
void operator()(const typename Bridge<OSGParam>::sg_type& val) const
{
(_obj->*_func)(this->get(val));
}
osg::ref_ptr<Obj>_obj;
MemFunc _func;
};
/**
* Typical convenience constructors
*/
template<typename OSGParam, typename Obj, typename Func>
OSGFunctor<OSGParam, Obj, Func> make_OSGFunctor(Obj* obj, const Func& func)
{
return OSGFunctor<OSGParam, Obj, Func>(obj, func);
}
template<typename OSGParam, typename Obj>
OSGFunctor<OSGParam, Obj, void (Obj::*const)(const OSGParam&)>
make_OSGFunctor(Obj* obj, void (Obj::*const func)(const OSGParam&))
{
return OSGFunctor<OSGParam, Obj,
void (Obj::* const)(const OSGParam&)>(obj, func);
}
template<typename OSGParamType, typename ObjType, typename F>
class ScalarChangeListener class ScalarChangeListener
: public SGPropertyChangeListener, public InitializeWhenAdded, : public SGPropertyChangeListener, public InitializeWhenAdded,
public Effect::Updater public Effect::Updater
{ {
public: public:
typedef void (ObjType::*setter_type)(const OSGParamType); ScalarChangeListener(ObjType* obj, const F& setter,
ScalarChangeListener(ObjType* obj, setter_type setter,
const std::string& propName) const std::string& propName)
: _obj(obj), _setter(setter) : _obj(obj), _setter(setter)
{ {
@@ -359,7 +502,7 @@ public:
} }
void valueChanged(SGPropertyNode* node) void valueChanged(SGPropertyNode* node)
{ {
_obj->*setter(node->getValue<OSGParamType>()); _setter(_obj.get(), node->getValue<OSGParamType>());
} }
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
{ {
@@ -371,7 +514,7 @@ public:
} }
private: private:
osg::ref_ptr<ObjType> _obj; osg::ref_ptr<ObjType> _obj;
setter_type _setter; F _setter;
std::string* _propName; std::string* _propName;
}; };
@@ -382,11 +525,12 @@ class EffectExtendedPropListener : public InitializeWhenAdded,
public: public:
template<typename Itr> template<typename Itr>
EffectExtendedPropListener(const Func& func, EffectExtendedPropListener(const Func& func,
const std::string& propName, Itr childNamesBegin, const std::string* propName, Itr childNamesBegin,
Itr childNamesEnd) Itr childNamesEnd)
: _func(func) : _propName(0), _func(func)
{ {
_propName = new std::string(propName); if (propName)
_propName = new std::string(*propName);
_childNames = new std::vector<std::string>(childNamesBegin, _childNames = new std::vector<std::string>(childNamesBegin,
childNamesEnd); childNamesEnd);
} }
@@ -397,7 +541,11 @@ public:
} }
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot) void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
{ {
SGPropertyNode* parent = propRoot->getNode(*_propName, true); SGPropertyNode* parent = 0;
if (_propName)
parent = propRoot->getNode(*_propName, true);
else
parent = propRoot;
_propListener _propListener
= new ExtendedPropListener<T, Func>(parent, _childNames->begin(), = new ExtendedPropListener<T, Func>(parent, _childNames->begin(),
_childNames->end(), _childNames->end(),
@@ -414,6 +562,15 @@ private:
Func _func; Func _func;
}; };
template<typename T, typename Func, typename Itr>
Effect::Updater*
new_EEPropListener(const Func& func, const std::string* propName,
const Itr& namesBegin, const Itr& namesEnd)
{
return new EffectExtendedPropListener<T, Func>
(func, 0, namesBegin, namesEnd);
}
/** /**
* Initialize the value and the possible updating of an effect * Initialize the value and the possible updating of an effect
* attribute. If the value is specified directly, set it. Otherwise, * attribute. If the value is specified directly, set it. Otherwise,
@@ -422,52 +579,97 @@ private:
* own <use> tag referring to a property in the global property tree; * own <use> tag referring to a property in the global property tree;
* install a change listener that will set the attribute when the * install a change listener that will set the attribute when the
* property changes. * property changes.
*
* For relative property names, the property root found in options is
* used.
*/ */
template<typename ObjType, typename OSGParamType> template<typename OSGParamType, typename ObjType, typename F>
void void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
void (ObjType::*setter)(const OSGParamType)) const F& setter, const SGReaderWriterXMLOptions* options)
{ {
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
if (!valProp) if (!valProp)
return; return;
if (valProp->nChildren() == 0) { if (valProp->nChildren() == 0) {
obj->*setter(valProp->getValue<OSGParamType>()); setter(obj, valProp->getValue<OSGParamType>());
} else { } else {
std::string propName = getGlobalProperty(prop); std::string propName = getGlobalProperty(valProp, options);
ScalarChangeListener<ObjType, OSGParamType>* listener ScalarChangeListener<OSGParamType, ObjType, F>* listener
= new ScalarChangeListener<ObjType, OSGParamType>(obj, setter, = new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
propName); propName);
effect->addUpdater(listener); effect->addUpdater(listener);
} }
} }
template<typename ObjType, typename OSGParamType, typename NameItrType> template<typename OSGParamType, typename ObjType, typename SetterReturn>
inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType),
const SGReaderWriterXMLOptions* options)
{
initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), options);
}
/*
* Initialize vector parameters from individual properties.
* The parameter may be updated at runtime.
*
* If the value is specified directly, set it. Otherwise, use the
* <use> tag to look at the parameters. Again, if there is a value
* there set it directly. Otherwise, the parameter contains one or several
* <use> tags. If there is one tag, it is a property that is the root
* for the values needed to update the parameter; nameIter holds the
* names of the properties relative to the root. If there are several
* <use> tags, they each hold the name of the property holding the
* value for the corresponding vector member.
*
* Install a change listener that will set the attribute when the
* property changes.
*
* For relative property names, the property root found in options is
* used.
*/
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename F>
void void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj, initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
void (ObjType::*setter)(const OSGParamType&), const F& setter,
NameItrType nameItr) NameItrType nameItr, const SGReaderWriterXMLOptions* options)
{ {
typedef typename OSGBridge<OSGParamType>::sg_type sg_type; typedef typename Bridge<OSGParamType>::sg_type sg_type;
const int numComponents = props::NumComponents<sg_type>::num_components;
const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop); const SGPropertyNode* valProp = getEffectPropertyNode(effect, prop);
if (!valProp) if (!valProp)
return; return;
if (valProp->nChildren() == 0) { if (valProp->nChildren() == 0) { // Has <use>?
(obj->*setter)(OSGBridge<OSGParamType> setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
::getOsgType(valProp->getValue<sg_type>()));
} else { } else {
string listenPropName = getGlobalProperty(valProp); std::vector<std::string> paramNames
if (listenPropName.empty()) = getVectorProperties(valProp, options,numComponents, nameItr);
return; if (paramNames.empty())
typedef OSGFunctor<ObjType, OSGParamType> Functor; throw BuilderException();
std::vector<std::string>::const_iterator pitr = paramNames.begin();
Effect::Updater* listener Effect::Updater* listener
= new EffectExtendedPropListener<sg_type, Functor> = new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
(Functor(obj, setter), listenPropName, nameItr, (obj, setter),
nameItr + props::NumComponents<sg_type>::num_components); 0, pitr, pitr + numComponents);
effect->addUpdater(listener); effect->addUpdater(listener);
} }
} }
template<typename OSGParamType, typename ObjType, typename NameItrType,
typename SetterReturn>
inline void
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
SetterReturn (ObjType::*setter)(const OSGParamType&),
NameItrType nameItr, const SGReaderWriterXMLOptions* options)
{
initFromParameters<OSGParamType>(effect, prop, obj,
boost::bind(setter, _1, _2), nameItr,
options);
}
extern const char* colorFields[]; extern const char* colorFields[];
} }
} }
+26
View File
@@ -23,6 +23,7 @@
#include "Technique.hxx" #include "Technique.hxx"
#include <osgUtil/CullVisitor> #include <osgUtil/CullVisitor>
#include <osgUtil/TangentSpaceGenerator>
#include <osgDB/Registry> #include <osgDB/Registry>
#include <osgDB/Input> #include <osgDB/Input>
@@ -66,6 +67,31 @@ void EffectGeode::releaseGLObjects(osg::State* state) const
Geode::releaseGLObjects(state); Geode::releaseGLObjects(state);
} }
// Generates tangent space vectors or other data from geom, as defined by effect
void EffectGeode::runGenerators(osg::Geometry *geometry)
{
if(geometry && _effect.valid()) {
// Generate tangent vectors for the geometry
osg::ref_ptr<osgUtil::TangentSpaceGenerator> tsg = new osgUtil::TangentSpaceGenerator;
// Generating only tangent vector should be enough
// since the binormal is a cross product of normal and tangent
// This saves a bit of memory & memory bandwidth!
int n = _effect->getGenerator(Effect::TANGENT);
tsg->generate(geometry, 0); // 0 is normal_unit, but I have no idea what that is!
if (n != -1 && !geometry->getVertexAttribArray(n))
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getTangentArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
n = _effect->getGenerator(Effect::BINORMAL);
if (n != -1 && !geometry->getVertexAttribArray(n))
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getBinormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
n = _effect->getGenerator(Effect::NORMAL);
if (n != -1 && !geometry->getVertexAttribArray(n))
geometry->setVertexAttribData(n, osg::Geometry::ArrayData(tsg->getNormalArray(), osg::Geometry::BIND_PER_VERTEX,GL_FALSE));
}
}
bool EffectGeode_writeLocalData(const Object& obj, osgDB::Output& fw) bool EffectGeode_writeLocalData(const Object& obj, osgDB::Output& fw)
{ {
const EffectGeode& eg = static_cast<const EffectGeode&>(obj); const EffectGeode& eg = static_cast<const EffectGeode&>(obj);
+1
View File
@@ -37,6 +37,7 @@ public:
typedef DrawableList::iterator DrawablesIterator; typedef DrawableList::iterator DrawablesIterator;
DrawablesIterator drawablesBegin() { return _drawables.begin(); } DrawablesIterator drawablesBegin() { return _drawables.begin(); }
DrawablesIterator drawablesEnd() { return _drawables.end(); } DrawablesIterator drawablesEnd() { return _drawables.end(); }
void runGenerators(osg::Geometry *geometry);
private: private:
osg::ref_ptr<Effect> _effect; osg::ref_ptr<Effect> _effect;
}; };
+1 -1
View File
@@ -30,6 +30,6 @@ libsgmaterial_a_SOURCES = \
mat.cxx \ mat.cxx \
matlib.cxx \ matlib.cxx \
matmodel.cxx \ matmodel.cxx \
Noise.cxx Noise.cxx Noise.hxx
INCLUDES = -I$(top_srcdir) INCLUDES = -I$(top_srcdir)
+1 -1
View File
@@ -59,7 +59,7 @@ Technique::Technique(bool alwaysValid)
Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) : Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) :
_contextMap(rhs._contextMap), _alwaysValid(rhs._alwaysValid), _contextMap(rhs._contextMap), _alwaysValid(rhs._alwaysValid),
_shadowingStateSet(copyop(rhs._shadowingStateSet)), _shadowingStateSet(copyop(rhs._shadowingStateSet.get())),
_validExpression(rhs._validExpression), _validExpression(rhs._validExpression),
_contextIdLocation(rhs._contextIdLocation) _contextIdLocation(rhs._contextIdLocation)
{ {
+130 -16
View File
@@ -29,12 +29,14 @@
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/Texture3D> #include <osg/Texture3D>
#include <osg/TextureRectangle> #include <osg/TextureRectangle>
#include <osg/TextureCubeMap>
#include <osgDB/FileUtils> #include <osgDB/FileUtils>
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include <boost/tuple/tuple.hpp> #include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp> #include <boost/tuple/tuple_comparison.hpp>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
@@ -50,13 +52,14 @@ using namespace osg;
using namespace effect; using namespace effect;
TexEnvCombine* buildTexEnvCombine(Effect* effect, TexEnvCombine* buildTexEnvCombine(Effect* effect,
const SGPropertyNode* envProp); const SGPropertyNode* envProp,
const SGReaderWriterXMLOptions* options);
TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp); TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
// Hack to force inclusion of TextureBuilder.cxx in library // Hack to force inclusion of TextureBuilder.cxx in library
osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type, osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
const SGPropertyNode*props, const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* const SGReaderWriterXMLOptions*
options) options)
{ {
return EffectBuilder<Texture>::buildFromType(effect, type, props, options); return EffectBuilder<Texture>::buildFromType(effect, type, props, options);
@@ -98,7 +101,7 @@ TexEnv* buildTexEnv(Effect* effect, const SGPropertyNode* prop)
void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass, void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, prop)) if (!isAttributeActive(effect, prop))
return; return;
@@ -141,7 +144,8 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
} }
const SGPropertyNode* combineProp = prop->getChild("texenv-combine"); const SGPropertyNode* combineProp = prop->getChild("texenv-combine");
TexEnvCombine* combiner = 0; TexEnvCombine* combiner = 0;
if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp)))) if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp,
options))))
pass->setTextureAttributeAndModes(unit, combiner); pass->setTextureAttributeAndModes(unit, combiner);
const SGPropertyNode* tgenProp = prop->getChild("texgen"); const SGPropertyNode* tgenProp = prop->getChild("texgen");
TexGen* tgen = 0; TexGen* tgen = 0;
@@ -177,7 +181,7 @@ EffectPropertyMap<Texture::WrapMode> wrapModes(wrapModesInit);
TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props, TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options, const SGReaderWriterXMLOptions* options,
const string& texType) const string& texType)
{ {
Texture::FilterMode minFilter = Texture::LINEAR_MIPMAP_LINEAR; Texture::FilterMode minFilter = Texture::LINEAR_MIPMAP_LINEAR;
@@ -213,7 +217,7 @@ TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
} }
void setAttrs(const TexTuple& attrs, Texture* tex, void setAttrs(const TexTuple& attrs, Texture* tex,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
const string& imageName = attrs.get<0>(); const string& imageName = attrs.get<0>();
if (imageName.empty()) { if (imageName.empty()) {
@@ -253,7 +257,7 @@ class TexBuilder : public TextureBuilder
public: public:
TexBuilder(const string& texType) : _type(texType) {} TexBuilder(const string& texType) : _type(texType) {}
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
protected: protected:
typedef map<TexTuple, ref_ptr<T> > TexMap; typedef map<TexTuple, ref_ptr<T> > TexMap;
TexMap texMap; TexMap texMap;
@@ -262,7 +266,7 @@ protected:
template<typename T> template<typename T>
Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props, Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
TexTuple attrs = makeTexTuple(effect, props, options, _type); TexTuple attrs = makeTexTuple(effect, props, options, _type);
typename TexMap::iterator itr = texMap.find(attrs); typename TexMap::iterator itr = texMap.find(attrs);
@@ -286,11 +290,11 @@ class WhiteTextureBuilder : public TextureBuilder
{ {
public: public:
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*, Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
return StateAttributeFactory::instance()->getWhiteTexture(); return StateAttributeFactory::instance()->getWhiteTexture();
} }
@@ -304,11 +308,11 @@ class TransparentTextureBuilder : public TextureBuilder
{ {
public: public:
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*, Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
return StateAttributeFactory::instance()->getTransparentTexture(); return StateAttributeFactory::instance()->getTransparentTexture();
} }
@@ -368,14 +372,14 @@ class NoiseBuilder : public TextureBuilder
{ {
public: public:
Texture* build(Effect* effect, const SGPropertyNode*, Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
protected: protected:
typedef map<int, ref_ptr<Texture3D> > NoiseMap; typedef map<int, ref_ptr<Texture3D> > NoiseMap;
NoiseMap _noises; NoiseMap _noises;
}; };
Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props, Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
int texSize = 64; int texSize = 64;
const SGPropertyNode* sizeProp = getEffectPropertyChild(effect, props, const SGPropertyNode* sizeProp = getEffectPropertyChild(effect, props,
@@ -401,6 +405,114 @@ namespace
TextureBuilder::Registrar installNoise("noise", new NoiseBuilder); TextureBuilder::Registrar installNoise("noise", new NoiseBuilder);
} }
// Image names for all sides
typedef boost::tuple<string, string, string, string, string, string> CubeMapTuple;
CubeMapTuple makeCubeMapTuple(Effect* effect, const SGPropertyNode* props)
{
const SGPropertyNode* ep = 0;
string positive_x;
if ((ep = getEffectPropertyChild(effect, props, "positive-x")))
positive_x = ep->getStringValue();
string negative_x;
if ((ep = getEffectPropertyChild(effect, props, "negative-x")))
negative_x = ep->getStringValue();
string positive_y;
if ((ep = getEffectPropertyChild(effect, props, "positive-y")))
positive_y = ep->getStringValue();
string negative_y;
if ((ep = getEffectPropertyChild(effect, props, "negative-y")))
negative_y = ep->getStringValue();
string positive_z;
if ((ep = getEffectPropertyChild(effect, props, "positive-z")))
positive_z = ep->getStringValue();
string negative_z;
if ((ep = getEffectPropertyChild(effect, props, "negative-z")))
negative_z = ep->getStringValue();
return CubeMapTuple(positive_x, negative_x, positive_y, negative_y, positive_z, negative_z);
}
class CubeMapBuilder : public TextureBuilder
{
public:
Texture* build(Effect* effect, const SGPropertyNode*,
const SGReaderWriterXMLOptions* options);
protected:
typedef map<CubeMapTuple, ref_ptr<TextureCubeMap> > CubeMap;
CubeMap _cubemaps;
};
Texture* CubeMapBuilder::build(Effect* effect, const SGPropertyNode* props,
const SGReaderWriterXMLOptions* options)
{
// First check that there is a <images> tag
const SGPropertyNode* texturesProp = getEffectPropertyChild(effect, props, "images");
if (!texturesProp) {
throw BuilderException("no <images> for cube map");
return NULL; // This is redundant
}
CubeMapTuple _tuple = makeCubeMapTuple(effect, texturesProp);
CubeMap::iterator itr = _cubemaps.find(_tuple);
if (itr != _cubemaps.end())
return itr->second.get();
TextureCubeMap* cubeTexture = new osg::TextureCubeMap;
// TODO: Read these from effect file? Maybe these are sane for all cuebmaps?
cubeTexture->setFilter(osg::Texture3D::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
cubeTexture->setFilter(osg::Texture3D::MAG_FILTER, osg::Texture::LINEAR);
cubeTexture->setWrap(osg::Texture3D::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
cubeTexture->setWrap(osg::Texture3D::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
cubeTexture->setWrap(osg::Texture3D::WRAP_R, osg::Texture::CLAMP_TO_EDGE);
osgDB::ReaderWriter::ReadResult result =
osgDB::Registry::instance()->readImage(_tuple.get<0>(), options);
if(result.success()) {
osg::Image* image = result.getImage();
cubeTexture->setImage(TextureCubeMap::POSITIVE_X, image);
}
result = osgDB::Registry::instance()->readImage(_tuple.get<1>(), options);
if(result.success()) {
osg::Image* image = result.getImage();
cubeTexture->setImage(TextureCubeMap::NEGATIVE_X, image);
}
result = osgDB::Registry::instance()->readImage(_tuple.get<2>(), options);
if(result.success()) {
osg::Image* image = result.getImage();
cubeTexture->setImage(TextureCubeMap::POSITIVE_Y, image);
}
result = osgDB::Registry::instance()->readImage(_tuple.get<3>(), options);
if(result.success()) {
osg::Image* image = result.getImage();
cubeTexture->setImage(TextureCubeMap::NEGATIVE_Y, image);
}
result = osgDB::Registry::instance()->readImage(_tuple.get<4>(), options);
if(result.success()) {
osg::Image* image = result.getImage();
cubeTexture->setImage(TextureCubeMap::POSITIVE_Z, image);
}
result = osgDB::Registry::instance()->readImage(_tuple.get<5>(), options);
if(result.success()) {
osg::Image* image = result.getImage();
cubeTexture->setImage(TextureCubeMap::NEGATIVE_Z, image);
}
_cubemaps[_tuple] = cubeTexture;
return cubeTexture;
}
namespace {
TextureBuilder::Registrar installCubeMap("cubemap", new CubeMapBuilder);
}
EffectNameValue<TexEnvCombine::CombineParam> combineParamInit[] = EffectNameValue<TexEnvCombine::CombineParam> combineParamInit[] =
{ {
{"replace", TexEnvCombine::REPLACE}, {"replace", TexEnvCombine::REPLACE},
@@ -443,7 +555,8 @@ EffectNameValue<TexEnvCombine::OperandParam> opParamInit[] =
EffectPropertyMap<TexEnvCombine::OperandParam> operandParams(opParamInit); EffectPropertyMap<TexEnvCombine::OperandParam> operandParams(opParamInit);
TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp) TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp,
const SGReaderWriterXMLOptions* options)
{ {
if (!isAttributeActive(effect, envProp)) if (!isAttributeActive(effect, envProp))
return 0; return 0;
@@ -538,7 +651,8 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp)
const SGPropertyNode* colorNode = envProp->getChild("constant-color"); const SGPropertyNode* colorNode = envProp->getChild("constant-color");
if (colorNode) if (colorNode)
initFromParameters(effect, colorNode, result, initFromParameters(effect, colorNode, result,
&TexEnvCombine::setConstantColor, colorFields); &TexEnvCombine::setConstantColor, colorFields,
options);
return result; return result;
} }
+2 -2
View File
@@ -29,13 +29,13 @@ public:
// Hack to force inclusion of TextureBuilder.cxx in library // Hack to force inclusion of TextureBuilder.cxx in library
static osg::Texture* buildFromType(Effect* effect, const std::string& type, static osg::Texture* buildFromType(Effect* effect, const std::string& type,
const SGPropertyNode*props, const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
struct TextureUnitBuilder : public PassAttributeBuilder struct TextureUnitBuilder : public PassAttributeBuilder
{ {
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
}; };
+22 -3
View File
@@ -31,6 +31,7 @@
#include <osgDB/Registry> #include <osgDB/Registry>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/SplicingVisitor.hxx> #include <simgear/scene/util/SplicingVisitor.hxx>
@@ -116,7 +117,7 @@ void mergePropertyTrees(SGPropertyNode* resultNode,
Effect* makeEffect(const string& name, Effect* makeEffect(const string& name,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
{ {
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex); OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex);
@@ -159,7 +160,7 @@ Effect* makeEffect(const string& name,
Effect* makeEffect(SGPropertyNode* prop, Effect* makeEffect(SGPropertyNode* prop,
bool realizeTechniques, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
// Give default names to techniques and passes // Give default names to techniques and passes
vector<SGPropertyNode_ptr> techniques = prop->getChildren("technique"); vector<SGPropertyNode_ptr> techniques = prop->getChildren("technique");
@@ -204,8 +205,10 @@ Effect* makeEffect(SGPropertyNode* prop,
lock(effectMutex); lock(effectMutex);
cache = parent->getCache(); cache = parent->getCache();
itr = cache->find(key); itr = cache->find(key);
if (itr != cache->end()) if (itr != cache->end()) {
effect = itr->second.get(); effect = itr->second.get();
effect->generator = parent->generator; // Copy the generators
}
} }
if (!effect.valid()) { if (!effect.valid()) {
effect = new Effect; effect = new Effect;
@@ -218,6 +221,7 @@ Effect* makeEffect(SGPropertyNode* prop,
= cache->insert(make_pair(key, effect)); = cache->insert(make_pair(key, effect));
if (!irslt.second) if (!irslt.second)
effect = irslt.first->second; effect = irslt.first->second;
effect->generator = parent->generator; // Copy the generators
} }
} else { } else {
SG_LOG(SG_INPUT, SG_ALERT, "can't find base effect " << SG_LOG(SG_INPUT, SG_ALERT, "can't find base effect " <<
@@ -229,6 +233,21 @@ Effect* makeEffect(SGPropertyNode* prop,
effect->root = prop; effect->root = prop;
effect->parametersProp = effect->root->getChild("parameters"); effect->parametersProp = effect->root->getChild("parameters");
} }
const SGPropertyNode *generateProp = prop->getChild("generate");
if(generateProp)
{
effect->generator.clear();
// Effect needs some generated properties, like tangent vectors
const SGPropertyNode *parameter = generateProp->getChild("normal");
if(parameter) effect->setGenerator(Effect::NORMAL, parameter->getIntValue());
parameter = generateProp->getChild("tangent");
if(parameter) effect->setGenerator(Effect::TANGENT, parameter->getIntValue());
parameter = generateProp->getChild("binormal");
if(parameter) effect->setGenerator(Effect::BINORMAL, parameter->getIntValue());
}
if (realizeTechniques) { if (realizeTechniques) {
try { try {
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> OpenThreads::ScopedLock<OpenThreads::ReentrantMutex>
+71 -11
View File
@@ -49,6 +49,7 @@
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx> #include <simgear/misc/sgstream.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/scene/model/model.hxx> #include <simgear/scene/model/model.hxx>
#include <simgear/scene/util/RenderConstants.hxx> #include <simgear/scene/util/RenderConstants.hxx>
@@ -67,13 +68,25 @@ using namespace simgear;
// Constructors and destructor. // Constructors and destructor.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
SGMaterial::_internal_state::_internal_state(Effect *e, const string &t, bool l, SGMaterial::_internal_state::_internal_state(Effect *e, bool l,
const osgDB::ReaderWriter::Options* o ) : const SGReaderWriterXMLOptions* o)
effect(e), texture_path(t), effect_realized(l), options(o) : effect(e), effect_realized(l), options(o)
{ {
} }
SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* options, SGMaterial::_internal_state::_internal_state(Effect *e, const string &t, bool l,
const SGReaderWriterXMLOptions* o)
: effect(e), effect_realized(l), options(o)
{
texture_paths.push_back(std::make_pair(t,0));
}
void SGMaterial::_internal_state::add_texture(const std::string &t, int i)
{
texture_paths.push_back(std::make_pair(t,i));
}
SGMaterial::SGMaterial( const SGReaderWriterXMLOptions* options,
const SGPropertyNode *props ) const SGPropertyNode *props )
{ {
init(); init();
@@ -81,6 +94,17 @@ SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* options,
buildEffectProperties(options); buildEffectProperties(options);
} }
SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* options,
const SGPropertyNode *props )
{
osg::ref_ptr<const SGReaderWriterXMLOptions> sgOptions;
if (options)
sgOptions = new SGReaderWriterXMLOptions(*options);
init();
read_properties( sgOptions.get(), props );
buildEffectProperties(sgOptions.get());
}
SGMaterial::~SGMaterial (void) SGMaterial::~SGMaterial (void)
{ {
} }
@@ -91,7 +115,7 @@ SGMaterial::~SGMaterial (void)
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
void void
SGMaterial::read_properties(const osgDB::ReaderWriter::Options* options, SGMaterial::read_properties(const SGReaderWriterXMLOptions* options,
const SGPropertyNode *props) const SGPropertyNode *props)
{ {
// Gather the path(s) to the texture(s) // Gather the path(s) to the texture(s)
@@ -117,7 +141,34 @@ SGMaterial::read_properties(const osgDB::ReaderWriter::Options* options,
} }
} }
if (textures.size() == 0) { vector<SGPropertyNode_ptr> texturesets = props->getChildren("texture-set");
for (unsigned int i = 0; i < texturesets.size(); i++)
{
_internal_state st( NULL, false, options );
vector<SGPropertyNode_ptr> textures = texturesets[i]->getChildren("texture");
for (unsigned int j = 0; j < textures.size(); j++)
{
string tname = textures[j]->getStringValue();
if (tname.empty()) {
tname = "unknown.rgb";
}
SGPath tpath("Textures.high");
tpath.append(tname);
string fullTexPath = osgDB::findDataFile(tpath.str(), options);
if (fullTexPath.empty()) {
tpath = SGPath("Textures");
tpath.append(tname);
fullTexPath = osgDB::findDataFile(tpath.str(), options);
}
st.add_texture(fullTexPath, textures[j]->getIndex());
}
if (!st.texture_paths.empty() ) {
_status.push_back( st );
}
}
if (textures.size() == 0 && texturesets.size() == 0) {
SGPath tpath("Textures"); SGPath tpath("Textures");
tpath.append("Terrain"); tpath.append("Terrain");
tpath.append("unknown.rgb"); tpath.append("unknown.rgb");
@@ -245,10 +296,12 @@ Effect* SGMaterial::get_effect(int n)
return _status[i].effect.get(); return _status[i].effect.get();
} }
void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options* void SGMaterial::buildEffectProperties(const SGReaderWriterXMLOptions* options)
options)
{ {
using namespace osg; using namespace osg;
ref_ptr<SGReaderWriterXMLOptions> xmlOptions;
if (options)
xmlOptions = new SGReaderWriterXMLOptions(*options);
ref_ptr<SGMaterialUserData> user = new SGMaterialUserData(this); ref_ptr<SGMaterialUserData> user = new SGMaterialUserData(this);
SGPropertyNode_ptr propRoot = new SGPropertyNode(); SGPropertyNode_ptr propRoot = new SGPropertyNode();
makeChild(propRoot, "inherits-from")->setStringValue(effect); makeChild(propRoot, "inherits-from")->setStringValue(effect);
@@ -271,15 +324,22 @@ void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options*
SGPropertyNode_ptr effectProp = new SGPropertyNode(); SGPropertyNode_ptr effectProp = new SGPropertyNode();
copyProperties(propRoot, effectProp); copyProperties(propRoot, effectProp);
SGPropertyNode* effectParamProp = effectProp->getChild("parameters", 0); SGPropertyNode* effectParamProp = effectProp->getChild("parameters", 0);
SGPropertyNode* texProp = makeChild(effectParamProp, "texture"); for (unsigned int i = 0; i < matState.texture_paths.size(); i++) {
makeChild(texProp, "image")->setStringValue(matState.texture_path); SGPropertyNode* texProp = makeChild(effectParamProp, "texture", matState.texture_paths[i].second);
makeChild(texProp, "image")->setStringValue(matState.texture_paths[i].first);
makeChild(texProp, "filter") makeChild(texProp, "filter")
->setStringValue(mipmap ? "linear-mipmap-linear" : "nearest"); ->setStringValue(mipmap ? "linear-mipmap-linear" : "nearest");
makeChild(texProp, "wrap-s") makeChild(texProp, "wrap-s")
->setStringValue(wrapu ? "repeat" : "clamp"); ->setStringValue(wrapu ? "repeat" : "clamp");
makeChild(texProp, "wrap-t") makeChild(texProp, "wrap-t")
->setStringValue(wrapv ? "repeat" : "clamp"); ->setStringValue(wrapv ? "repeat" : "clamp");
matState.effect = makeEffect(effectProp, false, options); }
makeChild(effectParamProp, "xsize")->setDoubleValue(xsize);
makeChild(effectParamProp, "ysize")->setDoubleValue(ysize);
makeChild(effectParamProp, "scale")->setValue(SGVec3d(xsize,ysize,0.0));
makeChild(effectParamProp, "light-coverage")->setDoubleValue(light_coverage);
matState.effect = makeEffect(effectProp, false, xmlOptions.get());
matState.effect->setUserData(user.get()); matState.effect->setUserData(user.get());
} }
} }
+11 -6
View File
@@ -39,13 +39,13 @@
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
#include <osg/ref_ptr> #include <osg/ref_ptr>
#include <osgDB/ReaderWriter>
namespace osg namespace osg
{ {
class StateSet; class StateSet;
} }
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx> #include <simgear/scene/util/SGSceneFeatures.hxx>
@@ -87,6 +87,8 @@ public:
*/ */
SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props); SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props);
SGMaterial(const simgear::SGReaderWriterXMLOptions*,
const SGPropertyNode *props);
/** /**
* Destructor. * Destructor.
*/ */
@@ -270,12 +272,15 @@ protected:
protected: protected:
struct _internal_state { struct _internal_state {
_internal_state(simgear::Effect *e, bool l,
const simgear::SGReaderWriterXMLOptions *o);
_internal_state(simgear::Effect *e, const std::string &t, bool l, _internal_state(simgear::Effect *e, const std::string &t, bool l,
const osgDB::ReaderWriter::Options *o); const simgear::SGReaderWriterXMLOptions *o);
void add_texture(const std::string &t, int i);
osg::ref_ptr<simgear::Effect> effect; osg::ref_ptr<simgear::Effect> effect;
std::string texture_path; std::vector<std::pair<std::string,int> > texture_paths;
bool effect_realized; bool effect_realized;
osg::ref_ptr<const osgDB::ReaderWriter::Options> options; osg::ref_ptr<const simgear::SGReaderWriterXMLOptions> options;
}; };
private: private:
@@ -361,9 +366,9 @@ private:
// Internal constructors and methods. // Internal constructors and methods.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
void read_properties(const osgDB::ReaderWriter::Options* options, void read_properties(const simgear::SGReaderWriterXMLOptions* options,
const SGPropertyNode *props); const SGPropertyNode *props);
void buildEffectProperties(const osgDB::ReaderWriter::Options* options); void buildEffectProperties(const simgear::SGReaderWriterXMLOptions* options);
}; };
+2 -5
View File
@@ -135,14 +135,11 @@ SGMatModel::load_models( SGPropertyNode *prop_root )
} }
osg::Node* osg::Node*
SGMatModel::get_random_model( SGPropertyNode *prop_root ) SGMatModel::get_random_model( SGPropertyNode *prop_root, mt seed )
{ {
load_models( prop_root ); // comment this out if preloading models load_models( prop_root ); // comment this out if preloading models
int nModels = _models.size(); int nModels = _models.size();
int index = int(sg_random() * nModels); return _models[mt_rand(&seed) * nModels].get();
if (index >= nModels)
index = 0;
return _models[index].get();
} }
double double
+1 -1
View File
@@ -82,7 +82,7 @@ public:
* *
* @return A randomly select model from the variants. * @return A randomly select model from the variants.
*/ */
osg::Node *get_random_model( SGPropertyNode *prop_root ); osg::Node *get_random_model( SGPropertyNode *prop_root, mt seed );
/** /**
+1
View File
@@ -27,6 +27,7 @@ include_HEADERS = \
libsgmodel_a_SOURCES = \ libsgmodel_a_SOURCES = \
animation.cxx \ animation.cxx \
BoundingVolumeBuildVisitor.hxx \
particles.cxx \ particles.cxx \
model.cxx \ model.cxx \
modellib.cxx \ modellib.cxx \
+1 -1
View File
@@ -98,7 +98,7 @@ public:
_bvhPolicy.buildBVH(fileName, optimizedNode.get()); _bvhPolicy.buildBVH(fileName, optimizedNode.get());
_cachePolicy.addToCache(fileName, optimizedNode.get()); _cachePolicy.addToCache(fileName, optimizedNode.get());
} }
return ReaderWriter::ReadResult(optimizedNode); return ReaderWriter::ReadResult(optimizedNode.get());
} }
protected: protected:
static osgDB::ReaderWriter::ReadResult static osgDB::ReaderWriter::ReadResult
+12 -2
View File
@@ -70,8 +70,18 @@ public:
osg::ref_ptr<osg::RefMatrix> mModelView; osg::ref_ptr<osg::RefMatrix> mModelView;
}; };
osgUtil::RegisterRenderBinProxy struct SGClipGroup::ClipBinRegistrar
SGClipGroup::clipBinProxy("ClipRenderBin", new SGClipGroup::ClipRenderBin); {
ClipBinRegistrar()
{
osgUtil::RenderBin
::addRenderBinPrototype("ClipRenderBin",
new SGClipGroup::ClipRenderBin);
}
static ClipBinRegistrar registrar;
};
SGClipGroup::ClipBinRegistrar SGClipGroup::ClipBinRegistrar::registrar;
class SGClipGroup::CullCallback : public osg::NodeCallback { class SGClipGroup::CullCallback : public osg::NodeCallback {
public: public:
+1 -3
View File
@@ -49,10 +49,8 @@ public:
protected: protected:
class CullCallback; class CullCallback;
class ClipRenderBin; class ClipRenderBin;
struct ClipBinRegistrar;
std::vector<osg::ref_ptr<osg::ClipPlane> > mClipPlanes; std::vector<osg::ref_ptr<osg::ClipPlane> > mClipPlanes;
static osgUtil::RegisterRenderBinProxy clipBinProxy;
}; };
#endif #endif
@@ -18,7 +18,7 @@
#ifndef SGREADERWRITERXMLOPTIONS_HXX #ifndef SGREADERWRITERXMLOPTIONS_HXX
#define SGREADERWRITERXMLOPTIONS_HXX 1 #define SGREADERWRITERXMLOPTIONS_HXX 1
#include <osgDB/ReaderWriter> #include <osgDB/Registry>
#include <simgear/scene/model/modellib.hxx> #include <simgear/scene/model/modellib.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
+13 -6
View File
@@ -33,6 +33,7 @@
#include <simgear/props/props_io.hxx> #include <simgear/props/props_io.hxx>
#include <simgear/props/condition.hxx> #include <simgear/props/condition.hxx>
#include "SGReaderWriterXMLOptions.hxx"
#include "model.hxx" #include "model.hxx"
using std::vector; using std::vector;
@@ -209,7 +210,7 @@ class MakeEffectVisitor : public SplicingVisitor
public: public:
typedef std::map<string, SGPropertyNode_ptr> EffectMap; typedef std::map<string, SGPropertyNode_ptr> EffectMap;
using SplicingVisitor::apply; using SplicingVisitor::apply;
MakeEffectVisitor(const osgDB::ReaderWriter::Options* options = 0) MakeEffectVisitor(const SGReaderWriterXMLOptions* options = 0)
: _options(options) : _options(options)
{ {
} }
@@ -225,7 +226,7 @@ public:
protected: protected:
EffectMap _effectMap; EffectMap _effectMap;
SGPropertyNode_ptr _currentEffectParent; SGPropertyNode_ptr _currentEffectParent;
osg::ref_ptr<const osgDB::ReaderWriter::Options> _options; osg::ref_ptr<const SGReaderWriterXMLOptions> _options;
}; };
void MakeEffectVisitor::apply(osg::Group& node) void MakeEffectVisitor::apply(osg::Group& node)
@@ -263,7 +264,7 @@ void MakeEffectVisitor::apply(osg::Geode& geode)
makeParametersFromStateSet(ssRoot, ss); makeParametersFromStateSet(ssRoot, ss);
SGPropertyNode_ptr effectRoot = new SGPropertyNode; SGPropertyNode_ptr effectRoot = new SGPropertyNode;
effect::mergePropertyTrees(effectRoot, ssRoot, _currentEffectParent); effect::mergePropertyTrees(effectRoot, ssRoot, _currentEffectParent);
Effect* effect = makeEffect(effectRoot, true, _options); Effect* effect = makeEffect(effectRoot, true, _options.get());
EffectGeode* eg = dynamic_cast<EffectGeode*>(&geode); EffectGeode* eg = dynamic_cast<EffectGeode*>(&geode);
if (eg) { if (eg) {
eg->setEffect(effect); eg->setEffect(effect);
@@ -273,8 +274,14 @@ void MakeEffectVisitor::apply(osg::Geode& geode)
ref_ptr<SGSceneUserData> userData = SGSceneUserData::getSceneUserData(&geode); ref_ptr<SGSceneUserData> userData = SGSceneUserData::getSceneUserData(&geode);
if (userData.valid()) if (userData.valid())
eg->setUserData(new SGSceneUserData(*userData)); eg->setUserData(new SGSceneUserData(*userData));
for (int i = 0; i < geode.getNumDrawables(); ++i) for (int i = 0; i < geode.getNumDrawables(); ++i) {
eg->addDrawable(geode.getDrawable(i)); osg::Drawable *drawable = geode.getDrawable(i);
eg->addDrawable(drawable);
// Generate tangent vectors etc if needed
osg::Geometry *geom = dynamic_cast<osg::Geometry*>(drawable);
if(geom) eg->runGenerators(geom);
}
} }
pushResultNode(&geode, eg); pushResultNode(&geode, eg);
@@ -302,7 +309,7 @@ protected:
ref_ptr<Node> instantiateEffects(osg::Node* modelGroup, ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
PropertyList& effectProps, PropertyList& effectProps,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
SGPropertyNode_ptr defaultEffectPropRoot; SGPropertyNode_ptr defaultEffectPropRoot;
MakeEffectVisitor visitor(options); MakeEffectVisitor visitor(options);
+7 -2
View File
@@ -23,6 +23,11 @@
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/util/NodeAndDrawableVisitor.hxx> #include <simgear/scene/util/NodeAndDrawableVisitor.hxx>
namespace simgear
{
class SGReaderWriterXMLOptions;
}
osg::Texture2D* osg::Texture2D*
SGLoadTexture2D(bool staticTexture, const std::string& path, SGLoadTexture2D(bool staticTexture, const std::string& path,
const osgDB::ReaderWriter::Options* options = 0, const osgDB::ReaderWriter::Options* options = 0,
@@ -97,7 +102,7 @@ public:
osg::ref_ptr<osg::Node> osg::ref_ptr<osg::Node>
instantiateEffects(osg::Node* model, instantiateEffects(osg::Node* model,
PropertyList& effectProps, PropertyList& effectProps,
const osgDB::ReaderWriter::Options* options); const SGReaderWriterXMLOptions* options);
/** /**
* Transform an OSG subgraph by substituting the Effects and * Transform an OSG subgraph by substituting the Effects and
@@ -110,7 +115,7 @@ instantiateEffects(osg::Node* model,
inline osg::ref_ptr<osg::Node> inline osg::ref_ptr<osg::Node>
instantiateEffects(osg::Node* model, instantiateEffects(osg::Node* model,
const osgDB::ReaderWriter::Options* options) const SGReaderWriterXMLOptions* options)
{ {
PropertyList effectProps; PropertyList effectProps;
return instantiateEffects(model, effectProps, options); return instantiateEffects(model, effectProps, options);
+6 -2
View File
@@ -71,8 +71,12 @@ osg::Node* loadFile(const string& path, osgDB::ReaderWriter::Options* options)
ref_ptr<Node> model = readRefNodeFile(path, options); ref_ptr<Node> model = readRefNodeFile(path, options);
if (!model) if (!model)
return 0; return 0;
if (boost::iends_with(path, ".ac")) if (boost::iends_with(path, ".ac")) {
model = instantiateEffects(model.get(), options); ref_ptr<SGReaderWriterXMLOptions> sgOptions;
if (options)
sgOptions = new SGReaderWriterXMLOptions(*options);
model = instantiateEffects(model.get(), sgOptions.get());
}
return model.release(); return model.release();
} }
} }
+3
View File
@@ -80,6 +80,7 @@ osg::ref_ptr<osg::Group> Particles::commonRoot;
osg::ref_ptr<osgParticle::ParticleSystemUpdater> Particles::psu = new osgParticle::ParticleSystemUpdater; osg::ref_ptr<osgParticle::ParticleSystemUpdater> Particles::psu = new osgParticle::ParticleSystemUpdater;
osg::ref_ptr<osg::Geode> Particles::commonGeode = new osg::Geode;; osg::ref_ptr<osg::Geode> Particles::commonGeode = new osg::Geode;;
osg::Vec3 Particles::_wind; osg::Vec3 Particles::_wind;
bool Particles::_frozen = false;
Particles::Particles() : Particles::Particles() :
useGravity(false), useGravity(false),
@@ -510,6 +511,8 @@ osg::Group * Particles::appendParticles(const SGPropertyNode* configNode,
void Particles::operator()(osg::Node* node, osg::NodeVisitor* nv) void Particles::operator()(osg::Node* node, osg::NodeVisitor* nv)
{ {
//SG_LOG(SG_GENERAL, SG_ALERT, "callback!\n"); //SG_LOG(SG_GENERAL, SG_ALERT, "callback!\n");
this->particleSys->setFrozen(_frozen);
using namespace osg; using namespace osg;
if (shooterValue) if (shooterValue)
shooter->setInitialSpeedRange(shooterValue->getValue(), shooter->setInitialSpeedRange(shooterValue->getValue(),
+3
View File
@@ -249,6 +249,8 @@ public:
return psu.get(); return psu.get();
} }
static void setFrozen(bool e) { _frozen = e; }
/** /**
* Set and get the wind vector for particles in the * Set and get the wind vector for particles in the
* atmosphere. This vector is in the Z-up Y-north frame, and the * atmosphere. This vector is in the Z-up Y-north frame, and the
@@ -279,6 +281,7 @@ protected:
bool useGravity; bool useGravity;
bool useWind; bool useWind;
static bool _frozen;
static osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu; static osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu;
static osg::ref_ptr<osg::Group> commonRoot; static osg::ref_ptr<osg::Group> commonRoot;
static osg::ref_ptr<osg::Geode> commonGeode; static osg::ref_ptr<osg::Geode> commonGeode;
+3 -3
View File
@@ -138,7 +138,7 @@ void
SGModelPlacement::setReferenceTime(const double& referenceTime) SGModelPlacement::setReferenceTime(const double& referenceTime)
{ {
SGSceneUserData* userData; SGSceneUserData* userData;
userData = SGSceneUserData::getOrCreateSceneUserData(_transform); userData = SGSceneUserData::getOrCreateSceneUserData(_transform.get());
SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity(); SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity();
vel->referenceTime = referenceTime; vel->referenceTime = referenceTime;
} }
@@ -147,7 +147,7 @@ void
SGModelPlacement::setBodyLinearVelocity(const SGVec3d& linear) SGModelPlacement::setBodyLinearVelocity(const SGVec3d& linear)
{ {
SGSceneUserData* userData; SGSceneUserData* userData;
userData = SGSceneUserData::getOrCreateSceneUserData(_transform); userData = SGSceneUserData::getOrCreateSceneUserData(_transform.get());
SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity(); SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity();
vel->linear = SGVec3d(-linear[0], linear[1], -linear[2]); vel->linear = SGVec3d(-linear[0], linear[1], -linear[2]);
} }
@@ -156,7 +156,7 @@ void
SGModelPlacement::setBodyAngularVelocity(const SGVec3d& angular) SGModelPlacement::setBodyAngularVelocity(const SGVec3d& angular)
{ {
SGSceneUserData* userData; SGSceneUserData* userData;
userData = SGSceneUserData::getOrCreateSceneUserData(_transform); userData = SGSceneUserData::getOrCreateSceneUserData(_transform.get());
SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity(); SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity();
vel->angular = SGVec3d(-angular[0], angular[1], -angular[2]); vel->angular = SGVec3d(-angular[0], angular[1], -angular[2]);
} }
+2 -1
View File
@@ -132,7 +132,8 @@ bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
field_transform->setMatrix( LAT*LON*T ); field_transform->setMatrix( LAT*LON*T );
} }
field_root->getStateSet()->setRenderBinDetails(asl, "DepthSortedBin"); // Render the clouds in order from farthest away layer to nearest one.
field_root->getStateSet()->setRenderBinDetails(CLOUDS_BIN, "DepthSortedBin");
return true; return true;
} }
+5 -2
View File
@@ -46,6 +46,7 @@
#include <simgear/misc/PathOptions.hxx> #include <simgear/misc/PathOptions.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/scene/model/model.hxx> #include <simgear/scene/model/model.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx> #include <simgear/scene/util/SGUpdateVisitor.hxx>
@@ -108,9 +109,11 @@ SGNewCloud::SGNewCloud(string type,
"texture"), "texture"),
"image"), "image"),
texture); texture);
osg::ref_ptr<osgDB::ReaderWriter::Options> options ref_ptr<osgDB::ReaderWriter::Options> options
= makeOptionsFromPath(tex_path); = makeOptionsFromPath(tex_path);
if ((effect = makeEffect(pcloudEffect, true, options))) ref_ptr<SGReaderWriterXMLOptions> sgOptions
= new SGReaderWriterXMLOptions(*options.get());
if ((effect = makeEffect(pcloudEffect, true, sgOptions.get())))
effectMap.insert(EffectMap::value_type(texture, effect)); effectMap.insert(EffectMap::value_type(texture, effect));
} else { } else {
effect = iter->second.get(); effect = iter->second.get();
+1
View File
@@ -310,6 +310,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
geode->setName("Ocean tile"); geode->setName("Ocean tile");
geode->setEffect(effect); geode->setEffect(effect);
geode->addDrawable(geometry); geode->addDrawable(geometry);
geode->runGenerators(geometry);
osg::MatrixTransform* transform = new osg::MatrixTransform; osg::MatrixTransform* transform = new osg::MatrixTransform;
transform->setName("Ocean"); transform->setName("Ocean");
+2 -2
View File
@@ -333,7 +333,7 @@ TileEntry::loadTileByFileName(const string& fileName,
if (found_tile_base) { if (found_tile_base) {
// load tile if found ... // load tile if found ...
opt->setCalcLights(true); opt->setCalcLights(true);
obj_load( object_base.str(), new_tile, true, opt); obj_load( object_base.str(), new_tile, true, opt.get());
} else { } else {
// ... or generate an ocean tile on the fly // ... or generate an ocean tile on the fly
@@ -354,7 +354,7 @@ TileEntry::loadTileByFileName(const string& fileName,
SGPath custom_path = obj->path; SGPath custom_path = obj->path;
custom_path.append( obj->name ); custom_path.append( obj->name );
opt->setCalcLights(true); opt->setCalcLights(true);
obj_load( custom_path.str(), new_tile, false, opt); obj_load( custom_path.str(), new_tile, false, opt.get());
} else if (obj->type == OBJECT_SHARED || obj->type == OBJECT_STATIC) { } else if (obj->type == OBJECT_SHARED || obj->type == OBJECT_STATIC) {
// object loading is deferred to main render thread, // object loading is deferred to main render thread,
+8 -1
View File
@@ -344,13 +344,20 @@ SGMakeSign(SGMaterialLib *matlib, const string& path, const string& content)
vl->push_back(osg::Vec3(0, hpos, dist + sign_height)); vl->push_back(osg::Vec3(0, hpos, dist + sign_height));
vl->push_back(osg::Vec3(0, hpos - total_width, dist + sign_height)); vl->push_back(osg::Vec3(0, hpos - total_width, dist + sign_height));
osg::Vec2Array* tl = new osg::Vec2Array;
for (int i = 0; i < 4; ++i)
tl->push_back(osg::Vec2(0.0, 0.0));
osg::Vec3Array* nl = new osg::Vec3Array; osg::Vec3Array* nl = new osg::Vec3Array;
nl->push_back(osg::Vec3(0, 1, 0)); nl->push_back(osg::Vec3(0, 1, 0));
osg::Vec4Array* cl = new osg::Vec4Array;
cl->push_back(osg::Vec4(0.0, 0.0, 0.0, 1.0));
osg::Geometry* geometry = new osg::Geometry; osg::Geometry* geometry = new osg::Geometry;
geometry->setVertexArray(vl); geometry->setVertexArray(vl);
geometry->setNormalArray(nl); geometry->setNormalArray(nl);
geometry->setNormalBinding(osg::Geometry::BIND_OVERALL); geometry->setNormalBinding(osg::Geometry::BIND_OVERALL);
geometry->setTexCoordArray(0, tl);
geometry->setColorArray(cl);
geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size())); geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, vl->size()));
EffectGeode* geode = new EffectGeode; EffectGeode* geode = new EffectGeode;
geode->addDrawable(geometry); geode->addDrawable(geometry);
+2 -1
View File
@@ -382,6 +382,7 @@ struct SGTileGeometryBin {
if (mat) if (mat)
eg->setEffect(mat->get_effect()); eg->setEffect(mat->get_effect());
eg->addDrawable(geometry); eg->addDrawable(geometry);
eg->runGenerators(geometry); // Generate extra data needed by effect
if (group) if (group)
group->addChild(eg); group->addChild(eg);
} }
@@ -610,7 +611,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
i < tileGeometryBin.randomModels.getNumModels(); i++) { i < tileGeometryBin.randomModels.getNumModels(); i++) {
SGMatModelBin::MatModel obj SGMatModelBin::MatModel obj
= tileGeometryBin.randomModels.getMatModel(i); = tileGeometryBin.randomModels.getMatModel(i);
osg::Node* node = sgGetRandomModel(obj.model); osg::Node* node = sgGetRandomModel(obj.model, seed);
// Create a matrix to place the object in the correct // Create a matrix to place the object in the correct
// location, and then apply the rotation matrix created // location, and then apply the rotation matrix created
+1 -1
View File
@@ -194,7 +194,7 @@ Effect* getLightEffect(float size, const Vec3& attenuation,
point->setDistanceAttenuation(attenuation); point->setDistanceAttenuation(attenuation);
attenuationPass->setAttributeAndModes(point); attenuationPass->setAttributeAndModes(point);
Pass *spritePass = clone(basicPass, CopyOp::SHALLOW_COPY); Pass *spritePass = clone(basicPass, CopyOp::SHALLOW_COPY);
spritePass->setTextureAttributeAndModes(0, pointSprite, spritePass->setTextureAttributeAndModes(0, pointSprite.get(),
osg::StateAttribute::ON); osg::StateAttribute::ON);
Texture2D* texture = gen_standard_light_sprite(); Texture2D* texture = gen_standard_light_sprite();
spritePass->setTextureAttribute(0, texture); spritePass->setTextureAttribute(0, texture);
+2 -2
View File
@@ -60,8 +60,8 @@ void sgUserDataInit( SGPropertyNode *p ) {
root_props = p; root_props = p;
} }
osg::Node* sgGetRandomModel(SGMatModel *obj) { osg::Node* sgGetRandomModel(SGMatModel *obj, mt seed) {
return obj->get_random_model( root_props ); return obj->get_random_model( root_props, seed );
} }
namespace simgear namespace simgear
+2 -1
View File
@@ -26,6 +26,7 @@
#define _SG_USERDATA_HXX #define _SG_USERDATA_HXX
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/math/sg_random.h>
#include <osg/Node> #include <osg/Node>
@@ -42,7 +43,7 @@ void sgUserDataInit(SGPropertyNode *p);
/** /**
* Get a random model. * Get a random model.
*/ */
osg::Node* sgGetRandomModel(SGMatModel *obj); osg::Node* sgGetRandomModel(SGMatModel *obj, mt seed);
namespace simgear namespace simgear
{ {
+2 -2
View File
@@ -52,8 +52,8 @@ Group* SplicingVisitor::pushResultNode(Group* node, Group* newNode,
result->addChild(itr->get()); result->addChild(itr->get());
} }
_childStack.back().push_back(result); _childStack.back().push_back(result);
recordNewNode(node, result); recordNewNode(node, result.get());
return result; return result.get();
} }
Node* SplicingVisitor::pushResultNode(Node* node, Node* newNode) Node* SplicingVisitor::pushResultNode(Node* node, Node* newNode)
+2 -1
View File
@@ -41,7 +41,8 @@ TestRenderTexture_SOURCES = TestRenderTexture.cpp
TestRenderTexture_LDADD = \ TestRenderTexture_LDADD = \
libsgscreen.a \ libsgscreen.a \
$(top_builddir)/simgear/debug/libsgdebug.a \ $(top_builddir)/simgear/debug/libsgdebug.a \
$(opengl_LIBS) $(opengl_LIBS) \
-ldl
endif endif
INCLUDES = -I$(top_srcdir) -I$(top_builddir) -DGLX_GLXEXT_PROTOTYPES INCLUDES = -I$(top_srcdir) -I$(top_builddir) -DGLX_GLXEXT_PROTOTYPES
-8
View File
@@ -121,11 +121,7 @@ void *SGGetGLProcAddress(const char *func) {
libHandle = dlopen(NULL, RTLD_LAZY); libHandle = dlopen(NULL, RTLD_LAZY);
if (!libHandle) { if (!libHandle) {
#if defined (__FreeBSD__)
const char *error = dlerror(); const char *error = dlerror();
#else
char *error = dlerror();
#endif
if (error) { if (error) {
SG_LOG(SG_GENERAL, SG_INFO, error); SG_LOG(SG_GENERAL, SG_INFO, error);
return 0; return 0;
@@ -145,11 +141,7 @@ void *SGGetGLProcAddress(const char *func) {
} else if (libHandle != NULL) { } else if (libHandle != NULL) {
fptr = dlsym(libHandle, func); fptr = dlsym(libHandle, func);
#if defined (__FreeBSD__)
const char *error = dlerror(); const char *error = dlerror();
#else
char *error = dlerror();
#endif
if (error) if (error)
SG_LOG(SG_GENERAL, SG_INFO, error); SG_LOG(SG_GENERAL, SG_INFO, error);
} }
+56
View File
@@ -766,6 +766,62 @@ typedef void (APIENTRY * glGetVertexAttribivProc) (GLuint index, GLenum pname, G
typedef void (APIENTRY * glGetVertexAttribPointervProc) (GLuint index, GLenum pname, GLvoid* *pointer); typedef void (APIENTRY * glGetVertexAttribPointervProc) (GLuint index, GLenum pname, GLvoid* *pointer);
typedef GLboolean (APIENTRY * glIsProgramProc) (GLuint program); typedef GLboolean (APIENTRY * glIsProgramProc) (GLuint program);
/*
* EXT_framebuffer_objects
*/
#ifndef GL_EXT_framebuffer_object
#define GL_EXT_framebuffer_object 1
#define GL_NONE_EXT 0
#define GL_FRAMEBUFFER_EXT 0x8D40
#define GL_RENDERBUFFER_EXT 0x8D41
#define GL_RGBA4_EXT 0x8056
#define GL_RGB5_A1_EXT 0x8057
#define GL_RGB565_EXT 0x8D62
#define GL_DEPTH_COMPONENT16_EXT 0x81A5
#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42
#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43
#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44
#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50
#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51
#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52
#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53
#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54
#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0
#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2
#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3
#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0
#define GL_DEPTH_ATTACHMENT_EXT 0x8D00
#define GL_STENCIL_ATTACHMENT_EXT 0x8D20
#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA
#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD
#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7
#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
#endif
typedef GLboolean (APIENTRY * glIsRenderbufferProc) (GLuint renderbuffer);
typedef void (APIENTRY * glBindRenderbufferProc) (GLenum target, GLuint renderbuffer);
typedef void (APIENTRY * glDeleteRenderbuffersProc) (GLsizei n, const GLuint* renderbuffers);
typedef void (APIENTRY * glGenRenderbuffersProc) (GLsizei n, GLuint* renderbuffers);
typedef void (APIENTRY * glRenderbufferStorageProc) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (APIENTRY * glGetRenderbufferParameterivProc) (GLenum target, GLenum pname, GLint* params);
typedef GLboolean (APIENTRY * glIsFramebufferProc) (GLuint framebuffer);
typedef void (APIENTRY * glBindFramebufferProc) (GLenum target, GLuint framebuffer);
typedef void (APIENTRY * glDeleteFramebuffersProc) (GLsizei n, const GLuint* framebuffers);
typedef void (APIENTRY * glGenFramebuffersProc) (GLsizei n, GLuint* framebuffers);
typedef GLenum (APIENTRY * glCheckFramebufferStatusProc) (GLenum target);
typedef void (APIENTRY * glFramebufferRenderbufferProc) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
typedef void (APIENTRY * glFramebufferTexture2DProc) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef void (APIENTRY * glGetFramebufferAttachmentParameterivProc) (GLenum target, GLenum attachment, GLenum pname, GLint* params);
typedef void (APIENTRY * glGenerateMipmapProc) (GLenum target);
/* /*
* ARB_shader_objects * ARB_shader_objects
*/ */
+2 -2
View File
@@ -275,7 +275,7 @@ SGSampleGroup::stop ()
void void
SGSampleGroup::suspend () SGSampleGroup::suspend ()
{ {
if (_pause == false) { if (_active && _pause == false) {
_pause = true; _pause = true;
sample_map_iterator sample_current = _samples.begin(); sample_map_iterator sample_current = _samples.begin();
sample_map_iterator sample_end = _samples.end(); sample_map_iterator sample_end = _samples.end();
@@ -294,7 +294,7 @@ SGSampleGroup::suspend ()
void void
SGSampleGroup::resume () SGSampleGroup::resume ()
{ {
if (_pause == true) { if (_active && _pause == true) {
sample_map_iterator sample_current = _samples.begin(); sample_map_iterator sample_current = _samples.begin();
sample_map_iterator sample_end = _samples.end(); sample_map_iterator sample_end = _samples.end();
for ( ; sample_current != sample_end; ++sample_current ) { for ( ; sample_current != sample_end; ++sample_current ) {
+13 -3
View File
@@ -30,7 +30,7 @@
#endif #endif
#if defined( __APPLE__ ) #if defined( __APPLE__ )
# include <OpenAL/alut.h> # include <ALUT/alut.h>
#else #else
# include <AL/alut.h> # include <AL/alut.h>
#endif #endif
@@ -45,10 +45,17 @@
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
using std::string;
extern bool isNaN(float *v); extern bool isNaN(float *v);
#define MAX_SOURCES 128 #define MAX_SOURCES 128
#ifndef ALC_ALL_DEVICES_SPECIFIER
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
// //
// Sound Manager // Sound Manager
// //
@@ -81,6 +88,8 @@ SGSoundMgr::SGSoundMgr() :
} }
} }
_alut_init++; _alut_init++;
#else
#error ALUT 1.1 required, ALUT 1.0 is no longer supported, please upgrade
#endif #endif
} }
@@ -164,8 +173,9 @@ void SGSoundMgr::init(const char *devname) {
_vendor = (const char *)alGetString(AL_VENDOR); _vendor = (const char *)alGetString(AL_VENDOR);
_renderer = (const char *)alGetString(AL_RENDERER); _renderer = (const char *)alGetString(AL_RENDERER);
if ( (_vendor != "OpenAL Community" && _vendor != "Apple Computer Inc.") || if ( (_vendor != "Adalin" && _vendor != "Apple Computer Inc.") &&
(_renderer != "Software" && _renderer != "OpenAL Sample Implementation") (_vendor != "OpenAL Community" || (_renderer != "Software" &&
_renderer != "OpenAL Sample Implementation"))
) )
{ {
_bad_doppler = true; _bad_doppler = true;
+16 -32
View File
@@ -35,32 +35,19 @@
#ifndef _SG_SOUNDMGR_OPENAL_HXX #ifndef _SG_SOUNDMGR_OPENAL_HXX
#define _SG_SOUNDMGR_OPENAL_HXX 1 #define _SG_SOUNDMGR_OPENAL_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
#if defined(__APPLE__) #if defined(__APPLE__)
# define AL_ILLEGAL_ENUM AL_INVALID_ENUM
# define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
# include <OpenAL/al.h> # include <OpenAL/al.h>
# include <OpenAL/alc.h> # include <OpenAL/alc.h>
# include <OpenAL/alut.h>
#elif defined(OPENALSDK) #elif defined(OPENALSDK)
# include <al.h> # include <al.h>
# include <alc.h> # include <alc.h>
# include <AL/alut.h>
#else #else
# include <AL/al.h> # include <AL/al.h>
# include <AL/alc.h> # include <AL/alc.h>
# include <AL/alut.h>
#endif
#ifndef ALC_ALL_DEVICES_SPECIFIER
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif #endif
#include <simgear/compiler.h> #include <simgear/compiler.h>
@@ -68,9 +55,6 @@
#include <simgear/math/SGMathFwd.hxx> #include <simgear/math/SGMathFwd.hxx>
#include "sample_group.hxx" #include "sample_group.hxx"
#include "sample_openal.hxx"
using std::string;
struct refUint { struct refUint {
unsigned int refctr; unsigned int refctr;
@@ -81,11 +65,11 @@ struct refUint {
~refUint() {}; ~refUint() {};
}; };
typedef std::map < string, refUint > buffer_map; typedef std::map < std::string, refUint > buffer_map;
typedef buffer_map::iterator buffer_map_iterator; typedef buffer_map::iterator buffer_map_iterator;
typedef buffer_map::const_iterator const_buffer_map_iterator; typedef buffer_map::const_iterator const_buffer_map_iterator;
typedef std::map < string, SGSharedPtr<SGSampleGroup> > sample_group_map; typedef std::map < std::string, SGSharedPtr<SGSampleGroup> > sample_group_map;
typedef sample_group_map::iterator sample_group_map_iterator; typedef sample_group_map::iterator sample_group_map_iterator;
typedef sample_group_map::const_iterator const_sample_group_map_iterator; typedef sample_group_map::const_iterator const_sample_group_map_iterator;
@@ -133,21 +117,21 @@ public:
* @param refname Reference name of the sample group * @param refname Reference name of the sample group
* @return true if successful, false otherwise * @return true if successful, false otherwise
*/ */
bool add( SGSampleGroup *sgrp, const string& refname ); bool add( SGSampleGroup *sgrp, const std::string& refname );
/** /**
* Remove a sample group from the sound manager. * Remove a sample group from the sound manager.
* @param refname Reference name of the sample group to remove * @param refname Reference name of the sample group to remove
* @return true if successful, false otherwise * @return true if successful, false otherwise
*/ */
bool remove( const string& refname ); bool remove( const std::string& refname );
/** /**
* Test if a specified sample group is registered at the sound manager * Test if a specified sample group is registered at the sound manager
* @param refname Reference name of the sample group test for * @param refname Reference name of the sample group test for
* @return true if the specified sample group exists * @return true if the specified sample group exists
*/ */
bool exists( const string& refname ); bool exists( const std::string& refname );
/** /**
* Find a specified sample group in the sound manager * Find a specified sample group in the sound manager
@@ -287,13 +271,13 @@ public:
/** /**
* Get a list of available playback devices. * Get a list of available playback devices.
*/ */
vector<const char*> get_available_devices(); std::vector<const char*> get_available_devices();
/** /**
* Get the current OpenAL vendor or rendering backend. * Get the current OpenAL vendor or rendering backend.
*/ */
const string& get_vendor() { return _vendor; } const std::string& get_vendor() { return _vendor; }
const string& get_renderer() { return _renderer; } const std::string& get_renderer() { return _renderer; }
private: private:
static int _alut_init; static int _alut_init;
@@ -323,17 +307,17 @@ private:
sample_group_map _sample_groups; sample_group_map _sample_groups;
buffer_map _buffers; buffer_map _buffers;
vector<ALuint> _free_sources; std::vector<ALuint> _free_sources;
vector<ALuint> _sources_in_use; std::vector<ALuint> _sources_in_use;
bool _bad_doppler; bool _bad_doppler;
string _renderer; std::string _renderer;
string _vendor; std::string _vendor;
bool testForALError(string s); bool testForALError(std::string s);
bool testForALCError(string s); bool testForALCError(std::string s);
bool testForALUTError(string s); bool testForALUTError(std::string s);
bool testForError(void *p, string s); bool testForError(void *p, std::string s);
void update_pos_and_orientation(); void update_pos_and_orientation();
void update_sample_config( SGSampleGroup *sound ); void update_sample_config( SGSampleGroup *sound );