Merge remote-tracking branch 'upstream/master' into cmake
Conflicts: panda/src/linmath/lvecBase4.h
This commit is contained in:
commit
3d0f587ca0
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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]]
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ public:
|
|||
int _num_default_parameters;
|
||||
Type _type;
|
||||
int _flags;
|
||||
int _args_type;
|
||||
string _expression;
|
||||
string _function_signature;
|
||||
string _hash;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);\
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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; };
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ®ion = 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 ®ion = 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 ®ion = 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 ®ion = 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 ®ion = _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 ®ion = _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 ®ion = _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 ®ion = _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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ®ion = 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 ©) :
|
||||
_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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ FrameBufferProperties() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void FrameBufferProperties::
|
||||
operator = (const FrameBufferProperties ©) {
|
||||
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 ©) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -36,10 +36,8 @@ WindowProperties() {
|
|||
void WindowProperties::
|
||||
operator = (const WindowProperties ©) {
|
||||
_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());
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ is_answer_ready() const {
|
|||
void CLP(OcclusionQueryContext)::
|
||||
waiting_for_answer() {
|
||||
PStatTimer timer(GraphicsStateGuardian::_wait_occlusion_pcollector);
|
||||
GLP(Flush)();
|
||||
glFlush();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)();
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue