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

View File

@@ -2,14 +2,11 @@ EXTRA_DIST = \
acinclude.m4 \
autogen.sh \
DoxygenMain.cxx \
README.MSVC \
README.zlib \
README.plib \
README.OpenAL \
README.OSG \
projects \
SimGear.dsp \
SimGear.dsw
projects
SUBDIRS = simgear

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.

View File

@@ -6,19 +6,25 @@ dnl
AC_DEFUN([wi_EXTRA_IDIR], [
incdir="$1"
if test -r $incdir ; then
case "$CPPFLAGS" in
*-I${incdir}*)
# echo " + already had $incdir" 1>&6
;;
*)
if test "$CPPFLAGS" = "" ; then
CPPFLAGS="-I$incdir"
else
CPPFLAGS="$CPPFLAGS -I$incdir"
fi
echo " + found $incdir" 1>&6
;;
esac
already=""
for CPPflag in $CPPFLAGS ; do
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
CPPFLAGS="-I$incdir"
else
CPPFLAGS="$CPPFLAGS -I$incdir"
fi
echo " + added -I$incdir" 1>&AS_MESSAGE_LOG_FD
fi
else
echo " + IDIR is not accessible: '$myincdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
@@ -28,19 +34,25 @@ dnl
AC_DEFUN([wi_EXTRA_LDIR], [
mylibdir="$1"
if test -r $mylibdir ; then
case "$LDFLAGS" in
*-L${mylibdir}*)
# echo " + already had $mylibdir" 1>&6
;;
*)
if test "$LDFLAGS" = "" ; then
LDFLAGS="-L$mylibdir"
else
LDFLAGS="$LDFLAGS -L$mylibdir"
fi
echo " + found $mylibdir" 1>&6
;;
esac
already=""
for LDflag in $LDFLAGS ; do
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
LDFLAGS="-L$mylibdir"
else
LDFLAGS="$LDFLAGS -L$mylibdir"
fi
echo " + added -L$mylibdir" 1>&AS_MESSAGE_LOG_FD
fi
else
echo " + LDIR is not accessible: '$mylibdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
@@ -50,12 +62,9 @@ dnl
AC_DEFUN([wi_EXTRA_PDIR], [
progdir="$1"
if test -r $progdir ; then
case "$PATH" in
*:${progdir}*)
# echo " + already had $progdir" 1>&6
;;
*${progdir}:*)
# echo " + already had $progdir" 1>&6
case ":$PATH:" in
*:${progdir}:*)
echo " + already had $progdir in \$PATH" 1>&AS_MESSAGE_LOG_FD
;;
*)
if test "$PATH" = "" ; then
@@ -63,9 +72,11 @@ if test -r $progdir ; then
else
PATH="$PATH:$progdir"
fi
echo " + found $progdir" 1>&6
echo " + appended $progdir to \$PATH" 1>&AS_MESSAGE_LOG_FD
;;
esac
else
echo " + PDIR is not accessible: '$progdir'" 1>&AS_MESSAGE_LOG_FD
fi
])
dnl
@@ -89,23 +100,32 @@ if test "$subexdirs" = "" ; then
subexdirs="-"
fi
for subexdir in $subexdirs ; do
if test "$subexdir" = "-" ; then
subexdir=""
else
subexdir="/$subexdir"
fi
for exdir in $exdirs ; do
if test "$exdir" != "/usr" || test "$subexdir" != ""; then
incdir="${exdir}/include${subexdir}"
wi_EXTRA_IDIR($incdir)
if test "$subexdir" = "-" ; then
subexdir=""
else
subexdir="/$subexdir"
fi
for exdir in $exdirs ; do
if test "$exdir" != "/usr" || test "$subexdir" != ""; then
incdir="${exdir}/include${subexdir}"
wi_EXTRA_IDIR($incdir)
mylibdir="${exdir}/lib${subexdir}"
wi_EXTRA_LDIR($mylibdir)
dnl On 64-bit machines, if lib64/ exists and is not identical to lib/
dnl then it should be listed here, listed ahead of lib/.
mylibdir64="${exdir}/lib64${subexdir}"
mylibdir32="${exdir}/lib${subexdir}"
progdir="${exdir}/bin${subexdir}"
wi_EXTRA_PDIR($progdir)
fi
done
if test "x86_64" = $(uname -m) \
-a ! ${mylibdir64} -ef ${mylibdir32} ; then
wi_EXTRA_LDIR($mylibdir64)
fi
wi_EXTRA_LDIR($mylibdir32)
progdir="${exdir}/bin${subexdir}"
wi_EXTRA_PDIR($progdir)
fi
done
done
])
dnl

View File

@@ -437,11 +437,18 @@ esac
AM_CONDITIONAL(HAVE_FRAMEWORK_PLIB, test "x$ac_cv_framework_PLIB" != "x")
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 "You *must* have the plib library installed on your system to build"
echo "SimGear!"
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "Please see README.plib for more details."
echo
echo "configure aborted."
@@ -475,18 +482,18 @@ LIBS="$saved_LIBS"
case "${host}" in
*-apple-darwin*)
if test "x$with_osg_framework" != "x"; then
AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/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(osgFX, [#include <osgFX/AnisotropicLighting>], $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(osgSim, [#include <osgSim/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework)
AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
osg_FRAMEWORKS="$FRAMEWORKS"
FRAMEWORKS=""
AC_SUBST(osg_FRAMEWORKS)
# AC_CHECK_FRAMEWORK(osgViewer, [#include <osgViewer/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(osgFX, [#include <osgFX/AnisotropicLighting>], $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(osgSim, [#include <osgSim/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osgParticle, [#include <osgParticle/Version>], $with_osg_framework)
# AC_CHECK_FRAMEWORK(osg, [#include <osg/Version>], $with_osg_framework)
# osg_FRAMEWORKS="$FRAMEWORKS"
# FRAMEWORKS=""
# AC_SUBST(osg_FRAMEWORKS)
AC_CHECK_FRAMEWORK(OpenThreads, [#include <OpenThreads/Version>], $with_osg_framework)
openthreads_FRAMEWORK="$FRAMEWORKS"
FRAMEWORKS=""
@@ -496,18 +503,33 @@ case "${host}" in
dnl This is needed when osg dynamic libs are specified
dnl instead of OSG frameworks on Mac OS X
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
;;
esac
AM_CONDITIONAL(HAVE_FRAMEWORK_OSG, test "x$ac_cv_framework_osg" != "x")
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
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 " 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 "Please see README.OSG for more details."
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 "to build this version of SimGear!"
echo
echo " LIBS: '$LIBS'"
echo " LDFLAGS: '$LDFLAGS'"
echo " CPPFLAGS: '$CPPFLAGS'"
echo
echo "configure aborted."
exit
fi

View File

@@ -1,5 +0,0 @@
Debug
Release
SimGear.ncb
SimGear.suo
*.user

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

View File

@@ -28,6 +28,7 @@
#include "visual_enviro.hxx"
#include <simgear/constants.h>
#include <osg/ClipNode>
/**
* @brief SGPrecipitation constructor
@@ -35,7 +36,7 @@
* Build a new OSG object from osgParticle.
*/
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;
}
@@ -54,7 +55,20 @@ osg::Group* SGPrecipitation::build(void)
_precipitationEffect->snow(0);
_precipitationEffect->rain(0);
group->addChild(_precipitationEffect.get());
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());
}
return group;
}

