Merge remote-tracking branch 'upstream/master' into cmake

Conflicts:
	panda/src/linmath/lvecBase4.h
This commit is contained in:
Sam Edwards 2014-07-24 22:59:52 -07:00
commit 3d0f587ca0
255 changed files with 12092 additions and 6532 deletions

View File

@ -1,3 +1,4 @@
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#ifdef _WIN32
@ -105,7 +106,7 @@ py_extend_frozen_modules(PyObject *self, PyObject *args) {
PyObject *tuple;
const char *name;
const char *code;
int size;
Py_ssize_t size;
tuple = PySequence_GetItem(list, i);
if (!PyArg_ParseTuple(tuple, "ss#", &name, &code, &size)) {
@ -178,7 +179,7 @@ py_get_frozen_module_code(PyObject *self, PyObject *args) {
if (strcmp(PyImport_FrozenModules[i].name, name) == 0) {
int is_package = (PyImport_FrozenModules[i].size < 0);
return Py_BuildValue("(s#i)", PyImport_FrozenModules[i].code,
abs(PyImport_FrozenModules[i].size),
(Py_ssize_t) abs(PyImport_FrozenModules[i].size),
is_package);
}
++i;

View File

@ -653,40 +653,6 @@
// space (instead of a dot). Thus, "1 1" means OpenGL version 1.1.
#define MIN_GL_VERSION 1 1
// Is Mesa installed separately from OpenGL? Mesa is an open-source
// software-only OpenGL renderer. Panda can link with it
// independently from OpenGL (and if Mesa is built statically, and/or
// with -DUSE_MGL_NAMESPACE declared to rename gl* to mgl*, it can
// switch between the system OpenGL implementation and the Mesa
// implementation at runtime).
// Also, Mesa includes some core libraries (in libOSMesa.so) that
// allow totally headless rendering, handy if you want to run a
// renderer as a batch service, and you don't want to insist that a
// user be logged on to the desktop or otherwise deal with X11 or
// Windows.
// If you define HAVE_MESA here, and the appropriate paths to headers
// and libraries, then Panda will build libmesadisplay, which can be
// used in lieu of libpandagl or libpandadx to do rendering. However,
// for most applications, you don't need to do this, since (a) if you
// have hardware rendering capability, you probably don't want to use
// Mesa, since it's software-only, and (b) if you don't have hardware
// rendering, you can install Mesa as the system's OpenGL
// implementation, so you can just use the normal libpandagl. You
// only need to define HAVE_MESA if you want to run totally headless,
// or if you want to be able to easily switch between Mesa and the
// system OpenGL implementation at runtime. If you compiled Mesa with
// USE_MGL_NAMESPACE defined, define MESA_MGL here.
#define MESA_IPATH
#define MESA_LPATH
#define MESA_LIBS
#define MESA_MGL
#defer HAVE_MESA $[libtest $[MESA_LPATH],$[MESA_LIBS]]
// Similar to MIN_GL_VERSION, above.
#define MIN_MESA_VERSION 1 1
// Do you want to build tinydisplay, a light and fast software
// renderer built into Panda, based on TinyGL? This isn't as
// full-featured as Mesa, but it is many times faster, and in fact

View File

@ -176,11 +176,6 @@
#else
#print - Did not find X11
#endif
#if $[HAVE_MESA]
#print + Mesa
#else
#print - Did not find Mesa
#endif
#if $[HAVE_OPENCV]
#print + OpenCV
#else
@ -437,14 +432,6 @@ $[cdefine HAVE_ODE]
/* Define if we have AWESOMIUM installed and want to build for AWESOMIUM. */
$[cdefine HAVE_AWESOMIUM]
/* Define if we have Mesa installed and want to build mesadisplay. */
$[cdefine HAVE_MESA]
$[cdefine MESA_MGL]
#if HAVE_MESA
# define MIN_MESA_VERSION_MAJOR $[word 1,$[MIN_MESA_VERSION]]
# define MIN_MESA_VERSION_MINOR $[word 2,$[MIN_MESA_VERSION]]
#endif
/* Define if we have GLX installed and want to build for GLX. */
$[cdefine HAVE_GLX]

View File

@ -236,12 +236,6 @@
#set GLES2_LIBS $[GLES2_LIBS]
#set HAVE_GLES2 $[HAVE_GLES2]
#set MESA_IPATH $[unixfilename $[MESA_IPATH]]
#set MESA_LPATH $[unixfilename $[MESA_LPATH]]
#set MESA_LIBS $[MESA_LIBS]
#set MESA_MGL $[MESA_MGL]
#set HAVE_MESA $[HAVE_MESA]
#set GLX_IPATH $[unixfilename $[GLX_IPATH]]
#set GLX_LPATH $[unixfilename $[GLX_LPATH]]
#set HAVE_GLX $[HAVE_GLX]

View File

@ -185,13 +185,6 @@
#define xcursor_libs $[XCURSOR_LIBS]
#endif
#if $[HAVE_MESA]
#define mesa_ipath $[wildcard $[MESA_IPATH]]
#define mesa_lpath $[wildcard $[MESA_LPATH]]
#define mesa_cflags $[MESA_CFLAGS]
#define mesa_libs $[MESA_LIBS]
#endif
#if $[HAVE_GLX]
#define glx_ipath $[wildcard $[GLX_IPATH]]
#define glx_lpath $[wildcard $[GLX_LPATH]]

View File

@ -23,7 +23,7 @@
#include "atomicAdjustDummyImpl.h"
typedef AtomicAdjustDummyImpl AtomicAdjust;
#elif defined(__i386__) || defined(_M_IX86)
#elif defined(__i386__) || defined(_M_IX86)
// For an i386 architecture, we'll always use the i386 implementation.
// It should be safe for any OS, and it might be a bit faster than
// any OS-provided calls.
@ -39,6 +39,15 @@ typedef AtomicAdjustI386Impl AtomicAdjust;
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
// GCC 4.7 and above has built-in __atomic functions for atomic operations.
#include "atomicAdjustGccImpl.h"
typedef AtomicAdjustGccImpl AtomicAdjust;
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE 1
#define HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR 1
#elif defined(THREAD_WIN32_IMPL)
#include "atomicAdjustWin32Impl.h"

View File

@ -0,0 +1,148 @@
// Filename: atomicAdjustGccImpl.I
// Created by: rdb (04Jul14)
//
////////////////////////////////////////////////////////////////////
//
// 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: AtomicAdjustGccImpl::inc
// Access: Public, Static
// Description: Atomically increments the indicated variable.
////////////////////////////////////////////////////////////////////
INLINE void AtomicAdjustGccImpl::
inc(TVOLATILE AtomicAdjustGccImpl::Integer &var) {
__atomic_fetch_add(&var, 1, __ATOMIC_SEQ_CST);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::dec
// Access: Public, Static
// Description: Atomically decrements the indicated variable and
// returns true if the new value is nonzero, false if it
// is zero.
////////////////////////////////////////////////////////////////////
INLINE bool AtomicAdjustGccImpl::
dec(TVOLATILE AtomicAdjustGccImpl::Integer &var) {
return (__atomic_sub_fetch(&var, 1, __ATOMIC_SEQ_CST) != 0);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::add
// Access: Public, Static
// Description: Atomically computes var += delta. It is legal for
// delta to be negative.
////////////////////////////////////////////////////////////////////
INLINE void AtomicAdjustGccImpl::
add(TVOLATILE AtomicAdjustGccImpl::Integer &var,
AtomicAdjustGccImpl::Integer delta) {
__atomic_fetch_add(&var, delta, __ATOMIC_SEQ_CST);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::set
// Access: Public, Static
// Description: Atomically changes the indicated variable and
// returns the original value.
////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustGccImpl::Integer AtomicAdjustGccImpl::
set(TVOLATILE AtomicAdjustGccImpl::Integer &var,
AtomicAdjustGccImpl::Integer new_value) {
return __atomic_exchange_n(&var, new_value, __ATOMIC_SEQ_CST);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::get
// Access: Public, Static
// Description: Atomically retrieves the snapshot value of the
// indicated variable. This is the only guaranteed safe
// way to retrieve the value that other threads might be
// asynchronously setting, incrementing, or decrementing
// (via other AtomicAjust methods).
////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustGccImpl::Integer AtomicAdjustGccImpl::
get(const TVOLATILE AtomicAdjustGccImpl::Integer &var) {
return __atomic_load_n(&var, __ATOMIC_SEQ_CST);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::set_ptr
// Access: Public, Static
// Description: Atomically changes the indicated variable and
// returns the original value.
////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustGccImpl::Pointer AtomicAdjustGccImpl::
set_ptr(TVOLATILE AtomicAdjustGccImpl::Pointer &var,
AtomicAdjustGccImpl::Pointer new_value) {
return __atomic_exchange_n(&var, new_value, __ATOMIC_SEQ_CST);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::get_ptr
// Access: Public, Static
// Description: Atomically retrieves the snapshot value of the
// indicated variable. This is the only guaranteed safe
// way to retrieve the value that other threads might be
// asynchronously setting, incrementing, or decrementing
// (via other AtomicAjust methods).
////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustGccImpl::Pointer AtomicAdjustGccImpl::
get_ptr(const TVOLATILE AtomicAdjustGccImpl::Pointer &var) {
return __atomic_load_n(&var, __ATOMIC_SEQ_CST);
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::compare_and_exchange
// Access: Public, Static
// Description: Atomic compare and exchange.
//
// If mem is equal to old_value, store new_value in mem.
// In either case, return the original value of mem.
// The caller can test for success by comparing
// return_value == old_value.
//
// The atomic function expressed in pseudo-code:
//
// orig_value = mem;
// if (mem == old_value) {
// mem = new_value;
// }
// return orig_value;
//
////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustGccImpl::Integer AtomicAdjustGccImpl::
compare_and_exchange(TVOLATILE AtomicAdjustGccImpl::Integer &mem,
AtomicAdjustGccImpl::Integer old_value,
AtomicAdjustGccImpl::Integer new_value) {
__atomic_compare_exchange_n(&mem, &old_value, new_value, false,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return old_value;
}
////////////////////////////////////////////////////////////////////
// Function: AtomicAdjustGccImpl::compare_and_exchange_ptr
// Access: Public, Static
// Description: Atomic compare and exchange.
//
// As above, but works on pointers instead of integers.
////////////////////////////////////////////////////////////////////
INLINE AtomicAdjustGccImpl::Pointer AtomicAdjustGccImpl::
compare_and_exchange_ptr(TVOLATILE AtomicAdjustGccImpl::Pointer &mem,
AtomicAdjustGccImpl::Pointer old_value,
AtomicAdjustGccImpl::Pointer new_value) {
__atomic_compare_exchange_n(&mem, &old_value, new_value, false,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
return old_value;
}

View File

@ -0,0 +1,60 @@
// Filename: atomicAdjustGccImpl.h
// Created by: rdb (04Jul14)
//
////////////////////////////////////////////////////////////////////
//
// 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 ATOMICADJUSTGCCIMPL_H
#define ATOMICADJUSTGCCIMPL_H
#include "dtoolbase.h"
#include "selectThreadImpl.h"
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
////////////////////////////////////////////////////////////////////
// Class : AtomicAdjustGccImpl
// Description : Uses GCC built-ins to implement atomic adjustments.
////////////////////////////////////////////////////////////////////
class EXPCL_DTOOL AtomicAdjustGccImpl {
public:
#if __GCC_ATOMIC_LONG_LOCK_FREE > __GCC_ATOMIC_INT_LOCK_FREE
// If the long can be more lock-free than int, use it instead.
typedef __attribute__ ((aligned (__SIZEOF_LONG__))) long Integer;
#else
typedef __attribute__ ((aligned (__SIZEOF_INT__))) int Integer;
#endif
typedef void *UnalignedPointer;
typedef __attribute__ ((aligned (__SIZEOF_POINTER__))) UnalignedPointer Pointer;
INLINE static void inc(TVOLATILE Integer &var);
INLINE static bool dec(TVOLATILE Integer &var);
INLINE static void add(TVOLATILE Integer &var, Integer delta);
INLINE static Integer set(TVOLATILE Integer &var, Integer new_value);
INLINE static Integer get(const TVOLATILE Integer &var);
INLINE static Pointer set_ptr(TVOLATILE Pointer &var, Pointer new_value);
INLINE static Pointer get_ptr(const TVOLATILE Pointer &var);
INLINE static Integer compare_and_exchange(TVOLATILE Integer &mem,
Integer old_value,
Integer new_value);
INLINE static Pointer compare_and_exchange_ptr(TVOLATILE Pointer &mem,
Pointer old_value,
Pointer new_value);
};
#include "atomicAdjustGccImpl.I"
#endif // HAVE_POSIX_THREADS
#endif

View File

@ -336,6 +336,28 @@ cpow(double x, double y) {
return pow(x, y);
}
////////////////////////////////////////////////////////////////////
// Function: cpow
// Description:
////////////////////////////////////////////////////////////////////
INLINE int
cpow(int x, int y) {
int result = 1;
if (y >= 0) {
for(; y > 0; --y) {
result *= x;
}
return result;
} else {
for(; y < 0; ++y) {
result *= x;
}
return 1 / result;
}
}
////////////////////////////////////////////////////////////////////
// Function: cnan
// Description:
@ -343,7 +365,7 @@ cpow(double x, double y) {
INLINE bool
cnan(double v) {
#ifndef _WIN32
return (isnan(v) != 0);
return (std::isnan(v) != 0);
#else
return (_isnan(v) != 0);
#endif

View File

@ -23,7 +23,7 @@
#include "dtoolbase.h"
#include <math.h>
#include <cmath>
// Windows defines isnan() in a different place and with a different
// name than everyone else. Sheesh.
@ -62,6 +62,8 @@ INLINE double cacos(double v);
INLINE double cmod(double x, double y);
INLINE double cpow(double x, double y);
INLINE int cpow(int x, int y);
// Returns true if the number is NaN, false if it's a genuine number
// or infinity.
INLINE bool cnan(double v);

View File

@ -33,6 +33,7 @@ using namespace std;
#define INLINE inline
#define TYPENAME typename
#define CONSTEXPR
#define EXPORT_TEMPLATE_CLASS(expcl, exptp, classname)
@ -119,6 +120,16 @@ typedef ios::seekdir ios_seekdir;
#define INLINE inline
#endif
#if defined(__has_extension) // Clang magic.
#if __has_extension(cxx_constexpr)
#define CONSTEXPR constexpr
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && (__cplusplus >= 201103L)
#define CONSTEXPR constexpr
#else
#define CONSTEXPR INLINE
#endif
#if defined(WIN32_VC) && !defined(LINK_ALL_STATIC) && defined(EXPORT_TEMPLATES)
// This macro must be used to export an instantiated template class
// from a DLL. If the template class name itself contains commas, it

View File

@ -35,6 +35,13 @@ get_nearly_zero_value(float) {
return 1.0e-6f;
}
INLINE 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.
return 0;
}
// IS_THRESHOLD_ZERO(value, threshold) returns true if the value is
// within threshold of zero.
@ -73,7 +80,7 @@ get_nearly_zero_value(float) {
// MAYBE_ZERO(value) returns 0 if the value is nearly zero, and the
// value itself otherwise.
#define MAYBE_ZERO(value) \
(IS_NEARLY_ZERO(value) ? 0.0 : (value))
(IS_NEARLY_ZERO(value) ? 0 : (value))
#endif

View File

@ -26,6 +26,7 @@ TypeHandle bool_type_handle;
TypeHandle double_type_handle;
TypeHandle float_type_handle;
TypeHandle string_type_handle;
TypeHandle wstring_type_handle;
TypeHandle long_p_type_handle;
TypeHandle int_p_type_handle;
@ -58,6 +59,7 @@ void init_system_type_handles() {
register_type(double_type_handle, "double");
register_type(float_type_handle, "float");
register_type(string_type_handle, "string");
register_type(wstring_type_handle, "wstring");
register_type(int_p_type_handle, "int*");
register_type(short_p_type_handle, "short*");
@ -75,5 +77,3 @@ void init_system_type_handles() {
register_type(pset_type_handle, "pset");
}
}

View File

@ -92,6 +92,7 @@ extern TypeHandle EXPCL_DTOOL bool_type_handle;
extern TypeHandle EXPCL_DTOOL double_type_handle;
extern TypeHandle EXPCL_DTOOL float_type_handle;
extern TypeHandle EXPCL_DTOOL string_type_handle;
extern TypeHandle EXPCL_DTOOL wstring_type_handle;
extern TypeHandle long_p_type_handle;
extern TypeHandle int_p_type_handle;
@ -175,6 +176,11 @@ INLINE TypeHandle _get_type_handle(const string *) {
return string_type_handle;
}
template<>
INLINE TypeHandle _get_type_handle(const wstring *) {
return wstring_type_handle;
}
template<>
INLINE TypeHandle _get_type_handle(const long * const *) {
return long_p_type_handle;

View File

@ -16,6 +16,10 @@
#include "typeRegistryNode.h"
#include "atomicAdjust.h"
#ifdef HAVE_PYTHON
#include "Python.h"
#endif
// This is initialized to zero by static initialization.
TypeHandle TypeHandle::_none;

View File

@ -66,7 +66,10 @@
class TypedObject;
#ifdef HAVE_PYTHON
#include "Python.h"
#ifndef PyObject_HEAD
struct _object;
typedef _object PyObject;
#endif
#endif
////////////////////////////////////////////////////////////////////
@ -127,15 +130,15 @@ PUBLISHED:
INLINE TypeHandle get_parent_towards(TypeHandle ancestor,
TypedObject *object = (TypedObject *)NULL) const;
INLINE int get_best_parent_from_Set(const std::set< int > &legal_vals) const;
INLINE int get_best_parent_from_Set(const std::set< int > &legal_vals) const;
#ifdef DO_MEMORY_USAGE
int get_memory_usage(MemoryClass memory_class) const;
void inc_memory_usage(MemoryClass memory_class, int size);
void dec_memory_usage(MemoryClass memory_class, int size);
#else
INLINE int get_memory_usage(MemoryClass) const { return 0; }
CONSTEXPR int get_memory_usage(MemoryClass) const { return 0; }
INLINE void inc_memory_usage(MemoryClass, int) { }
INLINE void dec_memory_usage(MemoryClass, int) { }
#endif // DO_MEMORY_USAGE
@ -170,4 +173,3 @@ EXPCL_DTOOL ostream &operator << (ostream &out, TypeHandle::MemoryClass mem_clas
#include "typeHandle.I"
#endif

View File

@ -58,9 +58,11 @@ PUBLISHED:
int get_num_typehandles();
TypeHandle get_typehandle(int n);
MAKE_SEQ(get_typehandles, get_num_typehandles, get_typehandle);
int get_num_root_classes();
TypeHandle get_root_class(int n);
MAKE_SEQ(get_root_classes, get_num_root_classes, get_root_class);
int get_num_parent_classes(TypeHandle child,
TypedObject *child_object) const;

View File

@ -50,6 +50,7 @@ FunctionRemap(const InterrogateType &itype, const InterrogateFunction &ifunc,
_num_default_parameters = num_default_parameters;
_type = T_normal;
_flags = 0;
_args_type = 0;
_wrapper_index = 0;
_return_value_needs_management = false;
@ -303,26 +304,6 @@ make_wrapper_entry(FunctionIndex function_index) {
assert(!iwrapper._parameters.empty());
iwrapper._parameters.front()._parameter_flags |=
InterrogateFunctionWrapper::PF_is_this;
if (_parameters.size() >= 2 && _parameters[1]._name == "self" &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type())) {
// Here's a special case. If the first parameter of a nonstatic
// method is a PyObject * called "self", then we will
// automatically fill it in from the this pointer, and remove it
// from the generated parameter list.
_parameters.erase(_parameters.begin() + 1);
_flags |= F_explicit_self;
}
} else if (_type == T_constructor) {
// We also allow "self" to be passed in to a constructor, even
// though the constructor doesn't normally accept a this pointer.
// But this makes sense to Python programmers.
if (_parameters.size() >= 1 && _parameters[0]._name == "self" &&
TypeManager::is_pointer_to_PyObject(_parameters[0]._remap->get_orig_type())) {
_parameters.erase(_parameters.begin() + 0);
_flags |= F_explicit_self;
}
}
if (!_void_return) {
@ -650,12 +631,32 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
}
// Check for a special meaning by name and signature.
if (_type == T_normal) {
int first_param = 0;
if (_has_this) {
first_param = 1;
}
int first_param = 0;
if (_has_this) {
first_param = 1;
}
if (_has_this || _type == T_constructor) {
if (_parameters.size() > first_param && _parameters[first_param]._name == "self" &&
TypeManager::is_pointer_to_PyObject(_parameters[first_param]._remap->get_orig_type())) {
// Here's a special case. If the first parameter of a nonstatic
// method is a PyObject * called "self", then we will
// automatically fill it in from the this pointer, and remove it
// from the generated parameter list.
_parameters.erase(_parameters.begin() + first_param);
_flags |= F_explicit_self;
}
}
if (_parameters.size() == first_param) {
_args_type = InterfaceMaker::AT_no_args;
} else if (_parameters.size() == first_param + 1) {
_args_type = InterfaceMaker::AT_single_arg;
} else {
_args_type = InterfaceMaker::AT_varargs;
}
if (_type == T_normal) {
if (fname == "operator []" || fname == "__getitem__") {
_flags |= F_getitem;
if (_has_this && _parameters.size() == 2) {
@ -671,6 +672,7 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
if (TypeManager::is_integer(_parameters[1]._remap->get_new_type())) {
// Its first parameter is an int parameter, presumably an index.
_flags |= F_setitem_int;
_args_type = InterfaceMaker::AT_varargs;
}
}
@ -681,55 +683,69 @@ setup_properties(const InterrogateFunction &ifunc, InterfaceMaker *interface_mak
_flags |= F_size;
}
} else if (fname == "make_copy" ) {
} else if (fname == "make_copy") {
if (_has_this && _parameters.size() == 1 &&
TypeManager::is_pointer(_return_type->get_new_type())) {
// It receives no parameters, and returns a pointer.
_flags |= F_make_copy;
}
} else if (fname == "__iter__" ) {
} else if (fname == "__iter__") {
if (_has_this && _parameters.size() == 1 &&
TypeManager::is_pointer(_return_type->get_new_type())) {
// It receives no parameters, and returns a pointer.
_flags |= F_iter;
}
} else if (fname == "__getbuffer__" ) {
if (_has_this && _parameters.size() == 4 &&
} else if (fname == "__getbuffer__") {
if (_has_this && _parameters.size() == 3 &&
TypeManager::is_integer(_return_type->get_new_type()) &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_pointer_to_Py_buffer(_parameters[2]._remap->get_orig_type()) &&
TypeManager::is_integer(_parameters[3]._remap->get_orig_type())) {
TypeManager::is_pointer_to_Py_buffer(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_integer(_parameters[2]._remap->get_orig_type())) {
_flags |= F_getbuffer;
}
} else if (fname == "__releasebuffer__" ) {
if (_has_this && _parameters.size() == 3 &&
TypeManager::is_pointer_to_PyObject(_parameters[1]._remap->get_orig_type()) &&
TypeManager::is_pointer_to_Py_buffer(_parameters[2]._remap->get_orig_type())) {
} else if (fname == "__releasebuffer__") {
if (_has_this && _parameters.size() == 2 &&
TypeManager::is_pointer_to_Py_buffer(_parameters[1]._remap->get_orig_type())) {
_flags |= F_releasebuffer;
}
} else if (fname == "compare_to" ) {
} else if (fname == "compare_to") {
if (_has_this && _parameters.size() == 2 &&
TypeManager::is_integer(_return_type->get_new_type())) {
// It receives one parameter, and returns an integer.
_flags |= F_compare_to;
}
} else if (fname == "operator ()" || fname == "__call__") {
// Call operators always take keyword arguments.
_args_type = InterfaceMaker::AT_keyword_args;
} else if (fname == "__setattr__" || fname == "__getattr__") {
// Just to prevent these from getting keyword arguments.
} else {
if (_args_type == InterfaceMaker::AT_varargs) {
// Every other method can take keyword arguments, if they
// take more than one argument.
_args_type = InterfaceMaker::AT_keyword_args;
}
}
} else if (_type == T_constructor) {
if (!_has_this && _parameters.size() == 1) {
if (TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
TypeManager::unwrap(_return_type->get_orig_type())) {
// If this is the only parameter, and it's the same as the
// "this" type, this is a copy constructor.
_flags |= F_copy_constructor;
}
if (!_has_this && _parameters.size() == 1 &&
TypeManager::unwrap(_parameters[0]._remap->get_orig_type()) ==
TypeManager::unwrap(_return_type->get_orig_type())) {
// If this is the only parameter, and it's the same as the
// "this" type, this is a copy constructor.
_flags |= F_copy_constructor;
}
// Constructors always take varargs and keyword args.
_args_type = InterfaceMaker::AT_keyword_args;
}
return true;

View File

@ -107,6 +107,7 @@ public:
int _num_default_parameters;
Type _type;
int _flags;
int _args_type;
string _expression;
string _function_signature;
string _hash;

View File

@ -57,6 +57,7 @@ Function(const string &name,
{
_has_this = false;
_flags = 0;
_args_type = AT_unknown;
}
////////////////////////////////////////////////////////////////////
@ -632,13 +633,13 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
CPPInstance *cppfunc = (*ii).second;
CPPFunctionType *ftype = cppfunc->_type->as_function_type();
int max_default_parameters = 0;
if (separate_overloading()) {
// Count up the number of default parameters this function might
// take.
CPPParameterList *parameters = ftype->_parameters;
CPPParameterList::Parameters::reverse_iterator pi;
for (pi = parameters->_parameters.rbegin();
for (pi = parameters->_parameters.rbegin();
pi != parameters->_parameters.rend();
++pi) {
CPPInstance *param = (*pi);
@ -651,7 +652,7 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
}
}
}
// Now make a different wrapper for each combination of default
// parameters. This will happen only if separate_overloading(),
// tested above, returned true; otherwise, max_default_parameters
@ -663,7 +664,7 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
make_function_remap(itype, ifunc, cppfunc, num_default_parameters);
if (remap != (FunctionRemap *)NULL) {
func->_remaps.push_back(remap);
// If *any* of the variants of this function has a "this"
// pointer, the entire set of functions is deemed to have a
// "this" pointer.
@ -672,9 +673,10 @@ record_function(const InterrogateType &itype, FunctionIndex func_index) {
}
func->_flags |= remap->_flags;
func->_args_type = (ArgsType)((int)func->_args_type | (int)remap->_args_type);
// Make a wrapper for the function.
FunctionWrapperIndex wrapper_index =
FunctionWrapperIndex wrapper_index =
remap->make_wrapper_entry(func_index);
if (wrapper_index != 0) {
InterrogateFunction &mod_ifunc = idb->update_function(func_index);

View File

@ -71,6 +71,28 @@ public:
static ostream &indent(ostream &out, int indent_level);
public:
// This contains information about the number
// of arguments that the wrapping function should take.
enum ArgsType {
// This is deliberately engineered such that these
// values can be OR'ed together to produce another
// valid enum value.
AT_unknown = 0x00,
// The method or function takes no arguments.
AT_no_args = 0x01,
// There is only a single argument.
AT_single_arg = 0x02,
// The method takes a variable number of arguments.
AT_varargs = 0x03,
// The method may take keyword arguments, if appropriate
// in the scripting language. Implies AT_varargs.
AT_keyword_args = 0x07,
};
class Function {
public:
Function(const string &name,
@ -85,6 +107,7 @@ public:
Remaps _remaps;
bool _has_this;
int _flags;
ArgsType _args_type;
};
typedef vector<Function *> Functions;
Functions _functions;

View File

@ -36,17 +36,12 @@ InterfaceMakerPython(InterrogateModuleDef *def) :
void InterfaceMakerPython::
write_includes(ostream &out) {
InterfaceMaker::write_includes(out);
out << "#undef HAVE_LONG_LONG\n"
<< "#undef _POSIX_C_SOURCE\n\n"
out << "#undef _POSIX_C_SOURCE\n\n"
<< "#if PYTHON_FRAMEWORK\n"
<< " #include \"Python/Python.h\"\n"
<< "#else\n"
<< " #include \"Python.h\"\n"
<< "#endif\n"
<< "#ifdef HAVE_LONG_LONG\n"
<< "#undef HAVE_LONG_LONG\n"
<< "#endif \n";
<< "#endif\n";
}
////////////////////////////////////////////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -27,8 +27,7 @@ class FunctionRemap;
// Description : An InterfaceMaker for generating complex Python
// function wrappers around C++ code.
////////////////////////////////////////////////////////////////////
class InterfaceMakerPythonNative : public InterfaceMakerPython
{
class InterfaceMakerPythonNative : public InterfaceMakerPython {
public:
InterfaceMakerPythonNative(InterrogateModuleDef *def);
virtual ~InterfaceMakerPythonNative();
@ -77,6 +76,8 @@ private:
WT_getbuffer,
WT_releasebuffer,
WT_iter_next,
WT_one_or_two_params,
WT_ternary_operator,
};
class SlottedFunctionDef {
@ -87,25 +88,28 @@ private:
};
static bool get_slotted_function_def(Object *obj, Function *func, SlottedFunctionDef &def);
void write_prototype_for_name(ostream &out, Function *func, const std::string &name);
void write_prototype_for(ostream &out, Function *func);
void write_function_for_name(ostream &out, Object *obj, Function *func, const std::string &name, const std::string &PreProcess, const std::string &ClassName,
bool coercion_allowed, bool &coercion_attempted);
void write_function_for_top(ostream &out, Object *obj, Function *func, const std::string &PreProcess);
void write_function_instance(ostream &out, Object *obj, Function *func,
FunctionRemap *remap, string &expected_params,
int indent_level, bool errors_fatal,
ostream &forwarddecl, const std::string &functionnamestr,
bool is_inplace, bool coercion_allowed,
bool &coercion_attempted,
const string &args_cleanup);
void write_function_for_top(ostream &out, Object *obj, Function *func);
void write_function_for_name(ostream &out, Object *obj, Function *func,
const std::string &name,
bool coercion_allowed, bool &coercion_attempted,
ArgsType args_type, bool return_int);
void write_function_forset(ostream &out, Object *obj, Function *func,
std::set<FunctionRemap*> &remaps, string &expected_params,
int indent_level, ostream &forwarddecl, bool inplace,
bool coercion_allowed, bool &coercion_attempted,
const string &args_cleanup);
int indent_level, bool inplace,
bool coercion_allowed, bool &coercion_attempted,
ArgsType args_type, bool return_int,
const string &first_expr = string());
void write_function_instance(ostream &out, Object *obj, Function *func,
FunctionRemap *remap, string &expected_params,
int indent_level, bool is_inplace,
bool coercion_allowed, bool &coercion_attempted,
ArgsType args_type, bool return_int,
const string &first_pexpr = string());
void pack_return_value(ostream &out, int indent_level, FunctionRemap *remap,
const std::string &return_expr, bool in_place);
@ -119,17 +123,16 @@ private:
void write_class_prototypes(ostream &out) ;
void write_class_declarations(ostream &out, ostream *out_h, Object *obj);
void write_class_details(ostream &out, Object *obj);
void do_assert_init(ostream &out, int &indent_level, bool constructor, const string &args_cleanup) const;
public:
bool is_remap_legal(FunctionRemap &remap);
bool is_remap_legal(FunctionRemap *remap);
bool is_function_legal( Function *func);
bool is_cpp_type_legal(CPPType *ctype);
bool isExportThisRun(CPPType *ctype);
bool isExportThisRun(Function *func);
bool isFunctionWithThis( Function *func);
bool IsRunTimeTyped(const InterrogateType &itype);
// comunicates the cast capabilites among methods..
struct CastDetails {
CPPStructType *_structType;

View File

@ -1863,26 +1863,34 @@ get_type(CPPType *type, bool global) {
// First, check to see if it's already there.
string true_name = type->get_local_name(&parser);
TypesByName::const_iterator tni = _types_by_name.find(true_name);
if (tni != _types_by_name.end()) {
// It's already here, so update the global flag.
index = (*tni).second;
if (index == 0) {
// This is an invalid type; we don't know anything about it.
return 0;
}
InterrogateType &itype = InterrogateDatabase::get_ptr()->update_type(index);
if (global) {
itype._flags |= InterrogateType::F_global;
}
if (true_name.empty()) {
// Whoops, it's an anonymous type. That's okay, because we'll
// usually only encounter them once anyway, so let's go ahead and
// define it without checking in _types_by_name.
if ((itype._flags & InterrogateType::F_fully_defined) != 0) {
return index;
}
} else {
TypesByName::const_iterator tni = _types_by_name.find(true_name);
if (tni != _types_by_name.end()) {
// It's already here, so update the global flag.
index = (*tni).second;
if (index == 0) {
// This is an invalid type; we don't know anything about it.
return 0;
}
// But wait--it's not fully defined yet! We'll go ahead and
// define it now.
InterrogateType &itype = InterrogateDatabase::get_ptr()->update_type(index);
if (global) {
itype._flags |= InterrogateType::F_global;
}
if ((itype._flags & InterrogateType::F_fully_defined) != 0) {
return index;
}
// But wait--it's not fully defined yet! We'll go ahead and
// define it now.
}
}
bool forced = in_forcetype(true_name);
@ -1890,7 +1898,9 @@ get_type(CPPType *type, bool global) {
if (index == 0) {
// It isn't already there, so we have to define it.
index = InterrogateDatabase::get_ptr()->get_next_index();
_types_by_name[true_name] = index;
if (!true_name.empty()) {
_types_by_name[true_name] = index;
}
InterrogateType itype;
if (global) {
@ -1904,7 +1914,7 @@ get_type(CPPType *type, bool global) {
InterrogateDatabase::get_ptr()->update_type(index);
itype._name = get_preferred_name(type);
int num_alt_names = type->get_num_alt_names();
if (num_alt_names != 0) {
itype._alt_names.clear();
@ -1954,23 +1964,19 @@ get_type(CPPType *type, bool global) {
}
}
if (forced || !in_ignoretype(true_name))
{
if (forced || !in_ignoretype(true_name)) {
itype._flags |= InterrogateType::F_fully_defined;
if (type->as_simple_type() != (CPPSimpleType *)NULL)
{
if (type->as_simple_type() != (CPPSimpleType *)NULL) {
define_atomic_type(itype, type->as_simple_type());
} else if (type->as_pointer_type() != (CPPPointerType *)NULL)
{
} else if (type->as_pointer_type() != (CPPPointerType *)NULL) {
define_wrapped_type(itype, type->as_pointer_type());
} else if (type->as_const_type() != (CPPConstType *)NULL) {
define_wrapped_type(itype, type->as_const_type());
} else if (type->as_struct_type() != (CPPStructType *)NULL)
{
} else if (type->as_struct_type() != (CPPStructType *)NULL) {
define_struct_type(itype, type->as_struct_type(), index, forced);
} else if (type->as_enum_type() != (CPPEnumType *)NULL) {
@ -1984,7 +1990,9 @@ get_type(CPPType *type, bool global) {
// Remove the type from the database.
InterrogateDatabase::get_ptr()->remove_type(index);
_types_by_name[true_name] = 0;
if (!true_name.empty()) {
_types_by_name[true_name] = 0;
}
index = 0;
}
}
@ -2229,6 +2237,7 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
for (di = scope->_declarations.begin();
di != scope->_declarations.end();
++di) {
if ((*di)->get_subtype() == CPPDeclaration::ST_instance) {
CPPInstance *inst = (*di)->as_instance();
if (inst->_type->get_subtype() == CPPDeclaration::ST_function) {
@ -2243,15 +2252,12 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
}
}
} else if ((*di)->get_subtype() == CPPDeclaration::ST_type_declaration)
{
} else if ((*di)->get_subtype() == CPPDeclaration::ST_type_declaration) {
CPPType *type = (*di)->as_type_declaration()->_type;
if ((*di)->_vis <= min_vis || in_forcetype(type->get_local_name(&parser)))
{
if ((*di)->_vis <= min_vis || in_forcetype(type->get_local_name(&parser))) {
if (type->as_struct_type() != (CPPStructType *)NULL ||
type->as_enum_type() != (CPPEnumType *)NULL)
{
type->as_enum_type() != (CPPEnumType *)NULL) {
// Here's a nested class or enum definition.
type->_vis = (*di)->_vis;
@ -2259,13 +2265,20 @@ define_struct_type(InterrogateType &itype, CPPStructType *cpptype,
assert(nested_type != (CPPExtensionType *)NULL);
// Only try to export named types.
if (nested_type->_ident != (CPPIdentifier *)NULL)
{
if (nested_type->_ident != (CPPIdentifier *)NULL) {
TypeIndex nested_index = get_type(nested_type, false);
itype._nested_types.push_back(nested_index);
}
}
}
} else if ((*di)->get_subtype() == CPPDeclaration::ST_enum) {
CPPType *type = (*di)->as_enum_type();
// An anonymous enum type.
if ((*di)->_vis <= min_vis) {
TypeIndex nested_index = get_type(type, false);
itype._nested_types.push_back(nested_index);
}
}
}

View File

@ -934,7 +934,7 @@ bool TypeManager::
is_double(CPPType *type) {
switch (type->get_subtype()) {
case CPPDeclaration::ST_const:
return is_float(type->as_const_type()->_wrapped_around);
return is_double(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_simple:
{
@ -1199,7 +1199,8 @@ is_PyObject(CPPType *type) {
return is_PyObject(type->as_const_type()->_wrapped_around);
case CPPDeclaration::ST_extension:
return (type->get_local_name(&parser) == "PyObject");
return (type->get_local_name(&parser) == "PyObject" ||
type->get_local_name(&parser) == "_object");
default:
return false;

View File

@ -83,7 +83,7 @@ int Dtool_Init_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds)
return -1;
}
int Dtool_InitNoCoerce_DTOOL_SUPER_BASE(PyObject *self, PyObject *args, PyObject *kwds) {
int Dtool_InitNoCoerce_DTOOL_SUPER_BASE(PyObject *self, PyObject *args) {
PyErr_SetString(PyExc_TypeError, "cannot init super base");
return -1;
}

View File

@ -79,9 +79,21 @@ attempt_coercion(PyObject *self, Dtool_PyTypedObject *classdef,
if (classdef->_PyType.tp_new != NULL) {
obj = classdef->_PyType.tp_new(&classdef->_PyType, self, NULL);
assert(obj != NULL);
if (classdef->_Dtool_InitNoCoerce(obj, self, NULL) != 0) {
Py_DECREF(obj);
obj = NULL;
if (PyTuple_Check(self)) {
// A tuple was passed, which we assume are the constructor arguments.
if (classdef->_Dtool_InitNoCoerce(obj, self) != 0) {
Py_DECREF(obj);
obj = NULL;
}
} else {
// We need to pack the value into an args tuple.
PyObject *args = PyTuple_Pack(1, self);
if (classdef->_Dtool_InitNoCoerce(obj, args) != 0) {
Py_DECREF(obj);
obj = NULL;
}
Py_DECREF(args);
}
}
if (obj == NULL) {
@ -93,7 +105,11 @@ attempt_coercion(PyObject *self, Dtool_PyTypedObject *classdef,
PyObject *make = PyObject_GetAttrString((PyObject *)classdef, "make");
if (make != NULL) {
PyErr_Clear();
obj = PyObject_Call(make, self, NULL);
if (PyTuple_Check(self)) {
obj = PyObject_CallObject(make, self);
} else {
obj = PyObject_CallFunctionObjArgs(make, self, NULL);
}
Py_DECREF(make);
}
}
@ -598,7 +614,7 @@ int DTOOL_PyObject_Compare(PyObject *v1, PyObject *v2) {
PyErr_Clear();
} else {
PyObject *res = NULL;
PyObject *args = Py_BuildValue("(O)", v2);
PyObject *args = PyTuple_Pack(1, v2);
if (args != NULL) {
res = PyObject_Call(func, args, NULL);
Py_DECREF(args);

View File

@ -42,18 +42,23 @@
#if defined(HAVE_PYTHON) && !defined(CPPPARSER)
#ifdef HAVE_LONG_LONG
#undef HAVE_LONG_LONG
#endif
#ifdef _POSIX_C_SOURCE
#undef _POSIX_C_SOURCE
#endif
#define PY_SSIZE_T_CLEAN 1
#include "Python.h"
#include "structmember.h"
#ifdef HAVE_LONG_LONG
#undef HAVE_LONG_LONG
#endif
#ifndef HAVE_LONG_LONG
#define PyLong_FromLongLong(x) PyLong_FromLong((long) (x))
#define PyLong_FromUnsignedLongLong(x) PyLong_FromUnsignedLong((unsigned long) (x))
#define PyLong_AsLongLong(x) PyLong_AsLong(x)
#define PyLong_AsUnsignedLongLong(x) PyLong_AsUnsignedLong(x)
#define PyLong_AsUnsignedLongLongMask(x) PyLong_AsUnsignedLongMask(x)
#define PyLong_AsLongLongAndOverflow(x) PyLong_AsLongAndOverflow(x)
#endif
#if PY_VERSION_HEX < 0x02050000
@ -139,7 +144,7 @@ typedef void * ( * ConvertFunctionType )(PyObject *,Dtool_PyTypedObject * );
typedef void * ( * ConvertFunctionType1 )(void *, Dtool_PyTypedObject *);
typedef void ( *FreeFunction )(PyObject *);
typedef void ( *PyModuleClassInit)(PyObject *module);
typedef int ( *InitNoCoerce)(PyObject *self, PyObject *args, PyObject *kwds);
typedef int ( *InitNoCoerce)(PyObject *self, PyObject *args);
//inline Dtool_PyTypedObject * Dtool_RuntimeTypeDtoolType(int type);
inline void Dtool_Deallocate_General(PyObject * self);
@ -369,7 +374,7 @@ EXPCL_DTOOLCONFIG PyObject *DTool_CreatePyInstance(void *local_this, Dtool_PyTyp
extern EXPORT_THIS Dtool_PyTypedObject Dtool_##CLASS_NAME;\
extern struct PyMethodDef Dtool_Methods_##CLASS_NAME[];\
int Dtool_Init_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
int Dtool_InitNoCoerce_##CLASS_NAME(PyObject *self, PyObject *args, PyObject *kwds);\
int Dtool_InitNoCoerce_##CLASS_NAME(PyObject *self, PyObject *args);\
PyObject * Dtool_new_##CLASS_NAME(PyTypeObject *type, PyObject *args, PyObject *kwds);\
void * Dtool_UpcastInterface_##CLASS_NAME(PyObject *self, Dtool_PyTypedObject *requested_type);\
void * Dtool_DowncastInterface_##CLASS_NAME(void *self, Dtool_PyTypedObject *requested_type);\

View File

@ -20,7 +20,9 @@
#ifndef PYTHON_H
#define PYTHON_H
class PyObject;
struct _object;
typedef _object PyObject;
class PyThreadState;
typedef int Py_ssize_t;
struct Py_buffer;

View File

@ -66,15 +66,19 @@ PUBLISHED:
bool has_value() const;
int get_num_declarations() const;
const ConfigDeclaration *get_declaration(int n) const;
MAKE_SEQ(get_declarations, get_num_declarations, get_declaration);
INLINE int get_num_references() const;
INLINE const ConfigDeclaration *get_reference(int n) const;
MAKE_SEQ(get_references, get_num_references, get_reference);
INLINE int get_num_trusted_references() const;
INLINE const ConfigDeclaration *get_trusted_reference(int n) const;
MAKE_SEQ(get_trusted_references, get_num_trusted_references, get_trusted_reference);
INLINE int get_num_unique_references() const;
INLINE const ConfigDeclaration *get_unique_reference(int n) const;
MAKE_SEQ(get_unique_references, get_num_unique_references, get_unique_reference);
void output(ostream &out) const;
void write(ostream &out) const;

View File

@ -47,6 +47,7 @@ PUBLISHED:
INLINE int get_num_variables() const;
INLINE ConfigVariableCore *get_variable(int n) const;
MAKE_SEQ(get_variables, get_num_variables, get_variable);
string get_variable_name(int n) const;
bool is_variable_used(int n) const;

View File

@ -106,7 +106,7 @@ is_debug() const {
// methods are redefined to be static to make it more
// obvious to the compiler.
////////////////////////////////////////////////////////////////////
INLINE bool NotifyCategory::
CONSTEXPR bool NotifyCategory::
is_spam() {
return false;
}
@ -119,7 +119,7 @@ is_spam() {
// methods are redefined to be static to make it more
// obvious to the compiler.
////////////////////////////////////////////////////////////////////
INLINE bool NotifyCategory::
CONSTEXPR bool NotifyCategory::
is_debug() {
return false;
}

View File

@ -56,8 +56,8 @@ PUBLISHED:
INLINE bool is_spam() const;
INLINE bool is_debug() const;
#else
INLINE static bool is_spam();
INLINE static bool is_debug();
CONSTEXPR static bool is_spam();
CONSTEXPR static bool is_debug();
#endif
INLINE bool is_info() const;
INLINE bool is_warning() const;

View File

@ -80,30 +80,38 @@ is_on(NotifySeverity severity) {
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
#ifdef NOTIFY_DEBUG
template<class GetCategory>
INLINE bool NotifyCategoryProxy<GetCategory>::
is_spam() {
#ifdef NOTIFY_DEBUG
return get_unsafe_ptr()->is_spam();
#else
return false;
#endif
}
#else
template<class GetCategory>
CONSTEXPR bool NotifyCategoryProxy<GetCategory>::
is_spam() {
return false;
}
#endif
////////////////////////////////////////////////////////////////////
// Function: NotifyCategoryProxy::is_debug
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
#ifdef NOTIFY_DEBUG
template<class GetCategory>
INLINE bool NotifyCategoryProxy<GetCategory>::
is_debug() {
#ifdef NOTIFY_DEBUG
return get_unsafe_ptr()->is_debug();
#else
return false;
#endif
}
#else
template<class GetCategory>
CONSTEXPR bool NotifyCategoryProxy<GetCategory>::
is_debug() {
return false;
}
#endif
////////////////////////////////////////////////////////////////////
// Function: NotifyCategoryProxy::is_info

View File

@ -85,8 +85,8 @@ public:
INLINE bool is_spam();
INLINE bool is_debug();
#else
INLINE static bool is_spam();
INLINE static bool is_debug();
CONSTEXPR static bool is_spam();
CONSTEXPR static bool is_debug();
#endif
INLINE bool is_info();
INLINE bool is_warning();

View File

@ -18,6 +18,7 @@ extern "C" {
EXPCL_PYSTUB int PyArg_Parse(...);
EXPCL_PYSTUB int PyArg_ParseTuple(...);
EXPCL_PYSTUB int PyArg_ParseTupleAndKeywords(...);
EXPCL_PYSTUB int PyArg_UnpackTuple(...);
EXPCL_PYSTUB int PyBool_FromLong(...);
EXPCL_PYSTUB int PyBuffer_Release(...);
EXPCL_PYSTUB int PyBytes_AsString(...);
@ -84,11 +85,14 @@ extern "C" {
EXPCL_PYSTUB int PyModule_AddObject(...);
EXPCL_PYSTUB int PyModule_AddStringConstant(...);
EXPCL_PYSTUB int PyModule_Create2(...);
EXPCL_PYSTUB int PyNumber_Check(...);
EXPCL_PYSTUB int PyNumber_Float(...);
EXPCL_PYSTUB int PyNumber_Int(...);
EXPCL_PYSTUB int PyNumber_Long(...);
EXPCL_PYSTUB int PyObject_ASCII(...);
EXPCL_PYSTUB int PyObject_Call(...);
EXPCL_PYSTUB int PyObject_CallFunction(...);
EXPCL_PYSTUB int PyObject_CallFunctionObjArgs(...);
EXPCL_PYSTUB int PyObject_CallMethod(...);
EXPCL_PYSTUB int PyObject_CallMethodObjArgs(...);
EXPCL_PYSTUB int PyObject_CallObject(...);
@ -152,8 +156,14 @@ extern "C" {
EXPCL_PYSTUB int Py_InitModule4(...);
EXPCL_PYSTUB int Py_InitModule4_64(...);
EXPCL_PYSTUB int Py_InitModule4TraceRefs(...);
EXPCL_PYSTUB int _PyArg_ParseTuple_SizeT(...);
EXPCL_PYSTUB int _PyArg_ParseTupleAndKeywords_SizeT(...);
EXPCL_PYSTUB int _PyArg_Parse_SizeT(...);
EXPCL_PYSTUB int _PyObject_CallFunction_SizeT(...);
EXPCL_PYSTUB int _PyObject_CallMethod_SizeT(...);
EXPCL_PYSTUB int _PyObject_DebugFree(...);
EXPCL_PYSTUB int _PyObject_Del(...);
EXPCL_PYSTUB int _Py_BuildValue_SizeT(...);
EXPCL_PYSTUB int _Py_Dealloc(...);
EXPCL_PYSTUB int _Py_NegativeRefcount(...);
EXPCL_PYSTUB int _Py_RefTotal(...);
@ -182,6 +192,7 @@ extern "C" {
int PyArg_Parse(...) { return 0; };
int PyArg_ParseTuple(...) { return 0; }
int PyArg_ParseTupleAndKeywords(...) { return 0; }
int PyArg_UnpackTuple(...) { return 0; };
int PyBool_FromLong(...) { return 0; }
int PyBuffer_Release(...) { return 0; }
int PyBytes_AsString(...) { return 0; }
@ -248,11 +259,14 @@ int PyModule_AddIntConstant(...) { return 0; };
int PyModule_AddObject(...) { return 0; };
int PyModule_AddStringConstant(...) { return 0; };
int PyModule_Create2(...) { return 0; };
int PyNumber_Check(...) { return 0; }
int PyNumber_Float(...) { return 0; }
int PyNumber_Int(...) { return 0; }
int PyNumber_Long(...) { return 0; }
int PyObject_ASCII(...) { return 0; }
int PyObject_Call(...) { return 0; }
int PyObject_CallFunction(...) { return 0; }
int PyObject_CallFunctionObjArgs(...) { return 0; }
int PyObject_CallMethod(...) { return 0; }
int PyObject_CallMethodObjArgs(...) { return 0; }
int PyObject_CallObject(...) { return 0; }
@ -316,8 +330,14 @@ int Py_BuildValue(...) { return 0; }
int Py_InitModule4(...) { return 0; }
int Py_InitModule4_64(...) { return 0; }
int Py_InitModule4TraceRefs(...) { return 0; };
int _PyArg_ParseTuple_SizeT(...) { return 0; };
int _PyArg_ParseTupleAndKeywords_SizeT(...) { return 0; };
int _PyArg_Parse_SizeT(...) { return 0; };
int _PyObject_CallFunction_SizeT(...) { return 0; };
int _PyObject_CallMethod_SizeT(...) { return 0; };
int _PyObject_DebugFree(...) { return 0; };
int _PyObject_Del(...) { return 0; };
int _Py_BuildValue_SizeT(...) { return 0; };
int _Py_Dealloc(...) { return 0; };
int _Py_NegativeRefcount(...) { return 0; };
int _Py_RefTotal(...) { return 0; };

View File

@ -92,7 +92,7 @@ PkgListSet(["PYTHON", "DIRECT", # Python support
"GTK2", "WX", "FLTK", # Toolkit support
"ROCKET", # GUI libraries
"CARBON", "COCOA", # Mac OS X toolkits
"OSMESA", "X11", "XF86DGA", "XRANDR", "XCURSOR", # Unix platform support
"X11", "XF86DGA", "XRANDR", "XCURSOR", # Unix platform support
"PANDATOOL", "PVIEW", "DEPLOYTOOLS", # Toolchain
"SKEL", # Example SKEL project
"PANDAFX", # Some distortion special lenses
@ -697,7 +697,6 @@ if (COMPILER=="GCC"):
SmartPkgEnable("GLES", "glesv1_cm", ("GLESv1_CM"), ("GLES/gl.h"), framework = "OpenGLES")
SmartPkgEnable("GLES2", "glesv2", ("GLESv2"), ("GLES2/gl2.h")) #framework = "OpenGLES"?
SmartPkgEnable("EGL", "egl", ("EGL"), ("EGL/egl.h"))
SmartPkgEnable("OSMESA", "osmesa", ("OSMesa"), ("GL/osmesa.h"))
SmartPkgEnable("NVIDIACG", "", ("Cg"), "Cg/cg.h", framework = "Cg")
SmartPkgEnable("ODE", "", ("ode"), "ode/ode.h", tool = "ode-config")
SmartPkgEnable("OPENAL", "openal", ("openal"), "AL/al.h", framework = "OpenAL")
@ -1901,9 +1900,6 @@ DTOOL_CONFIG=[
("HAVE_GL", '1', 'UNDEF'),
("HAVE_GLES", 'UNDEF', 'UNDEF'),
("HAVE_GLES2", 'UNDEF', 'UNDEF'),
("HAVE_MESA", 'UNDEF', 'UNDEF'),
("MESA_MGL", 'UNDEF', 'UNDEF'),
("HAVE_SGIGL", 'UNDEF', 'UNDEF'),
("HAVE_GLX", 'UNDEF', '1'),
("HAVE_EGL", 'UNDEF', 'UNDEF'),
("HAVE_WGL", '1', 'UNDEF'),
@ -3828,15 +3824,16 @@ if (PkgSkip("OPENSSL")==0 and not RTDIST and not RUNTIME and PkgSkip("DEPLOYTOOL
TargetAdd('build_patch.exe', input=COMMON_PANDA_LIBS_PYSTUB)
TargetAdd('build_patch.exe', opts=OPTS)
TargetAdd('check_adler_check_adler.obj', opts=OPTS, input='check_adler.cxx')
TargetAdd('check_adler.exe', input=['check_adler_check_adler.obj'])
TargetAdd('check_adler.exe', input=COMMON_PANDA_LIBS_PYSTUB)
TargetAdd('check_adler.exe', opts=OPTS)
if not PkgSkip("ZLIB"):
TargetAdd('check_adler_check_adler.obj', opts=OPTS, input='check_adler.cxx')
TargetAdd('check_adler.exe', input=['check_adler_check_adler.obj'])
TargetAdd('check_adler.exe', input=COMMON_PANDA_LIBS_PYSTUB)
TargetAdd('check_adler.exe', opts=OPTS)
TargetAdd('check_crc_check_crc.obj', opts=OPTS, input='check_crc.cxx')
TargetAdd('check_crc.exe', input=['check_crc_check_crc.obj'])
TargetAdd('check_crc.exe', input=COMMON_PANDA_LIBS_PYSTUB)
TargetAdd('check_crc.exe', opts=OPTS)
TargetAdd('check_crc_check_crc.obj', opts=OPTS, input='check_crc.cxx')
TargetAdd('check_crc.exe', input=['check_crc_check_crc.obj'])
TargetAdd('check_crc.exe', input=COMMON_PANDA_LIBS_PYSTUB)
TargetAdd('check_crc.exe', opts=OPTS)
TargetAdd('check_md5_check_md5.obj', opts=OPTS, input='check_md5.cxx')
TargetAdd('check_md5.exe', input=['check_md5_check_md5.obj'])
@ -4035,20 +4032,6 @@ if (not RUNTIME):
TargetAdd('egg.pyd', input=COMMON_PANDA_LIBS)
TargetAdd('egg.pyd', opts=['PYTHON'])
#
# DIRECTORY: panda/src/mesadisplay/
#
if (GetTarget() != 'windows' and PkgSkip("GL")==0 and PkgSkip("OSMESA")==0 and not RUNTIME):
OPTS=['DIR:panda/src/mesadisplay', 'DIR:panda/src/glstuff', 'BUILDING:PANDAMESA', 'NVIDIACG', 'GL', 'OSMESA']
TargetAdd('p3mesadisplay_composite1.obj', opts=OPTS, input='p3mesadisplay_composite1.cxx')
OPTS=['DIR:panda/metalibs/pandagl', 'BUILDING:PANDAMESA', 'NVIDIACG', 'GL']
TargetAdd('libpandamesa.dll', input='p3mesadisplay_composite1.obj')
if (PkgSkip('PANDAFX')==0):
TargetAdd('libpandamesa.dll', input='libpandafx.dll')
TargetAdd('libpandamesa.dll', input=COMMON_PANDA_LIBS)
TargetAdd('libpandamesa.dll', opts=['MODULE', 'GL', 'OSMESA'])
#
# DIRECTORY: panda/src/x11display/
#
@ -5539,15 +5522,17 @@ if (PkgSkip("PANDATOOL")==0):
# DIRECTORY: pandatool/src/miscprogs/
#
if (PkgSkip("PANDATOOL")==0):
OPTS=['DIR:pandatool/src/miscprogs']
TargetAdd('bin2c_binToC.obj', opts=OPTS, input='binToC.cxx')
TargetAdd('bin2c.exe', input='bin2c_binToC.obj')
TargetAdd('bin2c.exe', input='libp3progbase.lib')
TargetAdd('bin2c.exe', input='libp3pandatoolbase.lib')
TargetAdd('bin2c.exe', input=COMMON_PANDA_LIBS)
TargetAdd('bin2c.exe', input='libp3pystub.lib')
TargetAdd('bin2c.exe', opts=['ADVAPI'])
# This is a bit of an esoteric tool, and it causes issues because
# it conflicts with tools of the same name in different packages.
#if (PkgSkip("PANDATOOL")==0):
# OPTS=['DIR:pandatool/src/miscprogs']
# TargetAdd('bin2c_binToC.obj', opts=OPTS, input='binToC.cxx')
# TargetAdd('bin2c.exe', input='bin2c_binToC.obj')
# TargetAdd('bin2c.exe', input='libp3progbase.lib')
# TargetAdd('bin2c.exe', input='libp3pandatoolbase.lib')
# TargetAdd('bin2c.exe', input=COMMON_PANDA_LIBS)
# TargetAdd('bin2c.exe', input='libp3pystub.lib')
# TargetAdd('bin2c.exe', opts=['ADVAPI'])
#
# DIRECTORY: pandatool/src/pstatserver/

View File

@ -2328,15 +2328,20 @@ def SetupBuildEnvironment(compiler):
########################################################################
def CopyFile(dstfile, srcfile):
if (dstfile[-1]=='/'):
if dstfile[-1] == '/':
dstdir = dstfile
fnl = srcfile.rfind("/")
if (fnl < 0): fn = srcfile
else: fn = srcfile[fnl+1:]
if fnl < 0:
fn = srcfile
else:
fn = srcfile[fnl+1:]
dstfile = dstdir + fn
if NeedsBuild([dstfile], [srcfile]):
if os.path.islink(srcfile):
# Preserve symlinks
if os.path.exists(dstfile):
os.unlink(dstfile)
os.symlink(os.readlink(srcfile), dstfile)
else:
WriteBinaryFile(dstfile, ReadBinaryFile(srcfile))

View File

@ -405,8 +405,6 @@ get_extra_extensions() {
// not defined.
////////////////////////////////////////////////////////////////////
void *AndroidGraphicsStateGuardian::
do_get_extension_func(const char *prefix, const char *name) {
string fullname = string(prefix) + string(name);
return (void *)eglGetProcAddress(fullname.c_str());
do_get_extension_func(const char *name) {
return (void *)eglGetProcAddress(name);
}

View File

@ -61,7 +61,7 @@ protected:
virtual void query_gl_version();
virtual void get_extra_extensions();
virtual void *do_get_extension_func(const char *prefix, const char *name);
virtual void *do_get_extension_func(const char *name);
private:
int _egl_version_major, _egl_version_minor;

View File

@ -3,7 +3,7 @@
#define OTHER_LIBS p3interrogatedb:c p3dconfig:c p3dtoolconfig:m \
p3dtoolutil:c p3dtoolbase:c p3dtool:m
#define OSX_SYS_FRAMEWORKS ApplicationServices AppKit
#define OSX_SYS_FRAMEWORKS ApplicationServices AppKit Carbon
#begin lib_target
#define TARGET p3cocoadisplay

View File

@ -46,7 +46,7 @@ public:
protected:
virtual void query_gl_version();
virtual void *do_get_extension_func(const char *prefix, const char *name);
virtual void *do_get_extension_func(const char *name);
public:
static TypeHandle get_class_type() {

View File

@ -276,10 +276,9 @@ query_gl_version() {
// not defined.
////////////////////////////////////////////////////////////////////
void *CocoaGraphicsStateGuardian::
do_get_extension_func(const char *prefix, const char *name) {
char* fullname = (char*) malloc(strlen(prefix) + strlen(name) + 2);
strcpy(fullname + 1, prefix);
strcpy(fullname + 1 + strlen(prefix), name);
do_get_extension_func(const char *name) {
char* fullname = (char*) malloc(strlen(name) + 2);
strcpy(fullname + 1, name);
fullname[0] = '_';
// Believe it or not, but this is actually the
@ -292,7 +291,7 @@ do_get_extension_func(const char *prefix, const char *name) {
}
cocoadisplay_cat.warning() <<
"do_get_extension_func failed for " << prefix << name << "!\n";
"do_get_extension_func failed for " << fullname << "!\n";
free(fullname);
return NULL;

View File

@ -405,6 +405,17 @@ ConfigVariableBool framebuffer_stereo
PRC_DESC("True if FM_stereo should be added to the default framebuffer "
"properties, which requests a stereo-capable display, if "
"supported by the graphics driver."));
ConfigVariableBool framebuffer_srgb
("framebuffer-srgb", false,
PRC_DESC("Set this to request an sRGB framebuffer, which will "
"convert all values to linear space before blending. This "
"means that the output will be properly gamma-corrected, as "
"long as all the input textures are either converted from "
"original sRGB to linear or sRGB textures are used."));
ConfigVariableBool framebuffer_float
("framebuffer-float", false,
PRC_DESC("Set this to request a framebuffer that uses floating-point "
"storage for the color channel."));
ConfigVariableInt depth_bits
("depth-bits", 0,

View File

@ -92,6 +92,8 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_alpha;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_stencil;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_accum;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_stereo;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_srgb;
extern EXPCL_PANDA_DISPLAY ConfigVariableBool framebuffer_float;
extern EXPCL_PANDA_DISPLAY ConfigVariableInt depth_bits;
extern EXPCL_PANDA_DISPLAY ConfigVariableInt color_bits;
extern EXPCL_PANDA_DISPLAY ConfigVariableInt alpha_bits;

View File

@ -38,6 +38,34 @@ get_lens_index() const {
return cdata->_lens_index;
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_num_regions
// Access: Published
// Description: Returns the number of regions, see set_num_regions.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegion::
get_num_regions() const {
CDReader cdata(_cycler);
return cdata->_regions.size();
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_num_regions
// Access: Published
// Description: Sets the number of regions that this DisplayRegion
// indicates. Usually, this number is 1 (and it is
// always at least 1), and only the first is used for
// rendering. However, if more than one is provided,
// you may select which one to render into using a
// geometry shader (gl_ViewportIndex in GLSL).
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_num_regions(int i) {
nassertv(i >= 1);
CDWriter cdata(_cycler);
cdata->_regions.resize(i);
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_dimensions
// Access: Published
@ -47,11 +75,24 @@ get_lens_index() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
get_dimensions(0, l, r, b, t);
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_dimensions
// Access: Published
// Description: Retrieves the coordinates of the DisplayRegion's
// rectangle within its GraphicsOutput. These numbers
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
CDReader cdata(_cycler);
l = cdata->_dimensions[0];
r = cdata->_dimensions[1];
b = cdata->_dimensions[2];
t = cdata->_dimensions[3];
const Region &region = cdata->_regions[i];
l = region._dimensions[0];
r = region._dimensions[1];
b = region._dimensions[2];
t = region._dimensions[3];
}
///////////////////////////////////////////////////////////////////
@ -62,9 +103,9 @@ get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) c
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE LVecBase4 DisplayRegion::
get_dimensions() const {
get_dimensions(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions;
return cdata->_regions[i]._dimensions;
}
////////////////////////////////////////////////////////////////////
@ -75,9 +116,9 @@ get_dimensions() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_left() const {
get_left(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[0];
return cdata->_regions[i]._dimensions[0];
}
////////////////////////////////////////////////////////////////////
@ -88,9 +129,9 @@ get_left() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_right() const {
get_right(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[1];
return cdata->_regions[i]._dimensions[1];
}
////////////////////////////////////////////////////////////////////
@ -101,9 +142,9 @@ get_right() const {
// number will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_bottom() const {
get_bottom(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[2];
return cdata->_regions[i]._dimensions[2];
}
////////////////////////////////////////////////////////////////////
@ -114,9 +155,9 @@ get_bottom() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegion::
get_top() const {
get_top(int i) const {
CDReader cdata(_cycler);
return cdata->_dimensions[3];
return cdata->_regions[i]._dimensions[3];
}
////////////////////////////////////////////////////////////////////
@ -130,7 +171,35 @@ get_top() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_dimensions(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t) {
set_dimensions(LVecBase4(l, r, b, t));
set_dimensions(0, LVecBase4(l, r, b, t));
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_dimensions
// Access: Published, Virtual
// Description: Changes the portion of the framebuffer this
// DisplayRegion corresponds to. The parameters range
// from 0 to 1, where 0,0 is the lower left corner and
// 1,1 is the upper right; (0, 1, 0, 1) represents the
// whole screen.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_dimensions(int i, PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t) {
set_dimensions(i, LVecBase4(l, r, b, t));
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::set_dimensions
// Access: Published, Virtual
// Description: Changes the portion of the framebuffer this
// DisplayRegion corresponds to. The parameters range
// from 0 to 1, where 0,0 is the lower left corner and
// 1,1 is the upper right; (0, 1, 0, 1) represents the
// whole screen.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
set_dimensions(const LVecBase4 &dimensions) {
set_dimensions(0, dimensions);
}
////////////////////////////////////////////////////////////////////
@ -387,9 +456,9 @@ get_draw_callback() const {
// Description: Returns the width of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegion::
get_pixel_width() const {
get_pixel_width(int i) const {
CDReader cdata(_cycler);
return cdata->_pr - cdata->_pl;
return cdata->_regions[i]._pixels[1] - cdata->_regions[i]._pixels[0];
}
////////////////////////////////////////////////////////////////////
@ -398,9 +467,9 @@ get_pixel_width() const {
// Description: Returns the height of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegion::
get_pixel_height() const {
get_pixel_height(int i) const {
CDReader cdata(_cycler);
return cdata->_pt - cdata->_pb;
return cdata->_regions[i]._pixels[3] - cdata->_regions[i]._pixels[2];
}
////////////////////////////////////////////////////////////////////
@ -411,11 +480,23 @@ get_pixel_height() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_pixels(int &pl, int &pr, int &pb, int &pt) const {
get_pixels(0, pl, pr, pb, pt);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, in pixels.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const {
CDReader cdata(_cycler);
pl = cdata->_pl;
pr = cdata->_pr;
pb = cdata->_pb;
pt = cdata->_pt;
const Region &region = cdata->_regions[i];
pl = region._pixels[0];
pr = region._pixels[1];
pb = region._pixels[2];
pt = region._pixels[3];
}
////////////////////////////////////////////////////////////////////
@ -427,11 +508,24 @@ get_pixels(int &pl, int &pr, int &pb, int &pt) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels(int &xo, int &yo, int &w, int &h) const {
get_region_pixels(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_region_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, as the pixel location of its bottom-left
// corner, along with a pixel width and height.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const {
CDReader cdata(_cycler);
xo = cdata->_pl;
yo = cdata->_pb;
w = cdata->_pr - cdata->_pl;
h = cdata->_pt - cdata->_pb;
const Region &region = cdata->_regions[i];
xo = region._pixels[0];
yo = region._pixels[2];
w = region._pixels[1] - xo;
h = region._pixels[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -444,11 +538,25 @@ get_region_pixels(int &xo, int &yo, int &w, int &h) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels_i(int &xo, int &yo, int &w, int &h) const {
get_region_pixels_i(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::get_region_pixels_i
// Access: Public
// Description: Similar to get_region_pixels(), but returns the upper
// left corner, and the pixel numbers are numbered from
// the top-left corner down, in the DirectX way of
// things.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegion::
get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const {
CDReader cdata(_cycler);
xo = cdata->_pl;
yo = cdata->_pti;
w = cdata->_pr - cdata->_pl;
h = cdata->_pbi - cdata->_pti;
const Region &region = cdata->_regions[i];
xo = region._pixels_i[0];
yo = region._pixels_i[2];
w = region._pixels_i[1] - xo;
h = region._pixels_i[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -522,6 +630,18 @@ get_draw_region_pcollector() {
return _draw_region_pcollector;
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::Region::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DisplayRegion::Region::
Region() :
_dimensions(0, 1, 0, 1),
_pixels(0),
_pixels_i(0) {
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegion::CDataCull::Constructor
// Access: Public
@ -633,6 +753,16 @@ is_any_clear_active() const {
return _object->is_any_clear_active();
}
///////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_num_regions
// Access: Published
// Description: Returns the number of regions, see set_num_regions.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader::
get_num_regions() const {
return _cdata->_regions.size();
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_dimensions
// Access: Public
@ -642,10 +772,23 @@ is_any_clear_active() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
l = _cdata->_dimensions[0];
r = _cdata->_dimensions[1];
b = _cdata->_dimensions[2];
t = _cdata->_dimensions[3];
return get_dimensions(0, l, r, b, t);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_dimensions
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion's
// rectangle within its GraphicsOutput. These numbers
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
l = region._dimensions[0];
r = region._dimensions[1];
b = region._dimensions[2];
t = region._dimensions[3];
}
////////////////////////////////////////////////////////////////////
@ -656,8 +799,8 @@ get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) c
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE const LVecBase4 &DisplayRegionPipelineReader::
get_dimensions() const {
return _cdata->_dimensions;
get_dimensions(int i) const {
return _cdata->_regions[i]._dimensions;
}
////////////////////////////////////////////////////////////////////
@ -668,8 +811,8 @@ get_dimensions() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_left() const {
return _cdata->_dimensions[0];
get_left(int i) const {
return _cdata->_regions[i]._dimensions[0];
}
////////////////////////////////////////////////////////////////////
@ -680,8 +823,8 @@ get_left() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_right() const {
return _cdata->_dimensions[1];
get_right(int i) const {
return _cdata->_regions[i]._dimensions[1];
}
////////////////////////////////////////////////////////////////////
@ -692,8 +835,8 @@ get_right() const {
// number will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_bottom() const {
return _cdata->_dimensions[2];
get_bottom(int i) const {
return _cdata->_regions[i]._dimensions[2];
}
////////////////////////////////////////////////////////////////////
@ -704,8 +847,8 @@ get_bottom() const {
// will be in the range [0..1].
////////////////////////////////////////////////////////////////////
INLINE PN_stdfloat DisplayRegionPipelineReader::
get_top() const {
return _cdata->_dimensions[3];
get_top(int i) const {
return _cdata->_regions[i]._dimensions[3];
}
////////////////////////////////////////////////////////////////////
@ -816,10 +959,22 @@ get_draw_callback() const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_pixels(int &pl, int &pr, int &pb, int &pt) const {
pl = _cdata->_pl;
pr = _cdata->_pr;
pb = _cdata->_pb;
pt = _cdata->_pt;
get_pixels(0, pl, pr, pb, pt);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, in pixels.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
pl = region._pixels[0];
pr = region._pixels[1];
pb = region._pixels[2];
pt = region._pixels[3];
}
////////////////////////////////////////////////////////////////////
@ -831,10 +986,23 @@ get_pixels(int &pl, int &pr, int &pb, int &pt) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels(int &xo, int &yo, int &w, int &h) const {
xo = _cdata->_pl;
yo = _cdata->_pb;
w = _cdata->_pr - _cdata->_pl;
h = _cdata->_pt - _cdata->_pb;
get_region_pixels(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_region_pixels
// Access: Public
// Description: Retrieves the coordinates of the DisplayRegion within
// its window, as the pixel location of its bottom-left
// corner, along with a pixel width and height.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
xo = region._pixels[0];
yo = region._pixels[2];
w = region._pixels[1] - xo;
h = region._pixels[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -847,10 +1015,24 @@ get_region_pixels(int &xo, int &yo, int &w, int &h) const {
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels_i(int &xo, int &yo, int &w, int &h) const {
xo = _cdata->_pl;
yo = _cdata->_pti;
w = _cdata->_pr - _cdata->_pl;
h = _cdata->_pbi - _cdata->_pti;
get_region_pixels_i(0, xo, yo, w, h);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayRegionPipelineReader::get_region_pixels_i
// Access: Public
// Description: Similar to get_region_pixels(), but returns the upper
// left corner, and the pixel numbers are numbered from
// the top-left corner down, in the DirectX way of
// things.
////////////////////////////////////////////////////////////////////
INLINE void DisplayRegionPipelineReader::
get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const {
const DisplayRegion::Region &region = _cdata->_regions[i];
xo = region._pixels_i[0];
yo = region._pixels_i[2];
w = region._pixels_i[1] - xo;
h = region._pixels_i[3] - yo;
}
////////////////////////////////////////////////////////////////////
@ -859,8 +1041,8 @@ get_region_pixels_i(int &xo, int &yo, int &w, int &h) const {
// Description: Returns the width of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader::
get_pixel_width() const {
return _cdata->_pr - _cdata->_pl;
get_pixel_width(int i) const {
return _cdata->_regions[i]._pixels[1] - _cdata->_regions[i]._pixels[0];
}
////////////////////////////////////////////////////////////////////
@ -869,8 +1051,7 @@ get_pixel_width() const {
// Description: Gets the index into a lens_node lens array. 0 default
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader::
get_lens_index() const
{
get_lens_index() const {
return _cdata->_lens_index;
}
@ -880,6 +1061,6 @@ get_lens_index() const
// Description: Returns the height of the DisplayRegion in pixels.
////////////////////////////////////////////////////////////////////
INLINE int DisplayRegionPipelineReader::
get_pixel_height() const {
return _cdata->_pt - _cdata->_pb;
get_pixel_height(int i) const {
return _cdata->_regions[i]._pixels[3] - _cdata->_regions[i]._pixels[2];
}

View File

@ -42,7 +42,8 @@ DisplayRegion(GraphicsOutput *window, const LVecBase4 &dimensions) :
{
_screenshot_buffer_type = window->get_draw_buffer_type();
_draw_buffer_type = window->get_draw_buffer_type();
set_dimensions(dimensions);
set_num_regions(1);
set_dimensions(0, dimensions);
compute_pixels_all_stages();
_window->add_display_region(this);
@ -127,15 +128,15 @@ set_lens_index(int index) {
// whole screen.
////////////////////////////////////////////////////////////////////
void DisplayRegion::
set_dimensions(const LVecBase4 &dimensions) {
set_dimensions(int i, const LVecBase4 &dimensions) {
int pipeline_stage = Thread::get_current_pipeline_stage();
nassertv(pipeline_stage == 0);
CDWriter cdata(_cycler);
cdata->_dimensions = dimensions;
cdata->_regions[i]._dimensions = dimensions;
if (_window != (GraphicsOutput *)NULL && _window->has_size()) {
do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(), cdata);
do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(), cdata);
}
}
@ -419,9 +420,8 @@ set_target_tex_page(int page) {
void DisplayRegion::
output(ostream &out) const {
CDReader cdata(_cycler);
out << "DisplayRegion(" << cdata->_dimensions << ")=pixels(" << cdata->_pl
<< " " << cdata->_pr << " " << cdata->_pb << " " << cdata->_pt
<< ")";
out << "DisplayRegion(" << cdata->_regions[0]._dimensions
<< ")=pixels(" << cdata->_regions[0]._pixels << ")";
}
////////////////////////////////////////////////////////////////////
@ -636,8 +636,10 @@ void DisplayRegion::
compute_pixels() {
if (_window != (GraphicsOutput *)NULL) {
CDWriter cdata(_cycler, false);
do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
}
}
}
@ -656,8 +658,10 @@ compute_pixels_all_stages() {
if (_window != (GraphicsOutput *)NULL) {
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
do_compute_pixels(_window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, _window->get_fb_x_size(), _window->get_fb_y_size(),
cdata);
}
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
}
@ -673,7 +677,9 @@ compute_pixels_all_stages() {
void DisplayRegion::
compute_pixels(int x_size, int y_size) {
CDWriter cdata(_cycler, false);
do_compute_pixels(x_size, y_size, cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, x_size, y_size, cdata);
}
}
////////////////////////////////////////////////////////////////////
@ -689,7 +695,9 @@ void DisplayRegion::
compute_pixels_all_stages(int x_size, int y_size) {
OPEN_ITERATE_ALL_STAGES(_cycler) {
CDStageWriter cdata(_cycler, pipeline_stage);
do_compute_pixels(x_size, y_size, cdata);
for (int i = 0; i < cdata->_regions.size(); ++i) {
do_compute_pixels(i, x_size, y_size, cdata);
}
}
CLOSE_ITERATE_ALL_STAGES(_cycler);
}
@ -741,32 +749,36 @@ win_display_regions_changed() {
// assumes that we already have the lock.
////////////////////////////////////////////////////////////////////
void DisplayRegion::
do_compute_pixels(int x_size, int y_size, CData *cdata) {
do_compute_pixels(int i, int x_size, int y_size, CData *cdata) {
if (display_cat.is_debug()) {
display_cat.debug()
<< "DisplayRegion::do_compute_pixels(" << x_size << ", " << y_size << ")\n";
}
int old_w = cdata->_pr - cdata->_pl;
int old_h = cdata->_pt - cdata->_pb;
Region &region = cdata->_regions[i];
cdata->_pl = int((cdata->_dimensions[0] * x_size) + 0.5);
cdata->_pr = int((cdata->_dimensions[1] * x_size) + 0.5);
int old_w = region._pixels[1] - region._pixels[0];
int old_h = region._pixels[3] - region._pixels[2];
region._pixels[0] = int((region._dimensions[0] * x_size) + 0.5);
region._pixels[1] = int((region._dimensions[1] * x_size) + 0.5);
region._pixels_i[0] = region._pixels[0];
region._pixels_i[1] = region._pixels[1];
nassertv(_window != (GraphicsOutput *)NULL);
if (_window->get_inverted()) {
// The window is inverted; compute the DisplayRegion accordingly.
cdata->_pb = int(((1.0f - cdata->_dimensions[3]) * y_size) + 0.5);
cdata->_pt = int(((1.0f - cdata->_dimensions[2]) * y_size) + 0.5);
cdata->_pbi = int((cdata->_dimensions[3] * y_size) + 0.5);
cdata->_pti = int((cdata->_dimensions[2] * y_size) + 0.5);
region._pixels[2] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
region._pixels[3] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
region._pixels_i[2] = int((region._dimensions[3] * y_size) + 0.5);
region._pixels_i[3] = int((region._dimensions[2] * y_size) + 0.5);
} else {
// The window is normal.
cdata->_pb = int((cdata->_dimensions[2] * y_size) + 0.5);
cdata->_pt = int((cdata->_dimensions[3] * y_size) + 0.5);
cdata->_pbi = int(((1.0f - cdata->_dimensions[2]) * y_size) + 0.5);
cdata->_pti = int(((1.0f - cdata->_dimensions[3]) * y_size) + 0.5);
region._pixels[2] = int((region._dimensions[2] * y_size) + 0.5);
region._pixels[3] = int((region._dimensions[3] * y_size) + 0.5);
region._pixels_i[2] = int(((1.0f - region._dimensions[2]) * y_size) + 0.5);
region._pixels_i[3] = int(((1.0f - region._dimensions[3]) * y_size) + 0.5);
}
}
@ -814,9 +826,7 @@ do_cull(CullHandler *cull_handler, SceneSetup *scene_setup,
////////////////////////////////////////////////////////////////////
DisplayRegion::CData::
CData() :
_dimensions(0.0f, 1.0f, 0.0f, 1.0f),
_pl(0), _pr(0), _pb(0), _pt(0),
_pbi(0), _pti(0), _lens_index(0),
_lens_index(0),
_camera_node((Camera *)NULL),
_active(true),
_sort(0),
@ -824,6 +834,7 @@ CData() :
_tex_view_offset(0),
_target_tex_page(-1)
{
_regions.push_back(Region());
}
////////////////////////////////////////////////////////////////////
@ -833,13 +844,7 @@ CData() :
////////////////////////////////////////////////////////////////////
DisplayRegion::CData::
CData(const DisplayRegion::CData &copy) :
_dimensions(copy._dimensions),
_pl(copy._pl),
_pr(copy._pr),
_pb(copy._pb),
_pt(copy._pt),
_pbi(copy._pbi),
_pti(copy._pti),
_regions(copy._regions),
_lens_index(copy._lens_index),
_camera(copy._camera),
_camera_node(copy._camera_node),

View File

@ -72,14 +72,19 @@ public:
INLINE bool operator < (const DisplayRegion &other) const;
PUBLISHED:
INLINE int get_num_regions() const;
INLINE void set_num_regions(int i);
INLINE void get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE LVecBase4 get_dimensions() const;
INLINE PN_stdfloat get_left() const;
INLINE PN_stdfloat get_right() const;
INLINE PN_stdfloat get_bottom() const;
INLINE PN_stdfloat get_top() const;
INLINE void get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE LVecBase4 get_dimensions(int i = 0) const;
INLINE PN_stdfloat get_left(int i = 0) const;
INLINE PN_stdfloat get_right(int i = 0) const;
INLINE PN_stdfloat get_bottom(int i = 0) const;
INLINE PN_stdfloat get_top(int i = 0) const;
INLINE void set_dimensions(PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t);
virtual void set_dimensions(const LVecBase4 &dimensions);
INLINE void set_dimensions(int i, PN_stdfloat l, PN_stdfloat r, PN_stdfloat b, PN_stdfloat t);
INLINE void set_dimensions(const LVecBase4 &dimensions);
virtual void set_dimensions(int i, const LVecBase4 &dimensions);
INLINE GraphicsOutput *get_window() const;
GraphicsPipe *get_pipe() const;
@ -123,8 +128,8 @@ PUBLISHED:
INLINE void clear_draw_callback();
INLINE CallbackObject *get_draw_callback() const;
INLINE int get_pixel_width() const;
INLINE int get_pixel_height() const;
INLINE int get_pixel_width(int i = 0) const;
INLINE int get_pixel_height(int i = 0) const;
virtual void output(ostream &out) const;
@ -144,8 +149,11 @@ public:
void compute_pixels(int x_size, int y_size);
void compute_pixels_all_stages(int x_size, int y_size);
INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const;
virtual bool supports_pixel_zoom() const;
@ -157,11 +165,20 @@ public:
INLINE PStatCollector &get_cull_region_pcollector();
INLINE PStatCollector &get_draw_region_pcollector();
struct Region {
INLINE Region();
LVecBase4 _dimensions; // left, right, bottom, top
LVecBase4i _pixels;
LVecBase4i _pixels_i;
};
typedef pvector<Region> Regions;
private:
class CData;
void win_display_regions_changed();
void do_compute_pixels(int x_size, int y_size, CData *cdata);
void do_compute_pixels(int i, int x_size, int y_size, CData *cdata);
void set_active_index(int index);
protected:
@ -194,14 +211,8 @@ private:
return DisplayRegion::get_class_type();
}
LVecBase4 _dimensions; // left, right, bottom, top
int _pl;
int _pr;
int _pb;
int _pt;
int _pbi;
int _pti;
Regions _regions;
int _lens_index; // index into which lens of a camera is associated with this display region. 0 is default
NodePath _camera;
@ -293,12 +304,14 @@ public:
INLINE bool is_any_clear_active() const;
INLINE int get_num_regions() const;
INLINE void get_dimensions(PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE const LVecBase4 &get_dimensions() const;
INLINE PN_stdfloat get_left() const;
INLINE PN_stdfloat get_right() const;
INLINE PN_stdfloat get_bottom() const;
INLINE PN_stdfloat get_top() const;
INLINE void get_dimensions(int i, PN_stdfloat &l, PN_stdfloat &r, PN_stdfloat &b, PN_stdfloat &t) const;
INLINE const LVecBase4 &get_dimensions(int i = 0) const;
INLINE PN_stdfloat get_left(int i = 0) const;
INLINE PN_stdfloat get_right(int i = 0) const;
INLINE PN_stdfloat get_bottom(int i = 0) const;
INLINE PN_stdfloat get_top(int i = 0) const;
INLINE GraphicsOutput *get_window() const;
GraphicsPipe *get_pipe() const;
@ -313,11 +326,14 @@ public:
INLINE CallbackObject *get_draw_callback() const;
INLINE void get_pixels(int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_pixels(int i, int &pl, int &pr, int &pb, int &pt) const;
INLINE void get_region_pixels(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels(int i, int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int &xo, int &yo, int &w, int &h) const;
INLINE void get_region_pixels_i(int i, int &xo, int &yo, int &w, int &h) const;
INLINE int get_pixel_width() const;
INLINE int get_pixel_height() const;
INLINE int get_pixel_width(int i = 0) const;
INLINE int get_pixel_height(int i = 0) const;
INLINE int get_lens_index() const;

View File

@ -59,7 +59,7 @@ is_single_buffered() const {
////////////////////////////////////////////////////////////////////
INLINE bool FrameBufferProperties::
is_stereo() const {
return (_property[FBP_stereo] != 0);
return (_flags & FBF_stereo) != 0;
}
////////////////////////////////////////////////////////////////////
@ -189,9 +189,9 @@ get_back_buffers() const {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int FrameBufferProperties::
INLINE bool FrameBufferProperties::
get_indexed_color() const {
return _property[FBP_indexed_color];
return (_flags & FBF_indexed_color) != 0;
}
////////////////////////////////////////////////////////////////////
@ -199,9 +199,9 @@ get_indexed_color() const {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int FrameBufferProperties::
INLINE bool FrameBufferProperties::
get_rgb_color() const {
return _property[FBP_rgb_color];
return (_flags & FBF_rgb_color) != 0;
}
////////////////////////////////////////////////////////////////////
@ -209,9 +209,9 @@ get_rgb_color() const {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int FrameBufferProperties::
INLINE bool FrameBufferProperties::
get_stereo() const {
return _property[FBP_stereo];
return (_flags & FBF_stereo) != 0;
}
////////////////////////////////////////////////////////////////////
@ -219,9 +219,9 @@ get_stereo() const {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int FrameBufferProperties::
INLINE bool FrameBufferProperties::
get_force_hardware() const {
return _property[FBP_force_hardware];
return (_flags & FBF_force_hardware) != 0;
}
////////////////////////////////////////////////////////////////////
@ -229,9 +229,39 @@ get_force_hardware() const {
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int FrameBufferProperties::
INLINE bool FrameBufferProperties::
get_force_software() const {
return _property[FBP_force_software];
return (_flags & FBF_force_software) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::get_srgb_color
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool FrameBufferProperties::
get_srgb_color() const {
return (_flags & FBF_srgb_color) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::get_float_color
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool FrameBufferProperties::
get_float_color() const {
return (_flags & FBF_float_color) != 0;
}
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::get_float_depth
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool FrameBufferProperties::
get_float_depth() const {
return (_flags & FBF_float_depth) != 0;
}
////////////////////////////////////////////////////////////////////
@ -365,9 +395,13 @@ set_back_buffers(int n) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_indexed_color(int n) {
_property[FBP_indexed_color] = n;
_specified[FBP_indexed_color] = true;
set_indexed_color(bool n) {
if (n) {
_flags |= FBF_indexed_color;
} else {
_flags &= ~FBF_indexed_color;
}
_flags_specified |= FBF_indexed_color;
}
////////////////////////////////////////////////////////////////////
@ -376,9 +410,13 @@ set_indexed_color(int n) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_rgb_color(int n) {
_property[FBP_rgb_color] = n;
_specified[FBP_rgb_color] = true;
set_rgb_color(bool n) {
if (n) {
_flags |= FBF_rgb_color;
} else {
_flags &= ~FBF_rgb_color;
}
_flags_specified |= FBF_rgb_color;
}
////////////////////////////////////////////////////////////////////
@ -387,9 +425,13 @@ set_rgb_color(int n) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_stereo(int n) {
_property[FBP_stereo] = n;
_specified[FBP_stereo] = true;
set_stereo(bool n) {
if (n) {
_flags |= FBF_stereo;
} else {
_flags &= ~FBF_stereo;
}
_flags_specified |= FBF_stereo;
}
////////////////////////////////////////////////////////////////////
@ -398,9 +440,13 @@ set_stereo(int n) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_force_hardware(int n) {
_property[FBP_force_hardware] = n;
_specified[FBP_force_hardware] = true;
set_force_hardware(bool n) {
if (n) {
_flags |= FBF_force_hardware;
} else {
_flags &= ~FBF_force_hardware;
}
_flags_specified |= FBF_force_hardware;
}
////////////////////////////////////////////////////////////////////
@ -409,7 +455,56 @@ set_force_hardware(int n) {
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_force_software(int n) {
_property[FBP_force_software] = n;
_specified[FBP_force_software] = true;
set_force_software(bool n) {
if (n) {
_flags |= FBF_force_software;
} else {
_flags &= ~FBF_force_software;
}
_flags_specified |= FBF_force_software;
}
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::set_srgb_color
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_srgb_color(bool n) {
if (n) {
_flags |= FBF_srgb_color;
} else {
_flags &= ~FBF_srgb_color;
}
_flags_specified |= FBF_srgb_color;
}
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::set_float_color
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_float_color(bool n) {
if (n) {
_flags |= FBF_float_color;
} else {
_flags &= ~FBF_float_color;
}
_flags_specified |= FBF_float_color;
}
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::set_float_depth
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE void FrameBufferProperties::
set_float_depth(bool n) {
if (n) {
_flags |= FBF_float_depth;
} else {
_flags &= ~FBF_float_depth;
}
_flags_specified |= FBF_float_depth;
}

View File

@ -34,7 +34,10 @@ FrameBufferProperties() {
////////////////////////////////////////////////////////////////////
void FrameBufferProperties::
operator = (const FrameBufferProperties &copy) {
for (int i=0; i<FBP_COUNT; i++) {
_flags_specified = copy._flags_specified;
_flags = copy._flags;
for (int i = 0; i < FBP_COUNT; ++i) {
_specified[i] = copy._specified[i];
_property[i] = copy._property[i];
}
@ -49,11 +52,17 @@ operator = (const FrameBufferProperties &copy) {
////////////////////////////////////////////////////////////////////
bool FrameBufferProperties::
subsumes(const FrameBufferProperties &other) const {
for (int i=0; i<FBP_COUNT; i++) {
if (((other._flags & other._flags_specified) & ~(_flags & _flags_specified)) != 0) {
// The other has bits enabled that we don't have enabled.
return false;
}
for (int i = 0; i < FBP_COUNT; ++i) {
if (other._property[i] > _property[i]) {
return false;
}
}
return true;
}
@ -73,9 +82,9 @@ get_default() {
return default_props;
}
default_props.set_rgb_color(1);
default_props.set_rgb_color(true);
default_props.set_back_buffers(back_buffers);
int num_words = framebuffer_mode.get_num_words();
if (num_words > 0) {
display_cat.error()
@ -99,10 +108,10 @@ get_default() {
}
if (framebuffer_hardware) {
default_props.set_force_hardware(1);
default_props.set_force_hardware(true);
}
if (framebuffer_software) {
default_props.set_force_software(1);
default_props.set_force_software(true);
}
if (framebuffer_depth) {
default_props.set_depth_bits(1);
@ -120,7 +129,13 @@ get_default() {
default_props.set_multisamples(1);
}
if (framebuffer_stereo) {
default_props.set_stereo(1);
default_props.set_stereo(true);
}
if (framebuffer_srgb) {
default_props.set_srgb_color(true);
}
if (framebuffer_float) {
default_props.set_float_color(true);
}
if (depth_bits > 0) {
default_props.set_depth_bits(depth_bits);
@ -141,10 +156,9 @@ get_default() {
default_props.set_multisamples(multisamples);
}
if ((default_props._property[FBP_force_software])&&
(default_props._property[FBP_force_hardware])) {
default_props._property[FBP_force_software] = 0;
default_props._property[FBP_force_hardware] = 0;
if ((default_props._flags & FBF_force_software) != 0 &&
(default_props._flags & FBF_force_hardware) != 0){
default_props._flags &= ~(FBF_force_software | FBF_force_hardware);
}
default_ready = true;
@ -158,7 +172,11 @@ get_default() {
////////////////////////////////////////////////////////////////////
bool FrameBufferProperties::
operator == (const FrameBufferProperties &other) const {
for (int i=0; i<FBP_COUNT; i++) {
if ((_flags & _flags_specified) != (other._flags & other._flags_specified)) {
return false;
}
for (int i = 0; i < FBP_COUNT; ++i) {
if (_specified[i] != other._specified[i]) {
return false;
}
@ -166,6 +184,7 @@ operator == (const FrameBufferProperties &other) const {
return false;
}
}
return true;
}
@ -178,7 +197,10 @@ operator == (const FrameBufferProperties &other) const {
////////////////////////////////////////////////////////////////////
void FrameBufferProperties::
clear() {
for (int i=0; i<FBP_COUNT; i++) {
_flags = 0;
_flags_specified = 0;
for (int i = 0; i < FBP_COUNT; ++i) {
_specified[i] = 0;
_property[i] = 0;
}
@ -193,7 +215,10 @@ clear() {
////////////////////////////////////////////////////////////////////
void FrameBufferProperties::
add_properties(const FrameBufferProperties &other) {
for (int i=0; i<FBP_COUNT; i++) {
_flags &= ~other._flags_specified;
_flags |= other._flags & other._flags_specified;
for (int i = 0; i < FBP_COUNT; ++i) {
if (other._specified[i]) {
_property[i] = other._property[i];
_specified[i] = true;
@ -204,15 +229,25 @@ add_properties(const FrameBufferProperties &other) {
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::output
// Access: Published
// Description: Sets any properties that are explicitly specified in
// other on this object. Leaves other properties
// unchanged.
// Description: Generates a string representation.
////////////////////////////////////////////////////////////////////
void FrameBufferProperties::
output(ostream &out) const {
if ((_flags & FBF_float_depth) != 0) {
out << "float_depth ";
}
if (_property[FBP_depth_bits] > 0) {
out << "depth_bits=" << _property[FBP_depth_bits] << " ";
}
if ((_flags & FBF_float_color) != 0) {
out << "float_color ";
}
if ((_flags & FBF_srgb_color) != 0) {
out << "srgb_color ";
}
if ((_flags & FBF_indexed_color) != 0) {
out << "indexed_color ";
}
if (_property[FBP_color_bits] > 0) {
out << "color_bits=" << _property[FBP_color_bits] << " ";
}
@ -243,17 +278,14 @@ output(ostream &out) const {
if (_property[FBP_back_buffers] > 0) {
out << "back_buffers=" << _property[FBP_back_buffers] << " ";
}
if (_property[FBP_indexed_color] > 0) {
out << "indexed_color=" << _property[FBP_indexed_color] << " ";
if ((_flags & FBF_stereo) != 0) {
out << "stereo ";
}
if (_property[FBP_stereo] > 0) {
out << "stereo=" << _property[FBP_stereo] << " ";
if ((_flags & FBF_force_hardware) != 0) {
out << "force_hardware ";
}
if (_property[FBP_force_hardware] > 0) {
out << "force_hardware=" << _property[FBP_force_hardware] << " ";
}
if (_property[FBP_force_software] > 0) {
out << "force_software=" << _property[FBP_force_software] << " ";
if ((_flags & FBF_force_software) != 0) {
out << "force_software ";
}
}
@ -287,7 +319,7 @@ get_aux_mask() const {
int FrameBufferProperties::
get_buffer_mask() const {
int mask = 0;
if (_property[FBP_back_buffers] > 0) {
mask = RenderBuffer::T_front | RenderBuffer::T_back;
} else {
@ -310,7 +342,11 @@ get_buffer_mask() const {
////////////////////////////////////////////////////////////////////
bool FrameBufferProperties::
is_any_specified() const {
for (int i=0; i<FBP_COUNT; i++) {
if (_flags_specified != 0) {
return true;
}
for (int i = 0; i < FBP_COUNT; ++i) {
if (_specified[i]) {
return true;
}
@ -325,7 +361,9 @@ is_any_specified() const {
////////////////////////////////////////////////////////////////////
void FrameBufferProperties::
set_all_specified() {
for (int i=0; i<FBP_COUNT; i++) {
_flags_specified = FBF_all;
for (int i = 0; i < FBP_COUNT; ++i) {
_specified[i] = true;
}
}
@ -370,13 +408,22 @@ is_basic() const {
if (_property[FBP_back_buffers] > 0) {
return false;
}
if (_property[FBP_indexed_color] > 0) {
if ((_flags & FBF_indexed_color) != 0) {
return false;
}
if (_property[FBP_force_hardware] > 0) {
if ((_flags & FBF_force_hardware) != 0) {
return false;
}
if (_property[FBP_force_software] > 0) {
if ((_flags & FBF_force_software) != 0) {
return false;
}
if ((_flags & FBF_srgb_color) != 0) {
return false;
}
if ((_flags & FBF_float_color) != 0) {
return false;
}
if ((_flags & FBF_float_depth) != 0) {
return false;
}
return true;
@ -391,7 +438,7 @@ is_basic() const {
////////////////////////////////////////////////////////////////////
void FrameBufferProperties::
set_one_bit_per_channel() {
for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; ++prop) {
for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
if (_property[prop] > 1) {
_property[prop] = 1;
}
@ -426,13 +473,13 @@ set_one_bit_per_channel() {
int FrameBufferProperties::
get_quality(const FrameBufferProperties &reqs) const {
if ((_property[FBP_indexed_color]==0) && (_property[FBP_rgb_color]==0)) {
if (!get_indexed_color() && !get_rgb_color()) {
// Nonfunctioning window.
return 0;
}
if ((reqs._property[FBP_rgb_color] > _property[FBP_rgb_color])||
(reqs._property[FBP_indexed_color] > _property[FBP_indexed_color])) {
if ((reqs.get_rgb_color() && !get_rgb_color()) ||
(reqs.get_indexed_color() && !get_indexed_color())) {
// These properties are nonnegotiable.
return 0;
}
@ -441,17 +488,17 @@ get_quality(const FrameBufferProperties &reqs) const {
// Deduct for using the wrong kind of renderer (hardware or software).
// Cost: 10,000,000
if ((reqs._property[FBP_force_hardware] > _property[FBP_force_hardware])||
(reqs._property[FBP_force_software] > _property[FBP_force_software])) {
if ((reqs._flags & FBF_force_hardware) > (_flags & FBF_force_hardware) ||
(reqs._flags & FBF_force_software) > (_flags & FBF_force_software)) {
quality -= 10000000;
}
// Deduct for missing depth, color, alpha, stencil, or accum.
// Cost: 1,000,000
for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
if ((reqs._property[prop]) && (_property[prop]==0)) {
for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
if (reqs._property[prop] && _property[prop] == 0) {
quality -= 1000000;
}
}
@ -459,7 +506,7 @@ get_quality(const FrameBufferProperties &reqs) const {
// Deduct for missing aux bitplanes.
// Cost: 100,000
for (int prop=FBP_aux_rgba; prop<=FBP_aux_float; prop++) {
for (int prop = FBP_aux_rgba; prop <= FBP_aux_float; ++prop) {
if (reqs._property[prop] > _property[prop]) {
quality -= 100000;
}
@ -468,13 +515,31 @@ get_quality(const FrameBufferProperties &reqs) const {
// Deduct for stereo not enabled.
// Cost: 100,000
if (reqs._property[FBP_stereo] > _property[FBP_stereo]) {
if (reqs.get_stereo() && !get_stereo()) {
quality -= 100000;
}
// Deduct for not being sRGB-capable.
// Cost: 100,000
if (reqs.get_srgb_color() && !get_srgb_color()) {
quality -= 100000;
}
// Deduct for not having a floating-point format if we requested it.
// Cost: 100,000
if (reqs.get_float_color() && !get_float_color()) {
quality -= 100000;
}
if (reqs.get_float_depth() && !get_float_depth()) {
quality -= 100000;
}
// Deduct for insufficient back-buffers.
// Cost: 100,000
if (reqs._property[FBP_back_buffers] > _property[FBP_back_buffers]) {
quality -= 100000;
}
@ -488,7 +553,7 @@ get_quality(const FrameBufferProperties &reqs) const {
// Deduct for not enough bits in depth, color, alpha, stencil, or accum.
// Cost: 10,000
for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
if (_property[prop] != 0 && reqs._property[prop] > _property[prop]) {
quality -= 10000;
}
@ -497,33 +562,33 @@ get_quality(const FrameBufferProperties &reqs) const {
// deduct for insufficient multisamples.
// Cost: 1,000
if (_property[FBP_multisamples] != 0 &&
if (_property[FBP_multisamples] != 0 &&
reqs._property[FBP_multisamples] > _property[FBP_multisamples]) {
quality -= 1000;
}
// Deduct for unrequested bitplanes.
// Cost: 50
for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
if ((_property[prop]) && (reqs._property[prop] == 0)) {
quality -= 50;
}
}
for (int prop=FBP_aux_rgba; prop<=FBP_aux_float; prop++) {
for (int prop = FBP_aux_rgba; prop <= FBP_aux_float; ++prop) {
int extra = _property[prop] > reqs._property[prop];
if (extra > 0) {
extra = min(extra, 3);
quality -= extra*50;
}
}
// Deduct for excessive resolution in any bitplane (unless we asked
// for only 1 bit, which is the convention for any amount).
// Cost: 50
for (int prop=FBP_depth_bits; prop<=FBP_accum_bits; prop++) {
for (int prop = FBP_depth_bits; prop <= FBP_accum_bits; ++prop) {
if (reqs._property[prop] > 1 &&
_property[prop] > reqs._property[prop]) {
quality -= 50;
@ -555,9 +620,9 @@ get_quality(const FrameBufferProperties &reqs) const {
quality += _property[prop];
}
}
return quality;
};
}
////////////////////////////////////////////////////////////////////
// Function: FrameBufferProperties::verify_hardware_software
@ -594,8 +659,6 @@ verify_hardware_software(const FrameBufferProperties &props, const string &rende
<< "hardware/software configuration in your Config.prc file.\n";
return false;
}
return true;
}

View File

@ -44,18 +44,28 @@ private:
FBP_multisamples,
FBP_coverage_samples,
FBP_back_buffers,
FBP_indexed_color,
FBP_rgb_color,
FBP_stereo,
FBP_force_hardware,
FBP_force_software,
// This is a sentinel value.
FBP_COUNT
};
enum FrameBufferFlag {
FBF_indexed_color = 0x001,
FBF_rgb_color = 0x002,
FBF_stereo = 0x004,
FBF_force_hardware = 0x008,
FBF_force_software = 0x010,
FBF_srgb_color = 0x020,
FBF_float_color = 0x040,
FBF_float_depth = 0x080,
FBF_all = 0x100-1,
};
int _property[FBP_COUNT];
int _specified[FBP_COUNT];
bool _specified[FBP_COUNT];
int _flags;
int _flags_specified;
PUBLISHED:
@ -71,11 +81,14 @@ PUBLISHED:
INLINE int get_multisamples() const;
INLINE int get_coverage_samples() const;
INLINE int get_back_buffers() const;
INLINE int get_indexed_color() const;
INLINE int get_rgb_color() const;
INLINE int get_stereo() const;
INLINE int get_force_hardware() const;
INLINE int get_force_software() const;
INLINE bool get_indexed_color() const;
INLINE bool get_rgb_color() const;
INLINE bool get_stereo() const;
INLINE bool get_force_hardware() const;
INLINE bool get_force_software() const;
INLINE bool get_srgb_color() const;
INLINE bool get_float_color() const;
INLINE bool get_float_depth() const;
// Individual assigners.
INLINE void set_depth_bits(int n);
@ -89,11 +102,14 @@ PUBLISHED:
INLINE void set_multisamples(int n);
INLINE void set_coverage_samples(int n);
INLINE void set_back_buffers(int n);
INLINE void set_indexed_color(int n);
INLINE void set_rgb_color(int n);
INLINE void set_stereo(int n);
INLINE void set_force_hardware(int n);
INLINE void set_force_software(int n);
INLINE void set_indexed_color(bool n);
INLINE void set_rgb_color(bool n);
INLINE void set_stereo(bool n);
INLINE void set_force_hardware(bool n);
INLINE void set_force_software(bool n);
INLINE void set_srgb_color(bool n);
INLINE void set_float_color(bool n);
INLINE void set_float_depth(bool n);
// Other.
@ -111,9 +127,9 @@ PUBLISHED:
void add_properties(const FrameBufferProperties &other);
void output(ostream &out) const;
void set_one_bit_per_channel();
bool is_stereo() const;
bool is_single_buffered() const;
INLINE bool is_stereo() const;
INLINE bool is_single_buffered() const;
int get_quality(const FrameBufferProperties &reqs) const;
bool is_any_specified() const;
bool is_basic() const;

View File

@ -1094,7 +1094,58 @@ extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg) {
return gsg->extract_texture_data(tex);
}
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::dispatch_compute
// Access: Published
// Description: Asks the indicated GraphicsStateGuardian to dispatch
// the compute shader in the given ShaderAttrib using
// the given work group counts. This can act as an
// interface for running a one-off compute shader,
// without having to store it in the scene graph using
// a ComputeNode.
//
// Since this requires a round-trip to the draw thread,
// it may require waiting for the current thread to
// finish rendering if it is called in a multithreaded
// environment. However, you can call this several
// consecutive times on different textures for little
// additional cost.
//
// The return value is true if the operation is
// successful, false otherwise.
////////////////////////////////////////////////////////////////////
void GraphicsEngine::
dispatch_compute(const LVecBase3i &work_groups, const ShaderAttrib *sattr, GraphicsStateGuardian *gsg) {
ReMutexHolder holder(_lock);
CPT(RenderState) state = RenderState::make(sattr);
string draw_name = gsg->get_threading_model().get_draw_name();
if (draw_name.empty()) {
// A single-threaded environment. No problem.
} else {
// A multi-threaded environment. We have to wait until the draw
// thread has finished its current task.
WindowRenderer *wr = get_window_renderer(draw_name, 0);
RenderThread *thread = (RenderThread *)wr;
MutexHolder holder2(thread->_cv_mutex);
while (thread->_thread_state != TS_wait) {
thread->_cv_done.wait();
}
// OK, now the draw thread is idle. That's really good enough for
// our purposes; we don't *actually* need to make the draw thread
// do the work--it's sufficient that it's not doing anything else
// while we access the GSG.
}
gsg->set_state_and_transform(state, TransformState::make_identity());
gsg->dispatch_compute(work_groups[0], work_groups[1], work_groups[2]);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsEngine::get_global_ptr
// Access: Published, Static

View File

@ -108,6 +108,9 @@ PUBLISHED:
BLOCKING void flip_frame();
bool extract_texture_data(Texture *tex, GraphicsStateGuardian *gsg);
void dispatch_compute(const LVecBase3i &work_groups,
const ShaderAttrib *sattr,
GraphicsStateGuardian *gsg);
static GraphicsEngine *get_global_ptr();

View File

@ -655,6 +655,17 @@ get_supports_tessellation_shaders() const {
return _supports_tessellation_shaders;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_compute_shaders
// Access: Published
// Description: Returns true if this particular GSG supports
// compute shaders.
////////////////////////////////////////////////////////////////////
INLINE bool GraphicsStateGuardian::
get_supports_compute_shaders() const {
return _supports_compute_shaders;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_supports_glsl
// Access: Published

View File

@ -754,6 +754,17 @@ end_occlusion_query() {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::dispatch_compute
// Access: Public, Virtual
// Description: Dispatches a currently bound compute shader using
// the given work group counts.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
nassertv(false /* Compute shaders not supported by GSG */);
}
////////////////////////////////////////////////////////////////////
// Function: GraphicsStateGuardian::get_geom_munger
// Access: Public, Virtual
@ -1145,9 +1156,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
return &t;
}
case Shader::SMO_mat_constant_x: {
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
return &(np.node()->get_transform()->get_mat());
return &_target_shader->get_shader_input_matrix(name, t);
}
case Shader::SMO_vec_constant_x: {
const LVecBase4 &input = _target_shader->get_shader_input_vector(name);
@ -1169,8 +1178,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
return &(get_external_transform()->get_mat());
}
case Shader::SMO_view_to_model: {
// DANGER: SLOW AND NOT CACHEABLE!
t.invert_from(get_external_transform()->get_mat());
t = get_external_transform()->get_inverse()->get_mat();
return &t;
}
case Shader::SMO_apiview_to_view: {
@ -1216,7 +1224,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
t = get_scene()->get_camera_transform()->get_mat() *
invert(np.get_net_transform()->get_mat());
np.get_net_transform()->get_inverse()->get_mat();
return &t;
}
case Shader::SMO_apiview_x_to_view: {
@ -1231,7 +1239,7 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
t = (get_scene()->get_camera_transform()->get_mat() *
invert(np.get_net_transform()->get_mat()) *
np.get_net_transform()->get_inverse()->get_mat() *
LMatrix4::convert_mat(_coordinate_system, _internal_coordinate_system));
return &t;
}
@ -1252,21 +1260,35 @@ fetch_specified_part(Shader::ShaderMatInput part, InternalName *name, LMatrix4 &
nassertr(np.node()->is_of_type(LensNode::get_class_type()), &LMatrix4::ident_mat());
Lens *lens = DCAST(LensNode, np.node())->get_lens();
t = get_scene()->get_camera_transform()->get_mat() *
invert(np.get_net_transform()->get_mat()) *
np.get_net_transform()->get_inverse()->get_mat() *
LMatrix4::convert_mat(_coordinate_system, lens->get_coordinate_system()) *
lens->get_projection_mat(_current_stereo_channel);
return &t;
}
case Shader::SMO_apiclip_x_to_view: {
// NOT IMPLEMENTED
return &LMatrix4::ident_mat();
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
nassertr(np.node()->is_of_type(LensNode::get_class_type()), &LMatrix4::ident_mat());
Lens *lens = DCAST(LensNode, np.node())->get_lens();
t = calc_projection_mat(lens)->get_inverse()->get_mat() *
get_cs_transform_for(lens->get_coordinate_system())->get_inverse()->get_mat() *
np.get_net_transform()->get_mat() *
get_scene()->get_world_transform()->get_mat();
return &t;
}
case Shader::SMO_view_to_apiclip_x: {
// NOT IMPLEMENTED
return &LMatrix4::ident_mat();
const NodePath &np = _target_shader->get_shader_input_nodepath(name);
nassertr(!np.is_empty(), &LMatrix4::ident_mat());
nassertr(np.node()->is_of_type(LensNode::get_class_type()), &LMatrix4::ident_mat());
Lens *lens = DCAST(LensNode, np.node())->get_lens();
t = get_scene()->get_camera_transform()->get_mat() *
np.get_net_transform()->get_inverse()->get_mat() *
get_cs_transform_for(lens->get_coordinate_system())->get_mat() *
calc_projection_mat(lens)->get_mat();
return &t;
}
default:
// should never get here
nassertr(false /*should never get here*/, &LMatrix4::ident_mat());
return &LMatrix4::ident_mat();
}
}

View File

@ -145,6 +145,7 @@ PUBLISHED:
INLINE bool get_supports_basic_shaders() const;
INLINE bool get_supports_geometry_shaders() const;
INLINE bool get_supports_tessellation_shaders() const;
INLINE bool get_supports_compute_shaders() const;
INLINE bool get_supports_glsl() const;
INLINE bool get_supports_stencil() const;
INLINE bool get_supports_two_sided_stencil() const;
@ -225,6 +226,8 @@ public:
virtual void begin_occlusion_query();
virtual PT(OcclusionQueryContext) end_occlusion_query();
virtual void dispatch_compute(int size_x, int size_y, int size_z);
virtual PT(GeomMunger) get_geom_munger(const RenderState *state,
Thread *current_thread);
virtual PT(GeomMunger) make_geom_munger(const RenderState *state,
@ -487,10 +490,11 @@ protected:
bool _supports_basic_shaders;
bool _supports_geometry_shaders;
bool _supports_tessellation_shaders;
bool _supports_compute_shaders;
bool _supports_glsl;
bool _supports_framebuffer_multisample;
bool _supports_framebuffer_blit;
bool _supports_stencil;
bool _supports_stencil_wrap;
bool _supports_two_sided_stencil;

View File

@ -109,10 +109,10 @@ set_pixel_zoom(PN_stdfloat pixel_zoom) {
// indicated dimensions.
////////////////////////////////////////////////////////////////////
void StereoDisplayRegion::
set_dimensions(const LVecBase4 &dimensions) {
DisplayRegion::set_dimensions(dimensions);
_left_eye->set_dimensions(dimensions);
_right_eye->set_dimensions(dimensions);
set_dimensions(int i, const LVecBase4 &dimensions) {
DisplayRegion::set_dimensions(i, dimensions);
_left_eye->set_dimensions(i, dimensions);
_right_eye->set_dimensions(i, dimensions);
}
////////////////////////////////////////////////////////////////////

View File

@ -51,7 +51,7 @@ PUBLISHED:
virtual void set_pixel_zoom(PN_stdfloat pixel_zoom);
// Inherited from DisplayRegion
virtual void set_dimensions(const LVecBase4 &dimensions);
virtual void set_dimensions(int i, const LVecBase4 &dimensions);
virtual bool is_stereo() const;
virtual void set_camera(const NodePath &camera);
virtual void set_active(bool active);

View File

@ -63,12 +63,38 @@ is_any_specified() const {
// including decorations.
////////////////////////////////////////////////////////////////////
INLINE void WindowProperties::
set_origin(int x_origin, int y_origin) {
_x_origin = x_origin;
_y_origin = y_origin;
set_origin(const LPoint2i &origin) {
_origin = origin;
_specified |= S_origin;
}
////////////////////////////////////////////////////////////////////
// Function: WindowProperties::set_origin
// Access: Published
// Description: Specifies the origin on the screen (in pixels,
// relative to the top-left corner) at which the window
// should appear. This is the origin of the top-left
// corner of the useful part of the window, not
// including decorations.
////////////////////////////////////////////////////////////////////
INLINE void WindowProperties::
set_origin(int x_origin, int y_origin) {
_origin.set(x_origin, y_origin);
_specified |= S_origin;
}
////////////////////////////////////////////////////////////////////
// Function: WindowProperties::get_origin
// Access: Published
// Description: Returns the coordinates of the window's top-left
// corner, not including decorations.
////////////////////////////////////////////////////////////////////
INLINE const LPoint2i &WindowProperties::
get_origin() const {
nassertr(has_origin(), LPoint2i::zero());
return _origin;
}
////////////////////////////////////////////////////////////////////
// Function: WindowProperties::get_x_origin
// Access: Published
@ -78,7 +104,7 @@ set_origin(int x_origin, int y_origin) {
INLINE int WindowProperties::
get_x_origin() const {
nassertr(has_origin(), 0);
return _x_origin;
return _origin.get_x();
}
////////////////////////////////////////////////////////////////////
@ -90,7 +116,7 @@ get_x_origin() const {
INLINE int WindowProperties::
get_y_origin() const {
nassertr(has_origin(), 0);
return _y_origin;
return _origin.get_y();
}
////////////////////////////////////////////////////////////////////
@ -112,8 +138,20 @@ has_origin() const {
INLINE void WindowProperties::
clear_origin() {
_specified &= ~S_origin;
_x_origin = 0;
_y_origin = 0;
_origin = LPoint2i::zero();
}
////////////////////////////////////////////////////////////////////
// Function: WindowProperties::set_size
// Access: Published
// Description: Specifies the requested size of the window, in
// pixels. This is the size of the useful part of the
// window, not including decorations.
////////////////////////////////////////////////////////////////////
INLINE void WindowProperties::
set_size(const LVector2i &size) {
_size = size;
_specified |= S_size;
}
////////////////////////////////////////////////////////////////////
@ -125,11 +163,22 @@ clear_origin() {
////////////////////////////////////////////////////////////////////
INLINE void WindowProperties::
set_size(int x_size, int y_size) {
_x_size = x_size;
_y_size = y_size;
_size.set(x_size, y_size);
_specified |= S_size;
}
////////////////////////////////////////////////////////////////////
// Function: WindowProperties::get_origin
// Access: Published
// Description: Returns size in pixels of the useful part of the
// window, not including decorations.
////////////////////////////////////////////////////////////////////
INLINE const LVector2i &WindowProperties::
get_size() const {
nassertr(has_size(), LVector2i::zero());
return _size;
}
////////////////////////////////////////////////////////////////////
// Function: WindowProperties::get_x_size
// Access: Published
@ -140,7 +189,7 @@ set_size(int x_size, int y_size) {
INLINE int WindowProperties::
get_x_size() const {
nassertr(has_size(), 0);
return _x_size;
return _size.get_x();
}
////////////////////////////////////////////////////////////////////
@ -153,7 +202,7 @@ get_x_size() const {
INLINE int WindowProperties::
get_y_size() const {
nassertr(has_size(), 0);
return _y_size;
return _size.get_y();
}
////////////////////////////////////////////////////////////////////
@ -175,8 +224,7 @@ has_size() const {
INLINE void WindowProperties::
clear_size() {
_specified &= ~S_size;
_x_size = 0;
_y_size = 0;
_size = LVector2i::zero();
}
////////////////////////////////////////////////////////////////////

View File

@ -36,10 +36,8 @@ WindowProperties() {
void WindowProperties::
operator = (const WindowProperties &copy) {
_specified = copy._specified;
_x_origin = copy._x_origin;
_y_origin = copy._y_origin;
_x_size = copy._x_size;
_y_size = copy._y_size;
_origin = copy._origin;
_size = copy._size;
_title = copy._title;
_icon_filename = copy._icon_filename;
_cursor_filename = copy._cursor_filename;
@ -169,10 +167,8 @@ bool WindowProperties::
operator == (const WindowProperties &other) const {
return (_specified == other._specified &&
_flags == other._flags &&
_x_origin == other._x_origin &&
_y_origin == other._y_origin &&
_x_size == other._x_size &&
_y_size == other._y_size &&
_origin == other._origin &&
_size == other._size &&
_z_order == other._z_order &&
_title == other._title &&
_icon_filename == other._icon_filename &&
@ -191,10 +187,8 @@ operator == (const WindowProperties &other) const {
void WindowProperties::
clear() {
_specified = 0;
_x_origin = 0;
_y_origin = 0;
_x_size = 0;
_y_size = 0;
_origin = LPoint2i::zero();
_size = LVector2i::zero();
_title = string();
_icon_filename = Filename();
_cursor_filename = Filename();
@ -244,10 +238,10 @@ set_parent_window(size_t parent) {
void WindowProperties::
add_properties(const WindowProperties &other) {
if (other.has_origin()) {
set_origin(other.get_x_origin(), other.get_y_origin());
set_origin(other.get_origin());
}
if (other.has_size()) {
set_size(other.get_x_size(), other.get_y_size());
set_size(other.get_size());
}
if (other.has_title()) {
set_title(other.get_title());

View File

@ -19,7 +19,9 @@
#include "filename.h"
#include "pnotify.h"
#include "windowHandle.h"
#include "lpoint2.h"
#include "lvector2.h"
////////////////////////////////////////////////////////////////////
// Class : WindowProperties
// Description : A container for the various kinds of properties we
@ -57,14 +59,18 @@ PUBLISHED:
void clear();
INLINE bool is_any_specified() const;
INLINE void set_origin(const LPoint2i &origin);
INLINE void set_origin(int x_origin, int y_origin);
INLINE const LPoint2i &get_origin() const;
INLINE int get_x_origin() const;
INLINE int get_y_origin() const;
INLINE bool has_origin() const;
INLINE void clear_origin();
INLINE void set_size(const LVector2i &size);
INLINE void set_size(int x_size, int y_size);
INLINE const LVector2i &get_size() const;
INLINE int get_x_size() const;
INLINE int get_y_size() const;
INLINE bool has_size() const;
@ -73,7 +79,7 @@ PUBLISHED:
INLINE bool has_mouse_mode() const;
INLINE void set_mouse_mode(MouseMode mode);
INLINE MouseMode get_mouse_mode() const;
INLINE void clear_mouse_mode();
INLINE void clear_mouse_mode();
INLINE void set_title(const string &title);
INLINE const string &get_title() const;
@ -183,10 +189,8 @@ private:
};
int _specified;
int _x_origin;
int _y_origin;
int _x_size;
int _y_size;
LPoint2i _origin;
LVector2i _size;
MouseMode _mouse_mode;
string _title;
Filename _cursor_filename;

View File

@ -390,8 +390,6 @@ get_extra_extensions() {
// not defined.
////////////////////////////////////////////////////////////////////
void *eglGraphicsStateGuardian::
do_get_extension_func(const char *prefix, const char *name) {
string fullname = string(prefix) + string(name);
return (void *)eglGetProcAddress(fullname.c_str());
do_get_extension_func(const char *name) {
return (void *)eglGetProcAddress(name);
}

View File

@ -64,7 +64,7 @@ protected:
virtual void query_gl_version();
virtual void get_extra_extensions();
virtual void *do_get_extension_func(const char *prefix, const char *name);
virtual void *do_get_extension_func(const char *name);
private:
int _egl_version_major, _egl_version_minor;

View File

@ -96,11 +96,29 @@ typedef char GLchar;
#define GL_RG16F GL_RG16F_EXT
#define GL_RGB16F GL_RGB16F_EXT
#define GL_RGBA16F GL_RGBA16F_EXT
#define GL_RGB16F GL_RGB16F_EXT
#define GL_RGBA16F GL_RGBA16F_EXT
#define GL_RGB32F GL_RGB32F_EXT
#define GL_RGBA32F GL_RGBA32F_EXT
#define GL_DEBUG_SEVERITY_HIGH GL_DEBUG_SEVERITY_HIGH_KHR
#define GL_DEBUG_SEVERITY_MEDIUM GL_DEBUG_SEVERITY_MEDIUM_KHR
#define GL_DEBUG_SEVERITY_LOW GL_DEBUG_SEVERITY_LOW_KHR
#define GL_DEBUG_SEVERITY_NOTIFICATION GL_DEBUG_SEVERITY_NOTIFICATION_KHR
#define GL_DEBUG_OUTPUT_SYNCHRONOUS GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR
#define GL_FRAMEBUFFER_SRGB GL_FRAMEBUFFER_SRGB_EXT
#define GL_SRGB GL_SRGB_EXT
#define GL_SRGB_ALPHA GL_SRGB_ALPHA_EXT
#define GL_SRGB8 GL_SRGB8_EXT
#define GL_SRGB8_ALPHA GL_SRGB8_ALPHA_EXT
#define GL_SLUMINANCE GL_SLUMINANCE_NV
#define GL_SLUMINANCE_ALPHA GL_SLUMINANCE_ALPHA_NV
#define GL_SLUMINANCE8 GL_SLUMINANCE8_NV
#define GL_SLUMINANCE8_ALPHA GL_SLUMINANCE8_ALPHA_NV
#undef SUPPORT_IMMEDIATE_MODE
#define APIENTRY
#define APIENTRYP *
#include "glstuff_src.h"
#endif // GLES2GSG_H

View File

@ -110,11 +110,15 @@
#define GL_FUNC_SUBTRACT GL_FUNC_SUBTRACT_OES
#define GL_FUNC_REVERSE_SUBTRACT GL_FUNC_REVERSE_SUBTRACT_OES
#define GL_BGRA GL_BGRA_EXT
#define GL_RGB16F GL_RGB16F_EXT
#define GL_RGBA16F GL_RGBA16F_EXT
#define GL_RGB32F GL_RGB32F_EXT
#define GL_RGBA32F GL_RGBA32F_EXT
#undef SUPPORT_IMMEDIATE_MODE
#define APIENTRY
#define APIENTRYP *
#include "glstuff_src.h"
#endif // GLESGSG_H

View File

@ -0,0 +1,67 @@
// Filename: glCgShaderContext_src.h
// Created by: rdb (27Jun14)
//
////////////////////////////////////////////////////////////////////
//
// 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 OPENGLES_1
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::valid
// Access: Public
// Description: Returns true if the shader is "valid", ie, if the
// compilation was successful. The compilation could
// fail if there is a syntax error in the shader, or
// if the current video card isn't shader-capable,
// or if no shader languages are compiled into panda.
////////////////////////////////////////////////////////////////////
INLINE bool CLP(CgShaderContext)::
valid() {
if (_shader->get_error_flag()) return false;
if (_shader->get_language() != Shader::SL_Cg) return false;
if (_cg_context) return true;
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::uses_standard_vertex_arrays
// Access: Public
// Description: Returns true if the shader may need to access
// standard vertex attributes as passed by
// glVertexPointer and the like.
////////////////////////////////////////////////////////////////////
INLINE bool CLP(CgShaderContext)::
uses_standard_vertex_arrays() {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::uses_custom_vertex_arrays
// Access: Public
// Description: Always true, for now.
////////////////////////////////////////////////////////////////////
INLINE bool CLP(CgShaderContext)::
uses_custom_vertex_arrays() {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::uses_custom_texture_bindings
// Access: Public
// Description: Always true, for now.
////////////////////////////////////////////////////////////////////
INLINE bool CLP(CgShaderContext)::
uses_custom_texture_bindings() {
return true;
}
#endif // OPENGLES_1

View File

@ -0,0 +1,619 @@
// Filename: glCgShaderContext_src.cxx
// Created by: jyelon (01Sep05)
// Updated by: fperazzi, PandaSE (29Apr10) (updated CLP with note that some
// parameter types only supported under Cg)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#if defined(HAVE_CG) && !defined(OPENGLES)
#include "Cg/cgGL.h"
#include "pStatTimer.h"
TypeHandle CLP(CgShaderContext)::_type_handle;
#ifndef NDEBUG
#define cg_report_errors() { \
CGerror err = cgGetError(); \
if (err != CG_NO_ERROR) { \
GLCAT.error() << __FILE__ ", line " << __LINE__ << ": " << cgGetErrorString(err) << "\n"; \
} }
#else
#define cg_report_errors()
#endif
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::Constructor
// Access: Public
// Description: xyz
////////////////////////////////////////////////////////////////////
CLP(CgShaderContext)::
CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s) : ShaderContext(s) {
_glgsg = glgsg;
_cg_context = 0;
_cg_vprogram = 0;
_cg_fprogram = 0;
_cg_gprogram = 0;
_cg_vprofile = CG_PROFILE_UNKNOWN;
_cg_fprofile = CG_PROFILE_UNKNOWN;
_cg_gprofile = CG_PROFILE_UNKNOWN;
nassertv(s->get_language() == Shader::SL_Cg);
// Ask the shader to compile itself for us and
// to give us the resulting Cg program objects.
if (!s->cg_compile_for(_glgsg->_shader_caps,
_cg_context,
_cg_vprogram,
_cg_fprogram,
_cg_gprogram,
_cg_parameter_map)) {
return;
}
// Load the program.
if (_cg_vprogram != 0) {
_cg_vprofile = cgGetProgramProfile(_cg_vprogram);
cgGLLoadProgram(_cg_vprogram);
CGerror verror = cgGetError();
if (verror != CG_NO_ERROR) {
const char *str = cgGetErrorString(verror);
GLCAT.error()
<< "Could not load Cg vertex program: " << s->get_filename(Shader::ST_vertex)
<< " (" << cgGetProfileString(_cg_vprofile) << " " << str << ")\n";
release_resources();
}
}
if (_cg_fprogram != 0) {
_cg_fprofile = cgGetProgramProfile(_cg_fprogram);
cgGLLoadProgram(_cg_fprogram);
CGerror ferror = cgGetError();
if (ferror != CG_NO_ERROR) {
const char *str = cgGetErrorString(ferror);
GLCAT.error()
<< "Could not load Cg fragment program: " << s->get_filename(Shader::ST_fragment)
<< " (" << cgGetProfileString(_cg_fprofile) << " " << str << ")\n";
release_resources();
}
}
if (_cg_gprogram != 0) {
_cg_gprofile = cgGetProgramProfile(_cg_gprogram);
cgGLLoadProgram(_cg_gprogram);
CGerror gerror = cgGetError();
if (gerror != CG_NO_ERROR) {
const char *str = cgGetErrorString(gerror);
GLCAT.error()
<< "Could not load Cg geometry program: " << s->get_filename(Shader::ST_geometry)
<< " (" << cgGetProfileString(_cg_gprofile) << " " << str << ")\n";
release_resources();
}
}
_glgsg->report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::Destructor
// Access: Public
// Description: xyz
////////////////////////////////////////////////////////////////////
CLP(CgShaderContext)::
~CLP(CgShaderContext)() {
release_resources();
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::release_resources
// Access: Public
// Description: Should deallocate all system resources (such as
// vertex program handles or Cg contexts).
////////////////////////////////////////////////////////////////////
void CLP(CgShaderContext)::
release_resources() {
if (_cg_context) {
cgDestroyContext(_cg_context);
_cg_context = 0;
// Do *NOT* destroy the programs here! It causes problems.
// if (_cg_vprogram != 0) cgDestroyProgram(_cg_vprogram);
// if (_cg_fprogram != 0) cgDestroyProgram(_cg_fprogram);
// if (_cg_gprogram != 0) cgDestroyProgram(_cg_gprogram);
_cg_vprogram = 0;
_cg_fprogram = 0;
_cg_gprogram = 0;
_cg_parameter_map.clear();
}
if (_glgsg) {
_glgsg->report_my_gl_errors();
} else if (glGetError() != GL_NO_ERROR) {
GLCAT.error() << "GL error in ShaderContext destructor\n";
}
if (!_glgsg) {
return;
}
_glgsg->report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::bind
// Access: Public
// Description: This function is to be called to enable a new
// shader. It also initializes all of the shader's
// input parameters.
////////////////////////////////////////////////////////////////////
void CLP(CgShaderContext)::
bind(bool reissue_parameters) {
if (reissue_parameters) {
// Pass in k-parameters and transform-parameters
issue_parameters(Shader::SSD_general);
}
if (_cg_context != 0) {
// Bind the shaders.
if (_cg_vprogram != 0) {
cgGLEnableProfile(_cg_vprofile);
cgGLBindProgram(_cg_vprogram);
}
if (_cg_fprogram != 0) {
cgGLEnableProfile(_cg_fprofile);
cgGLBindProgram(_cg_fprogram);
}
if (_cg_gprogram != 0) {
cgGLEnableProfile(_cg_gprofile);
cgGLBindProgram(_cg_gprogram);
}
cg_report_errors();
_glgsg->report_my_gl_errors();
}
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::unbind
// Access: Public
// Description: This function disables a currently-bound shader.
////////////////////////////////////////////////////////////////////
void CLP(CgShaderContext)::
unbind() {
if (_cg_context != 0) {
if (_cg_vprogram != 0) {
cgGLUnbindProgram(_cg_vprofile);
cgGLDisableProfile(_cg_vprofile);
}
if (_cg_fprogram != 0) {
cgGLUnbindProgram(_cg_fprofile);
cgGLDisableProfile(_cg_fprofile);
}
if (_cg_gprogram != 0) {
cgGLUnbindProgram(_cg_gprofile);
cgGLDisableProfile(_cg_gprofile);
}
cg_report_errors();
_glgsg->report_my_gl_errors();
}
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::issue_parameters
// Access: Public
// Description: This function gets called whenever the RenderState
// or TransformState has changed, but the Shader
// itself has not changed. It loads new values into the
// shader's parameters.
//
// If "altered" is false, that means you promise that
// the parameters for this shader context have already
// been issued once, and that since the last time the
// parameters were issued, no part of the render
// state has changed except the external and internal
// transforms.
////////////////////////////////////////////////////////////////////
void CLP(CgShaderContext)::
issue_parameters(int altered) {
PStatTimer timer(_glgsg->_draw_set_state_shader_parameters_pcollector);
if (!valid()) {
return;
}
// Iterate through _ptr parameters
for (int i=0; i<(int)_shader->_ptr_spec.size(); i++) {
if (altered & (_shader->_ptr_spec[i]._dep[0] | _shader->_ptr_spec[i]._dep[1])) {
const Shader::ShaderPtrSpec& _ptr = _shader->_ptr_spec[i];
Shader::ShaderPtrData* ptr_data =
const_cast< Shader::ShaderPtrData*>(_glgsg->fetch_ptr_parameter(_ptr));
if (ptr_data == NULL){ //the input is not contained in ShaderPtrData
release_resources();
return;
}
//check if the data must be shipped to the GPU
/*if (!ptr_data->_updated)
continue;
ptr_data->_updated = false;*/
//Check if the size of the shader input and ptr_data match
int input_size = _ptr._dim[0] * _ptr._dim[1] * _ptr._dim[2];
// dimension is negative only if the parameter had the (deprecated)k_ prefix.
if ((input_size > ptr_data->_size) && (_ptr._dim[0] > 0)) {
GLCAT.error() << _ptr._id._name << ": incorrect number of elements, expected "
<< input_size <<" got " << ptr_data->_size << "\n";
release_resources();
return;
}
CGparameter p = _cg_parameter_map[_ptr._id._seqno];
switch (ptr_data->_type) {
case Shader::SPT_float:
switch(_ptr._info._class) {
case Shader::SAC_scalar: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
case Shader::SAC_vector:
switch(_ptr._info._type) {
case Shader::SAT_vec1: cgSetParameter1fv(p,(float*)ptr_data->_ptr); continue;
case Shader::SAT_vec2: cgSetParameter2fv(p,(float*)ptr_data->_ptr); continue;
case Shader::SAT_vec3: cgSetParameter3fv(p,(float*)ptr_data->_ptr); continue;
case Shader::SAT_vec4: cgSetParameter4fv(p,(float*)ptr_data->_ptr); continue;
}
case Shader::SAC_matrix: cgGLSetMatrixParameterfc(p,(float*)ptr_data->_ptr); continue;
case Shader::SAC_array: {
switch(_ptr._info._subclass) {
case Shader::SAC_scalar:
cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
case Shader::SAC_vector:
switch(_ptr._dim[2]) {
case 1: cgGLSetParameterArray1f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
case 2: cgGLSetParameterArray2f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
case 3: cgGLSetParameterArray3f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
case 4: cgGLSetParameterArray4f(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
}
case Shader::SAC_matrix:
cgGLSetMatrixParameterArrayfc(p,0,_ptr._dim[0],(float*)ptr_data->_ptr); continue;
}
}
}
case Shader::SPT_double:
switch(_ptr._info._class) {
case Shader::SAC_scalar: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
case Shader::SAC_vector:
switch(_ptr._info._type) {
case Shader::SAT_vec1: cgSetParameter1dv(p,(double*)ptr_data->_ptr); continue;
case Shader::SAT_vec2: cgSetParameter2dv(p,(double*)ptr_data->_ptr); continue;
case Shader::SAT_vec3: cgSetParameter3dv(p,(double*)ptr_data->_ptr); continue;
case Shader::SAT_vec4: cgSetParameter4dv(p,(double*)ptr_data->_ptr); continue;
}
case Shader::SAC_matrix: cgGLSetMatrixParameterdc(p,(double*)ptr_data->_ptr); continue;
case Shader::SAC_array: {
switch(_ptr._info._subclass) {
case Shader::SAC_scalar:
cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
case Shader::SAC_vector:
switch(_ptr._dim[2]) {
case 1: cgGLSetParameterArray1d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
case 2: cgGLSetParameterArray2d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
case 3: cgGLSetParameterArray3d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
case 4: cgGLSetParameterArray4d(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
}
case Shader::SAC_matrix:
cgGLSetMatrixParameterArraydc(p,0,_ptr._dim[0],(double*)ptr_data->_ptr); continue;
}
}
}
case Shader::SPT_int:
switch(_ptr._info._class) {
case Shader::SAC_scalar: cgSetParameter1iv(p,(int*)ptr_data->_ptr); continue;
case Shader::SAC_vector:
switch(_ptr._info._type) {
case Shader::SAT_vec1: cgSetParameter1iv(p,(int*)ptr_data->_ptr); continue;
case Shader::SAT_vec2: cgSetParameter2iv(p,(int*)ptr_data->_ptr); continue;
case Shader::SAT_vec3: cgSetParameter3iv(p,(int*)ptr_data->_ptr); continue;
case Shader::SAT_vec4: cgSetParameter4iv(p,(int*)ptr_data->_ptr); continue;
}
}
default: GLCAT.error() << _ptr._id._name << ":" << "unrecognized parameter type\n";
release_resources();
return;
}
}
}
for (int i=0; i<(int)_shader->_mat_spec.size(); i++) {
if (altered & (_shader->_mat_spec[i]._dep[0] | _shader->_mat_spec[i]._dep[1])) {
const LMatrix4 *val = _glgsg->fetch_specified_value(_shader->_mat_spec[i], altered);
if (!val) continue;
#ifndef STDFLOAT_DOUBLE
// In this case, the data is already single-precision.
const PN_float32 *data = val->get_data();
#else
// In this case, we have to convert it.
LMatrix4f valf = LCAST(PN_float32, *val);
const PN_float32 *data = valf.get_data();
#endif
CGparameter p = _cg_parameter_map[_shader->_mat_spec[i]._id._seqno];
switch (_shader->_mat_spec[i]._piece) {
case Shader::SMP_whole: GLfc(cgGLSetMatrixParameter)(p, data); continue;
case Shader::SMP_transpose: GLfr(cgGLSetMatrixParameter)(p, data); continue;
case Shader::SMP_col0: GLf(cgGLSetParameter4)(p, data[0], data[4], data[ 8], data[12]); continue;
case Shader::SMP_col1: GLf(cgGLSetParameter4)(p, data[1], data[5], data[ 9], data[13]); continue;
case Shader::SMP_col2: GLf(cgGLSetParameter4)(p, data[2], data[6], data[10], data[14]); continue;
case Shader::SMP_col3: GLf(cgGLSetParameter4)(p, data[3], data[7], data[11], data[15]); continue;
case Shader::SMP_row0: GLfv(cgGLSetParameter4)(p, data+ 0); continue;
case Shader::SMP_row1: GLfv(cgGLSetParameter4)(p, data+ 4); continue;
case Shader::SMP_row2: GLfv(cgGLSetParameter4)(p, data+ 8); continue;
case Shader::SMP_row3: GLfv(cgGLSetParameter4)(p, data+12); continue;
case Shader::SMP_row3x1: GLfv(cgGLSetParameter1)(p, data+12); continue;
case Shader::SMP_row3x2: GLfv(cgGLSetParameter2)(p, data+12); continue;
case Shader::SMP_row3x3: GLfv(cgGLSetParameter3)(p, data+12); continue;
case Shader::SMP_upper3x3:
{
LMatrix3f upper3 = val->get_upper_3();
GLfc(cgGLSetMatrixParameter)(p, upper3.get_data());
continue;
}
case Shader::SMP_transpose3x3:
{
LMatrix3f upper3 = val->get_upper_3();
GLfr(cgGLSetMatrixParameter)(p, upper3.get_data());
continue;
}
case Shader::SMP_cell15:
GLf(cgGLSetParameter1)(p, data[15]);
continue;
}
}
}
_glgsg->report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::disable_shader_vertex_arrays
// Access: Public
// Description: Disable all the vertex arrays used by this shader.
////////////////////////////////////////////////////////////////////
void CLP(CgShaderContext)::
disable_shader_vertex_arrays() {
if (!valid()) {
return;
}
for (int i=0; i<(int)_shader->_var_spec.size(); i++) {
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
if (p == 0) continue;
cgGLDisableClientState(p);
}
cg_report_errors();
_glgsg->report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::update_shader_vertex_arrays
// Access: Public
// Description: Disables all vertex arrays used by the previous
// shader, then enables all the vertex arrays needed
// by this shader. Extracts the relevant vertex array
// data from the gsg.
// The current implementation is inefficient, because
// it may unnecessarily disable arrays then immediately
// reenable them. We may optimize this someday.
////////////////////////////////////////////////////////////////////
bool CLP(CgShaderContext)::
update_shader_vertex_arrays(ShaderContext *prev, bool force) {
if (prev) {
prev->disable_shader_vertex_arrays();
}
if (!valid()) {
return true;
}
cg_report_errors();
#ifdef SUPPORT_IMMEDIATE_MODE
if (_glgsg->_use_sender) {
GLCAT.error() << "immediate mode shaders not implemented yet\n";
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
const GeomVertexArrayDataHandle *array_reader;
Geom::NumericType numeric_type;
int start, stride, num_values;
int nvarying = _shader->_var_spec.size();
for (int i = 0; i < nvarying; ++i) {
if (_cg_parameter_map[_shader->_var_spec[i]._id._seqno] == 0) {
continue;
}
InternalName *name = _shader->_var_spec[i]._name;
int texslot = _shader->_var_spec[i]._append_uv;
if (texslot >= 0 && texslot < _glgsg->_state_texture->get_num_on_stages()) {
TextureStage *stage = _glgsg->_state_texture->get_on_stage(texslot);
InternalName *texname = stage->get_texcoord_name();
if (name == InternalName::get_texcoord()) {
name = texname;
} else if (texname != InternalName::get_texcoord()) {
name = name->append(texname->get_basename());
}
}
if (_glgsg->_data_reader->get_array_info(name,
array_reader, num_values, numeric_type,
start, stride)) {
const unsigned char *client_pointer;
if (!_glgsg->setup_array_data(client_pointer, array_reader, force)) {
return false;
}
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
if (numeric_type == GeomEnums::NT_packed_dabc) {
cgGLSetParameterPointer(p, GL_BGRA, GL_UNSIGNED_BYTE,
stride, client_pointer + start);
} else {
if (name == InternalName::get_normal() && num_values == 4) {
// In some cases, the normals are aligned to 4 values.
// This would cause an error on some rivers, so we tell it
// to use the first three values only.
num_values = 3;
}
cgGLSetParameterPointer(p,
num_values, _glgsg->get_numeric_type(numeric_type),
stride, client_pointer + start);
}
cgGLEnableClientState(p);
} else {
CGparameter p = _cg_parameter_map[_shader->_var_spec[i]._id._seqno];
cgGLDisableClientState(p);
}
}
}
cg_report_errors();
_glgsg->report_my_gl_errors();
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::disable_shader_texture_bindings
// Access: Public
// Description: Disable all the texture bindings used by this shader.
////////////////////////////////////////////////////////////////////
void CLP(CgShaderContext)::
disable_shader_texture_bindings() {
if (!valid()) {
return;
}
#ifndef OPENGLES_2
for (int i=0; i<(int)_shader->_tex_spec.size(); i++) {
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
if (p == 0) continue;
int texunit = cgGetParameterResourceIndex(p);
_glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
#ifndef OPENGLES
glBindTexture(GL_TEXTURE_1D, 0);
#endif // OPENGLES
glBindTexture(GL_TEXTURE_2D, 0);
#ifndef OPENGLES_1
if (_glgsg->_supports_3d_texture) {
glBindTexture(GL_TEXTURE_3D, 0);
}
#endif // OPENGLES_1
#ifndef OPENGLES
if (_glgsg->_supports_2d_texture_array) {
glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);
}
#endif
if (_glgsg->_supports_cube_map) {
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
}
// This is probably faster - but maybe not as safe?
// cgGLDisableTextureParameter(p);
}
#endif // OPENGLES_2
cg_report_errors();
_glgsg->report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: GLCgShaderContext::update_shader_texture_bindings
// Access: Public
// Description: Disables all texture bindings used by the previous
// shader, then enables all the texture bindings needed
// by this shader. Extracts the relevant vertex array
// data from the gsg.
// The current implementation is inefficient, because
// it may unnecessarily disable textures then immediately
// reenable them. We may optimize this someday.
////////////////////////////////////////////////////////////////////
void CLP(CgShaderContext)::
update_shader_texture_bindings(ShaderContext *prev) {
if (prev) {
prev->disable_shader_texture_bindings();
}
if (!valid()) {
return;
}
// We get the TextureAttrib directly from the _target_rs, not the
// filtered TextureAttrib in _target_texture.
const TextureAttrib *texattrib = DCAST(TextureAttrib, _glgsg->_target_rs->get_attrib_def(TextureAttrib::get_class_slot()));
nassertv(texattrib != (TextureAttrib *)NULL);
for (int i = 0; i < (int)_shader->_tex_spec.size(); ++i) {
InternalName *id = _shader->_tex_spec[i]._name;
CGparameter p = _cg_parameter_map[_shader->_tex_spec[i]._id._seqno];
if (p == 0) {
continue;
}
int texunit = cgGetParameterResourceIndex(p);
Texture *tex = 0;
int view = _glgsg->get_current_tex_view_offset();
if (id != 0) {
const ShaderInput *input = _glgsg->_target_shader->get_shader_input(id);
tex = input->get_texture();
} 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);
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) {
continue;
}
tex = tex->load_related(_shader->_tex_spec[i]._suffix);
}
if ((tex == 0) || (tex->get_texture_type() != _shader->_tex_spec[i]._desired_type)) {
continue;
}
_glgsg->_glActiveTexture(GL_TEXTURE0 + texunit);
TextureContext *tc = tex->prepare_now(view, _glgsg->_prepared_objects, _glgsg);
if (tc == (TextureContext*)NULL) {
continue;
}
GLenum target = _glgsg->get_texture_target(tex->get_texture_type());
if (target == GL_NONE) {
// Unsupported texture mode.
continue;
}
if (!_glgsg->update_texture(tc, false)) {
continue;
}
_glgsg->apply_texture(tc);
}
cg_report_errors();
_glgsg->report_my_gl_errors();
}
#endif // OPENGLES_1

View File

@ -0,0 +1,89 @@
// Filename: glShaderContext_src.h
// Created by: jyelon (01Sep05)
//
////////////////////////////////////////////////////////////////////
//
// 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."
//
////////////////////////////////////////////////////////////////////
#if defined(HAVE_CG) && !defined(OPENGLES)
#include "pandabase.h"
#include "string_utils.h"
#include "internalName.h"
#include "shader.h"
#include "shaderContext.h"
#include "deletedChain.h"
#include <Cg/cg.h>
class CLP(GraphicsStateGuardian);
////////////////////////////////////////////////////////////////////
// Class : GLShaderContext
// Description : xyz
////////////////////////////////////////////////////////////////////
class EXPCL_GL CLP(CgShaderContext) : public ShaderContext {
public:
friend class CLP(GraphicsStateGuardian);
CLP(CgShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s);
~CLP(CgShaderContext)();
ALLOC_DELETED_CHAIN(CLP(CgShaderContext));
INLINE bool valid(void);
void bind(bool reissue_parameters = true);
void unbind();
void issue_parameters(int altered);
void disable_shader_vertex_arrays();
bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
void disable_shader_texture_bindings();
void update_shader_texture_bindings(ShaderContext *prev);
INLINE bool uses_standard_vertex_arrays(void);
INLINE bool uses_custom_vertex_arrays(void);
INLINE bool uses_custom_texture_bindings(void);
private:
CGcontext _cg_context;
CGprogram _cg_vprogram;
CGprogram _cg_fprogram;
CGprogram _cg_gprogram;
CGprofile _cg_vprofile;
CGprofile _cg_fprofile;
CGprofile _cg_gprofile;
pvector <CGparameter> _cg_parameter_map;
CLP(GraphicsStateGuardian) *_glgsg;
void release_resources();
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
TypedObject::init_type();
register_type(_type_handle, CLASSPREFIX_QUOTED "CgShaderContext",
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;
};
#include "glCgShaderContext_src.I"
#endif // OPENGLES_1

View File

@ -46,7 +46,7 @@ get_display_list(GLuint &index, const CLP(GeomMunger) *munger,
DisplayList &dl = _display_lists[(CLP(GeomMunger) *)munger];
bool list_current = (dl._modified == modified);
if (dl._index == 0) {
dl._index = GLP(GenLists)(1);
dl._index = glGenLists(1);
list_current = false;
if (munger != (CLP(GeomMunger) *)NULL) {
((CLP(GeomMunger) *)munger)->_geom_contexts.insert(this);
@ -87,7 +87,7 @@ release_display_lists() {
GLCAT.debug()
<< "releasing index " << (int)dl._index << "\n";
}
GLP(DeleteLists)(dl._index, 1);
glDeleteLists(dl._index, 1);
}
_display_lists.clear();

View File

@ -36,9 +36,9 @@ CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) :
_flags = 0;
if (CLP(interleaved_arrays)) {
if (gl_interleaved_arrays) {
_flags |= F_interleaved_arrays;
} else if (CLP(parallel_arrays)) {
} else if (gl_parallel_arrays) {
_flags |= F_parallel_arrays;
}
}
@ -46,7 +46,7 @@ CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) :
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::Destructor
// Access: Public, Virtual
// Description:
// Description:
////////////////////////////////////////////////////////////////////
CLP(GeomMunger)::
~CLP(GeomMunger)() {
@ -84,9 +84,13 @@ munge_format_impl(const GeomVertexFormat *orig,
PT(GeomVertexFormat) new_format = new GeomVertexFormat(*orig);
new_format->set_animation(animation);
CLP(GraphicsStateGuardian) *glgsg;
DCAST_INTO_R(glgsg, get_gsg(), NULL);
const GeomVertexColumn *color_type = orig->get_color_column();
if (color_type != (GeomVertexColumn *)NULL &&
color_type->get_numeric_type() == NT_packed_dabc) {
color_type->get_numeric_type() == NT_packed_dabc &&
!glgsg->_supports_packed_dabc) {
// We need to convert the color format; OpenGL doesn't support the
// byte order of DirectX's packed ARGB format.
int color_array = orig->get_array_with(InternalName::get_color());
@ -102,7 +106,7 @@ munge_format_impl(const GeomVertexFormat *orig,
if (animation.get_animation_type() == AT_hardware) {
// If we want hardware animation, we need to reserve space for the
// blend weights.
// Make sure the old weights and indices are removed, just in
// case.
new_format->remove_column(InternalName::get_transform_weight());
@ -116,11 +120,11 @@ munge_format_impl(const GeomVertexFormat *orig,
new_array_format->add_column
(InternalName::get_transform_weight(), animation.get_num_transforms() - 1,
NT_stdfloat, C_other);
if (animation.get_indexed_transforms()) {
// Also, if we'll be indexing into the transform table, reserve
// space for the index.
// TODO: We should examine the maximum palette index so we can
// decide whether we need 16-bit indices. That implies saving
// the maximum palette index, presumably in the AnimationSpec.
@ -129,7 +133,7 @@ munge_format_impl(const GeomVertexFormat *orig,
new_array_format->add_column
(InternalName::get_transform_index(), animation.get_num_transforms(),
NT_uint8, C_index);
}
}
new_format->add_array(new_array_format);
}
@ -149,16 +153,16 @@ munge_format_impl(const GeomVertexFormat *orig,
new_format->add_array(new_array_format);
}
format = GeomVertexFormat::register_format(new_format);
} else if ((_flags & F_interleaved_arrays) != 0) {
// Combine the primary data columns into a single array.
new_format = new GeomVertexFormat(*format);
PT(GeomVertexArrayFormat) new_array_format = new GeomVertexArrayFormat;
const GeomVertexColumn *column = format->get_vertex_column();
if (column != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(column->get_name(), column->get_num_components(),
(column->get_name(), column->get_num_components(),
column->get_numeric_type(), column->get_contents(),
-1, column->get_column_alignment());
new_format->remove_column(column->get_name());
@ -167,7 +171,7 @@ munge_format_impl(const GeomVertexFormat *orig,
column = format->get_normal_column();
if (column != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(column->get_name(), column->get_num_components(),
(column->get_name(), column->get_num_components(),
column->get_numeric_type(), column->get_contents(),
-1, column->get_column_alignment());
new_format->remove_column(column->get_name());
@ -176,7 +180,7 @@ munge_format_impl(const GeomVertexFormat *orig,
column = format->get_color_column();
if (column != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(column->get_name(), column->get_num_components(),
(column->get_name(), column->get_num_components(),
column->get_numeric_type(), column->get_contents(),
-1, column->get_column_alignment());
new_format->remove_column(column->get_name());
@ -187,7 +191,7 @@ munge_format_impl(const GeomVertexFormat *orig,
if (_texture != (TextureAttrib *)NULL) {
typedef pset<const InternalName *> UsedStages;
UsedStages used_stages;
int num_stages = _texture->get_num_on_stages();
for (int i = 0; i < num_stages; ++i) {
TextureStage *stage = _texture->get_on_stage(i);
@ -197,7 +201,7 @@ munge_format_impl(const GeomVertexFormat *orig,
if (used_stages.insert(name).second) {
// This is the first time we've encountered this texcoord name.
const GeomVertexColumn *texcoord_type = format->get_column(name);
if (texcoord_type != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(name, texcoord_type->get_num_values(), NT_stdfloat, C_texcoord,
@ -230,9 +234,13 @@ CPT(GeomVertexFormat) CLP(GeomMunger)::
premunge_format_impl(const GeomVertexFormat *orig) {
PT(GeomVertexFormat) new_format = new GeomVertexFormat(*orig);
CLP(GraphicsStateGuardian) *glgsg;
DCAST_INTO_R(glgsg, get_gsg(), NULL);
const GeomVertexColumn *color_type = orig->get_color_column();
if (color_type != (GeomVertexColumn *)NULL &&
color_type->get_numeric_type() == NT_packed_dabc) {
color_type->get_numeric_type() == NT_packed_dabc &&
!glgsg->_supports_packed_dabc) {
// We need to convert the color format; OpenGL doesn't support the
// byte order of DirectX's packed ARGB format.
int color_array = orig->get_array_with(InternalName::get_color());
@ -259,7 +267,7 @@ premunge_format_impl(const GeomVertexFormat *orig) {
new_format->add_array(new_array_format);
}
format = GeomVertexFormat::register_format(new_format);
} else {
// Combine the primary data columns into a single array. Unlike
// the munge case, above, in the premunge case, we do this even if
@ -269,11 +277,11 @@ premunge_format_impl(const GeomVertexFormat *orig) {
// at run time.
new_format = new GeomVertexFormat(*format);
PT(GeomVertexArrayFormat) new_array_format = new GeomVertexArrayFormat;
const GeomVertexColumn *column = format->get_vertex_column();
if (column != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(column->get_name(), column->get_num_components(),
(column->get_name(), column->get_num_components(),
column->get_numeric_type(), column->get_contents(),
-1, column->get_column_alignment());
new_format->remove_column(column->get_name());
@ -282,7 +290,7 @@ premunge_format_impl(const GeomVertexFormat *orig) {
column = format->get_normal_column();
if (column != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(column->get_name(), column->get_num_components(),
(column->get_name(), column->get_num_components(),
column->get_numeric_type(), column->get_contents(),
-1, column->get_column_alignment());
new_format->remove_column(column->get_name());
@ -291,7 +299,7 @@ premunge_format_impl(const GeomVertexFormat *orig) {
column = format->get_color_column();
if (column != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(column->get_name(), column->get_num_components(),
(column->get_name(), column->get_num_components(),
column->get_numeric_type(), column->get_contents(),
-1, column->get_column_alignment());
new_format->remove_column(column->get_name());
@ -303,7 +311,7 @@ premunge_format_impl(const GeomVertexFormat *orig) {
if (_texture != (TextureAttrib *)NULL) {
typedef pset<const InternalName *> UsedStages;
UsedStages used_stages;
int num_stages = _texture->get_num_on_stages();
for (int i = 0; i < num_stages; ++i) {
TextureStage *stage = _texture->get_on_stage(i);
@ -313,7 +321,7 @@ premunge_format_impl(const GeomVertexFormat *orig) {
if (used_stages.insert(name).second) {
// This is the first time we've encountered this texcoord name.
const GeomVertexColumn *texcoord_type = format->get_column(name);
if (texcoord_type != (const GeomVertexColumn *)NULL) {
new_array_format->add_column
(name, texcoord_type->get_num_values(), NT_stdfloat, C_texcoord,

View File

@ -73,9 +73,8 @@ CLP(GraphicsBuffer)(GraphicsEngine *engine, GraphicsPipe *pipe,
_rb_size_x = 0;
_rb_size_y = 0;
_rb_size_z = 0;
for (int i=0; i<RTP_COUNT; i++) {
for (int i = 0; i < RTP_COUNT; ++i) {
_rb[i] = 0;
_tex[i] = 0;
_rbm[i] = 0;
}
@ -170,6 +169,24 @@ begin_frame(FrameMode mode, Thread *current_thread) {
// rebuild_bitplanes().
return false;
}
// In case of multisample rendering, we don't need to issue
// the barrier until we call glBlitFramebuffer.
if (gl_enable_memory_barriers && _fbo_multisample == 0) {
CLP(GraphicsStateGuardian) *glgsg;
DCAST_INTO_R(glgsg, _gsg, false);
pvector<CLP(TextureContext)*>::iterator it;
for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) {
CLP(TextureContext) *gtc = *it;
if (gtc->needs_barrier(GL_FRAMEBUFFER_BARRIER_BIT)) {
glgsg->issue_memory_barrier(GL_FRAMEBUFFER_BARRIER_BIT);
// If we've done it for one, we've done it for all.
break;
}
}
}
}
_gsg->set_current_properties(&get_fb_properties());
@ -248,7 +265,9 @@ rebuild_bitplanes() {
DCAST_INTO_V(glgsg, _gsg);
if (!_needs_rebuild) {
if (_fbo.size() > 0) {
if (_fbo_multisample != 0) {
glgsg->bind_fbo(_fbo_multisample);
} else if (_fbo.size() > 0) {
glgsg->bind_fbo(_fbo[0]);
} else {
glgsg->bind_fbo(0);
@ -284,6 +303,7 @@ rebuild_bitplanes() {
// These variables indicate what should be bound to each bitplane.
Texture *attach[RTP_COUNT];
memset(attach, 0, sizeof(Texture *) * RTP_COUNT);
_texture_contexts.clear();
// Sort the textures list into appropriate slots.
{
@ -370,6 +390,11 @@ rebuild_bitplanes() {
// explicitly bound something to RTP_depth.
_use_depth_stencil = false;
} else if (_fb_properties.get_float_depth()) {
// Let's not bother with a depth-stencil buffer
// if a float buffer was requested.
_use_depth_stencil = false;
} else if (_fb_properties.get_depth_bits() > 24) {
// We can't give more than 24 depth bits with a depth-stencil buffer.
_use_depth_stencil = false;
@ -432,12 +457,13 @@ rebuild_bitplanes() {
bind_slot(layer, rb_resize, attach, RTP_color, next++);
if (_fb_properties.is_stereo()) {
// The texture has already been initialized, so bind it straight away.
// The second tex view has already been initialized, so bind it straight away.
if (attach[RTP_color] != NULL) {
attach_tex(layer, 1, attach[RTP_color], next++);
} else {
//XXX hack: I needed a slot to use, and we don't currently use RTP_stencil
// which is treated as a color attachment below, so this fits the bill.
// and it's treated as a color attachment below, so this fits the bill.
// Eventually, we might want to add RTP_color_left and RTP_color_right.
bind_slot(layer, rb_resize, attach, RTP_stencil, next++);
}
}
@ -548,7 +574,6 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
DCAST_INTO_V(glgsg, _gsg);
Texture *tex = attach[slot];
_tex[slot] = tex;
if (tex && layer >= tex->get_z_size()) {
// If the requested layer index exceeds the number of layers
@ -582,7 +607,10 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
// Adjust the texture format based on the requested framebuffer settings.
switch (slot) {
case RTP_depth:
if (_fb_properties.get_depth_bits() > 24) {
if (_fb_properties.get_float_depth()) {
tex->set_format(Texture::F_depth_component32);
tex->set_component_type(Texture::T_float);
} else if (_fb_properties.get_depth_bits() > 24) {
tex->set_format(Texture::F_depth_component32);
} else if (_fb_properties.get_depth_bits() > 16) {
tex->set_format(Texture::F_depth_component24);
@ -594,7 +622,12 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
break;
case RTP_depth_stencil:
tex->set_format(Texture::F_depth_stencil);
tex->set_component_type(Texture::T_unsigned_int_24_8);
if (_fb_properties.get_float_depth()) {
tex->set_component_type(Texture::T_float);
} else {
tex->set_component_type(Texture::T_unsigned_int_24_8);
}
break;
case RTP_aux_hrgba_0:
case RTP_aux_hrgba_1:
@ -611,16 +644,24 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
tex->set_component_type(Texture::T_float);
break;
default:
if (_fb_properties.get_color_bits() > 48) {
tex->set_format(Texture::F_rgba32);
// Currently a float format. Should change.
tex->set_component_type(Texture::T_float);
} else if (_fb_properties.get_color_bits() > 24) {
tex->set_format(Texture::F_rgba16);
// Currently a float format. Should change.
tex->set_component_type(Texture::T_float);
if (_fb_properties.get_srgb_color()) {
if (_fb_properties.get_alpha_bits() == 0) {
tex->set_format(Texture::F_srgb);
} else {
tex->set_format(Texture::F_srgb_alpha);
}
} else {
tex->set_format(Texture::F_rgba);
if (_fb_properties.get_float_color()) {
tex->set_component_type(Texture::T_float);
}
if (_fb_properties.get_color_bits() > 16 * 3) {
tex->set_format(Texture::F_rgba32);
tex->set_component_type(Texture::T_float);
} else if (_fb_properties.get_color_bits() > 8 * 3) {
tex->set_format(Texture::F_rgba16);
} else {
tex->set_format(Texture::F_rgba);
}
}
}
@ -638,7 +679,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
#ifndef OPENGLES
GLint depth_size = 0;
GLP(GetTexLevelParameteriv)(target, 0, GL_TEXTURE_DEPTH_SIZE, &depth_size);
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_DEPTH_SIZE, &depth_size);
_fb_properties.set_depth_bits(depth_size);
#endif
@ -649,7 +690,7 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
#ifndef OPENGLES
GLint stencil_size = 0;
GLP(GetTexLevelParameteriv)(target, 0, GL_TEXTURE_STENCIL_SIZE, &stencil_size);
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_STENCIL_SIZE, &stencil_size);
_fb_properties.set_stencil_bits(stencil_size);
#endif
}
@ -662,10 +703,10 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
#ifndef OPENGLES
if (attachpoint == GL_COLOR_ATTACHMENT0_EXT) {
GLint red_size = 0, green_size = 0, blue_size = 0, alpha_size = 0;
GLP(GetTexLevelParameteriv)(target, 0, GL_TEXTURE_RED_SIZE, &red_size);
GLP(GetTexLevelParameteriv)(target, 0, GL_TEXTURE_GREEN_SIZE, &green_size);
GLP(GetTexLevelParameteriv)(target, 0, GL_TEXTURE_BLUE_SIZE, &blue_size);
GLP(GetTexLevelParameteriv)(target, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_RED_SIZE, &red_size);
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_GREEN_SIZE, &green_size);
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_BLUE_SIZE, &blue_size);
glGetTexLevelParameteriv(target, 0, GL_TEXTURE_ALPHA_SIZE, &alpha_size);
_fb_properties.set_color_bits(red_size + green_size + blue_size);
_fb_properties.set_alpha_bits(alpha_size);
@ -730,10 +771,16 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
GLuint gl_format = GL_RGBA;
switch (slot) {
case RTP_depth_stencil:
gl_format = GL_DEPTH_STENCIL_EXT;
if (_fb_properties.get_float_depth()) {
gl_format = GL_DEPTH32F_STENCIL8;
} else {
gl_format = GL_DEPTH24_STENCIL8;
}
break;
case RTP_depth:
if (_fb_properties.get_depth_bits() > 24) {
if (_fb_properties.get_float_depth()) {
gl_format = GL_DEPTH_COMPONENT32F;
} else if (_fb_properties.get_depth_bits() > 24) {
gl_format = GL_DEPTH_COMPONENT32;
} else if (_fb_properties.get_depth_bits() > 16) {
gl_format = GL_DEPTH_COMPONENT24;
@ -763,7 +810,41 @@ bind_slot(int layer, bool rb_resize, Texture **attach, RenderTexturePlane slot,
break;
default:
if (_fb_properties.get_alpha_bits() == 0) {
gl_format = GL_RGB;
if (_fb_properties.get_srgb_color()) {
gl_format = GL_SRGB8;
} else if (_fb_properties.get_float_color()) {
if (_fb_properties.get_color_bits() > 16 * 3) {
gl_format = GL_RGB32F_ARB;
} else {
gl_format = GL_RGB16F_ARB;
}
} else {
if (_fb_properties.get_color_bits() > 16 * 3) {
gl_format = GL_RGBA32F_ARB;
} else if (_fb_properties.get_color_bits() > 8 * 3) {
gl_format = GL_RGB16_EXT;
} else {
gl_format = GL_RGB;
}
}
} else {
if (_fb_properties.get_srgb_color()) {
gl_format = GL_SRGB8_ALPHA8;
} else if (_fb_properties.get_float_color()) {
if (_fb_properties.get_color_bits() > 16 * 3) {
gl_format = GL_RGBA32F_ARB;
} else {
gl_format = GL_RGBA16F_ARB;
}
} else {
if (_fb_properties.get_color_bits() > 16 * 3) {
gl_format = GL_RGB32F_ARB;
} else if (_fb_properties.get_color_bits() > 8 * 3) {
gl_format = GL_RGB16_EXT;
} else {
gl_format = GL_RGB;
}
}
}
};
#endif
@ -986,7 +1067,10 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) {
TextureContext *tc = attach->prepare_now(view, glgsg->get_prepared_objects(), glgsg);
nassertv(tc != (TextureContext *)NULL);
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
glgsg->update_texture(tc, true);
glgsg->update_texture(gtc, true);
gtc->set_active(true);
_texture_contexts.push_back(gtc);
#ifndef OPENGLES
GLclampf priority = 1.0f;
@ -1037,23 +1121,26 @@ attach_tex(int layer, int view, Texture *attach, GLenum attachpoint) {
////////////////////////////////////////////////////////////////////
void CLP(GraphicsBuffer)::
generate_mipmaps() {
if (gl_ignore_mipmaps && !gl_force_mipmaps) {
return;
}
CLP(GraphicsStateGuardian) *glgsg;
DCAST_INTO_V(glgsg, _gsg);
for (int slot=0; slot<RTP_COUNT; slot++) {
Texture *tex = _tex[slot];
if ((tex != 0) && (tex->uses_mipmaps())) {
pvector<CLP(TextureContext)*>::iterator it;
for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) {
CLP(TextureContext) *gtc = *it;
if (gtc->_generate_mipmaps) {
glgsg->_state_texture = 0;
TextureContext *tc = tex->prepare_now(0, glgsg->get_prepared_objects(), glgsg);
nassertv(tc != (TextureContext *)NULL);
CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
glgsg->update_texture(tc, true);
GLenum target = glgsg->get_texture_target(tex->get_texture_type());
GLP(BindTexture)(target, gtc->_index);
glgsg->_glGenerateMipmap(target);
GLP(BindTexture)(target, 0);
glgsg->update_texture(gtc, true);
glgsg->apply_texture(gtc);
glgsg->_glGenerateMipmap(gtc->_target);
glBindTexture(gtc->_target, 0);
}
}
report_my_gl_errors();
}
@ -1136,8 +1223,12 @@ select_target_tex_page(int page) {
resolve_multisamples();
}
}
glgsg->bind_fbo(_fbo[page]);
if (_fbo_multisample != 0) {
// TODO: re-issue clears?
} else {
glgsg->bind_fbo(_fbo[page]);
}
_bound_tex_page = page;
}
@ -1160,7 +1251,7 @@ open_buffer() {
// Count total color buffers.
int totalcolor =
(_fb_properties.is_stereo() ? 2 : 1) +
(_fb_properties.get_stereo() ? 2 : 1) +
_fb_properties.get_aux_rgba() +
_fb_properties.get_aux_hrgba() +
_fb_properties.get_aux_float();
@ -1215,12 +1306,37 @@ open_buffer() {
_fb_properties.set_alpha_bits(32);
}
if (_fb_properties.get_float_depth()) {
// GL_DEPTH_COMPONENT32F seems the only depth float format.
_fb_properties.set_depth_bits(32);
}
// We currently only support color formats this big as float.
if (_fb_properties.get_color_bits() > 16 * 3) {
_fb_properties.set_color_bits(32 * 3);
_fb_properties.set_float_color(true);
if (_fb_properties.get_alpha_bits() > 0) {
_fb_properties.set_alpha_bits(32);
}
}
if (_fb_properties.get_srgb_color()) {
_fb_properties.set_color_bits(24);
_fb_properties.set_float_color(false);
if (_fb_properties.get_alpha_bits() > 0) {
_fb_properties.set_alpha_bits(32);
}
}
if (!_gsg->get_supports_depth_stencil()) {
// At least we know we won't be getting stencil bits.
_fb_properties.set_stencil_bits(0);
}
_fb_properties.set_accum_bits(0);
_fb_properties.set_multisamples(_host->get_fb_properties().get_multisamples());
_fb_properties.set_multisamples(_requested_multisamples);
// Update aux settings to reflect the GL_MAX_DRAW_BUFFERS limit,
// if we exceed it, that is.
@ -1293,7 +1409,6 @@ close_buffer() {
glgsg->_glDeleteRenderbuffers(1, &(_rb[i]));
_rb[i] = 0;
}
_tex[i] = 0;
}
// Delete the renderbuffers.
for (int i=0; i<RTP_COUNT; i++) {
@ -1301,7 +1416,6 @@ close_buffer() {
glgsg->_glDeleteRenderbuffers(1, &(_rbm[i]));
_rb[i] = 0;
}
_tex[i] = 0;
}
_rb_size_x = 0;
_rb_size_y = 0;
@ -1492,6 +1606,21 @@ resolve_multisamples() {
nassertv(_fbo.size() > 0);
if (gl_enable_memory_barriers) {
// Issue memory barriers as necessary to make sure that the
// texture memory is synchronized before we blit to it.
pvector<CLP(TextureContext)*>::iterator it;
for (it = _texture_contexts.begin(); it != _texture_contexts.end(); ++it) {
CLP(TextureContext) *gtc = *it;
if (gtc->needs_barrier(GL_FRAMEBUFFER_BARRIER_BIT)) {
glgsg->issue_memory_barrier(GL_FRAMEBUFFER_BARRIER_BIT);
// If we've done it for one, we've done it for all.
break;
}
}
}
glgsg->report_my_gl_errors();
GLuint fbo = _fbo[0];
if (_bound_tex_page != -1) {
@ -1501,31 +1630,34 @@ resolve_multisamples() {
glgsg->_glBindFramebuffer(GL_READ_FRAMEBUFFER_EXT, _fbo_multisample);
// If the depth buffer is shared, resolve it only on the last to render FBO.
int do_depth_blit = 0;
if (_shared_depth_buffer) {
CLP(GraphicsBuffer) *graphics_buffer = NULL;
CLP(GraphicsBuffer) *highest_sort_graphics_buffer = NULL;
list <CLP(GraphicsBuffer) *>::iterator graphics_buffer_iterator;
int max_sort_order = 0;
for (graphics_buffer_iterator = _shared_depth_buffer_list.begin();
graphics_buffer_iterator != _shared_depth_buffer_list.end();
graphics_buffer_iterator++) {
graphics_buffer = (*graphics_buffer_iterator);
if (graphics_buffer) {
// this call removes the entry from the list
if ( graphics_buffer->get_sort() >= max_sort_order ) {
max_sort_order = graphics_buffer->get_sort();
highest_sort_graphics_buffer = graphics_buffer;
bool do_depth_blit = false;
if (_rbm[RTP_depth_stencil] != 0 || _rbm[RTP_depth] != 0) {
if (_shared_depth_buffer) {
CLP(GraphicsBuffer) *graphics_buffer = NULL;
CLP(GraphicsBuffer) *highest_sort_graphics_buffer = NULL;
list <CLP(GraphicsBuffer) *>::iterator graphics_buffer_iterator;
int max_sort_order = 0;
for (graphics_buffer_iterator = _shared_depth_buffer_list.begin();
graphics_buffer_iterator != _shared_depth_buffer_list.end();
graphics_buffer_iterator++) {
graphics_buffer = (*graphics_buffer_iterator);
if (graphics_buffer) {
// this call removes the entry from the list
if (graphics_buffer->get_sort() >= max_sort_order) {
max_sort_order = graphics_buffer->get_sort();
highest_sort_graphics_buffer = graphics_buffer;
}
}
}
if (max_sort_order == this->get_sort()) {
do_depth_blit = true;
}
} else {
do_depth_blit = true;
}
if (max_sort_order == this->get_sort()) {
do_depth_blit = 1;
}
} else {
do_depth_blit = 1;
}
if (do_depth_blit) {
glgsg->_glBlitFramebuffer(0, 0, _rb_size_x, _rb_size_y, 0, 0, _rb_size_x, _rb_size_y,
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
@ -1535,7 +1667,6 @@ resolve_multisamples() {
GL_COLOR_BUFFER_BIT,
GL_NEAREST);
}
#ifndef OPENGLES
// Now handle the other color buffers.
int next = GL_COLOR_ATTACHMENT1_EXT;
if (_fb_properties.is_stereo()) {
@ -1545,6 +1676,7 @@ resolve_multisamples() {
GL_COLOR_BUFFER_BIT, GL_NEAREST);
next += 1;
}
#ifndef OPENGLES
for (int i = 0; i < _fb_properties.get_aux_rgba(); ++i) {
glReadBuffer(next);
glDrawBuffer(next);

View File

@ -120,13 +120,15 @@ private:
int _rb_size_y;
int _rb_size_z;
// The texture or render buffer bound to each plane.
PT(Texture) _tex[RTP_COUNT];
// Stores the render buffers for each plane.
// _rbm stores the multisample renderbuffers.
GLuint _rb[RTP_COUNT];
// The render buffer for _fbo_multisample.
GLuint _rbm[RTP_COUNT];
// List of textures for which we might have to generate mipmaps
// after rendering one frame.
pvector<CLP(TextureContext)*> _texture_contexts;
// The cube map face we are currently drawing to or have just
// finished drawing to, or -1 if we are not drawing to a cube map.
int _bound_tex_page;

View File

@ -27,7 +27,7 @@
INLINE bool CLP(GraphicsStateGuardian)::
report_errors(int line, const char *source_file) {
#ifndef NDEBUG
GLenum error_code = GLP(GetError)();
GLenum error_code = glGetError();
if (error_code != GL_NO_ERROR) {
int error_count = 0;
return report_errors_loop(line, source_file, error_code, error_count);
@ -45,8 +45,8 @@ report_errors(int line, const char *source_file) {
INLINE void CLP(GraphicsStateGuardian)::
report_my_errors(int line, const char *source_file) {
#ifndef NDEBUG
if (_track_errors) {
GLenum error_code = GLP(GetError)();
if (_check_errors) {
GLenum error_code = glGetError();
if (error_code != GL_NO_ERROR) {
if (!report_errors_loop(line, source_file, error_code, _error_count)) {
panic_deactivate();
@ -69,7 +69,7 @@ report_my_errors(int line, const char *source_file) {
////////////////////////////////////////////////////////////////////
INLINE bool CLP(GraphicsStateGuardian)::
clear_errors(int line, const char *source_file) {
GLenum error_code = GLP(GetError)();
GLenum error_code = glGetError();
if (error_code != GL_NO_ERROR) {
int error_count = 0;
return report_errors_loop(line, source_file, error_code, error_count);
@ -83,7 +83,7 @@ clear_errors(int line, const char *source_file) {
// Access: Public
// Description: This works like report_my_errors(), except that it
// always runs, even in the NDEBUG case (but not when
// _track_errors is false), and it never calls
// _check_errors is false), and it never calls
// panic_deactivate(). It is designed to be called when
// it is important to clear the error stack (for
// instance, because we want to be able to reliably
@ -91,8 +91,8 @@ clear_errors(int line, const char *source_file) {
////////////////////////////////////////////////////////////////////
INLINE void CLP(GraphicsStateGuardian)::
clear_my_errors(int line, const char *source_file) {
if (_track_errors) {
GLenum error_code = GLP(GetError)();
if (_check_errors) {
GLenum error_code = glGetError();
if (error_code != GL_NO_ERROR) {
int error_count = 0;
report_errors_loop(line, source_file, error_code, error_count);
@ -161,8 +161,8 @@ get_gl_version_minor() const {
INLINE void CLP(GraphicsStateGuardian)::
maybe_gl_finish() const {
#ifdef DO_PSTATS
if (CLP(finish)) {
GLP(Finish)();
if (gl_finish) {
glFinish();
}
#endif
}
@ -231,12 +231,12 @@ enable_multisample_antialias(bool val) {
// Turn off antialias multisample.
_multisample_mode &= ~MM_antialias;
if (_multisample_mode == 0) {
GLP(Disable)(GL_MULTISAMPLE);
glDisable(GL_MULTISAMPLE);
}
} else if ((_multisample_mode & MM_antialias) == 0 && val) {
// Turn on antialias multisample.
if (_multisample_mode == 0) {
GLP(Enable)(GL_MULTISAMPLE);
glEnable(GL_MULTISAMPLE);
}
_multisample_mode |= MM_antialias;
}
@ -258,16 +258,16 @@ enable_multisample_alpha_one(bool val) {
if ((_multisample_mode & MM_alpha_one) != 0 && !val) {
// Turn off sample_alpha_to_one multisample.
_multisample_mode &= ~MM_alpha_one;
GLP(Disable)(GL_SAMPLE_ALPHA_TO_ONE);
glDisable(GL_SAMPLE_ALPHA_TO_ONE);
if (_multisample_mode == 0) {
GLP(Disable)(GL_MULTISAMPLE);
glDisable(GL_MULTISAMPLE);
}
} else if ((_multisample_mode & MM_alpha_one) == 0 && val) {
// Turn on sample_alpha_to_one multisample.
if (_multisample_mode == 0) {
GLP(Enable)(GL_MULTISAMPLE);
glEnable(GL_MULTISAMPLE);
}
GLP(Enable)(GL_SAMPLE_ALPHA_TO_ONE);
glEnable(GL_SAMPLE_ALPHA_TO_ONE);
_multisample_mode |= MM_alpha_one;
}
}
@ -288,16 +288,16 @@ enable_multisample_alpha_mask(bool val) {
if ((_multisample_mode & MM_alpha_mask) != 0 && !val) {
// Turn off sample_alpha_to_mask multisample.
_multisample_mode &= ~MM_alpha_mask;
GLP(Disable)(GL_SAMPLE_ALPHA_TO_COVERAGE);
glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
if (_multisample_mode == 0) {
GLP(Disable)(GL_MULTISAMPLE);
glDisable(GL_MULTISAMPLE);
}
} else if ((_multisample_mode & MM_alpha_mask) == 0 && val) {
// Turn on sample_alpha_to_mask multisample.
if (_multisample_mode == 0) {
GLP(Enable)(GL_MULTISAMPLE);
glEnable(GL_MULTISAMPLE);
}
GLP(Enable)(GL_SAMPLE_ALPHA_TO_COVERAGE);
glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
_multisample_mode |= MM_alpha_mask;
}
}
@ -316,9 +316,9 @@ enable_line_smooth(bool val) {
_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
_line_smooth_enabled = val;
if (val) {
GLP(Enable)(GL_LINE_SMOOTH);
glEnable(GL_LINE_SMOOTH);
} else {
GLP(Disable)(GL_LINE_SMOOTH);
glDisable(GL_LINE_SMOOTH);
}
}
#endif
@ -336,9 +336,9 @@ enable_point_smooth(bool val) {
_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
_point_smooth_enabled = val;
if (val) {
GLP(Enable)(GL_POINT_SMOOTH);
glEnable(GL_POINT_SMOOTH);
} else {
GLP(Disable)(GL_POINT_SMOOTH);
glDisable(GL_POINT_SMOOTH);
}
}
#endif
@ -355,9 +355,9 @@ enable_polygon_smooth(bool val) {
if (_polygon_smooth_enabled != val) {
_polygon_smooth_enabled = val;
if (val) {
GLP(Enable)(GL_POLYGON_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
} else {
GLP(Disable)(GL_POLYGON_SMOOTH);
glDisable(GL_POLYGON_SMOOTH);
}
}
#endif // OPENGLES
@ -448,13 +448,13 @@ enable_stencil_test(bool val) {
GLCAT.spam()
<< "glEnable(GL_STENCIL_TEST)" << endl;
#endif
GLP(Enable)(GL_STENCIL_TEST);
glEnable(GL_STENCIL_TEST);
} else {
#ifdef GSG_VERBOSE
GLCAT.spam()
<< "glDisable(GL_STENCIL_TEST)" << endl;
#endif
GLP(Disable)(GL_STENCIL_TEST);
glDisable(GL_STENCIL_TEST);
}
}
}
@ -473,13 +473,13 @@ enable_blend(bool val) {
GLCAT.spam()
<< "glEnable(GL_BLEND)" << endl;
#endif
GLP(Enable)(GL_BLEND);
glEnable(GL_BLEND);
} else {
#ifdef GSG_VERBOSE
GLCAT.spam()
<< "glDisable(GL_BLEND)" << endl;
#endif
GLP(Disable)(GL_BLEND);
glDisable(GL_BLEND);
}
}
}
@ -498,13 +498,13 @@ enable_depth_test(bool val) {
GLCAT.spam()
<< "glEnable(GL_DEPTH_TEST)" << endl;
#endif
GLP(Enable)(GL_DEPTH_TEST);
glEnable(GL_DEPTH_TEST);
} else {
#ifdef GSG_VERBOSE
GLCAT.spam()
<< "glDisable(GL_DEPTH_TEST)" << endl;
#endif
GLP(Disable)(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
}
}
}
@ -524,13 +524,13 @@ enable_fog(bool val) {
GLCAT.spam()
<< "glEnable(GL_FOG)" << endl;
#endif
GLP(Enable)(GL_FOG);
glEnable(GL_FOG);
} else {
#ifdef GSG_VERBOSE
GLCAT.spam()
<< "glDisable(GL_FOG)" << endl;
#endif
GLP(Disable)(GL_FOG);
glDisable(GL_FOG);
}
}
#endif
@ -551,13 +551,13 @@ enable_alpha_test(bool val) {
GLCAT.spam()
<< "glEnable(GL_ALPHA_TEST)" << endl;
#endif
GLP(Enable)(GL_ALPHA_TEST);
glEnable(GL_ALPHA_TEST);
} else {
#ifdef GSG_VERBOSE
GLCAT.spam()
<< "glDisable(GL_ALPHA_TEST)" << endl;
#endif
GLP(Disable)(GL_ALPHA_TEST);
glDisable(GL_ALPHA_TEST);
}
}
#endif // OPENGLES_2
@ -578,17 +578,17 @@ enable_polygon_offset(bool val) {
GLCAT.spam()
<< "glEnable(GL_POLYGON_OFFSET_*)" << endl;
#endif
GLP(Enable)(GL_POLYGON_OFFSET_FILL);
//GLP(Enable)(GL_POLYGON_OFFSET_LINE); // not widely supported anyway
//GLP(Enable)(GL_POLYGON_OFFSET_POINT);
glEnable(GL_POLYGON_OFFSET_FILL);
//glEnable(GL_POLYGON_OFFSET_LINE); // not widely supported anyway
//glEnable(GL_POLYGON_OFFSET_POINT);
} else {
#ifdef GSG_VERBOSE
GLCAT.spam()
<< "glDisable(GL_POLYGON_OFFSET_*)" << endl;
#endif
GLP(Disable)(GL_POLYGON_OFFSET_FILL);
//GLP(Disable)(GL_POLYGON_OFFSET_LINE); // not widely supported anyway
//GLP(Disable)(GL_POLYGON_OFFSET_POINT);
glDisable(GL_POLYGON_OFFSET_FILL);
//glDisable(GL_POLYGON_OFFSET_LINE); // not widely supported anyway
//glDisable(GL_POLYGON_OFFSET_POINT);
}
}
}
@ -603,10 +603,10 @@ INLINE void CLP(GraphicsStateGuardian)::
call_glFogfv(GLenum pname, const LColor &color) {
#ifndef OPENGLES_2
#ifndef STDFLOAT_DOUBLE
GLP(Fogfv)(pname, color.get_data());
glFogfv(pname, color.get_data());
#else // STDFLOAT_DOUBLE
LColorf fcolor = LCAST(float, color);
GLP(Fogfv)(pname, fcolor.get_data());
glFogfv(pname, fcolor.get_data());
#endif // STDFLOAT_DOUBLE
#endif
}
@ -621,10 +621,10 @@ INLINE void CLP(GraphicsStateGuardian)::
call_glMaterialfv(GLenum face, GLenum pname, const LColor &color) {
#ifndef OPENGLES_2
#ifndef STDFLOAT_DOUBLE
GLP(Materialfv)(face, pname, color.get_data());
glMaterialfv(face, pname, color.get_data());
#else // STDFLOAT_DOUBLE
LColorf fcolor = LCAST(float, color);
GLP(Materialfv)(face, pname, fcolor.get_data());
glMaterialfv(face, pname, fcolor.get_data());
#endif // STDFLOAT_DOUBLE
#endif
}
@ -639,10 +639,10 @@ INLINE void CLP(GraphicsStateGuardian)::
call_glLightfv(GLenum light, GLenum pname, const LVecBase4 &value) {
#ifndef OPENGLES_2
#ifndef STDFLOAT_DOUBLE
GLP(Lightfv)(light, pname, value.get_data());
glLightfv(light, pname, value.get_data());
#else // STDFLOAT_DOUBLE
LVecBase4f fvalue = LCAST(float, value);
GLP(Lightfv)(light, pname, fvalue.get_data());
glLightfv(light, pname, fvalue.get_data());
#endif // STDFLOAT_DOUBLE
#endif
}
@ -657,10 +657,10 @@ INLINE void CLP(GraphicsStateGuardian)::
call_glLightfv(GLenum light, GLenum pname, const LVecBase3 &value) {
#ifndef OPENGLES_2
#ifndef STDFLOAT_DOUBLE
GLP(Lightfv)(light, pname, value.get_data());
glLightfv(light, pname, value.get_data());
#else // STDFLOAT_DOUBLE
LVecBase3f fvalue = LCAST(float, value);
GLP(Lightfv)(light, pname, fvalue.get_data());
glLightfv(light, pname, fvalue.get_data());
#endif // STDFLOAT_DOUBLE
#endif
}
@ -675,10 +675,10 @@ INLINE void CLP(GraphicsStateGuardian)::
call_glLightModelfv(GLenum pname, const LVecBase4 &value) {
#ifndef OPENGLES_2
#ifndef STDFLOAT_DOUBLE
GLP(LightModelfv)(pname, value.get_data());
glLightModelfv(pname, value.get_data());
#else // STDFLOAT_DOUBLE
LVecBase4f fvalue = LCAST(float, value);
GLP(LightModelfv)(pname, fvalue.get_data());
glLightModelfv(pname, fvalue.get_data());
#endif // STDFLOAT_DOUBLE
#endif // OPENGLES_2
}
@ -693,10 +693,10 @@ INLINE void CLP(GraphicsStateGuardian)::
call_glTexEnvfv(GLenum target, GLenum pname, const LVecBase4 &value) {
#ifndef OPENGLES_2
#ifndef STDFLOAT_DOUBLE
GLP(TexEnvfv)(target, pname, value.get_data());
glTexEnvfv(target, pname, value.get_data());
#else // STDFLOAT_DOUBLE
LVecBase4f fvalue = LCAST(float, value);
GLP(TexEnvfv)(target, pname, fvalue.get_data());
glTexEnvfv(target, pname, fvalue.get_data());
#endif // STDFLOAT_DOUBLE
#endif
}
@ -710,10 +710,10 @@ call_glTexEnvfv(GLenum target, GLenum pname, const LVecBase4 &value) {
INLINE void CLP(GraphicsStateGuardian)::
call_glTexParameterfv(GLenum target, GLenum pname, const LVecBase4 &value) {
#ifndef STDFLOAT_DOUBLE
GLP(TexParameterfv)(target, pname, value.get_data());
glTexParameterfv(target, pname, value.get_data());
#else // STDFLOAT_DOUBLE
LVecBase4f fvalue = LCAST(float, value);
GLP(TexParameterfv)(target, pname, fvalue.get_data());
glTexParameterfv(target, pname, fvalue.get_data());
#endif // STDFLOAT_DOUBLE
}

File diff suppressed because it is too large Load Diff

View File

@ -55,6 +55,9 @@ typedef double GLdouble;
// functions are defined, and the system gl.h sometimes doesn't
// declare these typedefs.
#if !defined( __EDG__ ) || defined( __INTEL_COMPILER ) // Protect the following from the Tau instrumentor and expose it for the intel compiler.
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids);
typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id);
@ -131,6 +134,9 @@ typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXOESPROC) (GLuint matrixpalettei
typedef void (APIENTRYP PFNGLLOADPALETTEFROMMODELVIEWMATRIXOESPROC) (void);
typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLWEIGHTPOINTEROESPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLTEXSTORAGE1DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width);
typedef void (APIENTRYP PFNGLTEXSTORAGE2DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height);
typedef void (APIENTRYP PFNGLTEXSTORAGE3DPROC) (GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
#ifndef OPENGLES_1
// GLSL shader functions
@ -161,15 +167,44 @@ typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, con
typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value);
typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value);
typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program);
typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
#endif // OPENGLES_1
#ifndef OPENGLES
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 PFNGLBINDTEXTURESPROC) (GLuint first, GLsizei count, const GLuint *textures);
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);
typedef void (APIENTRYP PFNGLMEMORYBARRIERPROC) (GLbitfield barriers);
typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufsize, GLsizei *length, GLenum *binaryFormat, void *binary);
typedef void (APIENTRYP PFNGLGETINTERNALFORMATIVPROC) (GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params);
typedef GLuint64 (APIENTRYP PFNGLGETTEXTUREHANDLEPROC) (GLuint texture);
typedef GLuint64 (APIENTRYP PFNGLGETTEXTURESAMPLERHANDLEPROC) (GLuint texture, GLuint sampler);
typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLERESIDENTPROC) (GLuint64 handle);
typedef void (APIENTRYP PFNGLMAKETEXTUREHANDLENONRESIDENTPROC) (GLuint64 handle);
typedef GLuint64 (APIENTRYP PFNGLGETIMAGEHANDLEPROC) (GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum format);
typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLERESIDENTPROC) (GLuint64 handle, GLenum access);
typedef void (APIENTRYP PFNGLMAKEIMAGEHANDLENONRESIDENTPROC) (GLuint64 handle);
typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64PROC) (GLint location, GLuint64 value);
typedef void (APIENTRYP PFNGLUNIFORMHANDLEUI64VPROC) (GLint location, GLsizei count, const GLuint64 *value);
typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64PROC) (GLuint program, GLint location, GLuint64 value);
typedef void (APIENTRYP PFNGLPROGRAMUNIFORMHANDLEUI64VPROC) (GLuint program, GLint location, GLsizei count, const GLuint64 *values);
typedef GLboolean (APIENTRYP PFNGLISTEXTUREHANDLERESIDENTPROC) (GLuint64 handle);
typedef GLboolean (APIENTRYP PFNGLISIMAGEHANDLERESIDENTPROC) (GLuint64 handle);
typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64PROC) (GLuint index, GLuint64EXT x);
typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VPROC) (GLuint index, const GLuint64EXT *v);
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VPROC) (GLuint index, GLenum pname, GLuint64EXT *params);
#endif // OPENGLES
#endif // __EDG__
@ -193,6 +228,10 @@ public:
virtual int get_driver_shader_version_major();
virtual int get_driver_shader_version_minor();
#ifndef OPENGLES_1
static void debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam);
#endif
virtual void reset();
virtual void prepare_display_region(DisplayRegionPipelineReader *dr);
@ -225,6 +264,8 @@ public:
bool force);
virtual void end_draw_primitives();
void issue_memory_barrier(GLbitfield barrier);
virtual TextureContext *prepare_texture(Texture *tex, int view);
virtual bool update_texture(TextureContext *tc, bool force);
virtual void release_texture(TextureContext *tc);
@ -260,6 +301,8 @@ public:
virtual void begin_occlusion_query();
virtual PT(OcclusionQueryContext) end_occlusion_query();
virtual void dispatch_compute(int size_x, int size_y, int size_z);
virtual PT(GeomMunger) make_geom_munger(const RenderState *state,
Thread *current_thread);
@ -343,8 +386,8 @@ protected:
bool has_extension(const string &extension) const;
INLINE bool is_at_least_gl_version(int major_version, int minor_version) const;
INLINE bool is_at_least_gles_version(int major_version, int minor_version) const;
void *get_extension_func(const char *prefix, const char *name);
virtual void *do_get_extension_func(const char *prefix, const char *name);
void *get_extension_func(const char *name);
virtual void *do_get_extension_func(const char *name);
virtual void reissue_transforms();
virtual void enable_lighting(bool enable);
@ -429,7 +472,7 @@ protected:
bool specify_texture(CLP(TextureContext) *gtc);
bool apply_texture(TextureContext *tc);
bool upload_texture(CLP(TextureContext) *gtc, bool force);
bool upload_texture_image(CLP(TextureContext) *gtc,
bool upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
bool uses_mipmaps, int mipmap_bias,
GLenum texture_target, GLenum page_target,
GLint internal_format, GLint external_format,
@ -487,12 +530,12 @@ protected:
bool _vertex_blending_enabled;
#ifndef OPENGLES_1
PT(Shader) _current_shader;
CLP(ShaderContext) *_current_shader_context;
PT(Shader) _vertex_array_shader;
CLP(ShaderContext) *_vertex_array_shader_context;
PT(Shader) _texture_binding_shader;
CLP(ShaderContext) *_texture_binding_shader_context;
PT(Shader) _current_shader;
ShaderContext *_current_shader_context;
PT(Shader) _vertex_array_shader;
ShaderContext *_vertex_array_shader_context;
PT(Shader) _texture_binding_shader;
ShaderContext *_texture_binding_shader_context;
#endif
#ifdef OPENGLES_2
static PT(Shader) _default_shader;
@ -522,6 +565,9 @@ protected:
int _num_active_texture_stages;
PN_stdfloat _max_anisotropy;
bool _supports_anisotropy;
GLint _max_image_units;
bool _supports_multi_bind;
bool _supports_get_program_binary;
#ifdef OPENGLES
bool _supports_depth24;
@ -536,6 +582,7 @@ protected:
int _gl_version_major, _gl_version_minor;
//#--- Zhao Nov/2011
int _gl_shadlang_ver_major, _gl_shadlang_ver_minor;
pset<string> _extensions;
public:
@ -567,6 +614,11 @@ public:
PFNGLTEXSUBIMAGE3DPROC _glTexSubImage3D;
PFNGLCOPYTEXSUBIMAGE3DPROC _glCopyTexSubImage3D;
bool _supports_tex_storage;
PFNGLTEXSTORAGE1DPROC _glTexStorage1D;
PFNGLTEXSTORAGE2DPROC _glTexStorage2D;
PFNGLTEXSTORAGE3DPROC _glTexStorage3D;
PFNGLCOMPRESSEDTEXIMAGE1DPROC _glCompressedTexImage1D;
PFNGLCOMPRESSEDTEXIMAGE2DPROC _glCompressedTexImage2D;
PFNGLCOMPRESSEDTEXIMAGE3DPROC _glCompressedTexImage3D;
@ -577,8 +629,8 @@ public:
bool _supports_bgr;
bool _supports_rescale_normal;
bool _supports_mesa_6;
bool _supports_packed_dabc;
bool _supports_multitexture;
PFNGLACTIVETEXTUREPROC _glActiveTexture;
PFNGLCLIENTACTIVETEXTUREPROC _glClientActiveTexture;
@ -638,6 +690,8 @@ public:
PFNGLBLITFRAMEBUFFEREXTPROC _glBlitFramebuffer;
PFNGLDRAWBUFFERSPROC _glDrawBuffers;
int _max_fb_samples;
bool _supports_viewport_arrays;
bool _supports_bindless_texture;
PFNGLGENQUERIESPROC _glGenQueries;
PFNGLBEGINQUERYPROC _glBeginQuery;
@ -677,16 +731,37 @@ public:
PFNGLUNIFORM2FVPROC _glUniform2fv;
PFNGLUNIFORM3FVPROC _glUniform3fv;
PFNGLUNIFORM4FVPROC _glUniform4fv;
PFNGLUNIFORM1IVPROC _glUniform1iv;
PFNGLUNIFORM2IVPROC _glUniform2iv;
PFNGLUNIFORM3IVPROC _glUniform3iv;
PFNGLUNIFORM4IVPROC _glUniform4iv;
PFNGLUNIFORMMATRIX3FVPROC _glUniformMatrix3fv;
PFNGLUNIFORMMATRIX4FVPROC _glUniformMatrix4fv;
PFNGLVALIDATEPROGRAMPROC _glValidateProgram;
PFNGLVERTEXATTRIBPOINTERPROC _glVertexAttribPointer;
PFNGLVERTEXATTRIBIPOINTERPROC _glVertexAttribIPointer;
PFNGLVERTEXATTRIBLPOINTERPROC _glVertexAttribLPointer;
#endif // OPENGLES_1
#ifndef OPENGLES
PFNGLPROGRAMPARAMETERIPROC _glProgramParameteri;
PFNGLPATCHPARAMETERIPROC _glPatchParameteri;
PFNGLDRAWARRAYSINSTANCEDPROC _glDrawArraysInstanced;
PFNGLDRAWELEMENTSINSTANCEDPROC _glDrawElementsInstanced;
PFNGLBINDTEXTURESPROC _glBindTextures;
PFNGLBINDIMAGETEXTUREPROC _glBindImageTexture;
PFNGLBINDIMAGETEXTURESPROC _glBindImageTextures;
PFNGLDISPATCHCOMPUTEPROC _glDispatchCompute;
PFNGLMEMORYBARRIERPROC _glMemoryBarrier;
PFNGLGETPROGRAMBINARYPROC _glGetProgramBinary;
PFNGLGETINTERNALFORMATIVPROC _glGetInternalformativ;
PFNGLVIEWPORTARRAYVPROC _glViewportArrayv;
PFNGLSCISSORARRAYVPROC _glScissorArrayv;
PFNGLDEPTHRANGEARRAYVPROC _glDepthRangeArrayv;
PFNGLGETTEXTUREHANDLEPROC _glGetTextureHandle;
PFNGLMAKETEXTUREHANDLERESIDENTPROC _glMakeTextureHandleResident;
PFNGLMAKETEXTUREHANDLENONRESIDENTPROC _glMakeTextureHandleNonResident;
PFNGLUNIFORMHANDLEUI64PROC _glUniformHandleui64;
PFNGLUNIFORMHANDLEUI64VPROC _glUniformHandleui64v;
#endif // OPENGLES
GLenum _edge_clamp;
@ -704,10 +779,20 @@ public:
DeletedDisplayLists _deleted_display_lists;
DeletedDisplayLists _deleted_queries;
#ifndef OPENGLES
// Stores textures for which memory bariers should be issued.
typedef pset<TextureContext*> TextureSet;
TextureSet _textures_needing_fetch_barrier;
TextureSet _textures_needing_image_access_barrier;
TextureSet _textures_needing_update_barrier;
TextureSet _textures_needing_framebuffer_barrier;
#endif
//RenderState::SlotMask _inv_state_mask;
bool _track_errors;
bool _allow_flush;
bool _check_errors;
bool _force_flush;
bool _supports_debug;
#ifndef NDEBUG
bool _show_texture_usage;
@ -730,6 +815,7 @@ public:
static PStatCollector _primitive_batches_display_list_pcollector;
static PStatCollector _vertices_display_list_pcollector;
static PStatCollector _vertices_immediate_pcollector;
static PStatCollector _compute_dispatch_pcollector;
public:
virtual TypeHandle get_type() const {
@ -754,10 +840,9 @@ private:
friend class CLP(VertexBufferContext);
friend class CLP(IndexBufferContext);
friend class CLP(ShaderContext);
friend class CLP(CgShaderContext);
friend class CLP(GraphicsBuffer);
friend class CLP(OcclusionQueryContext);
};
#include "glGraphicsStateGuardian_src.I"

View File

@ -564,7 +564,7 @@ issue_vertex() {
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender2fui::
issue_vertex() {
const int *d = _reader->get_data2i();
const LVecBase2i &d = _reader->get_data2i();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
@ -573,7 +573,7 @@ issue_vertex() {
}
#endif // NDEBUG
(*_func)(2, (const GLuint *)d);
(*_func)(2, (const GLuint *)d.get_data());
}
////////////////////////////////////////////////////////////////////
@ -583,7 +583,7 @@ issue_vertex() {
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender3fui::
issue_vertex() {
const int *d = _reader->get_data3i();
const LVecBase3i &d = _reader->get_data3i();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
@ -592,7 +592,7 @@ issue_vertex() {
}
#endif // NDEBUG
(*_func)(3, (const GLuint *)d);
(*_func)(3, (const GLuint *)d.get_data());
}
////////////////////////////////////////////////////////////////////
@ -602,7 +602,7 @@ issue_vertex() {
////////////////////////////////////////////////////////////////////
void CLP(ImmediateModeSender)::VectorSender4fui::
issue_vertex() {
const int *d = _reader->get_data4i();
const LVecBase4i &d = _reader->get_data4i();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam()
@ -611,7 +611,7 @@ issue_vertex() {
}
#endif // NDEBUG
(*_func)(4, (const GLuint *)d);
(*_func)(4, (const GLuint *)d.get_data());
}
#endif // SUPPORT_IMMEDIATE_MODE

View File

@ -35,7 +35,7 @@ evict_lru() {
// Make sure the buffer is unbound before we delete it.
if (_glgsg->_current_ibuffer_index == _index) {
if (GLCAT.is_debug() && CLP(debug_buffers)) {
if (GLCAT.is_debug() && gl_debug_buffers) {
GLCAT.debug()
<< "unbinding index buffer\n";
}

View File

@ -75,7 +75,7 @@ is_answer_ready() const {
void CLP(OcclusionQueryContext)::
waiting_for_answer() {
PStatTimer timer(GraphicsStateGuardian::_wait_occlusion_pcollector);
GLP(Flush)();
glFlush();
}
////////////////////////////////////////////////////////////////////

View File

@ -12,7 +12,6 @@
//
////////////////////////////////////////////////////////////////////
#ifndef OPENGLES_1
////////////////////////////////////////////////////////////////////
// Function: GLShaderContext::valid
@ -26,11 +25,10 @@
INLINE bool CLP(ShaderContext)::
valid() {
if (_shader->get_error_flag()) return false;
if (_shader->get_language() == Shader::SL_none) return false;
#if defined(HAVE_CG) && !defined(OPENGLES)
if (_cg_context) return true;
#endif
if (_shader->get_language() == Shader::SL_GLSL && _glsl_program != 0) {
if (_shader->get_language() != Shader::SL_GLSL) {
return false;
}
if (_glsl_program != 0) {
return true;
}
return false;
@ -67,6 +65,3 @@ INLINE bool CLP(ShaderContext)::
uses_custom_texture_bindings() {
return true;
}
#endif // OPENGLES_1

File diff suppressed because it is too large Load Diff

View File

@ -21,75 +21,64 @@
#include "shaderContext.h"
#include "deletedChain.h"
#if defined(HAVE_CG) && !defined(OPENGLES)
#include <Cg/cg.h>
#endif
class CLP(GraphicsStateGuardian);
////////////////////////////////////////////////////////////////////
// Class : GLShaderContext
// Description : xyz
////////////////////////////////////////////////////////////////////
class EXPCL_GL CLP(ShaderContext): public ShaderContext {
class EXPCL_GL CLP(ShaderContext) : public ShaderContext {
public:
friend class CLP(GraphicsStateGuardian);
typedef CLP(GraphicsStateGuardian) GSG;
CLP(ShaderContext)(Shader *s, GSG *gsg);
CLP(ShaderContext)(CLP(GraphicsStateGuardian) *glgsg, Shader *s);
~CLP(ShaderContext)();
ALLOC_DELETED_CHAIN(CLP(ShaderContext));
INLINE bool valid(void);
void bind(GSG *gsg, bool reissue_parameters = true);
void unbind(GSG *gsg);
void issue_parameters(GSG *gsg, int altered);
void disable_shader_vertex_arrays(GSG *gsg);
bool update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg,
bool force);
void disable_shader_texture_bindings(GSG *gsg);
void update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg);
void bind(bool reissue_parameters = true);
void unbind();
void issue_parameters(int altered);
void disable_shader_vertex_arrays();
bool update_shader_vertex_arrays(ShaderContext *prev, bool force);
void disable_shader_texture_bindings();
void update_shader_texture_bindings(ShaderContext *prev);
INLINE bool uses_standard_vertex_arrays(void);
INLINE bool uses_custom_vertex_arrays(void);
INLINE bool uses_custom_texture_bindings(void);
private:
#if defined(HAVE_CG) && !defined(OPENGLES)
CGcontext _cg_context;
CGprogram _cg_vprogram;
CGprogram _cg_fprogram;
CGprogram _cg_gprogram;
CGprofile _cg_vprofile;
CGprofile _cg_fprofile;
CGprofile _cg_gprofile;
pvector <CGparameter> _cg_parameter_map;
#endif
GLuint _glsl_program;
GLuint _glsl_vshader;
GLuint _glsl_fshader;
GLuint _glsl_gshader;
GLuint _glsl_tcshader;
GLuint _glsl_teshader;
typedef pvector<GLuint> GLSLShaders;
GLSLShaders _glsl_shaders;
pvector <GLint> _glsl_parameter_map;
//struct ParamContext {
// CPT(InternalName) _name;
// GLint _location;
// GLsizei _count;
// WPT(ParamValue) _value;
// UpdateSeq _updated;
//};
//typedef pvector<ParamContext> ParamContexts;
//ParamContexts _params;
int _stage_offset;
// Avoid using this! It merely exists so the
// destructor has access to the extension functions.
WPT(GSG) _last_gsg;
pvector<GLint> _glsl_parameter_map;
pmap<GLint, GLuint64> _glsl_uniform_handles;
pvector<CPT(InternalName)> _glsl_img_inputs;
pvector<CLP(TextureContext)*> _glsl_img_textures;
CLP(GraphicsStateGuardian) *_glgsg;
bool _uses_standard_vertex_arrays;
void glsl_report_shader_errors(GSG *gsg, unsigned int shader);
void glsl_report_program_errors(GSG *gsg, unsigned int program);
unsigned int glsl_compile_entry_point(GSG *gsg, Shader::ShaderType type);
bool glsl_compile_shader(GSG *gsg);
void glsl_report_shader_errors(GLuint shader);
void glsl_report_program_errors(GLuint program);
bool glsl_compile_shader(Shader::ShaderType type);
bool glsl_compile_and_link();
bool parse_and_set_short_hand_shader_vars(Shader::ShaderArgId &arg_id, Shader *s);
void release_resources(GSG *gsg);
void release_resources();
public:
static TypeHandle get_class_type() {
@ -112,4 +101,3 @@ private:
#include "glShaderContext_src.I"
#endif // OPENGLES_1

View File

@ -19,12 +19,20 @@
// Description:
////////////////////////////////////////////////////////////////////
INLINE CLP(TextureContext)::
CLP(TextureContext)(PreparedGraphicsObjects *pgo, Texture *tex, int view) :
CLP(TextureContext)(CLP(GraphicsStateGuardian) *glgsg,
PreparedGraphicsObjects *pgo, Texture *tex, int view) :
TextureContext(pgo, tex, view)
{
_index = 0;
_already_applied = false;
_glgsg = glgsg;
glGenTextures(1, &_index);
_handle = 0;
_needs_barrier = false;
_has_storage = false;
_immutable = false;
_uses_mipmaps = false;
_generate_mipmaps = false;
_internal_format = 0;
_width = 0;
_height = 0;

View File

@ -16,6 +16,23 @@
TypeHandle CLP(TextureContext)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CLP(TextureContext)::Denstructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
CLP(TextureContext)::
~CLP(TextureContext)() {
if (gl_enable_memory_barriers) {
_glgsg->_textures_needing_fetch_barrier.erase(this);
_glgsg->_textures_needing_image_access_barrier.erase(this);
_glgsg->_textures_needing_update_barrier.erase(this);
_glgsg->_textures_needing_framebuffer_barrier.erase(this);
}
glDeleteTextures(1, &_index);
_index = 0;
}
////////////////////////////////////////////////////////////////////
// Function: GLTextureContext::evict_lru
@ -35,7 +52,16 @@ TypeHandle CLP(TextureContext)::_type_handle;
void CLP(TextureContext)::
evict_lru() {
dequeue_lru();
reset_data();
if (_handle != 0) {
if (_handle_resident) {
_glgsg->_glMakeTextureHandleNonResident(_handle);
}
_handle_resident = false;
} else {
reset_data();
}
update_data_size_bytes(0);
mark_unloaded();
}
@ -48,12 +74,113 @@ evict_lru() {
////////////////////////////////////////////////////////////////////
void CLP(TextureContext)::
reset_data() {
if (_handle != 0 && _handle_resident) {
_glgsg->_glMakeTextureHandleNonResident(_handle);
}
// Free the texture resources.
GLP(DeleteTextures)(1, &_index);
glDeleteTextures(1, &_index);
// We still need a valid index number, though, in case we want to
// re-load the texture later.
GLP(GenTextures)(1, &_index);
glGenTextures(1, &_index);
_already_applied = false;
_handle = 0;
_handle_resident = false;
_needs_barrier = false;
_has_storage = false;
_immutable = false;
#ifndef OPENGLES
// Mark the texture as coherent.
if (gl_enable_memory_barriers) {
_glgsg->_textures_needing_fetch_barrier.erase(this);
_glgsg->_textures_needing_image_access_barrier.erase(this);
_glgsg->_textures_needing_update_barrier.erase(this);
_glgsg->_textures_needing_framebuffer_barrier.erase(this);
}
#endif
}
////////////////////////////////////////////////////////////////////
// Function: GLTextureContext::make_handle_resident
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void CLP(TextureContext)::
make_handle_resident() {
if (_handle != 0) {
if (!_handle_resident) {
_glgsg->_glMakeTextureHandleResident(_handle);
_handle_resident = true;
}
set_resident(true);
}
}
////////////////////////////////////////////////////////////////////
// Function: CLP(TextureContext)::get_handle
// Access: Public
// Description: Returns a handle for this texture. Once this has
// been created, the texture data may still be updated,
// but its properties may not.
////////////////////////////////////////////////////////////////////
INLINE GLuint64 CLP(TextureContext)::
get_handle() {
#ifdef OPENGLES
return 0;
#else
if (!_glgsg->_supports_bindless_texture) {
return false;
}
if (_handle == 0) {
_handle = _glgsg->_glGetTextureHandle(_index);
}
_immutable = true;
return _handle;
#endif
}
#ifndef OPENGLES
////////////////////////////////////////////////////////////////////
// Function: GLTextureContext::needs_barrier
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool CLP(TextureContext)::
needs_barrier(GLbitfield barrier) {
if (!gl_enable_memory_barriers) {
return false;
}
return (((barrier & GL_TEXTURE_FETCH_BARRIER_BIT) &&
_glgsg->_textures_needing_fetch_barrier.count(this)))
|| (((barrier & GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) &&
_glgsg->_textures_needing_image_access_barrier.count(this)))
|| (((barrier & GL_TEXTURE_UPDATE_BARRIER_BIT) &&
_glgsg->_textures_needing_update_barrier.count(this)))
|| (((barrier & GL_FRAMEBUFFER_BARRIER_BIT) &&
_glgsg->_textures_needing_framebuffer_barrier.count(this)));
}
////////////////////////////////////////////////////////////////////
// Function: GLTextureContext::mark_incoherent
// Access: Public
// Description: Mark a texture as needing a memory barrier, since
// a non-coherent write just happened to it.
////////////////////////////////////////////////////////////////////
void CLP(TextureContext)::
mark_incoherent() {
if (!gl_enable_memory_barriers) {
return;
}
_glgsg->_textures_needing_fetch_barrier.insert(this);
_glgsg->_textures_needing_image_access_barrier.insert(this);
_glgsg->_textures_needing_update_barrier.insert(this);
_glgsg->_textures_needing_framebuffer_barrier.insert(this);
}
#endif // OPENGLES

View File

@ -16,32 +16,60 @@
#include "textureContext.h"
#include "deletedChain.h"
class CLP(GraphicsStateGuardian);
////////////////////////////////////////////////////////////////////
// Class : GLTextureContext
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_GL CLP(TextureContext) : public TextureContext {
public:
INLINE CLP(TextureContext)(PreparedGraphicsObjects *pgo, Texture *tex, int view);
INLINE CLP(TextureContext)(CLP(GraphicsStateGuardian) *glgsg,
PreparedGraphicsObjects *pgo,
Texture *tex, int view);
ALLOC_DELETED_CHAIN(CLP(TextureContext));
virtual ~CLP(TextureContext)();
virtual void evict_lru();
void reset_data();
void make_handle_resident();
GLuint64 get_handle();
#ifdef OPENGLES
CONSTEXPR bool needs_barrier(GLbitfield barrier) { return false; };
#else
bool needs_barrier(GLbitfield barrier);
void mark_incoherent();
#endif
// This is the GL "name" of the texture object.
GLuint _index;
// This is the bindless "handle" to the texture object.
GLuint64 _handle;
bool _handle_resident;
// This is true if the texture was recently written to in a
// non-coherent way, and Panda may have to call glMemoryBarrier
// for the results of this write to become visible.
bool _needs_barrier;
// These are the parameters that we specified with the last
// glTexImage2D() call. If none of these have changed, we can
// reload the texture image with a glTexSubImage2D().
bool _already_applied;
// glTexImage2D() or glTexStorage2D() call. If none of these have
// changed, we can reload the texture image with a glTexSubImage2D().
bool _has_storage;
bool _immutable;
bool _uses_mipmaps;
bool _generate_mipmaps;
GLint _internal_format;
GLsizei _width;
GLsizei _height;
GLsizei _depth;
GLenum _target;
CLP(GraphicsStateGuardian) *_glgsg;
public:
static TypeHandle get_class_type() {
return _type_handle;

View File

@ -35,7 +35,7 @@ evict_lru() {
// Make sure the buffer is unbound before we delete it.
if (_glgsg->_current_vbuffer_index == _index) {
if (GLCAT.is_debug() && CLP(debug_buffers)) {
if (GLCAT.is_debug() && gl_debug_buffers) {
GLCAT.debug()
<< "unbinding vertex buffer\n";
}

View File

@ -14,45 +14,45 @@
#include "pandaSystem.h"
ConfigVariableBool CLP(cheap_textures)
ConfigVariableBool gl_cheap_textures
("gl-cheap-textures", false,
PRC_DESC("Configure this true to GLP(Hint) the textures into the cheapest "
PRC_DESC("Configure this true to glHint the textures into the cheapest "
"possible mode."));
ConfigVariableBool CLP(ignore_clamp)
ConfigVariableBool gl_ignore_clamp
("gl-ignore-clamp", false,
PRC_DESC("Configure this true to disable texture clamp mode (all textures "
"repeat, a little cheaper for software renderers)."));
ConfigVariableBool CLP(support_clamp_to_border)
ConfigVariableBool gl_support_clamp_to_border
("gl-support-clamp-to-border", true,
PRC_DESC("Configure this true to enable the use of the clamp_to_border "
"extension if the GL claims to support it, or false not to "
"use it even if it appears to be available. (On some OpenGL "
"drivers, enabling this mode can force software rendering.)"));
ConfigVariableBool CLP(support_rescale_normal)
ConfigVariableBool gl_support_rescale_normal
("gl-support-rescale-normal", true,
PRC_DESC("Configure this true to enable the use of the rescale_normal "
"extension if the GL claims to support it, or false not to use "
"it even if it appears to be available. (This appears to be "
"buggy on some drivers.)"));
ConfigVariableBool CLP(ignore_filters)
ConfigVariableBool gl_ignore_filters
("gl-ignore-filters", false,
PRC_DESC("Configure this true to disable any texture filters at all (forcing "
"point sampling)."));
ConfigVariableBool CLP(ignore_mipmaps)
ConfigVariableBool gl_ignore_mipmaps
("gl-ignore-mipmaps", false,
PRC_DESC("Configure this true to disable mipmapping only."));
ConfigVariableBool CLP(force_mipmaps)
ConfigVariableBool gl_force_mipmaps
("gl-force-mipmaps", false,
PRC_DESC("Configure this true to enable full trilinear mipmapping on every "
"texture, whether it asks for it or not."));
ConfigVariableBool CLP(show_texture_usage)
ConfigVariableBool gl_show_texture_usage
("gl-show-texture-usage", false,
PRC_DESC("If you set this true, the screen will flash with textures drawn "
"in a special mode that shows the mipmap detail level and texture "
@ -60,27 +60,27 @@ ConfigVariableBool CLP(show_texture_usage)
"mipmap level 0, yellow for mipmap level 1, and red for all higher "
"mipmap levels. Brighter colors represent larger textures."));
ConfigVariableInt CLP(show_texture_usage_max_size)
ConfigVariableInt gl_show_texture_usage_max_size
("gl-show-texture-usage-max-size", 1024,
PRC_DESC("Specifies the texture size (along one side) of the largest "
"texture expected to be loaded. This controls the assignment "
"of the texture color in gl-show-texture-usage mode; colors "
"will be fully bright for textures of this size or larger."));
ConfigVariableBool CLP(color_mask)
ConfigVariableBool gl_color_mask
("gl-color-mask", true,
PRC_DESC("Configure this false if your GL's implementation of glColorMask() "
"is broken (some are). This will force the use of a (presumably) "
"more expensive blending operation instead."));
ConfigVariableBool CLP(support_occlusion_query)
ConfigVariableBool gl_support_occlusion_query
("gl-support-occlusion-query", true,
PRC_DESC("Configure this true to enable the use of the occlusion_query "
"extension if the GL claims to support it, or false not to "
"use it even if it appears to be available. (On some OpenGL "
"drivers, enabling this mode can force software rendering.)"));
ConfigVariableBool CLP(compile_and_execute)
ConfigVariableBool gl_compile_and_execute
("gl-compile-and-execute", false,
PRC_DESC("Configure this true if you know your GL's implementation of "
"glNewList(n, GL_COMPILE_AND_EXECUTE) works. It is "
@ -90,7 +90,7 @@ ConfigVariableBool CLP(compile_and_execute)
"for the first time, by allowing the display list to be "
"rendered at the same time it is being compiled."));
ConfigVariableBool CLP(interleaved_arrays)
ConfigVariableBool gl_interleaved_arrays
("gl-interleaved-arrays", false,
PRC_DESC("Set this true to convert OpenGL geometry such that the "
"primary data columns vertex, normal, color, and texcoord "
@ -98,20 +98,20 @@ ConfigVariableBool CLP(interleaved_arrays)
"render geometry as it appears in the GeomVertexData. See "
"also gl-parallel-arrays."));
ConfigVariableBool CLP(parallel_arrays)
ConfigVariableBool gl_parallel_arrays
("gl-parallel-arrays", false,
PRC_DESC("Set this true to convert OpenGL geometry such that each "
"data column is a separate array, or false to "
"render geometry as it appears in the GeomVertexData. See "
"also gl-interleaved-arrays."));
ConfigVariableInt CLP(max_errors)
ConfigVariableInt gl_max_errors
("gl-max-errors", 20,
PRC_DESC("This is the limit on the number of OpenGL errors Panda will "
"detect and report before it shuts down rendering. Set it to "
"-1 for no limit."));
ConfigVariableEnum<GeomEnums::UsageHint> CLP(min_buffer_usage_hint)
ConfigVariableEnum<GeomEnums::UsageHint> gl_min_buffer_usage_hint
("gl-min-buffer-usage-hint", GeomEnums::UH_stream,
PRC_DESC("This specifies the first usage hint value that will be "
"loaded as a vertex buffer, instead of directly from the "
@ -126,13 +126,38 @@ ConfigVariableEnum<GeomEnums::UsageHint> CLP(min_buffer_usage_hint)
"of reusing the same buffers. Consider increasing "
"released-vbuffer-cache-size instead."));
ConfigVariableBool CLP(debug_buffers)
ConfigVariableBool gl_debug
("gl-debug", false,
PRC_DESC("Setting this to true will cause OpenGL to emit more useful "
"error and debug messages, at a slight runtime performance cost. "
"notify-level-glgsg controls which severity levels are shown."));
ConfigVariableBool gl_debug_synchronous
("gl-debug-synchronous", false,
PRC_DESC("Set this true to make sure that the errors generated by "
"gl-debug are reported as soon as they happen. This is "
"highly recommended if you want to attach a debugger since "
"the call stack may otherwise not point to the GL call "
"where the error originated."));
ConfigVariableEnum<NotifySeverity> gl_debug_abort_level
("gl-debug-abort-level", NS_fatal,
PRC_DESC("Set this to a setting other than 'fatal' to cause an "
"abort to be triggered when an error of the indicated "
"severity level (or a more severe one) occurs. This is "
"useful if you want to attach a debugger. If you set this, "
"it is highly recommended to also set gl-debug-synchronous, "
"since the call stack will otherwise not point to the GL call "
"that triggered the error message. "
"This feature is not available when NDEBUG has been defined."));
ConfigVariableBool gl_debug_buffers
("gl-debug-buffers", false,
PRC_DESC("Set this true, in addition to enabling debug notify for "
"glgsg, to enable debug messages about the creation and "
"destruction of OpenGL vertex buffers."));
ConfigVariableBool CLP(finish)
ConfigVariableBool gl_finish
("gl-finish", false,
PRC_DESC("Set this true to force a call to glFinish() after every major "
"graphics operation. This is likely to slow down rendering "
@ -140,31 +165,78 @@ ConfigVariableBool CLP(finish)
"more accurately reflect where the graphics bottlenecks are. "
"This variable is enabled only if PStats is compiled in."));
ConfigVariableBool CLP(force_depth_stencil)
("gl-force-depth-stencil", false,
ConfigVariableBool gl_force_depth_stencil
("gl-force-depth-stencil", false,
PRC_DESC("Temporary hack variable 7x00 vs 8x00 nVidia bug. See glGraphicsStateGuardian_src.cxx."));
ConfigVariableBool CLP(matrix_palette)
("gl-matrix-palette", false,
ConfigVariableBool gl_matrix_palette
("gl-matrix-palette", false,
PRC_DESC("Temporary hack variable protecting untested code. See glGraphicsStateGuardian_src.cxx."));
ConfigVariableBool CLP(force_no_error)
("gl-force-no-error", false,
PRC_DESC("Avoid reporting OpenGL errors, for a small performance benefit."));
ConfigVariableBool gl_check_errors
("gl-check-errors", false,
PRC_DESC("Regularly call glGetError() to check for OpenGL errors. "
"This will slow down rendering significantly. If your "
"video driver supports it, you should use gl-debug instead."));
ConfigVariableBool CLP(force_no_flush)
("gl-force-no-flush", false,
PRC_DESC("Avoid calling glFlush(), for a potential performance benefit. This may be a little dangerous."));
ConfigVariableBool gl_force_flush
("gl-force-flush", false,
PRC_DESC("Call this to force a call to glFlush() after rendering a "
"frame, even when using a double-buffered framebuffer. "
"This can incur a significant performance penalty."));
ConfigVariableBool CLP(separate_specular_color)
("gl-separate-specular-color", true,
ConfigVariableBool gl_separate_specular_color
("gl-separate-specular-color", true,
PRC_DESC("When separate specular mode is on, the specular component "
"will be written to the secondary instead of the primary "
"color, which is added after the texturing stage. In other "
"words, the specular highlight will be unmodulated by the "
"color of the texture."));
extern ConfigVariableBool CLP(parallel_arrays);
ConfigVariableBool gl_cube_map_seamless
("gl-cube-map-seamless", true,
PRC_DESC("This configures Panda to try and enable seamless cube map "
"sampling when supported. This will help to remove seams "
"that show up at cube map edges, especially at lower "
"resolutions. On by default; disable if you suspect that "
"this is causing problems or if you simply don't need the "
"functionality."));
ConfigVariableBool gl_dump_compiled_shaders
("gl-dump-compiled-shaders", false,
PRC_DESC("This configures Panda to dump the binary content of GLSL "
"programs to disk with a filename like glsl_program0.dump "
"into the current directory."));
ConfigVariableBool gl_immutable_texture_storage
("gl-immutable-texture-storage", false,
PRC_DESC("This configures Panda to pre-allocate immutable storage "
"for each texture. This improves runtime performance, but "
"changing the size or type of a texture will be slower."));
ConfigVariableBool gl_use_bindless_texture
("gl-use-bindless-texture", false,
PRC_DESC("Set this to let Panda use OpenGL's bindless texture "
"extension for all textures passed to shaders, for improved "
"performance. This is an experimental feature and comes "
"with a few caveats; for one, it requires that all sampler "
"uniforms have a layout(bindless_sampler) qualifier, and "
"it also requires that the texture properties are not "
"modified after the texture handle has been initialized."));
ConfigVariableBool gl_enable_memory_barriers
("gl-enable-memory-barriers", true,
PRC_DESC("If this is set, Panda will make sure that every write "
"to an image using an image2D (et al) binding will cause "
"Panda to issue a memory barrier before the next use of "
"said texture, to ensure that all reads and writes are "
"properly synchronized. This may not be strictly necessary "
"when using the 'coherent' qualifier, but Panda has no "
"way to detect whether you are using those. Turning "
"this off may give a slight performance increase, but you "
"have to know what you're doing."));
extern ConfigVariableBool gl_parallel_arrays;
void CLP(init_classes)() {
CLP(GeomContext)::init_type();
@ -189,4 +261,3 @@ void CLP(init_classes)() {
// since we won't know those until we create a graphics context (and
// the answer may be different for different contexts).
}

View File

@ -40,28 +40,36 @@
//#define GSG_VERBOSE 1
extern ConfigVariableBool CLP(cheap_textures);
extern ConfigVariableBool CLP(ignore_clamp);
extern ConfigVariableBool CLP(support_clamp_to_border);
extern ConfigVariableBool CLP(ignore_filters);
extern ConfigVariableBool CLP(ignore_mipmaps);
extern ConfigVariableBool CLP(force_mipmaps);
extern ConfigVariableBool CLP(show_texture_usage);
extern ConfigVariableInt CLP(show_texture_usage_max_size);
extern ConfigVariableBool CLP(color_mask);
extern ConfigVariableBool CLP(support_occlusion_query);
extern ConfigVariableBool CLP(compile_and_execute);
extern ConfigVariableBool CLP(interleaved_arrays);
extern ConfigVariableBool CLP(parallel_arrays);
extern ConfigVariableInt CLP(max_errors);
extern ConfigVariableEnum<GeomEnums::UsageHint> CLP(min_buffer_usage_hint);
extern ConfigVariableBool CLP(debug_buffers);
extern ConfigVariableBool CLP(finish);
extern ConfigVariableBool CLP(force_depth_stencil);
extern ConfigVariableBool CLP(matrix_palette);
extern ConfigVariableBool CLP(force_no_error);
extern ConfigVariableBool CLP(force_no_flush);
extern ConfigVariableBool CLP(separate_specular_color);
extern ConfigVariableBool gl_cheap_textures;
extern ConfigVariableBool gl_ignore_clamp;
extern ConfigVariableBool gl_support_clamp_to_border;
extern ConfigVariableBool gl_ignore_filters;
extern ConfigVariableBool gl_ignore_mipmaps;
extern ConfigVariableBool gl_force_mipmaps;
extern ConfigVariableBool gl_show_texture_usage;
extern ConfigVariableInt gl_show_texture_usage_max_size;
extern ConfigVariableBool gl_color_mask;
extern ConfigVariableBool gl_support_occlusion_query;
extern ConfigVariableBool gl_compile_and_execute;
extern ConfigVariableBool gl_interleaved_arrays;
extern ConfigVariableBool gl_parallel_arrays;
extern ConfigVariableInt gl_max_errors;
extern ConfigVariableEnum<GeomEnums::UsageHint> gl_min_buffer_usage_hint;
extern ConfigVariableBool gl_debug;
extern ConfigVariableBool gl_debug_synchronous;
extern ConfigVariableEnum<NotifySeverity> gl_debug_abort_level;
extern ConfigVariableBool gl_debug_buffers;
extern ConfigVariableBool gl_finish;
extern ConfigVariableBool gl_force_depth_stencil;
extern ConfigVariableBool gl_matrix_palette;
extern ConfigVariableBool gl_check_errors;
extern ConfigVariableBool gl_force_flush;
extern ConfigVariableBool gl_separate_specular_color;
extern ConfigVariableBool gl_cube_map_seamless;
extern ConfigVariableBool gl_dump_compiled_shaders;
extern ConfigVariableBool gl_immutable_texture_storage;
extern ConfigVariableBool gl_use_bindless_texture;
extern ConfigVariableBool gl_enable_memory_barriers;
extern EXPCL_GL void CLP(init_classes)();

View File

@ -25,8 +25,7 @@
#include "glGeomContext_src.cxx"
#include "glGeomMunger_src.cxx"
#include "glShaderContext_src.cxx"
#include "glCgShaderContext_src.cxx"
#include "glImmediateModeSender_src.cxx"
#include "glGraphicsBuffer_src.cxx"
#include "glGraphicsStateGuardian_src.cxx"

View File

@ -18,7 +18,6 @@
// some such), define the following symbols and #include this header
// file.
// #define GLP(name): returns name prefixed by the gl prefix, e.g. gl##name
// #define CLP(name): returns name prefixed by the class prefix, e.g. GL##name
// #define CLASSPREFIX_QUOTED: the quoted prefix of CLP, e.g. "GL"
// #define CONFIGOBJ: a Configrc object, e.g. config_glgsg
@ -40,7 +39,7 @@
#include "glGeomContext_src.h"
#include "glGeomMunger_src.h"
#include "glShaderContext_src.h"
#include "glCgShaderContext_src.h"
#include "glImmediateModeSender_src.h"
#include "glGraphicsBuffer_src.h"
#include "glGraphicsStateGuardian_src.h"

View File

@ -2398,6 +2398,71 @@ extern "C" {
#define GL_TEXTURE_IMMUTABLE_FORMAT 0x912F
#endif
#ifndef GL_KHR_debug
#define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242
#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243
#define GL_DEBUG_CALLBACK_FUNCTION 0x8244
#define GL_DEBUG_CALLBACK_USER_PARAM 0x8245
#define GL_DEBUG_SOURCE_API 0x8246
#define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247
#define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248
#define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249
#define GL_DEBUG_SOURCE_APPLICATION 0x824A
#define GL_DEBUG_SOURCE_OTHER 0x824B
#define GL_DEBUG_TYPE_ERROR 0x824C
#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D
#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E
#define GL_DEBUG_TYPE_PORTABILITY 0x824F
#define GL_DEBUG_TYPE_PERFORMANCE 0x8250
#define GL_DEBUG_TYPE_OTHER 0x8251
#define GL_DEBUG_TYPE_MARKER 0x8268
#define GL_DEBUG_TYPE_PUSH_GROUP 0x8269
#define GL_DEBUG_TYPE_POP_GROUP 0x826A
#define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B
#define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C
#define GL_DEBUG_GROUP_STACK_DEPTH 0x826D
#define GL_BUFFER 0x82E0
#define GL_SHADER 0x82E1
#define GL_PROGRAM 0x82E2
#define GL_QUERY 0x82E3
#define GL_PROGRAM_PIPELINE 0x82E4
#define GL_SAMPLER 0x82E6
#define GL_DISPLAY_LIST 0x82E7
/* DISPLAY_LIST used in compatibility profile only */
#define GL_MAX_LABEL_LENGTH 0x82E8
#define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143
#define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144
#define GL_DEBUG_LOGGED_MESSAGES 0x9145
#define GL_DEBUG_SEVERITY_HIGH 0x9146
#define GL_DEBUG_SEVERITY_MEDIUM 0x9147
#define GL_DEBUG_SEVERITY_LOW 0x9148
#define GL_DEBUG_OUTPUT 0x92E0
#define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002
/* reuse GL_STACK_UNDERFLOW */
/* reuse GL_STACK_OVERFLOW */
#endif
#ifndef GL_ARB_compute_shader
#define GL_COMPUTE_SHADER 0x91B9
#define GL_MAX_COMPUTE_UNIFORM_BLOCKS 0x91BB
#define GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS 0x91BC
#define GL_MAX_COMPUTE_IMAGE_UNIFORMS 0x91BD
#define GL_MAX_COMPUTE_SHARED_MEMORY_SIZE 0x8262
#define GL_MAX_COMPUTE_UNIFORM_COMPONENTS 0x8263
#define GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS 0x8264
#define GL_MAX_COMPUTE_ATOMIC_COUNTERS 0x8265
#define GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS 0x8266
#define GL_MAX_COMPUTE_LOCAL_INVOCATIONS 0x90EB
#define GL_MAX_COMPUTE_WORK_GROUP_COUNT 0x91BE
#define GL_MAX_COMPUTE_WORK_GROUP_SIZE 0x91BF
#define GL_COMPUTE_LOCAL_WORK_SIZE 0x8267
#define GL_UNIFORM_BLOCK_REFERENCED_BY_COMPUTE_SHADER 0x90EC
#define GL_ATOMIC_COUNTER_BUFFER_REFERENCED_BY_COMPUTE_SHADER 0x90ED
#define GL_DISPATCH_INDIRECT_BUFFER 0x90EE
#define GL_DISPATCH_INDIRECT_BUFFER_BINDING 0x90EF
#define GL_COMPUTE_SHADER_BIT 0x00000020
#endif
#ifndef GL_EXT_abgr
#define GL_ABGR_EXT 0x8000
#endif
@ -5501,8 +5566,12 @@ typedef ptrdiff_t GLsizeiptrARB;
#ifndef GL_ARB_shader_objects
/* GL types for program/shader text and shader object handles */
typedef char GLcharARB;
#ifdef __APPLE__
typedef void *GLhandleARB;
#else
typedef unsigned int GLhandleARB;
#endif
#endif
/* GL type for "half" precision (s10e5) float data in host memory */
#ifndef GL_ARB_half_float_pixel
@ -5576,6 +5645,10 @@ typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLen
typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#endif
#ifndef GL_KHR_debug
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam);
#endif
#ifndef GL_NV_vdpau_interop
typedef GLintptr GLvdpauSurfaceNV;
#endif
@ -7882,6 +7955,42 @@ typedef void (APIENTRYP PFNGLTEXTURESTORAGE2DEXTPROC) (GLuint texture, GLenum ta
typedef void (APIENTRYP PFNGLTEXTURESTORAGE3DEXTPROC) (GLuint texture, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
#endif
#ifndef GL_KHR_debug
#define GL_KHR_debug 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glDebugMessageControl (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
GLAPI void APIENTRY glDebugMessageInsert (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
GLAPI void APIENTRY glDebugMessageCallback (GLDEBUGPROC callback, const void *userParam);
GLAPI GLuint APIENTRY glGetDebugMessageLog (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
GLAPI void APIENTRY glPushDebugGroup (GLenum source, GLuint id, GLsizei length, const GLchar *message);
GLAPI void APIENTRY glPopDebugGroup (void);
GLAPI void APIENTRY glObjectLabel (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
GLAPI void APIENTRY glGetObjectLabel (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
GLAPI void APIENTRY glObjectPtrLabel (const void *ptr, GLsizei length, const GLchar *label);
GLAPI void APIENTRY glGetObjectPtrLabel (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled);
typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf);
typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam);
typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog);
typedef void (APIENTRYP PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar *message);
typedef void (APIENTRYP PFNGLPOPDEBUGGROUPPROC) (void);
typedef void (APIENTRYP PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar *label);
typedef void (APIENTRYP PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label);
typedef void (APIENTRYP PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar *label);
typedef void (APIENTRYP PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label);
#endif
#ifndef GL_ARB_compute_shader
#define GL_ARB_compute_shader 1
#ifdef GL_GLEXT_PROTOTYPES
GLAPI void APIENTRY glDispatchCompute (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
GLAPI void APIENTRY glDispatchComputeIndirect (GLintptr indirect);
#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEPROC) (GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z);
typedef void (APIENTRYP PFNGLDISPATCHCOMPUTEINDIRECTPROC) (GLintptr indirect);
#endif
#ifndef GL_EXT_abgr
#define GL_EXT_abgr 1
#endif

View File

@ -88,14 +88,17 @@ make_output(const string &name,
GraphicsOutput *host,
int retry,
bool &precertify) {
if (!_is_valid) {
return NULL;
}
glxGraphicsStateGuardian *glxgsg = 0;
if (gsg != 0) {
DCAST_INTO_R(glxgsg, gsg, NULL);
// This may not be a GLX GSG; it might be a callback GSG.
PosixGraphicsStateGuardian *posixgsg = NULL;
glxGraphicsStateGuardian *glxgsg = NULL;
if (gsg != NULL) {
DCAST_INTO_R(posixgsg, gsg, NULL);
glxgsg = DCAST(glxGraphicsStateGuardian, posixgsg);
}
bool support_rtt;
@ -103,15 +106,19 @@ make_output(const string &name,
/*
Currently, no support for glxGraphicsBuffer render-to-texture.
if (glxgsg) {
support_rtt =
glxgsg -> get_supports_render_texture() &&
support_rtt =
glxgsg -> get_supports_render_texture() &&
support_render_texture;
}
}
*/
// First thing to try: a glxGraphicsWindow
if (retry == 0) {
if (gsg != NULL && glxgsg == NULL) {
// We can't use a non-GLX GSG.
return NULL;
}
if (((flags&BF_require_parasite)!=0)||
((flags&BF_refuse_window)!=0)||
((flags&BF_resizeable)!=0)||
@ -125,7 +132,7 @@ make_output(const string &name,
return new glxGraphicsWindow(engine, this, name, fb_prop, win_prop,
flags, gsg, host);
}
// Second thing to try: a GLGraphicsBuffer
if (retry == 1) {
@ -139,7 +146,7 @@ make_output(const string &name,
// meet specs, we can bail out early.
int _fbo_multisample = 0;
if (!ConfigVariableBool("framebuffer-object-multisample", false, PRC_DESC("Enabled Multisample."))) {
_fbo_multisample = 16;
_fbo_multisample = 16;
}
if ((flags & BF_fb_props_optional)==0) {
if ((fb_prop.get_indexed_color() > 0)||
@ -151,11 +158,11 @@ make_output(const string &name,
}
// Early success - if we are sure that this buffer WILL
// meet specs, we can precertify it.
if ((glxgsg != 0) &&
(glxgsg->is_valid()) &&
(!glxgsg->needs_reset()) &&
(glxgsg->_supports_framebuffer_object) &&
(glxgsg->_glDrawBuffers != 0)&&
if ((posixgsg != 0) &&
(posixgsg->is_valid()) &&
(!posixgsg->needs_reset()) &&
(posixgsg->_supports_framebuffer_object) &&
(posixgsg->_glDrawBuffers != 0)&&
(fb_prop.is_basic())) {
precertify = true;
}

View File

@ -90,7 +90,7 @@ get_properties(FrameBufferProperties &properties, XVisualInfo *visual) {
red_size, green_size, blue_size,
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
depth_size, stencil_size;
glXGetConfig(_display, visual, GLX_USE_GL, &use_gl);
glXGetConfig(_display, visual, GLX_RGBA, &render_mode);
glXGetConfig(_display, visual, GLX_DOUBLEBUFFER, &double_buffer);
@ -131,7 +131,7 @@ get_properties(FrameBufferProperties &properties, XVisualInfo *visual) {
properties.set_depth_bits(depth_size);
properties.set_alpha_bits(alpha_size);
properties.set_accum_bits(ared_size+agreen_size+ablue_size+aalpha_size);
// Set both hardware and software bits, indicating not-yet-known.
properties.set_force_software(1);
properties.set_force_hardware(1);
@ -153,8 +153,8 @@ get_properties_advanced(FrameBufferProperties &properties,
// Now update our framebuffer_mode and bit depth appropriately.
int render_type, double_buffer, stereo, red_size, green_size, blue_size,
alpha_size, ared_size, agreen_size, ablue_size, aalpha_size,
depth_size, stencil_size, samples, drawable_type, caveat;
depth_size, stencil_size, samples, drawable_type, caveat, srgb_capable;
_glXGetFBConfigAttrib(_display, config, GLX_RENDER_TYPE, &render_type);
_glXGetFBConfigAttrib(_display, config, GLX_DOUBLEBUFFER, &double_buffer);
_glXGetFBConfigAttrib(_display, config, GLX_STEREO, &stereo);
@ -171,47 +171,54 @@ get_properties_advanced(FrameBufferProperties &properties,
_glXGetFBConfigAttrib(_display, config, GLX_SAMPLES, &samples);
_glXGetFBConfigAttrib(_display, config, GLX_DRAWABLE_TYPE, &drawable_type);
_glXGetFBConfigAttrib(_display, config, GLX_CONFIG_CAVEAT, &caveat);
_glXGetFBConfigAttrib(_display, config, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable);
context_has_pbuffer = false;
if ((drawable_type & GLX_PBUFFER_BIT)!=0) {
context_has_pbuffer = true;
}
context_has_pixmap = false;
if ((drawable_type & GLX_PIXMAP_BIT)!=0) {
context_has_pixmap = true;
}
slow = false;
if (caveat == GLX_SLOW_CONFIG) {
slow = true;
}
if ((drawable_type & GLX_WINDOW_BIT)==0) {
// We insist on having a context that will support an onscreen window.
return;
}
if (double_buffer) {
properties.set_back_buffers(1);
}
if (stereo) {
properties.set_stereo(1);
properties.set_stereo(true);
}
if (srgb_capable) {
properties.set_srgb_color(true);
}
if ((render_type & GLX_RGBA_BIT)!=0) {
properties.set_rgb_color(1);
properties.set_rgb_color(true);
}
if ((render_type & GLX_COLOR_INDEX_BIT)!=0) {
properties.set_indexed_color(1);
properties.set_indexed_color(true);
}
properties.set_color_bits(red_size+green_size+blue_size);
properties.set_stencil_bits(stencil_size);
properties.set_depth_bits(depth_size);
properties.set_alpha_bits(alpha_size);
properties.set_accum_bits(ared_size+agreen_size+ablue_size+aalpha_size);
properties.set_multisamples(samples);
// Set both hardware and software bits, indicating not-yet-known.
properties.set_force_software(1);
properties.set_force_hardware(1);
@ -288,6 +295,11 @@ choose_pixel_format(const FrameBufferProperties &properties,
int best_result = 0;
FrameBufferProperties best_props;
int render_type = GLX_RGBA_TYPE;
if (properties.get_indexed_color()) {
render_type = GLX_COLOR_INDEX_TYPE;
}
static const int max_attrib_list = 32;
int attrib_list[max_attrib_list];
int n = 0;
@ -298,11 +310,11 @@ choose_pixel_format(const FrameBufferProperties &properties,
attrib_list[n++] = GLX_DRAWABLE_TYPE;
attrib_list[n++] = GLX_DONT_CARE;
attrib_list[n] = (int)None;
int num_configs = 0;
GLXFBConfig *configs =
_glXChooseFBConfig(_display, _screen, attrib_list, &num_configs);
if (configs != 0) {
bool context_has_pbuffer, context_has_pixmap, slow;
int quality, i;
@ -317,7 +329,8 @@ choose_pixel_format(const FrameBufferProperties &properties,
const char *pixmaptext = context_has_pixmap ? " (pixmap)" : "";
const char *slowtext = slow ? " (slow)" : "";
glxdisplay_cat.debug()
<< i << ": " << fbprops << " quality=" << quality << pbuffertext << pixmaptext << slowtext << "\n";
<< i << ": " << fbprops << " quality=" << quality << pbuffertext
<< pixmaptext << slowtext << "\n";
}
if (need_pbuffer && !context_has_pbuffer) {
continue;
@ -325,7 +338,7 @@ choose_pixel_format(const FrameBufferProperties &properties,
if (need_pixmap && !context_has_pixmap) {
continue;
}
if (quality > best_quality) {
best_quality = quality;
best_result = i;
@ -336,10 +349,29 @@ choose_pixel_format(const FrameBufferProperties &properties,
if (best_quality > 0) {
_fbconfig = configs[best_result];
_context =
_glXCreateNewContext(_display, _fbconfig, GLX_RGBA_TYPE, _share_context,
GL_TRUE);
if (_glXCreateContextAttribs != NULL) {
// NB. This is a wholly different type of attrib list
// than below, the same values are not used!
n = 0;
attrib_list[n++] = GLX_RENDER_TYPE;
attrib_list[n++] = render_type;
if (gl_debug) {
attrib_list[n++] = GLX_CONTEXT_FLAGS_ARB;
attrib_list[n++] = GLX_CONTEXT_DEBUG_BIT_ARB;
}
attrib_list[n] = None;
_context = _glXCreateContextAttribs(_display, _fbconfig, _share_context,
GL_TRUE, attrib_list);
} else {
_context =
_glXCreateNewContext(_display, _fbconfig, render_type, _share_context,
GL_TRUE);
}
if (_context) {
mark_new();
if (_visuals != (XVisualInfo *)NULL) {
XFree(_visuals);
_visuals = NULL;
@ -351,6 +383,10 @@ choose_pixel_format(const FrameBufferProperties &properties,
get_properties_advanced(_fbprops, _context_has_pbuffer, _context_has_pixmap,
_slow, _fbconfig);
if (!properties.get_srgb_color()) {
_fbprops.set_srgb_color(false);
}
if (glxdisplay_cat.is_debug()) {
glxdisplay_cat.debug()
<< "Selected context " << best_result << ": " << _fbprops << "\n";
@ -387,150 +423,6 @@ choose_pixel_format(const FrameBufferProperties &properties,
_context_has_pbuffer = false;
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsStateGuardian::reset
// Access: Public, Virtual
// Description: Resets all internal state as if the gsg were newly
// created.
////////////////////////////////////////////////////////////////////
void glxGraphicsStateGuardian::
reset() {
PosixGraphicsStateGuardian::reset();
_supports_swap_control = has_extension("GLX_SGI_swap_control");
if (_supports_swap_control) {
_glXSwapIntervalSGI =
(PFNGLXSWAPINTERVALSGIPROC)get_extension_func("glX", "SwapIntervalSGI");
if (_glXSwapIntervalSGI == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_SGI_swap_control extension, but does not define all functions.\n";
_supports_swap_control = false;
}
}
if (_supports_swap_control) {
// Set the video-sync setting up front, if we have the extension
// that supports it.
_glXSwapIntervalSGI(sync_video ? 1 : 0);
}
if (glx_support_fbconfig) {
if (glx_is_at_least_version(1, 3)) {
// If we have glx 1.3 or better, we have the FBConfig interface.
_supports_fbconfig = true;
_glXChooseFBConfig =
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glX", "ChooseFBConfig");
_glXCreateNewContext =
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glX", "CreateNewContext");
_glXGetVisualFromFBConfig =
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glX", "GetVisualFromFBConfig");
_glXGetFBConfigAttrib =
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glX", "GetFBConfigAttrib");
_glXCreatePixmap =
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glX", "CreatePixmap");
if (_glXChooseFBConfig == NULL ||
_glXCreateNewContext == NULL ||
_glXGetVisualFromFBConfig == NULL ||
_glXGetFBConfigAttrib == NULL ||
_glXCreatePixmap == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_fbconfig extension, but does not define all functions.\n";
_supports_fbconfig = false;
}
} else if (has_extension("GLX_SGIX_fbconfig")) {
// Or maybe we have the old SGIX extension for FBConfig. This is
// the same, but the function names are different--we just remap
// them to the same function pointers.
_supports_fbconfig = true;
_glXChooseFBConfig =
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glX", "ChooseFBConfigSGIX");
_glXCreateNewContext =
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glX", "CreateContextWithConfigSGIX");
_glXGetVisualFromFBConfig =
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glX", "GetVisualFromFBConfigSGIX");
_glXGetFBConfigAttrib =
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glX", "GetFBConfigAttribSGIX");
_glXCreatePixmap =
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glX", "CreateGLXPixmapWithConfigSGIX");
if (_glXChooseFBConfig == NULL ||
_glXCreateNewContext == NULL ||
_glXGetVisualFromFBConfig == NULL ||
_glXGetFBConfigAttrib == NULL ||
_glXCreatePixmap == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_SGIX_fbconfig extension, but does not define all functions.\n";
_supports_fbconfig = false;
}
}
if (glx_is_at_least_version(1, 3)) {
// If we have glx 1.3 or better, we have the PBuffer interface.
_supports_pbuffer = true;
_uses_sgix_pbuffer = false;
_glXCreatePbuffer =
(PFNGLXCREATEPBUFFERPROC)get_extension_func("glX", "CreatePbuffer");
_glXCreateGLXPbufferSGIX = NULL;
_glXDestroyPbuffer =
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glX", "DestroyPbuffer");
if (_glXCreatePbuffer == NULL ||
_glXDestroyPbuffer == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_pbuffer extension, but does not define all functions.\n";
_supports_pbuffer = false;
}
} else if (has_extension("GLX_SGIX_pbuffer")) {
// Or maybe we have the old SGIX extension for PBuffers.
_uses_sgix_pbuffer = true;
// CreatePbuffer has a different form between SGIX and 1.3,
// however, so we must treat it specially. But we can use the
// same function pointer for DestroyPbuffer.
_glXCreatePbuffer = NULL;
_glXCreateGLXPbufferSGIX =
(PFNGLXCREATEGLXPBUFFERSGIXPROC)get_extension_func("glX", "CreateGLXPbufferSGIX");
_glXDestroyPbuffer =
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glX", "DestroyGLXPbufferSGIX");
if (_glXCreateGLXPbufferSGIX == NULL ||
_glXDestroyPbuffer == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_SGIX_pbuffer extension, but does not define all functions.\n";
_supports_pbuffer = false;
}
}
}
if (glxdisplay_cat.is_debug()) {
glxdisplay_cat.debug()
<< "supports_swap_control = " << _supports_swap_control << "\n";
glxdisplay_cat.debug()
<< "supports_fbconfig = " << _supports_fbconfig << "\n";
glxdisplay_cat.debug()
<< "supports_pbuffer = " << _supports_pbuffer
<< " sgix = " << _uses_sgix_pbuffer << "\n";
}
// If "Mesa" is present, assume software. However, if "Mesa DRI" is
// found, it's actually a Mesa-based OpenGL layer running over a
// hardware driver.
if (_gl_renderer.find("Mesa") != string::npos &&
_gl_renderer.find("Mesa DRI") == string::npos) {
// It's Mesa, therefore probably a software context.
_fbprops.set_force_software(1);
_fbprops.set_force_hardware(0);
} else {
_fbprops.set_force_hardware(1);
_fbprops.set_force_software(0);
}
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsStateGuardian::glx_is_at_least_version
// Access: Public
@ -625,41 +517,39 @@ get_extra_extensions() {
// not defined.
////////////////////////////////////////////////////////////////////
void *glxGraphicsStateGuardian::
do_get_extension_func(const char *prefix, const char *name) {
nassertr(prefix != NULL, NULL);
do_get_extension_func(const char *name) {
nassertr(name != NULL, NULL);
string fullname = string(prefix) + string(name);
if (glx_get_proc_address) {
// First, check if we have glXGetProcAddress available. This will
// be superior if we can get it.
#if defined(LINK_IN_GLXGETPROCADDRESS) && defined(HAVE_GLXGETPROCADDRESS)
// If we are confident the system headers defined it, we can
// call it directly. This is more reliable than trying to
// determine its address dynamically, but it may make
// libpandagl.so fail to load if the symbol isn't in the runtime
// library.
return (void *)glXGetProcAddress((const GLubyte *)fullname.c_str());
return (void *)glXGetProcAddress((const GLubyte *)name);
#elif defined(LINK_IN_GLXGETPROCADDRESS) && defined(HAVE_GLXGETPROCADDRESSARB)
// The ARB extension version is OK too. Sometimes the prototype
// isn't supplied for some reason.
return (void *)glXGetProcAddressARB((const GLubyte *)fullname.c_str());
return (void *)glXGetProcAddressARB((const GLubyte *)name);
#else
// Otherwise, we have to fiddle around with the dynamic runtime.
if (!_checked_get_proc_address) {
const char *funcName = NULL;
if (glx_is_at_least_version(1, 4)) {
funcName = "glXGetProcAddress";
} else if (has_extension("GLX_ARB_get_proc_address")) {
funcName = "glXGetProcAddressARB";
}
if (funcName != NULL) {
_glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC)get_system_func(funcName);
if (_glXGetProcAddress == NULL) {
@ -671,16 +561,163 @@ do_get_extension_func(const char *prefix, const char *name) {
_checked_get_proc_address = true;
}
// Use glxGetProcAddress() if we've got it; it should be more robust.
if (_glXGetProcAddress != NULL) {
return (void *)_glXGetProcAddress((const GLubyte *)fullname.c_str());
return (void *)_glXGetProcAddress((const GLubyte *)name);
}
#endif // HAVE_GLXGETPROCADDRESS
}
// Otherwise, fall back to the OS-provided calls.
return PosixGraphicsStateGuardian::do_get_extension_func(prefix, name);
return PosixGraphicsStateGuardian::do_get_extension_func(name);
}
////////////////////////////////////////////////////////////////////
// Function: glxGraphicsStateGuardian::query_glx_extensions
// Access: Private
// Description: Queries the GLX extension pointers.
////////////////////////////////////////////////////////////////////
void glxGraphicsStateGuardian::
query_glx_extensions() {
_supports_swap_control = has_extension("GLX_SGI_swap_control");
if (_supports_swap_control) {
_glXSwapIntervalSGI =
(PFNGLXSWAPINTERVALSGIPROC)get_extension_func("glXSwapIntervalSGI");
if (_glXSwapIntervalSGI == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_SGI_swap_control extension, but does not define all functions.\n";
_supports_swap_control = false;
}
}
if (_supports_swap_control) {
// Set the video-sync setting up front, if we have the extension
// that supports it.
_glXSwapIntervalSGI(sync_video ? 1 : 0);
}
if (glx_support_fbconfig) {
if (glx_is_at_least_version(1, 3)) {
// If we have glx 1.3 or better, we have the FBConfig interface.
_supports_fbconfig = true;
_glXChooseFBConfig =
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glXChooseFBConfig");
_glXCreateNewContext =
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glXCreateNewContext");
_glXGetVisualFromFBConfig =
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glXGetVisualFromFBConfig");
_glXGetFBConfigAttrib =
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glXGetFBConfigAttrib");
_glXCreatePixmap =
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glXCreatePixmap");
if (_glXChooseFBConfig == NULL ||
_glXCreateNewContext == NULL ||
_glXGetVisualFromFBConfig == NULL ||
_glXGetFBConfigAttrib == NULL ||
_glXCreatePixmap == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_fbconfig extension, but does not define all functions.\n";
_supports_fbconfig = false;
}
} else if (has_extension("GLX_SGIX_fbconfig")) {
// Or maybe we have the old SGIX extension for FBConfig. This is
// the same, but the function names are different--we just remap
// them to the same function pointers.
_supports_fbconfig = true;
_glXChooseFBConfig =
(PFNGLXCHOOSEFBCONFIGPROC)get_extension_func("glXChooseFBConfigSGIX");
_glXCreateNewContext =
(PFNGLXCREATENEWCONTEXTPROC)get_extension_func("glXCreateContextWithConfigSGIX");
_glXGetVisualFromFBConfig =
(PFNGLXGETVISUALFROMFBCONFIGPROC)get_extension_func("glXGetVisualFromFBConfigSGIX");
_glXGetFBConfigAttrib =
(PFNGLXGETFBCONFIGATTRIBPROC)get_extension_func("glXGetFBConfigAttribSGIX");
_glXCreatePixmap =
(PFNGLXCREATEPIXMAPPROC)get_extension_func("glXCreateGLXPixmapWithConfigSGIX");
if (_glXChooseFBConfig == NULL ||
_glXCreateNewContext == NULL ||
_glXGetVisualFromFBConfig == NULL ||
_glXGetFBConfigAttrib == NULL ||
_glXCreatePixmap == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_SGIX_fbconfig extension, but does not define all functions.\n";
_supports_fbconfig = false;
}
}
if (glx_is_at_least_version(1, 3)) {
// If we have glx 1.3 or better, we have the PBuffer interface.
_supports_pbuffer = true;
_uses_sgix_pbuffer = false;
_glXCreatePbuffer =
(PFNGLXCREATEPBUFFERPROC)get_extension_func("glXCreatePbuffer");
_glXCreateGLXPbufferSGIX = NULL;
_glXDestroyPbuffer =
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glXDestroyPbuffer");
if (_glXCreatePbuffer == NULL ||
_glXDestroyPbuffer == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_pbuffer extension, but does not define all functions.\n";
_supports_pbuffer = false;
}
} else if (has_extension("GLX_SGIX_pbuffer")) {
// Or maybe we have the old SGIX extension for PBuffers.
_uses_sgix_pbuffer = true;
// CreatePbuffer has a different form between SGIX and 1.3,
// however, so we must treat it specially. But we can use the
// same function pointer for DestroyPbuffer.
_glXCreatePbuffer = NULL;
_glXCreateGLXPbufferSGIX =
(PFNGLXCREATEGLXPBUFFERSGIXPROC)get_extension_func("glXCreateGLXPbufferSGIX");
_glXDestroyPbuffer =
(PFNGLXDESTROYPBUFFERPROC)get_extension_func("glXDestroyGLXPbufferSGIX");
if (_glXCreateGLXPbufferSGIX == NULL ||
_glXDestroyPbuffer == NULL) {
glxdisplay_cat.error()
<< "Driver claims to support GLX_SGIX_pbuffer extension, but does not define all functions.\n";
_supports_pbuffer = false;
}
}
if (has_extension("GLX_ARB_create_context")) {
_glXCreateContextAttribs =
(PFNGLXCREATECONTEXTATTRIBSARBPROC)get_extension_func("glXCreateContextAttribsARB");
} else {
_glXCreateContextAttribs = NULL;
}
}
if (glxdisplay_cat.is_debug()) {
glxdisplay_cat.debug()
<< "supports_swap_control = " << _supports_swap_control << "\n";
glxdisplay_cat.debug()
<< "supports_fbconfig = " << _supports_fbconfig << "\n";
glxdisplay_cat.debug()
<< "supports_pbuffer = " << _supports_pbuffer
<< " sgix = " << _uses_sgix_pbuffer << "\n";
}
// If "Mesa" is present, assume software. However, if "Mesa DRI" is
// found, it's actually a Mesa-based OpenGL layer running over a
// hardware driver.
if (_gl_renderer.find("Mesa") != string::npos &&
_gl_renderer.find("Mesa DRI") == string::npos) {
// It's Mesa, therefore probably a software context.
_fbprops.set_force_software(1);
_fbprops.set_force_hardware(0);
} else {
_fbprops.set_force_hardware(1);
_fbprops.set_force_software(0);
}
}
////////////////////////////////////////////////////////////////////
@ -759,17 +796,17 @@ choose_temp_visual(const FrameBufferProperties &properties) {
}
}
}
if (best_quality > 0) {
_visual = _visuals + best_result;
_temp_context = glXCreateContext(_display, _visual, None, GL_TRUE);
_temp_context = glXCreateContext(_display, _visual, None, GL_TRUE);
if (_temp_context) {
_fbprops = best_props;
return;
}
}
glxdisplay_cat.error()
glxdisplay_cat.error()
<< "Could not find a usable pixel format.\n";
}
@ -805,8 +842,11 @@ init_temp_context() {
return;
}
// Now use it to query the available GLX features.
glXMakeCurrent(_display, _temp_xwindow, _temp_context);
reset();
query_gl_version();
get_extra_extensions();
query_glx_extensions();
}
////////////////////////////////////////////////////////////////////
@ -828,7 +868,7 @@ destroy_temp_xwindow() {
_temp_xwindow = (X11_Window)NULL;
}
if (_temp_context != (GLXContext)NULL){
if (_temp_context != (GLXContext)NULL) {
glXDestroyContext(_display, _temp_context);
_temp_context = (GLXContext)NULL;
}

View File

@ -67,7 +67,7 @@ typedef int (* PFNGLXGETFBCONFIGATTRIBPROC) (X11_Display *dpy, GLXFBConfig confi
typedef GLXPixmap (* PFNGLXCREATEPIXMAPPROC) (X11_Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list);
typedef GLXPbuffer (* PFNGLXCREATEPBUFFERPROC) (X11_Display *dpy, GLXFBConfig config, const int *attrib_list);
typedef void (* PFNGLXDESTROYPBUFFERPROC) (X11_Display *dpy, GLXPbuffer pbuf);
typedef GLXContext ( *PFNGLXCREATECONTEXTATTRIBSARBPROC) (X11_Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
#endif // __EDG__
////////////////////////////////////////////////////////////////////
@ -92,8 +92,6 @@ public:
virtual ~glxGraphicsStateGuardian();
virtual void reset();
bool glx_is_at_least_version(int major_version, int minor_version) const;
GLXContext _share_context;
@ -119,6 +117,7 @@ public:
PFNGLXGETVISUALFROMFBCONFIGPROC _glXGetVisualFromFBConfig;
PFNGLXGETFBCONFIGATTRIBPROC _glXGetFBConfigAttrib;
PFNGLXCREATEPIXMAPPROC _glXCreatePixmap;
PFNGLXCREATECONTEXTATTRIBSARBPROC _glXCreateContextAttribs;
bool _supports_pbuffer; // true if the interface is available.
bool _uses_sgix_pbuffer;
@ -132,9 +131,10 @@ protected:
virtual void query_gl_version();
virtual void get_extra_extensions();
virtual void *do_get_extension_func(const char *prefix, const char *name);
virtual void *do_get_extension_func(const char *name);
private:
void query_glx_extensions();
void show_glx_client_string(const string &name, int id);
void show_glx_server_string(const string &name, int id);
void choose_temp_visual(const FrameBufferProperties &properties);

File diff suppressed because it is too large Load Diff

View File

@ -53,13 +53,11 @@ PosixGraphicsStateGuardian::
// not defined.
////////////////////////////////////////////////////////////////////
void *PosixGraphicsStateGuardian::
do_get_extension_func(const char *prefix, const char *name) {
nassertr(prefix != NULL, NULL);
do_get_extension_func(const char *name) {
nassertr(name != NULL, NULL);
string fullname = string(prefix) + string(name);
if (glx_get_os_address) {
return get_system_func(fullname.c_str());
return get_system_func(name);
}
return NULL;

View File

@ -32,7 +32,7 @@ public:
~PosixGraphicsStateGuardian();
protected:
virtual void *do_get_extension_func(const char *prefix, const char *name);
virtual void *do_get_extension_func(const char *name);
void *get_system_func(const char *name);
private:

View File

@ -510,6 +510,13 @@ ConfigVariableInt lens_geom_segments
"lens; for a normal perspective or orthographic lens, the "
"wireframe is not subdivided."));
ConfigVariableString cg_glsl_version
("cg-glsl-version", "",
PRC_DESC("If this is set, it forces the Cg compiler to generate GLSL "
"code conforming to the given GLSL version when using the "
"glslv, glslf or glslg profiles. Use this when you are having "
"problems with these profiles. Example values are 120 or 150."));
ConfigureFn(config_gobj) {
AnimateVerticesRequest::init_type();
BufferContext::init_type();

View File

@ -101,6 +101,6 @@ extern EXPCL_PANDA_GOBJ ConfigVariableInt adaptive_lru_max_updates_per_frame;
extern EXPCL_PANDA_GOBJ ConfigVariableDouble async_load_delay;
extern EXPCL_PANDA_GOBJ ConfigVariableInt lens_geom_segments;
extern EXPCL_PANDA_GOBJ ConfigVariableString cg_glsl_version;
#endif

View File

@ -242,6 +242,19 @@ make_points() const {
return new_geom;
}
////////////////////////////////////////////////////////////////////
// Function: Geom::make_patches
// Access: Published
// Description: Returns a new Geom with each primitive converted
// into a patch. Calls decompose() first.
////////////////////////////////////////////////////////////////////
INLINE PT(Geom) Geom::
make_patches() const {
PT(Geom) new_geom = make_copy();
new_geom->make_patches_in_place();
return new_geom;
}
////////////////////////////////////////////////////////////////////
// Function: Geom::get_modified
// Access: Published

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