Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b0ba10b0b | ||
|
|
9f9c4cf32c | ||
|
|
536ebf604f | ||
|
|
03a616b737 | ||
|
|
0b05f67114 | ||
|
|
0ede690580 | ||
|
|
d81545a871 | ||
|
|
1cda1fc201 | ||
|
|
490dad7838 | ||
|
|
13ecbb8bce | ||
|
|
3346bfc9a8 | ||
|
|
c5de65f115 | ||
|
|
4fffcf9975 | ||
|
|
8962d9b293 | ||
|
|
050c1560e8 | ||
|
|
68b3041f50 | ||
|
|
1ddd153399 | ||
|
|
df0a60caae | ||
|
|
675c86582d | ||
|
|
e6d01ed1a3 | ||
|
|
d8d1064e05 | ||
|
|
5d04cb81ba | ||
|
|
5d5906e980 | ||
|
|
2e7b862ad3 | ||
|
|
ad86e22824 | ||
|
|
536b8a213b | ||
|
|
2e13877926 | ||
|
|
967d63dec4 | ||
|
|
573c4268b6 | ||
|
|
f19e83dcf1 | ||
|
|
caabe8fc87 | ||
|
|
7c4e5309fc | ||
|
|
542124e90c | ||
|
|
e0d02be0f5 | ||
|
|
461e6d1b5b | ||
|
|
d767e6d7eb | ||
|
|
bff1584012 | ||
|
|
3d91a11b95 | ||
|
|
1349b46a8c | ||
|
|
74330ba1dd | ||
|
|
64ab227f62 | ||
|
|
1c51fbd1b4 | ||
|
|
4c2dd553f2 | ||
|
|
2fb985afa4 | ||
|
|
44c93d5074 | ||
|
|
dcf07a46aa | ||
|
|
284a9e0612 | ||
|
|
60349a8690 | ||
|
|
64072be83c | ||
|
|
229abb8412 | ||
|
|
7b1d1fd288 | ||
|
|
1ca1f6ad22 | ||
|
|
0ad66f4bc4 | ||
|
|
d5757c4fb8 | ||
|
|
7fe40bce86 | ||
|
|
5da3d64ede | ||
|
|
2e93b06ac0 | ||
|
|
1e6aa4b40f | ||
|
|
262383395d | ||
|
|
127226c421 | ||
|
|
fabcb021cb | ||
|
|
60ab1ab83e | ||
|
|
1f37095087 | ||
|
|
93c2f70b64 | ||
|
|
b0562df6bb | ||
|
|
65d6a5c774 | ||
|
|
650af0f7b0 | ||
|
|
cf9de25c25 | ||
|
|
fc4009aa50 | ||
|
|
d04cf4d897 | ||
|
|
2e45c67ef2 | ||
|
|
b6d8e1f842 | ||
|
|
284bc364fe | ||
|
|
a050654b4c | ||
|
|
7311dae483 | ||
|
|
c57c3cd1d3 | ||
|
|
3ec5e85485 | ||
|
|
ff95af0367 | ||
|
|
aa9c7d5435 | ||
|
|
dcc9f33357 | ||
|
|
1ace645505 | ||
|
|
dc2b87dce1 | ||
|
|
8e47f5d494 | ||
|
|
333d381f41 | ||
|
|
f9b064cc19 | ||
|
|
116a6c1b2e | ||
|
|
c4506b8e6c | ||
|
|
6786a7be4a | ||
|
|
bb370a304d | ||
|
|
fdcf53c688 | ||
|
|
d3f575547c | ||
|
|
68797e51c6 | ||
|
|
c76c55cdee | ||
|
|
acf19cebf8 |
@@ -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
|
||||
|
||||
|
||||
24
README.MSVC
24
README.MSVC
@@ -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.
|
||||
116
acinclude.m4
116
acinclude.m4
@@ -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
|
||||
|
||||
58
configure.ac
58
configure.ac
@@ -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
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
Debug
|
||||
Release
|
||||
SimGear.ncb
|
||||
SimGear.suo
|
||||
*.user
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ private:
|
||||
|
||||
float _snow_intensity;
|
||||
float _rain_intensity;
|
||||
float _clip_distance;
|
||||
|
||||
int _wind_dir;
|
||||
osg::Vec3 _wind_vec;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 = \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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>);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -30,6 +30,6 @@ libsgmaterial_a_SOURCES = \
|
||||
mat.cxx \
|
||||
matlib.cxx \
|
||||
matmodel.cxx \
|
||||
Noise.cxx
|
||||
Noise.cxx Noise.hxx
|
||||
|
||||
INCLUDES = -I$(top_srcdir)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 );
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ include_HEADERS = \
|
||||
|
||||
libsgmodel_a_SOURCES = \
|
||||
animation.cxx \
|
||||
BoundingVolumeBuildVisitor.hxx \
|
||||
particles.cxx \
|
||||
model.cxx \
|
||||
modellib.cxx \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -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 ) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 );
|
||||
|
||||
Reference in New Issue
Block a user