View File

@@ -39,6 +39,7 @@ private:
float _snow_intensity;
float _rain_intensity;
float _clip_distance;
int _wind_dir;
osg::Vec3 _wind_vec;

View File

@@ -24,6 +24,7 @@
#include <math.h>
#include <simgear/magvar/magvar.hxx>
#include <simgear/math/SGMath.hxx>
#include "coremag.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]));
}
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 ) {
// cout << "lat = " << lat << " lon = " << lon << " elev = " << alt_m

View File

@@ -33,6 +33,9 @@
#endif
// forward decls
class SGGeod;
/**
* Magnetic variation wrapper class.
*
@@ -78,6 +81,11 @@ public:
*/
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. */
double get_magvar() const { return magvar; }

View File

@@ -71,6 +71,14 @@ public:
(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
SGVec3<T> getCenter() const

View File

@@ -38,25 +38,11 @@ intersects(const SGBox<T1>& box, const SGSphere<T2>& sphere)
{
if (sphere.empty())
return false;
// Is more or less trivially included in the next tests
// 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())
if (box.empty())
return false;
if (box.getMax().x() + sphere.getRadius() < sphere.getCenter().x())
return false;
if (box.getMax().y() + sphere.getRadius() < sphere.getCenter().y())
return false;
if (box.getMax().z() + sphere.getRadius() < sphere.getCenter().z())
return false;
return true;
SGVec3<T1> closest = box.getClosestPoint(sphere.getCenter());
return distSqr(closest, SGVec3<T1>(sphere.getCenter())) <= sphere.getRadius2();
}
// make it symmetric
template<typename T1, typename T2>

View File

@@ -15,7 +15,7 @@ libsgprops_a_SOURCES = \
props_io.cxx \
AtomicChangeListener.cxx
noinst_PROGRAMS = props_test
check_PROGRAMS = props_test
props_test_SOURCES = props_test.cxx
props_test_LDADD = \

View File

@@ -94,7 +94,7 @@ public:
template<typename 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 max = path.end();
@@ -118,15 +118,24 @@ parse_name (const Range &path)
} else if (*i == '[' || *i == '/') {
break;
} 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++;
}
}
else {
if (path.begin() == i)
throw string("name must begin with alpha or '_'");
if (path.begin() == i) {
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);
}
@@ -268,7 +277,7 @@ find_node_aux(SGPropertyNode * current, SplitItr& itr, bool create,
// Empty name at this point is empty, not root.
if (token.empty())
return find_node_aux(current, ++itr, create, last_index);
Range name = parse_name(token);
Range name = parse_name(current, token);
if (equals(name, "."))
return find_node_aux(current, ++itr, create, last_index);
if (equals(name, "..")) {
@@ -1027,17 +1036,22 @@ SGPropertyNode::getDisplayName (bool simplify) const
}
const char *
string
SGPropertyNode::getPath (bool simplify) const
{
// Calculate the complete path only once.
if (_parent != 0 && _path.empty()) {
_path = _parent->getPath(simplify);
_path += '/';
_path += getDisplayName(simplify);
typedef std::vector<SGConstPropertyNode_ptr> PList;
PList pathList;
for (const SGPropertyNode* node = this; node->_parent; node = node->_parent)
pathList.push_back(node);
string result;
for (PList::reverse_iterator itr = pathList.rbegin(),
rend = pathList.rend();
itr != rend;
++itr) {
result += '/';
result += (*itr)->getDisplayName(simplify);
}
return _path.c_str();
return result;
}
props::Type

View File

@@ -994,7 +994,7 @@ public:
/**
* 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 _removedChildren;
std::vector<hash_table *> _linkedNodes;
mutable std::string _path;
mutable std::string _buffer;
hash_table * _path_cache;
simgear::props::Type _type;

View File

@@ -130,6 +130,12 @@ public:
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
* placeholder for the user to stash a distance value. This is useful

View File

@@ -148,9 +148,9 @@ private:
osg::Geometry* geometry = new osg::Geometry;
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->push_back(triangle.getVertex(0).osg());
vertices->push_back(triangle.getVertex(1).osg());
vertices->push_back(triangle.getVertex(2).osg());
vertices->push_back(toOsg(triangle.getVertex(0)));
vertices->push_back(toOsg(triangle.getVertex(1)));
vertices->push_back(toOsg(triangle.getVertex(2)));
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(color);
@@ -172,7 +172,7 @@ private:
return;
SGSphered sphere = node.getBoundingSphere();
osg::Sphere* shape = new osg::Sphere;
shape->setCenter(SGVec3f(sphere.getCenter()).osg());
shape->setCenter(toOsg(sphere.getCenter()));
shape->setRadius(sphere.getRadius());
addShape(shape, osg::Vec4(0.5f, 0.5f, 0.5f, 0.1f));
}
@@ -184,8 +184,8 @@ private:
BVHBoundingBoxVisitor bbv;
node.accept(bbv, data);
osg::Box* shape = new osg::Box;
shape->setCenter(bbv.getBox().getCenter().osg());
shape->setHalfLengths((0.5*bbv.getBox().getSize()).osg());
shape->setCenter(toOsg(bbv.getBox().getCenter()));
shape->setHalfLengths(toOsg((0.5*bbv.getBox().getSize())));
addShape(shape, osg::Vec4(0.5f, 0, 0, 0.1f));
}

View File

@@ -51,6 +51,7 @@
#include <osg/RenderInfo>
#include <osg/ShadeModel>
#include <osg/StateSet>
#include <osg/Stencil>
#include <osg/TexEnv>
#include <osg/Texture1D>
#include <osg/Texture2D>
@@ -65,6 +66,7 @@
#include <osgDB/ReadFile>
#include <osgDB/Registry>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
@@ -96,6 +98,8 @@ Effect::Effect(const Effect& rhs, const CopyOp& copyop)
itr != end;
++itr)
techniques.push_back(static_cast<Technique*>(copyop(itr->get())));
generator = rhs.generator;
}
// Assume that the last technique is always valid.
@@ -108,6 +112,13 @@ StateSet* Effect::getDefaultStateSet()
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.
Technique* Effect::chooseTechnique(RenderInfo* info)
@@ -142,7 +153,7 @@ Effect::~Effect()
}
void buildPass(Effect* effect, Technique* tniq, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
Pass* pass = new 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)
{
if (prop->nChildren() == 0) {
@@ -187,12 +202,12 @@ osg::Vec4f getColor(const SGPropertyNode* prop)
struct LightingBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
};
void LightingBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp)
@@ -206,7 +221,7 @@ InstallAttributeBuilder<LightingBuilder> installLighting("lighting");
struct ShadeModelBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp)
@@ -228,7 +243,7 @@ InstallAttributeBuilder<ShadeModelBuilder> installShadeModel("shade-model");
struct CullFaceBuilder : PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp) {
@@ -253,6 +268,24 @@ struct CullFaceBuilder : PassAttributeBuilder
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[] =
{
{ "default", StateSet::DEFAULT_BIN },
@@ -265,7 +298,7 @@ EffectPropertyMap<StateSet::RenderingHint> renderingHints(renderingHintInit);
struct HintBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp)
@@ -281,7 +314,7 @@ InstallAttributeBuilder<HintBuilder> installHint("rendering-hint");
struct RenderBinBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
@@ -308,7 +341,7 @@ InstallAttributeBuilder<RenderBinBuilder> installRenderBin("render-bin");
struct MaterialBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
};
EffectNameValue<Material::ColorMode> colorModeInit[] =
@@ -324,7 +357,7 @@ EffectPropertyMap<Material::ColorMode> colorModes(colorModeInit);
void MaterialBuilder::buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
@@ -394,7 +427,7 @@ EffectPropertyMap<BlendFunc::BlendFuncMode> blendFuncModes(blendFuncModesInit);
struct BlendBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
@@ -475,6 +508,99 @@ struct BlendBuilder : public PassAttributeBuilder
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[] =
{
{"never", AlphaFunc::NEVER},
@@ -492,7 +618,7 @@ alphaComparison(alphaComparisonInit);
struct AlphaTestBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
@@ -603,18 +729,41 @@ void reload_shaders()
struct ShaderProgramBuilder : PassAttributeBuilder
{
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,
const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options*
const SGReaderWriterXMLOptions*
options)
{
using namespace boost;
if (!isAttributeActive(effect, prop))
return;
PropertyList pVertShaders = prop->getChildren("vertex-shader");
PropertyList pGeomShaders = prop->getChildren("geometry-shader");
PropertyList pFragShaders = prop->getChildren("fragment-shader");
PropertyList pAttributes = prop->getChildren("attribute");
ProgramKey prgKey;
@@ -624,6 +773,12 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
++itr)
prgKey.shaders.push_back(ShaderKey((*itr)->getStringValue(),
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(),
e = pFragShaders.end();
itr != e;
@@ -655,7 +810,7 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
// Add vertex shaders, then fragment shaders
PropertyList& pvec = pVertShaders;
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();
nameItr != e;
++nameItr) {
@@ -676,13 +831,35 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
}
}
}
pvec = pFragShaders;
stype = Shader::FRAGMENT;
if (i == 0) {
pvec = pGeomShaders;
stype = Shader::GEOMETRY;
} else {
pvec = pFragShaders;
stype = Shader::FRAGMENT;
}
}
BOOST_FOREACH(const ProgramKey::AttribKey& key, prgKey.attributes) {
program->addBindAttribLocation(key.first, key.second);
}
programMap.insert(ProgramMap::value_type(prgKey, program));
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));
}
pass->setAttributeAndModes(program);
}
@@ -695,22 +872,24 @@ EffectNameValue<Uniform::Type> uniformTypesInit[] =
{"float-vec3", Uniform::FLOAT_VEC3},
{"float-vec4", Uniform::FLOAT_VEC4},
{"sampler-1d", Uniform::SAMPLER_1D},
{"sampler-1d-shadow", Uniform::SAMPLER_1D_SHADOW},
{"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);
struct UniformBuilder :public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
const SGPropertyNode* nameProp = prop->getChild("name");
const SGPropertyNode* typeProp = prop->getChild("type");
const SGPropertyNode* valProp
= getEffectPropertyChild(effect, prop, "value");
const SGPropertyNode* valProp = prop->getChild("value");
string name;
Uniform::Type uniformType = Uniform::FLOAT;
if (nameProp) {
@@ -749,18 +928,29 @@ struct UniformBuilder :public PassAttributeBuilder
uniform->setType(uniformType);
switch (uniformType) {
case Uniform::FLOAT:
uniform->set(valProp->getValue<float>());
initFromParameters(effect, valProp, uniform.get(),
static_cast<bool (Uniform::*)(float)>(&Uniform::set),
options);
break;
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;
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;
case Uniform::SAMPLER_1D:
case Uniform::SAMPLER_2D:
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;
default: // avoid compiler warning
break;
@@ -777,7 +967,7 @@ InstallAttributeBuilder<UniformBuilder> installUniform("uniform");
struct NameBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
// name can't use <use>
string name = prop->getStringValue();
@@ -799,7 +989,7 @@ EffectPropertyMap<PolygonMode::Mode> polygonModeModes(polygonModeModesInit);
struct PolygonModeBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
@@ -827,7 +1017,7 @@ InstallAttributeBuilder<PolygonModeBuilder> installPolygonMode("polygon-mode");
struct VertexProgramTwoSideBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp)
@@ -844,7 +1034,7 @@ installTwoSide("vertex-program-two-side");
struct VertexProgramPointSizeBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
const SGPropertyNode* realProp = getEffectPropertyNode(effect, prop);
if (!realProp)
@@ -874,7 +1064,7 @@ EffectPropertyMap<Depth::Function> depthFunction(depthFunctionInit);
struct DepthBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
@@ -905,7 +1095,7 @@ struct DepthBuilder : public PassAttributeBuilder
InstallAttributeBuilder<DepthBuilder> installDepth("depth");
void buildTechnique(Effect* effect, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
Technique* tniq = new Technique;
effect->techniques.push_back(tniq);
@@ -1011,7 +1201,7 @@ bool makeParametersFromStateSet(SGPropertyNode* effectRoot, const StateSet* ss)
// Walk the techniques property tree, building techniques and
// passes.
bool Effect::realizeTechniques(const osgDB::ReaderWriter::Options* options)
bool Effect::realizeTechniques(const SGReaderWriterXMLOptions* options)
{
if (_isRealized)
return true;
@@ -1089,14 +1279,15 @@ osgDB::RegisterDotOsgWrapperProxy effectProxy
}
// Property expressions for technique predicates
class PropertyExpression : public SGExpression<bool>
template<typename T>
class PropertyExpression : public SGExpression<T>
{
public:
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:
SGPropertyNode_ptr _pnode;
@@ -1115,12 +1306,13 @@ protected:
osg::ref_ptr<Technique> _tniq;
};
template<typename T>
Expression* propertyExpressionParser(const SGPropertyNode* exp,
expression::Parser* parser)
{
SGPropertyNode_ptr pnode = getPropertyRoot()->getNode(exp->getStringValue(),
true);
PropertyExpression* pexp = new PropertyExpression(pnode);
PropertyExpression<T>* pexp = new PropertyExpression<T>(pnode);
TechniquePredParser* predParser
= dynamic_cast<TechniquePredParser*>(parser);
if (predParser)
@@ -1130,6 +1322,9 @@ Expression* propertyExpressionParser(const SGPropertyNode* exp,
}
expression::ExpParserRegistrar propertyRegistrar("property",
propertyExpressionParser);
propertyExpressionParser<bool>);
expression::ExpParserRegistrar propvalueRegistrar("float-property",
propertyExpressionParser<float>);
}

View File

@@ -45,6 +45,7 @@ namespace simgear
{
class Technique;
class Effect;
class SGReaderWriterXMLOptions;
/**
* Object to be initialized at some point after an effect -- and its
@@ -79,6 +80,18 @@ public:
Effect(const Effect& rhs,
const osg::CopyOp& copyop = osg::CopyOp::SHALLOW_COPY);
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;
SGPropertyNode_ptr root;
// Pointer to the parameters node, if it exists
@@ -89,7 +102,7 @@ public:
/**
* 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
* deleted. Updaters arrange to be run by listening on properties
@@ -144,7 +157,7 @@ protected:
Cache* _cache;
friend size_t hash_value(const Key& key);
friend Effect* makeEffect(SGPropertyNode* prop, bool realizeTechniques,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
bool _isRealized;
};
// Automatic support for boost hash function
@@ -153,11 +166,11 @@ size_t hash_value(const Effect::Key&);
Effect* makeEffect(const std::string& name,
bool realizeTechniques,
const osgDB::ReaderWriter::Options* options = 0);
const SGReaderWriterXMLOptions* options = 0);
Effect* makeEffect(SGPropertyNode* prop,
bool realizeTechniques,
const osgDB::ReaderWriter::Options* options = 0);
const SGReaderWriterXMLOptions* options = 0);
bool makeParametersFromStateSet(SGPropertyNode* paramRoot,
const osg::StateSet* ss);

View File

@@ -2,6 +2,7 @@
# include <simgear_config.h>
#endif
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/math/SGMath.hxx>
@@ -41,13 +42,29 @@ const SGPropertyNode* getEffectPropertyChild(Effect* effect,
return getEffectPropertyNode(effect, child);
}
string getGlobalProperty(const SGPropertyNode* prop)
string getGlobalProperty(const SGPropertyNode* prop,
const SGReaderWriterXMLOptions* options)
{
if (!prop)
return string();
const SGPropertyNode* useProp = prop->getChild("use");
if (!useProp)
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();
}

View File

@@ -33,6 +33,7 @@
#include <simgear/math/SGMath.hxx>
#include <simgear/props/AtomicChangeListener.hxx>
#include <simgear/props/props.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/Singleton.hxx>
@@ -46,6 +47,7 @@ namespace simgear
{
class Effect;
class Pass;
class SGReaderWriterXMLOptions;
/**
* Builder that returns an object, probably an OSG object.
@@ -56,10 +58,10 @@ class EffectBuilder : public SGReferenced
public:
virtual ~EffectBuilder() {}
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,
const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
BuilderMap& builderMap = getMap();
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));
}
// 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
{
public:
@@ -201,6 +218,42 @@ void findAttr(const effect::EffectPropertyMap<T>& pMap,
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>
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
* 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
{
@@ -255,7 +346,7 @@ protected:
public:
virtual void buildAttribute(Effect* effect, Pass* pass,
const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
= 0;
static PassAttributeBuilder* find(const std::string& str)
{
@@ -289,64 +380,116 @@ bool isAttributeActive(Effect* effect, const SGPropertyNode* prop);
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>
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<>
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<>
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<>
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;
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&))
OSGFunctor(Obj* obj, const 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;
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
: public SGPropertyChangeListener, public InitializeWhenAdded,
public Effect::Updater
{
public:
typedef void (ObjType::*setter_type)(const OSGParamType);
ScalarChangeListener(ObjType* obj, setter_type setter,
ScalarChangeListener(ObjType* obj, const F& setter,
const std::string& propName)
: _obj(obj), _setter(setter)
{
@@ -359,7 +502,7 @@ public:
}
void valueChanged(SGPropertyNode* node)
{
_obj->*setter(node->getValue<OSGParamType>());
_setter(_obj.get(), node->getValue<OSGParamType>());
}
void initOnAddImpl(Effect* effect, SGPropertyNode* propRoot)
{
@@ -371,7 +514,7 @@ public:
}
private:
osg::ref_ptr<ObjType> _obj;
setter_type _setter;
F _setter;
std::string* _propName;
};
@@ -382,11 +525,12 @@ class EffectExtendedPropListener : public InitializeWhenAdded,
public:
template<typename Itr>
EffectExtendedPropListener(const Func& func,
const std::string& propName, Itr childNamesBegin,
const std::string* propName, Itr childNamesBegin,
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,
childNamesEnd);
}
@@ -397,7 +541,11 @@ public:
}
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
= new ExtendedPropListener<T, Func>(parent, _childNames->begin(),
_childNames->end(),
@@ -414,6 +562,15 @@ private:
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
* 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;
* 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 ObjType, typename OSGParamType>
template<typename OSGParamType, typename ObjType, typename F>
void
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);
if (!valProp)
return;
if (valProp->nChildren() == 0) {
obj->*setter(valProp->getValue<OSGParamType>());
setter(obj, valProp->getValue<OSGParamType>());
} else {
std::string propName = getGlobalProperty(prop);
ScalarChangeListener<ObjType, OSGParamType>* listener
= new ScalarChangeListener<ObjType, OSGParamType>(obj, setter,
propName);
std::string propName = getGlobalProperty(valProp, options);
ScalarChangeListener<OSGParamType, ObjType, F>* listener
= new ScalarChangeListener<OSGParamType, ObjType, F>(obj, setter,
propName);
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
initFromParameters(Effect* effect, const SGPropertyNode* prop, ObjType* obj,
void (ObjType::*setter)(const OSGParamType&),
NameItrType nameItr)
const F& setter,
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);
if (!valProp)
return;
if (valProp->nChildren() == 0) {
(obj->*setter)(OSGBridge<OSGParamType>
::getOsgType(valProp->getValue<sg_type>()));
if (valProp->nChildren() == 0) { // Has <use>?
setter(obj, Bridge<OSGParamType>::get(valProp->getValue<sg_type>()));
} else {
string listenPropName = getGlobalProperty(valProp);
if (listenPropName.empty())
return;
typedef OSGFunctor<ObjType, OSGParamType> Functor;
std::vector<std::string> paramNames
= getVectorProperties(valProp, options,numComponents, nameItr);
if (paramNames.empty())
throw BuilderException();
std::vector<std::string>::const_iterator pitr = paramNames.begin();
Effect::Updater* listener
= new EffectExtendedPropListener<sg_type, Functor>
(Functor(obj, setter), listenPropName, nameItr,
nameItr + props::NumComponents<sg_type>::num_components);
= new_EEPropListener<sg_type>(make_OSGFunctor<OSGParamType>
(obj, setter),
0, pitr, pitr + numComponents);
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[];
}
}

View File

@@ -23,6 +23,7 @@
#include "Technique.hxx"
#include <osgUtil/CullVisitor>
#include <osgUtil/TangentSpaceGenerator>
#include <osgDB/Registry>
#include <osgDB/Input>
@@ -66,6 +67,31 @@ void EffectGeode::releaseGLObjects(osg::State* state) const
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)
{
const EffectGeode& eg = static_cast<const EffectGeode&>(obj);

View File

@@ -37,6 +37,7 @@ public:
typedef DrawableList::iterator DrawablesIterator;
DrawablesIterator drawablesBegin() { return _drawables.begin(); }
DrawablesIterator drawablesEnd() { return _drawables.end(); }
void runGenerators(osg::Geometry *geometry);
private:
osg::ref_ptr<Effect> _effect;
};

View File

@@ -30,6 +30,6 @@ libsgmaterial_a_SOURCES = \
mat.cxx \
matlib.cxx \
matmodel.cxx \
Noise.cxx
Noise.cxx Noise.hxx
INCLUDES = -I$(top_srcdir)

View File

@@ -59,7 +59,7 @@ Technique::Technique(bool alwaysValid)
Technique::Technique(const Technique& rhs, const osg::CopyOp& copyop) :
_contextMap(rhs._contextMap), _alwaysValid(rhs._alwaysValid),
_shadowingStateSet(copyop(rhs._shadowingStateSet)),
_shadowingStateSet(copyop(rhs._shadowingStateSet.get())),
_validExpression(rhs._validExpression),
_contextIdLocation(rhs._contextIdLocation)
{

View File

@@ -29,12 +29,14 @@
#include <osg/Texture2D>
#include <osg/Texture3D>
#include <osg/TextureRectangle>
#include <osg/TextureCubeMap>
#include <osgDB/FileUtils>
#include <boost/lexical_cast.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/tuple/tuple_comparison.hpp>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/math/SGMath.hxx>
@@ -50,13 +52,14 @@ using namespace osg;
using namespace effect;
TexEnvCombine* buildTexEnvCombine(Effect* effect,
const SGPropertyNode* envProp);
const SGPropertyNode* envProp,
const SGReaderWriterXMLOptions* options);
TexGen* buildTexGen(Effect* Effect, const SGPropertyNode* tgenProp);
// Hack to force inclusion of TextureBuilder.cxx in library
osg::Texture* TextureBuilder::buildFromType(Effect* effect, const string& type,
const SGPropertyNode*props,
const osgDB::ReaderWriter::Options*
const SGReaderWriterXMLOptions*
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,
const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
if (!isAttributeActive(effect, prop))
return;
@@ -141,7 +144,8 @@ void TextureUnitBuilder::buildAttribute(Effect* effect, Pass* pass,
}
const SGPropertyNode* combineProp = prop->getChild("texenv-combine");
TexEnvCombine* combiner = 0;
if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp))))
if (combineProp && ((combiner = buildTexEnvCombine(effect, combineProp,
options))))
pass->setTextureAttributeAndModes(unit, combiner);
const SGPropertyNode* tgenProp = prop->getChild("texgen");
TexGen* tgen = 0;
@@ -177,7 +181,7 @@ EffectPropertyMap<Texture::WrapMode> wrapModes(wrapModesInit);
TexTuple makeTexTuple(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options,
const SGReaderWriterXMLOptions* options,
const string& texType)
{
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,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
const string& imageName = attrs.get<0>();
if (imageName.empty()) {
@@ -253,7 +257,7 @@ class TexBuilder : public TextureBuilder
public:
TexBuilder(const string& texType) : _type(texType) {}
Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
protected:
typedef map<TexTuple, ref_ptr<T> > TexMap;
TexMap texMap;
@@ -262,7 +266,7 @@ protected:
template<typename T>
Texture* TexBuilder<T>::build(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
TexTuple attrs = makeTexTuple(effect, props, options, _type);
typename TexMap::iterator itr = texMap.find(attrs);
@@ -286,11 +290,11 @@ class WhiteTextureBuilder : public TextureBuilder
{
public:
Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
};
Texture* WhiteTextureBuilder::build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
return StateAttributeFactory::instance()->getWhiteTexture();
}
@@ -304,11 +308,11 @@ class TransparentTextureBuilder : public TextureBuilder
{
public:
Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
};
Texture* TransparentTextureBuilder::build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
return StateAttributeFactory::instance()->getTransparentTexture();
}
@@ -368,14 +372,14 @@ class NoiseBuilder : public TextureBuilder
{
public:
Texture* build(Effect* effect, const SGPropertyNode*,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
protected:
typedef map<int, ref_ptr<Texture3D> > NoiseMap;
NoiseMap _noises;
};
Texture* NoiseBuilder::build(Effect* effect, const SGPropertyNode* props,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
int texSize = 64;
const SGPropertyNode* sizeProp = getEffectPropertyChild(effect, props,
@@ -401,6 +405,114 @@ namespace
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[] =
{
{"replace", TexEnvCombine::REPLACE},
@@ -443,7 +555,8 @@ EffectNameValue<TexEnvCombine::OperandParam> 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))
return 0;
@@ -538,7 +651,8 @@ TexEnvCombine* buildTexEnvCombine(Effect* effect, const SGPropertyNode* envProp)
const SGPropertyNode* colorNode = envProp->getChild("constant-color");
if (colorNode)
initFromParameters(effect, colorNode, result,
&TexEnvCombine::setConstantColor, colorFields);
&TexEnvCombine::setConstantColor, colorFields,
options);
return result;
}

View File

@@ -29,13 +29,13 @@ public:
// Hack to force inclusion of TextureBuilder.cxx in library
static osg::Texture* buildFromType(Effect* effect, const std::string& type,
const SGPropertyNode*props,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
};
struct TextureUnitBuilder : public PassAttributeBuilder
{
void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
};

View File

@@ -31,6 +31,7 @@
#include <osgDB/Registry>
#include <simgear/debug/logstream.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx>
#include <simgear/scene/util/SplicingVisitor.hxx>
@@ -116,7 +117,7 @@ void mergePropertyTrees(SGPropertyNode* resultNode,
Effect* makeEffect(const string& name,
bool realizeTechniques,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
{
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex);
@@ -159,7 +160,7 @@ Effect* makeEffect(const string& name,
Effect* makeEffect(SGPropertyNode* prop,
bool realizeTechniques,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
// Give default names to techniques and passes
vector<SGPropertyNode_ptr> techniques = prop->getChildren("technique");
@@ -204,8 +205,10 @@ Effect* makeEffect(SGPropertyNode* prop,
lock(effectMutex);
cache = parent->getCache();
itr = cache->find(key);
if (itr != cache->end())
if (itr != cache->end()) {
effect = itr->second.get();
effect->generator = parent->generator; // Copy the generators
}
}
if (!effect.valid()) {
effect = new Effect;
@@ -218,6 +221,7 @@ Effect* makeEffect(SGPropertyNode* prop,
= cache->insert(make_pair(key, effect));
if (!irslt.second)
effect = irslt.first->second;
effect->generator = parent->generator; // Copy the generators
}
} else {
SG_LOG(SG_INPUT, SG_ALERT, "can't find base effect " <<
@@ -229,6 +233,21 @@ Effect* makeEffect(SGPropertyNode* prop,
effect->root = prop;
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) {
try {
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex>

View File

@@ -49,6 +49,7 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sgstream.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
@@ -67,13 +68,25 @@ using namespace simgear;
// Constructors and destructor.
////////////////////////////////////////////////////////////////////////
SGMaterial::_internal_state::_internal_state(Effect *e, const string &t, bool l,
const osgDB::ReaderWriter::Options* o ) :
effect(e), texture_path(t), effect_realized(l), options(o)
SGMaterial::_internal_state::_internal_state(Effect *e, bool l,
const SGReaderWriterXMLOptions* 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 )
{
init();
@@ -81,6 +94,17 @@ SGMaterial::SGMaterial( const osgDB::ReaderWriter::Options* 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)
{
}
@@ -91,7 +115,7 @@ SGMaterial::~SGMaterial (void)
////////////////////////////////////////////////////////////////////////
void
SGMaterial::read_properties(const osgDB::ReaderWriter::Options* options,
SGMaterial::read_properties(const SGReaderWriterXMLOptions* options,
const SGPropertyNode *props)
{
// 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");
tpath.append("Terrain");
tpath.append("unknown.rgb");
@@ -245,10 +296,12 @@ Effect* SGMaterial::get_effect(int n)
return _status[i].effect.get();
}
void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options*
options)
void SGMaterial::buildEffectProperties(const SGReaderWriterXMLOptions* options)
{
using namespace osg;
ref_ptr<SGReaderWriterXMLOptions> xmlOptions;
if (options)
xmlOptions = new SGReaderWriterXMLOptions(*options);
ref_ptr<SGMaterialUserData> user = new SGMaterialUserData(this);
SGPropertyNode_ptr propRoot = new SGPropertyNode();
makeChild(propRoot, "inherits-from")->setStringValue(effect);
@@ -271,15 +324,22 @@ void SGMaterial::buildEffectProperties(const osgDB::ReaderWriter::Options*
SGPropertyNode_ptr effectProp = new SGPropertyNode();
copyProperties(propRoot, effectProp);
SGPropertyNode* effectParamProp = effectProp->getChild("parameters", 0);
SGPropertyNode* texProp = makeChild(effectParamProp, "texture");
makeChild(texProp, "image")->setStringValue(matState.texture_path);
makeChild(texProp, "filter")
->setStringValue(mipmap ? "linear-mipmap-linear" : "nearest");
makeChild(texProp, "wrap-s")
->setStringValue(wrapu ? "repeat" : "clamp");
makeChild(texProp, "wrap-t")
->setStringValue(wrapv ? "repeat" : "clamp");
matState.effect = makeEffect(effectProp, false, options);
for (unsigned int i = 0; i < matState.texture_paths.size(); i++) {
SGPropertyNode* texProp = makeChild(effectParamProp, "texture", matState.texture_paths[i].second);
makeChild(texProp, "image")->setStringValue(matState.texture_paths[i].first);
makeChild(texProp, "filter")
->setStringValue(mipmap ? "linear-mipmap-linear" : "nearest");
makeChild(texProp, "wrap-s")
->setStringValue(wrapu ? "repeat" : "clamp");
makeChild(texProp, "wrap-t")
->setStringValue(wrapv ? "repeat" : "clamp");
}
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());
}
}

View File

@@ -39,13 +39,13 @@
#include <simgear/math/SGMath.hxx>
#include <osg/ref_ptr>
#include <osgDB/ReaderWriter>
namespace osg
{
class StateSet;
}
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/props/props.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/scene/util/SGSceneFeatures.hxx>
@@ -87,6 +87,8 @@ public:
*/
SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props);
SGMaterial(const simgear::SGReaderWriterXMLOptions*,
const SGPropertyNode *props);
/**
* Destructor.
*/
@@ -270,12 +272,15 @@ protected:
protected:
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,
const osgDB::ReaderWriter::Options *o);
const simgear::SGReaderWriterXMLOptions *o);
void add_texture(const std::string &t, int i);
osg::ref_ptr<simgear::Effect> effect;
std::string texture_path;
std::vector<std::pair<std::string,int> > texture_paths;
bool effect_realized;
osg::ref_ptr<const osgDB::ReaderWriter::Options> options;
osg::ref_ptr<const simgear::SGReaderWriterXMLOptions> options;
};
private:
@@ -361,9 +366,9 @@ private:
// Internal constructors and methods.
////////////////////////////////////////////////////////////////////
void read_properties(const osgDB::ReaderWriter::Options* options,
void read_properties(const simgear::SGReaderWriterXMLOptions* options,
const SGPropertyNode *props);
void buildEffectProperties(const osgDB::ReaderWriter::Options* options);
void buildEffectProperties(const simgear::SGReaderWriterXMLOptions* options);
};

