Merge branch 'upstream-master'

This commit is contained in:
Harvir 2014-12-26 18:55:15 +00:00
commit caa7cf67c7
112 changed files with 5311 additions and 2128 deletions

View File

@ -4,7 +4,7 @@ compiler:
- clang
before_script:
- sudo apt-get install python-dev libpng-dev zlib1g-dev libssl-dev libx11-dev libgl1-mesa-dev libxrandr-dev libxxf86dga-dev libxcursor-dev bison flex libfreetype6-dev libvorbis-dev libjpeg-dev libopenal-dev libode-dev nvidia-cg-toolkit
script: python makepanda/makepanda.py --everything
script: python makepanda/makepanda.py --everything --git-commit $TRAVIS_COMMIT
notifications:
irc:
channels:

View File

@ -590,7 +590,7 @@ class Installer:
if package.platform:
xpackage.SetAttribute('platform', package.platform)
assert package.platform == platform
xpackage.SetAttribute('per_platform', '1')
xpackage.SetAttribute('per_platform', '0')
if package.packageVersion:
xpackage.SetAttribute('version', version)
xpackage.SetAttribute('filename', package.packageName + "/" + package.packageVersion + "/" + package.descFileBasename)

View File

@ -25,17 +25,17 @@
// const identifier, and then returning the value of that identifier,
// seems to lead to compilation errors (at least in VC7) in which
// sometimes IS_THRESHOLD_COMPEQ(a, a, get_nearly_zero_value(a)) != 0.
INLINE double
CONSTEXPR double
get_nearly_zero_value(double) {
return 1.0e-12;
}
INLINE float
CONSTEXPR float
get_nearly_zero_value(float) {
return 1.0e-6f;
}
INLINE int
CONSTEXPR int
get_nearly_zero_value(int) {
// This is a bit silly, but we should nevertheless define it in
// case it is called for an integer type.

View File

@ -226,7 +226,7 @@ is_official_version() {
return false;
#endif
}
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::get_distributor
// Access: Published, Static
@ -239,7 +239,7 @@ string PandaSystem::
get_distributor() {
return PANDA_DISTRIBUTOR;
}
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::get_compiler
// Access: Published, Static
@ -279,7 +279,7 @@ get_compiler() {
return "unknown";
#endif
}
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::get_build_date
// Access: Published, Static
@ -291,7 +291,23 @@ string PandaSystem::
get_build_date() {
return __DATE__ " " __TIME__;
}
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::get_git_commit
// Access: Published, Static
// Description: Returns a string representing the git commit hash
// that this source tree is based on, or the empty
// string if it has not been specified at build time.
////////////////////////////////////////////////////////////////////
string PandaSystem::
get_git_commit() {
#ifdef PANDA_GIT_COMMIT_STR
return PANDA_GIT_COMMIT_STR;
#else
return string();
#endif
}
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::get_platform
// Access: Published, Static
@ -440,7 +456,7 @@ heap_trim(size_t pad) {
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::output
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void PandaSystem::
output(ostream &out) const {
@ -450,7 +466,7 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::write
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void PandaSystem::
write(ostream &out) const {
@ -472,7 +488,7 @@ write(ostream &out) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: PandaSystem::get_global_ptr
// Access: Published, Static
@ -498,12 +514,12 @@ void PandaSystem::
reset_system_names() {
_system_names.clear();
_system_names.reserve(_systems.size());
Systems::const_iterator si;
for (si = _systems.begin(); si != _systems.end(); ++si) {
_system_names.push_back((*si).first);
}
_system_names_dirty = false;
}

View File

@ -41,10 +41,11 @@ PUBLISHED:
static int get_minor_version();
static int get_sequence_version();
static bool is_official_version();
static string get_distributor();
static string get_compiler();
static string get_build_date();
static string get_git_commit();
static string get_platform();
@ -106,4 +107,4 @@ inline ostream &operator << (ostream &out, const PandaSystem &ps) {
#endif

17
makepanda/getversion.py Executable file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
# This script parses the version number in dtool/PandaVersion.pp
# and returns it on the command-line. This is useful for the
# automated scripts that build the Panda3D releases.
from makepandacore import ParsePandaVersion, ParsePluginVersion
import sys
if '--runtime' in sys.argv:
version = ParsePluginVersion("dtool/PandaVersion.pp")
else:
version = ParsePandaVersion("dtool/PandaVersion.pp")
version = version.strip()
sys.stdout.write(version)
sys.stdout.flush()

View File

@ -91,19 +91,54 @@ def WriteKeysFile(fname, info):
fhandle.write("\n")
fhandle.close()
def GetLibDir():
# This one's a bit tricky. Some systems require us to install
# 64-bits libraries into /usr/lib64, some into /usr/lib.
# Debian forbids installing to lib64 nowadays, and the only distros
# I know of that use lib64 are all RPM-based. So, the 'solution'
# seems to be to use the rpm command to give us the libdir for now.
def GetDebLibDir():
""" Returns the lib dir according to the debian system. """
# We're on Debian or Ubuntu, which use multiarch directories.
# Call dpkg-architecture to get the multiarch libdir.
handle = os.popen("dpkg-architecture -qDEB_HOST_MULTIARCH")
multiarch = handle.read().strip()
if handle.close():
# It failed. Old Debian/Ubuntu version?
pass
elif len(multiarch) > 0:
return "lib/" + multiarch
return "lib"
def GetRPMLibDir():
""" Returns the lib dir according to the rpm system. """
handle = os.popen("rpm -E '%_lib'")
result = handle.read().strip()
handle.close()
if len(result) > 0:
assert result == "lib64" or result == "lib"
return result
else:
return "lib"
def GetLibDir():
""" Returns the directory to install architecture-dependent
libraries in, relative to the prefix directory. This may be
something like "lib" or "lib64" or in some cases, something
similar to "lib/x86_64-linux-gnu". """
# This one's a bit tricky. Some systems require us to install
# 64-bits libraries into /usr/lib64, some into /usr/lib.
# Debian forbids installing to lib64 nowadays, and the only distros
# I know of that use lib64 are all RPM-based. So, the 'solution'
# seems to be to use the rpm command to give us the libdir for now,
# unless we know we're on debian, since rpm may be installed on
# Debian and will give the wrong result. Ugh.
if os.environ.get("DEB_HOST_MULTIARCH"):
# We're building inside the Debian build environment.
return "lib/" + os.environ["DEB_HOST_MULTIARCH"]
if os.path.isfile('/etc/debian_version'):
return GetDebLibDir()
else:
# Okay, maybe we're on an RPM-based system?
return GetRPMLibDir()
# If Python is installed into /usr/lib64, it's probably safe
# to assume that we should install there as well.
@ -114,14 +149,19 @@ def GetLibDir():
return "lib"
def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
if (not prefix.startswith("/")): prefix = "/" + prefix
libdir = prefix + "/" + GetLibDir()
def InstallPanda(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir()):
if (not prefix.startswith("/")):
prefix = "/" + prefix
libdir = prefix + "/" + libdir
# Determine the location of the Python executable and site-packages dir.
PPATH = get_python_lib(1)
if os.path.islink(sys.executable):
PEXEC = os.path.join(os.path.dirname(sys.executable), os.readlink(sys.executable))
else:
PEXEC = sys.executable
# Create the directory structure that we will be putting our files in.
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/bin")
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/include")
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/panda3d")
@ -131,27 +171,32 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/applications")
oscmd("mkdir -m 0755 -p "+destdir+libdir+"/panda3d")
oscmd("mkdir -m 0755 -p "+destdir+PPATH)
if (sys.platform.startswith("freebsd")):
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/etc")
oscmd("mkdir -m 0755 -p "+destdir+"/usr/local/libdata/ldconfig")
else:
oscmd("mkdir -m 0755 -p "+destdir+"/etc/ld.so.conf.d")
# Write the Config.prc file.
Configrc = ReadFile(outputdir+"/etc/Config.prc")
Configrc = Configrc.replace("model-path $THIS_PRC_DIR/..", "model-path "+prefix+"/share/panda3d")
if (sys.platform.startswith("freebsd")):
WriteFile(destdir+prefix+"/etc/Config.prc", Configrc)
oscmd("cp "+outputdir+"/etc/Confauto.prc "+destdir+prefix+"/etc/Confauto.prc")
oscmd("cp "+outputdir+"/etc/Confauto.prc "+destdir+prefix+"/etc/Confauto.prc")
else:
WriteFile(destdir+"/etc/Config.prc", Configrc)
oscmd("cp "+outputdir+"/etc/Confauto.prc "+destdir+"/etc/Confauto.prc")
oscmd("cp "+outputdir+"/etc/Confauto.prc "+destdir+"/etc/Confauto.prc")
oscmd("cp -R "+outputdir+"/include "+destdir+prefix+"/include/panda3d")
oscmd("cp -R "+outputdir+"/direct "+destdir+prefix+"/share/panda3d/")
oscmd("cp -R "+outputdir+"/pandac "+destdir+prefix+"/share/panda3d/")
oscmd("cp -R "+outputdir+"/panda3d "+destdir+PPATH+"/")
oscmd("cp -R "+outputdir+"/models "+destdir+prefix+"/share/panda3d/")
if os.path.isdir("samples"): oscmd("cp -R samples "+destdir+prefix+"/share/panda3d/")
if os.path.isdir(outputdir+"/direct"): oscmd("cp -R "+outputdir+"/direct "+destdir+prefix+"/share/panda3d/")
if os.path.isdir(outputdir+"/Pmw"): oscmd("cp -R "+outputdir+"/Pmw "+destdir+prefix+"/share/panda3d/")
if os.path.isdir(outputdir+"/plugins"): oscmd("cp -R "+outputdir+"/plugins "+destdir+prefix+"/share/panda3d/")
WriteMimeFile(destdir+prefix+"/share/mime-info/panda3d.mime", MIME_INFO)
WriteKeysFile(destdir+prefix+"/share/mime-info/panda3d.keys", MIME_INFO)
WriteMimeXMLFile(destdir+prefix+"/share/mime/packages/panda3d.xml", MIME_INFO)
@ -167,7 +212,6 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
else:
oscmd("echo '"+libdir+"/panda3d'> "+destdir+"/etc/ld.so.conf.d/panda3d.conf")
oscmd("chmod +x "+destdir+"/etc/ld.so.conf.d/panda3d.conf")
oscmd("ln -f -s "+PEXEC+" "+destdir+prefix+"/bin/ppython")
oscmd("cp "+outputdir+"/bin/* "+destdir+prefix+"/bin/")
for base in os.listdir(outputdir+"/lib"):
if (not base.endswith(".a")) or base == "libp3pystub.a":
@ -190,9 +234,11 @@ def InstallPanda(destdir="", prefix="/usr", outputdir="built"):
if (os.path.isfile(destdir+prefix+"/share/panda3d/direct/leveleditor/copyfiles.pl")):
os.remove(destdir+prefix+"/share/panda3d/direct/leveleditor/copyfiles.pl")
def InstallRuntime(destdir="", prefix="/usr", outputdir="built"):
if (not prefix.startswith("/")): prefix = "/" + prefix
libdir = prefix + "/" + GetLibDir()
def InstallRuntime(destdir="", prefix="/usr", outputdir="built", libdir=GetLibDir()):
if (not prefix.startswith("/")):
prefix = "/" + prefix
libdir = prefix + "/" + libdir
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/bin")
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/mime-info")
oscmd("mkdir -m 0755 -p "+destdir+prefix+"/share/mime/packages")
@ -245,7 +291,7 @@ if (__name__ == "__main__"):
print("Installing Panda3D Runtime into " + destdir + options.prefix)
InstallRuntime(destdir = destdir, prefix = options.prefix, outputdir = options.outputdir)
else:
print("Installing Panda3D into " + destdir + options.prefix)
print("Installing Panda3D SDK into " + destdir + options.prefix)
InstallPanda(destdir = destdir, prefix = options.prefix, outputdir = options.outputdir)
print("Installation finished!")

View File

@ -52,6 +52,7 @@ GENMAN=0
COMPRESSOR="zlib"
THREADCOUNT=0
CFLAGS=""
CXXFLAGS=""
LDFLAGS=""
RTDIST=0
RTDIST_VERSION="dev"
@ -60,6 +61,7 @@ DISTRIBUTOR=""
VERSION=None
DEBVERSION=None
RPMRELEASE="1"
GIT_COMMIT=None
P3DSUFFIX=None
MAJOR_VERSION=None
COREAPI_VERSION=None
@ -120,7 +122,7 @@ signal.signal(signal.SIGINT, keyboardInterruptHandler)
def usage(problem):
if (problem):
print("")
print("Error parsing commandline input", problem)
print("Error parsing command-line input: %s" % (problem))
print("")
print("Makepanda generates a 'built' subdirectory containing a")
@ -163,7 +165,7 @@ def usage(problem):
def parseopts(args):
global INSTALLER,RTDIST,RUNTIME,GENMAN,DISTRIBUTOR,VERSION
global COMPRESSOR,THREADCOUNT,OSXTARGET,UNIVERSAL,HOST_URL
global DEBVERSION,RPMRELEASE,P3DSUFFIX
global DEBVERSION,RPMRELEASE,GIT_COMMIT,P3DSUFFIX
global STRDXSDKVERSION, STRMSPLATFORMVERSION, BOOUSEINTELCOMPILER
longopts = [
"help","distributor=","verbose","runtime","osxtarget=",
@ -171,7 +173,7 @@ def parseopts(args):
"version=","lzma","no-python","threads=","outputdir=","override=",
"static","host=","debversion=","rpmrelease=","p3dsuffix=",
"directx-sdk=", "platform-sdk=", "use-icl",
"universal", "target=", "arch="]
"universal", "target=", "arch=", "git-commit="]
anything = 0
optimize = ""
target = None
@ -207,6 +209,7 @@ def parseopts(args):
elif (option=="--host"): HOST_URL=value
elif (option=="--debversion"): DEBVERSION=value
elif (option=="--rpmrelease"): RPMRELEASE=value
elif (option=="--git-commit"): GIT_COMMIT=value
elif (option=="--p3dsuffix"): P3DSUFFIX=value
# Backward compatibility, OPENGL was renamed to GL
elif (option=="--use-opengl"): PkgEnable("GL")
@ -232,12 +235,18 @@ def parseopts(args):
PkgDisable(pkg)
break
if (option=="--everything" or option.startswith("--use-")
or option=="--nothing" or option.startswith("--no-")):
anything = 1
or option=="--nothing" or option.startswith("--no-")):
anything = 1
except:
usage(0)
print("Exception while parsing commandline:", sys.exc_info()[0])
if (anything==0): usage(0)
if not anything:
if RUNTIME:
PkgEnableAll()
else:
usage("You should specify a list of packages to use or --everything to enable all packages.")
if (RTDIST and RUNTIME):
usage("Options --runtime and --rtdist cannot be specified at the same time!")
if (optimize=="" and (RTDIST or RUNTIME)): optimize = "4"
@ -258,6 +267,9 @@ def parseopts(args):
except:
usage("Invalid setting for OPTIMIZE")
if GIT_COMMIT is not None and not re.match("^[a-f0-9]{40}$", GIT_COMMIT):
usage("Invalid SHA-1 hash given for --git-commit option!")
if target is not None or target_arch is not None:
SetTarget(target, target_arch)
@ -283,13 +295,17 @@ parseopts(sys.argv[1:])
########################################################################
if ("CFLAGS" in os.environ):
CFLAGS = os.environ["CFLAGS"]
CFLAGS = os.environ["CFLAGS"].strip()
if ("CXXFLAGS" in os.environ):
CXXFLAGS = os.environ["CXXFLAGS"].strip()
if ("RPM_OPT_FLAGS" in os.environ):
CFLAGS += " " + os.environ["RPM_OPT_FLAGS"]
CFLAGS = CFLAGS.strip()
CFLAGS += " " + os.environ["RPM_OPT_FLAGS"].strip()
CXXFLAGS += " " + os.environ["RPM_OPT_FLAGS"].strip()
if ("LDFLAGS" in os.environ):
LDFLAGS = os.environ["LDFLAGS"]
LDFLAGS = LDFLAGS.strip()
LDFLAGS = os.environ["LDFLAGS"].strip()
os.environ["MAKEPANDA"] = os.path.abspath(sys.argv[0])
if (GetHost() == "darwin" and OSXTARGET != None):
@ -364,8 +380,8 @@ if (GetHost() == 'windows'):
if (INSTALLER and RTDIST):
exit("Cannot build an installer for the rtdist build!")
if (INSTALLER) and (PkgSkip("PYTHON")) and (not RUNTIME):
exit("Cannot build installer without python")
if (INSTALLER) and (PkgSkip("PYTHON")) and (not RUNTIME) and GetTarget() == 'windows':
exit("Cannot build installer on Windows without python")
if (RTDIST) and (PkgSkip("JPEG")):
exit("Cannot build rtdist without jpeg")
@ -568,13 +584,13 @@ if (COMPILER == "MSVC"):
LibName("FMODEX", GetThirdpartyDir() + "fmodex/lib/fmodex64_vc.lib")
else:
LibName("FMODEX", GetThirdpartyDir() + "fmodex/lib/fmodex_vc.lib")
if (PkgSkip("WX")==0):
if (PkgSkip("WX")==0 and RTDIST):
LibName("WX", GetThirdpartyDir() + "wx/lib/wxbase28u.lib")
LibName("WX", GetThirdpartyDir() + "wx/lib/wxmsw28u_core.lib")
DefSymbol("WX", "__WXMSW__", "")
DefSymbol("WX", "_UNICODE", "")
DefSymbol("WX", "UNICODE", "")
if (PkgSkip("FLTK")==0):
if (PkgSkip("FLTK")==0 and RTDIST):
LibName("FLTK", GetThirdpartyDir() + "fltk/lib/fltk.lib")
if (PkgSkip("VORBIS")==0):
LibName("VORBIS", GetThirdpartyDir() + "vorbis/lib/libogg_static.lib")
@ -1126,7 +1142,13 @@ def CompileCxx(obj,src,opts):
if (optlevel==2): cmd += " -O1 -D_DEBUG"
if (optlevel==3): cmd += " -O2"
if (optlevel==4): cmd += " -O3 -DNDEBUG"
if (CFLAGS !=""): cmd += " " + CFLAGS
if src.endswith(".c"):
cmd += ' ' + CFLAGS
else:
cmd += ' ' + CXXFLAGS
cmd = cmd.rstrip()
building = GetValueOption(opts, "BUILDING:")
if (building): cmd += " -DBUILDING_" + building
cmd += ' ' + BracketNameWithQuotes(src)
@ -2388,6 +2410,9 @@ def CreatePandaVersionFiles():
else:
pandaversion_h += "\n#undef PANDA_OFFICIAL_VERSION\n"
if GIT_COMMIT:
pandaversion_h += "\n#define PANDA_GIT_COMMIT_STR \"%s\"\n" % (GIT_COMMIT)
if not RUNTIME:
checkpandaversion_cxx = CHECKPANDAVERSION_CXX.replace("$VERSION1",str(version1))
checkpandaversion_cxx = checkpandaversion_cxx.replace("$VERSION2",str(version2))
@ -2585,11 +2610,11 @@ CopyAllHeaders('panda/src/downloader')
CopyAllHeaders('panda/metalibs/pandaexpress')
CopyAllHeaders('panda/src/pipeline')
CopyAllHeaders('panda/src/linmath')
CopyAllHeaders('panda/src/putil')
CopyAllHeaders('dtool/src/prckeys')
CopyAllHeaders('panda/src/audio')
CopyAllHeaders('panda/src/event')
CopyAllHeaders('panda/src/linmath')
CopyAllHeaders('panda/src/mathutil')
CopyAllHeaders('panda/src/gsgbase')
CopyAllHeaders('panda/src/pnmimage')
@ -3025,6 +3050,25 @@ if (not RUNTIME):
TargetAdd('libp3pipeline.in', opts=['IMOD:panda3d.core', 'ILIB:libp3pipeline', 'SRCDIR:panda/src/pipeline'])
TargetAdd('libp3pipeline_igate.obj', input='libp3pipeline.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/linmath/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/linmath', 'BUILDING:PANDA']
TargetAdd('p3linmath_composite1.obj', opts=OPTS, input='p3linmath_composite1.cxx')
TargetAdd('p3linmath_composite2.obj', opts=OPTS, input='p3linmath_composite2.cxx')
IGATEFILES=GetDirectoryContents('panda/src/linmath', ["*.h", "*_composite*.cxx"])
for ifile in IGATEFILES[:]:
if "_src." in ifile:
IGATEFILES.remove(ifile)
IGATEFILES.remove('cast_to_double.h')
IGATEFILES.remove('lmat_ops.h')
IGATEFILES.remove('cast_to_float.h')
TargetAdd('libp3linmath.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3linmath.in', opts=['IMOD:panda3d.core', 'ILIB:libp3linmath', 'SRCDIR:panda/src/linmath'])
TargetAdd('libp3linmath_igate.obj', input='libp3linmath.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/putil/
#
@ -3065,25 +3109,6 @@ if (not RUNTIME):
TargetAdd('libp3event.in', opts=['IMOD:panda3d.core', 'ILIB:libp3event', 'SRCDIR:panda/src/event'])
TargetAdd('libp3event_igate.obj', input='libp3event.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/linmath/
#
if (not RUNTIME):
OPTS=['DIR:panda/src/linmath', 'BUILDING:PANDA']
TargetAdd('p3linmath_composite1.obj', opts=OPTS, input='p3linmath_composite1.cxx')
TargetAdd('p3linmath_composite2.obj', opts=OPTS, input='p3linmath_composite2.cxx')
IGATEFILES=GetDirectoryContents('panda/src/linmath', ["*.h", "*_composite*.cxx"])
for ifile in IGATEFILES[:]:
if "_src." in ifile:
IGATEFILES.remove(ifile)
IGATEFILES.remove('cast_to_double.h')
IGATEFILES.remove('lmat_ops.h')
IGATEFILES.remove('cast_to_float.h')
TargetAdd('libp3linmath.in', opts=OPTS, input=IGATEFILES)
TargetAdd('libp3linmath.in', opts=['IMOD:panda3d.core', 'ILIB:libp3linmath', 'SRCDIR:panda/src/linmath'])
TargetAdd('libp3linmath_igate.obj', input='libp3linmath.in', opts=["DEPENDENCYONLY"])
#
# DIRECTORY: panda/src/mathutil/
#
@ -6126,7 +6151,8 @@ Priority: optional
Architecture: ARCH
Essential: no
Depends: DEPENDS
Recommends: panda3d-runtime, python-wxversion, python-profiler (>= PV), python-tk (>= PV), RECOMMENDS
Recommends: RECOMMENDS
Suggests: panda3d-runtime
Provides: panda3d
Conflicts: panda3d
Replaces: panda3d
@ -6188,7 +6214,6 @@ This package contains the SDK for development with Panda3D, install panda3d-runt
/usr/share/application-registry/panda3d.applications
/usr/share/applications/*.desktop
/etc/ld.so.conf.d/panda3d.conf
/usr/bin
/usr/%_lib/panda3d
%{python_sitearch}
/usr/include/panda3d
@ -6248,48 +6273,31 @@ WWW: http://www.panda3d.org/
"""
def MakeInstallerLinux():
if RUNTIME: # No worries, it won't be used
PYTHONV = "python"
else:
if not RUNTIME and not PkgSkip("PYTHON"):
PYTHONV = SDK["PYTHONVERSION"]
else:
PYTHONV = "python"
PV = PYTHONV.replace("python", "")
if (os.path.isdir("targetroot")): oscmd("chmod -R 755 targetroot")
# Clean and set up a directory to install Panda3D into
oscmd("rm -rf targetroot data.tar.gz control.tar.gz panda3d.spec")
oscmd("mkdir --mode=0755 targetroot")
# Invoke installpanda.py to install it into a temporary dir
if RUNTIME:
InstallRuntime(destdir = "targetroot", prefix = "/usr", outputdir = GetOutputDir())
else:
InstallPanda(destdir = "targetroot", prefix = "/usr", outputdir = GetOutputDir())
oscmd("chmod -R 755 targetroot/usr/share/panda3d")
if (os.path.exists("/usr/bin/rpmbuild") and not os.path.exists("/usr/bin/dpkg-deb")):
oscmd("rm -rf targetroot/DEBIAN")
oscmd("rpm -E '%_target_cpu' > "+GetOutputDir()+"/tmp/architecture.txt")
ARCH = ReadFile(GetOutputDir()+"/tmp/architecture.txt").strip()
pandasource = os.path.abspath(os.getcwd())
if (RUNTIME):
txt = RUNTIME_INSTALLER_SPEC_FILE[1:]
if os.path.exists("/usr/bin/dpkg-deb"):
# Invoke installpanda.py to install it into a temporary dir
if RUNTIME:
InstallRuntime(destdir="targetroot", prefix="/usr", outputdir=GetOutputDir(), libdir=GetDebLibDir())
else:
txt = INSTALLER_SPEC_FILE[1:]
txt = txt.replace("VERSION", VERSION).replace("RPMRELEASE", RPMRELEASE).replace("PANDASOURCE", pandasource).replace("PV", PV)
WriteFile("panda3d.spec", txt)
oscmd("fakeroot rpmbuild --define '_rpmdir "+pandasource+"' --buildroot '"+os.path.abspath("targetroot")+"' -bb panda3d.spec")
if (RUNTIME):
oscmd("mv "+ARCH+"/panda3d-runtime-"+VERSION+"-"+RPMRELEASE+"."+ARCH+".rpm .")
else:
oscmd("mv "+ARCH+"/panda3d-"+VERSION+"-"+RPMRELEASE+"."+ARCH+".rpm .")
oscmd("rm -rf "+ARCH, True)
InstallPanda(destdir="targetroot", prefix="/usr", outputdir=GetOutputDir(), libdir=GetDebLibDir())
oscmd("chmod -R 755 targetroot/usr/share/panda3d")
if (os.path.exists("/usr/bin/dpkg-deb")):
oscmd("dpkg --print-architecture > "+GetOutputDir()+"/tmp/architecture.txt")
ARCH = ReadFile(GetOutputDir()+"/tmp/architecture.txt").strip()
pkg_arch = ReadFile(GetOutputDir()+"/tmp/architecture.txt").strip()
if (RUNTIME):
txt = RUNTIME_INSTALLER_DEB_FILE[1:]
else:
txt = INSTALLER_DEB_FILE[1:]
txt = txt.replace("VERSION", DEBVERSION).replace("ARCH", ARCH).replace("PV", PV).replace("MAJOR", MAJOR_VERSION)
txt = txt.replace("VERSION", DEBVERSION).replace("ARCH", pkg_arch).replace("PV", PV).replace("MAJOR", MAJOR_VERSION)
txt = txt.replace("INSTSIZE", str(GetDirectorySize("targetroot") / 1024))
oscmd("mkdir --mode=0755 -p targetroot/DEBIAN")
oscmd("cd targetroot ; (find usr -type f -exec md5sum {} \;) > DEBIAN/md5sums")
@ -6298,44 +6306,105 @@ def MakeInstallerLinux():
WriteFile("targetroot/DEBIAN/conffiles","/etc/Config.prc\n")
WriteFile("targetroot/DEBIAN/postinst","#!/bin/sh\necho running ldconfig\nldconfig\n")
oscmd("cp targetroot/DEBIAN/postinst targetroot/DEBIAN/postrm")
oscmd("mkdir targetroot/debian")
WriteFile("targetroot/debian/control", "")
if (RUNTIME):
oscmd("ln -s .. targetroot/debian/panda3d-runtime")
oscmd("cd targetroot ; dpkg-shlibdeps -xpanda3d-runtime debian/panda3d-runtime/usr/lib/*.so* debian/panda3d-runtime/usr/lib64/*.so* debian/panda3d-runtime/usr/bin/*")
depends = ReadFile("targetroot/debian/substvars").replace("shlibs:Depends=", "").strip()
WriteFile("targetroot/DEBIAN/control", txt.replace("DEPENDS", depends))
# Determine the package name and the locations that
# dpkg-shlibdeps should look in for executables.
lib_dir = GetLibDir()
pkg_version = DEBVERSION
if RUNTIME:
pkg_name = "panda3d-runtime"
lib_pattern = "debian/%s/usr/%s/*.so" % (pkg_name, lib_dir)
else:
oscmd("ln -s .. targetroot/debian/panda3d" + MAJOR_VERSION)
oscmd("cd targetroot ; dpkg-gensymbols -v%s -ppanda3d%s -eusr/lib/panda3d/lib*.so* -eusr/lib64/panda3d/lib*.so* -ODEBIAN/symbols >/dev/null" % (DEBVERSION, MAJOR_VERSION))
# Library dependencies are required, binary dependencies are recommended. Dunno why -xlibphysx-extras is needed, prolly a bug in their package
oscmd("cd targetroot ; LD_LIBRARY_PATH=usr/lib/panda3d dpkg-shlibdeps --ignore-missing-info --warnings=2 -xpanda3d%s -xlibphysx-extras -Tdebian/substvars_dep debian/panda3d%s/usr/lib/panda3d/lib*.so* debian/panda3d%s/usr/lib64/panda3d/lib*.so*" % (MAJOR_VERSION, MAJOR_VERSION, MAJOR_VERSION))
oscmd("cd targetroot ; LD_LIBRARY_PATH=usr/lib/panda3d dpkg-shlibdeps --ignore-missing-info --warnings=2 -xpanda3d%s -Tdebian/substvars_rec debian/panda3d%s/usr/bin/*" % (MAJOR_VERSION, MAJOR_VERSION))
pkg_name = "panda3d" + MAJOR_VERSION
lib_pattern = "debian/%s/usr/%s/panda3d/*.so*" % (pkg_name, lib_dir)
bin_pattern = "debian/%s/usr/bin/*" % (pkg_name)
# dpkg-shlibdeps looks in the debian/{pkg_name}/DEBIAN/shlibs directory
# and also expects a debian/control file, so we create this dummy set-up.
oscmd("mkdir targetroot/debian")
oscmd("ln -s .. targetroot/debian/" + pkg_name)
WriteFile("targetroot/debian/control", "")
dpkg_shlibdeps = "dpkg-shlibdeps"
if GetVerbose():
dpkg_shlibdeps += " -v"
if RUNTIME:
# The runtime doesn't export any useful symbols, so just query the dependencies.
oscmd("cd targetroot; %(dpkg_shlibdeps)s -x%(pkg_name)s %(lib_pattern)s %(bin_pattern)s*" % locals())
depends = ReadFile("targetroot/debian/substvars").replace("shlibs:Depends=", "").strip()
recommends = ""
else:
pkg_name = "panda3d" + MAJOR_VERSION
pkg_dir = "debian/panda3d" + MAJOR_VERSION
# Generate a symbols file so that other packages can know which symbols we export.
oscmd("cd targetroot; dpkg-gensymbols -q -ODEBIAN/symbols -v%(pkg_version)s -p%(pkg_name)s -e%(lib_pattern)s" % locals())
# Library dependencies are required, binary dependencies are recommended.
# We explicitly exclude libphysx-extras since we don't want to depend on PhysX.
oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_dep --ignore-missing-info -x%(pkg_name)s -xlibphysx-extras %(lib_pattern)s" % locals())
oscmd("cd targetroot; LD_LIBRARY_PATH=usr/%(lib_dir)s/panda3d %(dpkg_shlibdeps)s -Tdebian/substvars_rec --ignore-missing-info -x%(pkg_name)s %(bin_pattern)s" % locals())
# Parse the substvars files generated by dpkg-shlibdeps.
depends = ReadFile("targetroot/debian/substvars_dep").replace("shlibs:Depends=", "").strip()
recommends = ReadFile("targetroot/debian/substvars_rec").replace("shlibs:Depends=", "").strip()
if PkgSkip("PYTHON")==0:
depends += ", " + PYTHONV + ", python-pmw"
recommends += ", python-wxversion, python-profiler (>= " + PV + "), python-tk (>= " + PV + ")"
if PkgSkip("NVIDIACG")==0:
depends += ", nvidia-cg-toolkit"
if depends.startswith(', '):
depends = depends[2:]
WriteFile("targetroot/DEBIAN/control", txt.replace("DEPENDS", depends).replace("RECOMMENDS", recommends))
# Write back the dependencies, and delete the dummy set-up.
txt = txt.replace("DEPENDS", depends.strip(', '))
txt = txt.replace("RECOMMENDS", recommends.strip(', '))
WriteFile("targetroot/DEBIAN/control", txt)
oscmd("rm -rf targetroot/debian")
# Package it all up into a .deb file.
oscmd("chmod -R 755 targetroot/DEBIAN")
if (RUNTIME):
oscmd("cd targetroot/DEBIAN ; chmod 644 control md5sums")
oscmd("fakeroot dpkg-deb -b targetroot panda3d-runtime_"+DEBVERSION+"_"+ARCH+".deb")
oscmd("chmod 644 targetroot/DEBIAN/control targetroot/DEBIAN/md5sums")
if not RUNTIME:
oscmd("chmod 644 targetroot/DEBIAN/conffiles targetroot/DEBIAN/symbols")
oscmd("fakeroot dpkg-deb -b targetroot %s_%s_%s.deb" % (pkg_name, pkg_version, pkg_arch))
elif os.path.exists("/usr/bin/rpmbuild"):
# Invoke installpanda.py to install it into a temporary dir
if RUNTIME:
InstallRuntime(destdir="targetroot", prefix="/usr", outputdir=GetOutputDir(), libdir=GetRPMLibDir())
else:
oscmd("cd targetroot/DEBIAN ; chmod 644 control md5sums conffiles symbols")
oscmd("fakeroot dpkg-deb -b targetroot panda3d"+MAJOR_VERSION+"_"+DEBVERSION+"_"+ARCH+".deb")
oscmd("chmod -R 755 targetroot")
InstallPanda(destdir="targetroot", prefix="/usr", outputdir=GetOutputDir(), libdir=GetRPMLibDir())
oscmd("chmod -R 755 targetroot/usr/share/panda3d")
if not (os.path.exists("/usr/bin/rpmbuild") or os.path.exists("/usr/bin/dpkg-deb")):
oscmd("rpm -E '%_target_cpu' > "+GetOutputDir()+"/tmp/architecture.txt")
ARCH = ReadFile(GetOutputDir()+"/tmp/architecture.txt").strip()
pandasource = os.path.abspath(os.getcwd())
if RUNTIME:
txt = RUNTIME_INSTALLER_SPEC_FILE[1:]
else:
txt = INSTALLER_SPEC_FILE[1:]
# Add the binaries in /usr/bin explicitly to the spec file
for base in os.listdir(GetOutputDir() + "/bin"):
txt += "/usr/bin/%s\n" % (base)
# Write out the spec file.
txt = txt.replace("VERSION", VERSION)
txt = txt.replace("RPMRELEASE", RPMRELEASE)
txt = txt.replace("PANDASOURCE", pandasource)
txt = txt.replace("PV", PV)
WriteFile("panda3d.spec", txt)
oscmd("fakeroot rpmbuild --define '_rpmdir "+pandasource+"' --buildroot '"+os.path.abspath("targetroot")+"' -bb panda3d.spec")
if (RUNTIME):
oscmd("mv "+ARCH+"/panda3d-runtime-"+VERSION+"-"+RPMRELEASE+"."+ARCH+".rpm .")
else:
oscmd("mv "+ARCH+"/panda3d-"+VERSION+"-"+RPMRELEASE+"."+ARCH+".rpm .")
oscmd("rm -rf "+ARCH, True)
else:
exit("To build an installer, either rpmbuild or dpkg-deb must be present on your system!")
# oscmd("chmod -R 755 targetroot")
# oscmd("rm -rf targetroot data.tar.gz control.tar.gz panda3d.spec "+ARCH)
def MakeInstallerOSX():
if (RUNTIME):
# Invoke the make_installer script.
@ -6570,30 +6639,33 @@ def MakeInstallerFreeBSD():
cmd += " -d pkg-descr -f pkg-plist panda3d-%s" % VERSION
oscmd(cmd)
if (INSTALLER != 0):
ProgressOutput(100.0, "Building installer")
target = GetTarget()
if (target == 'windows'):
dbg = ""
if (GetOptimize() <= 2): dbg = "-dbg"
if GetTargetArch() == 'x64':
if (RUNTIME):
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
try:
if INSTALLER:
ProgressOutput(100.0, "Building installer")
target = GetTarget()
if (target == 'windows'):
dbg = ""
if (GetOptimize() <= 2): dbg = "-dbg"
if GetTargetArch() == 'x64':
if (RUNTIME):
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
else:
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
else:
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+"-x64.exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION+"-x64")
if (RUNTIME):
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
else:
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
elif (target == 'linux'):
MakeInstallerLinux()
elif (target == 'darwin'):
MakeInstallerOSX()
elif (target == 'freebsd'):
MakeInstallerFreeBSD()
else:
if (RUNTIME):
MakeInstallerNSIS("Panda3D-Runtime-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
else:
MakeInstallerNSIS("Panda3D-"+VERSION+dbg+".exe", "Panda3D", "Panda3D "+VERSION, "C:\\Panda3D-"+VERSION)
elif (target == 'linux'):
MakeInstallerLinux()
elif (target == 'darwin'):
MakeInstallerOSX()
elif (target == 'freebsd'):
MakeInstallerFreeBSD()
else:
exit("Do not know how to make an installer for this platform")
exit("Do not know how to make an installer for this platform")
finally:
SaveDependencyCache()
##########################################################################################
#
@ -6601,8 +6673,6 @@ if (INSTALLER != 0):
#
##########################################################################################
SaveDependencyCache()
WARNINGS.append("Elapsed Time: "+PrettyTime(time.time() - STARTTIME))
printStatus("Makepanda Final Status Report", WARNINGS)

View File

@ -41,6 +41,7 @@
#include "bamCache.h"
#include "cullableObject.h"
#include "geomVertexArrayData.h"
#include "omniBoundingVolume.h"
#include "vertexDataSaveFile.h"
#include "vertexDataBook.h"
#include "vertexDataPage.h"
@ -1212,7 +1213,8 @@ do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
PT(BoundingVolume) bv = scene_setup->get_cull_bounds();
if (bv != (BoundingVolume *)NULL &&
bv->is_of_type(GeometricBoundingVolume::get_class_type())) {
bv->is_of_type(GeometricBoundingVolume::get_class_type()) &&
!bv->is_of_type(OmniBoundingVolume::get_class_type())) {
// Transform it into the appropriate coordinate space.
PT(GeometricBoundingVolume) local_frustum;
local_frustum = DCAST(GeometricBoundingVolume, bv->make_copy());

View File

@ -308,8 +308,8 @@ add_render_texture(Texture *tex, RenderTextureMode mode,
// Create texture if necessary.
if (tex == (Texture *)NULL) {
tex = new Texture(get_name());
tex->set_wrap_u(Texture::WM_clamp);
tex->set_wrap_v(Texture::WM_clamp);
tex->set_wrap_u(SamplerState::WM_clamp);
tex->set_wrap_v(SamplerState::WM_clamp);
} else {
tex->clear_ram_image();
}
@ -1050,8 +1050,8 @@ make_cube_map(const string &name, int size, NodePath &camera_rig,
PT(Texture) tex = new Texture(name);
tex->setup_cube_map();
tex->set_wrap_u(Texture::WM_clamp);
tex->set_wrap_v(Texture::WM_clamp);
tex->set_wrap_u(SamplerState::WM_clamp);
tex->set_wrap_v(SamplerState::WM_clamp);
GraphicsOutput *buffer;
buffer = make_texture_buffer(name, size, size, tex, to_ram, fbp);

View File

@ -36,6 +36,17 @@ release_all_textures() {
return _prepared_objects->release_all_textures();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_all_samplers
// Access: Public
// Description: Frees the resources for all samplers associated with
// this GSG.
////////////////////////////////////////////////////////////////////
INLINE int GraphicsStateGuardian::
release_all_samplers() {
return _prepared_objects->release_all_samplers();
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_all_geoms
// Access: Public
@ -632,6 +643,22 @@ get_supports_shadow_filter() const {
return _supports_shadow_filter;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_sampler_objects
// Access: Published
// Description: Returns true if this particular GSG supports the
// use of sampler objects to record texture sampling
// parameters separately from the texture objects.
// This doesn't really affect functionality, but if
// this is false, it may mean that using the same
// texture with different SamplerState objects will
// result in reduced performance.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_supports_sampler_objects() const {
return _supports_sampler_objects;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_basic_shaders
// Access: Published

View File

@ -98,6 +98,7 @@ PStatCollector GraphicsStateGuardian::_command_latency_pcollector("Command laten
PStatCollector GraphicsStateGuardian::_prepare_pcollector("Draw:Prepare");
PStatCollector GraphicsStateGuardian::_prepare_texture_pcollector("Draw:Prepare:Texture");
PStatCollector GraphicsStateGuardian::_prepare_sampler_pcollector("Draw:Prepare:Sampler");
PStatCollector GraphicsStateGuardian::_prepare_geom_pcollector("Draw:Prepare:Geom");
PStatCollector GraphicsStateGuardian::_prepare_shader_pcollector("Draw:Prepare:Shader");
PStatCollector GraphicsStateGuardian::_prepare_vertex_buffer_pcollector("Draw:Prepare:Vertex buffer");
@ -230,6 +231,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
_supports_depth_texture = false;
_supports_depth_stencil = false;
_supports_shadow_filter = false;
_supports_sampler_objects = false;
_supports_basic_shaders = false;
_supports_geometry_shaders = false;
_supports_tessellation_shaders = false;
@ -626,6 +628,35 @@ extract_texture_data(Texture *) {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::prepare_sampler
// Access: Public, Virtual
// Description: Creates whatever structures the GSG requires to
// represent the sampler internally, and returns a
// newly-allocated SamplerContext object with this data.
// It is the responsibility of the calling function to
// later call release_sampler() with this same pointer
// (which will also delete the pointer).
//
// This function should not be called directly to
// prepare a sampler. Instead, call Texture::prepare().
////////////////////////////////////////////////////////////////////
SamplerContext *GraphicsStateGuardian::
prepare_sampler(const SamplerState &sampler) {
return (SamplerContext *)NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::release_sampler
// Access: Public, Virtual
// Description: Frees the resources previously allocated via a call
// to prepare_sampler(), including deleting the
// SamplerContext itself, if it is non-NULL.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
release_sampler(SamplerContext *) {
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::prepare_geom
// Access: Public, Virtual
@ -2883,22 +2914,22 @@ make_shadow_buffer(const NodePath &light_np, GraphicsOutputBase *host) {
// Set the wrap mode
if (is_point) {
tex->set_wrap_u(Texture::WM_clamp);
tex->set_wrap_v(Texture::WM_clamp);
tex->set_wrap_u(SamplerState::WM_clamp);
tex->set_wrap_v(SamplerState::WM_clamp);
} else {
tex->set_wrap_u(Texture::WM_border_color);
tex->set_wrap_v(Texture::WM_border_color);
tex->set_wrap_u(SamplerState::WM_border_color);
tex->set_wrap_v(SamplerState::WM_border_color);
tex->set_border_color(LVecBase4(1, 1, 1, 1));
}
if (get_supports_shadow_filter()) {
// If we have the ARB_shadow extension, enable shadow filtering.
tex->set_minfilter(Texture::FT_shadow);
tex->set_magfilter(Texture::FT_shadow);
tex->set_minfilter(SamplerState::FT_shadow);
tex->set_magfilter(SamplerState::FT_shadow);
} else {
// We only accept linear - this tells the GPU to use hardware PCF.
tex->set_minfilter(Texture::FT_linear);
tex->set_magfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear);
tex->set_magfilter(SamplerState::FT_linear);
}
// Assign display region(s) to the buffer and camera

View File

@ -87,6 +87,7 @@ PUBLISHED:
INLINE void release_all();
INLINE int release_all_textures();
INLINE int release_all_samplers();
INLINE int release_all_geoms();
INLINE int release_all_vertex_buffers();
INLINE int release_all_index_buffers();
@ -143,6 +144,7 @@ PUBLISHED:
INLINE bool get_supports_depth_texture() const;
INLINE bool get_supports_depth_stencil() const;
INLINE bool get_supports_shadow_filter() const;
INLINE bool get_supports_sampler_objects() const;
INLINE bool get_supports_basic_shaders() const;
INLINE bool get_supports_geometry_shaders() const;
INLINE bool get_supports_tessellation_shaders() const;
@ -165,7 +167,6 @@ PUBLISHED:
virtual int get_supported_geom_rendering() const;
virtual bool get_supports_cg_profile(const string &name) const;
INLINE bool get_color_scale_via_lighting() const;
INLINE bool get_alpha_scale_via_texture() const;
INLINE bool get_alpha_scale_via_texture(const TextureAttrib *tex_attrib) const;
@ -215,6 +216,9 @@ public:
virtual void release_texture(TextureContext *tc);
virtual bool extract_texture_data(Texture *tex);
virtual SamplerContext *prepare_sampler(const SamplerState &sampler);
virtual void release_sampler(SamplerContext *sc);
virtual GeomContext *prepare_geom(Geom *geom);
virtual void release_geom(GeomContext *gc);
@ -509,6 +513,7 @@ protected:
bool _supports_depth_texture;
bool _supports_depth_stencil;
bool _supports_shadow_filter;
bool _supports_sampler_objects;
bool _supports_basic_shaders;
bool _supports_geometry_shaders;
bool _supports_tessellation_shaders;
@ -586,6 +591,7 @@ public:
static PStatCollector _prepare_pcollector;
static PStatCollector _prepare_texture_pcollector;
static PStatCollector _prepare_sampler_pcollector;
static PStatCollector _prepare_geom_pcollector;
static PStatCollector _prepare_shader_pcollector;
static PStatCollector _prepare_vertex_buffer_pcollector;

View File

@ -81,7 +81,7 @@ specified a power-of-2 size.) You can extract this Texture and set
various properties on it, then apply it to geometry:
Texture *tex = buffer->get_texture();
tex->set_minfilter(Texture::FT_linear_mipmap_linear);
tex->set_minfilter(SamplerState::FT_linear_mipmap_linear);
screen.set_texture(tex);

View File

@ -79,17 +79,17 @@ LColor_to_D3DCOLOR(const LColor &cLColor) {
// GL's.
////////////////////////////////////////////////////////////////////
INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian8::
get_texture_wrap_mode(Texture::WrapMode wm) {
get_texture_wrap_mode(SamplerState::WrapMode wm) {
switch (wm) {
case Texture::WM_clamp:
case SamplerState::WM_clamp:
return D3DTADDRESS_CLAMP;
case Texture::WM_repeat:
case SamplerState::WM_repeat:
return D3DTADDRESS_WRAP;
case Texture::WM_mirror:
case SamplerState::WM_mirror:
return D3DTADDRESS_MIRROR;
case Texture::WM_mirror_once:
case SamplerState::WM_mirror_once:
return D3DTADDRESS_MIRRORONCE;
case Texture::WM_border_color:
case SamplerState::WM_border_color:
return D3DTADDRESS_BORDER;
}
dxgsg8_cat.error() << "Invalid Texture::Mode value" << endl;

View File

@ -175,7 +175,7 @@ prepare_texture(Texture *tex, int view) {
// rendering on the ith stage.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
apply_texture(int i, TextureContext *tc) {
apply_texture(int i, TextureContext *tc, const SamplerState &sampler) {
if (tc == (TextureContext *)NULL) {
// The texture wasn't bound properly or something, so ensure
// texturing is disabled and just return.
@ -193,20 +193,20 @@ apply_texture(int i, TextureContext *tc) {
DXTextureContext8 *dtc = DCAST(DXTextureContext8, tc);
Texture *tex = tc->get_texture();
Texture::WrapMode wrap_u, wrap_v, wrap_w;
wrap_u = tex->get_wrap_u();
wrap_v = tex->get_wrap_v();
wrap_w = tex->get_wrap_w();
SamplerState::WrapMode wrap_u, wrap_v, wrap_w;
wrap_u = sampler.get_wrap_u();
wrap_v = sampler.get_wrap_v();
wrap_w = sampler.get_wrap_w();
_d3d_device->SetTextureStageState(i, D3DTSS_ADDRESSU, get_texture_wrap_mode(wrap_u));
_d3d_device->SetTextureStageState(i, D3DTSS_ADDRESSV, get_texture_wrap_mode(wrap_v));
_d3d_device->SetTextureStageState(i, D3DTSS_ADDRESSW, get_texture_wrap_mode(wrap_w));
_d3d_device->SetTextureStageState(i, D3DTSS_BORDERCOLOR,
LColor_to_D3DCOLOR(tex->get_border_color()));
LColor_to_D3DCOLOR(sampler.get_border_color()));
uint aniso_degree = tex->get_effective_anisotropic_degree();
Texture::FilterType ft = tex->get_effective_magfilter();
uint aniso_degree = sampler.get_effective_anisotropic_degree();
SamplerState::FilterType ft = sampler.get_effective_magfilter();
if (aniso_degree >= 1) {
_d3d_device->SetTextureStageState(i, D3DTSS_MAXANISOTROPY, aniso_degree);
@ -214,7 +214,7 @@ apply_texture(int i, TextureContext *tc) {
D3DTEXTUREFILTERTYPE new_mag_filter;
if (aniso_degree <= 1) {
new_mag_filter = ((ft != Texture::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
new_mag_filter = ((ft != SamplerState::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
} else {
new_mag_filter = D3DTEXF_ANISOTROPIC;
}
@ -222,8 +222,8 @@ apply_texture(int i, TextureContext *tc) {
_d3d_device->SetTextureStageState(i, D3DTSS_MAGFILTER, new_mag_filter);
// map Panda composite min+mip filter types to d3d's separate min & mip filter types
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(tex->get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(tex->get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(sampler.get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(sampler.get_effective_minfilter());
if (!tex->might_have_ram_image()) {
// If the texture is completely dynamic, don't try to issue
@ -2859,11 +2859,12 @@ do_issue_texture() {
Texture *texture = _target_texture->get_on_texture(stage);
nassertv(texture != (Texture *)NULL);
const SamplerState &sampler = _target_texture->get_on_sampler(stage);
// We always reissue every stage in DX, just in case the texcoord
// index or texgen mode or some other property has changed.
TextureContext *tc = texture->prepare_now(0, _prepared_objects, this);
apply_texture(si, tc);
apply_texture(si, tc, sampler);
set_texture_blend_mode(si, stage);
int texcoord_dimensions = 2;
@ -4031,28 +4032,28 @@ copy_pres_reset(DXScreenData *screen) {
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian8::
get_d3d_min_type(Texture::FilterType filter_type) {
get_d3d_min_type(SamplerState::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
case SamplerState::FT_nearest:
return D3DTEXF_POINT;
case Texture::FT_linear:
case SamplerState::FT_linear:
return D3DTEXF_LINEAR;
case Texture::FT_nearest_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_nearest:
return D3DTEXF_POINT;
case Texture::FT_linear_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
return D3DTEXF_LINEAR;
case Texture::FT_nearest_mipmap_linear:
case SamplerState::FT_nearest_mipmap_linear:
return D3DTEXF_POINT;
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
return D3DTEXF_LINEAR;
case Texture::FT_shadow:
case Texture::FT_default:
case SamplerState::FT_shadow:
case SamplerState::FT_default:
return D3DTEXF_LINEAR;
}
@ -4067,28 +4068,28 @@ get_d3d_min_type(Texture::FilterType filter_type) {
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian8::
get_d3d_mip_type(Texture::FilterType filter_type) {
get_d3d_mip_type(SamplerState::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
case SamplerState::FT_nearest:
return D3DTEXF_NONE;
case Texture::FT_linear:
case SamplerState::FT_linear:
return D3DTEXF_NONE;
case Texture::FT_nearest_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_nearest:
return D3DTEXF_POINT;
case Texture::FT_linear_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
return D3DTEXF_POINT;
case Texture::FT_nearest_mipmap_linear:
case SamplerState::FT_nearest_mipmap_linear:
return D3DTEXF_LINEAR;
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
return D3DTEXF_LINEAR;
case Texture::FT_shadow:
case Texture::FT_default:
case SamplerState::FT_shadow:
case SamplerState::FT_default:
return D3DTEXF_NONE;
}

View File

@ -50,7 +50,7 @@ public:
calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype);
virtual TextureContext *prepare_texture(Texture *tex, int view);
void apply_texture(int i, TextureContext *tc);
void apply_texture(int i, TextureContext *tc, const SamplerState &sampler);
virtual bool update_texture(TextureContext *tc, bool force);
bool upload_texture(DXTextureContext8 *dtc, bool force);
virtual void release_texture(TextureContext *tc);
@ -174,7 +174,7 @@ protected:
void do_auto_rescale_normal();
protected:
INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm);
INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(SamplerState::WrapMode wm);
INLINE static D3DFOGMODE get_fog_mode_type(Fog::Mode m);
const D3DCOLORVALUE &get_light_color(Light *light) const;
INLINE static D3DTRANSFORMSTATETYPE get_tex_mat_sym(int stage_index);
@ -199,8 +199,8 @@ protected:
bool release_swap_chain (DXScreenData *new_context);
void copy_pres_reset(DXScreenData *new_context);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(Texture::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(Texture::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(SamplerState::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(SamplerState::FilterType filter_type);
static D3DTEXTUREOP get_texture_operation(TextureStage::CombineMode mode, int scale);
static DWORD get_texture_argument(TextureStage::CombineSource source,
TextureStage::CombineOperand operand);
@ -258,7 +258,7 @@ protected:
const DXIndexBufferContext8 *_active_ibuffer;
int _num_active_texture_stages;
// Cache the data necessary to bind each particular light each
// frame, so if we bind a given light multiple times, we only have
// to compute its data once.
@ -292,7 +292,7 @@ public:
register_type(_type_handle, "DXGraphicsStateGuardian8",
GraphicsStateGuardian::get_class_type());
}
private:
static TypeHandle _type_handle;

View File

@ -591,21 +591,21 @@ create_texture(DXScreenData &scrn) {
// validate magfilter setting
// degrade filtering if no HW support
Texture::FilterType ft;
SamplerState::FilterType ft;
ft = tex->get_magfilter();
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
if ((ft != SamplerState::FT_linear) && ft != SamplerState::FT_nearest) {
// mipmap settings make no sense for magfilter
if (ft == Texture::FT_nearest_mipmap_nearest) {
ft = Texture::FT_nearest;
if (ft == SamplerState::FT_nearest_mipmap_nearest) {
ft = SamplerState::FT_nearest;
} else {
ft = Texture::FT_linear;
ft = SamplerState::FT_linear;
}
}
if (ft == Texture::FT_linear &&
if (ft == SamplerState::FT_linear &&
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
ft = Texture::FT_nearest;
ft = SamplerState::FT_nearest;
}
tex->set_magfilter(ft);
@ -615,33 +615,33 @@ create_texture(DXScreenData &scrn) {
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
switch(ft) {
case Texture::FT_nearest_mipmap_nearest:
case Texture::FT_linear_mipmap_nearest:
case Texture::FT_nearest_mipmap_linear: // pick nearest in each, interpolate linearly b/w them
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_nearest_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_linear: // pick nearest in each, interpolate linearly b/w them
case SamplerState::FT_linear_mipmap_linear:
_has_mipmaps = true;
}
if (dx_mipmap_everything) { // debug toggle, ok to leave in since its just a creation cost
_has_mipmaps = true;
if (dxgsg8_cat.is_spam()) {
if (ft != Texture::FT_linear_mipmap_linear) {
if (ft != SamplerState::FT_linear_mipmap_linear) {
dxgsg8_cat.spam()
<< "Forcing trilinear mipmapping on DX texture ["
<< tex->get_name() << "]\n";
}
}
ft = Texture::FT_linear_mipmap_linear;
ft = SamplerState::FT_linear_mipmap_linear;
tex->set_minfilter(ft);
}
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
(ft == Texture::FT_nearest_mipmap_linear)) {
ft = Texture::FT_nearest;
} else if ((ft == SamplerState::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
(ft == SamplerState::FT_nearest_mipmap_linear)) {
ft = SamplerState::FT_nearest;
} else if ((ft == Texture::FT_linear_mipmap_nearest) ||
(ft == Texture::FT_linear_mipmap_linear)) {
ft = Texture::FT_linear;
} else if ((ft == SamplerState::FT_linear_mipmap_nearest) ||
(ft == SamplerState::FT_linear_mipmap_linear)) {
ft = SamplerState::FT_linear;
}
nassertr((filter_caps & D3DPTFILTERCAPS_MINFPOINT) != 0, false);
@ -650,36 +650,36 @@ create_texture(DXScreenData &scrn) {
// do any other filter type degradations necessary
switch(ft) {
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
if ((filter_caps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
if (filter_caps & D3DPTFILTERCAPS_MINFLINEAR) {
ft = Texture::FT_linear_mipmap_nearest;
ft = SamplerState::FT_linear_mipmap_nearest;
} else {
// if you cant do linear in a level, you probably cant do
// linear b/w levels, so just do nearest-all
ft = Texture::FT_nearest_mipmap_nearest;
ft = SamplerState::FT_nearest_mipmap_nearest;
}
}
break;
case Texture::FT_nearest_mipmap_linear:
case SamplerState::FT_nearest_mipmap_linear:
// if we don't have bilinear, do nearest_nearest
if (!((filter_caps & D3DPTFILTERCAPS_MIPFPOINT) &&
(filter_caps & D3DPTFILTERCAPS_MINFLINEAR))) {
ft = Texture::FT_nearest_mipmap_nearest;
ft = SamplerState::FT_nearest_mipmap_nearest;
}
break;
case Texture::FT_linear_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
// if we don't have mip linear, do nearest_nearest
if (!(filter_caps & D3DPTFILTERCAPS_MIPFLINEAR)) {
ft = Texture::FT_nearest_mipmap_nearest;
ft = SamplerState::FT_nearest_mipmap_nearest;
}
break;
case Texture::FT_linear:
case SamplerState::FT_linear:
if (!(filter_caps & D3DPTFILTERCAPS_MINFLINEAR)) {
ft = Texture::FT_nearest;
ft = SamplerState::FT_nearest;
}
break;
}

View File

@ -79,17 +79,17 @@ LColor_to_D3DCOLOR(const LColor &cLColor) {
// GL's.
////////////////////////////////////////////////////////////////////
INLINE D3DTEXTUREADDRESS DXGraphicsStateGuardian9::
get_texture_wrap_mode(Texture::WrapMode wm) {
get_texture_wrap_mode(SamplerState::WrapMode wm) {
switch (wm) {
case Texture::WM_clamp:
case SamplerState::WM_clamp:
return D3DTADDRESS_CLAMP;
case Texture::WM_repeat:
case SamplerState::WM_repeat:
return D3DTADDRESS_WRAP;
case Texture::WM_mirror:
case SamplerState::WM_mirror:
return D3DTADDRESS_MIRROR;
case Texture::WM_mirror_once:
case SamplerState::WM_mirror_once:
return D3DTADDRESS_MIRRORONCE;
case Texture::WM_border_color:
case SamplerState::WM_border_color:
return D3DTADDRESS_BORDER;
}
dxgsg9_cat.error() << "Invalid Texture::Mode value" << endl;

View File

@ -206,7 +206,7 @@ prepare_texture(Texture *tex, int view) {
// rendering on the ith stage.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
apply_texture(int i, TextureContext *tc) {
apply_texture(int i, TextureContext *tc, const SamplerState &sampler) {
if (tc == (TextureContext *)NULL) {
// The texture wasn't bound properly or something, so ensure
// texturing is disabled and just return.
@ -231,31 +231,22 @@ apply_texture(int i, TextureContext *tc) {
set_sampler_state(i, D3DSAMP_SRGBTEXTURE, FALSE);
}
Texture::WrapMode wrap_u, wrap_v, wrap_w;
set_sampler_state(i, D3DSAMP_ADDRESSU,
get_texture_wrap_mode(sampler.get_wrap_u()));
DWORD address_u;
DWORD address_v;
DWORD address_w;
set_sampler_state(i, D3DSAMP_ADDRESSV,
get_texture_wrap_mode(sampler.get_wrap_v()));
wrap_u = tex->get_wrap_u();
wrap_v = tex->get_wrap_v();
wrap_w = tex->get_wrap_w();
address_u = get_texture_wrap_mode(wrap_u);
address_v = get_texture_wrap_mode(wrap_v);
address_w = get_texture_wrap_mode(wrap_w);
set_sampler_state(i, D3DSAMP_ADDRESSU, address_u);
set_sampler_state(i, D3DSAMP_ADDRESSV, address_v);
set_sampler_state(i, D3DSAMP_ADDRESSW, address_w);
set_sampler_state(i, D3DSAMP_ADDRESSW,
get_texture_wrap_mode(sampler.get_wrap_w()));
DWORD border_color;
border_color = LColor_to_D3DCOLOR(tex->get_border_color());
border_color = LColor_to_D3DCOLOR(sampler.get_border_color());
set_sampler_state(i, D3DSAMP_BORDERCOLOR, border_color);
uint aniso_degree = tex->get_effective_anisotropic_degree();
Texture::FilterType ft = tex->get_effective_magfilter();
uint aniso_degree = sampler.get_effective_anisotropic_degree();
SamplerState::FilterType ft = sampler.get_effective_magfilter();
if (aniso_degree >= 1) {
set_sampler_state(i, D3DSAMP_MAXANISOTROPY, aniso_degree);
@ -266,7 +257,7 @@ apply_texture(int i, TextureContext *tc) {
supports_anisotropic_mag_filter = (_screen -> _d3dcaps.TextureFilterCaps & D3DPTFILTERCAPS_MAGFANISOTROPIC) != 0;
if (aniso_degree <= 1 || supports_anisotropic_mag_filter == 0) {
new_mag_filter = ((ft != Texture::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
new_mag_filter = ((ft != SamplerState::FT_nearest) ? D3DTEXF_LINEAR : D3DTEXF_POINT);
} else {
new_mag_filter = D3DTEXF_ANISOTROPIC;
}
@ -276,12 +267,12 @@ apply_texture(int i, TextureContext *tc) {
if (hr != D3D_OK) {
dxgsg9_cat.error()
<< "ERROR: set_sampler_state (D3DSAMP_MAGFILTER, "
<< new_mag_filter << ") failed for texture:" << tex -> get_name() << endl;
<< new_mag_filter << ") failed for sampler: " << sampler << endl;
}
// map Panda composite min+mip filter types to d3d's separate min & mip filter types
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(tex->get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(tex->get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_min_filter = get_d3d_min_type(sampler.get_effective_minfilter());
D3DTEXTUREFILTERTYPE new_mip_filter = get_d3d_mip_type(sampler.get_effective_minfilter());
if (!tex->might_have_ram_image()) {
// If the texture is completely dynamic, don't try to issue
@ -302,6 +293,9 @@ apply_texture(int i, TextureContext *tc) {
set_sampler_state(i, D3DSAMP_MINFILTER, new_min_filter);
set_sampler_state(i, D3DSAMP_MIPFILTER, new_mip_filter);
float lod_bias = sampler.get_lod_bias();
set_sampler_state(i, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)&lod_bias);
_d3d_device->SetTexture(i, dtc->get_d3d_texture());
}
@ -3734,12 +3728,13 @@ update_standard_texture_bindings() {
Texture *texture = _target_texture->get_on_texture(stage);
nassertv(texture != (Texture *)NULL);
const SamplerState &sampler = _target_texture->get_on_sampler(stage);
// We always reissue every stage in DX, just in case the texcoord
// index or texgen mode or some other property has changed.
int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
apply_texture(si, tc);
apply_texture(si, tc, sampler);
set_texture_blend_mode(si, stage);
int texcoord_dimensions = 2;
@ -4936,28 +4931,28 @@ copy_pres_reset(DXScreenData *screen) {
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
get_d3d_min_type(Texture::FilterType filter_type) {
get_d3d_min_type(SamplerState::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
case SamplerState::FT_nearest:
return D3DTEXF_POINT;
case Texture::FT_linear:
case SamplerState::FT_linear:
return D3DTEXF_LINEAR;
case Texture::FT_nearest_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_nearest:
return D3DTEXF_POINT;
case Texture::FT_linear_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
return D3DTEXF_LINEAR;
case Texture::FT_nearest_mipmap_linear:
case SamplerState::FT_nearest_mipmap_linear:
return D3DTEXF_POINT;
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
return D3DTEXF_LINEAR;
case Texture::FT_shadow:
case Texture::FT_default:
case SamplerState::FT_shadow:
case SamplerState::FT_default:
return D3DTEXF_LINEAR;
}
@ -4972,28 +4967,28 @@ get_d3d_min_type(Texture::FilterType filter_type) {
// Description:
////////////////////////////////////////////////////////////////////
D3DTEXTUREFILTERTYPE DXGraphicsStateGuardian9::
get_d3d_mip_type(Texture::FilterType filter_type) {
get_d3d_mip_type(SamplerState::FilterType filter_type) {
switch (filter_type) {
case Texture::FT_nearest:
case SamplerState::FT_nearest:
return D3DTEXF_NONE;
case Texture::FT_linear:
case SamplerState::FT_linear:
return D3DTEXF_NONE;
case Texture::FT_nearest_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_nearest:
return D3DTEXF_POINT;
case Texture::FT_linear_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
return D3DTEXF_POINT;
case Texture::FT_nearest_mipmap_linear:
case SamplerState::FT_nearest_mipmap_linear:
return D3DTEXF_LINEAR;
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
return D3DTEXF_LINEAR;
case Texture::FT_shadow:
case Texture::FT_default:
case SamplerState::FT_shadow:
case SamplerState::FT_default:
return D3DTEXF_NONE;
}

View File

@ -22,6 +22,7 @@
#include "graphicsStateGuardian.h"
#include "texture.h"
#include "samplerState.h"
#include "displayRegion.h"
#include "material.h"
#include "depthTestAttrib.h"
@ -67,7 +68,7 @@ public:
DWORD multisampletype, DWORD multisamplequality);
virtual TextureContext *prepare_texture(Texture *tex, int view);
void apply_texture(int i, TextureContext *tc);
void apply_texture(int i, TextureContext *tc, const SamplerState &sampler);
virtual bool update_texture(TextureContext *tc, bool force);
bool upload_texture(DXTextureContext9 *dtc, bool force);
virtual void release_texture(TextureContext *tc);
@ -217,7 +218,7 @@ protected:
void update_standard_texture_bindings();
protected:
INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(Texture::WrapMode wm);
INLINE static D3DTEXTUREADDRESS get_texture_wrap_mode(SamplerState::WrapMode wm);
INLINE static D3DFOGMODE get_fog_mode_type(Fog::Mode m);
const D3DCOLORVALUE &get_light_color(Light *light) const;
INLINE static D3DTRANSFORMSTATETYPE get_tex_mat_sym(int stage_index);
@ -242,8 +243,8 @@ protected:
bool release_swap_chain (DXScreenData *new_context);
void copy_pres_reset(DXScreenData *new_context);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(Texture::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(Texture::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_min_type(SamplerState::FilterType filter_type);
static D3DTEXTUREFILTERTYPE get_d3d_mip_type(SamplerState::FilterType filter_type);
static D3DTEXTUREOP get_texture_operation(TextureStage::CombineMode mode, int scale);
DWORD get_texture_argument(TextureStage::CombineSource source,
TextureStage::CombineOperand operand) const;

View File

@ -48,27 +48,27 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
#ifdef HAVE_CG
_cg_context = 0;
if (s->get_language() == Shader::SL_Cg) {
// Ask the shader to compile itself for us and
// Ask the shader to compile itself for us and
// to give us the resulting Cg program objects.
if (!s->cg_compile_for(gsg->_shader_caps,
_cg_context,
_cg_vprogram,
_cg_fprogram,
_cg_fprogram,
_cg_gprogram, // CG2 CHANGE
_cg_parameter_map)) {
return;
}
// Load the program.
BOOL paramater_shadowing;
DWORD assembly_flags;
paramater_shadowing = FALSE;
assembly_flags = 0;
#if DEBUG_SHADER
assembly_flags |= D3DXSHADER_DEBUG;
#endif
@ -80,26 +80,26 @@ CLP(ShaderContext)(Shader *s, GSG *gsg) : ShaderContext(s) {
dxgsg9_cat.error()
<< "vertex shader cgD3D9LoadProgram failed "
<< D3DERRORSTRING(hr);
CGerror error = cgGetError();
if (error != CG_NO_ERROR) {
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
}
success = false;
}
hr = cgD3D9LoadProgram(_cg_fprogram, paramater_shadowing, assembly_flags);
if (FAILED (hr)) {
dxgsg9_cat.error()
<< "pixel shader cgD3D9LoadProgram failed "
<< D3DERRORSTRING(hr);
CGerror error = cgGetError();
if (error != CG_NO_ERROR) {
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
}
success = false;
}
}
// BEGIN CG2 CHANGE
if (_cg_gprogram != 0)
@ -150,7 +150,7 @@ CLP(ShaderContext)::
// {
// int state;
// int file_handle;
//
//
// state = false;
// file_handle = _open (file_path, _O_CREAT | _O_RDWR | _O_TRUNC, _S_IREAD | _S_IWRITE);
// if (file_handle != -1) {
@ -159,36 +159,36 @@ CLP(ShaderContext)::
// }
// _close (file_handle);
// }
//
//
// return state;
// }
//
//
// if (dxgsg9_cat.is_debug()) {
// // DEBUG: output the generated program
// const char *vertex_program;
// const char *pixel_program;
//
//
// vertex_program = cgGetProgramString (_cg_program[0], CG_COMPILED_PROGRAM);
// pixel_program = cgGetProgramString (_cg_program[1], CG_COMPILED_PROGRAM);
//
//
// dxgsg9_cat.debug() << vertex_program << "\n";
// dxgsg9_cat.debug() << pixel_program << "\n";
//
//
// // save the generated program to a file
// int size;
// char file_path [512];
//
//
// char drive[_MAX_DRIVE];
// char dir[_MAX_DIR];
// char fname[_MAX_FNAME];
// char ext[_MAX_EXT];
//
//
// _splitpath (_name.c_str ( ), drive, dir, fname, ext);
//
//
// size = strlen (vertex_program);
// sprintf (file_path, "%s.vasm", fname);
// save_file (size, (void *) vertex_program, file_path);
//
//
// size = strlen (pixel_program);
// sprintf (file_path, "%s.pasm", fname);
// save_file (size, (void *) pixel_program, file_path);
@ -234,36 +234,36 @@ bind(GSG *gsg) {
#ifdef HAVE_CG
if (_cg_context) {
// clear the last cached FVF to make sure the next SetFVF call goes through
gsg -> _last_fvf = 0;
// Pass in k-parameters and transform-parameters
issue_parameters(gsg, Shader::SSD_general);
HRESULT hr;
// Bind the shaders.
bind_state = true;
hr = cgD3D9BindProgram(_cg_vprogram);
if (FAILED (hr)) {
dxgsg9_cat.error() << "cgD3D9BindProgram vertex shader failed " << D3DERRORSTRING(hr);
CGerror error = cgGetError();
if (error != CG_NO_ERROR) {
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
}
bind_state = false;
}
hr = cgD3D9BindProgram(_cg_fprogram);
if (FAILED (hr)) {
dxgsg9_cat.error() << "cgD3D9BindProgram pixel shader failed " << D3DERRORSTRING(hr);
CGerror error = cgGetError();
if (error != CG_NO_ERROR) {
dxgsg9_cat.error() << " CG ERROR: " << cgGetErrorString(error) << "\n";
}
bind_state = false;
}
@ -349,25 +349,25 @@ issue_parameters(GSG *gsg, int altered)
if(altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])){
#ifdef HAVE_CG
const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
Shader::ShaderPtrData* _ptr_data =
Shader::ShaderPtrData* _ptr_data =
const_cast< Shader::ShaderPtrData*>(gsg->fetch_ptr_parameter(_ptr));
if (_ptr_data == NULL){ //the input is not contained in ShaderPtrData
release_resources();
return;
}
CGparameter p = _cg_parameter_map[_ptr._id._seqno];
switch(_ptr_data->_type) {
case Shader::SPT_float:
cgD3D9SetUniform(p, (PN_stdfloat*)_ptr_data->_ptr);
cgD3D9SetUniform(p, (PN_stdfloat*)_ptr_data->_ptr);
break;
default:
dxgsg9_cat.error()
<< _ptr._id._name << ":" << "unrecognized parameter type\n";
release_resources();
default:
dxgsg9_cat.error()
<< _ptr._id._name << ":" << "unrecognized parameter type\n";
release_resources();
return;
}
}
@ -379,7 +379,7 @@ issue_parameters(GSG *gsg, int altered)
CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
if (p == NULL) {
continue;
}
}
const LMatrix4 *val = gsg->fetch_specified_value(_shader->_mat_spec[i], altered);
if (val) {
HRESULT hr;
@ -588,7 +588,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg, bool force) {
dxgsg9_cat.info() << "Geometry contains no data for shader parameter " << *name << "\n";
continue;
}
// If not associated with the array we're working on, move on.
if ( param_array_reader != array_reader ) {
continue;
@ -768,7 +768,7 @@ disable_shader_texture_bindings(GSG *gsg)
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
if (p == NULL) {
continue;
}
}
int texunit = cgGetParameterResourceIndex(p);
HRESULT hr;
@ -809,13 +809,17 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
if (p == NULL) {
continue;
}
Texture *tex = 0;
}
Texture *tex = NULL;
int view = gsg->get_current_tex_view_offset();
InternalName *id = _shader->_tex_spec[i]._name;
if (id != 0) {
SamplerState sampler;
if (id != NULL) {
const ShaderInput *input = gsg->_target_shader->get_shader_input(id);
tex = input->get_texture();
sampler = input->get_sampler();
} else {
// We get the TextureAttrib directly from the _target_rs, not the
// filtered TextureAttrib in _target_texture.
@ -827,6 +831,7 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
}
TextureStage *stage = texattrib->get_on_stage(_shader->_tex_spec[i]._stage);
tex = texattrib->get_on_texture(stage);
sampler = texattrib->get_on_sampler(stage);
view += stage->get_tex_view_offset();
}
if (_shader->_tex_spec[i]._suffix != 0) {
@ -843,10 +848,10 @@ update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
if (tc == (TextureContext*)NULL) {
continue;
}
int texunit = cgGetParameterResourceIndex(p);
gsg->apply_texture(texunit, tc);
gsg->apply_texture(texunit, tc, sampler);
}
}
#endif

View File

@ -645,21 +645,21 @@ create_texture(DXScreenData &scrn) {
// validate magfilter setting
// degrade filtering if no HW support
Texture::FilterType ft;
SamplerState::FilterType ft;
ft = tex->get_magfilter();
if ((ft != Texture::FT_linear) && ft != Texture::FT_nearest) {
if ((ft != SamplerState::FT_linear) && ft != SamplerState::FT_nearest) {
// mipmap settings make no sense for magfilter
if (ft == Texture::FT_nearest_mipmap_nearest) {
ft = Texture::FT_nearest;
if (ft == SamplerState::FT_nearest_mipmap_nearest) {
ft = SamplerState::FT_nearest;
} else {
ft = Texture::FT_linear;
ft = SamplerState::FT_linear;
}
}
if (ft == Texture::FT_linear &&
if (ft == SamplerState::FT_linear &&
(filter_caps & D3DPTFILTERCAPS_MAGFLINEAR) == 0) {
ft = Texture::FT_nearest;
ft = SamplerState::FT_nearest;
}
tex->set_magfilter(ft);
@ -669,33 +669,33 @@ create_texture(DXScreenData &scrn) {
if (!dx_ignore_mipmaps) { // set if no HW mipmap capable
switch(ft) {
case Texture::FT_nearest_mipmap_nearest:
case Texture::FT_linear_mipmap_nearest:
case Texture::FT_nearest_mipmap_linear: // pick nearest in each, interpolate linearly b/w them
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_nearest_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_linear: // pick nearest in each, interpolate linearly b/w them
case SamplerState::FT_linear_mipmap_linear:
_has_mipmaps = true;
}
if (dx_mipmap_everything) { // debug toggle, ok to leave in since its just a creation cost
_has_mipmaps = true;
if (dxgsg9_cat.is_spam()) {
if (ft != Texture::FT_linear_mipmap_linear) {
if (ft != SamplerState::FT_linear_mipmap_linear) {
dxgsg9_cat.spam()
<< "Forcing trilinear mipmapping on DX texture ["
<< tex->get_name() << "]\n";
}
}
ft = Texture::FT_linear_mipmap_linear;
ft = SamplerState::FT_linear_mipmap_linear;
tex->set_minfilter(ft);
}
} else if ((ft == Texture::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
(ft == Texture::FT_nearest_mipmap_linear)) {
ft = Texture::FT_nearest;
} else if ((ft == SamplerState::FT_nearest_mipmap_nearest) || // cvt to no-mipmap filter types
(ft == SamplerState::FT_nearest_mipmap_linear)) {
ft = SamplerState::FT_nearest;
} else if ((ft == Texture::FT_linear_mipmap_nearest) ||
(ft == Texture::FT_linear_mipmap_linear)) {
ft = Texture::FT_linear;
} else if ((ft == SamplerState::FT_linear_mipmap_nearest) ||
(ft == SamplerState::FT_linear_mipmap_linear)) {
ft = SamplerState::FT_linear;
}
nassertr((filter_caps & D3DPTFILTERCAPS_MINFPOINT) != 0, false);
@ -704,36 +704,36 @@ create_texture(DXScreenData &scrn) {
// do any other filter type degradations necessary
switch(ft) {
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
if ((filter_caps & TRILINEAR_MIPMAP_TEXFILTERCAPS) != TRILINEAR_MIPMAP_TEXFILTERCAPS) {
if (filter_caps & D3DPTFILTERCAPS_MINFLINEAR) {
ft = Texture::FT_linear_mipmap_nearest;
ft = SamplerState::FT_linear_mipmap_nearest;
} else {
// if you cant do linear in a level, you probably cant do
// linear b/w levels, so just do nearest-all
ft = Texture::FT_nearest_mipmap_nearest;
ft = SamplerState::FT_nearest_mipmap_nearest;
}
}
break;
case Texture::FT_nearest_mipmap_linear:
case SamplerState::FT_nearest_mipmap_linear:
// if we don't have bilinear, do nearest_nearest
if (!((filter_caps & D3DPTFILTERCAPS_MIPFPOINT) &&
(filter_caps & D3DPTFILTERCAPS_MINFLINEAR))) {
ft = Texture::FT_nearest_mipmap_nearest;
ft = SamplerState::FT_nearest_mipmap_nearest;
}
break;
case Texture::FT_linear_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
// if we don't have mip linear, do nearest_nearest
if (!(filter_caps & D3DPTFILTERCAPS_MIPFLINEAR)) {
ft = Texture::FT_nearest_mipmap_nearest;
ft = SamplerState::FT_nearest_mipmap_nearest;
}
break;
case Texture::FT_linear:
case SamplerState::FT_linear:
if (!(filter_caps & D3DPTFILTERCAPS_MINFLINEAR)) {
ft = Texture::FT_nearest;
ft = SamplerState::FT_nearest;
}
break;
}

View File

@ -1108,16 +1108,16 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
switch (egg_tex->get_minfilter()) {
case EggTexture::FT_nearest:
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
break;
case EggTexture::FT_linear:
if (egg_ignore_filters) {
egg2pg_cat.warning()
<< "Ignoring minfilter request\n";
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
} else {
tex->set_minfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear);
}
break;
@ -1125,13 +1125,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
if (egg_ignore_filters) {
egg2pg_cat.warning()
<< "Ignoring minfilter request\n";
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
} else if (egg_ignore_mipmaps) {
egg2pg_cat.warning()
<< "Ignoring mipmap request\n";
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
} else {
tex->set_minfilter(Texture::FT_nearest_mipmap_nearest);
tex->set_minfilter(SamplerState::FT_nearest_mipmap_nearest);
}
break;
@ -1139,13 +1139,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
if (egg_ignore_filters) {
egg2pg_cat.warning()
<< "Ignoring minfilter request\n";
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
} else if (egg_ignore_mipmaps) {
egg2pg_cat.warning()
<< "Ignoring mipmap request\n";
tex->set_minfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear);
} else {
tex->set_minfilter(Texture::FT_linear_mipmap_nearest);
tex->set_minfilter(SamplerState::FT_linear_mipmap_nearest);
}
break;
@ -1153,13 +1153,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
if (egg_ignore_filters) {
egg2pg_cat.warning()
<< "Ignoring minfilter request\n";
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
} else if (egg_ignore_mipmaps) {
egg2pg_cat.warning()
<< "Ignoring mipmap request\n";
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
} else {
tex->set_minfilter(Texture::FT_nearest_mipmap_linear);
tex->set_minfilter(SamplerState::FT_nearest_mipmap_linear);
}
break;
@ -1167,13 +1167,13 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
if (egg_ignore_filters) {
egg2pg_cat.warning()
<< "Ignoring minfilter request\n";
tex->set_minfilter(Texture::FT_nearest);
tex->set_minfilter(SamplerState::FT_nearest);
} else if (egg_ignore_mipmaps) {
egg2pg_cat.warning()
<< "Ignoring mipmap request\n";
tex->set_minfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear);
} else {
tex->set_minfilter(Texture::FT_linear_mipmap_linear);
tex->set_minfilter(SamplerState::FT_linear_mipmap_linear);
}
break;
@ -1185,7 +1185,7 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
case EggTexture::FT_nearest:
case EggTexture::FT_nearest_mipmap_nearest:
case EggTexture::FT_nearest_mipmap_linear:
tex->set_magfilter(Texture::FT_nearest);
tex->set_magfilter(SamplerState::FT_nearest);
break;
case EggTexture::FT_linear:
@ -1194,9 +1194,9 @@ apply_texture_attributes(Texture *tex, const EggTexture *egg_tex) {
if (egg_ignore_filters) {
egg2pg_cat.warning()
<< "Ignoring magfilter request\n";
tex->set_magfilter(Texture::FT_nearest);
tex->set_magfilter(SamplerState::FT_nearest);
} else {
tex->set_magfilter(Texture::FT_linear);
tex->set_magfilter(SamplerState::FT_linear);
}
break;
@ -1397,35 +1397,35 @@ convert_compression_mode(EggTexture::CompressionMode compression_mode) const {
////////////////////////////////////////////////////////////////////
// Function: EggLoader::convert_wrap_mode
// Access: Private
// Description: Returns the Texture::WrapMode enum corresponding to
// Description: Returns the SamplerState::WrapMode enum corresponding to
// the EggTexture::WrapMode. Returns WM_repeat if the
// wrap mode is unspecified.
////////////////////////////////////////////////////////////////////
Texture::WrapMode EggLoader::
SamplerState::WrapMode EggLoader::
convert_wrap_mode(EggTexture::WrapMode wrap_mode) const {
switch (wrap_mode) {
case EggTexture::WM_clamp:
return Texture::WM_clamp;
return SamplerState::WM_clamp;
case EggTexture::WM_repeat:
return Texture::WM_repeat;
return SamplerState::WM_repeat;
case EggTexture::WM_mirror:
return Texture::WM_mirror;
return SamplerState::WM_mirror;
case EggTexture::WM_mirror_once:
return Texture::WM_mirror_once;
return SamplerState::WM_mirror_once;
case EggTexture::WM_border_color:
return Texture::WM_border_color;
return SamplerState::WM_border_color;
case EggTexture::WM_unspecified:
return Texture::WM_repeat;
return SamplerState::WM_repeat;
}
egg2pg_cat.warning()
<< "Unexpected texture wrap flag: " << (int)wrap_mode << "\n";
return Texture::WM_repeat;
return SamplerState::WM_repeat;
}
////////////////////////////////////////////////////////////////////

View File

@ -123,7 +123,7 @@ private:
bool load_texture(TextureDef &def, EggTexture *egg_tex);
void apply_texture_attributes(Texture *tex, const EggTexture *egg_tex);
Texture::CompressionMode convert_compression_mode(EggTexture::CompressionMode compression_mode) const;
Texture::WrapMode convert_wrap_mode(EggTexture::WrapMode wrap_mode) const;
SamplerState::WrapMode convert_wrap_mode(EggTexture::WrapMode wrap_mode) const;
PT(TextureStage) make_texture_stage(const EggTexture *egg_tex);
void separate_switches(EggNode *egg_node);

View File

@ -965,22 +965,22 @@ get_egg_texture(Texture *tex) {
}
switch (tex->get_minfilter()) {
case Texture::FT_nearest:
case SamplerState::FT_nearest:
temp.set_minfilter(EggTexture::FT_nearest);
break;
case Texture::FT_linear:
case SamplerState::FT_linear:
temp.set_minfilter(EggTexture::FT_linear);
break;
case Texture::FT_nearest_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_nearest:
temp.set_minfilter(EggTexture::FT_nearest_mipmap_nearest);
break;
case Texture::FT_linear_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
temp.set_minfilter(EggTexture::FT_linear_mipmap_nearest);
break;
case Texture::FT_nearest_mipmap_linear:
case SamplerState::FT_nearest_mipmap_linear:
temp.set_minfilter(EggTexture::FT_nearest_mipmap_linear);
break;
case Texture::FT_linear_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
temp.set_minfilter(EggTexture::FT_linear_mipmap_linear);
break;
@ -989,10 +989,10 @@ get_egg_texture(Texture *tex) {
}
switch (tex->get_magfilter()) {
case Texture::FT_nearest:
case SamplerState::FT_nearest:
temp.set_magfilter(EggTexture::FT_nearest);
break;
case Texture::FT_linear:
case SamplerState::FT_linear:
temp.set_magfilter(EggTexture::FT_linear);
break;
@ -1001,10 +1001,10 @@ get_egg_texture(Texture *tex) {
}
switch (tex->get_wrap_u()) {
case Texture::WM_clamp:
case SamplerState::WM_clamp:
temp.set_wrap_u(EggTexture::WM_clamp);
break;
case Texture::WM_repeat:
case SamplerState::WM_repeat:
temp.set_wrap_u(EggTexture::WM_repeat);
break;
@ -1015,10 +1015,10 @@ get_egg_texture(Texture *tex) {
}
switch (tex->get_wrap_v()) {
case Texture::WM_clamp:
case SamplerState::WM_clamp:
temp.set_wrap_v(EggTexture::WM_clamp);
break;
case Texture::WM_repeat:
case SamplerState::WM_repeat:
temp.set_wrap_v(EggTexture::WM_repeat);
break;

View File

@ -34,7 +34,7 @@ class DatagramIterator;
// but it may be used anywhere a list of ButtonEvents
// is desired.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_EVENT ButtonEventList : public EventStoreValueBase {
class EXPCL_PANDA_EVENT ButtonEventList : public ParamValueBase {
public:
INLINE ButtonEventList();
INLINE ButtonEventList(const ButtonEventList &copy);
@ -64,15 +64,15 @@ protected:
public:
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EventStoreValueBase::init_type();
ParamValueBase::init_type();
register_type(_type_handle, "ButtonEventList",
EventStoreValueBase::get_class_type());
ParamValueBase::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -42,12 +42,8 @@ ConfigureFn(config_event) {
PointerEventList::init_type();
Event::init_type();
EventHandler::init_type();
EventStoreValueBase::init_type();
EventStoreInt::init_type("EventStoreInt");
EventStoreDouble::init_type("EventStoreDouble");
EventStoreString::init_type("EventStoreString");
EventStoreWstring::init_type("EventStoreWstring");
EventStoreTypedRefCount::init_type();
GenericAsyncTask::init_type();
#ifdef HAVE_PYTHON
PythonTask::init_type();
@ -56,6 +52,4 @@ ConfigureFn(config_event) {
ButtonEventList::register_with_read_factory();
EventStoreInt::register_with_read_factory();
EventStoreDouble::register_with_read_factory();
EventStoreString::register_with_read_factory();
}

View File

@ -13,10 +13,6 @@
////////////////////////////////////////////////////////////////////
template<class Type>
TypeHandle EventStoreValue<Type>::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EventParameter::Default constructor
// Access: Published
@ -299,175 +295,3 @@ operator << (ostream &out, const EventParameter &param) {
param.output(out);
return out;
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValueBase::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE EventStoreValueBase::
EventStoreValueBase() {
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreTypedRefCount::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE EventStoreTypedRefCount::
EventStoreTypedRefCount(const TypedReferenceCount *value) :
_value((TypedReferenceCount *)value)
{
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreTypedRefCount::set_value
// Access: Published
// Description: Changes the value stored in the parameter. It is
// dangerous to do this for a parameter already added to
// an event, since the parameters may be shared.
////////////////////////////////////////////////////////////////////
INLINE void EventStoreTypedRefCount::
set_value(const TypedReferenceCount *value) {
_value = (TypedReferenceCount *)value;
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreTypedRefCount::get_value
// Access: Published
// Description: Retrieves the value stored in the parameter.
////////////////////////////////////////////////////////////////////
INLINE TypedReferenceCount *EventStoreTypedRefCount::
get_value() const {
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::Default Constructor
// Access: Private
// Description: This constructor is only for make_from_bam().
////////////////////////////////////////////////////////////////////
template<class Type>
EventStoreValue<Type>::
EventStoreValue() {
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class Type>
EventStoreValue<Type>::
EventStoreValue(const Type &value) :
_value(value)
{
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
template<class Type>
EventStoreValue<Type>::
~EventStoreValue() {
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::set_value
// Access: Public
// Description: Changes the value stored in the parameter. It is
// dangerous to do this for a parameter already added to
// an event, since the parameters may be shared.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE void EventStoreValue<Type>::
set_value(const Type &value) {
_value = value;
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::get_value
// Access: Public
// Description: Retrieves the value stored in the parameter.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE const Type &EventStoreValue<Type>::
get_value() const {
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
template<class Type>
void EventStoreValue<Type>::
output(ostream &out) const {
out << _value;
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// Lens.
////////////////////////////////////////////////////////////////////
template<class Type>
void EventStoreValue<Type>::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
template<class Type>
void EventStoreValue<Type>::
write_datagram(BamWriter *manager, Datagram &dg) {
TypedWritable::write_datagram(manager, dg);
generic_write_datagram(dg, _value);
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type Lens is encountered
// in the Bam file. It should create the Lens
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
template<class Type>
TypedWritable *EventStoreValue<Type>::
make_from_bam(const FactoryParams &params) {
EventStoreValue<Type> *esv = new EventStoreValue<Type>;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
esv->fillin(scan, manager);
return esv;
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValue::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new Lens.
////////////////////////////////////////////////////////////////////
template<class Type>
void EventStoreValue<Type>::
fillin(DatagramIterator &scan, BamReader *manager) {
TypedWritable::fillin(scan, manager);
generic_read_datagram(_value, scan);
}

View File

@ -20,21 +20,18 @@
#pragma implementation
#endif
TypeHandle EventStoreValueBase::_type_handle;
TypeHandle EventStoreTypedRefCount::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EventParameter::output
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void EventParameter::
output(ostream &out) const {
if (_ptr == (TypedWritableReferenceCount *)NULL) {
out << "(empty)";
} else if (_ptr->is_of_type(EventStoreValueBase::get_class_type())) {
const EventStoreValueBase *sv_ptr;
} else if (_ptr->is_of_type(ParamValueBase::get_class_type())) {
const ParamValueBase *sv_ptr;
DCAST_INTO_V(sv_ptr, _ptr);
sv_ptr->output(out);
@ -42,36 +39,3 @@ output(ostream &out) const {
out << _ptr->get_type();
}
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreValueBase::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EventStoreValueBase::
~EventStoreValueBase() {
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreTypedRefCount::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
EventStoreTypedRefCount::
~EventStoreTypedRefCount() {
}
////////////////////////////////////////////////////////////////////
// Function: EventStoreTypedRefCount::output
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void EventStoreTypedRefCount::
output(ostream &out) const {
if (_value == (TypedReferenceCount *)NULL) {
out << "(empty)";
} else {
out << _value->get_type();
}
}

View File

@ -23,6 +23,7 @@
#include "pointerTo.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "paramValue.h"
////////////////////////////////////////////////////////////////////
// Class : EventParameter
@ -32,8 +33,7 @@
// object, which of course could be pretty much
// anything. To store a simple value like a double or a
// string, the EventParameter constructors transparently
// use the EventStoreValue template class, defined
// below.
// use the ParamValue template class from paramValue.h.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_EVENT EventParameter {
PUBLISHED:
@ -77,138 +77,15 @@ private:
INLINE ostream &operator << (ostream &out, const EventParameter &param);
////////////////////////////////////////////////////////////////////
// Class : EventStoreValueBase
// Description : A non-template base class of EventStoreValue (below),
// which serves mainly to define the placeholder for the
// virtual output function.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_EVENT EventStoreValueBase : public TypedWritableReferenceCount {
public:
INLINE EventStoreValueBase();
typedef ParamTypedRefCount EventStoreTypedRefCount;
PUBLISHED:
virtual ~EventStoreValueBase();
virtual void output(ostream &out) const=0;
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_EVENT, EXPTP_PANDA_EVENT, ParamValue<int>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_EVENT, EXPTP_PANDA_EVENT, ParamValue<double>);
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedWritableReferenceCount::init_type();
register_type(_type_handle, "EventStoreValueBase",
TypedWritableReferenceCount::get_class_type());
}
private:
static TypeHandle _type_handle;
};
////////////////////////////////////////////////////////////////////
// Class : EventStoreTypedRefCount
// Description : A class object for storing specifically objects of
// type TypedReferenceCount, which is different than
// TypedWritableReferenceCount.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_EVENT EventStoreTypedRefCount : public EventStoreValueBase {
PUBLISHED:
INLINE EventStoreTypedRefCount(const TypedReferenceCount *value);
virtual ~EventStoreTypedRefCount();
INLINE void set_value(const TypedReferenceCount *value);
INLINE TypedReferenceCount *get_value() const;
virtual void output(ostream &out) const;
public:
PT(TypedReferenceCount) _value;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
EventStoreValueBase::init_type();
register_type(_type_handle, "EventStoreTypedRefCount",
EventStoreValueBase::get_class_type());
}
private:
static TypeHandle _type_handle;
};
////////////////////////////////////////////////////////////////////
// Class : EventStoreValue
// Description : A handy class object for storing simple values (like
// integers or strings) passed along with an Event.
// This is essentially just a wrapper around whatever
// data type you like, to make it a
// TypedWritableReferenceCount object which can be
// passed along inside an EventParameter.
////////////////////////////////////////////////////////////////////
template<class Type>
class EventStoreValue : public EventStoreValueBase {
private:
INLINE EventStoreValue();
public:
INLINE EventStoreValue(const Type &value);
virtual ~EventStoreValue();
INLINE void set_value(const Type &value);
INLINE const Type &get_value() const;
virtual void output(ostream &out) const;
Type _value;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type(const string &type_name = "UndefinedEventStoreValue") {
EventStoreValueBase::init_type();
_type_handle = register_dynamic_type
(type_name, EventStoreValueBase::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {
// In this case, we can't do anything, since we don't have the
// class' type_name.
return get_class_type();
}
private:
static TypeHandle _type_handle;
};
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_EVENT, EXPTP_PANDA_EVENT, EventStoreValue<int>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_EVENT, EXPTP_PANDA_EVENT, EventStoreValue<double>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_EVENT, EXPTP_PANDA_EVENT, EventStoreValue<std::string>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_EVENT, EXPTP_PANDA_EVENT, EventStoreValue<std::wstring>);
typedef EventStoreValue<int> EventStoreInt;
typedef EventStoreValue<double> EventStoreDouble;
typedef EventStoreValue<string> EventStoreString;
typedef EventStoreValue<wstring> EventStoreWstring;
typedef ParamValue<int> EventStoreInt;
typedef ParamValue<double> EventStoreDouble;
typedef ParamString EventStoreString;
typedef ParamWstring EventStoreWstring;
#include "eventParameter.I"
@ -218,4 +95,3 @@ typedef EventStoreValue<wstring> EventStoreWstring;
#endif
#endif

View File

@ -34,7 +34,7 @@ class DatagramIterator;
// but it may be used anywhere a list of PointerEvents
// is desired.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_EVENT PointerEventList : public EventStoreValueBase {
class EXPCL_PANDA_EVENT PointerEventList : public ParamValueBase {
PUBLISHED:
INLINE PointerEventList();
@ -53,16 +53,15 @@ PUBLISHED:
INLINE void clear();
INLINE void pop_front();
void add_event(bool in_win, int xpos, int ypos, int seq, double time);
bool encircles(int x, int y) const;
double total_turns(double sec) const;
double match_pattern(const string &pattern, double rot, double seglen);
public:
INLINE PointerEventList(const PointerEventList &copy);
INLINE void operator = (const PointerEventList &copy);
virtual void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
@ -76,9 +75,9 @@ public:
return _type_handle;
}
static void init_type() {
EventStoreValueBase::init_type();
ParamValueBase::init_type();
register_type(_type_handle, "PointerEventList",
EventStoreValueBase::get_class_type());
ParamValueBase::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -710,8 +710,8 @@ load_default_model(const NodePath &parent) {
PT(Texture) tex = new Texture;
tex->set_name("rock-floor.rgb");
tex->load(rock_floor_pnm);
tex->set_minfilter(Texture::FT_linear);
tex->set_magfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear);
tex->set_magfilter(SamplerState::FT_linear);
state = state->add_attrib(TextureAttrib::make(tex));
}
@ -1257,8 +1257,8 @@ load_image_as_model(const Filename &filename) {
}
// Yes, it is an image file; make a texture out of it.
tex->set_minfilter(Texture::FT_linear_mipmap_linear);
tex->set_magfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear_mipmap_linear);
tex->set_magfilter(SamplerState::FT_linear);
// Ok, now make a polygon to show the texture.
bool has_alpha = true;

View File

@ -570,19 +570,25 @@ update_shader_texture_bindings(ShaderContext *prev) {
}
int texunit = cgGetParameterResourceIndex(p);
Texture *tex = 0;
Texture *tex = NULL;
int view = _glgsg->get_current_tex_view_offset();
if (id != 0) {
SamplerState sampler;
if (id != NULL) {
const ShaderInput *input = _glgsg->_target_shader->get_shader_input(id);
tex = input->get_texture();
sampler = input->get_sampler();
} else {
if (_shader->_tex_spec[i]._stage >= texattrib->get_num_on_stages()) {
continue;
}
TextureStage *stage = texattrib->get_on_stage(_shader->_tex_spec[i]._stage);
tex = texattrib->get_on_texture(stage);
sampler = texattrib->get_on_sampler(stage);
view += stage->get_tex_view_offset();
}
if (_shader->_tex_spec[i]._suffix != 0) {
// The suffix feature is inefficient. It is a temporary hack.
if (tex == 0) {
@ -612,6 +618,7 @@ update_shader_texture_bindings(ShaderContext *prev) {
}
_glgsg->apply_texture(tc);
_glgsg->apply_sampler(i, sampler, tc);
}
cg_report_errors();

File diff suppressed because it is too large Load Diff

View File

@ -184,10 +184,20 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size
typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
#endif // OPENGLES_1
#ifndef OPENGLES
typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param);
typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param);
typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param);
typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value);
typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount);
typedef void (APIENTRYP PFNGLCLEARTEXIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, const void *data);
typedef void (APIENTRYP PFNGLCLEARTEXSUBIMAGEPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data);
typedef void (APIENTRYP PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);
typedef void (APIENTRYP PFNGLBINDSAMPLERSPROC) (GLuint first, GLsizei count, const GLuint *samplers);
typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREPROC) (GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format);
typedef void (APIENTRYP PFNGLBINDIMAGETEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);
typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
@ -276,6 +286,9 @@ public:
virtual void release_texture(TextureContext *tc);
virtual bool extract_texture_data(Texture *tex);
virtual SamplerContext *prepare_sampler(const SamplerState &sampler);
virtual void release_sampler(SamplerContext *sc);
virtual GeomContext *prepare_geom(Geom *geom);
virtual void release_geom(GeomContext *gc);
@ -443,14 +456,14 @@ protected:
static GLenum get_numeric_type(Geom::NumericType numeric_type);
GLenum get_texture_target(Texture::TextureType texture_type) const;
GLenum get_texture_wrap_mode(Texture::WrapMode wm) const;
static Texture::WrapMode get_panda_wrap_mode(GLenum wm);
static GLenum get_texture_filter_type(Texture::FilterType ft,
GLenum get_texture_wrap_mode(SamplerState::WrapMode wm) const;
static SamplerState::WrapMode get_panda_wrap_mode(GLenum wm);
static GLenum get_texture_filter_type(SamplerState::FilterType ft,
bool ignore_mipmaps);
static Texture::FilterType get_panda_filter_type(GLenum ft);
static SamplerState::FilterType get_panda_filter_type(GLenum ft);
GLenum get_component_type(Texture::ComponentType component_type);
GLint get_external_image_format(Texture *tex) const;
GLint get_internal_image_format(Texture *tex) const;
GLint get_internal_image_format(Texture *tex, bool force_sized=false) const;
static bool is_mipmap_filter(GLenum min_filter);
static bool is_compressed_format(GLenum format);
static GLint get_texture_apply_mode_type(TextureStage::Mode am);
@ -476,9 +489,10 @@ protected:
#endif // NDEBUG
void do_auto_rescale_normal();
bool specify_texture(CLP(TextureContext) *gtc);
bool specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler);
bool apply_texture(TextureContext *tc);
bool upload_texture(CLP(TextureContext) *gtc, bool force);
bool apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc);
bool upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps);
bool upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
bool uses_mipmaps, int mipmap_bias,
GLenum texture_target, GLenum page_target,
@ -632,6 +646,11 @@ public:
PFNGLTEXSTORAGE2DPROC _glTexStorage2D;
PFNGLTEXSTORAGE3DPROC _glTexStorage3D;
bool _supports_clear_texture;
#ifndef OPENGLES
PFNGLCLEARTEXIMAGEPROC _glClearTexImage;
#endif
PFNGLCOMPRESSEDTEXIMAGE1DPROC _glCompressedTexImage1D;
PFNGLCOMPRESSEDTEXIMAGE2DPROC _glCompressedTexImage2D;
PFNGLCOMPRESSEDTEXIMAGE3DPROC _glCompressedTexImage3D;
@ -765,11 +784,19 @@ public:
PFNGLVERTEXATTRIBLPOINTERPROC _glVertexAttribLPointer;
#endif // OPENGLES_1
#ifndef OPENGLES
PFNGLGENSAMPLERSPROC _glGenSamplers;
PFNGLDELETESAMPLERSPROC _glDeleteSamplers;
PFNGLBINDSAMPLERPROC _glBindSampler;
PFNGLSAMPLERPARAMETERIPROC _glSamplerParameteri;
PFNGLSAMPLERPARAMETERIVPROC _glSamplerParameteriv;
PFNGLSAMPLERPARAMETERFPROC _glSamplerParameterf;
PFNGLSAMPLERPARAMETERFVPROC _glSamplerParameterfv;
PFNGLPROGRAMPARAMETERIPROC _glProgramParameteri;
PFNGLPATCHPARAMETERIPROC _glPatchParameteri;
PFNGLDRAWARRAYSINSTANCEDPROC _glDrawArraysInstanced;
PFNGLDRAWELEMENTSINSTANCEDPROC _glDrawElementsInstanced;
PFNGLBINDTEXTURESPROC _glBindTextures;
PFNGLBINDSAMPLERSPROC _glBindSamplers;
PFNGLBINDIMAGETEXTUREPROC _glBindImageTexture;
PFNGLBINDIMAGETEXTURESPROC _glBindImageTextures;
PFNGLDISPATCHCOMPUTEPROC _glDispatchCompute;
@ -780,6 +807,7 @@ public:
PFNGLSCISSORARRAYVPROC _glScissorArrayv;
PFNGLDEPTHRANGEARRAYVPROC _glDepthRangeArrayv;
PFNGLGETTEXTUREHANDLEPROC _glGetTextureHandle;
PFNGLGETTEXTURESAMPLERHANDLEPROC _glGetTextureSamplerHandle;
PFNGLMAKETEXTUREHANDLERESIDENTPROC _glMakeTextureHandleResident;
PFNGLMAKETEXTUREHANDLENONRESIDENTPROC _glMakeTextureHandleNonResident;
PFNGLUNIFORMHANDLEUI64PROC _glUniformHandleui64;

View File

@ -0,0 +1,83 @@
// Filename: glSamplerContext_src.cxx
// Created by: rdb (11Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "pnotify.h"
TypeHandle CLP(SamplerContext)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CLP(SamplerContext)::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(SamplerContext)::
CLP(SamplerContext)(CLP(GraphicsStateGuardian) *glgsg,
const SamplerState &sampler) :
SamplerContext(sampler)
{
_glgsg = glgsg;
_glgsg->_glGenSamplers(1, &_index);
}
////////////////////////////////////////////////////////////////////
// Function: CLP(SamplerContext)::Denstructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CLP(SamplerContext)::
~CLP(SamplerContext)() {
if (_index != 0) {
_glgsg->_glDeleteSamplers(1, &_index);
_index = 0;
}
}
////////////////////////////////////////////////////////////////////
// Function: GLSamplerContext::evict_lru
// Access: Public, Virtual
// Description: Evicts the page from the LRU. Called internally when
// the LRU determines that it is full. May also be
// called externally when necessary to explicitly evict
// the page.
//
// It is legal for this method to either evict the page
// as requested, do nothing (in which case the eviction
// will be requested again at the next epoch), or
// requeue itself on the tail of the queue (in which
// case the eviction will be requested again much
// later).
////////////////////////////////////////////////////////////////////
void CLP(SamplerContext)::
evict_lru() {
dequeue_lru();
reset_data();
}
////////////////////////////////////////////////////////////////////
// Function: GLSamplerContext::reset_data
// Access: Public
// Description: Resets the texture object to a new one so a new GL
// texture object can be uploaded.
////////////////////////////////////////////////////////////////////
void CLP(SamplerContext)::
reset_data() {
// Free the sampler resource.
_glgsg->_glDeleteSamplers(1, &_index);
_index = 0;
// We still need a valid index number, though, in case we want to
// re-load the sampler later.
//glGenSamplers(1, &_index);
}

View File

@ -0,0 +1,58 @@
// Filename: glSamplerContext_src.h
// Created by: rdb (11Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "samplerContext.h"
#include "deletedChain.h"
class CLP(GraphicsStateGuardian);
////////////////////////////////////////////////////////////////////
// Class : GLSamplerContext
// Description : This class represents a sampler object, which
// contains a set of sampler parameters used when
// sampling a texture.
////////////////////////////////////////////////////////////////////
class EXPCL_GL CLP(SamplerContext) : public SamplerContext {
public:
INLINE CLP(SamplerContext)(CLP(GraphicsStateGuardian) *glgsg,
const SamplerState &sampler);
ALLOC_DELETED_CHAIN(CLP(SamplerContext));
virtual ~CLP(SamplerContext)();
virtual void evict_lru();
void reset_data();
// This is the GL "name" of the sampler object.
GLuint _index;
CLP(GraphicsStateGuardian) *_glgsg;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
SamplerContext::init_type();
register_type(_type_handle, CLASSPREFIX_QUOTED "SamplerContext",
SamplerContext::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
};

View File

@ -1228,17 +1228,14 @@ update_shader_texture_bindings(ShaderContext *prev) {
} else {
//TODO: automatically convert to sized type instead of plain GL_RGBA
// If a base type is used, it will crash.
if (gtc->_internal_format == GL_RGBA || gtc->_internal_format == GL_RGB) {
GLenum internal_format = gtc->_internal_format;
if (internal_format == GL_RGBA || internal_format == GL_RGB) {
GLCAT.error()
<< "Texture " << tex->get_name() << " has an unsized format. Textures bound "
<< "to a shader as an image need a sized format.\n";
// This may not actually be right, but may still prevent a crash.
if (gtc->_internal_format == GL_RGBA) {
gtc->_internal_format = GL_RGBA8;
} else {
gtc->_internal_format = GL_RGB8;
}
internal_format = _glgsg->get_internal_image_format(tex, true);
}
GLenum access = GL_READ_ONLY;
@ -1276,9 +1273,12 @@ update_shader_texture_bindings(ShaderContext *prev) {
Texture *tex = NULL;
int view = _glgsg->get_current_tex_view_offset();
SamplerState sampler;
if (id != NULL) {
const ShaderInput *input = _glgsg->_target_shader->get_shader_input(id);
tex = input->get_texture();
sampler = input->get_sampler();
} else {
if (texunit >= texattrib->get_num_on_stages()) {
@ -1286,6 +1286,7 @@ update_shader_texture_bindings(ShaderContext *prev) {
}
TextureStage *stage = texattrib->get_on_stage(texunit);
tex = texattrib->get_on_texture(stage);
sampler = texattrib->get_on_sampler(stage);
view += stage->get_tex_view_offset();
}
@ -1349,6 +1350,7 @@ update_shader_texture_bindings(ShaderContext *prev) {
continue;
}
_glgsg->apply_texture(gtc);
_glgsg->apply_sampler(i, sampler, gtc);
}
#ifndef OPENGLES

View File

@ -15,8 +15,10 @@
#include "pandabase.h"
#include "textureContext.h"
#include "deletedChain.h"
#include "samplerState.h"
class CLP(GraphicsStateGuardian);
class CLP(SamplerContext);
////////////////////////////////////////////////////////////////////
// Class : GLTextureContext
@ -62,6 +64,7 @@ public:
GLsizei _height;
GLsizei _depth;
GLenum _target;
SamplerState _active_sampler;
CLP(GraphicsStateGuardian) *_glgsg;

View File

@ -259,6 +259,12 @@ ConfigVariableBool gl_support_primitive_restart_index
"segment primitives. Set to false if you suspect a bug "
"in the driver implementation."));
ConfigVariableBool gl_support_sampler_objects
("gl-support-sampler-objects", true,
PRC_DESC("Setting this allows Panda to make use of sampler "
"objects. Set to false if you suspect a bug in the "
"driver implementation."));
extern ConfigVariableBool gl_parallel_arrays;
void CLP(init_classes)() {
@ -270,6 +276,7 @@ void CLP(init_classes)() {
CLP(ShaderContext)::init_type();
#endif
CLP(TextureContext)::init_type();
CLP(SamplerContext)::init_type();
CLP(VertexBufferContext)::init_type();
CLP(GraphicsBuffer)::init_type();

View File

@ -73,6 +73,7 @@ extern ConfigVariableBool gl_use_bindless_texture;
extern ConfigVariableBool gl_enable_memory_barriers;
extern ConfigVariableBool gl_vertex_array_objects;
extern ConfigVariableBool gl_support_primitive_restart_index;
extern ConfigVariableBool gl_support_sampler_objects;
extern EXPCL_GL void CLP(init_classes)();

View File

@ -19,6 +19,7 @@
#include "glmisc_src.cxx"
#include "glTextureContext_src.cxx"
#include "glSamplerContext_src.cxx"
#include "glVertexBufferContext_src.cxx"
#include "glIndexBufferContext_src.cxx"
#include "glOcclusionQueryContext_src.cxx"

View File

@ -33,6 +33,7 @@
#include "glmisc_src.h"
#include "glTextureContext_src.h"
#include "glSamplerContext_src.h"
#include "glVertexBufferContext_src.h"
#include "glIndexBufferContext_src.h"
#include "glOcclusionQueryContext_src.h"

View File

@ -31,12 +31,13 @@
#include "geomVertexArrayFormat.h"
#include "geomVertexData.h"
#include "geomVertexFormat.h"
#include "lens.h"
#include "material.h"
#include "occlusionQueryContext.h"
#include "orthographicLens.h"
#include "matrixLens.h"
#include "paramTexture.h"
#include "perspectiveLens.h"
#include "lens.h"
#include "queryContext.h"
#include "sliderTable.h"
#include "texture.h"
@ -45,6 +46,8 @@
#include "textureStage.h"
#include "textureContext.h"
#include "timerQueryContext.h"
#include "samplerContext.h"
#include "samplerState.h"
#include "shader.h"
#include "shaderContext.h"
#include "transformBlend.h"
@ -480,6 +483,16 @@ ConfigVariableInt graphics_memory_limit
"Set this to -1 to have no limit other than the normal "
"hardware-imposed limit."));
ConfigVariableInt sampler_object_limit
("sampler-object-limit", 2048,
PRC_DESC("This is a default limit that is imposed on each GSG at "
"GSG creation time. It limits the total amount of sampler "
"objects that will be k.ept by the GSG, regardless of whether "
"the hardware claims to provide more sampler objects than this. "
"Direct3D 10-capable hardware supports at least 4096 distinct "
"sampler objects, but we provide a slightly more conservative "
"limit by default."));
ConfigVariableDouble adaptive_lru_weight
("adaptive-lru-weight", 0.2,
PRC_DESC("Specifies the weight factor used to compute the AdaptiveLru's "
@ -559,8 +572,12 @@ ConfigureFn(config_gobj) {
MatrixLens::init_type();
OcclusionQueryContext::init_type();
OrthographicLens::init_type();
ParamTextureImage::init_type();
ParamTextureSampler::init_type();
PerspectiveLens::init_type();
QueryContext::init_type();
SamplerContext::init_type();
SamplerState::init_type();
ShaderContext::init_type();
Shader::init_type();
SliderTable::init_type();
@ -600,6 +617,8 @@ ConfigureFn(config_gobj) {
Material::register_with_read_factory();
MatrixLens::register_with_read_factory();
OrthographicLens::register_with_read_factory();
ParamTextureImage::register_with_read_factory();
ParamTextureSampler::register_with_read_factory();
PerspectiveLens::register_with_read_factory();
Shader::register_with_read_factory();
SliderTable::register_with_read_factory();

View File

@ -96,6 +96,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableString vertex_save_file_prefix;
extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_data_small_size;
extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_data_page_threads;
extern EXPCL_PANDA_GOBJ ConfigVariableInt graphics_memory_limit;
extern EXPCL_PANDA_GOBJ ConfigVariableInt sampler_object_limit;
extern EXPCL_PANDA_GOBJ ConfigVariableDouble adaptive_lru_weight;
extern EXPCL_PANDA_GOBJ ConfigVariableInt adaptive_lru_max_updates_per_frame;
extern EXPCL_PANDA_GOBJ ConfigVariableDouble async_load_delay;

View File

@ -1602,6 +1602,11 @@ get_index_format(NumericType index_type) {
}
return cformat;
}
default:
gobj_cat.error()
<< "Not a valid index type: " << index_type << "\n";
return NULL;
}
return NULL;

View File

@ -33,3 +33,5 @@
#include "material.cxx"
#include "materialPool.cxx"
#include "matrixLens.cxx"
#include "occlusionQueryContext.cxx"
#include "orthographicLens.cxx"

View File

@ -1,8 +1,9 @@
#include "occlusionQueryContext.cxx"
#include "orthographicLens.cxx"
#include "paramTexture.cxx"
#include "perspectiveLens.cxx"
#include "preparedGraphicsObjects.cxx"
#include "queryContext.cxx"
#include "samplerContext.cxx"
#include "samplerState.cxx"
#include "savedContext.cxx"
#include "shaderContext.cxx"
#include "shader.cxx"

View File

@ -0,0 +1,158 @@
// Filename: paramTexture.I
// Created by: rdb (11Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::Constructor
// Access: Published
// Description: Creates a new ParamTextureSampler storing the given
// texture and sampler objects.
////////////////////////////////////////////////////////////////////
INLINE ParamTextureSampler::
ParamTextureSampler(Texture *tex, const SamplerState &sampler) :
_texture(tex),
_sampler(sampler)
{
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::get_value_type
// Access: Published, Virtual
// Description: Returns Texture::get_class_type(), even though it
// technically stores more than just a Texture.
////////////////////////////////////////////////////////////////////
INLINE TypeHandle ParamTextureSampler::
get_value_type() const {
return Texture::get_class_type();
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::get_texture
// Access: Published
// Description: Retrieves the texture stored in the parameter.
////////////////////////////////////////////////////////////////////
INLINE Texture *ParamTextureSampler::
get_texture() const {
return _texture;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::get_sampler
// Access: Published
// Description: Retrieves the sampler state stored in the parameter.
////////////////////////////////////////////////////////////////////
INLINE const SamplerState &ParamTextureSampler::
get_sampler() const {
return _sampler;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::Constructor
// Access: Published
// Description: Creates a new ParamTextureImage storing the given
// texture and image binding parameters.
////////////////////////////////////////////////////////////////////
INLINE ParamTextureImage::
ParamTextureImage(Texture *tex, bool read, bool write, int z, int n) :
_texture(tex),
_access(0),
_bind_level(min(n, 127)),
_bind_layer(z)
{
if (read) {
_access |= A_read;
}
if (write) {
_access |= A_write;
}
if (z < 0) {
_bind_layer = 0;
_access |= A_layered;
}
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::get_value_type
// Access: Published, Virtual
// Description: Returns Texture::get_class_type(), even though it
// technically stores more than just a Texture.
////////////////////////////////////////////////////////////////////
INLINE TypeHandle ParamTextureImage::
get_value_type() const {
return Texture::get_class_type();
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::get_texture
// Access: Published
// Description: Retrieves the texture stored in the parameter.
////////////////////////////////////////////////////////////////////
INLINE Texture *ParamTextureImage::
get_texture() const {
return _texture;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::has_read_access
// Access: Published
// Description: Returns true if this image should be bound with
// read access enabled.
////////////////////////////////////////////////////////////////////
INLINE bool ParamTextureImage::
has_read_access() const {
return (_access & A_read) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::has_write_access
// Access: Published
// Description: Returns true if this image should be bound with
// write access enabled.
////////////////////////////////////////////////////////////////////
INLINE bool ParamTextureImage::
has_write_access() const {
return (_access & A_write) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::get_bind_layered
// Access: Published
// Description: Returns true if all layers of this image should be
// bound simultaneously.
////////////////////////////////////////////////////////////////////
INLINE bool ParamTextureImage::
get_bind_layered() const {
return (_access & A_layered) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::get_bind_level
// Access: Published
// Description: Returns the image level that should be bound.
////////////////////////////////////////////////////////////////////
INLINE int ParamTextureImage::
get_bind_level() const {
return _bind_level;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::get_bind_layer
// Access: Published
// Description: Returns the image layer that should be bound. This
// is undefined if get_bind_layered() returns false.
////////////////////////////////////////////////////////////////////
INLINE int ParamTextureImage::
get_bind_layer() const {
return _bind_layer;
}

View File

@ -0,0 +1,220 @@
// Filename: paramTexture.cxx
// Created by: rdb (11Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "paramTexture.h"
#include "dcast.h"
TypeHandle ParamTextureSampler::_type_handle;
TypeHandle ParamTextureImage::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::output
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void ParamTextureSampler::
output(ostream &out) const {
out << "texture ";
if (_texture != (Texture *)NULL) {
out << _texture->get_name();
} else {
out << "(empty)";
}
out << ", ";
_sampler.output(out);
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// ParamValue.
////////////////////////////////////////////////////////////////////
void ParamTextureSampler::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void ParamTextureSampler::
write_datagram(BamWriter *manager, Datagram &dg) {
ParamValueBase::write_datagram(manager, dg);
manager->write_pointer(dg, _texture);
_sampler.write_datagram(dg);
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::complete_pointers
// Access: Public, Virtual
// Description: Receives an array of pointers, one for each time
// manager->read_pointer() was called in fillin().
// Returns the number of pointers processed.
////////////////////////////////////////////////////////////////////
int ParamTextureSampler::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = ParamValueBase::complete_pointers(p_list, manager);
_texture = DCAST(Texture, p_list[pi++]);
return pi;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type ParamValue is encountered
// in the Bam file. It should create the ParamValue
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *ParamTextureSampler::
make_from_bam(const FactoryParams &params) {
ParamTextureSampler *param = new ParamTextureSampler;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
param->fillin(scan, manager);
return param;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureSampler::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new ParamValue.
////////////////////////////////////////////////////////////////////
void ParamTextureSampler::
fillin(DatagramIterator &scan, BamReader *manager) {
ParamValueBase::fillin(scan, manager);
manager->read_pointer(scan);
_sampler.read_datagram(scan, manager);
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::output
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void ParamTextureImage::
output(ostream &out) const {
out << "texture ";
if (_texture != (Texture *)NULL) {
out << _texture->get_name();
} else {
out << "(empty)";
}
if (_access & A_read) {
if (_access & A_write) {
out << ", read-write";
} else {
out << ", read-only";
}
} else if (_access & A_write) {
out << ", write-only";
}
if (_access & A_layered) {
out << ", all layers";
} else {
out << ", layer " << _bind_layer;
}
out << ", level " << _bind_level;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// ParamValue.
////////////////////////////////////////////////////////////////////
void ParamTextureImage::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
void ParamTextureImage::
write_datagram(BamWriter *manager, Datagram &dg) {
ParamValueBase::write_datagram(manager, dg);
manager->write_pointer(dg, _texture);
dg.add_uint8(_access);
dg.add_int8(_bind_level);
dg.add_int32(_bind_layer);
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::complete_pointers
// Access: Public, Virtual
// Description: Receives an array of pointers, one for each time
// manager->read_pointer() was called in fillin().
// Returns the number of pointers processed.
////////////////////////////////////////////////////////////////////
int ParamTextureImage::
complete_pointers(TypedWritable **p_list, BamReader *manager) {
int pi = ParamValueBase::complete_pointers(p_list, manager);
_texture = DCAST(Texture, p_list[pi++]);
return pi;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type ParamValue is encountered
// in the Bam file. It should create the ParamValue
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
TypedWritable *ParamTextureImage::
make_from_bam(const FactoryParams &params) {
ParamTextureImage *param = new ParamTextureImage;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
param->fillin(scan, manager);
return param;
}
////////////////////////////////////////////////////////////////////
// Function: ParamTextureImage::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new ParamValue.
////////////////////////////////////////////////////////////////////
void ParamTextureImage::
fillin(DatagramIterator &scan, BamReader *manager) {
ParamValueBase::fillin(scan, manager);
manager->read_pointer(scan);
_access = scan.get_uint8();
_bind_level = scan.get_int8();
_bind_layer = scan.get_int32();
}

View File

@ -0,0 +1,143 @@
// Filename: paramTexture.h
// Created by: rdb (11Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef PARAMTEXTURE_H
#define PARAMTEXTURE_H
#include "pandabase.h"
#include "paramValue.h"
#include "samplerState.h"
#include "texture.h"
////////////////////////////////////////////////////////////////////
// Class : ParamTextureSampler
// Description : A class object for storing a pointer to a Texture
// along with a sampler state that indicates how to
// to sample the given texture.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ ParamTextureSampler : public ParamValueBase {
protected:
INLINE ParamTextureSampler() {};
PUBLISHED:
INLINE ParamTextureSampler(Texture *tex, const SamplerState &sampler);
INLINE virtual TypeHandle get_value_type() const;
INLINE Texture *get_texture() const;
INLINE const SamplerState &get_sampler() const;
virtual void output(ostream &out) const;
private:
PT(Texture) _texture;
SamplerState _sampler;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
virtual int complete_pointers(TypedWritable **plist,
BamReader *manager);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ParamValueBase::init_type();
register_type(_type_handle, "ParamTextureSampler",
ParamValueBase::get_class_type());
}
private:
static TypeHandle _type_handle;
};
////////////////////////////////////////////////////////////////////
// Class : ParamTextureImage
// Description : A class object for storing a pointer to a Texture
// along with a set of properties that indicates which
// image to bind to a shader input.
//
// This class is useful for binding texture images
// to a shader, which is a fairly esoteric feature.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ ParamTextureImage : public ParamValueBase {
protected:
INLINE ParamTextureImage() {};
enum AccessFlags {
A_read = 0x01,
A_write = 0x02,
A_layered = 0x04,
};
PUBLISHED:
INLINE ParamTextureImage(Texture *tex, bool read, bool write, int z=-1, int n=0);
INLINE virtual TypeHandle get_value_type() const;
INLINE Texture *get_texture() const;
INLINE bool has_read_access() const;
INLINE bool has_write_access() const;
INLINE bool get_bind_layered() const;
INLINE int get_bind_level() const;
INLINE int get_bind_layer() const;
virtual void output(ostream &out) const;
private:
PT(Texture) _texture;
int _access : 4;
int _bind_level : 8;
int _bind_layer : 20;
public:
static void register_with_read_factory();
virtual void write_datagram(BamWriter *manager, Datagram &dg);
virtual int complete_pointers(TypedWritable **plist,
BamReader *manager);
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ParamValueBase::init_type();
register_type(_type_handle, "ParamTextureImage",
ParamValueBase::get_class_type());
}
private:
static TypeHandle _type_handle;
};
#include "paramTexture.I"
#endif

View File

@ -45,6 +45,7 @@ get_graphics_memory_limit() const {
INLINE void PreparedGraphicsObjects::
release_all() {
release_all_textures();
release_all_samplers();
release_all_geoms();
release_all_shaders();
release_all_vertex_buffers();
@ -63,7 +64,8 @@ release_all() {
////////////////////////////////////////////////////////////////////
INLINE int PreparedGraphicsObjects::
get_num_queued() const {
return (get_num_queued_textures() +
return (get_num_queued_textures() +
get_num_queued_samplers() +
get_num_queued_geoms() +
get_num_queued_shaders() +
get_num_queued_vertex_buffers() +
@ -78,7 +80,8 @@ get_num_queued() const {
////////////////////////////////////////////////////////////////////
INLINE int PreparedGraphicsObjects::
get_num_prepared() const {
return (get_num_prepared_textures() +
return (get_num_prepared_textures() +
get_num_prepared_samplers() +
get_num_prepared_geoms() +
get_num_prepared_shaders() +
get_num_prepared_vertex_buffers() +
@ -88,7 +91,7 @@ get_num_prepared() const {
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::BufferCacheKey::operator <
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PreparedGraphicsObjects::BufferCacheKey::
operator < (const PreparedGraphicsObjects::BufferCacheKey &other) const {
@ -101,7 +104,7 @@ operator < (const PreparedGraphicsObjects::BufferCacheKey &other) const {
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::BufferCacheKey::operator ==
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PreparedGraphicsObjects::BufferCacheKey::
operator == (const PreparedGraphicsObjects::BufferCacheKey &other) const {
@ -112,7 +115,7 @@ operator == (const PreparedGraphicsObjects::BufferCacheKey &other) const {
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::BufferCacheKey::operator !=
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool PreparedGraphicsObjects::BufferCacheKey::
operator != (const PreparedGraphicsObjects::BufferCacheKey &other) const {

View File

@ -20,6 +20,7 @@
#include "geom.h"
#include "geomVertexArrayData.h"
#include "geomPrimitive.h"
#include "samplerContext.h"
#include "shader.h"
#include "reMutexHolder.h"
#include "geomContext.h"
@ -32,10 +33,10 @@ int PreparedGraphicsObjects::_name_index = 0;
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
PreparedGraphicsObjects::
PreparedGraphicsObjects() :
PreparedGraphicsObjects() :
_lock("PreparedGraphicsObjects::_lock"),
_name(init_name()),
_vertex_buffer_cache_size(0),
@ -43,7 +44,8 @@ PreparedGraphicsObjects() :
_texture_residency(_name, "texture"),
_vbuffer_residency(_name, "vbuffer"),
_ibuffer_residency(_name, "ibuffer"),
_graphics_memory_lru("graphics_memory_lru", graphics_memory_limit)
_graphics_memory_lru("graphics_memory_lru", graphics_memory_limit),
_sampler_object_lru("sampler_object_lru", sampler_object_limit)
{
// GLGSG will turn this flag on. This is a temporary hack to
// disable this feature for DX8/DX9 for now, until we work out the
@ -54,7 +56,7 @@ PreparedGraphicsObjects() :
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::Destructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
PreparedGraphicsObjects::
~PreparedGraphicsObjects() {
@ -75,6 +77,9 @@ PreparedGraphicsObjects::
// Is this a leak? Should we delete these TextureContexts?
_released_textures.clear();
release_all_samplers();
_released_samplers.clear();
release_all_geoms();
_released_geoms.clear();
@ -121,7 +126,7 @@ void PreparedGraphicsObjects::
set_graphics_memory_limit(size_t limit) {
if (limit != _graphics_memory_lru.get_max_size()) {
_graphics_memory_lru.set_max_size(limit);
// We throw an event here so global objects (particularly the
// TexMemWatcher) can automatically respond to this change.
throw_event("graphics_memory_limit_changed");
@ -358,6 +363,198 @@ prepare_texture_now(Texture *tex, int view, GraphicsStateGuardianBase *gsg) {
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::enqueue_sampler
// Access: Public
// Description: Indicates that a sampler would like to be put on the
// list to be prepared when the GSG is next ready to
// do this (presumably at the next frame).
////////////////////////////////////////////////////////////////////
void PreparedGraphicsObjects::
enqueue_sampler(const SamplerState &sampler) {
ReMutexHolder holder(_lock);
_enqueued_samplers.insert(sampler);
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::is_sampler_queued
// Access: Public
// Description: Returns true if the sampler has been queued on this
// GSG, false otherwise.
////////////////////////////////////////////////////////////////////
bool PreparedGraphicsObjects::
is_sampler_queued(const SamplerState &sampler) const {
ReMutexHolder holder(_lock);
EnqueuedSamplers::const_iterator qi = _enqueued_samplers.find(sampler);
return (qi != _enqueued_samplers.end());
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::dequeue_sampler
// Access: Public
// Description: Removes a sampler from the queued list of samplers to
// be prepared. Normally it is not necessary to call
// this, unless you change your mind about preparing it
// at the last minute, since the sampler will
// automatically be dequeued and prepared at the next
// frame.
//
// The return value is true if the sampler is
// successfully dequeued, false if it had not been
// queued.
////////////////////////////////////////////////////////////////////
bool PreparedGraphicsObjects::
dequeue_sampler(const SamplerState &sampler) {
ReMutexHolder holder(_lock);
EnqueuedSamplers::iterator qi = _enqueued_samplers.find(sampler);
if (qi != _enqueued_samplers.end()) {
_enqueued_samplers.erase(qi);
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::is_sampler_prepared
// Access: Public
// Description: Returns true if the sampler has been prepared on
// this GSG, false otherwise.
////////////////////////////////////////////////////////////////////
bool PreparedGraphicsObjects::
is_sampler_prepared(const SamplerState &sampler) const {
ReMutexHolder holder(_lock);
PreparedSamplers::const_iterator it = _prepared_samplers.find(sampler);
return (it != _prepared_samplers.end());
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::release_sampler
// Access: Public
// Description: Indicates that a sampler context, created by a
// previous call to prepare_sampler(), is no longer
// needed. The driver resources will not be freed until
// some GSG calls update(), indicating it is at a
// stage where it is ready to release samplers.
////////////////////////////////////////////////////////////////////
void PreparedGraphicsObjects::
release_sampler(SamplerContext *sc) {
ReMutexHolder holder(_lock);
_released_samplers.insert(sc);
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::release_sampler
// Access: Public
// Description: Releases a sampler if it has already been prepared,
// or removes it from the preparation queue.
////////////////////////////////////////////////////////////////////
void PreparedGraphicsObjects::
release_sampler(const SamplerState &sampler) {
ReMutexHolder holder(_lock);
PreparedSamplers::iterator it = _prepared_samplers.find(sampler);
if (it != _prepared_samplers.end()) {
_released_samplers.insert(it->second);
_prepared_samplers.erase(it);
}
_enqueued_samplers.erase(sampler);
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::release_all_samplers
// Access: Public
// Description: Releases all samplers at once. This will force them
// to be reloaded for all GSG's that share this object.
// Returns the number of samplers released.
////////////////////////////////////////////////////////////////////
int PreparedGraphicsObjects::
release_all_samplers() {
ReMutexHolder holder(_lock);
int num_samplers = (int)_prepared_samplers.size() + (int)_enqueued_samplers.size();
PreparedSamplers::iterator sci;
for (sci = _prepared_samplers.begin();
sci != _prepared_samplers.end();
++sci) {
_released_samplers.insert(sci->second);
}
_prepared_samplers.clear();
_enqueued_samplers.clear();
return num_samplers;
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::get_num_queued_samplers
// Access: Public
// Description: Returns the number of samplers that have been
// enqueued to be prepared on this GSG.
////////////////////////////////////////////////////////////////////
int PreparedGraphicsObjects::
get_num_queued_samplers() const {
return _enqueued_samplers.size();
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::get_num_prepared_samplers
// Access: Public
// Description: Returns the number of samplers that have already been
// prepared on this GSG.
////////////////////////////////////////////////////////////////////
int PreparedGraphicsObjects::
get_num_prepared_samplers() const {
return _prepared_samplers.size();
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::prepare_sampler_now
// Access: Public
// Description: Immediately creates a new SamplerContext for the
// indicated sampler and returns it. This assumes that
// the GraphicsStateGuardian is the currently active
// rendering context and that it is ready to accept new
// samplers. If this is not necessarily the case, you
// should use enqueue_sampler() instead.
//
// Normally, this function is not called directly.
// Call Sampler::prepare_now() instead.
//
// The SamplerContext contains all of the pertinent
// information needed by the GSG to keep track of this
// one particular sampler, and will exist as long as the
// sampler is ready to be rendered.
//
// When either the Sampler or the
// PreparedGraphicsObjects object destructs, the
// SamplerContext will be deleted.
////////////////////////////////////////////////////////////////////
SamplerContext *PreparedGraphicsObjects::
prepare_sampler_now(const SamplerState &sampler, GraphicsStateGuardianBase *gsg) {
ReMutexHolder holder(_lock);
PreparedSamplers::const_iterator it = _prepared_samplers.find(sampler);
if (it != _prepared_samplers.end()) {
return it->second;
}
// Ask the GSG to create a brand new SamplerContext.
SamplerContext *sc = gsg->prepare_sampler(sampler);
if (sc != (SamplerContext *)NULL) {
_prepared_samplers[sampler] = sc;
}
return sc;
}
////////////////////////////////////////////////////////////////////
// Function: PreparedGraphicsObjects::enqueue_geom
// Access: Public
@ -870,8 +1067,8 @@ release_all_vertex_buffers() {
// Also clear the cache of recently-unprepared vertex buffers.
BufferCache::iterator bci;
for (bci = _vertex_buffer_cache.begin();
bci != _vertex_buffer_cache.end();
for (bci = _vertex_buffer_cache.begin();
bci != _vertex_buffer_cache.end();
++bci) {
BufferList &buffer_list = (*bci).second;
nassertr(!buffer_list.empty(), num_vertex_buffers);
@ -884,7 +1081,7 @@ release_all_vertex_buffers() {
_vertex_buffer_cache.clear();
_vertex_buffer_cache_lru.clear();
_vertex_buffer_cache_size = 0;
return num_vertex_buffers;
}
@ -1099,8 +1296,8 @@ release_all_index_buffers() {
// Also clear the cache of recently-unprepared index buffers.
BufferCache::iterator bci;
for (bci = _index_buffer_cache.begin();
bci != _index_buffer_cache.end();
for (bci = _index_buffer_cache.begin();
bci != _index_buffer_cache.end();
++bci) {
BufferList &buffer_list = (*bci).second;
nassertr(!buffer_list.empty(), num_index_buffers);
@ -1218,9 +1415,21 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) {
TextureContext *tc = (*tci);
gsg->release_texture(tc);
}
_released_textures.clear();
}
_released_textures.clear();
if (!_released_samplers.empty()) {
ReleasedSamplers::iterator sci;
for (sci = _released_samplers.begin();
sci != _released_samplers.end();
++sci) {
SamplerContext *sc = (*sci);
gsg->release_sampler(sc);
}
_released_samplers.clear();
}
Geoms::iterator gci;
for (gci = _released_geoms.begin();
@ -1284,6 +1493,16 @@ begin_frame(GraphicsStateGuardianBase *gsg, Thread *current_thread) {
_enqueued_textures.clear();
EnqueuedSamplers::iterator qsmi;
for (qsmi = _enqueued_samplers.begin();
qsmi != _enqueued_samplers.end();
++qsmi) {
const SamplerState &sampler = (*qsmi);
sampler.prepare_now(this, gsg);
}
_enqueued_samplers.clear();
EnqueuedGeoms::iterator qgi;
for (qgi = _enqueued_geoms.begin();
qgi != _enqueued_geoms.end();
@ -1371,7 +1590,7 @@ cache_unprepared_buffer(BufferContext *buffer, size_t data_size_bytes,
GeomEnums::UsageHint usage_hint,
PreparedGraphicsObjects::BufferCache &buffer_cache,
PreparedGraphicsObjects::BufferCacheLRU &buffer_cache_lru,
size_t &buffer_cache_size,
size_t &buffer_cache_size,
int released_buffer_cache_size,
PreparedGraphicsObjects::Buffers &released_buffers) {
BufferCacheKey key;
@ -1395,7 +1614,7 @@ cache_unprepared_buffer(BufferContext *buffer, size_t data_size_bytes,
nassertv(!buffer_cache_lru.empty());
const BufferCacheKey &release_key = *buffer_cache_lru.rbegin();
BufferList &buffer_list = buffer_cache[release_key];
while (!buffer_list.empty() &&
while (!buffer_list.empty() &&
(int)buffer_cache_size > released_buffer_cache_size) {
BufferContext *released_buffer = buffer_list.back();
buffer_list.pop_back();

View File

@ -18,6 +18,7 @@
#include "pandabase.h"
#include "referenceCount.h"
#include "texture.h"
#include "samplerState.h"
#include "geom.h"
#include "geomVertexArrayData.h"
#include "geomPrimitive.h"
@ -30,6 +31,7 @@
#include "adaptiveLru.h"
class TextureContext;
class SamplerContext;
class GeomContext;
class ShaderContext;
class VertexBufferContext;
@ -82,7 +84,20 @@ PUBLISHED:
int get_num_queued_textures() const;
int get_num_prepared_textures() const;
TextureContext *prepare_texture_now(Texture *tex, int view,
TextureContext *prepare_texture_now(Texture *tex, int view,
GraphicsStateGuardianBase *gsg);
void enqueue_sampler(const SamplerState &sampler);
bool is_sampler_queued(const SamplerState &sampler) const;
bool dequeue_sampler(const SamplerState &sampler);
bool is_sampler_prepared(const SamplerState &sampler) const;
void release_sampler(SamplerContext *sc);
void release_sampler(const SamplerState &sampler);
int release_all_samplers();
int get_num_queued_samplers() const;
int get_num_prepared_samplers() const;
SamplerContext *prepare_sampler_now(const SamplerState &sampler,
GraphicsStateGuardianBase *gsg);
void enqueue_geom(Geom *geom);
@ -152,6 +167,12 @@ private:
typedef phash_set< PT(GeomVertexArrayData) > EnqueuedVertexBuffers;
typedef phash_set< PT(GeomPrimitive) > EnqueuedIndexBuffers;
// Sampler states are stored a little bit differently, as they are
// mapped by value and can't store the list of prepared samplers.
typedef pmap<SamplerState, SamplerContext *> PreparedSamplers;
typedef pset<SamplerContext *, pointer_hash> ReleasedSamplers;
typedef pset<SamplerState> EnqueuedSamplers;
class BufferCacheKey {
public:
INLINE bool operator < (const BufferCacheKey &other) const;
@ -171,7 +192,7 @@ private:
size_t &buffer_cache_size,
int released_buffer_cache_size,
Buffers &released_buffers);
BufferContext *get_cached_buffer(size_t data_size_bytes,
BufferContext *get_cached_buffer(size_t data_size_bytes,
GeomEnums::UsageHint usage_hint,
BufferCache &buffer_cache,
BufferCacheLRU &buffer_cache_lru,
@ -179,15 +200,18 @@ private:
ReMutex _lock;
string _name;
Textures _prepared_textures, _released_textures;
Textures _prepared_textures, _released_textures;
EnqueuedTextures _enqueued_textures;
Geoms _prepared_geoms, _released_geoms;
PreparedSamplers _prepared_samplers;
ReleasedSamplers _released_samplers;
EnqueuedSamplers _enqueued_samplers;
Geoms _prepared_geoms, _released_geoms;
EnqueuedGeoms _enqueued_geoms;
Shaders _prepared_shaders, _released_shaders;
EnqueuedShaders _enqueued_shaders;
Buffers _prepared_vertex_buffers, _released_vertex_buffers;
Buffers _prepared_vertex_buffers, _released_vertex_buffers;
EnqueuedVertexBuffers _enqueued_vertex_buffers;
Buffers _prepared_index_buffers, _released_index_buffers;
Buffers _prepared_index_buffers, _released_index_buffers;
EnqueuedIndexBuffers _enqueued_index_buffers;
BufferCache _vertex_buffer_cache;
@ -204,6 +228,7 @@ public:
BufferResidencyTracker _ibuffer_residency;
AdaptiveLru _graphics_memory_lru;
SimpleLru _sampler_object_lru;
public:
// This is only public as a temporary hack. Don't mess with it

View File

@ -0,0 +1,25 @@
// Filename: samplerContext.I
// Created by: rdb (11Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: SamplerContext::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE SamplerContext::
SamplerContext(const SamplerState &sampler) :
SimpleLruPage(1)
{
}

View File

@ -0,0 +1,38 @@
// Filename: samplerContext.cxx
// Created by: rdb (11Dec14))
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "samplerContext.h"
TypeHandle SamplerContext::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: SamplerContext::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void SamplerContext::
output(ostream &out) const {
SavedContext::output(out);
}
////////////////////////////////////////////////////////////////////
// Function: SamplerContext::write
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void SamplerContext::
write(ostream &out, int indent_level) const {
SavedContext::write(out, indent_level);
}

View File

@ -0,0 +1,73 @@
// Filename: samplerContext.h
// Created by: rdb (11Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef SAMPLERCONTEXT_H
#define SAMPLERCONTEXT_H
#include "pandabase.h"
#include "adaptiveLru.h"
#include "samplerState.h"
#include "savedContext.h"
////////////////////////////////////////////////////////////////////
// Class : SamplerContext
// Description : This is a special class object that holds a handle
// to the sampler state object given by the graphics
// back-end for a particular combination of texture
// sampling settings.
//
// Some graphics back-ends (like OpenGL) use mutable
// sampler objects, whereas others (Direct3D 10+) use
// immutable ones. In Panda3D, each unique sampler
// state has its own SamplerContext, which simplifies
// the implementation and makes redundant sampler
// objects impossible.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ SamplerContext : public SavedContext, public SimpleLruPage {
public:
INLINE SamplerContext(const SamplerState &sampler);
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
SavedContext::init_type();
register_type(_type_handle, "SamplerContext",
SavedContext::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
private:
static TypeHandle _type_handle;
friend class PreparedGraphicsObjects;
};
inline ostream &operator << (ostream &out, const SamplerContext &context) {
context.output(out);
return out;
}
#include "samplerContext.I"
#endif

View File

@ -0,0 +1,370 @@
// Filename: samplerState.I
// Created by: rdb (09Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: SamplerState::Constructor
// Access: Published
// Description: Creates a new SamplerState initialized to the
// default values.
////////////////////////////////////////////////////////////////////
INLINE SamplerState::
SamplerState() :
_border_color(0, 0, 0, 1),
_wrap_u(WM_repeat),
_wrap_v(WM_repeat),
_wrap_w(WM_repeat),
_minfilter(FT_default),
_magfilter(FT_default),
_min_lod(-1000),
_max_lod(1000),
_lod_bias(0),
_anisotropic_degree(0)
{
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_default
// Access: Published, Static
// Description: Returns a reference to the global default immutable
// SamplerState object.
////////////////////////////////////////////////////////////////////
INLINE const SamplerState &SamplerState::
get_default() {
return _default;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_wrap_u
// Access: Published
// Description: This setting determines what happens when the
// SamplerState is sampled with a U value outside the range
// 0.0-1.0. The default is WM_repeat, which indicates
// that the SamplerState should repeat indefinitely.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_wrap_u(SamplerState::WrapMode wrap) {
_wrap_u = wrap;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_wrap_v
// Access: Published
// Description: This setting determines what happens when the
// SamplerState is sampled with a V value outside the range
// 0.0-1.0. The default is WM_repeat, which indicates
// that the SamplerState should repeat indefinitely.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_wrap_v(SamplerState::WrapMode wrap) {
_wrap_v = wrap;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_wrap_w
// Access: Published
// Description: The W wrap direction is only used for 3-d SamplerStates.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_wrap_w(SamplerState::WrapMode wrap) {
_wrap_w = wrap;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_minfilter
// Access: Published
// Description: Sets the filtering method that should be used when
// viewing the SamplerState from a distance.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_minfilter(SamplerState::FilterType filter) {
_minfilter = filter;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_magfilter
// Access: Published
// Description: Sets the filtering method that should be used when
// viewing the SamplerState up close.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_magfilter(SamplerState::FilterType filter) {
_magfilter = filter;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_anisotropic_degree
// Access: Published
// Description: Specifies the level of anisotropic filtering to apply
// to the SamplerState. Set this 0 to indicate the default
// value, which is specified in the
// SamplerState-anisotropic-degree config variable.
//
// To explicitly disable anisotropic filtering, set this
// value to 1. To explicitly enable anisotropic
// filtering, set it to a value higher than 1; larger
// numbers indicate greater degrees of filtering.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_anisotropic_degree(int anisotropic_degree) {
_anisotropic_degree = anisotropic_degree;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_border_color
// Access: Published
// Description: Specifies the solid color of the SamplerState's border.
// Some OpenGL implementations use a border for tiling
// SamplerStates; in Panda, it is only used for specifying
// the clamp color.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_border_color(const LColor &color) {
_border_color = color;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_min_lod
// Access: Published
// Description: Sets the minimum level of detail that will be used
// when sampling this texture. This may be a negative
// value.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_min_lod(PN_stdfloat min_lod) {
_min_lod = min_lod;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_max_lod
// Access: Published
// Description: Sets the maximum level of detail that will be used
// when sampling this texture. This may exceed the
// number of mipmap levels that the texture has.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_max_lod(PN_stdfloat max_lod) {
_max_lod = max_lod;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::set_lod_bias
// Access: Published
// Description: Sets the value that will be added to the level of
// detail when sampling the texture. This may be a
// negative value, although some graphics hardware may
// not support the use of negative LOD values.
////////////////////////////////////////////////////////////////////
INLINE void SamplerState::
set_lod_bias(PN_stdfloat lod_bias) {
_lod_bias = lod_bias;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_wrap_u
// Access: Published
// Description: Returns the wrap mode of the texture in the U
// direction.
////////////////////////////////////////////////////////////////////
INLINE SamplerState::WrapMode SamplerState::
get_wrap_u() const {
return _wrap_u;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_wrap_v
// Access: Published
// Description: Returns the wrap mode of the texture in the V
// direction.
////////////////////////////////////////////////////////////////////
INLINE SamplerState::WrapMode SamplerState::
get_wrap_v() const {
return _wrap_v;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_wrap_w
// Access: Published
// Description: Returns the wrap mode of the texture in the W
// direction. This is the depth direction of 3-d
// textures.
////////////////////////////////////////////////////////////////////
INLINE SamplerState::WrapMode SamplerState::
get_wrap_w() const {
return _wrap_w;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_minfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// minification. If this is one of the mipmap
// constants, then the texture requires mipmaps. This
// may return FT_default; see also
// get_effective_minfilter().
////////////////////////////////////////////////////////////////////
INLINE SamplerState::FilterType SamplerState::
get_minfilter() const {
return _minfilter;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_magfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// magnification. The mipmap constants are invalid
// here. This may return FT_default; see also
// get_effective_minfilter().
////////////////////////////////////////////////////////////////////
INLINE SamplerState::FilterType SamplerState::
get_magfilter() const {
return _magfilter;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_anisotropic_degree
// Access: Published
// Description: Returns the degree of anisotropic filtering that
// should be applied to the texture. This value may
// return 0, indicating the default value; see also
// get_effective_anisotropic_degree.
////////////////////////////////////////////////////////////////////
INLINE int SamplerState::
get_anisotropic_degree() const {
return _anisotropic_degree;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_effective_anisotropic_degree
// Access: Published
// Description: Returns the degree of anisotropic filtering that
// should be applied to the texture. This value will
// normally not return 0, unless there is an error in
// the config file.
////////////////////////////////////////////////////////////////////
INLINE int SamplerState::
get_effective_anisotropic_degree() const {
if (_anisotropic_degree != 0) {
return _anisotropic_degree;
}
return texture_anisotropic_degree;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_border_color
// Access: Published
// Description: Returns the solid color of the texture's border.
// Some OpenGL implementations use a border for tiling
// textures; in Panda, it is only used for specifying
// the clamp color.
////////////////////////////////////////////////////////////////////
INLINE const LColor &SamplerState::
get_border_color() const {
return _border_color;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_min_lod
// Access: Published
// Description: Returns the minimum level of detail that will be
// observed when sampling this texture.
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat SamplerState::
get_min_lod() const {
return _min_lod;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_max_lod
// Access: Published
// Description: Returns the maximum level of detail that will be
// observed when sampling this texture.
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat SamplerState::
get_max_lod() const {
return _max_lod;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_lod_bias
// Access: Published
// Description: Returns the bias that will be added to the texture
// level of detail when sampling this texture.
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat SamplerState::
get_lod_bias() const {
return _lod_bias;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::uses_mipmaps
// Access: Public
// Description: Returns true if the minfilter settings on this
// sampler indicate the use of mipmapping, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool SamplerState::
uses_mipmaps() const {
return is_mipmap(get_effective_minfilter());
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::is_mipmap
// Access: Published, Static
// Description: Returns true if the indicated filter type requires
// the use of mipmaps, or false if it does not.
////////////////////////////////////////////////////////////////////
INLINE bool SamplerState::
is_mipmap(FilterType filter_type) {
switch (filter_type) {
case SamplerState::FT_nearest_mipmap_nearest:
case SamplerState::FT_linear_mipmap_nearest:
case SamplerState::FT_nearest_mipmap_linear:
case SamplerState::FT_linear_mipmap_linear:
return true;
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::operator ==
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool SamplerState::
operator == (const SamplerState &other) const {
return compare_to(other) == 0;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::operator !=
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool SamplerState::
operator != (const SamplerState &other) const {
return compare_to(other) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::operator <
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool SamplerState::
operator < (const SamplerState &other) const {
return compare_to(other) < 0;
}

View File

@ -0,0 +1,401 @@
// Filename: samplerState.cxx
// Created by: rdb (09Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "samplerState.h"
#include "indent.h"
#include "datagram.h"
#include "datagramIterator.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "samplerContext.h"
#include "preparedGraphicsObjects.h"
TypeHandle SamplerState::_type_handle;
SamplerState SamplerState::_default;
ConfigVariableEnum<SamplerState::FilterType> texture_minfilter
("texture-minfilter", SamplerState::FT_linear,
PRC_DESC("This specifies the default minfilter that is applied to a texture "
"in the absence of a specific minfilter setting. Normally this "
"is either 'linear' to disable mipmapping by default, or "
"'mipmap', to enable trilinear mipmapping by default. This "
"does not apply to depth textures. Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
ConfigVariableEnum<SamplerState::FilterType> texture_magfilter
("texture-magfilter", SamplerState::FT_linear,
PRC_DESC("This specifies the default magfilter that is applied to a texture "
"in the absence of a specific magfilter setting. Normally this "
"is 'linear' (since mipmapping does not apply to magfilters). This "
"does not apply to depth textures. Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
ConfigVariableInt texture_anisotropic_degree
("texture-anisotropic-degree", 1,
PRC_DESC("This specifies the default anisotropic degree that is applied "
"to a texture in the absence of a particular anisotropic degree "
"setting (that is, a texture for which the anisotropic degree "
"is 0, meaning the default setting). It should be 1 to disable "
"anisotropic filtering, or a higher number to enable it. "
"Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_effective_minfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// minification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
////////////////////////////////////////////////////////////////////
SamplerState::FilterType SamplerState::
get_effective_minfilter() const {
if (_minfilter != FT_default) {
return _minfilter;
}
return texture_minfilter;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::get_effective_magfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// magnification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
////////////////////////////////////////////////////////////////////
SamplerState::FilterType SamplerState::
get_effective_magfilter() const {
if (_magfilter != FT_default) {
return _magfilter;
}
return texture_magfilter;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::format_filter_type
// Access: Published, Static
// Description: Returns the indicated FilterType converted to a
// string word.
////////////////////////////////////////////////////////////////////
string SamplerState::
format_filter_type(FilterType ft) {
switch (ft) {
case FT_nearest:
return "nearest";
case FT_linear:
return "linear";
case FT_nearest_mipmap_nearest:
return "nearest_mipmap_nearest";
case FT_linear_mipmap_nearest:
return "linear_mipmap_nearest";
case FT_nearest_mipmap_linear:
return "nearest_mipmap_linear";
case FT_linear_mipmap_linear:
return "linear_mipmap_linear";
case FT_shadow:
return "shadow";
case FT_default:
return "default";
case FT_invalid:
return "invalid";
}
return "**invalid**";
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::string_filter_type
// Access: Public
// Description: Returns the FilterType value associated with the given
// string representation, or FT_invalid if the string
// does not match any known FilterType value.
////////////////////////////////////////////////////////////////////
SamplerState::FilterType SamplerState::
string_filter_type(const string &string) {
if (cmp_nocase_uh(string, "nearest") == 0) {
return FT_nearest;
} else if (cmp_nocase_uh(string, "linear") == 0) {
return FT_linear;
} else if (cmp_nocase_uh(string, "nearest_mipmap_nearest") == 0) {
return FT_nearest_mipmap_nearest;
} else if (cmp_nocase_uh(string, "linear_mipmap_nearest") == 0) {
return FT_linear_mipmap_nearest;
} else if (cmp_nocase_uh(string, "nearest_mipmap_linear") == 0) {
return FT_nearest_mipmap_linear;
} else if (cmp_nocase_uh(string, "linear_mipmap_linear") == 0) {
return FT_linear_mipmap_linear;
} else if (cmp_nocase_uh(string, "mipmap") == 0) {
return FT_linear_mipmap_linear;
} else if (cmp_nocase_uh(string, "shadow") == 0) {
return FT_shadow;
} else if (cmp_nocase_uh(string, "default") == 0) {
return FT_default;
} else {
return FT_invalid;
}
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::format_wrap_mode
// Access: Published, Static
// Description: Returns the indicated WrapMode converted to a
// string word.
////////////////////////////////////////////////////////////////////
string SamplerState::
format_wrap_mode(WrapMode wm) {
switch (wm) {
case WM_clamp:
return "clamp";
case WM_repeat:
return "repeat";
case WM_mirror:
return "mirror";
case WM_mirror_once:
return "mirror_once";
case WM_border_color:
return "border_color";
case WM_invalid:
return "invalid";
}
return "**invalid**";
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::string_wrap_mode
// Access: Public
// Description: Returns the WrapMode value associated with the given
// string representation, or WM_invalid if the string
// does not match any known WrapMode value.
////////////////////////////////////////////////////////////////////
SamplerState::WrapMode SamplerState::
string_wrap_mode(const string &string) {
if (cmp_nocase_uh(string, "repeat") == 0 ||
cmp_nocase_uh(string, "wrap") == 0) {
return WM_repeat;
} else if (cmp_nocase_uh(string, "clamp") == 0) {
return WM_clamp;
} else if (cmp_nocase_uh(string, "mirror") == 0 ||
cmp_nocase_uh(string, "mirrored_repeat") == 0) {
return WM_mirror;
} else if (cmp_nocase_uh(string, "mirror_once") == 0) {
return WM_mirror_once;
} else if (cmp_nocase_uh(string, "border_color") == 0 ||
cmp_nocase_uh(string, "border") == 0) {
return WM_border_color;
} else {
return WM_invalid;
}
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::prepare
// Access: Published
// Description: Indicates that the sampler should be enqueued to be
// prepared in the indicated prepared_objects at the
// beginning of the next frame.
//
// Use this function instead of prepare_now() to preload
// samplers from a user interface standpoint.
////////////////////////////////////////////////////////////////////
void SamplerState::
prepare(PreparedGraphicsObjects *prepared_objects) const {
prepared_objects->enqueue_sampler(*this);
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::is_prepared
// Access: Published
// Description: Returns true if the sampler has already been prepared
// or enqueued for preparation on the indicated GSG,
// false otherwise.
////////////////////////////////////////////////////////////////////
bool SamplerState::
is_prepared(PreparedGraphicsObjects *prepared_objects) const {
return prepared_objects->is_sampler_queued(*this)
|| prepared_objects->is_sampler_prepared(*this);
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::release
// Access: Published
// Description: Frees the texture context only on the indicated object,
// if it exists there. Returns true if it was released,
// false if it had not been prepared.
////////////////////////////////////////////////////////////////////
void SamplerState::
release(PreparedGraphicsObjects *prepared_objects) const {
prepared_objects->release_sampler(*this);
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::prepare_now
// Access: Published
// Description: Creates a context for the sampler on the particular
// GSG, if it does not already exist. Returns the new
// (or old) SamplerContext. This assumes that the
// GraphicsStateGuardian is the currently active
// rendering context and that it is ready to accept new
// textures. If this is not necessarily the case, you
// should use prepare() instead.
//
// Normally, this is not called directly except by the
// GraphicsStateGuardian; a sampler does not need to be
// explicitly prepared by the user before it may be
// rendered.
////////////////////////////////////////////////////////////////////
SamplerContext *SamplerState::
prepare_now(PreparedGraphicsObjects *prepared_objects,
GraphicsStateGuardianBase *gsg) const {
return prepared_objects->prepare_sampler_now(*this, gsg);
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::compare_to
// Access: Public
// Description: Returns a number less than zero if this sampler
// sorts before the other one, greater than zero if it
// sorts after, or zero if they are equivalent. The
// sorting order is arbitrary and largely meaningless,
// except to differentiate different sampler states.
////////////////////////////////////////////////////////////////////
int SamplerState::
compare_to(const SamplerState &other) const {
if (_wrap_u != other._wrap_u) {
return (_wrap_u < other._wrap_u) ? -1 : 1;
}
if (_wrap_v != other._wrap_v) {
return (_wrap_v < other._wrap_v) ? -1 : 1;
}
if (_wrap_w != other._wrap_w) {
return (_wrap_w < other._wrap_w) ? -1 : 1;
}
if (_minfilter != other._minfilter) {
return (_minfilter < other._minfilter) ? -1 : 1;
}
if (_magfilter != other._magfilter) {
return (_magfilter < other._magfilter) ? -1 : 1;
}
if (_anisotropic_degree != other._anisotropic_degree) {
return (_anisotropic_degree < other._anisotropic_degree) ? -1 : 1;
}
if (_border_color != other._border_color) {
return (_border_color < other._border_color) ? -1 : 1;
}
if (_min_lod != other._min_lod) {
return (_min_lod < other._min_lod) ? -1 : 1;
}
if (_max_lod != other._max_lod) {
return (_max_lod < other._max_lod) ? -1 : 1;
}
if (_lod_bias != other._lod_bias) {
return (_lod_bias < other._lod_bias) ? -1 : 1;
}
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::output
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void SamplerState::
output(ostream &out) const {
out
<< "sampler"
<< " wrap(u=" << _wrap_u << ", v=" << _wrap_v << ", w=" << _wrap_w
<< ", border=" << _border_color << ")"
<< " filter(min=" << _minfilter << ", mag=" << _magfilter
<< ", aniso=" << _anisotropic_degree << ")"
<< " lod(min=" << _min_lod << ", max=" << _max_lod
<< ", bias=" << _lod_bias << ")";
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::write
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void SamplerState::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << "SamplerState\n";
indent(out, indent_level) << " wrap_u = " << _wrap_u << "\n";
indent(out, indent_level) << " wrap_v = " << _wrap_v << "\n";
indent(out, indent_level) << " wrap_w = " << _wrap_w << "\n";
indent(out, indent_level) << " minfilter = " << _minfilter << "\n";
indent(out, indent_level) << " magfilter = " << _magfilter << "\n";
indent(out, indent_level) << " anisotropic_degree = " << _anisotropic_degree << "\n";
indent(out, indent_level) << " border_color = " << _border_color << "\n";
indent(out, indent_level) << " min_lod = " << _min_lod << "\n";
indent(out, indent_level) << " max_lod = " << _max_lod << "\n";
indent(out, indent_level) << " lod_bias = " << _lod_bias << "\n";
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::write_datagram
// Access: Public
// Description: Encodes the sampler state into a datagram.
////////////////////////////////////////////////////////////////////
void SamplerState::
write_datagram(Datagram &me) const {
me.add_uint8(_wrap_u);
me.add_uint8(_wrap_v);
me.add_uint8(_wrap_w);
me.add_uint8(_minfilter);
me.add_uint8(_magfilter);
me.add_int16(_anisotropic_degree);
_border_color.write_datagram(me);
me.add_stdfloat(_min_lod);
me.add_stdfloat(_max_lod);
me.add_stdfloat(_lod_bias);
}
////////////////////////////////////////////////////////////////////
// Function: SamplerState::read_datagram
// Access: Protected
// Description: Reads the sampler state from the datagram that has
// been previously written using write_datagram.
////////////////////////////////////////////////////////////////////
void SamplerState::
read_datagram(DatagramIterator &scan, BamReader *manager) {
_wrap_u = (WrapMode)scan.get_uint8();
_wrap_v = (WrapMode)scan.get_uint8();
_wrap_w = (WrapMode)scan.get_uint8();
_minfilter = (FilterType)scan.get_uint8();
_magfilter = (FilterType)scan.get_uint8();
_anisotropic_degree = scan.get_int16();
_border_color.read_datagram(scan);
if (manager->get_file_minor_ver() >= 36) {
// These were added with the introduction of SamplerState.
// Since Texture::do_fillin_body calls this, we still have to
// preserve backward compatibility here.
_min_lod = scan.get_stdfloat();
_max_lod = scan.get_stdfloat();
_lod_bias = scan.get_stdfloat();
} else {
_min_lod = -1000;
_max_lod = 1000;
_lod_bias = 0;
}
}

View File

@ -0,0 +1,213 @@
// Filename: samplerState.h
// Created by: rdb (09Dec14)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef SAMPLERSTATE_H
#define SAMPLERSTATE_H
#include "pandabase.h"
#include "typedObject.h"
#include "namable.h"
#include "luse.h"
#include "numeric_types.h"
#include "config_gobj.h"
class FactoryParams;
class GraphicsStateGuardianBase;
class PreparedGraphicsObjects;
class SamplerContext;
////////////////////////////////////////////////////////////////////
// Class : SamplerState
// Description : Represents a set of settings that indicate how a
// texture is sampled. This can be used to sample the
// same texture using different settings in different
// places.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_GOBJ SamplerState {
PUBLISHED:
enum FilterType {
// Mag Filter and Min Filter
// Point sample the pixel
FT_nearest,
// Bilinear filtering of four neighboring pixels
FT_linear,
// Min Filter Only
// Point sample the pixel from the nearest mipmap level
FT_nearest_mipmap_nearest,
// Bilinear filter the pixel from the nearest mipmap level
FT_linear_mipmap_nearest,
// Point sample the pixel from two mipmap levels, and linearly blend
FT_nearest_mipmap_linear,
// A.k.a. trilinear filtering: Bilinear filter the pixel from
// two mipmap levels, and linearly blend the results.
FT_linear_mipmap_linear,
// The OpenGL ARB_shadow extension can be thought of as a kind of filtering.
FT_shadow,
// Default is usually linear, but it depends on format.
// This was added at the end of the list to avoid bumping TXO version #.
FT_default,
// Returned by string_filter_type() for an invalid match.
FT_invalid
};
enum WrapMode {
WM_clamp, // coords that would be outside [0-1] are clamped to 0 or 1
WM_repeat,
WM_mirror,
WM_mirror_once, // mirror once, then clamp
WM_border_color, // coords outside [0-1] use explicit border color
// Returned by string_wrap_mode() for an invalid match.
WM_invalid
};
INLINE SamplerState();
INLINE static const SamplerState &get_default();
INLINE void set_wrap_u(WrapMode wrap);
INLINE void set_wrap_v(WrapMode wrap);
INLINE void set_wrap_w(WrapMode wrap);
INLINE void set_minfilter(FilterType filter);
INLINE void set_magfilter(FilterType filter);
INLINE void set_anisotropic_degree(int anisotropic_degree);
INLINE void set_border_color(const LColor &color);
INLINE void set_min_lod(PN_stdfloat min_lod);
INLINE void set_max_lod(PN_stdfloat max_lod);
INLINE void set_lod_bias(PN_stdfloat lod_bias);
INLINE WrapMode get_wrap_u() const;
INLINE WrapMode get_wrap_v() const;
INLINE WrapMode get_wrap_w() const;
INLINE FilterType get_minfilter() const;
INLINE FilterType get_magfilter() const;
FilterType get_effective_minfilter() const;
FilterType get_effective_magfilter() const;
INLINE int get_anisotropic_degree() const;
INLINE int get_effective_anisotropic_degree() const;
INLINE const LColor &get_border_color() const;
INLINE PN_stdfloat get_min_lod() const;
INLINE PN_stdfloat get_max_lod() const;
INLINE PN_stdfloat get_lod_bias() const;
INLINE bool uses_mipmaps() const;
INLINE static bool is_mipmap(FilterType type);
static string format_filter_type(FilterType ft);
static FilterType string_filter_type(const string &str);
static string format_wrap_mode(WrapMode wm);
static WrapMode string_wrap_mode(const string &str);
INLINE bool operator == (const SamplerState &other) const;
INLINE bool operator != (const SamplerState &other) const;
INLINE bool operator < (const SamplerState &other) const;
void prepare(PreparedGraphicsObjects *prepared_objects) const;
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
void release(PreparedGraphicsObjects *prepared_objects) const;
SamplerContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
GraphicsStateGuardianBase *gsg) const;
public:
int compare_to(const SamplerState &other) const;
void output(ostream &out) const;
void write(ostream &out, int indent) const;
private:
LColor _border_color;
PN_stdfloat _min_lod;
PN_stdfloat _max_lod;
PN_stdfloat _lod_bias;
// These are packed in a way that this class conveniently fits in
// 32 bytes; feel free to change the packing as necessary when
// more enum values are added.
FilterType _minfilter : 4;
FilterType _magfilter : 4;
WrapMode _wrap_u : 4;
WrapMode _wrap_v : 4;
WrapMode _wrap_w : 4;
int _anisotropic_degree : 12;
static SamplerState _default;
public:
void write_datagram(Datagram &destination) const;
void read_datagram(DatagramIterator &source, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
register_type(_type_handle, "SamplerState",
TypedObject::get_class_type());
}
/*virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}*/
private:
static TypeHandle _type_handle;
};
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<SamplerState::FilterType> texture_minfilter;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<SamplerState::FilterType> texture_magfilter;
extern EXPCL_PANDA_GOBJ ConfigVariableInt texture_anisotropic_degree;
INLINE ostream &operator << (ostream &out, const SamplerState &m) {
m.output(out);
return out;
}
INLINE ostream &operator << (ostream &out, SamplerState::FilterType ft) {
return out << SamplerState::format_filter_type(ft);
}
INLINE istream &operator >> (istream &in, SamplerState::FilterType &ft) {
string word;
in >> word;
ft = SamplerState::string_filter_type(word);
return in;
}
INLINE ostream &operator << (ostream &out, SamplerState::WrapMode wm) {
return out << SamplerState::format_wrap_mode(wm);
}
INLINE istream &operator >> (istream &in, SamplerState::WrapMode &wm) {
string word;
in >> word;
wm = SamplerState::string_wrap_mode(word);
return in;
}
#include "samplerState.I"
#endif

View File

@ -55,14 +55,15 @@ clear() {
// Description: Sets the texture to the indicated type and
// dimensions, presumably in preparation for calling
// read() or load(), or set_ram_image() or
// modify_ram_image().
// modify_ram_image(), or use set_clear_color to let
// the texture be cleared to a solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_texture(Texture::TextureType texture_type, int x_size, int y_size,
int z_size, Texture::ComponentType component_type,
Texture::Format format) {
CDWriter cdata(_cycler, true);
do_setup_texture(cdata, texture_type, x_size, y_size, z_size,
do_setup_texture(cdata, texture_type, x_size, y_size, z_size,
component_type, format);
}
@ -71,7 +72,9 @@ setup_texture(Texture::TextureType texture_type, int x_size, int y_size,
// Access: Published
// Description: Sets the texture as an empty 1-d texture with no
// dimensions. Follow up with read() or load() to fill
// the texture properties and image data.
// the texture properties and image data, or use
// set_clear_color to let the texture be cleared to a
// solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_1d_texture() {
@ -84,7 +87,8 @@ setup_1d_texture() {
// Description: Sets the texture as an empty 1-d texture with the
// specified dimensions and properties. Follow up with
// set_ram_image() or modify_ram_image() to fill the
// image data.
// image data, or use set_clear_color to let the
// texture be cleared to a solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_1d_texture(int x_size, ComponentType component_type, Format format) {
@ -96,7 +100,9 @@ setup_1d_texture(int x_size, ComponentType component_type, Format format) {
// Access: Published
// Description: Sets the texture as an empty 2-d texture with no
// dimensions. Follow up with read() or load() to fill
// the texture properties and image data.
// the texture properties and image data, or use
// set_clear_color to let the texture be cleared to a
// solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_2d_texture() {
@ -109,10 +115,11 @@ setup_2d_texture() {
// Description: Sets the texture as an empty 2-d texture with the
// specified dimensions and properties. Follow up with
// set_ram_image() or modify_ram_image() to fill the
// image data.
// image data, or use set_clear_color to let the
// texture be cleared to a solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_2d_texture(int x_size, int y_size, ComponentType component_type,
setup_2d_texture(int x_size, int y_size, ComponentType component_type,
Format format) {
setup_texture(TT_2d_texture, x_size, y_size, 1, component_type, format);
}
@ -124,7 +131,8 @@ setup_2d_texture(int x_size, int y_size, ComponentType component_type,
// dimensions (though if you know the depth ahead
// of time, it saves a bit of reallocation later).
// Follow up with read() or load() to fill the texture
// properties and image data.
// properties and image data, or use set_clear_color
// to let the texture be cleared to a solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_3d_texture(int z_size) {
@ -152,7 +160,8 @@ setup_3d_texture(int x_size, int y_size, int z_size,
// no dimensions (though if you know the depth ahead
// of time, it saves a bit of reallocation later).
// Follow up with read() or load() to fill the texture
// properties and image data.
// properties and image data, or use set_clear_color
// to let the texture be cleared to a solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_2d_texture_array(int z_size) {
@ -165,7 +174,8 @@ setup_2d_texture_array(int z_size) {
// Description: Sets the texture as an empty 2-d texture array with the
// specified dimensions and properties. Follow up with
// set_ram_image() or modify_ram_image() to fill the
// image data.
// image data, or use set_clear_color to let the
// texture be cleared to a solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_2d_texture_array(int x_size, int y_size, int z_size,
@ -178,7 +188,9 @@ setup_2d_texture_array(int x_size, int y_size, int z_size,
// Access: Published
// Description: Sets the texture as an empty cube map texture with no
// dimensions. Follow up with read() or load() to fill
// the texture properties and image data.
// the texture properties and image data, or use
// set_clear_color to let the texture be cleared to a
// solid color.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
setup_cube_map() {
@ -191,7 +203,8 @@ setup_cube_map() {
// Description: Sets the texture as an empty cube map texture with
// the specified dimensions and properties. Follow up
// with set_ram_image() or modify_ram_image() to fill
// the image data.
// the image data, or use set_clear_color to let the
// texture be cleared to a solid color.
//
// Note that a cube map should always consist of six
// square images, so x_size and y_size will be the same,
@ -202,6 +215,87 @@ setup_cube_map(int size, ComponentType component_type, Format format) {
setup_texture(TT_cube_map, size, size, 6, component_type, format);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::clear_image
// Access: Published
// Description: Clears the texture data without changing its format
// or resolution. The texture is cleared on both the
// graphics hardware and from RAM, unlike clear_ram_image,
// which only removes the data from RAM.
//
// If a clear color has been specified using
// set_clear_color, the texture will be cleared using
// a solid color.
//
// The texture data will be cleared the first time in
// which the texture is used after this method is called.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
clear_image() {
CDWriter cdata(_cycler, true);
do_clear_ram_image(cdata);
do_clear_simple_ram_image(cdata);
cdata->inc_image_modified();
cdata->inc_simple_image_modified();
}
////////////////////////////////////////////////////////////////////
// Function: Texture::has_clear_color
// Access: Published
// Description: Returns true if a color was previously set using
// set_clear_color.
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
has_clear_color() const {
CDReader cdata(_cycler);
return cdata->_has_clear_color;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_clear_color
// Access: Published
// Description: Returns the color that was previously set using
// set_clear_color.
////////////////////////////////////////////////////////////////////
INLINE LColor Texture::
get_clear_color() const {
CDReader cdata(_cycler);
return cdata->_clear_color;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_clear_color
// Access: Published
// Description: Sets the color that will be used to fill the
// texture image in absence of any image data. It is
// used when any of the setup_texture functions or
// clear_image is called and image data is not
// provided using read() or modify_ram_image().
//
// This does not affect a texture that has already
// been cleared; call clear_image to clear it again.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_clear_color(const LColor &color) {
CDWriter cdata(_cycler, true);
cdata->_clear_color = color;
cdata->_has_clear_color = true;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_clear_data
// Access: Published
// Description: Returns the raw image data for a single pixel if
// it were set to the clear color.
////////////////////////////////////////////////////////////////////
INLINE string Texture::
get_clear_data() const {
CDReader cdata(_cycler);
unsigned char data[16];
int size = do_get_clear_data(cdata, data);
return string((char *)data, size);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::write
// Access: Published
@ -273,7 +367,7 @@ write(const Filename &fullpath) {
// the page index.
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
write(const Filename &fullpath, int z, int n,
write(const Filename &fullpath, int z, int n,
bool write_pages, bool write_mipmaps) {
CDWriter cdata(_cycler, false);
return do_write(cdata, fullpath, z, n, write_pages, write_mipmaps);
@ -523,7 +617,7 @@ has_alpha_fullpath() const {
////////////////////////////////////////////////////////////////////
// Function: Texture::get_alpha_fullpath
// Access: Published
// Description:
// Description:
// Returns the alpha_fullpath that has been set. This
// is the full path to the alpha part of the image file
// as it was found along the texture search path.
@ -594,7 +688,7 @@ get_num_views() const {
////////////////////////////////////////////////////////////////////
// Function: Texture::get_num_pages
// Access: Published
// Description: Returns the total number of pages in the texture.
// Description: Returns the total number of pages in the texture.
// Each "page" is a 2-d texture image within the larger
// image--a face of a cube map, or a level of a 3-d
// texture. Normally, get_num_pages() is the same as
@ -795,10 +889,17 @@ get_component_type() const {
////////////////////////////////////////////////////////////////////
// Function: Texture::set_wrap_u
// Access: Published
// Description:
// Description: This setting determines what happens when the
// texture is sampled with a U value outside the range
// 0.0-1.0. The default is WM_repeat, which indicates
// that the texture should repeat indefinitely.
//
// This sets the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_wrap_u(Texture::WrapMode wrap) {
set_wrap_u(SamplerState::WrapMode wrap) {
CDWriter cdata(_cycler, true);
do_set_wrap_u(cdata, wrap);
}
@ -806,10 +907,17 @@ set_wrap_u(Texture::WrapMode wrap) {
////////////////////////////////////////////////////////////////////
// Function: Texture::set_wrap_v
// Access: Published
// Description:
// Description: This setting determines what happens when the
// texture is sampled with a V value outside the range
// 0.0-1.0. The default is WM_repeat, which indicates
// that the texture should repeat indefinitely.
//
// This sets the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_wrap_v(Texture::WrapMode wrap) {
set_wrap_v(SamplerState::WrapMode wrap) {
CDWriter cdata(_cycler, true);
do_set_wrap_v(cdata, wrap);
}
@ -818,9 +926,13 @@ set_wrap_v(Texture::WrapMode wrap) {
// Function: Texture::set_wrap_w
// Access: Published
// Description: The W wrap direction is only used for 3-d textures.
//
// This sets the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_wrap_w(Texture::WrapMode wrap) {
set_wrap_w(SamplerState::WrapMode wrap) {
CDWriter cdata(_cycler, true);
do_set_wrap_w(cdata, wrap);
}
@ -828,10 +940,15 @@ set_wrap_w(Texture::WrapMode wrap) {
////////////////////////////////////////////////////////////////////
// Function: Texture::set_minfilter
// Access: Published
// Description:
// Description: Sets the filtering method that should be used when
// viewing the texture from a distance.
//
// This sets the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_minfilter(Texture::FilterType filter) {
set_minfilter(SamplerState::FilterType filter) {
CDWriter cdata(_cycler, true);
do_set_minfilter(cdata, filter);
}
@ -839,10 +956,15 @@ set_minfilter(Texture::FilterType filter) {
////////////////////////////////////////////////////////////////////
// Function: Texture::set_magfilter
// Access: Published
// Description:
// Description: Sets the filtering method that should be used when
// viewing the texture up close.
//
// This sets the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_magfilter(Texture::FilterType filter) {
set_magfilter(SamplerState::FilterType filter) {
CDWriter cdata(_cycler, true);
do_set_magfilter(cdata, filter);
}
@ -859,6 +981,10 @@ set_magfilter(Texture::FilterType filter) {
// value to 1. To explicitly enable anisotropic
// filtering, set it to a value higher than 1; larger
// numbers indicate greater degrees of filtering.
//
// This sets the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_anisotropic_degree(int anisotropic_degree) {
@ -873,6 +999,10 @@ set_anisotropic_degree(int anisotropic_degree) {
// Some OpenGL implementations use a border for tiling
// textures; in Panda, it is only used for specifying
// the clamp color.
//
// This sets the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE void Texture::
set_border_color(const LColor &color) {
@ -884,7 +1014,7 @@ set_border_color(const LColor &color) {
// Function: Texture::set_compression
// Access: Published
// Description: Requests that this particular Texture be compressed
// when it is loaded into texture memory.
// when it is loaded into texture memory.
//
// This refers to the internal compression of the
// texture image within texture memory; it is not
@ -928,16 +1058,35 @@ set_render_to_texture(bool render_to_texture) {
cdata->_render_to_texture = render_to_texture;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_default_sampler
// Access: Published
// Description: This returns the default sampler state for this
// texture, containing the wrap and filter properties
// specified on the texture level; it may still be
// overridden by a sampler state specified at a higher
// level.
////////////////////////////////////////////////////////////////////
INLINE const SamplerState &Texture::
get_default_sampler() const {
CDReader cdata(_cycler);
return cdata->_default_sampler;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_wrap_u
// Access: Published
// Description: Returns the wrap mode of the texture in the U
// direction.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE Texture::WrapMode Texture::
INLINE SamplerState::WrapMode Texture::
get_wrap_u() const {
CDReader cdata(_cycler);
return cdata->_wrap_u;
return cdata->_default_sampler.get_wrap_u();
}
////////////////////////////////////////////////////////////////////
@ -945,11 +1094,15 @@ get_wrap_u() const {
// Access: Published
// Description: Returns the wrap mode of the texture in the V
// direction.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE Texture::WrapMode Texture::
INLINE SamplerState::WrapMode Texture::
get_wrap_v() const {
CDReader cdata(_cycler);
return cdata->_wrap_v;
return cdata->_default_sampler.get_wrap_v();
}
////////////////////////////////////////////////////////////////////
@ -958,11 +1111,15 @@ get_wrap_v() const {
// Description: Returns the wrap mode of the texture in the W
// direction. This is the depth direction of 3-d
// textures.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE Texture::WrapMode Texture::
INLINE SamplerState::WrapMode Texture::
get_wrap_w() const {
CDReader cdata(_cycler);
return cdata->_wrap_w;
return cdata->_default_sampler.get_wrap_w();
}
////////////////////////////////////////////////////////////////////
@ -973,11 +1130,15 @@ get_wrap_w() const {
// constants, then the texture requires mipmaps. This
// may return FT_default; see also
// get_effective_minfilter().
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE Texture::FilterType Texture::
INLINE SamplerState::FilterType Texture::
get_minfilter() const {
CDReader cdata(_cycler);
return cdata->_minfilter;
return cdata->_default_sampler.get_minfilter();
}
////////////////////////////////////////////////////////////////////
@ -987,11 +1148,51 @@ get_minfilter() const {
// magnification. The mipmap constants are invalid
// here. This may return FT_default; see also
// get_effective_minfilter().
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE Texture::FilterType Texture::
INLINE SamplerState::FilterType Texture::
get_magfilter() const {
CDReader cdata(_cycler);
return cdata->_magfilter;
return cdata->_default_sampler.get_magfilter();
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_minfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// minification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
SamplerState::FilterType Texture::
get_effective_minfilter() const {
CDReader cdata(_cycler);
return cdata->_default_sampler.get_effective_minfilter();
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_magfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// magnification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
SamplerState::FilterType Texture::
get_effective_magfilter() const {
CDReader cdata(_cycler);
return cdata->_default_sampler.get_effective_magfilter();
}
////////////////////////////////////////////////////////////////////
@ -1001,11 +1202,15 @@ get_magfilter() const {
// should be applied to the texture. This value may
// return 0, indicating the default value; see also
// get_effective_anisotropic_degree.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE int Texture::
get_anisotropic_degree() const {
CDReader cdata(_cycler);
return cdata->_anisotropic_degree;
return cdata->_default_sampler.get_anisotropic_degree();
}
////////////////////////////////////////////////////////////////////
@ -1015,14 +1220,15 @@ get_anisotropic_degree() const {
// should be applied to the texture. This value will
// normally not return 0, unless there is an error in
// the config file.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE int Texture::
get_effective_anisotropic_degree() const {
CDReader cdata(_cycler);
if (cdata->_anisotropic_degree != 0) {
return cdata->_anisotropic_degree;
}
return texture_anisotropic_degree;
return cdata->_default_sampler.get_effective_anisotropic_degree();
}
////////////////////////////////////////////////////////////////////
@ -1032,11 +1238,15 @@ get_effective_anisotropic_degree() const {
// Some OpenGL implementations use a border for tiling
// textures; in Panda, it is only used for specifying
// the clamp color.
//
// This returns the default sampler state for this
// texture; it may still be overridden by a sampler
// state specified at a higher level.
////////////////////////////////////////////////////////////////////
INLINE LColor Texture::
get_border_color() const {
CDReader cdata(_cycler);
return cdata->_border_color;
return cdata->_default_sampler.get_border_color();
}
////////////////////////////////////////////////////////////////////
@ -1107,7 +1317,7 @@ get_render_to_texture() const {
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
uses_mipmaps() const {
return is_mipmap(get_effective_minfilter());
return SamplerState::is_mipmap(get_effective_minfilter());
}
////////////////////////////////////////////////////////////////////
@ -2400,7 +2610,7 @@ adjust_this_size(int &x_size, int &y_size, const string &name,
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_ram_image_size
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE size_t Texture::
do_get_ram_image_size(const CData *cdata) const {
@ -2413,18 +2623,18 @@ do_get_ram_image_size(const CData *cdata) const {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_has_ram_mipmap_image
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool Texture::
do_has_ram_mipmap_image(const CData *cdata, int n) const {
return (n >= 0 && n < (int)cdata->_ram_images.size() &&
return (n >= 0 && n < (int)cdata->_ram_images.size() &&
!cdata->_ram_images[n]._image.empty());
}
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_expected_ram_image_size
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE size_t Texture::
do_get_expected_ram_image_size(const CData *cdata) const {
@ -2434,7 +2644,7 @@ do_get_expected_ram_image_size(const CData *cdata) const {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_expected_ram_view_size
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE size_t Texture::
do_get_expected_ram_view_size(const CData *cdata) const {
@ -2444,7 +2654,7 @@ do_get_expected_ram_view_size(const CData *cdata) const {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_expected_ram_page_size
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE size_t Texture::
do_get_expected_ram_page_size(const CData *cdata) const {
@ -2454,7 +2664,7 @@ do_get_expected_ram_page_size(const CData *cdata) const {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_expected_ram_mipmap_image_size
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE size_t Texture::
do_get_expected_ram_mipmap_image_size(const CData *cdata, int n) const {
@ -2464,7 +2674,7 @@ do_get_expected_ram_mipmap_image_size(const CData *cdata, int n) const {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_expected_ram_mipmap_view_size
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE size_t Texture::
do_get_expected_ram_mipmap_view_size(const CData *cdata, int n) const {
@ -2474,7 +2684,7 @@ do_get_expected_ram_mipmap_view_size(const CData *cdata, int n) const {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_expected_ram_mipmap_page_size
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE size_t Texture::
do_get_expected_ram_mipmap_page_size(const CData *cdata, int n) const {
@ -2494,7 +2704,7 @@ do_get_expected_mipmap_num_pages(const CData *cdata, int n) const {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_clear_ram_image
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Texture::
do_clear_ram_image(CData *cdata) {
@ -2505,7 +2715,7 @@ do_clear_ram_image(CData *cdata) {
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_auto_texture_scale
// Access: Protected
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE AutoTextureScale Texture::
do_get_auto_texture_scale(const CData *cdata) const {
@ -2647,7 +2857,7 @@ is_dds_filename(const Filename &fullpath) {
////////////////////////////////////////////////////////////////////
// Function: Texture::CData::inc_properties_modified
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Texture::CData::
inc_properties_modified() {
@ -2657,7 +2867,7 @@ inc_properties_modified() {
////////////////////////////////////////////////////////////////////
// Function: Texture::CData::inc_image_modified
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Texture::CData::
inc_image_modified() {
@ -2667,7 +2877,7 @@ inc_image_modified() {
////////////////////////////////////////////////////////////////////
// Function: Texture::CData::inc_simple_image_modified
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE void Texture::CData::
inc_simple_image_modified() {
@ -2677,7 +2887,7 @@ inc_simple_image_modified() {
////////////////////////////////////////////////////////////////////
// Function: Texture::RamImage::Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE Texture::RamImage::
RamImage() :

View File

@ -58,36 +58,6 @@ ConfigVariableEnum<Texture::QualityLevel> texture_quality_level
"it has little or no effect on normal, hardware-accelerated "
"renderers. See Texture::set_quality_level()."));
ConfigVariableEnum<Texture::FilterType> texture_minfilter
("texture-minfilter", Texture::FT_linear,
PRC_DESC("This specifies the default minfilter that is applied to a texture "
"in the absence of a specific minfilter setting. Normally this "
"is either 'linear' to disable mipmapping by default, or "
"'mipmap', to enable trilinear mipmapping by default. This "
"does not apply to depth textures. Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
ConfigVariableEnum<Texture::FilterType> texture_magfilter
("texture-magfilter", Texture::FT_linear,
PRC_DESC("This specifies the default magfilter that is applied to a texture "
"in the absence of a specific magfilter setting. Normally this "
"is 'linear' (since mipmapping does not apply to magfilters). This "
"does not apply to depth textures. Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
ConfigVariableInt texture_anisotropic_degree
("texture-anisotropic-degree", 1,
PRC_DESC("This specifies the default anisotropic degree that is applied "
"to a texture in the absence of a particular anisotropic degree "
"setting (that is, a texture for which the anisotropic degree "
"is 0, meaning the default setting). It should be 1 to disable "
"anisotropic filtering, or a higher number to enable it. "
"Note if this variable is "
"changed at runtime, you may need to reload textures explicitly "
"in order to change their visible properties."));
PStatCollector Texture::_texture_read_pcollector("*:Texture:Read");
TypeHandle Texture::_type_handle;
TypeHandle Texture::CData::_type_handle;
@ -380,9 +350,10 @@ void Texture::
generate_alpha_scale_map() {
CDWriter cdata(_cycler, true);
do_setup_texture(cdata, TT_1d_texture, 256, 1, 1, T_unsigned_byte, F_alpha);
cdata->_wrap_u = WM_clamp;
cdata->_minfilter = FT_nearest;
cdata->_magfilter = FT_nearest;
cdata->_default_sampler.set_wrap_u(SamplerState::WM_clamp);
cdata->_default_sampler.set_minfilter(SamplerState::FT_nearest);
cdata->_default_sampler.set_magfilter(SamplerState::FT_nearest);
cdata->_compression = CM_off;
cdata->inc_image_modified();
@ -591,6 +562,8 @@ estimate_texture_memory() const {
case Texture::F_rgb8:
case Texture::F_rgba8:
case Texture::F_srgb_alpha:
case Texture::F_rgb8i:
case Texture::F_rgba8i:
bpp = 4;
break;
@ -612,6 +585,8 @@ estimate_texture_memory() const {
break;
case Texture::F_r16:
case Texture::F_r8i:
case Texture::F_rg8i:
bpp = 2;
break;
case Texture::F_rg16:
@ -877,48 +852,6 @@ load_related(const InternalName *suffix) const {
return res;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_minfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// minification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
////////////////////////////////////////////////////////////////////
Texture::FilterType Texture::
get_effective_minfilter() const {
CDReader cdata(_cycler);
if (cdata->_minfilter != FT_default) {
return cdata->_minfilter;
}
if (cdata->_format == Texture::F_depth_stencil ||
cdata->_format == Texture::F_depth_component) {
return FT_nearest;
}
return texture_minfilter;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::get_effective_magfilter
// Access: Published
// Description: Returns the filter mode of the texture for
// magnification, with special treatment for FT_default.
// This will normally not return FT_default, unless
// there is an error in the config file.
////////////////////////////////////////////////////////////////////
Texture::FilterType Texture::
get_effective_magfilter() const {
CDReader cdata(_cycler);
if (cdata->_magfilter != FT_default) {
return cdata->_magfilter;
}
if (cdata->_format == Texture::F_depth_stencil ||
cdata->_format == Texture::F_depth_component) {
return FT_nearest;
}
return texture_magfilter;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::set_ram_image_as
// Access: Published
@ -1789,32 +1722,7 @@ write(ostream &out, int indent_level) const {
indent(out, indent_level + 2);
switch (cdata->_texture_type) {
case TT_1d_texture:
out << cdata->_wrap_u << ", ";
break;
case TT_2d_texture:
out << cdata->_wrap_u << " x " << cdata->_wrap_v << ", ";
break;
case TT_3d_texture:
out << cdata->_wrap_u << " x " << cdata->_wrap_v << " x " << cdata->_wrap_w << ", ";
break;
case TT_2d_texture_array:
out << cdata->_wrap_u << " x " << cdata->_wrap_v << " x " << cdata->_wrap_w << ", ";
break;
case TT_cube_map:
break;
}
out << "min " << cdata->_minfilter
<< ", mag " << cdata->_magfilter
<< ", aniso " << cdata->_anisotropic_degree
<< ", border " << cdata->_border_color
<< "\n";
cdata->_default_sampler.output(out);
if (do_has_ram_image(cdata)) {
indent(out, indent_level + 2)
@ -1879,7 +1787,7 @@ set_size_padded(int x, int y, int z) {
do_set_y_size(cdata, y);
do_set_z_size(cdata, z);
}
do_set_pad_size(cdata,
do_set_pad_size(cdata,
cdata->_x_size - x,
cdata->_y_size - y,
cdata->_z_size - z);
@ -1900,26 +1808,6 @@ set_orig_file_size(int x, int y, int z) {
nassertv(z == cdata->_z_size);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::is_mipmap
// Access: Published, Static
// Description: Returns true if the indicated filter type requires
// the use of mipmaps, or false if it does not.
////////////////////////////////////////////////////////////////////
bool Texture::
is_mipmap(FilterType filter_type) {
switch (filter_type) {
case FT_nearest_mipmap_nearest:
case FT_linear_mipmap_nearest:
case FT_nearest_mipmap_linear:
case FT_linear_mipmap_linear:
return true;
default:
return false;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::prepare_now
// Access: Published
@ -2315,127 +2203,6 @@ string_format(const string &str) {
return F_rgba;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::format_filter_type
// Access: Published, Static
// Description: Returns the indicated FilterType converted to a
// string word.
////////////////////////////////////////////////////////////////////
string Texture::
format_filter_type(FilterType ft) {
switch (ft) {
case FT_nearest:
return "nearest";
case FT_linear:
return "linear";
case FT_nearest_mipmap_nearest:
return "nearest_mipmap_nearest";
case FT_linear_mipmap_nearest:
return "linear_mipmap_nearest";
case FT_nearest_mipmap_linear:
return "nearest_mipmap_linear";
case FT_linear_mipmap_linear:
return "linear_mipmap_linear";
case FT_shadow:
return "shadow";
case FT_default:
return "default";
case FT_invalid:
return "invalid";
}
return "**invalid**";
}
////////////////////////////////////////////////////////////////////
// Function: Texture::string_filter_type
// Access: Public
// Description: Returns the FilterType value associated with the given
// string representation, or FT_invalid if the string
// does not match any known FilterType value.
////////////////////////////////////////////////////////////////////
Texture::FilterType Texture::
string_filter_type(const string &string) {
if (cmp_nocase_uh(string, "nearest") == 0) {
return FT_nearest;
} else if (cmp_nocase_uh(string, "linear") == 0) {
return FT_linear;
} else if (cmp_nocase_uh(string, "nearest_mipmap_nearest") == 0) {
return FT_nearest_mipmap_nearest;
} else if (cmp_nocase_uh(string, "linear_mipmap_nearest") == 0) {
return FT_linear_mipmap_nearest;
} else if (cmp_nocase_uh(string, "nearest_mipmap_linear") == 0) {
return FT_nearest_mipmap_linear;
} else if (cmp_nocase_uh(string, "linear_mipmap_linear") == 0) {
return FT_linear_mipmap_linear;
} else if (cmp_nocase_uh(string, "mipmap") == 0) {
return FT_linear_mipmap_linear;
} else if (cmp_nocase_uh(string, "shadow") == 0) {
return FT_shadow;
} else if (cmp_nocase_uh(string, "default") == 0) {
return FT_default;
} else {
return FT_invalid;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::format_wrap_mode
// Access: Published, Static
// Description: Returns the indicated WrapMode converted to a
// string word.
////////////////////////////////////////////////////////////////////
string Texture::
format_wrap_mode(WrapMode wm) {
switch (wm) {
case WM_clamp:
return "clamp";
case WM_repeat:
return "repeat";
case WM_mirror:
return "mirror";
case WM_mirror_once:
return "mirror_once";
case WM_border_color:
return "border_color";
case WM_invalid:
return "invalid";
}
return "**invalid**";
}
////////////////////////////////////////////////////////////////////
// Function: Texture::string_wrap_mode
// Access: Public
// Description: Returns the WrapMode value associated with the given
// string representation, or WM_invalid if the string
// does not match any known WrapMode value.
////////////////////////////////////////////////////////////////////
Texture::WrapMode Texture::
string_wrap_mode(const string &string) {
if (cmp_nocase_uh(string, "repeat") == 0 ||
cmp_nocase_uh(string, "wrap") == 0) {
return WM_repeat;
} else if (cmp_nocase_uh(string, "clamp") == 0) {
return WM_clamp;
} else if (cmp_nocase_uh(string, "mirror") == 0 ||
cmp_nocase_uh(string, "mirrored_repeat") == 0) {
return WM_mirror;
} else if (cmp_nocase_uh(string, "mirror_once") == 0) {
return WM_mirror_once;
} else if (cmp_nocase_uh(string, "border_color") == 0 ||
cmp_nocase_uh(string, "border") == 0) {
return WM_border_color;
} else {
return WM_invalid;
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::format_compression_mode
// Access: Published, Static
@ -3955,7 +3722,7 @@ do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only)
// mipmap levels to disk files.
////////////////////////////////////////////////////////////////////
bool Texture::
do_write(CData *cdata,
do_write(CData *cdata,
const Filename &fullpath, int z, int n, bool write_pages, bool write_mipmaps) {
if (is_txo_filename(fullpath)) {
if (!do_has_bam_rawdata(cdata)) {
@ -4273,20 +4040,20 @@ unlocked_ensure_ram_image(bool allow_compression) {
// We need to reload.
nassertr(!_reloading, NULL);
_reloading = true;
PT(Texture) tex = do_make_copy(cdata);
_cycler.release_read(cdata);
_lock.release();
// Perform the actual reload in a copy of the texture, while our
// own mutex is left unlocked.
CDWriter cdata_tex(tex->_cycler, true);
tex->do_reload_ram_image(cdata_tex, allow_compression);
_lock.acquire();
CData *cdataw = _cycler.write_upstream(false, current_thread);
// Rather than calling do_assign(), which would copy *all* of the
// reloaded texture's properties over, we only copy in the ones
// which are relevant to the ram image. This way, if the
@ -4295,7 +4062,7 @@ unlocked_ensure_ram_image(bool allow_compression) {
// texture.
cdataw->_orig_file_x_size = cdata_tex->_orig_file_x_size;
cdataw->_orig_file_y_size = cdata_tex->_orig_file_y_size;
// If any of *these* properties have changed, the texture has
// changed in some fundamental way. Update it appropriately.
if (cdata_tex->_x_size != cdataw->_x_size ||
@ -4306,33 +4073,33 @@ unlocked_ensure_ram_image(bool allow_compression) {
cdata_tex->_component_width != cdataw->_component_width ||
cdata_tex->_texture_type != cdataw->_texture_type ||
cdata_tex->_component_type != cdataw->_component_type) {
cdataw->_x_size = cdata_tex->_x_size;
cdataw->_y_size = cdata_tex->_y_size;
cdataw->_z_size = cdata_tex->_z_size;
cdataw->_num_views = cdata_tex->_num_views;
cdataw->_num_components = cdata_tex->_num_components;
cdataw->_component_width = cdata_tex->_component_width;
cdataw->_texture_type = cdata_tex->_texture_type;
cdataw->_format = cdata_tex->_format;
cdataw->_component_type = cdata_tex->_component_type;
cdataw->inc_properties_modified();
cdataw->inc_image_modified();
}
cdataw->_keep_ram_image = cdata_tex->_keep_ram_image;
cdataw->_ram_image_compression = cdata_tex->_ram_image_compression;
cdataw->_ram_images = cdata_tex->_ram_images;
nassertr(_reloading, NULL);
_reloading = false;
// We don't generally increment the cdata->_image_modified semaphore,
// because this is just a reload, and presumably the image hasn't
// changed (unless we hit the if condition above).
_cvar.notify_all();
// Return the still-locked cdata.
@ -4495,12 +4262,26 @@ do_modify_ram_image(CData *cdata) {
////////////////////////////////////////////////////////////////////
PTA_uchar Texture::
do_make_ram_image(CData *cdata) {
int image_size = do_get_expected_ram_image_size(cdata);
cdata->_ram_images.clear();
cdata->_ram_images.push_back(RamImage());
cdata->_ram_images[0]._page_size = do_get_expected_ram_page_size(cdata);
cdata->_ram_images[0]._image = PTA_uchar::empty_array(do_get_expected_ram_image_size(cdata), get_class_type());
cdata->_ram_images[0]._image = PTA_uchar::empty_array(image_size, get_class_type());
cdata->_ram_images[0]._pointer_image = NULL;
cdata->_ram_image_compression = CM_off;
if (cdata->_has_clear_color) {
// Fill the image with the clear color.
unsigned char pixel[16];
const int pixel_size = do_get_clear_data(cdata, pixel);
nassertr(pixel_size > 0, cdata->_ram_images[0]._image);
unsigned char *image_data = cdata->_ram_images[0]._image;
for (int i = 0; i < image_size; i += pixel_size) {
memcpy(image_data + i, pixel, pixel_size);
}
}
return cdata->_ram_images[0]._image;
}
@ -4568,9 +4349,23 @@ do_make_ram_mipmap_image(CData *cdata, int n) {
cdata->_ram_images.push_back(RamImage());
}
cdata->_ram_images[n]._image = PTA_uchar::empty_array(do_get_expected_ram_mipmap_image_size(cdata, n), get_class_type());
size_t image_size = do_get_expected_ram_mipmap_image_size(cdata, n);
cdata->_ram_images[n]._image = PTA_uchar::empty_array(image_size, get_class_type());
cdata->_ram_images[n]._pointer_image = NULL;
cdata->_ram_images[n]._page_size = do_get_expected_ram_mipmap_page_size(cdata, n);
if (cdata->_has_clear_color) {
// Fill the image with the clear color.
unsigned char pixel[16];
const int pixel_size = do_get_clear_data(cdata, pixel);
nassertr(pixel_size > 0, cdata->_ram_images[n]._image);
unsigned char *image_data = cdata->_ram_images[n]._image;
for (int i = 0; i < image_size; i += pixel_size) {
memcpy(image_data + i, pixel, pixel_size);
}
}
return cdata->_ram_images[n]._image;
}
@ -4599,6 +4394,116 @@ do_set_ram_mipmap_image(CData *cdata, int n, CPTA_uchar image, size_t page_size)
}
}
////////////////////////////////////////////////////////////////////
// Function: Texture::do_get_clear_color
// Access: Published
// Description: Returns a string with a single pixel representing
// the clear color of the texture in the format of
// this texture.
//
// In other words, to create an uncompressed RAM
// texture filled with the clear color, it should
// be initialized with this string repeated for
// every pixel.
////////////////////////////////////////////////////////////////////
int Texture::
do_get_clear_data(const CData *cdata, unsigned char *into) const {
nassertr(cdata->_has_clear_color, 0);
nassertr(cdata->_num_components <= 4, 0);
//TODO: encode the color into the sRGB color space if used
switch (cdata->_component_type) {
case T_unsigned_byte:
{
LColorf scaled = cdata->_clear_color.fmin(LColorf(1)).fmax(LColorf::zero());
scaled *= 255;
switch (cdata->_num_components) {
case 2:
into[1] = (unsigned char)scaled[1];
case 1:
into[0] = (unsigned char)scaled[0];
break;
case 4:
into[3] = (unsigned char)scaled[3];
case 3: // BGR <-> RGB
into[0] = (unsigned char)scaled[2];
into[1] = (unsigned char)scaled[1];
into[2] = (unsigned char)scaled[0];
break;
}
break;
}
case T_unsigned_short:
{
LColorf scaled = cdata->_clear_color.fmin(LColorf(1)).fmax(LColorf::zero());
scaled *= 65535;
switch (cdata->_num_components) {
case 2:
((unsigned short *)into)[1] = (unsigned short)scaled[1];
case 1:
((unsigned short *)into)[0] = (unsigned short)scaled[0];
break;
case 4:
((unsigned short *)into)[3] = (unsigned short)scaled[3];
case 3: // BGR <-> RGB
((unsigned short *)into)[0] = (unsigned short)scaled[2];
((unsigned short *)into)[1] = (unsigned short)scaled[1];
((unsigned short *)into)[2] = (unsigned short)scaled[0];
break;
}
break;
}
case T_float:
switch (cdata->_num_components) {
case 2:
((float *)into)[1] = cdata->_clear_color[1];
case 1:
((float *)into)[0] = cdata->_clear_color[0];
break;
case 4:
((float *)into)[3] = cdata->_clear_color[3];
case 3: // BGR <-> RGB
((float *)into)[0] = cdata->_clear_color[2];
((float *)into)[1] = cdata->_clear_color[1];
((float *)into)[2] = cdata->_clear_color[0];
break;
}
break;
case T_unsigned_int_24_8:
nassertr(cdata->_num_components == 1, 0);
*((unsigned int *)into) =
((unsigned int)(cdata->_clear_color[0] * 16777215) << 8) +
(unsigned int)max(min(cdata->_clear_color[1], (PN_stdfloat)255), (PN_stdfloat)0);
break;
case T_int:
{
// Note: there are no 32-bit UNORM textures. Therefore, we don't
// do any normalization here, either.
switch (cdata->_num_components) {
case 2:
((int *)into)[1] = (int)cdata->_clear_color[1];
case 1:
((int *)into)[0] = (int)cdata->_clear_color[0];
break;
case 4:
((int *)into)[3] = (int)cdata->_clear_color[3];
case 3: // BGR <-> RGB
((int *)into)[0] = (int)cdata->_clear_color[2];
((int *)into)[1] = (int)cdata->_clear_color[1];
((int *)into)[2] = (int)cdata->_clear_color[0];
break;
}
break;
}
}
return cdata->_num_components * cdata->_component_width;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::consider_auto_process_ram_image
// Access: Protected
@ -4626,7 +4531,7 @@ consider_auto_process_ram_image(bool generate_mipmaps, bool allow_compression) {
// operation, false if it wasn't.
////////////////////////////////////////////////////////////////////
bool Texture::
do_consider_auto_process_ram_image(CData *cdata, bool generate_mipmaps,
do_consider_auto_process_ram_image(CData *cdata, bool generate_mipmaps,
bool allow_compression) {
bool modified = false;
@ -5158,10 +5063,10 @@ do_setup_texture(CData *cdata, Texture::TextureType texture_type, int x_size, in
// In principle the wrap mode shouldn't mean anything to a cube
// map, but some drivers seem to misbehave if it's other than
// WM_clamp.
cdata->_wrap_u = WM_clamp;
cdata->_wrap_v = WM_clamp;
cdata->_wrap_w = WM_clamp;
// SamplerState::WM_clamp.
cdata->_default_sampler.set_wrap_u(SamplerState::WM_clamp);
cdata->_default_sampler.set_wrap_v(SamplerState::WM_clamp);
cdata->_default_sampler.set_wrap_w(SamplerState::WM_clamp);
break;
}
@ -5359,10 +5264,10 @@ do_set_num_views(CData *cdata, int num_views) {
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
do_set_wrap_u(CData *cdata, Texture::WrapMode wrap) {
if (cdata->_wrap_u != wrap) {
do_set_wrap_u(CData *cdata, SamplerState::WrapMode wrap) {
if (cdata->_default_sampler.get_wrap_u() != wrap) {
cdata->inc_properties_modified();
cdata->_wrap_u = wrap;
cdata->_default_sampler.set_wrap_u(wrap);
}
}
@ -5372,10 +5277,10 @@ do_set_wrap_u(CData *cdata, Texture::WrapMode wrap) {
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
do_set_wrap_v(CData *cdata, Texture::WrapMode wrap) {
if (cdata->_wrap_v != wrap) {
do_set_wrap_v(CData *cdata, SamplerState::WrapMode wrap) {
if (cdata->_default_sampler.get_wrap_v() != wrap) {
cdata->inc_properties_modified();
cdata->_wrap_v = wrap;
cdata->_default_sampler.set_wrap_v(wrap);
}
}
@ -5385,10 +5290,10 @@ do_set_wrap_v(CData *cdata, Texture::WrapMode wrap) {
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
do_set_wrap_w(CData *cdata, Texture::WrapMode wrap) {
if (cdata->_wrap_w != wrap) {
do_set_wrap_w(CData *cdata, SamplerState::WrapMode wrap) {
if (cdata->_default_sampler.get_wrap_w() != wrap) {
cdata->inc_properties_modified();
cdata->_wrap_w = wrap;
cdata->_default_sampler.set_wrap_w(wrap);
}
}
@ -5398,10 +5303,10 @@ do_set_wrap_w(CData *cdata, Texture::WrapMode wrap) {
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
do_set_minfilter(CData *cdata, Texture::FilterType filter) {
if (cdata->_minfilter != filter) {
do_set_minfilter(CData *cdata, SamplerState::FilterType filter) {
if (cdata->_default_sampler.get_minfilter() != filter) {
cdata->inc_properties_modified();
cdata->_minfilter = filter;
cdata->_default_sampler.set_minfilter(filter);
}
}
@ -5411,10 +5316,10 @@ do_set_minfilter(CData *cdata, Texture::FilterType filter) {
// Description:
////////////////////////////////////////////////////////////////////
void Texture::
do_set_magfilter(CData *cdata, Texture::FilterType filter) {
if (cdata->_magfilter != filter) {
do_set_magfilter(CData *cdata, SamplerState::FilterType filter) {
if (cdata->_default_sampler.get_magfilter() != filter) {
cdata->inc_properties_modified();
cdata->_magfilter = filter;
cdata->_default_sampler.set_magfilter(filter);
}
}
@ -5425,9 +5330,9 @@ do_set_magfilter(CData *cdata, Texture::FilterType filter) {
////////////////////////////////////////////////////////////////////
void Texture::
do_set_anisotropic_degree(CData *cdata, int anisotropic_degree) {
if (cdata->_anisotropic_degree != anisotropic_degree) {
if (cdata->_default_sampler.get_anisotropic_degree() != anisotropic_degree) {
cdata->inc_properties_modified();
cdata->_anisotropic_degree = anisotropic_degree;
cdata->_default_sampler.set_anisotropic_degree(anisotropic_degree);
}
}
@ -5438,9 +5343,9 @@ do_set_anisotropic_degree(CData *cdata, int anisotropic_degree) {
////////////////////////////////////////////////////////////////////
void Texture::
do_set_border_color(CData *cdata, const LColor &color) {
if (cdata->_border_color != color) {
if (cdata->_default_sampler.get_border_color() != color) {
cdata->inc_properties_modified();
cdata->_border_color = color;
cdata->_default_sampler.set_border_color(color);
}
}
@ -7870,7 +7775,7 @@ do_write_datagram_header(CData *cdata, BamWriter *manager, Datagram &me, bool &h
// loads the bam file later will have access to the image file on
// disk.
BamWriter::BamTextureMode file_texture_mode = manager->get_file_texture_mode();
has_rawdata = (file_texture_mode == BamWriter::BTM_rawdata ||
has_rawdata = (file_texture_mode == BamWriter::BTM_rawdata ||
(cdata->_filename.empty() && do_has_bam_rawdata(cdata)));
if (has_rawdata && !do_has_bam_rawdata(cdata)) {
do_get_bam_rawdata(cdata);
@ -7953,13 +7858,8 @@ do_write_datagram_header(CData *cdata, BamWriter *manager, Datagram &me, bool &h
////////////////////////////////////////////////////////////////////
void Texture::
do_write_datagram_body(CData *cdata, BamWriter *manager, Datagram &me) {
me.add_uint8(cdata->_wrap_u);
me.add_uint8(cdata->_wrap_v);
me.add_uint8(cdata->_wrap_w);
me.add_uint8(cdata->_minfilter);
me.add_uint8(cdata->_magfilter);
me.add_int16(cdata->_anisotropic_degree);
cdata->_border_color.write_datagram(me);
cdata->_default_sampler.write_datagram(me);
me.add_uint8(cdata->_compression);
me.add_uint8(cdata->_quality_level);
@ -8181,13 +8081,7 @@ make_this_from_bam(const FactoryParams &params) {
////////////////////////////////////////////////////////////////////
void Texture::
do_fillin_body(CData *cdata, DatagramIterator &scan, BamReader *manager) {
cdata->_wrap_u = (WrapMode)scan.get_uint8();
cdata->_wrap_v = (WrapMode)scan.get_uint8();
cdata->_wrap_w = (WrapMode)scan.get_uint8();
cdata->_minfilter = (FilterType)scan.get_uint8();
cdata->_magfilter = (FilterType)scan.get_uint8();
cdata->_anisotropic_degree = scan.get_int16();
cdata->_border_color.read_datagram(scan);
cdata->_default_sampler.read_datagram(scan, manager);
if (manager->get_file_minor_ver() >= 1) {
cdata->_compression = (CompressionMode)scan.get_uint8();
@ -8261,12 +8155,12 @@ do_fillin_rawdata(CData *cdata, DatagramIterator &scan, BamReader *manager) {
if (manager->get_file_minor_ver() >= 1) {
cdata->_ram_image_compression = (CompressionMode)scan.get_uint8();
}
int num_ram_images = 1;
if (manager->get_file_minor_ver() >= 3) {
num_ram_images = scan.get_uint8();
}
cdata->_ram_images.clear();
cdata->_ram_images.reserve(num_ram_images);
for (int n = 0; n < num_ram_images; ++n) {
@ -8275,9 +8169,9 @@ do_fillin_rawdata(CData *cdata, DatagramIterator &scan, BamReader *manager) {
if (manager->get_file_minor_ver() >= 1) {
cdata->_ram_images[n]._page_size = scan.get_uint32();
}
size_t u_size = scan.get_uint32();
// fill the cdata->_image buffer with image data
PTA_uchar image = PTA_uchar::empty_array(u_size, get_class_type());
for (size_t u_idx = 0; u_idx < u_size; ++u_idx) {
@ -8308,19 +8202,19 @@ do_fillin_from(CData *cdata, const Texture *dummy) {
CDReader cdata_dummy(dummy->_cycler);
do_set_wrap_u(cdata, cdata_dummy->_wrap_u);
do_set_wrap_v(cdata, cdata_dummy->_wrap_v);
do_set_wrap_w(cdata, cdata_dummy->_wrap_w);
do_set_border_color(cdata, cdata_dummy->_border_color);
do_set_wrap_u(cdata, cdata_dummy->_default_sampler.get_wrap_u());
do_set_wrap_v(cdata, cdata_dummy->_default_sampler.get_wrap_v());
do_set_wrap_w(cdata, cdata_dummy->_default_sampler.get_wrap_w());
do_set_border_color(cdata, cdata_dummy->_default_sampler.get_border_color());
if (cdata_dummy->_minfilter != FT_default) {
do_set_minfilter(cdata, cdata_dummy->_minfilter);
if (cdata_dummy->_default_sampler.get_minfilter() != SamplerState::FT_default) {
do_set_minfilter(cdata, cdata_dummy->_default_sampler.get_minfilter());
}
if (cdata_dummy->_magfilter != FT_default) {
do_set_magfilter(cdata, cdata_dummy->_magfilter);
if (cdata_dummy->_default_sampler.get_magfilter() != SamplerState::FT_default) {
do_set_magfilter(cdata, cdata_dummy->_default_sampler.get_magfilter());
}
if (cdata_dummy->_anisotropic_degree != 0) {
do_set_anisotropic_degree(cdata, cdata_dummy->_anisotropic_degree);
if (cdata_dummy->_default_sampler.get_anisotropic_degree() != 0) {
do_set_anisotropic_degree(cdata, cdata_dummy->_default_sampler.get_anisotropic_degree());
}
if (cdata_dummy->_compression != CM_default) {
do_set_compression(cdata, cdata_dummy->_compression);
@ -8345,7 +8239,7 @@ do_fillin_from(CData *cdata, const Texture *dummy) {
// recently than the one we already have.
if (cdata->_simple_ram_image._image.empty() ||
cdata_dummy->_simple_image_date_generated > cdata->_simple_image_date_generated) {
do_set_simple_ram_image(cdata,
do_set_simple_ram_image(cdata,
cdata_dummy->_simple_ram_image._image,
cdata_dummy->_simple_x_size,
cdata_dummy->_simple_y_size);
@ -8357,20 +8251,13 @@ do_fillin_from(CData *cdata, const Texture *dummy) {
////////////////////////////////////////////////////////////////////
// Function: Texture::CData::Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
Texture::CData::
CData() {
_primary_file_num_channels = 0;
_alpha_file_channel = 0;
_magfilter = FT_default;
_minfilter = FT_default;
_wrap_u = WM_repeat;
_wrap_v = WM_repeat;
_wrap_w = WM_repeat;
_anisotropic_degree = 0;
_keep_ram_image = true;
_border_color.set(0.0f, 0.0f, 0.0f, 1.0f);
_compression = CM_default;
_auto_texture_scale = ATS_unspecified;
_ram_image_compression = CM_off;
@ -8406,12 +8293,14 @@ CData() {
_simple_x_size = 0;
_simple_y_size = 0;
_simple_ram_image._page_size = 0;
_has_clear_color = false;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::CData::Copy Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
Texture::CData::
CData(const Texture::CData &copy) {
@ -8437,7 +8326,7 @@ make_copy() const {
////////////////////////////////////////////////////////////////////
// Function: Texture::CData::do_assign
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void Texture::CData::
do_assign(const Texture::CData *copy) {
@ -8470,14 +8359,8 @@ do_assign(const Texture::CData *copy) {
_has_read_pages = copy->_has_read_pages;
_has_read_mipmaps = copy->_has_read_mipmaps;
_num_mipmap_levels_read = copy->_num_mipmap_levels_read;
_wrap_u = copy->_wrap_u;
_wrap_v = copy->_wrap_v;
_wrap_w = copy->_wrap_w;
_minfilter = copy->_minfilter;
_magfilter = copy->_magfilter;
_anisotropic_degree = copy->_anisotropic_degree;
_default_sampler = copy->_default_sampler;
_keep_ram_image = copy->_keep_ram_image;
_border_color = copy->_border_color;
_compression = copy->_compression;
_match_framebuffer_format = copy->_match_framebuffer_format;
_quality_level = copy->_quality_level;
@ -8549,50 +8432,6 @@ operator << (ostream &out, Texture::Format f) {
return out << Texture::format_format(f);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::FilterType output operator
// Description:
////////////////////////////////////////////////////////////////////
ostream &
operator << (ostream &out, Texture::FilterType ft) {
return out << Texture::format_filter_type(ft);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::FilterType input operator
// Description:
////////////////////////////////////////////////////////////////////
istream &
operator >> (istream &in, Texture::FilterType &ft) {
string word;
in >> word;
ft = Texture::string_filter_type(word);
return in;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::WrapMode output operator
// Description:
////////////////////////////////////////////////////////////////////
ostream &
operator << (ostream &out, Texture::WrapMode wm) {
return out << Texture::format_wrap_mode(wm);
}
////////////////////////////////////////////////////////////////////
// Function: Texture::WrapMode input operator
// Description:
////////////////////////////////////////////////////////////////////
istream &
operator >> (istream &in, Texture::WrapMode &wm) {
string word;
in >> word;
wm = Texture::string_wrap_mode(word);
return in;
}
////////////////////////////////////////////////////////////////////
// Function: Texture::CompressionMode output operator
// Description:

View File

@ -39,6 +39,7 @@
#include "cycleDataStageReader.h"
#include "cycleDataStageWriter.h"
#include "pipelineCycler.h"
#include "samplerState.h"
class PNMImage;
class PfmFile;
@ -145,52 +146,37 @@ PUBLISHED:
F_r32,
F_rg32,
F_rgb32,
F_r8i, // 8 integer bits per R channel
F_rg8i, // 8 integer bits per R,G channel
F_rgb8i, // 8 integer bits per R,G,B channel
F_rgba8i, // 8 integer bits per R,G,B,A channel
};
enum FilterType {
// Mag Filter and Min Filter
// Point sample the pixel
FT_nearest,
// Bilinear filtering of four neighboring pixels
FT_linear,
// Min Filter Only
// Point sample the pixel from the nearest mipmap level
FT_nearest_mipmap_nearest,
// Bilinear filter the pixel from the nearest mipmap level
FT_linear_mipmap_nearest,
// Point sample the pixel from two mipmap levels, and linearly blend
FT_nearest_mipmap_linear,
// A.k.a. trilinear filtering: Bilinear filter the pixel from
// two mipmap levels, and linearly blend the results.
FT_linear_mipmap_linear,
// The OpenGL ARB_shadow extension can be thought of as a kind of filtering.
FT_shadow,
// Default is usually linear, but it depends on format.
// This was added at the end of the list to avoid bumping TXO version #.
FT_default,
// Returned by string_filter_type() for an invalid match.
FT_invalid
// Deprecated. See SamplerState.FilterType.
enum DeprecatedFilterType {
FT_nearest = SamplerState::FT_nearest,
FT_linear = SamplerState::FT_linear,
FT_nearest_mipmap_nearest = SamplerState::FT_nearest_mipmap_nearest,
FT_linear_mipmap_nearest = SamplerState::FT_linear_mipmap_nearest,
FT_nearest_mipmap_linear = SamplerState::FT_nearest_mipmap_linear,
FT_linear_mipmap_linear = SamplerState::FT_linear_mipmap_linear,
FT_shadow = SamplerState::FT_shadow,
FT_default = SamplerState::FT_default,
FT_invalid = SamplerState::FT_invalid
};
typedef SamplerState::FilterType FilterType;
enum WrapMode {
WM_clamp, // coords that would be outside [0-1] are clamped to 0 or 1
WM_repeat,
WM_mirror,
WM_mirror_once, // mirror once, then clamp
WM_border_color, // coords outside [0-1] use explict border color
// Returned by string_wrap_mode() for an invalid match.
WM_invalid
// Deprecated. See SamplerState.WrapMode.
enum DeprecatedWrapMode {
WM_clamp = SamplerState::WM_clamp,
WM_repeat = SamplerState::WM_repeat,
WM_mirror = SamplerState::WM_mirror,
WM_mirror_once = SamplerState::WM_mirror_once,
WM_border_color = SamplerState::WM_border_color,
WM_invalid = SamplerState::WM_invalid
};
typedef SamplerState::WrapMode WrapMode;
enum CompressionMode {
// Generic compression modes. Usually, you should choose one of
@ -253,11 +239,17 @@ PUBLISHED:
void generate_normalization_cube_map(int size);
void generate_alpha_scale_map();
INLINE void clear_image();
INLINE bool has_clear_color() const;
INLINE LColor get_clear_color() const;
INLINE void set_clear_color(const LColor &color);
INLINE string get_clear_data() const;
BLOCKING bool read(const Filename &fullpath, const LoaderOptions &options = LoaderOptions());
BLOCKING bool read(const Filename &fullpath, const Filename &alpha_fullpath,
int primary_file_num_channels, int alpha_file_channel,
const LoaderOptions &options = LoaderOptions());
BLOCKING bool read(const Filename &fullpath, int z, int n,
BLOCKING bool read(const Filename &fullpath, int z, int n,
bool read_pages, bool read_mipmaps,
const LoaderOptions &options = LoaderOptions());
BLOCKING bool read(const Filename &fullpath, const Filename &alpha_fullpath,
@ -267,7 +259,7 @@ PUBLISHED:
const LoaderOptions &options = LoaderOptions());
BLOCKING INLINE bool write(const Filename &fullpath);
BLOCKING INLINE bool write(const Filename &fullpath, int z, int n,
BLOCKING INLINE bool write(const Filename &fullpath, int z, int n,
bool write_pages, bool write_mipmaps);
BLOCKING bool read_txo(istream &in, const string &filename = "");
@ -319,13 +311,14 @@ PUBLISHED:
INLINE void set_compression(CompressionMode compression);
INLINE void set_render_to_texture(bool render_to_texture);
INLINE WrapMode get_wrap_u() const;
INLINE WrapMode get_wrap_v() const;
INLINE WrapMode get_wrap_w() const;
INLINE FilterType get_minfilter() const;
INLINE FilterType get_magfilter() const;
FilterType get_effective_minfilter() const;
FilterType get_effective_magfilter() const;
INLINE const SamplerState &get_default_sampler() const;
INLINE SamplerState::WrapMode get_wrap_u() const;
INLINE SamplerState::WrapMode get_wrap_v() const;
INLINE SamplerState::WrapMode get_wrap_w() const;
INLINE SamplerState::FilterType get_minfilter() const;
INLINE SamplerState::FilterType get_magfilter() const;
INLINE SamplerState::FilterType get_effective_minfilter() const;
INLINE SamplerState::FilterType get_effective_magfilter() const;
INLINE int get_anisotropic_degree() const;
INLINE int get_effective_anisotropic_degree() const;
INLINE LColor get_border_color() const;
@ -458,7 +451,7 @@ PUBLISHED:
INLINE int get_pad_y_size() const;
INLINE int get_pad_z_size() const;
INLINE LVecBase2 get_tex_scale() const;
INLINE void set_pad_size(int x=0, int y=0, int z=0);
void set_size_padded(int x=1, int y=1, int z=1);
@ -467,7 +460,7 @@ PUBLISHED:
INLINE int get_orig_file_z_size() const;
void set_orig_file_size(int x, int y, int z = 1);
INLINE void set_format(Format format);
INLINE void set_component_type(ComponentType component_type);
INLINE void set_loaded_from_image();
@ -476,8 +469,6 @@ PUBLISHED:
INLINE void set_loaded_from_txo();
INLINE bool get_loaded_from_txo() const;
static bool is_mipmap(FilterType type);
INLINE bool get_match_framebuffer_format() const;
INLINE void set_match_framebuffer_format(bool flag);
@ -503,22 +494,16 @@ PUBLISHED:
static string format_format(Format f);
static Format string_format(const string &str);
static string format_filter_type(FilterType ft);
static FilterType string_filter_type(const string &str);
static string format_wrap_mode(WrapMode wm);
static WrapMode string_wrap_mode(const string &str);
static string format_compression_mode(CompressionMode cm);
static CompressionMode string_compression_mode(const string &str);
static string format_quality_level(QualityLevel tql);
static QualityLevel string_quality_level(const string &str);
public:
void texture_uploaded();
virtual bool has_cull_callback() const;
virtual bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
@ -550,8 +535,8 @@ protected:
// CData pointer representing that lock); generally, they also avoid
// adjusting the _properties_modified and _image_modified
// semaphores.
virtual bool do_adjust_this_size(const CData *cdata,
int &x_size, int &y_size, const string &name,
virtual bool do_adjust_this_size(const CData *cdata,
int &x_size, int &y_size, const string &name,
bool for_padding) const;
virtual bool do_read(CData *cdata,
@ -577,7 +562,7 @@ protected:
bool do_read_dds_file(CData *cdata, const Filename &fullpath, bool header_only);
bool do_read_dds(CData *cdata, istream &in, const string &filename, bool header_only);
bool do_write(CData *cdata, const Filename &fullpath, int z, int n,
bool do_write(CData *cdata, const Filename &fullpath, int z, int n,
bool write_pages, bool write_mipmaps);
bool do_write_one(CData *cdata, const Filename &fullpath, int z, int n);
bool do_store_one(CData *cdata, PNMImage &pnmimage, int z, int n);
@ -590,14 +575,15 @@ protected:
PTA_uchar do_modify_ram_image(CData *cdata);
PTA_uchar do_make_ram_image(CData *cdata);
void do_set_ram_image(CData *cdata, CPTA_uchar image,
void do_set_ram_image(CData *cdata, CPTA_uchar image,
CompressionMode compression = CM_off, size_t page_size = 0);
PTA_uchar do_modify_ram_mipmap_image(CData *cdata, int n);
PTA_uchar do_make_ram_mipmap_image(CData *cdata, int n);
void do_set_ram_mipmap_image(CData *cdata, int n, CPTA_uchar image, size_t page_size);
int do_get_clear_data(const CData *cdata, unsigned char *into) const;
bool consider_auto_process_ram_image(bool generate_mipmaps, bool allow_compression);
bool do_consider_auto_process_ram_image(CData *cdata, bool generate_mipmaps,
bool do_consider_auto_process_ram_image(CData *cdata, bool generate_mipmaps,
bool allow_compression);
bool do_compress_ram_image(CData *cdata, CompressionMode compression,
QualityLevel quality_level,
@ -607,7 +593,7 @@ protected:
bool do_reconsider_z_size(CData *cdata, int z, const LoaderOptions &options);
virtual void do_allocate_pages(CData *cdata);
bool do_reconsider_image_properties(CData *cdata,
bool do_reconsider_image_properties(CData *cdata,
int x_size, int y_size, int num_components,
ComponentType component_type, int z,
const LoaderOptions &options);
@ -617,7 +603,7 @@ protected:
PT(Texture) do_make_copy(const CData *cdata) const;
void do_assign(CData *cdata, const Texture *copy, const CData *cdata_copy);
virtual void do_clear(CData *cdata);
void do_setup_texture(CData *cdata,
void do_setup_texture(CData *cdata,
TextureType texture_type, int x_size, int y_size,
int z_size, ComponentType component_type,
Format format);
@ -700,28 +686,28 @@ private:
int num_components, int component_width,
CPTA_uchar image, size_t page_size,
int z);
static PTA_uchar read_dds_level_bgr8(Texture *tex, CData *cdata, const DDSHeader &header,
static PTA_uchar read_dds_level_bgr8(Texture *tex, CData *cdata, const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_rgb8(Texture *tex, CData *cdata, const DDSHeader &header,
static PTA_uchar read_dds_level_rgb8(Texture *tex, CData *cdata, const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_abgr8(Texture *tex, CData *cdata, const DDSHeader &header,
static PTA_uchar read_dds_level_abgr8(Texture *tex, CData *cdata, const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_rgba8(Texture *tex, CData *cdata, const DDSHeader &header,
static PTA_uchar read_dds_level_rgba8(Texture *tex, CData *cdata, const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_generic_uncompressed(Texture *tex, CData *cdata,
const DDSHeader &header,
static PTA_uchar read_dds_level_generic_uncompressed(Texture *tex, CData *cdata,
const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_luminance_uncompressed(Texture *tex, CData *cdata,
const DDSHeader &header,
static PTA_uchar read_dds_level_luminance_uncompressed(Texture *tex, CData *cdata,
const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_dxt1(Texture *tex, CData *cdata,
const DDSHeader &header,
static PTA_uchar read_dds_level_dxt1(Texture *tex, CData *cdata,
const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_dxt23(Texture *tex, CData *cdata,
const DDSHeader &header,
static PTA_uchar read_dds_level_dxt23(Texture *tex, CData *cdata,
const DDSHeader &header,
int n, istream &in);
static PTA_uchar read_dds_level_dxt45(Texture *tex, CData *cdata,
const DDSHeader &header,
static PTA_uchar read_dds_level_dxt45(Texture *tex, CData *cdata,
const DDSHeader &header,
int n, istream &in);
void clear_prepared(int view, PreparedGraphicsObjects *prepared_objects);
@ -748,36 +734,36 @@ private:
RamImage &to, const RamImage &from,
int x_size, int y_size, int z_size) const;
typedef void Filter2DComponent(unsigned char *&p,
typedef void Filter2DComponent(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size);
typedef void Filter3DComponent(unsigned char *&p,
typedef void Filter3DComponent(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size,
size_t page_size);
static void filter_2d_unsigned_byte(unsigned char *&p,
static void filter_2d_unsigned_byte(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size);
static void filter_2d_unsigned_byte_srgb(unsigned char *&p,
static void filter_2d_unsigned_byte_srgb(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size);
static void filter_2d_unsigned_short(unsigned char *&p,
static void filter_2d_unsigned_short(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size);
static void filter_2d_float(unsigned char *&p, const unsigned char *&q,
size_t pixel_size, size_t row_size);
static void filter_3d_unsigned_byte(unsigned char *&p,
static void filter_3d_unsigned_byte(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size,
size_t page_size);
static void filter_3d_unsigned_byte_srgb(unsigned char *&p,
static void filter_3d_unsigned_byte_srgb(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size,
size_t page_size);
static void filter_3d_unsigned_short(unsigned char *&p,
static void filter_3d_unsigned_short(unsigned char *&p,
const unsigned char *&q,
size_t pixel_size, size_t row_size,
size_t page_size);
@ -813,16 +799,16 @@ protected:
Filename _alpha_filename;
Filename _fullpath;
Filename _alpha_fullpath;
// The number of channels of the primary file we use. 1, 2, 3, or 4.
int _primary_file_num_channels;
// If we have a separate alpha file, this designates which channel
// in the alpha file provides the alpha channel. 0 indicates the
// combined grayscale value of rgb; otherwise, 1, 2, 3, or 4 are
// valid.
int _alpha_file_channel;
int _x_size;
int _y_size;
int _z_size;
@ -832,19 +818,14 @@ protected:
TextureType _texture_type;
Format _format;
ComponentType _component_type;
bool _loaded_from_image;
bool _loaded_from_txo;
bool _has_read_pages;
bool _has_read_mipmaps;
int _num_mipmap_levels_read;
WrapMode _wrap_u;
WrapMode _wrap_v;
WrapMode _wrap_w;
FilterType _minfilter;
FilterType _magfilter;
int _anisotropic_degree;
SamplerState _default_sampler;
bool _keep_ram_image;
LColor _border_color;
CompressionMode _compression;
@ -852,14 +833,14 @@ protected:
bool _match_framebuffer_format;
bool _post_load_store_cache;
QualityLevel _quality_level;
int _pad_x_size;
int _pad_y_size;
int _pad_z_size;
int _orig_file_x_size;
int _orig_file_y_size;
AutoTextureScale _auto_texture_scale;
CompressionMode _ram_image_compression;
@ -874,11 +855,15 @@ protected:
int _simple_x_size;
int _simple_y_size;
PN_int32 _simple_image_date_generated;
// This is the color that should be used when no image was given.
bool _has_clear_color;
LColor _clear_color;
UpdateSeq _properties_modified;
UpdateSeq _image_modified;
UpdateSeq _simple_image_modified;
public:
static TypeHandle get_class_type() {
return _type_handle;
@ -886,11 +871,11 @@ protected:
static void init_type() {
register_type(_type_handle, "Texture::CData");
}
private:
static TypeHandle _type_handle;
};
PipelineCycler<CData> _cycler;
typedef CycleDataLockedReader<CData> CDLockedReader;
typedef CycleDataReader<CData> CDReader;
@ -904,7 +889,7 @@ protected:
// Used to implement unlocked_reload_ram_image().
ConditionVarFull _cvar; // condition: _reloading is true.
bool _reloading;
// A Texture keeps a list (actually, a map) of all the
// PreparedGraphicsObjects tables that it has been prepared into.
// Each PGO conversely keeps a list (a set) of all the Textures that
@ -913,7 +898,7 @@ protected:
typedef pmap<int, TextureContext *> Contexts;
typedef pmap<PreparedGraphicsObjects *, Contexts> PreparedViews;
PreparedViews _prepared_views;
// It is common, when using normal maps, specular maps, gloss maps,
// and such, to use a file naming convention where the filenames
// of the special maps are derived by concatenating a suffix to
@ -924,7 +909,7 @@ protected:
// The TexturePool finds this useful.
Filename _texture_pool_key;
private:
// The auxiliary data is not recorded to a bam file.
typedef pmap<string, PT(TypedReferenceCount) > AuxData;
@ -976,20 +961,11 @@ private:
};
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<Texture::QualityLevel> texture_quality_level;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<Texture::FilterType> texture_minfilter;
extern EXPCL_PANDA_GOBJ ConfigVariableEnum<Texture::FilterType> texture_magfilter;
extern EXPCL_PANDA_GOBJ ConfigVariableInt texture_anisotropic_degree;
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::TextureType tt);
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::ComponentType ct);
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::Format f);
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::FilterType ft);
EXPCL_PANDA_GOBJ istream &operator >> (istream &in, Texture::FilterType &ft);
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::WrapMode wm);
EXPCL_PANDA_GOBJ istream &operator >> (istream &in, Texture::WrapMode &wm);
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::CompressionMode cm);
EXPCL_PANDA_GOBJ ostream &operator << (ostream &out, Texture::QualityLevel tql);
EXPCL_PANDA_GOBJ istream &operator >> (istream &in, Texture::QualityLevel &tql);
@ -997,4 +973,3 @@ EXPCL_PANDA_GOBJ istream &operator >> (istream &in, Texture::QualityLevel &tql);
#include "texture.I"
#endif

View File

@ -19,7 +19,7 @@ TypeHandle TextureContext::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: TextureContext::output
// Access: Public, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void TextureContext::
output(ostream &out) const {
@ -29,7 +29,7 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
// Function: TextureContext::write
// Access: Published, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void TextureContext::
write(ostream &out, int indent_level) const {

View File

@ -246,8 +246,8 @@ flatten(GraphicsOutput *window) {
Texture *model_tex = model_stage._tex;
int aniso_degree = model_tex->get_anisotropic_degree();
Texture::FilterType minfilter = model_tex->get_minfilter();
Texture::FilterType magfilter = model_tex->get_magfilter();
SamplerState::FilterType minfilter = model_tex->get_minfilter();
SamplerState::FilterType magfilter = model_tex->get_magfilter();
// What is the UV range of the model stage?
LTexCoord min_uv, max_uv;

View File

@ -54,8 +54,10 @@ class PreparedGraphicsObjects;
class GraphicsOutput;
class Texture;
class TextureContext;
class ShaderContext;
class SamplerContext;
class SamplerState;
class Shader;
class ShaderContext;
class RenderState;
class TransformState;
class Material;
@ -148,6 +150,9 @@ public:
virtual void release_texture(TextureContext *tc)=0;
virtual bool extract_texture_data(Texture *tex)=0;
virtual SamplerContext *prepare_sampler(const SamplerState &sampler)=0;
virtual void release_sampler(SamplerContext *sc)=0;
virtual GeomContext *prepare_geom(Geom *geom)=0;
virtual void release_geom(GeomContext *gc)=0;

View File

@ -998,11 +998,9 @@ INLINE_LINMATH void FLOATNAME(LMatrix3)::
transpose_in_place() {
TAU_PROFILE("void LMatrix3::transpose_in_place()", " ", TAU_USER);
#define SWAP__(x,y) { FLOATTYPE temp = (x); (x) = (y); (y) = temp;}
SWAP__(_m(0, 1),_m(1, 0));
SWAP__(_m(0, 2),_m(2, 0));
SWAP__(_m(1, 2),_m(2, 1));
#undef SWAP__
std::swap(_m(0, 1), _m(1, 0));
std::swap(_m(0, 2), _m(2, 0));
std::swap(_m(1, 2), _m(2, 1));
}
// Matrix inversion code from Numerical Recipes in C.
@ -1050,12 +1048,16 @@ INLINE_LINMATH bool FLOATNAME(LMatrix3)::
invert_from(const FLOATNAME(LMatrix3) &other) {
TAU_PROFILE("bool LMatrix3::invert_from(const LMatrix3 &)", " ", TAU_USER);
// We throw the value out only if it's smaller than our "small"
// threshold squared. This helps reduce overly-sensitive
// rejections.
#ifdef HAVE_EIGEN
bool invertible;
other._m.computeInverseWithCheck(_m, invertible);
other._m.computeInverseWithCheck(_m, invertible,
NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE));
if (!invertible) {
#ifdef NDEBUG
#ifdef NOTIFY_DEBUG
linmath_cat.warning() << "Tried to invert singular LMatrix3.\n";
#endif
(*this) = ident_mat();
@ -1068,11 +1070,7 @@ invert_from(const FLOATNAME(LMatrix3) &other) {
FLOATTYPE other_det = MATRIX3_DETERMINANT(other._m);
// We throw the value out only if it's smaller than our "small"
// threshold squared. This helps reduce overly-sensitive
// rejections.
if (IS_THRESHOLD_ZERO(other_det, (NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE)))) {
// if (IS_NEARLY_ZERO(other_det)) {
#ifdef NOTIFY_DEBUG
linmath_cat.warning() << "Tried to invert singular LMatrix3.\n";
#endif
@ -1125,10 +1123,11 @@ invert_transpose_from(const FLOATNAME(LMatrix3) &other) {
#ifdef HAVE_EIGEN
bool invertible;
EMatrix3 temp;
other._m.computeInverseWithCheck(temp, invertible);
other._m.computeInverseWithCheck(temp, invertible,
NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE));
if (!invertible) {
#ifdef NDEBUG
#ifdef NOTIFY_DEBUG
linmath_cat.warning() << "Tried to invert singular LMatrix3.\n";
#endif
(*this) = ident_mat();
@ -1139,6 +1138,7 @@ invert_transpose_from(const FLOATNAME(LMatrix3) &other) {
return true;
#else // HAVE_EIGEN
FLOATTYPE other_det = MATRIX3_DETERMINANT(other._m);
if (IS_THRESHOLD_ZERO(other_det, (NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE)))) {
@ -1180,10 +1180,11 @@ invert_transpose_from(const FLOATNAME(LMatrix4) &other) {
#ifdef HAVE_EIGEN
bool invertible;
EMatrix3 temp;
other._m.block<3, 3>(0, 0).computeInverseWithCheck(temp, invertible);
other._m.block<3, 3>(0, 0).computeInverseWithCheck(temp, invertible,
NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE));
if (!invertible) {
#ifdef NDEBUG
#ifdef NOTIFY_DEBUG
linmath_cat.warning() << "Tried to invert singular LMatrix3.\n";
#endif
(*this) = ident_mat();

View File

@ -831,7 +831,7 @@ xform(const FLOATNAME(LVecBase4) &v) const {
#ifdef HAVE_EIGEN
v_res._v.noalias() = v._v * _m;
#else
#else
VECTOR4_MATRIX4_PRODUCT(v_res, v,(*this));
#endif // HAVE_EIGEN
return v_res;
@ -853,12 +853,12 @@ xform_point(const FLOATNAME(LVecBase3) &v) const {
#ifdef HAVE_EIGEN
v_res._v.noalias() = v._v * _m.block<3, 3>(0, 0) + _m.block<1, 3>(3, 0);
#else
#else
v_res._v(0) = v._v(0)*_m(0, 0) + v._v(1)*_m(1, 0) + v._v(2)*_m(2, 0) + _m(3, 0);
v_res._v(1) = v._v(0)*_m(0, 1) + v._v(1)*_m(1, 1) + v._v(2)*_m(2, 1) + _m(3, 1);
v_res._v(2) = v._v(0)*_m(0, 2) + v._v(1)*_m(1, 2) + v._v(2)*_m(2, 2) + _m(3, 2);
#endif // HAVE_EIGEN
return v_res;
}
@ -888,17 +888,17 @@ INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LMatrix4)::
xform_vec(const FLOATNAME(LVecBase3) &v) const {
TAU_PROFILE("LVecBase3 LMatrix4::xform_vec(const LVecBase3 &)", " ", TAU_USER);
FLOATNAME(LVecBase3) v_res;
// v._v(3) == 0.0f for this case
#ifdef HAVE_EIGEN
v_res._v.noalias() = v._v * _m.block<3, 3>(0, 0);
#else
#else
v_res._v(0) = v._v(0)*_m(0, 0) + v._v(1)*_m(1, 0) + v._v(2)*_m(2, 0);
v_res._v(1) = v._v(0)*_m(0, 1) + v._v(1)*_m(1, 1) + v._v(2)*_m(2, 1);
v_res._v(2) = v._v(0)*_m(0, 2) + v._v(1)*_m(1, 2) + v._v(2)*_m(2, 2);
#endif // HAVE_EIGEN
return v_res;
}
@ -934,7 +934,7 @@ xform_in_place(FLOATNAME(LVecBase4) &v) const {
#ifdef HAVE_EIGEN
v._v = v._v * _m;
#else
#else
v = xform(v);
#endif // HAVE_EIGEN
}
@ -953,7 +953,7 @@ xform_point_in_place(FLOATNAME(LVecBase3) &v) const {
#ifdef HAVE_EIGEN
v._v = v._v * _m.block<3, 3>(0, 0) + _m.block<1, 3>(3, 0);
#else
#else
v = xform_point(v);
#endif // HAVE_EIGEN
}
@ -981,10 +981,10 @@ INLINE_LINMATH void FLOATNAME(LMatrix4)::
xform_vec_in_place(FLOATNAME(LVecBase3) &v) const {
TAU_PROFILE("void LMatrix4::xform_vec_in_place(LVecBase3 &)", " ", TAU_USER);
// v._v(3) == 0.0f for this case
#ifdef HAVE_EIGEN
v._v = v._v * _m.block<3, 3>(0, 0);
#else
#else
v = xform_vec(v);
#endif // HAVE_EIGEN
}
@ -1325,14 +1325,12 @@ transpose_in_place() {
_m.transposeInPlace();
#else
#define SWAP__(x,y) { FLOATTYPE temp = (x); (x) = (y); (y) = temp;}
SWAP__(_m(0, 1),_m(1, 0));
SWAP__(_m(0, 2),_m(2, 0));
SWAP__(_m(0, 3),_m(3, 0));
SWAP__(_m(1, 2),_m(2, 1));
SWAP__(_m(1, 3),_m(3, 1));
SWAP__(_m(2, 3),_m(3, 2));
#undef SWAP__
std::swap(_m(0, 1), _m(1, 0));
std::swap(_m(0, 2), _m(2, 0));
std::swap(_m(0, 3), _m(3, 0));
std::swap(_m(1, 2), _m(2, 1));
std::swap(_m(1, 3), _m(3, 1));
std::swap(_m(2, 3), _m(3, 2));
#endif // HAVE_EIGEN
}
@ -1356,13 +1354,19 @@ INLINE_LINMATH bool FLOATNAME(LMatrix4)::
invert_from(const FLOATNAME(LMatrix4) &other) {
TAU_PROFILE("bool LMatrix4::invert_from(const LMatrix4 &)", " ", TAU_USER);
#ifdef HAVE_EIGEN
// We use the squared nearly_zero value as determinant threshold
// for checking whether a matrix is singular, since that's the
// same constant we use in the non-Eigen case (see lmatrix3_src.I)
// and also because we otherwise run into issues very quickly.
bool invertible;
other._m.computeInverseWithCheck(_m, invertible);
other._m.computeInverseWithCheck(_m, invertible,
NEARLY_ZERO(FLOATTYPE) * NEARLY_ZERO(FLOATTYPE));
if (!invertible) {
#ifdef NDEBUG
#ifdef NOTIFY_DEBUG
linmath_cat.warning() << "Tried to invert singular LMatrix4.\n";
#endif
(*this) = ident_mat();
nassertr(!no_singular_invert, false);
}
@ -1382,9 +1386,10 @@ invert_from(const FLOATNAME(LMatrix4) &other) {
int index[4];
if (!decompose_mat(index)) {
#ifdef NDEBUG
#ifdef NOTIFY_DEBUG
linmath_cat.warning() << "Tried to invert singular LMatrix4.\n";
#endif
(*this) = ident_mat();
nassertr(!no_singular_invert, false);
return false;
@ -1441,11 +1446,11 @@ invert_affine_from(const FLOATNAME(LMatrix4) &other) {
_m(3, 0) = -(other._m(3, 0) * _m(0, 0) +
other._m(3, 1) * _m(1, 0) +
other._m(3, 2) * _m(2, 0));
_m(3, 1) = -(other._m(3, 0) * _m(0, 1) +
other._m(3, 1) * _m(1, 1) +
other._m(3, 2) * _m(2, 1));
_m(3, 2) = -(other._m(3, 0) * _m(0, 2) +
other._m(3, 1) * _m(1, 2) +
other._m(3, 2) * _m(2, 2));
@ -1481,17 +1486,17 @@ accumulate(const FLOATNAME(LMatrix4) &other, FLOATTYPE weight) {
_m(0, 1) += other._m(0, 1) * weight;
_m(0, 2) += other._m(0, 2) * weight;
_m(0, 3) += other._m(0, 3) * weight;
_m(1, 0) += other._m(1, 0) * weight;
_m(1, 1) += other._m(1, 1) * weight;
_m(1, 2) += other._m(1, 2) * weight;
_m(1, 3) += other._m(1, 3) * weight;
_m(2, 0) += other._m(2, 0) * weight;
_m(2, 1) += other._m(2, 1) * weight;
_m(2, 2) += other._m(2, 2) * weight;
_m(2, 3) += other._m(2, 3) * weight;
_m(3, 0) += other._m(3, 0) * weight;
_m(3, 1) += other._m(3, 1) * weight;
_m(3, 2) += other._m(3, 2) * weight;

View File

@ -754,7 +754,7 @@ componentwise_mult(const FLOATNAME(LVecBase2) &other) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
fmax(const FLOATNAME(LVecBase2) &other) {
fmax(const FLOATNAME(LVecBase2) &other) const {
TAU_PROFILE("LVecBase2::fmax()", " ", TAU_USER);
return FLOATNAME(LVecBase2)(_v(0) > other._v(0) ? _v(0) : other._v(0),
_v(1) > other._v(1) ? _v(1) : other._v(1));
@ -766,7 +766,7 @@ fmax(const FLOATNAME(LVecBase2) &other) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase2) FLOATNAME(LVecBase2)::
fmin(const FLOATNAME(LVecBase2) &other) {
fmin(const FLOATNAME(LVecBase2) &other) const {
TAU_PROFILE("LVecBase2::fmin()", " ", TAU_USER);
return FLOATNAME(LVecBase2)(_v(0) < other._v(0) ? _v(0) : other._v(0),
_v(1) < other._v(1) ? _v(1) : other._v(1));

View File

@ -126,8 +126,8 @@ PUBLISHED:
EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase2) __pow__(FLOATTYPE exponent) const);
EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent));
INLINE_LINMATH FLOATNAME(LVecBase2) fmax(const FLOATNAME(LVecBase2) &other);
INLINE_LINMATH FLOATNAME(LVecBase2) fmin(const FLOATNAME(LVecBase2) &other);
INLINE_LINMATH FLOATNAME(LVecBase2) fmax(const FLOATNAME(LVecBase2) &other) const;
INLINE_LINMATH FLOATNAME(LVecBase2) fmin(const FLOATNAME(LVecBase2) &other) const;
INLINE_LINMATH bool almost_equal(const FLOATNAME(LVecBase2) &other,
FLOATTYPE threshold) const;

View File

@ -931,7 +931,7 @@ componentwise_mult(const FLOATNAME(LVecBase3) &other) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
fmax(const FLOATNAME(LVecBase3) &other) {
fmax(const FLOATNAME(LVecBase3) &other) const {
TAU_PROFILE("LVecBase3::fmax()", " ", TAU_USER);
return FLOATNAME(LVecBase3)(_v(0) > other._v(0) ? _v(0) : other._v(0),
_v(1) > other._v(1) ? _v(1) : other._v(1),
@ -944,7 +944,7 @@ fmax(const FLOATNAME(LVecBase3) &other) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase3) FLOATNAME(LVecBase3)::
fmin(const FLOATNAME(LVecBase3) &other) {
fmin(const FLOATNAME(LVecBase3) &other) const {
TAU_PROFILE("LVecBase3::fmin()", " ", TAU_USER);
return FLOATNAME(LVecBase3)(_v(0) < other._v(0) ? _v(0) : other._v(0),
_v(1) < other._v(1) ? _v(1) : other._v(1),

View File

@ -139,8 +139,8 @@ PUBLISHED:
EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase3) __pow__(FLOATTYPE exponent) const);
EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent));
INLINE_LINMATH FLOATNAME(LVecBase3) fmax(const FLOATNAME(LVecBase3) &other);
INLINE_LINMATH FLOATNAME(LVecBase3) fmin(const FLOATNAME(LVecBase3) &other);
INLINE_LINMATH FLOATNAME(LVecBase3) fmax(const FLOATNAME(LVecBase3) &other) const;
INLINE_LINMATH FLOATNAME(LVecBase3) fmin(const FLOATNAME(LVecBase3) &other) const;
INLINE_LINMATH void cross_into(const FLOATNAME(LVecBase3) &other);

View File

@ -915,7 +915,7 @@ componentwise_mult(const FLOATNAME(LVecBase4) &other) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
fmax(const FLOATNAME(LVecBase4) &other) {
fmax(const FLOATNAME(LVecBase4) &other) const {
TAU_PROFILE("LVecBase4::fmax()", " ", TAU_USER);
return FLOATNAME(LVecBase4)(_v(0) > other._v(0) ? _v(0) : other._v(0),
_v(1) > other._v(1) ? _v(1) : other._v(1),
@ -929,7 +929,7 @@ fmax(const FLOATNAME(LVecBase4) &other) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE_LINMATH FLOATNAME(LVecBase4) FLOATNAME(LVecBase4)::
fmin(const FLOATNAME(LVecBase4) &other) {
fmin(const FLOATNAME(LVecBase4) &other) const {
TAU_PROFILE("LVecBase4::fmin()", " ", TAU_USER);
return FLOATNAME(LVecBase4)(_v(0) < other._v(0) ? _v(0) : other._v(0),
_v(1) < other._v(1) ? _v(1) : other._v(1),

View File

@ -140,8 +140,8 @@ PUBLISHED:
EXTENSION(INLINE_LINMATH FLOATNAME(LVecBase4) __pow__(FLOATTYPE exponent) const);
EXTENSION(INLINE_LINMATH PyObject *__ipow__(PyObject *self, FLOATTYPE exponent));
INLINE_LINMATH FLOATNAME(LVecBase4) fmax(const FLOATNAME(LVecBase4) &other);
INLINE_LINMATH FLOATNAME(LVecBase4) fmin(const FLOATNAME(LVecBase4) &other);
INLINE_LINMATH FLOATNAME(LVecBase4) fmax(const FLOATNAME(LVecBase4) &other) const;
INLINE_LINMATH FLOATNAME(LVecBase4) fmin(const FLOATNAME(LVecBase4) &other) const;
INLINE_LINMATH bool almost_equal(const FLOATNAME(LVecBase4) &other,
FLOATTYPE threshold) const;

View File

@ -24,7 +24,6 @@
#include "boundingPlane.h"
#include "unionBoundingVolume.h"
#include "intersectionBoundingVolume.h"
#include "linmath_events.h"
#include "dconfig.h"
#include "pandaSystem.h"
@ -80,17 +79,9 @@ init_libmathutil() {
IntersectionBoundingVolume::init_type();
BoundingLine::init_type();
BoundingPlane::init_type();
EventStoreVec2::init_type("EventStoreVec2");
EventStoreVec3::init_type("EventStoreVec3");
EventStoreMat4::init_type("EventStoreMat4");
EventStoreVec2::register_with_read_factory();
EventStoreVec3::register_with_read_factory();
EventStoreMat4::register_with_read_factory();
#ifdef HAVE_FFTW
PandaSystem *ps = PandaSystem::get_global_ptr();
ps->add_system("fftw");
#endif // FFTW
}

View File

@ -17,29 +17,22 @@
#include "pandabase.h"
#include "eventParameter.h"
#include "paramValue.h"
#include "luse.h"
////////////////////////////////////////////////////////////////////
//
// This file defines a few more EventStore classes for storing linmath
// objects in an EventParameter. We can't define this with the other
// EventStore classes, because linmath hasn't been defined yet at that
// point.
// objects in an EventParameter. These are just for backward
// compatibility; they are defined as typedefs to ParamVecBase types.
//
// See eventParameter.h.
// See paramValue.h.
//
////////////////////////////////////////////////////////////////////
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_MATHUTIL, EXPTP_PANDA_MATHUTIL, EventStoreValue<LVecBase2>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_MATHUTIL, EXPTP_PANDA_MATHUTIL, EventStoreValue<LVecBase3>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_MATHUTIL, EXPTP_PANDA_MATHUTIL, EventStoreValue<LMatrix4>);
typedef EventStoreValue<LVecBase2> EventStoreVec2;
typedef EventStoreValue<LVecBase3> EventStoreVec3;
typedef EventStoreValue<LMatrix4> EventStoreMat4;
typedef ParamVecBase2 EventStoreVec2;
typedef ParamVecBase3 EventStoreVec3;
typedef ParamMatrix4 EventStoreMat4;
// Tell GCC that we'll take care of the instantiation explicitly here.
#ifdef __GNUC__

View File

@ -135,8 +135,8 @@ draw_resize_box() {
PT(Texture) tex = new Texture;
tex->set_name("resize_box.rgb");
tex->load(resize_box_pnm);
tex->set_minfilter(Texture::FT_linear);
tex->set_magfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear);
tex->set_magfilter(SamplerState::FT_linear);
state = state->add_attrib(TextureAttrib::make(tex));
}
}

View File

@ -24,7 +24,7 @@
// Description : A class object for storing specifically objects of
// type PandaNode.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PGRAPH EventStorePandaNode : public EventStoreValueBase {
class EXPCL_PANDA_PGRAPH EventStorePandaNode : public ParamValueBase {
PUBLISHED:
INLINE EventStorePandaNode(const PandaNode *value);
virtual ~EventStorePandaNode();
@ -46,9 +46,9 @@ public:
return _type_handle;
}
static void init_type() {
EventStoreValueBase::init_type();
ParamValueBase::init_type();
register_type(_type_handle, "EventStorePandaNode",
EventStoreValueBase::get_class_type());
ParamValueBase::get_class_type());
}
private:

View File

@ -141,7 +141,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
AccumulatedAttribs geom_attribs = attribs;
entry->_state = geom_attribs.collect(entry->_state, attrib_types);
bool any_changed = false;
if ((attrib_types & SceneGraphReducer::TT_color) != 0) {
@ -152,9 +152,9 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
}
ra = entry->_state->get_attrib_def(ColorAttrib::get_class_slot());
CPT (ColorAttrib) ca = DCAST(ColorAttrib, ra);
CPT (ColorAttrib) ca = DCAST(ColorAttrib, ra);
if (ca->get_color_type() != ColorAttrib::T_vertex) {
if(allow_flatten_color) {
if(allow_flatten_color) {
if(transformer.set_color(new_geom, ca->get_color())) {
any_changed = true;
entry->_state = entry->_state->set_attrib(ColorAttrib::make_vertex());
@ -163,15 +163,15 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
if (transformer.remove_column(new_geom, InternalName::get_color())) {
any_changed = true;
}
}
}
}
}
}
if ((attrib_types & SceneGraphReducer::TT_color_scale) != 0) {
if (geom_attribs._color_scale != (const RenderAttrib *)NULL) {
CPT(ColorScaleAttrib) csa = DCAST(ColorScaleAttrib, geom_attribs._color_scale);
if (csa->get_scale() != LVecBase4(1.0f, 1.0f, 1.0f, 1.0f)) {
// Now, if we have an "off" or "flat" color attribute, we
// simply modify the color attribute, and leave the
// vertices alone.
@ -187,16 +187,16 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
// ColorAttrib::T_off means the color scale becomes
// the new color.
entry->_state = entry->_state->set_attrib(ColorAttrib::make_flat(csa->get_scale()));
} else if (ca->get_color_type() == ColorAttrib::T_flat) {
// ColorAttrib::T_flat means the color scale modulates
// the specified color to produce a new color.
const LColor &c1 = ca->get_color();
const LVecBase4 &c2 = csa->get_scale();
LColor color(c1[0] * c2[0], c1[1] * c2[1],
LColor color(c1[0] * c2[0], c1[1] * c2[1],
c1[2] * c2[2], c1[3] * c2[3]);
entry->_state = entry->_state->set_attrib(ColorAttrib::make_flat(color));
} else {
// Otherwise, we have vertex color, and we just scale
// it normally.
@ -219,7 +219,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
// that from which we started the flatten operation, but
// caveat programmer.
NameCount name_count;
if (geom_attribs._texture != (RenderAttrib *)NULL) {
const TextureAttrib *ta = DCAST(TextureAttrib, geom_attribs._texture);
int num_on_stages = ta->get_num_on_stages();
@ -229,12 +229,12 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
count_name(name_count, name);
}
}
const TexMatrixAttrib *tma =
const TexMatrixAttrib *tma =
DCAST(TexMatrixAttrib, geom_attribs._tex_matrix);
CPT(TexMatrixAttrib) new_tma = DCAST(TexMatrixAttrib, TexMatrixAttrib::make());
int num_stages = tma->get_num_stages();
for (int i = 0; i < num_stages; i++) {
TextureStage *stage = tma->get_stage(i);
@ -243,7 +243,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
// We can't transform these texcoords, since the name is
// used by more than one active stage.
new_tma = DCAST(TexMatrixAttrib, new_tma->add_stage(stage, tma->get_transform(stage)));
} else {
// It's safe to transform these texcoords; the name is
// used by no more than one active stage.
@ -252,7 +252,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
}
}
}
if (!new_tma->is_empty()) {
entry->_state = entry->_state->add_attrib(new_tma);
}
@ -288,7 +288,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
// invalidated our old pointer into the list, so we
// reassign it now.
entry = &(*geoms)[i];
} else {
// If there are no normals, we can just doubleside it in
// place. This is preferable because we can share vertices.
@ -297,14 +297,14 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
}
}
break;
case CullFaceAttrib::M_cull_counter_clockwise:
// Reverse winding order.
new_geom->reverse_in_place();
transformer.reverse_normals(new_geom);
any_changed = true;
break;
default:
break;
}
@ -425,7 +425,7 @@ r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state,
}
// And now prepare each of the textures.
const RenderAttrib *attrib =
const RenderAttrib *attrib =
geom_state->get_attrib(TextureAttrib::get_class_slot());
if (attrib != (const RenderAttrib *)NULL) {
const TextureAttrib *ta;
@ -433,6 +433,7 @@ r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state,
int num_stages = ta->get_num_on_stages();
for (int i = 0; i < num_stages; ++i) {
Texture *texture = ta->get_on_texture(ta->get_on_stage(i));
//TODO: prepare the sampler states, if specified.
if (texture != (Texture *)NULL) {
texture->prepare(prepared_objects);
}
@ -448,10 +449,11 @@ r_prepare_scene(GraphicsStateGuardianBase *gsg, const RenderState *node_state,
if (shader != (Shader *)NULL) {
shader->prepare(prepared_objects);
}
//TODO: prepare the shader inputs.
//TODO: Invoke the shader generator if enabled.
}
}
PandaNode::r_prepare_scene(gsg, node_state, transformer, current_thread);
}
@ -503,7 +505,7 @@ combine_with(PandaNode *other) {
CPT(TransformState) GeomNode::
calc_tight_bounds(LPoint3 &min_point, LPoint3 &max_point, bool &found_any,
const TransformState *transform, Thread *current_thread) const {
CPT(TransformState) next_transform =
CPT(TransformState) next_transform =
PandaNode::calc_tight_bounds(min_point, max_point, found_any, transform,
current_thread);
@ -552,10 +554,10 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
if (pgraph_cat.is_spam()) {
pgraph_cat.spam()
<< "Found " << *this << " in state " << *data._state
<< "Found " << *this << " in state " << *data._state
<< " draw_mask = " << data._draw_mask << "\n";
}
// Get all the Geoms, with no decalling.
Geoms geoms = get_geoms(trav->get_current_thread());
int num_geoms = geoms.get_num_geoms();
@ -575,7 +577,7 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
// Cull.
continue;
}
// Cull the Geom bounding volume against the view frustum
// and/or the cull planes. Don't bother unless we've got more
// than one Geom, since otherwise the bounding volume of the
@ -587,7 +589,7 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
CPT(BoundingVolume) geom_volume = geom->get_bounds();
const GeometricBoundingVolume *geom_gbv =
DCAST(GeometricBoundingVolume, geom_volume);
int result = data._view_frustum->contains(geom_gbv);
if (result == BoundingVolume::IF_no_intersection) {
// Cull this Geom.
@ -607,9 +609,9 @@ add_for_draw(CullTraverser *trav, CullTraverserData &data) {
}
}
}
CullableObject *object =
new CullableObject(geom, state, net_transform,
CullableObject *object =
new CullableObject(geom, state, net_transform,
modelview_transform, internal_transform);
trav->get_cull_handler()->record_object(object, trav);
}
@ -803,7 +805,7 @@ unify(int max_indices, bool preserve_order) {
CPT(GeomList) old_geoms = cdata->get_geoms();
for (gi = old_geoms->begin(); gi != old_geoms->end(); ++gi) {
const GeomEntry &old_entry = (*gi);
bool unified = false;
// Go from back to front, to minimize damage to the primitive ordering.
@ -827,14 +829,14 @@ unify(int max_indices, bool preserve_order) {
break;
}
}
if (!unified) {
// Couldn't unify this Geom with anything, so just add it to the
// output list.
new_geoms->push_back(old_entry);
}
}
// Done! We'll keep whatever's left in the output list.
cdata->set_geoms(new_geoms);
@ -868,7 +870,7 @@ write_geoms(ostream &out, int indent_level) const {
CPT(GeomList) geoms = cdata->get_geoms();
for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
const GeomEntry &entry = (*gi);
indent(out, indent_level + 2)
indent(out, indent_level + 2)
<< *entry._geom.get_read_pointer() << " " << *entry._state << "\n";
}
}
@ -888,7 +890,7 @@ write_verbose(ostream &out, int indent_level) const {
for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
const GeomEntry &entry = (*gi);
CPT(Geom) geom = entry._geom.get_read_pointer();
indent(out, indent_level + 2)
indent(out, indent_level + 2)
<< *geom << " " << *entry._state << "\n";
geom->write(out, indent_level + 4);
}
@ -897,7 +899,7 @@ write_verbose(ostream &out, int indent_level) const {
////////////////////////////////////////////////////////////////////
// Function: GeomNode::output
// Access: Public, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void GeomNode::
output(ostream &out) const {
@ -923,7 +925,7 @@ output(ostream &out) const {
out << " (" << geoms->size() << " geoms";
if (!common->is_empty()) {
out << ": " << *common;
out << ": " << *common;
}
out << ")";
@ -1061,7 +1063,7 @@ compute_internal_bounds(CPT(BoundingVolume) &internal_bounds,
const BoundingVolume **child_end = child_begin + child_volumes.size();
((BoundingVolume *)gbv)->around(child_begin, child_end);
}
internal_bounds = gbv;
internal_vertices = num_vertices;
}
@ -1216,7 +1218,7 @@ write_datagram(BamWriter *manager, Datagram &dg) const {
int num_geoms = geoms->size();
nassertv(num_geoms == (int)(PN_uint16)num_geoms);
dg.add_uint16(num_geoms);
GeomList::const_iterator gi;
for (gi = geoms->begin(); gi != geoms->end(); ++gi) {
const GeomEntry &entry = (*gi);

File diff suppressed because it is too large Load Diff

View File

@ -54,6 +54,7 @@ class MaterialCollection;
class Fog;
class GlobPattern;
class PreparedGraphicsObjects;
class SamplerState;
class Shader;
class ShaderInput;
@ -539,7 +540,7 @@ PUBLISHED:
INLINE void compose_color_scale(PN_stdfloat sx, PN_stdfloat sy, PN_stdfloat sz, PN_stdfloat sa,
int priority = 0);
void set_color_scale_off(int priority = 0);
void set_alpha_scale(PN_stdfloat scale, int priority = 0);
void set_all_color_scale(PN_stdfloat scale, int priority = 0);
INLINE void set_sr(PN_stdfloat sr);
@ -573,12 +574,12 @@ PUBLISHED:
void set_scissor(PN_stdfloat left, PN_stdfloat right, PN_stdfloat bottom, PN_stdfloat top);
void set_scissor(const LPoint3 &a, const LPoint3 &b);
void set_scissor(const LPoint3 &a, const LPoint3 &b,
void set_scissor(const LPoint3 &a, const LPoint3 &b,
const LPoint3 &c, const LPoint3 &d);
void set_scissor(const NodePath &other,
void set_scissor(const NodePath &other,
const LPoint3 &a, const LPoint3 &b);
void set_scissor(const NodePath &other,
const LPoint3 &a, const LPoint3 &b,
const LPoint3 &a, const LPoint3 &b,
const LPoint3 &c, const LPoint3 &d);
void clear_scissor();
bool has_scissor() const;
@ -596,6 +597,8 @@ PUBLISHED:
void set_texture(Texture *tex, int priority = 0);
void set_texture(TextureStage *stage, Texture *tex, int priority = 0);
void set_texture(Texture *tex, const SamplerState &sampler, int priority = 0);
void set_texture(TextureStage *stage, Texture *tex, const SamplerState &sampler, int priority = 0);
void set_texture_off(int priority = 0);
void set_texture_off(TextureStage *stage, int priority = 0);
void clear_texture();
@ -606,6 +609,8 @@ PUBLISHED:
bool has_texture_off(TextureStage *stage) const;
Texture *get_texture() const;
Texture *get_texture(TextureStage *stage) const;
const SamplerState &get_texture_sampler() const;
const SamplerState &get_texture_sampler(TextureStage *stage) const;
void set_shader(const Shader *sha, int priority = 0);
void set_shader_off(int priority = 0);
@ -615,6 +620,7 @@ PUBLISHED:
void set_shader_input(const ShaderInput *inp);
void set_shader_input(const InternalName *id, Texture *tex, int priority=0);
void set_shader_input(const InternalName *id, Texture *tex, const SamplerState &sampler, int priority=0);
void set_shader_input(const InternalName *id, Texture *tex, bool read, bool write, int z=-1, int n=0, int priority=0);
void set_shader_input(const InternalName *id, const NodePath &np, int priority=0);
void set_shader_input(const InternalName *id, const PTA_float &v, int priority=0);
@ -646,7 +652,7 @@ PUBLISHED:
const Shader *get_shader() const;
const ShaderInput *get_shader_input(const InternalName *id) const;
const int get_instance_count() const;
int get_instance_count() const;
void set_tex_transform(TextureStage *stage, const TransformState *transform);
void clear_tex_transform();
@ -698,10 +704,10 @@ PUBLISHED:
INLINE LVecBase3 get_tex_scale_3d(const NodePath &other, TextureStage *stage) const;
void set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode, int priority = 0);
void set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
const string &source_name, const NodePath &light,
void set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
const string &source_name, const NodePath &light,
int priority = 0);
void set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
void set_tex_gen(TextureStage *stage, RenderAttrib::TexGenMode mode,
const LTexCoord3 &constant_value,
int priority = 0);
void clear_tex_gen();
@ -915,20 +921,20 @@ PUBLISHED:
private:
static NodePathComponent *
find_common_ancestor(const NodePath &a, const NodePath &b,
int &a_count, int &b_count,
int &a_count, int &b_count,
Thread *current_thread);
CPT(RenderState) r_get_net_state(NodePathComponent *comp,
CPT(RenderState) r_get_net_state(NodePathComponent *comp,
Thread *current_thread) const;
CPT(RenderState) r_get_partial_state(NodePathComponent *comp, int n,
Thread *current_thread) const;
CPT(TransformState) r_get_net_transform(NodePathComponent *comp,
CPT(TransformState) r_get_net_transform(NodePathComponent *comp,
Thread *current_thread) const;
CPT(TransformState) r_get_partial_transform(NodePathComponent *comp, int n,
Thread *current_thread) const;
CPT(TransformState) r_get_net_prev_transform(NodePathComponent *comp,
Thread *current_thread) const;
CPT(TransformState) r_get_partial_prev_transform(NodePathComponent *comp,
CPT(TransformState) r_get_partial_prev_transform(NodePathComponent *comp,
int n, Thread *current_thread) const;
void find_matches(NodePathCollection &result,
@ -937,7 +943,7 @@ private:
void find_matches(NodePathCollection &result,
FindApproxPath &approx_path,
int max_matches) const;
void find_matches(NodePathCollection &result,
void find_matches(NodePathCollection &result,
FindApproxLevelEntry *level,
int max_matches) const;
@ -946,13 +952,13 @@ private:
void r_force_recompute_bounds(PandaNode *node);
void r_set_collide_mask(PandaNode *node,
void r_set_collide_mask(PandaNode *node,
CollideMask and_mask, CollideMask or_mask,
TypeHandle node_type);
typedef phash_set<InternalName *, pointer_hash> InternalNames;
bool r_has_vertex_column(PandaNode *node, const InternalName *name) const;
void r_find_all_vertex_columns(PandaNode *node,
void r_find_all_vertex_columns(PandaNode *node,
InternalNames &vertex_columns) const;
typedef phash_set<Texture *, pointer_hash> Textures;

View File

@ -257,39 +257,39 @@ get_occluder_viz(CullTraverser *trav, CullTraverserData &data) {
pgraph_cat.debug()
<< "Recomputing viz for " << *this << "\n";
}
PT(GeomVertexData) vdata = new GeomVertexData
(get_name(), GeomVertexFormat::get_v3n3t2(), Geom::UH_static);
// Compute the polygon normal from the first three vertices.
LPlane plane(_vertices[0], _vertices[1], _vertices[2]);
LVector3 poly_normal = plane.get_normal();
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
GeomVertexWriter normal(vdata, InternalName::get_normal());
GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
vertex.add_data3(_vertices[0]);
normal.add_data3(poly_normal);
texcoord.add_data2(0.0, 0.0);
vertex.add_data3(_vertices[1]);
normal.add_data3(poly_normal);
texcoord.add_data2(8.0, 0.0);
vertex.add_data3(_vertices[2]);
normal.add_data3(poly_normal);
texcoord.add_data2(8.0, 8.0);
vertex.add_data3(_vertices[3]);
normal.add_data3(poly_normal);
texcoord.add_data2(0.0, 8.0);
PT(GeomTriangles) triangles = new GeomTriangles(Geom::UH_static);
triangles->add_vertices(0, 1, 2);
triangles->close_primitive();
triangles->add_vertices(0, 2, 3);
triangles->close_primitive();
_occluder_viz = new Geom(vdata);
_occluder_viz->add_primitive(triangles);
@ -297,7 +297,7 @@ get_occluder_viz(CullTraverser *trav, CullTraverserData &data) {
lines->add_vertices(0, 1, 2, 3);
lines->add_vertex(0);
lines->close_primitive();
_frame_viz = new Geom(vdata);
_frame_viz->add_primitive(lines);
}
@ -321,8 +321,8 @@ get_occluder_viz_state(CullTraverser *trav, CullTraverserData &data) {
PTA_uchar image;
image.set_data("\x20\x80\x80\x20");
_viz_tex->set_ram_image(image);
_viz_tex->set_minfilter(Texture::FT_nearest);
_viz_tex->set_magfilter(Texture::FT_nearest);
_viz_tex->set_minfilter(SamplerState::FT_nearest);
_viz_tex->set_magfilter(SamplerState::FT_nearest);
}
static CPT(RenderState) viz_state;

View File

@ -81,7 +81,7 @@ make_default() {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader(const Shader *s, int priority) const {
@ -96,7 +96,7 @@ set_shader(const Shader *s, int priority) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_off
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_off(int priority) const {
@ -117,7 +117,7 @@ set_shader_off(int priority) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_auto
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_auto(int priority) const {
@ -142,7 +142,7 @@ set_shader_auto(int priority) const {
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_auto(BitMask32 shader_switch, int priority) const {
ShaderAttrib *result = new ShaderAttrib(*this);
result->_shader = NULL;
result->_shader_priority = priority;
@ -160,7 +160,7 @@ set_shader_auto(BitMask32 shader_switch, int priority) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_shader
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_shader() const {
@ -180,7 +180,7 @@ clear_shader() const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_flag
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_flag(int flag, bool value) const {
@ -194,11 +194,11 @@ set_flag(int flag, bool value) const {
result->_has_flags |= bit;
return return_new(result);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_flag
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_flag(int flag) const {
@ -212,7 +212,7 @@ clear_flag(int flag) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const ShaderInput *input) const {
@ -229,9 +229,9 @@ set_shader_input(const ShaderInput *input) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_float &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -239,9 +239,9 @@ set_shader_input(const InternalName *id, const PTA_float &v, int priority) const
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_double &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -249,9 +249,9 @@ set_shader_input(const InternalName *id, const PTA_double &v, int priority) cons
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LVecBase4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -259,9 +259,9 @@ set_shader_input(const InternalName *id, const PTA_LVecBase4 &v, int priority) c
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LVecBase3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -270,9 +270,9 @@ set_shader_input(const InternalName *id, const PTA_LVecBase3 &v, int priority) c
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LVecBase2 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -280,9 +280,9 @@ set_shader_input(const InternalName *id, const PTA_LVecBase2 &v, int priority) c
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LVecBase4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -290,9 +290,9 @@ set_shader_input(const InternalName *id, const LVecBase4 &v, int priority) const
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LVecBase3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -300,9 +300,9 @@ set_shader_input(const InternalName *id, const LVecBase3 &v, int priority) const
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LVecBase2 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -310,9 +310,9 @@ set_shader_input(const InternalName *id, const LVecBase2 &v, int priority) const
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LMatrix4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -320,9 +320,9 @@ set_shader_input(const InternalName *id, const PTA_LMatrix4 &v, int priority) co
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const PTA_LMatrix3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -330,9 +330,9 @@ set_shader_input(const InternalName *id, const PTA_LMatrix3 &v, int priority) co
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LMatrix4 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -340,9 +340,9 @@ set_shader_input(const InternalName *id, const LMatrix4 &v, int priority) const
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const LMatrix3 &v, int priority) const {
return set_shader_input(new ShaderInput(id,v,priority));
}
@ -350,7 +350,7 @@ set_shader_input(const InternalName *id, const LMatrix3 &v, int priority) const
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, Texture *tex, int priority) const {
@ -360,7 +360,7 @@ set_shader_input(const InternalName *id, Texture *tex, int priority) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, const NodePath &np, int priority) const {
@ -370,7 +370,7 @@ set_shader_input(const InternalName *id, const NodePath &np, int priority) const
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::set_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
set_shader_input(const InternalName *id, double n1, double n2, double n3, double n4, int priority) const {
@ -395,7 +395,7 @@ set_instance_count(int instance_count) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_shader_input(const InternalName *id) const {
@ -407,7 +407,7 @@ clear_shader_input(const InternalName *id) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::clear_shader_input
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
clear_shader_input(const string &id) const {
@ -458,7 +458,7 @@ get_shader_input(const string &id) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_nodepath
// Access: Published
// Description: Returns the ShaderInput as a nodepath. Assertion
// Description: Returns the ShaderInput as a nodepath. Assertion
// fails if there is none, or if it is not a nodepath.
////////////////////////////////////////////////////////////////////
const NodePath &ShaderAttrib::
@ -488,7 +488,7 @@ get_shader_input_nodepath(const InternalName *id) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_vector
// Access: Published
// Description: Returns the ShaderInput as a vector. Assertion
// Description: Returns the ShaderInput as a vector. Assertion
// fails if there is none, or if it is not a vector.
////////////////////////////////////////////////////////////////////
const LVecBase4 &ShaderAttrib::
@ -502,24 +502,33 @@ get_shader_input_vector(InternalName *id) const {
return resfail;
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_numeric) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a vector.\n";
nassert_raise(strm.str());
return resfail;
if (p->get_value_type() == ShaderInput::M_numeric) {
return p->get_vector();
} else if (p->get_value_type() == ShaderInput::M_param) {
// Temporary solution until the new param system
ParamValueBase *param = p->get_param();
if (param != NULL && param->is_of_type(ParamVecBase4::get_class_type())) {
return ((const ParamVecBase4 *) param)->get_value();
}
}
return p->get_vector();
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a vector.\n";
nassert_raise(strm.str());
return resfail;
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_ptr
// Access: Published
// Description: Returns the ShaderInput as a ShaderPtrData struct.
// Assertion fails if there is none. or if it is not
// Description: Returns the ShaderInput as a ShaderPtrData struct.
// Assertion fails if there is none. or if it is not
// a PTA(double/float)
////////////////////////////////////////////////////////////////////
const Shader::ShaderPtrData *ShaderAttrib::
const Shader::ShaderPtrData *ShaderAttrib::
get_shader_input_ptr(const InternalName *id) const {
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
@ -542,7 +551,7 @@ get_shader_input_ptr(const InternalName *id) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_texture
// Access: Published
// Description: Returns the ShaderInput as a texture. Assertion
// Description: Returns the ShaderInput as a texture. Assertion
// fails if there is none, or if it is not a texture.
////////////////////////////////////////////////////////////////////
Texture *ShaderAttrib::
@ -555,7 +564,8 @@ get_shader_input_texture(const InternalName *id) const {
return NULL;
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_texture) {
if (p->get_value_type() != ShaderInput::M_texture &&
p->get_value_type() != ShaderInput::M_texture_sampler) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a texture.\n";
nassert_raise(strm.str());
@ -565,6 +575,33 @@ get_shader_input_texture(const InternalName *id) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_sampler
// Access: Published
// Description: Returns the ShaderInput as a sampler. Assertion
// fails if there is none, or if it is not a texture.
////////////////////////////////////////////////////////////////////
const SamplerState &ShaderAttrib::
get_shader_input_sampler(const InternalName *id) const {
Inputs::const_iterator i = _inputs.find(id);
if (i == _inputs.end()) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not present.\n";
nassert_raise(strm.str());
return SamplerState::get_default();
} else {
const ShaderInput *p = (*i).second;
if (p->get_value_type() != ShaderInput::M_texture &&
p->get_value_type() != ShaderInput::M_texture_sampler) {
ostringstream strm;
strm << "Shader input " << id->get_name() << " is not a texture.\n";
nassert_raise(strm.str());
return SamplerState::get_default();
}
return p->get_sampler();
}
}
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_shader_input_matrix
// Access: Published
@ -604,6 +641,12 @@ get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const {
matrix = LCAST(PN_stdfloat, matrixd);
return matrix;
}
default: {
ostringstream strm;
strm << "Shader input " << id->get_name() << " does not contain floating-point data.\n";
nassert_raise(strm.str());
return LMatrix4::ident_mat();
}
}
}
@ -618,7 +661,7 @@ get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const {
// Function: ShaderAttrib::get_shader
// Access: Published
// Description: Returns the shader object associated with the node.
// If get_override returns true, but get_shader
// If get_override returns true, but get_shader
// returns NULL, that means that this attribute should
// disable the shader.
////////////////////////////////////////////////////////////////////
@ -646,7 +689,7 @@ int ShaderAttrib::
compare_to_impl(const RenderAttrib *other) const {
const ShaderAttrib *that;
DCAST_INTO_R(that, other, 0);
if (this->_shader != that->_shader) {
return (this->_shader < that->_shader) ? -1 : 1;
}
@ -699,7 +742,7 @@ compare_to_impl(const RenderAttrib *other) const {
if (i2 != that->_inputs.end()) {
return -1;
}
return 0;
}
@ -789,7 +832,7 @@ compose_impl(const RenderAttrib *other) const {
////////////////////////////////////////////////////////////////////
// Function: ShaderAttrib::get_auto_shader_attrib_impl
// Access: Protected, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) ShaderAttrib::
get_auto_shader_attrib_impl(const RenderState *state) const {

View File

@ -33,11 +33,9 @@
////////////////////////////////////////////////////////////////////
// Class : ShaderAttrib
// Description :
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PGRAPH ShaderAttrib: public RenderAttrib {
private:
INLINE ShaderAttrib();
INLINE ShaderAttrib(const ShaderAttrib &copy);
@ -71,7 +69,7 @@ PUBLISHED:
CPT(RenderAttrib) clear_shader() const;
// Shader Inputs
CPT(RenderAttrib) set_shader_input(const ShaderInput *inp) const;
// InternalName* id
CPT(RenderAttrib) set_shader_input(const InternalName *id, Texture *tex, int priority=0) const;
CPT(RenderAttrib) set_shader_input(const InternalName *id, const NodePath &np, int priority=0) const;
@ -88,7 +86,7 @@ PUBLISHED:
CPT(RenderAttrib) set_shader_input(const InternalName *id, const LMatrix4 &v, int priority=0) const;
CPT(RenderAttrib) set_shader_input(const InternalName *id, const LMatrix3 &v, int priority=0) const;
CPT(RenderAttrib) set_shader_input(const InternalName *id, double n1=0, double n2=0, double n3=0, double n4=1,
int priority=0) const;
int priority=0) const;
CPT(RenderAttrib) set_instance_count(int instance_count) const;
@ -97,11 +95,11 @@ PUBLISHED:
CPT(RenderAttrib) clear_shader_input(const InternalName *id) const;
CPT(RenderAttrib) clear_shader_input(const string &id) const;
CPT(RenderAttrib) clear_all_shader_inputs() const;
INLINE bool get_flag(int flag) const;
const Shader *get_shader() const;
const ShaderInput *get_shader_input(const InternalName *id) const;
const ShaderInput *get_shader_input(const string &id) const;
@ -109,11 +107,12 @@ PUBLISHED:
const NodePath &get_shader_input_nodepath(const InternalName *id) const;
const LVecBase4 &get_shader_input_vector(InternalName *id) const;
Texture *get_shader_input_texture(const InternalName *id) const;
const SamplerState &get_shader_input_sampler(const InternalName *id) const;
const Shader::ShaderPtrData *get_shader_input_ptr(const InternalName *id) const;
const LMatrix4 &get_shader_input_matrix(const InternalName *id, LMatrix4 &matrix) const;
static void register_with_read_factory();
public:
protected:
@ -121,7 +120,7 @@ protected:
virtual size_t get_hash_impl() const;
virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const;
virtual CPT(RenderAttrib) get_auto_shader_attrib_impl(const RenderState *state) const;
private:
CPT(Shader) _shader;

View File

@ -12,20 +12,20 @@
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Destructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
~ShaderInput()
{
~ShaderInput() {
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, int priority) :
@ -41,14 +41,14 @@ ShaderInput(const InternalName *name, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, Texture *tex, int priority) :
_name(name),
_type(M_texture),
_priority(priority),
_stored_texture(tex),
_value(tex),
_bind_layer(0),
_bind_level(0),
_access(A_read | A_write | A_layered)
@ -58,14 +58,32 @@ ShaderInput(const InternalName *name, Texture *tex, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, Texture *tex, const SamplerState &sampler, int priority) :
_name(name),
_type(M_texture_sampler),
_priority(priority),
_value(tex),
_sampler(sampler),
_bind_layer(0),
_bind_level(0),
_access(A_read | A_layered)
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, Texture *tex, bool read, bool write, int z, int n, int priority) :
_name(name),
_type(M_texture),
_priority(priority),
_stored_texture(tex),
_value(tex),
_bind_layer(z),
_bind_level(n),
_access(0)
@ -87,7 +105,24 @@ ShaderInput(const InternalName *name, Texture *tex, bool read, bool write, int z
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, ParamValueBase *param, int priority) :
_name(name),
_type(M_param),
_priority(priority),
_value(param),
_bind_layer(0),
_bind_level(0),
_access(A_read)
{
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const NodePath &np, int priority) :
@ -104,10 +139,10 @@ ShaderInput(const InternalName *name, const NodePath &np, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_float &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_float &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -121,10 +156,10 @@ ShaderInput(const InternalName *name, const PTA_float &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase4f &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LVecBase4f &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -138,10 +173,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase4f &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase3f &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LVecBase3f &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -155,7 +190,7 @@ ShaderInput(const InternalName *name, const PTA_LVecBase3f &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase2f &ptr, int priority) :
@ -172,7 +207,7 @@ ShaderInput(const InternalName *name, const PTA_LVecBase2f &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase4f &vec, int priority) :
@ -190,7 +225,7 @@ ShaderInput(const InternalName *name, const LVecBase4f &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase3f &vec, int priority) :
@ -208,7 +243,7 @@ ShaderInput(const InternalName *name, const LVecBase3f &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase2f &vec, int priority) :
@ -226,10 +261,10 @@ ShaderInput(const InternalName *name, const LVecBase2f &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LMatrix4f &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LMatrix4f &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -243,10 +278,10 @@ ShaderInput(const InternalName *name, const PTA_LMatrix4f &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LMatrix3f &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LMatrix3f &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -260,7 +295,7 @@ ShaderInput(const InternalName *name, const PTA_LMatrix3f &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LMatrix4f &mat, int priority) :
@ -277,7 +312,7 @@ ShaderInput(const InternalName *name, const LMatrix4f &mat, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LMatrix3f &mat, int priority) :
@ -294,10 +329,10 @@ ShaderInput(const InternalName *name, const LMatrix3f &mat, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_double &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_double &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -311,10 +346,10 @@ ShaderInput(const InternalName *name, const PTA_double &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase4d &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LVecBase4d &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -328,10 +363,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase4d &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase3d &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LVecBase3d &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -345,7 +380,7 @@ ShaderInput(const InternalName *name, const PTA_LVecBase3d &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase2d &ptr, int priority) :
@ -362,7 +397,7 @@ ShaderInput(const InternalName *name, const PTA_LVecBase2d &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase4d &vec, int priority) :
@ -380,7 +415,7 @@ ShaderInput(const InternalName *name, const LVecBase4d &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase3d &vec, int priority) :
@ -398,7 +433,7 @@ ShaderInput(const InternalName *name, const LVecBase3d &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase2d &vec, int priority) :
@ -416,10 +451,10 @@ ShaderInput(const InternalName *name, const LVecBase2d &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LMatrix4d &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LMatrix4d &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -433,10 +468,10 @@ ShaderInput(const InternalName *name, const PTA_LMatrix4d &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LMatrix3d &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LMatrix3d &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -450,7 +485,7 @@ ShaderInput(const InternalName *name, const PTA_LMatrix3d &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LMatrix4d &mat, int priority) :
@ -467,7 +502,7 @@ ShaderInput(const InternalName *name, const LMatrix4d &mat, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LMatrix3d &mat, int priority) :
@ -484,10 +519,10 @@ ShaderInput(const InternalName *name, const LMatrix3d &mat, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_int &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_int &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -501,10 +536,10 @@ ShaderInput(const InternalName *name, const PTA_int &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase4i &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LVecBase4i &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -518,10 +553,10 @@ ShaderInput(const InternalName *name, const PTA_LVecBase4i &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase3i &ptr, int priority) :
ShaderInput(const InternalName *name, const PTA_LVecBase3i &ptr, int priority) :
_name(name),
_type(M_numeric),
_priority(priority),
@ -535,7 +570,7 @@ ShaderInput(const InternalName *name, const PTA_LVecBase3i &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const PTA_LVecBase2i &ptr, int priority) :
@ -552,7 +587,7 @@ ShaderInput(const InternalName *name, const PTA_LVecBase2i &ptr, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase4i &vec, int priority) :
@ -570,7 +605,7 @@ ShaderInput(const InternalName *name, const LVecBase4i &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase3i &vec, int priority) :
@ -588,7 +623,7 @@ ShaderInput(const InternalName *name, const LVecBase3i &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::Constructor
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE ShaderInput::
ShaderInput(const InternalName *name, const LVecBase2i &vec, int priority) :
@ -606,7 +641,7 @@ ShaderInput(const InternalName *name, const LVecBase2i &vec, int priority) :
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_name
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE const InternalName *ShaderInput::
get_name() const {
@ -616,7 +651,7 @@ get_name() const {
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_value_type
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE int ShaderInput::
get_value_type() const {
@ -626,7 +661,7 @@ get_value_type() const {
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_priority
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE int ShaderInput::
get_priority() const {
@ -636,27 +671,17 @@ get_priority() const {
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_texture
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE Texture *ShaderInput::
get_texture() const {
return _stored_texture;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_ptr
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const Shader::ShaderPtrData &ShaderInput::
get_ptr() const {
return _stored_ptr;
return DCAST(Texture, _value);
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_nodepath
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE const NodePath &ShaderInput::
get_nodepath() const {
@ -666,10 +691,41 @@ get_nodepath() const {
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_vector
// Access: Published
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE const LVecBase4 &ShaderInput::
get_vector() const {
return _stored_vector;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_ptr
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const Shader::ShaderPtrData &ShaderInput::
get_ptr() const {
return _stored_ptr;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_sampler
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE const SamplerState &ShaderInput::
get_sampler() const {
return (_type == M_texture)
? get_texture()->get_default_sampler()
: _sampler;
}
////////////////////////////////////////////////////////////////////
// Function: ShaderInput::get_param
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ParamValueBase *ShaderInput::
get_param() const {
return DCAST(ParamValueBase, _value);
}

View File

@ -20,9 +20,8 @@
#include "typedWritableReferenceCount.h"
#include "pointerTo.h"
#include "nodePath.h"
#include "texture.h"
#include "internalName.h"
#include "shader.h"
#include "paramValue.h"
#include "pta_float.h"
#include "pta_double.h"
#include "pta_LMatrix4.h"
@ -30,6 +29,9 @@
#include "pta_LVecBase4.h"
#include "pta_LVecBase3.h"
#include "pta_LVecBase2.h"
#include "samplerState.h"
#include "shader.h"
#include "texture.h"
////////////////////////////////////////////////////////////////////
// Class : ShaderInput
@ -37,8 +39,7 @@
// one of the value types that can be passed as input
// to a shader.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PGRAPH ShaderInput: public TypedWritableReferenceCount {
class EXPCL_PANDA_PGRAPH ShaderInput : public TypedWritableReferenceCount {
public:
INLINE ~ShaderInput();
@ -54,7 +55,9 @@ PUBLISHED:
INLINE ShaderInput(const InternalName *id, int priority=0);
INLINE ShaderInput(const InternalName *id, const NodePath &np, int priority=0);
INLINE ShaderInput(const InternalName *id, Texture *tex, int priority=0);
INLINE ShaderInput(const InternalName *id, Texture *tex, const SamplerState &sampler, int priority=0);
INLINE ShaderInput(const InternalName *id, Texture *tex, bool read, bool write, int z=-1, int n=0, int priority=0);
INLINE ShaderInput(const InternalName *id, ParamValueBase *param, int priority=0);
INLINE ShaderInput(const InternalName *id, const PTA_float &ptr, int priority=0);
INLINE ShaderInput(const InternalName *id, const PTA_LVecBase4f &ptr, int priority=0);
INLINE ShaderInput(const InternalName *id, const PTA_LVecBase3f &ptr, int priority=0);
@ -91,7 +94,9 @@ PUBLISHED:
M_invalid = 0,
M_texture,
M_nodepath,
M_numeric
M_numeric,
M_texture_sampler,
M_param
};
INLINE const InternalName *get_name() const;
@ -102,23 +107,27 @@ PUBLISHED:
INLINE const NodePath &get_nodepath() const;
INLINE const LVecBase4 &get_vector() const;
INLINE const Shader::ShaderPtrData &get_ptr() const;
INLINE const SamplerState &get_sampler() const;
public:
INLINE ParamValueBase *get_param() const;
static void register_with_read_factory();
private:
CPT(InternalName) _name;
int _type;
int _priority;
Shader::ShaderPtrData _stored_ptr;
PT(Texture) _stored_texture;
NodePath _stored_nodepath;
SamplerState _sampler;
LVecBase4 _stored_vector;
NodePath _stored_nodepath;
Shader::ShaderPtrData _stored_ptr;
CPT(InternalName) _name;
PT(TypedWritableReferenceCount) _value;
int _priority;
public:
int _type : 8;
int _access : 8;
int _bind_level : 16;
int _bind_layer;
int _bind_level;
int _access;
public:
static TypeHandle get_class_type() {

View File

@ -109,7 +109,7 @@ get_on_stage(int n) const {
// Function: TextureAttrib::get_num_on_ff_stages
// Access: Published
// Description: Returns the number of on-stages that are relevant
// to the classic fixed function pipeline. This excludes
// to the classic fixed function pipeline. This excludes
// texture stages such as normal maps.
////////////////////////////////////////////////////////////////////
INLINE int TextureAttrib::
@ -123,7 +123,7 @@ get_num_on_ff_stages() const {
// Access: Published
// Description: Returns the nth stage turned on by the attribute,
// sorted in render order, including only those relevant
// to the classic fixed function pipeline. This excludes
// to the classic fixed function pipeline. This excludes
// texture stages such as normal maps.
////////////////////////////////////////////////////////////////////
INLINE TextureStage *TextureAttrib::
@ -175,6 +175,24 @@ get_on_texture(TextureStage *stage) const {
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::get_on_sampler
// Access: Published
// Description: Returns the sampler associated with the indicated
// stage, or the one associated with its texture if
// no custom stage has been specified. It is an error
// to call this if the stage does not exist.
////////////////////////////////////////////////////////////////////
INLINE const SamplerState &TextureAttrib::
get_on_sampler(TextureStage *stage) const {
Stages::const_iterator si;
si = _on_stages.find(StageNode(stage));
nassertr_always(si != _on_stages.end(), SamplerState::get_default());
return si->_has_sampler ? si->_sampler
: si->_texture->get_default_sampler();
}
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::get_on_stage_override
// Access: Published
@ -269,7 +287,7 @@ check_sorted() const {
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::StageNode::Constructor
// Access: Public
// Description:
// Description:
////////////////////////////////////////////////////////////////////
INLINE TextureAttrib::StageNode::
StageNode(const TextureStage *stage, unsigned int implicit_sort, int override) :
@ -277,11 +295,11 @@ StageNode(const TextureStage *stage, unsigned int implicit_sort, int override) :
// deal with it properly.
_stage((TextureStage *)stage),
_implicit_sort(implicit_sort),
_override(override)
_override(override),
_has_sampler(false)
{
}
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::CompareTextureStagePriorities::operator ()
// Access: Public
@ -290,7 +308,7 @@ StageNode(const TextureStage *stage, unsigned int implicit_sort, int override) :
// within priority, within order by sort.
////////////////////////////////////////////////////////////////////
INLINE bool TextureAttrib::CompareTextureStagePriorities::
operator () (const TextureAttrib::StageNode *a,
operator () (const TextureAttrib::StageNode *a,
const TextureAttrib::StageNode *b) const {
if (a->_stage->get_priority() != b->_stage->get_priority()) {
return a->_stage->get_priority() > b->_stage->get_priority();
@ -308,7 +326,7 @@ operator () (const TextureAttrib::StageNode *a,
// texture stages in order by sort.
////////////////////////////////////////////////////////////////////
INLINE bool TextureAttrib::CompareTextureStageSort::
operator () (const TextureAttrib::StageNode *a,
operator () (const TextureAttrib::StageNode *a,
const TextureAttrib::StageNode *b) const {
if (a->_stage->get_sort() != b->_stage->get_sort()) {
return a->_stage->get_sort() < b->_stage->get_sort();
@ -323,7 +341,7 @@ operator () (const TextureAttrib::StageNode *a,
// texture stages in order by pointer.
////////////////////////////////////////////////////////////////////
INLINE bool TextureAttrib::CompareTextureStagePointer::
operator () (const TextureAttrib::StageNode &a,
operator () (const TextureAttrib::StageNode &a,
const TextureAttrib::StageNode &b) const {
return a._stage < b._stage;
}

View File

@ -131,6 +131,32 @@ add_on_stage(TextureStage *stage, Texture *tex, int override) const {
(*si)._override = override;
(*si)._texture = tex;
(*si)._implicit_sort = attrib->_next_implicit_sort;
(*si)._has_sampler = false;
++(attrib->_next_implicit_sort);
// We now need to re-sort the attrib list.
attrib->_sort_seq = UpdateSeq::old();
attrib->_filtered_seq = UpdateSeq::old();
return return_new(attrib);
}
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::add_on_stage
// Access: Published
// Description: Returns a new TextureAttrib, just like this one, but
// with the indicated stage added to the list of stages
// turned on by this attrib.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) TextureAttrib::
add_on_stage(TextureStage *stage, Texture *tex, const SamplerState &sampler, int override) const {
TextureAttrib *attrib = new TextureAttrib(*this);
Stages::iterator si = attrib->_on_stages.insert(StageNode(stage)).first;
(*si)._override = override;
(*si)._texture = tex;
(*si)._sampler = sampler;
(*si)._implicit_sort = attrib->_next_implicit_sort;
(*si)._has_sampler = true;
++(attrib->_next_implicit_sort);
// We now need to re-sort the attrib list.
@ -239,7 +265,7 @@ unify_texture_stages(TextureStage *stage) const {
for (fsi = _off_stages.begin(); fsi != _off_stages.end(); ++fsi) {
TextureStage *this_stage = (*fsi)._stage;
if (this_stage != stage &&
if (this_stage != stage &&
this_stage->get_name() == stage->get_name()) {
this_stage = stage;
any_changed = true;
@ -291,7 +317,7 @@ filter_to_max(int max_texture_stages) const {
RenderStages priority_stages = _render_stages;
// This sort function uses the STL function object defined above.
sort(priority_stages.begin(), priority_stages.end(),
sort(priority_stages.begin(), priority_stages.end(),
CompareTextureStagePriorities());
// Now lop off all of the stages after the first max_texture_stages.
@ -362,7 +388,7 @@ lower_attrib_can_override() const {
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::output
// Access: Public, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
void TextureAttrib::
output(ostream &out) const {
@ -399,7 +425,7 @@ output(ostream &out) const {
out << " on";
}
}
RenderStages::const_iterator ri;
for (ri = _render_stages.begin(); ri != _render_stages.end(); ++ri) {
const StageNode &sn = *(*ri);
@ -520,6 +546,22 @@ compare_to_impl(const RenderAttrib *other) const {
return override < other_override ? -1 : 1;
}
int has_sampler = (*si)._has_sampler;
int other_has_sampler = (*osi)._has_sampler;
if (has_sampler != other_has_sampler) {
return has_sampler < other_has_sampler ? -1 : 1;
}
if (has_sampler) {
const SamplerState &sampler = (*si)._sampler;
const SamplerState &other_sampler = (*osi)._sampler;
if (sampler != other_sampler) {
return sampler < other_sampler ? -1 : 1;
}
}
++si;
++osi;
}
@ -560,7 +602,7 @@ compare_to_impl(const RenderAttrib *other) const {
if (ofi != ta->_off_stages.end()) {
return -1;
}
return 0;
}
@ -641,8 +683,8 @@ compose_impl(const RenderAttrib *other) const {
// Create a new TextureAttrib that will hold the result.
TextureAttrib *attrib = new TextureAttrib;
while (ai != _on_stages.end() &&
bi != ta->_on_stages.end() &&
while (ai != _on_stages.end() &&
bi != ta->_on_stages.end() &&
ci != ta->_off_stages.end()) {
if ((*ai)._stage < (*bi)._stage) {
if ((*ai)._stage < (*ci)._stage) {
@ -717,12 +759,12 @@ compose_impl(const RenderAttrib *other) const {
// present in the secondary.
attrib->_on_stages.insert(attrib->_on_stages.end(), *ai);
++ai;
} else if ((*ci)._stage < (*ai)._stage) {
// Here is a stage that is turned off in the secondary, but
// was not present in the original.
++ci;
} else { // (*ci)._stage == (*ai)._stage
// Here is a stage that is turned off in the secondary, and
// was present in the original.
@ -772,7 +814,7 @@ invert_compose_impl(const RenderAttrib *other) const {
////////////////////////////////////////////////////////////////////
// Function: TextureAttrib::get_auto_shader_attrib_impl
// Access: Protected, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) TextureAttrib::
get_auto_shader_attrib_impl(const RenderState *state) const {
@ -821,6 +863,10 @@ write_datagram(BamWriter *manager, Datagram &dg) {
manager->write_pointer(dg, tex);
dg.add_uint16((*si)._implicit_sort);
dg.add_int32((*si)._override);
dg.add_bool((*si)._has_sampler);
if ((*si)._has_sampler) {
(*si)._sampler.write_datagram(dg);
}
}
}
@ -850,13 +896,13 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
// The Texture pointer filters itself through the TexturePool, so
// we don't have to do anything special here.
Texture *tex = DCAST(Texture, p_list[pi++]);
if (tex != (Texture *)NULL) {
StageNode &sn = _on_stages[sni];
sn._stage = ts;
sn._texture = tex;
++sni;
} else {
// If we couldn't load a texture pointer, turn off that
// particular texture stage.
@ -905,7 +951,7 @@ fillin(DatagramIterator &scan, BamReader *manager) {
// read the _off_stages data.
_off_all_stages = scan.get_bool();
int num_off_stages = scan.get_uint16();
// Push back a NULL pointer for each off TextureStage for now, until
// we get the actual list of pointers later in complete_pointers().
int i;
@ -938,8 +984,16 @@ fillin(DatagramIterator &scan, BamReader *manager) {
}
_next_implicit_sort = max(_next_implicit_sort, implicit_sort + 1);
_on_stages.push_back(StageNode(NULL, _next_implicit_sort, override));
Stages::iterator si =
_on_stages.insert_nonunique(StageNode(NULL, _next_implicit_sort, override));
++_next_implicit_sort;
if (manager->get_file_minor_ver() >= 36) {
(*si)._has_sampler = scan.get_bool();
if ((*si)._has_sampler) {
(*si)._sampler.read_datagram(scan, manager);
}
}
}
}

View File

@ -61,6 +61,7 @@ PUBLISHED:
INLINE int get_ff_tc_index(int n) const;
INLINE bool has_on_stage(TextureStage *stage) const;
INLINE Texture *get_on_texture(TextureStage *stage) const;
INLINE const SamplerState &get_on_sampler(TextureStage *stage) const;
INLINE int get_on_stage_override(TextureStage *stage) const;
int find_on_stage(const TextureStage *stage) const;
@ -74,6 +75,8 @@ PUBLISHED:
INLINE bool is_identity() const;
CPT(RenderAttrib) add_on_stage(TextureStage *stage, Texture *tex, int override = 0) const;
CPT(RenderAttrib) add_on_stage(TextureStage *stage, Texture *tex,
const SamplerState &sampler, int override = 0) const;
CPT(RenderAttrib) remove_on_stage(TextureStage *stage) const;
CPT(RenderAttrib) add_off_stage(TextureStage *stage, int override = 0) const;
CPT(RenderAttrib) remove_off_stage(TextureStage *stage) const;
@ -102,12 +105,14 @@ private:
private:
class StageNode {
public:
INLINE StageNode(const TextureStage *stage,
INLINE StageNode(const TextureStage *stage,
unsigned int implicit_sort = 0,
int override = 0);
PT(TextureStage) _stage;
PT(Texture) _texture;
SamplerState _sampler;
bool _has_sampler;
int _ff_tc_index;
unsigned int _implicit_sort;
int _override;
@ -135,7 +140,7 @@ private:
RenderStages _render_stages; // all "on" stages, sorted in render order.
RenderStages _render_ff_stages; // fixed-function stages only, in render order.
unsigned int _next_implicit_sort;
Stages _off_stages;
bool _off_all_stages;
@ -164,7 +169,7 @@ public:
protected:
static TypedWritable *make_from_bam(const FactoryParams &params);
void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
@ -188,4 +193,3 @@ private:
#include "textureAttrib.I"
#endif

View File

@ -199,11 +199,11 @@ make_spot(int pixel_width, PN_stdfloat full_radius, LColor &fg, LColor &bg) {
PT(Texture) tex = new Texture("spot");
tex->load(image);
tex->set_border_color(bg);
tex->set_wrap_u(Texture::WM_border_color);
tex->set_wrap_v(Texture::WM_border_color);
tex->set_wrap_u(SamplerState::WM_border_color);
tex->set_wrap_v(SamplerState::WM_border_color);
tex->set_minfilter(Texture::FT_linear);
tex->set_magfilter(Texture::FT_linear);
tex->set_minfilter(SamplerState::FT_linear);
tex->set_magfilter(SamplerState::FT_linear);
return tex;
}

View File

@ -1,6 +1,6 @@
#define OTHER_LIBS p3interrogatedb:c p3dconfig:c p3dtoolconfig:m \
p3dtoolutil:c p3dtoolbase:c p3dtool:m p3prc:c
#define LOCAL_LIBS p3pipeline p3express p3pandabase
#define LOCAL_LIBS p3pipeline p3linmath p3express p3pandabase
#define USE_PACKAGES zlib
#begin lib_target
@ -57,6 +57,7 @@
modifierButtons.I modifierButtons.h mouseButton.h \
mouseData.I mouseData.h nameUniquifier.I nameUniquifier.h \
nodeCachedReferenceCount.h nodeCachedReferenceCount.I \
paramValue.I paramValue.h \
pbitops.I pbitops.h \
portalMask.h \
pta_ushort.h \
@ -107,6 +108,7 @@
modifierButtons.cxx mouseButton.cxx mouseData.cxx \
nameUniquifier.cxx \
nodeCachedReferenceCount.cxx \
paramValue.cxx \
pbitops.cxx \
pta_ushort.cxx \
pythonCallbackObject.cxx \
@ -167,8 +169,9 @@
modifierButtons.h mouseButton.h mouseData.I mouseData.h \
nameUniquifier.I nameUniquifier.h \
nodeCachedReferenceCount.h nodeCachedReferenceCount.I \
portalMask.h \
paramValue.I paramValue.h \
pbitops.I pbitops.h \
portalMask.h \
pta_ushort.h \
pythonCallbackObject.h pythonCallbackObject.I \
simpleHashMap.I simpleHashMap.h \

View File

@ -33,7 +33,7 @@ static const unsigned short _bam_major_ver = 6;
// Bumped to major version 6 on 2/11/06 to factor out PandaNode::CData.
static const unsigned short _bam_first_minor_ver = 14;
static const unsigned short _bam_minor_ver = 35;
static const unsigned short _bam_minor_ver = 36;
// Bumped to minor version 14 on 12/19/07 to change default ColorAttrib.
// Bumped to minor version 15 on 4/9/08 to add TextureAttrib::_implicit_sort.
// Bumped to minor version 16 on 5/13/08 to add Texture::_quality_level.
@ -56,5 +56,6 @@ static const unsigned short _bam_minor_ver = 35;
// Bumped to minor version 33 on 8/17/13 to add UvScrollNode::_w_speed.
// Bumped to minor version 34 on 9/16/14 to add ScissorAttrib::_off.
// Bumped to minor version 35 on 12/3/14 to change StencilAttrib.
// Bumped to minor version 36 on 12/9/14 to add samplers and lod settings.
#endif

View File

@ -34,6 +34,7 @@
#include "factoryParam.h"
#include "namable.h"
#include "nodeCachedReferenceCount.h"
#include "paramValue.h"
#include "pythonCallbackObject.h"
#include "referenceCount.h"
#include "sparseArray.h"
@ -62,7 +63,7 @@ ConfigVariableEnum<BamEnums::BamEndian> bam_endian
"particular platform."));
ConfigVariableBool bam_stdfloat_double
("bam-stdfloat-double",
("bam-stdfloat-double",
#ifdef STDFLOAT_DOUBLE
true,
#else
@ -70,7 +71,7 @@ ConfigVariableBool bam_stdfloat_double
#endif
PRC_DESC("The default width of floating-point numbers to write to a bam "
"file. Set this true to force doubles (64-bit floats), or false "
"to force sinles (32-bit floats). The default is whichever width "
"to force singles (32-bit floats). The default is whichever width "
"Panda has been compiled to use natively. Normally, this setting "
"should not be changed from the default."));
@ -79,8 +80,6 @@ ConfigVariableEnum<BamEnums::BamTextureMode> bam_texture_mode
PRC_DESC("Set this to specify how textures should be written into Bam files."
"See the panda source or documentation for available options."));
ConfigureFn(config_util) {
init_libputil();
}
@ -200,6 +199,23 @@ init_libputil() {
FactoryParam::init_type();
Namable::init_type();
NodeCachedReferenceCount::init_type();
ParamMatrix3d::init_type("ParamMatrix3d");
ParamMatrix3f::init_type("ParamMatrix3f");
ParamMatrix4d::init_type("ParamMatrix4d");
ParamMatrix4f::init_type("ParamMatrix4f");
ParamString::init_type("ParamString");
ParamTypedRefCount::init_type();
ParamValueBase::init_type();
ParamVecBase2d::init_type("ParamVecBase2d");
ParamVecBase2f::init_type("ParamVecBase2f");
ParamVecBase2i::init_type("ParamVecBase2i");
ParamVecBase3d::init_type("ParamVecBase3d");
ParamVecBase3f::init_type("ParamVecBase3f");
ParamVecBase3i::init_type("ParamVecBase3i");
ParamVecBase4f::init_type("ParamVecBase4f");
ParamVecBase4d::init_type("ParamVecBase4d");
ParamVecBase4i::init_type("ParamVecBase4i");
ParamWstring::init_type("ParamWstring");
#ifdef HAVE_PYTHON
PythonCallbackObject::init_type();
#endif
@ -218,4 +234,19 @@ init_libputil() {
BamCacheIndex::register_with_read_factory();
BamCacheRecord::register_with_read_factory();
ParamMatrix3d::register_with_read_factory();
ParamMatrix3f::register_with_read_factory();
ParamMatrix4d::register_with_read_factory();
ParamMatrix4f::register_with_read_factory();
ParamString::register_with_read_factory();
ParamVecBase2d::register_with_read_factory();
ParamVecBase2f::register_with_read_factory();
ParamVecBase2i::register_with_read_factory();
ParamVecBase3d::register_with_read_factory();
ParamVecBase3f::register_with_read_factory();
ParamVecBase3i::register_with_read_factory();
ParamVecBase4d::register_with_read_factory();
ParamVecBase4f::register_with_read_factory();
ParamVecBase4i::register_with_read_factory();
ParamWstring::register_with_read_factory();
}

View File

@ -12,6 +12,7 @@
#include "mouseData.cxx"
#include "nameUniquifier.cxx"
#include "nodeCachedReferenceCount.cxx"
#include "paramValue.cxx"
#include "pbitops.cxx"
#include "pta_ushort.cxx"
#include "pythonCallbackObject.cxx"

View File

@ -0,0 +1,209 @@
// Filename: paramValue.I
// Created by: drose (08Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
template<class Type>
TypeHandle ParamValue<Type>::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ParamValueBase::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE ParamValueBase::
ParamValueBase() {
}
////////////////////////////////////////////////////////////////////
// Function: ParamValueBase::get_value_type
// Access: Published, Virtual
// Description: Returns the type of the underlying value.
////////////////////////////////////////////////////////////////////
INLINE TypeHandle ParamValueBase::
get_value_type() const {
return TypeHandle::none();
}
////////////////////////////////////////////////////////////////////
// Function: ParamTypedRefCount::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE ParamTypedRefCount::
ParamTypedRefCount(const TypedReferenceCount *value) :
_value((TypedReferenceCount *)value)
{
}
////////////////////////////////////////////////////////////////////
// Function: ParamTypedRefCount::get_value_type
// Access: Published
// Description: Retrieves the type of the value stored in the
// parameter.
////////////////////////////////////////////////////////////////////
INLINE TypeHandle ParamTypedRefCount::
get_value_type() const {
if (_value == NULL) {
return TypeHandle::none();
} else {
return _value->get_type();
}
}
////////////////////////////////////////////////////////////////////
// Function: ParamTypedRefCount::get_value
// Access: Published
// Description: Retrieves the value stored in the parameter.
////////////////////////////////////////////////////////////////////
INLINE TypedReferenceCount *ParamTypedRefCount::
get_value() const {
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::Constructor
// Access: Protected
// Description:
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE ParamValue<Type>::
ParamValue() {}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE ParamValue<Type>::
ParamValue(const Type &value) :
_value(value)
{
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE ParamValue<Type>::
~ParamValue() {
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::get_value_type
// Access: Public, Virtual
// Description: Retrieves the type of the value stored in the
// parameter.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE TypeHandle ParamValue<Type>::
get_value_type() const {
return get_type_handle(Type);
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::set_value
// Access: Public, Virtual
// Description: Changes the value stored in the parameter.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE void ParamValue<Type>::
set_value(const Type &type) {
_value = type;
mark_bam_modified();
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::get_value
// Access: Public
// Description: Retrieves the value stored in the parameter.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE const Type &ParamValue<Type>::
get_value() const {
return _value;
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::output
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE void ParamValue<Type>::
output(ostream &out) const {
out << _value;
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::register_with_read_factory
// Access: Public, Static
// Description: Tells the BamReader how to create objects of type
// ParamValue.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE void ParamValue<Type>::
register_with_read_factory() {
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::write_datagram
// Access: Public, Virtual
// Description: Writes the contents of this object to the datagram
// for shipping out to a Bam file.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE void ParamValue<Type>::
write_datagram(BamWriter *manager, Datagram &dg) {
TypedWritable::write_datagram(manager, dg);
generic_write_datagram(dg, _value);
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::make_from_bam
// Access: Protected, Static
// Description: This function is called by the BamReader's factory
// when a new object of type ParamValue is encountered
// in the Bam file. It should create the ParamValue
// and extract its information from the file.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE TypedWritable *ParamValue<Type>::
make_from_bam(const FactoryParams &params) {
ParamValue<Type> *esv = new ParamValue<Type>;
DatagramIterator scan;
BamReader *manager;
parse_params(params, scan, manager);
esv->fillin(scan, manager);
return esv;
}
////////////////////////////////////////////////////////////////////
// Function: ParamValue::fillin
// Access: Protected
// Description: This internal function is called by make_from_bam to
// read in all of the relevant data from the BamFile for
// the new ParamValue.
////////////////////////////////////////////////////////////////////
template<class Type>
INLINE void ParamValue<Type>::
fillin(DatagramIterator &scan, BamReader *manager) {
TypedWritable::fillin(scan, manager);
generic_read_datagram(_value, scan);
}

View File

@ -0,0 +1,57 @@
// Filename: paramValue.cxx
// Created by: drose (08Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#include "paramValue.h"
#include "dcast.h"
// Tell GCC that we'll take care of the instantiation explicitly here.
#ifdef __GNUC__
#pragma implementation
#endif
TypeHandle ParamValueBase::_type_handle;
TypeHandle ParamTypedRefCount::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ParamValueBase::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
ParamValueBase::
~ParamValueBase() {
}
////////////////////////////////////////////////////////////////////
// Function: ParamTypedRefCount::Destructor
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
ParamTypedRefCount::
~ParamTypedRefCount() {
}
////////////////////////////////////////////////////////////////////
// Function: ParamTypedRefCount::output
// Access: Published, Virtual
// Description:
////////////////////////////////////////////////////////////////////
void ParamTypedRefCount::
output(ostream &out) const {
if (_value == (TypedReferenceCount *)NULL) {
out << "(empty)";
} else {
out << _value->get_type();
}
}

View File

@ -0,0 +1,221 @@
// Filename: paramValue.h
// Created by: drose (08Feb99)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
#ifndef PARAMVALUE_H
#define PARAMVALUE_H
#include "pandabase.h"
#include "typedef.h"
#include "typedObject.h"
#include "typedWritableReferenceCount.h"
#include "pointerTo.h"
#include "bamReader.h"
#include "bamWriter.h"
#include "luse.h"
////////////////////////////////////////////////////////////////////
// Class : ParamValueBase
// Description : A non-template base class of ParamValue (below),
// which serves mainly to define the placeholder for the
// virtual output function.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PUTIL ParamValueBase : public TypedWritableReferenceCount {
public:
INLINE ParamValueBase();
PUBLISHED:
virtual ~ParamValueBase();
INLINE virtual TypeHandle get_value_type() const;
virtual void output(ostream &out) const=0;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedWritableReferenceCount::init_type();
register_type(_type_handle, "ParamValueBase",
TypedWritableReferenceCount::get_class_type());
}
private:
static TypeHandle _type_handle;
};
////////////////////////////////////////////////////////////////////
// Class : ParamTypedRefCount
// Description : A class object for storing specifically objects of
// type TypedReferenceCount, which is different than
// TypedWritableReferenceCount.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_PUTIL ParamTypedRefCount : public ParamValueBase {
PUBLISHED:
INLINE ParamTypedRefCount(const TypedReferenceCount *value);
virtual ~ParamTypedRefCount();
INLINE virtual TypeHandle get_value_type() const;
INLINE TypedReferenceCount *get_value() const;
virtual void output(ostream &out) const;
private:
PT(TypedReferenceCount) _value;
public:
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
ParamValueBase::init_type();
register_type(_type_handle, "ParamTypedRefCount",
ParamValueBase::get_class_type());
}
private:
static TypeHandle _type_handle;
};
////////////////////////////////////////////////////////////////////
// Class : ParamValue
// Description : A handy class object for storing simple values (like
// integers or strings) passed along with an Event
// or to be used as a shader input.
// This is essentially just a wrapper around whatever
// data type you like, to make it a
// TypedWritableReferenceCount object which can be
// passed along inside an EventParameter or ShaderInput.
////////////////////////////////////////////////////////////////////
template<class Type>
class ParamValue : public ParamValueBase {
protected:
INLINE ParamValue();
PUBLISHED:
INLINE ParamValue(const Type &value);
INLINE virtual ~ParamValue();
INLINE virtual TypeHandle get_value_type() const;
INLINE void set_value(const Type &value);
INLINE const Type &get_value() const;
INLINE virtual void output(ostream &out) const;
private:
Type _value;
public:
INLINE static void register_with_read_factory();
INLINE virtual void write_datagram(BamWriter *manager, Datagram &dg);
protected:
INLINE static TypedWritable *make_from_bam(const FactoryParams &params);
INLINE void fillin(DatagramIterator &scan, BamReader *manager);
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type(const string &type_name = "UndefinedParamValue") {
ParamValueBase::init_type();
_type_handle = register_dynamic_type
(type_name, ParamValueBase::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();
}
virtual TypeHandle force_init_type() {
// In this case, we can't do anything, since we don't have the
// class' type_name.
return get_class_type();
}
private:
static TypeHandle _type_handle;
};
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<std::string>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<std::wstring>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase2d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase2f>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase2i>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase3d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase3f>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase3i>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase4d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase4f>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LVecBase4i>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LMatrix3d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LMatrix3f>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LMatrix4d>);
EXPORT_TEMPLATE_CLASS(EXPCL_PANDA_PUTIL, EXPTP_PANDA_PUTIL, ParamValue<LMatrix4f>);
typedef ParamValue<string> ParamString;
typedef ParamValue<wstring> ParamWstring;
typedef ParamValue<LVecBase2d> ParamVecBase2d;
typedef ParamValue<LVecBase2f> ParamVecBase2f;
typedef ParamValue<LVecBase2i> ParamVecBase2i;
typedef ParamValue<LVecBase3d> ParamVecBase3d;
typedef ParamValue<LVecBase3f> ParamVecBase3f;
typedef ParamValue<LVecBase3i> ParamVecBase3i;
typedef ParamValue<LVecBase4d> ParamVecBase4d;
typedef ParamValue<LVecBase4f> ParamVecBase4f;
typedef ParamValue<LVecBase4i> ParamVecBase4i;
typedef ParamValue<LMatrix3d> ParamMatrix3d;
typedef ParamValue<LMatrix3f> ParamMatrix3f;
typedef ParamValue<LMatrix4d> ParamMatrix4d;
typedef ParamValue<LMatrix4f> ParamMatrix4f;
#ifdef STDFLOAT_DOUBLE
typedef ParamVecBase2d ParamVecBase2;
typedef ParamVecBase3d ParamVecBase3;
typedef ParamVecBase4d ParamVecBase4;
typedef ParamMatrix3d ParamMatrix3;
typedef ParamMatrix4d ParamMatrix4;
#else
typedef ParamVecBase2f ParamVecBase2;
typedef ParamVecBase3f ParamVecBase3;
typedef ParamVecBase4f ParamVecBase4;
typedef ParamMatrix3f ParamMatrix3;
typedef ParamMatrix4f ParamMatrix4;
#endif
#include "paramValue.I"
// Tell GCC that we'll take care of the instantiation explicitly here.
#ifdef __GNUC__
#pragma interface
#endif
#endif

View File

@ -267,8 +267,7 @@ get_highest_on_bit(PN_uint64 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_next_higher_bit(PN_uint16 x) {
PN_uint16 w = flood_bits_down(x);
return count_bits_in_word(w);
return get_highest_on_bit(x) + 1;
}
////////////////////////////////////////////////////////////////////
@ -280,8 +279,7 @@ get_next_higher_bit(PN_uint16 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_next_higher_bit(PN_uint32 x) {
PN_uint32 w = flood_bits_down(x);
return count_bits_in_word(w);
return get_highest_on_bit(x) + 1;
}
////////////////////////////////////////////////////////////////////
@ -293,6 +291,5 @@ get_next_higher_bit(PN_uint32 x) {
////////////////////////////////////////////////////////////////////
INLINE int
get_next_higher_bit(PN_uint64 x) {
PN_uint64 w = flood_bits_down(x);
return count_bits_in_word(w);
return get_highest_on_bit(x) + 1;
}

View File

@ -223,7 +223,7 @@ operator ++ () {
#else
_seq = new_seq;
#endif // HAVE_THREADS
return *this;
}
@ -284,15 +284,15 @@ INLINE void UpdateSeq::
output(ostream &out) const {
AtomicAdjust::Integer seq = AtomicAdjust::get(_seq);
switch (seq) {
case SC_initial:
case (AtomicAdjust::Integer)SC_initial:
out << "initial";
break;
case SC_old:
case (AtomicAdjust::Integer)SC_old:
out << "old";
break;
case SC_fresh:
case (AtomicAdjust::Integer)SC_fresh:
out << "fresh";
break;

Some files were not shown because too many files have changed in this diff Show More