View File

@@ -135,14 +135,11 @@ SGMatModel::load_models( SGPropertyNode *prop_root )
}
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
int nModels = _models.size();
int index = int(sg_random() * nModels);
if (index >= nModels)
index = 0;
return _models[index].get();
return _models[mt_rand(&seed) * nModels].get();
}
double

View File

@@ -82,7 +82,7 @@ public:
*
* @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 );
/**

View File

@@ -27,6 +27,7 @@ include_HEADERS = \
libsgmodel_a_SOURCES = \
animation.cxx \
BoundingVolumeBuildVisitor.hxx \
particles.cxx \
model.cxx \
modellib.cxx \

View File

@@ -98,7 +98,7 @@ public:
_bvhPolicy.buildBVH(fileName, optimizedNode.get());
_cachePolicy.addToCache(fileName, optimizedNode.get());
}
return ReaderWriter::ReadResult(optimizedNode);
return ReaderWriter::ReadResult(optimizedNode.get());
}
protected:
static osgDB::ReaderWriter::ReadResult

View File

@@ -70,8 +70,18 @@ public:
osg::ref_ptr<osg::RefMatrix> mModelView;
};
osgUtil::RegisterRenderBinProxy
SGClipGroup::clipBinProxy("ClipRenderBin", new SGClipGroup::ClipRenderBin);
struct SGClipGroup::ClipBinRegistrar
{
ClipBinRegistrar()
{
osgUtil::RenderBin
::addRenderBinPrototype("ClipRenderBin",
new SGClipGroup::ClipRenderBin);
}
static ClipBinRegistrar registrar;
};
SGClipGroup::ClipBinRegistrar SGClipGroup::ClipBinRegistrar::registrar;
class SGClipGroup::CullCallback : public osg::NodeCallback {
public:

View File

@@ -49,10 +49,8 @@ public:
protected:
class CullCallback;
class ClipRenderBin;
struct ClipBinRegistrar;
std::vector<osg::ref_ptr<osg::ClipPlane> > mClipPlanes;
static osgUtil::RegisterRenderBinProxy clipBinProxy;
};
#endif

View File

@@ -18,7 +18,7 @@
#ifndef SGREADERWRITERXMLOPTIONS_HXX
#define SGREADERWRITERXMLOPTIONS_HXX 1
#include <osgDB/ReaderWriter>
#include <osgDB/Registry>
#include <simgear/scene/model/modellib.hxx>
#include <simgear/props/props.hxx>

View File

@@ -33,6 +33,7 @@
#include <simgear/props/props_io.hxx>
#include <simgear/props/condition.hxx>
#include "SGReaderWriterXMLOptions.hxx"
#include "model.hxx"
using std::vector;
@@ -209,7 +210,7 @@ class MakeEffectVisitor : public SplicingVisitor
public:
typedef std::map<string, SGPropertyNode_ptr> EffectMap;
using SplicingVisitor::apply;
MakeEffectVisitor(const osgDB::ReaderWriter::Options* options = 0)
MakeEffectVisitor(const SGReaderWriterXMLOptions* options = 0)
: _options(options)
{
}
@@ -225,7 +226,7 @@ public:
protected:
EffectMap _effectMap;
SGPropertyNode_ptr _currentEffectParent;
osg::ref_ptr<const osgDB::ReaderWriter::Options> _options;
osg::ref_ptr<const SGReaderWriterXMLOptions> _options;
};
void MakeEffectVisitor::apply(osg::Group& node)
@@ -263,7 +264,7 @@ void MakeEffectVisitor::apply(osg::Geode& geode)
makeParametersFromStateSet(ssRoot, ss);
SGPropertyNode_ptr effectRoot = new SGPropertyNode;
effect::mergePropertyTrees(effectRoot, ssRoot, _currentEffectParent);
Effect* effect = makeEffect(effectRoot, true, _options);
Effect* effect = makeEffect(effectRoot, true, _options.get());
EffectGeode* eg = dynamic_cast<EffectGeode*>(&geode);
if (eg) {
eg->setEffect(effect);
@@ -273,8 +274,14 @@ void MakeEffectVisitor::apply(osg::Geode& geode)
ref_ptr<SGSceneUserData> userData = SGSceneUserData::getSceneUserData(&geode);
if (userData.valid())
eg->setUserData(new SGSceneUserData(*userData));
for (int i = 0; i < geode.getNumDrawables(); ++i)
eg->addDrawable(geode.getDrawable(i));
for (int i = 0; i < geode.getNumDrawables(); ++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);
@@ -302,7 +309,7 @@ protected:
ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
PropertyList& effectProps,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
SGPropertyNode_ptr defaultEffectPropRoot;
MakeEffectVisitor visitor(options);

View File

@@ -23,6 +23,11 @@
#include <simgear/props/props.hxx>
#include <simgear/scene/util/NodeAndDrawableVisitor.hxx>
namespace simgear
{
class SGReaderWriterXMLOptions;
}
osg::Texture2D*
SGLoadTexture2D(bool staticTexture, const std::string& path,
const osgDB::ReaderWriter::Options* options = 0,
@@ -97,7 +102,7 @@ public:
osg::ref_ptr<osg::Node>
instantiateEffects(osg::Node* model,
PropertyList& effectProps,
const osgDB::ReaderWriter::Options* options);
const SGReaderWriterXMLOptions* options);
/**
* Transform an OSG subgraph by substituting the Effects and
@@ -110,7 +115,7 @@ instantiateEffects(osg::Node* model,
inline osg::ref_ptr<osg::Node>
instantiateEffects(osg::Node* model,
const osgDB::ReaderWriter::Options* options)
const SGReaderWriterXMLOptions* options)
{
PropertyList effectProps;
return instantiateEffects(model, effectProps, options);

View File

@@ -71,8 +71,12 @@ osg::Node* loadFile(const string& path, osgDB::ReaderWriter::Options* options)
ref_ptr<Node> model = readRefNodeFile(path, options);
if (!model)
return 0;
if (boost::iends_with(path, ".ac"))
model = instantiateEffects(model.get(), options);
if (boost::iends_with(path, ".ac")) {
ref_ptr<SGReaderWriterXMLOptions> sgOptions;
if (options)
sgOptions = new SGReaderWriterXMLOptions(*options);
model = instantiateEffects(model.get(), sgOptions.get());
}
return model.release();
}
}

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<osg::Geode> Particles::commonGeode = new osg::Geode;;
osg::Vec3 Particles::_wind;
bool Particles::_frozen = false;
Particles::Particles() :
useGravity(false),
@@ -510,6 +511,8 @@ osg::Group * Particles::appendParticles(const SGPropertyNode* configNode,
void Particles::operator()(osg::Node* node, osg::NodeVisitor* nv)
{
//SG_LOG(SG_GENERAL, SG_ALERT, "callback!\n");
this->particleSys->setFrozen(_frozen);
using namespace osg;
if (shooterValue)
shooter->setInitialSpeedRange(shooterValue->getValue(),

View File

@@ -75,7 +75,7 @@ public:
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv);
static const osg::Vec3 &getGravityVector()
{
return gravity;
@@ -249,6 +249,8 @@ public:
return psu.get();
}
static void setFrozen(bool e) { _frozen = e; }
/**
* Set and get the wind vector for particles in the
* atmosphere. This vector is in the Z-up Y-north frame, and the
@@ -279,6 +281,7 @@ protected:
bool useGravity;
bool useWind;
static bool _frozen;
static osg::ref_ptr<osgParticle::ParticleSystemUpdater> psu;
static osg::ref_ptr<osg::Group> commonRoot;
static osg::ref_ptr<osg::Geode> commonGeode;

View File

@@ -138,7 +138,7 @@ void
SGModelPlacement::setReferenceTime(const double& referenceTime)
{
SGSceneUserData* userData;
userData = SGSceneUserData::getOrCreateSceneUserData(_transform);
userData = SGSceneUserData::getOrCreateSceneUserData(_transform.get());
SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity();
vel->referenceTime = referenceTime;
}
@@ -147,7 +147,7 @@ void
SGModelPlacement::setBodyLinearVelocity(const SGVec3d& linear)
{
SGSceneUserData* userData;
userData = SGSceneUserData::getOrCreateSceneUserData(_transform);
userData = SGSceneUserData::getOrCreateSceneUserData(_transform.get());
SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity();
vel->linear = SGVec3d(-linear[0], linear[1], -linear[2]);
}
@@ -156,7 +156,7 @@ void
SGModelPlacement::setBodyAngularVelocity(const SGVec3d& angular)
{
SGSceneUserData* userData;
userData = SGSceneUserData::getOrCreateSceneUserData(_transform);
userData = SGSceneUserData::getOrCreateSceneUserData(_transform.get());
SGSceneUserData::Velocity* vel = userData->getOrCreateVelocity();
vel->angular = SGVec3d(-angular[0], angular[1], -angular[2]);
}

View File

@@ -132,7 +132,8 @@ bool SGCloudField::reposition( const SGVec3f& p, const SGVec3f& up, double lon,
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;
}

View File

@@ -46,6 +46,7 @@
#include <simgear/misc/PathOptions.hxx>
#include <simgear/props/props.hxx>
#include <simgear/scene/model/model.hxx>
#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx>
@@ -108,9 +109,11 @@ SGNewCloud::SGNewCloud(string type,
"texture"),
"image"),
texture);
osg::ref_ptr<osgDB::ReaderWriter::Options> options
ref_ptr<osgDB::ReaderWriter::Options> options
= 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));
} else {
effect = iter->second.get();

View File

@@ -310,6 +310,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
geode->setName("Ocean tile");
geode->setEffect(effect);
geode->addDrawable(geometry);
geode->runGenerators(geometry);
osg::MatrixTransform* transform = new osg::MatrixTransform;
transform->setName("Ocean");

View File

@@ -333,7 +333,7 @@ TileEntry::loadTileByFileName(const string& fileName,
if (found_tile_base) {
// load tile if found ...
opt->setCalcLights(true);
obj_load( object_base.str(), new_tile, true, opt);
obj_load( object_base.str(), new_tile, true, opt.get());
} else {
// ... or generate an ocean tile on the fly
@@ -354,7 +354,7 @@ TileEntry::loadTileByFileName(const string& fileName,
SGPath custom_path = obj->path;
custom_path.append( obj->name );
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) {
// object loading is deferred to main render thread,

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 - 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;
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;
geometry->setVertexArray(vl);
geometry->setNormalArray(nl);
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()));
EffectGeode* geode = new EffectGeode;
geode->addDrawable(geometry);

View File

@@ -382,6 +382,7 @@ struct SGTileGeometryBin {
if (mat)
eg->setEffect(mat->get_effect());
eg->addDrawable(geometry);
eg->runGenerators(geometry); // Generate extra data needed by effect
if (group)
group->addChild(eg);
}
@@ -610,7 +611,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool
i < tileGeometryBin.randomModels.getNumModels(); i++) {
SGMatModelBin::MatModel obj
= 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
// location, and then apply the rotation matrix created

View File

@@ -194,7 +194,7 @@ Effect* getLightEffect(float size, const Vec3& attenuation,
point->setDistanceAttenuation(attenuation);
attenuationPass->setAttributeAndModes(point);
Pass *spritePass = clone(basicPass, CopyOp::SHALLOW_COPY);
spritePass->setTextureAttributeAndModes(0, pointSprite,
spritePass->setTextureAttributeAndModes(0, pointSprite.get(),
osg::StateAttribute::ON);
Texture2D* texture = gen_standard_light_sprite();
spritePass->setTextureAttribute(0, texture);

View File

@@ -60,8 +60,8 @@ void sgUserDataInit( SGPropertyNode *p ) {
root_props = p;
}
osg::Node* sgGetRandomModel(SGMatModel *obj) {
return obj->get_random_model( root_props );
osg::Node* sgGetRandomModel(SGMatModel *obj, mt seed) {
return obj->get_random_model( root_props, seed );
}
namespace simgear

View File

@@ -26,6 +26,7 @@
#define _SG_USERDATA_HXX
#include <simgear/compiler.h>
#include <simgear/math/sg_random.h>
#include <osg/Node>
@@ -42,7 +43,7 @@ void sgUserDataInit(SGPropertyNode *p);
/**
* Get a random model.
*/
osg::Node* sgGetRandomModel(SGMatModel *obj);
osg::Node* sgGetRandomModel(SGMatModel *obj, mt seed);
namespace simgear
{

View File

@@ -52,8 +52,8 @@ Group* SplicingVisitor::pushResultNode(Group* node, Group* newNode,
result->addChild(itr->get());
}
_childStack.back().push_back(result);
recordNewNode(node, result);
return result;
recordNewNode(node, result.get());
return result.get();
}
Node* SplicingVisitor::pushResultNode(Node* node, Node* newNode)

View File

@@ -41,7 +41,8 @@ TestRenderTexture_SOURCES = TestRenderTexture.cpp
TestRenderTexture_LDADD = \
libsgscreen.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(opengl_LIBS)
$(opengl_LIBS) \
-ldl
endif
INCLUDES = -I$(top_srcdir) -I$(top_builddir) -DGLX_GLXEXT_PROTOTYPES

View File

@@ -121,11 +121,7 @@ void *SGGetGLProcAddress(const char *func) {
libHandle = dlopen(NULL, RTLD_LAZY);
if (!libHandle) {
#if defined (__FreeBSD__)
const char *error = dlerror();
#else
char *error = dlerror();
#endif
if (error) {
SG_LOG(SG_GENERAL, SG_INFO, error);
return 0;
@@ -145,11 +141,7 @@ void *SGGetGLProcAddress(const char *func) {
} else if (libHandle != NULL) {
fptr = dlsym(libHandle, func);
#if defined (__FreeBSD__)
const char *error = dlerror();
#else
char *error = dlerror();
#endif
if (error)
SG_LOG(SG_GENERAL, SG_INFO, error);
}

View File

@@ -202,7 +202,7 @@ typedef void (APIENTRY * glClientActiveTextureProc)(GLenum texture);
#define GL_RGB_SCALE_ARB 0x8573
#define GL_ADD_SIGNED_ARB 0x8574
#define GL_INTERPOLATE_ARB 0x8575
#define GL_SUBTRACT_ARB 0x84E7
#define GL_SUBTRACT_ARB 0x84E7
#define GL_CONSTANT_ARB 0x8576
#define GL_PRIMARY_COLOR_ARB 0x8577
#define GL_PREVIOUS_ARB 0x8578
@@ -766,6 +766,62 @@ typedef void (APIENTRY * glGetVertexAttribivProc) (GLuint index, GLenum pname, G
typedef void (APIENTRY * glGetVertexAttribPointervProc) (GLuint index, GLenum pname, GLvoid* *pointer);
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
*/

View File

@@ -275,7 +275,7 @@ SGSampleGroup::stop ()
void
SGSampleGroup::suspend ()
{
if (_pause == false) {
if (_active && _pause == false) {
_pause = true;
sample_map_iterator sample_current = _samples.begin();
sample_map_iterator sample_end = _samples.end();
@@ -294,7 +294,7 @@ SGSampleGroup::suspend ()
void
SGSampleGroup::resume ()
{
if (_pause == true) {
if (_active && _pause == true) {
sample_map_iterator sample_current = _samples.begin();
sample_map_iterator sample_end = _samples.end();
for ( ; sample_current != sample_end; ++sample_current ) {

View File

@@ -30,7 +30,7 @@
#endif
#if defined( __APPLE__ )
# include <OpenAL/alut.h>
# include <ALUT/alut.h>
#else
# include <AL/alut.h>
#endif
@@ -45,10 +45,17 @@
#include <simgear/misc/sg_path.hxx>
#include <simgear/math/SGMath.hxx>
using std::string;
extern bool isNaN(float *v);
#define MAX_SOURCES 128
#ifndef ALC_ALL_DEVICES_SPECIFIER
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
//
// Sound Manager
//
@@ -81,6 +88,8 @@ SGSoundMgr::SGSoundMgr() :
}
}
_alut_init++;
#else
#error ALUT 1.1 required, ALUT 1.0 is no longer supported, please upgrade
#endif
}
@@ -164,8 +173,9 @@ void SGSoundMgr::init(const char *devname) {
_vendor = (const char *)alGetString(AL_VENDOR);
_renderer = (const char *)alGetString(AL_RENDERER);
if ( (_vendor != "OpenAL Community" && _vendor != "Apple Computer Inc.") ||
(_renderer != "Software" && _renderer != "OpenAL Sample Implementation")
if ( (_vendor != "Adalin" && _vendor != "Apple Computer Inc.") &&
(_vendor != "OpenAL Community" || (_renderer != "Software" &&
_renderer != "OpenAL Sample Implementation"))
)
{
_bad_doppler = true;

View File

@@ -35,32 +35,19 @@
#ifndef _SG_SOUNDMGR_OPENAL_HXX
#define _SG_SOUNDMGR_OPENAL_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#include <string>
#include <vector>
#include <map>
#if defined(__APPLE__)
# define AL_ILLEGAL_ENUM AL_INVALID_ENUM
# define AL_ILLEGAL_COMMAND AL_INVALID_OPERATION
# include <OpenAL/al.h>
# include <OpenAL/alc.h>
# include <OpenAL/alut.h>
#elif defined(OPENALSDK)
# include <al.h>
# include <alc.h>
# include <AL/alut.h>
#else
# include <AL/al.h>
# include <AL/alc.h>
# include <AL/alut.h>
#endif
#ifndef ALC_ALL_DEVICES_SPECIFIER
# define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
#include <simgear/compiler.h>
@@ -68,9 +55,6 @@
#include <simgear/math/SGMathFwd.hxx>
#include "sample_group.hxx"
#include "sample_openal.hxx"
using std::string;
struct refUint {
unsigned int refctr;
@@ -81,11 +65,11 @@ struct 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::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::const_iterator const_sample_group_map_iterator;
@@ -133,21 +117,21 @@ public:
* @param refname Reference name of the sample group
* @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.
* @param refname Reference name of the sample group to remove
* @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
* @param refname Reference name of the sample group test for
* @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
@@ -287,13 +271,13 @@ public:
/**
* 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.
*/
const string& get_vendor() { return _vendor; }
const string& get_renderer() { return _renderer; }
const std::string& get_vendor() { return _vendor; }
const std::string& get_renderer() { return _renderer; }
private:
static int _alut_init;
@@ -323,17 +307,17 @@ private:
sample_group_map _sample_groups;
buffer_map _buffers;
vector<ALuint> _free_sources;
vector<ALuint> _sources_in_use;
std::vector<ALuint> _free_sources;
std::vector<ALuint> _sources_in_use;
bool _bad_doppler;
string _renderer;
string _vendor;
std::string _renderer;
std::string _vendor;
bool testForALError(string s);
bool testForALCError(string s);
bool testForALUTError(string s);
bool testForError(void *p, string s);
bool testForALError(std::string s);
bool testForALCError(std::string s);
bool testForALUTError(std::string s);
bool testForError(void *p, std::string s);
void update_pos_and_orientation();
void update_sample_config( SGSampleGroup *sound );