mirror of
https://github.com/panda3d/panda3d.git
synced 2026-05-25 01:18:31 -05:00
better windows tau support; better threaded DeletedChain support; beginning PipelineReader classes
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "dcFile.h"
|
||||
#include "dcField.h" // to pick up Python.h
|
||||
#include "pStatCollector.h"
|
||||
#include "datagramIterator.h"
|
||||
|
||||
#ifdef HAVE_NSPR
|
||||
#include "queuedConnectionManager.h"
|
||||
|
||||
@@ -279,6 +279,8 @@ finish_send_update(DCPacker &packer) {
|
||||
nassertv(clock_delta != NULL);
|
||||
double delta = PyFloat_AsDouble(clock_delta);
|
||||
Py_DECREF(clock_delta);
|
||||
#else
|
||||
static const double delta = 0.0f;
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
double local_time = ClockObject::get_global_clock()->get_frame_time();
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
#push 1 $[file]_obj
|
||||
#end file
|
||||
|
||||
#if $[USE_SINGLE_COMPOSITE_SOURCEFILE]
|
||||
#if $[and $[not $[DONT_COMBINE]],$[or $[USE_SINGLE_COMPOSITE_SOURCEFILE],$[and $[USE_TAU],$[WINDOWS_PLATFORM]]]]
|
||||
#if $[> $[words $[cxx_sources]], 1]
|
||||
// If we have multiple C++ files, put them together into one
|
||||
// composite file.
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
// '#defer extra_cflags $[extra_cflags] /STUFF' will never work because extra_cflags hasnt been
|
||||
// defined yet, so this just evaluates the reference to null and removes the reference and the
|
||||
// the defining extra_cflags in individual sources.pp's will not picked up. use END_FLAGS instead
|
||||
#defer extra_cflags /EHsc /Zm500 /DWIN32_VC /DWIN32 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
|
||||
#defer extra_cflags /EHsc /Zm500 /DWIN32_VC /DWIN32=1 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
|
||||
|
||||
#if $[direct_tau]
|
||||
#define tau_ipath $[TAU_ROOT]/include
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
// '#defer extra_cflags $[extra_cflags] /STUFF' will never work because extra_cflags hasnt been
|
||||
// defined yet, so this just evaluates the reference to null and removes the reference and the
|
||||
// the defining extra_cflags in individual sources.pp's will not picked up. use END_FLAGS instead
|
||||
#defer extra_cflags /EHsc /Zm300 /DWIN32_VC /DWIN32 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
|
||||
#defer extra_cflags /EHsc /Zm300 /DWIN32_VC /DWIN32=1 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
|
||||
|
||||
#defer DECYGWINED_INC_PATHLIST_ARGS $[decygwin %,/I"%",$[EXTRA_INCPATH] $[ipath] $[WIN32_PLATFORMSDK_INCPATH]]
|
||||
#defer MAIN_C_COMPILE_ARGS /nologo /c $[DECYGWINED_INC_PATHLIST_ARGS] $[flags] $[extra_cflags] "$[osfilename $[source]]"
|
||||
|
||||
@@ -183,7 +183,14 @@
|
||||
/* ################################# DO NOT EDIT ########################### */
|
||||
|
||||
#foreach file $[$[composite_file]_sources]
|
||||
#if $[USE_TAU]
|
||||
// For the benefit of Tau, we copy the source file verbatim into the
|
||||
// composite file. (Tau doesn't instrument files picked up via #include.)
|
||||
#copy $[DIRPREFIX]$[file]
|
||||
|
||||
#else
|
||||
##include "$[file]"
|
||||
#endif // USE_TAU
|
||||
#end file
|
||||
|
||||
#end $[composite_file]
|
||||
|
||||
@@ -27,7 +27,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.
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
template<class Type>
|
||||
TYPENAME DeletedChain<Type>::ObjectNode *DeletedChain<Type>::_deleted_chain;
|
||||
TVOLATILE TYPENAME DeletedChain<Type>::ObjectNode * TVOLATILE DeletedChain<Type>::_deleted_chain;
|
||||
|
||||
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
template<class Type>
|
||||
MutexImpl DeletedChain<Type>::_lock;
|
||||
#endif
|
||||
@@ -35,38 +35,54 @@ allocate(size_t size) {
|
||||
TAU_PROFILE("Type *DeletedChain<Type>::allocate(size_t)", " ", TAU_USER);
|
||||
assert(size <= sizeof(Type));
|
||||
|
||||
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
TVOLATILE ObjectNode *obj;
|
||||
|
||||
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
_lock.lock();
|
||||
if (_deleted_chain != (ObjectNode *)NULL) {
|
||||
ObjectNode *obj = _deleted_chain;
|
||||
obj = _deleted_chain;
|
||||
_deleted_chain = _deleted_chain->_next;
|
||||
_lock.release();
|
||||
#ifndef NDEBUG
|
||||
assert(obj->_flag == ((PN_int32)obj ^ deleted_chain_flag_hash));
|
||||
obj->_flag = 0;
|
||||
#endif // NDEBUG
|
||||
return (Type *)obj;
|
||||
}
|
||||
_lock.release();
|
||||
|
||||
#else // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
ObjectNode *obj = _deleted_chain;
|
||||
#else // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
obj = _deleted_chain;
|
||||
while (obj != (ObjectNode *)NULL) {
|
||||
ObjectNode *result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void *&)_deleted_chain, (void *)obj, (void *)obj->_next);
|
||||
TVOLATILE ObjectNode *next = obj->_next;
|
||||
TVOLATILE ObjectNode *result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_deleted_chain, (void *)obj, (void *)next);
|
||||
if (result == obj) {
|
||||
// We got it.
|
||||
#ifndef NDEBUG
|
||||
assert(obj->_flag == ((PN_int32)obj ^ deleted_chain_flag_hash));
|
||||
obj->_flag = 0;
|
||||
#endif // NDEBUG
|
||||
return (Type *)obj;
|
||||
}
|
||||
// Someone else grabbed the top link first. Try again.
|
||||
obj = _deleted_chain;
|
||||
}
|
||||
|
||||
#endif // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
|
||||
// If we get here, the deleted_chain is empty; we have to allocate a
|
||||
// new object from the system pool.
|
||||
|
||||
#ifdef DO_MEMORY_USAGE
|
||||
return (Type *)(*global_operator_new)(sizeof(Type));
|
||||
obj = (ObjectNode *)(*global_operator_new)(max(sizeof(Type), sizeof(ObjectNode)));
|
||||
#else
|
||||
return (Type *)malloc(sizeof(Type));
|
||||
obj = (ObjectNode *)malloc(max(sizeof(Type), sizeof(ObjectNode)));
|
||||
#endif
|
||||
#ifndef NDEBUG
|
||||
obj->_flag = 0;
|
||||
#endif // NDEBUG
|
||||
|
||||
return (Type *)obj;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -78,25 +94,32 @@ template<class Type>
|
||||
INLINE void DeletedChain<Type>::
|
||||
deallocate(Type *ptr) {
|
||||
TAU_PROFILE("void DeletedChain<Type>::deallocate(Type *)", " ", TAU_USER);
|
||||
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
TVOLATILE ObjectNode *obj = (ObjectNode *)ptr;
|
||||
|
||||
#ifndef NDEBUG
|
||||
assert(obj->_flag != ((PN_int32)obj ^ deleted_chain_flag_hash));
|
||||
obj->_flag = (PN_int32)obj ^ deleted_chain_flag_hash;
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
_lock.lock();
|
||||
|
||||
ObjectNode *obj = (ObjectNode *)ptr;
|
||||
obj->_next = _deleted_chain;
|
||||
_deleted_chain = obj;
|
||||
|
||||
_lock.release();
|
||||
|
||||
#else // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
#else // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
|
||||
ObjectNode *obj = (ObjectNode *)ptr;
|
||||
ObjectNode *result;
|
||||
TVOLATILE ObjectNode *result;
|
||||
TVOLATILE ObjectNode *next;
|
||||
|
||||
do {
|
||||
obj->_next = _deleted_chain;
|
||||
result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void *&)_deleted_chain, (void *)obj->_next, (void *)obj);
|
||||
next = _deleted_chain;
|
||||
obj->_next = next;
|
||||
result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_deleted_chain, (void *)next, (void *)obj);
|
||||
// Keep trying until no one else got to _deleted_chain first.
|
||||
} while (result != obj->_next);
|
||||
} while (result != next);
|
||||
|
||||
#endif // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
}
|
||||
|
||||
@@ -23,8 +23,19 @@
|
||||
|
||||
#include "mutexImpl.h"
|
||||
#include "atomicAdjust.h"
|
||||
#include "numeric_types.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
// Actually, there appears to be a (maybe fatal) flaw in our
|
||||
//implementation of DeletedChain via the atomic exchange operation.
|
||||
//Specifically, a pointer may be removed from the head of the chain,
|
||||
//then the same pointer reinserted in the chain, while another thread
|
||||
//is waiting; and that thread will not detect the change. For now,
|
||||
//then, let's not use this implmentation, and fall back to the mutex.
|
||||
//#define DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DeletedChain
|
||||
// Description : This template class can be used to provide faster
|
||||
@@ -60,7 +71,10 @@ public:
|
||||
private:
|
||||
class ObjectNode {
|
||||
public:
|
||||
ObjectNode *_next;
|
||||
TVOLATILE ObjectNode * TVOLATILE _next;
|
||||
#ifndef NDEBUG
|
||||
TVOLATILE PN_int32 _flag;
|
||||
#endif
|
||||
};
|
||||
|
||||
// Ideally, the compiler and linker will unify all references to
|
||||
@@ -68,15 +82,17 @@ private:
|
||||
// However, if the compiler fails to do this (*cough* Microsoft), it
|
||||
// won't be a big deal; it just means there will be multiple
|
||||
// unrelated chains of deleted objects for a particular type.
|
||||
static ObjectNode *_deleted_chain;
|
||||
static TVOLATILE ObjectNode * TVOLATILE _deleted_chain;
|
||||
|
||||
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
|
||||
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
|
||||
// If we don't have atomic compare-and-exchange, we need to use a
|
||||
// Mutex to protect the above linked list.
|
||||
static MutexImpl _lock;
|
||||
#endif
|
||||
};
|
||||
|
||||
static const PN_int32 deleted_chain_flag_hash = 0x12345678;
|
||||
|
||||
// Place this macro within a class definition to define appropriate
|
||||
// operator new and delete methods that take advantage of
|
||||
// DeletedChain.
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#if defined(USE_TAU) && defined(WIN32)
|
||||
// Hack around tau's lack of DLL export declarations for Profiler class.
|
||||
bool __tau_shutdown = false;
|
||||
#endif
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Memory manager: DLMALLOC
|
||||
|
||||
@@ -185,15 +185,18 @@ INLINE void operator delete[](void *ptr) {
|
||||
|
||||
#if defined(USE_TAU) && defined(WIN32)
|
||||
// Hack around tau's lack of DLL export declarations for Profiler class.
|
||||
extern EXPCL_DTOOL bool __tau_shutdown;
|
||||
class EXPCL_DTOOL TauProfile {
|
||||
public:
|
||||
TauProfile(char *name, char *type, int group, char *group_name) {
|
||||
_tautimer = NULL;
|
||||
Tau_profile_c_timer(&_tautimer, name, type, group, group_name);
|
||||
TauProfile(void *&tautimer, char *name, char *type, int group, char *group_name) {
|
||||
Tau_profile_c_timer(&tautimer, name, type, group, group_name);
|
||||
_tautimer = tautimer;
|
||||
TAU_PROFILE_START(_tautimer);
|
||||
}
|
||||
~TauProfile() {
|
||||
TAU_PROFILE_STOP(_tautimer);
|
||||
if (!__tau_shutdown) {
|
||||
TAU_PROFILE_STOP(_tautimer);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -201,7 +204,15 @@ private:
|
||||
};
|
||||
|
||||
#undef TAU_PROFILE
|
||||
#define TAU_PROFILE(name, type, group) TauProfile _taupr(name, type, group, #group)
|
||||
#define TAU_PROFILE(name, type, group) \
|
||||
static void *__tautimer; \
|
||||
TauProfile __taupr(__tautimer, name, type, group, #group)
|
||||
|
||||
#undef TAU_PROFILE_EXIT
|
||||
#define TAU_PROFILE_EXIT(msg) \
|
||||
__tau_shutdown = true; \
|
||||
Tau_exit(msg);
|
||||
|
||||
#endif // USE_TAU
|
||||
|
||||
#endif // GLOBAL_OPERATOR_NEW_EXCEPTIONS
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#ifndef NUMERIC_TYPES_H
|
||||
#define NUMERIC_TYPES_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
// This header file defines a number of typedefs that correspond to
|
||||
// the various numeric types for unsigned and signed numbers of
|
||||
// various widths.
|
||||
|
||||
@@ -452,12 +452,17 @@ assert_failure(const char *expression, int line,
|
||||
// doesn't seem to work properly either, since we don't seem to
|
||||
// get a reliable stack trace.
|
||||
|
||||
// Guess we'll still have to force a segfault.
|
||||
// The old reliable int 3 works (at least on an Intel platform) if
|
||||
// you are already running within a debugger. But it doesn't
|
||||
// offer to bring up a debugger otherwise.
|
||||
|
||||
// So we'll force a segfault, which works every time.
|
||||
int *ptr = (int *)NULL;
|
||||
*ptr = 1;
|
||||
#else
|
||||
|
||||
#else // WIN32
|
||||
abort();
|
||||
#endif
|
||||
#endif // WIN32
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -88,7 +88,8 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
|
||||
|
||||
set_coordinate_system(get_default_coordinate_system());
|
||||
|
||||
_current_display_region = (DisplayRegion*)0L;
|
||||
_data_reader = (GeomVertexDataPipelineReader *)NULL;
|
||||
_current_display_region = (DisplayRegion*)NULL;
|
||||
_current_stereo_channel = Lens::SC_mono;
|
||||
_current_lens = (Lens *)NULL;
|
||||
_projection_mat = TransformState::make_identity();
|
||||
@@ -1253,12 +1254,13 @@ finish_decal() {
|
||||
// are ok, false to abort this group of primitives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GraphicsStateGuardian::
|
||||
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
const GeomVertexData *data) {
|
||||
begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader) {
|
||||
_munger = munger;
|
||||
_vertex_data = data;
|
||||
nassertr(geom->check_valid(data), false);
|
||||
return _vertex_data->has_vertex();
|
||||
_data_reader = data_reader;
|
||||
nassertr(geom_reader->check_valid(data_reader), false);
|
||||
return _data_reader->has_vertex();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1267,7 +1269,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
// Description: Draws a series of disconnected triangles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_triangles(const GeomTriangles *) {
|
||||
draw_triangles(const GeomPrimitivePipelineReader *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1276,7 +1278,7 @@ draw_triangles(const GeomTriangles *) {
|
||||
// Description: Draws a series of triangle strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_tristrips(const GeomTristrips *primitive) {
|
||||
draw_tristrips(const GeomPrimitivePipelineReader *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1285,7 +1287,7 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
// Description: Draws a series of triangle fans.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_trifans(const GeomTrifans *primitive) {
|
||||
draw_trifans(const GeomPrimitivePipelineReader *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1294,7 +1296,7 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
// Description: Draws a series of disconnected line segments.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_lines(const GeomLines *) {
|
||||
draw_lines(const GeomPrimitivePipelineReader *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1303,7 +1305,7 @@ draw_lines(const GeomLines *) {
|
||||
// Description: Draws a series of line strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_linestrips(const GeomLinestrips *primitive) {
|
||||
draw_linestrips(const GeomPrimitivePipelineReader *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1312,7 +1314,7 @@ draw_linestrips(const GeomLinestrips *primitive) {
|
||||
// Description: Draws a series of disconnected points.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_points(const GeomPoints *) {
|
||||
draw_points(const GeomPrimitivePipelineReader *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1325,7 +1327,7 @@ draw_points(const GeomPoints *) {
|
||||
void GraphicsStateGuardian::
|
||||
end_draw_primitives() {
|
||||
_munger = NULL;
|
||||
_vertex_data = NULL;
|
||||
_data_reader = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -193,15 +193,15 @@ public:
|
||||
virtual CPT(RenderState) begin_decal_base_second();
|
||||
virtual void finish_decal();
|
||||
|
||||
virtual bool begin_draw_primitives(const Geom *geom,
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(const GeomTriangles *primitive);
|
||||
virtual void draw_tristrips(const GeomTristrips *primitive);
|
||||
virtual void draw_trifans(const GeomTrifans *primitive);
|
||||
virtual void draw_lines(const GeomLines *primitive);
|
||||
virtual void draw_linestrips(const GeomLinestrips *primitive);
|
||||
virtual void draw_points(const GeomPoints *primitive);
|
||||
const GeomVertexDataPipelineReader *data_reader);
|
||||
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
INLINE bool reset_if_new();
|
||||
@@ -270,8 +270,11 @@ protected:
|
||||
CPT(RenderState) _state_rs;
|
||||
CPT(RenderState) _target_rs;
|
||||
CPT(TransformState) _internal_transform;
|
||||
|
||||
// These are set by begin_draw_primitives(), and are only valid
|
||||
// between begin_draw_primitives() and end_draw_primitives().
|
||||
CPT(GeomMunger) _munger;
|
||||
CPT(GeomVertexData) _vertex_data;
|
||||
const GeomVertexDataPipelineReader *_data_reader;
|
||||
|
||||
unsigned int _color_write_mask;
|
||||
Colorf _color_clear_value;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "buffer.h"
|
||||
#include "multifile.h"
|
||||
#include "pointerTo.h"
|
||||
#include "vector_int.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Extractor
|
||||
@@ -63,7 +64,7 @@ private:
|
||||
|
||||
Filename _extract_dir;
|
||||
|
||||
typedef pvector<int> Requests;
|
||||
typedef vector_int Requests;
|
||||
Requests _requests;
|
||||
size_t _requests_total_length;
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include "filename.h"
|
||||
#include "zStream.h"
|
||||
#include "pnotify.h"
|
||||
#include "config_util.h"
|
||||
|
||||
#ifndef HAVE_GETOPT
|
||||
#include "gnu_getopt.h"
|
||||
|
||||
@@ -788,24 +788,26 @@ end_frame() {
|
||||
// are ok, false to abort this group of primitives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian8::
|
||||
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
|
||||
begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger,
|
||||
data_reader)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(_vertex_data != (GeomVertexData *)NULL, false);
|
||||
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
|
||||
|
||||
const GeomVertexFormat *format = _vertex_data->get_format();
|
||||
const GeomVertexFormat *format = _data_reader->get_format();
|
||||
|
||||
// The munger should have put the FVF data in the first array.
|
||||
const GeomVertexArrayData *data = _vertex_data->get_array(0);
|
||||
const GeomVertexArrayDataPipelineReader *data = _data_reader->get_array_reader(0);
|
||||
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)(data->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, false);
|
||||
apply_vertex_buffer(vbc);
|
||||
|
||||
const GeomVertexAnimationSpec &animation =
|
||||
vertex_data->get_format()->get_animation();
|
||||
data_reader->get_format()->get_animation();
|
||||
if (animation.get_animation_type() == Geom::AT_hardware) {
|
||||
// Set up vertex blending.
|
||||
switch (animation.get_num_transforms()) {
|
||||
@@ -836,7 +838,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
_d3d_device->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
|
||||
}
|
||||
|
||||
const TransformTable *table = vertex_data->get_transform_table();
|
||||
const TransformTable *table = data_reader->get_transform_table();
|
||||
if (table != (TransformTable *)NULL) {
|
||||
for (int i = 0; i < table->get_num_transforms(); i++) {
|
||||
LMatrix4f mat;
|
||||
@@ -859,14 +861,14 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
_vertex_blending_enabled = false;
|
||||
}
|
||||
|
||||
if (_transform_stale && !_vertex_data->is_vertex_transformed()) {
|
||||
if (_transform_stale && !_data_reader->is_vertex_transformed()) {
|
||||
const D3DMATRIX *d3d_mat = (const D3DMATRIX *)_internal_transform->get_mat().get_data();
|
||||
_d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
|
||||
_transform_stale = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
// If the vertex data claims to be already transformed into clip
|
||||
// coordinates, wipe out the current projection and modelview
|
||||
// matrix (so we don't attempt to transform it again).
|
||||
@@ -895,53 +897,53 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
// Description: Draws a series of disconnected triangles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_triangles(const GeomTriangles *primitive) {
|
||||
draw_triangles(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_tri_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_tri_pcollector.add_level(1);
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
_d3d_device->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLELIST,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_primitives());
|
||||
0, reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
draw_indexed_primitive_up
|
||||
(D3DPT_TRIANGLELIST,
|
||||
min_vertex, max_vertex,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_data(),
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
index_type,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_primitives());
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
|
||||
draw_primitive_up(D3DPT_TRIANGLELIST, primitive->get_num_primitives(),
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -952,77 +954,77 @@ draw_triangles(const GeomTriangles *primitive) {
|
||||
// Description: Draws a series of triangle strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_tristrips(const GeomTristrips *primitive) {
|
||||
draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
|
||||
// One long triangle strip, connected by the degenerate vertices
|
||||
// that have already been set up within the primitive.
|
||||
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_tristrip_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_tristrip_pcollector.add_level(1);
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers, one line triangle strip.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
_d3d_device->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_vertices() - 2);
|
||||
0, reader->get_num_vertices() - 2);
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays, one long triangle strip.
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
draw_indexed_primitive_up
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
min_vertex, max_vertex,
|
||||
primitive->get_num_vertices() - 2,
|
||||
primitive->get_data(), index_type,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
reader->get_num_vertices() - 2,
|
||||
reader->get_data(), index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers, one long triangle strip.
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices() - 2);
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices() - 2);
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays, one long triangle strip.
|
||||
draw_primitive_up(D3DPT_TRIANGLESTRIP,
|
||||
primitive->get_num_vertices() - 2,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
reader->get_num_vertices() - 2,
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Send the individual triangle strips, stepping over the
|
||||
// degenerate vertices.
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_int ends = reader->get_ends();
|
||||
_primitive_batches_tristrip_pcollector.add_level(ends.size());
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
int index_stride = primitive->get_index_stride();
|
||||
if (reader->is_indexed()) {
|
||||
CPTA_int ends = reader->get_ends();
|
||||
int index_stride = reader->get_index_stride();
|
||||
_primitive_batches_tristrip_pcollector.add_level(ends.size());
|
||||
|
||||
GeomVertexReader mins(primitive->get_mins(), 0);
|
||||
GeomVertexReader maxs(primitive->get_maxs(), 0);
|
||||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
GeomVertexReader mins(reader->get_mins(), 0);
|
||||
GeomVertexReader maxs(reader->get_maxs(), 0);
|
||||
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
reader->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers, individual triangle strips.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
@@ -1041,10 +1043,10 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = primitive->get_data();
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1062,7 +1064,7 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned int first_vertex = primitive->get_first_vertex();
|
||||
unsigned int first_vertex = reader->get_first_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers, individual triangle strips.
|
||||
@@ -1078,8 +1080,8 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1102,27 +1104,27 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
// Description: Draws a series of triangle fans.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_trifans(const GeomTrifans *primitive) {
|
||||
draw_trifans(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_int ends = reader->get_ends();
|
||||
_primitive_batches_trifan_pcollector.add_level(ends.size());
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
// Send the individual triangle fans. There's no connecting fans
|
||||
// with degenerate vertices, so no worries about that.
|
||||
int index_stride = primitive->get_index_stride();
|
||||
int index_stride = reader->get_index_stride();
|
||||
|
||||
GeomVertexReader mins(primitive->get_mins(), 0);
|
||||
GeomVertexReader maxs(primitive->get_maxs(), 0);
|
||||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
GeomVertexReader mins(reader->get_mins(), 0);
|
||||
GeomVertexReader maxs(reader->get_maxs(), 0);
|
||||
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
reader->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
@@ -1141,10 +1143,10 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = primitive->get_data();
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1162,7 +1164,7 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned int first_vertex = primitive->get_first_vertex();
|
||||
unsigned int first_vertex = reader->get_first_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
@@ -1178,8 +1180,8 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1201,54 +1203,54 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
// Description: Draws a series of disconnected line segments.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_lines(const GeomLines *primitive) {
|
||||
draw_lines(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_other_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_other_pcollector.add_level(1);
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
_d3d_device->DrawIndexedPrimitive
|
||||
(D3DPT_LINELIST,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_primitives());
|
||||
0, reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
draw_indexed_primitive_up
|
||||
(D3DPT_LINELIST,
|
||||
min_vertex, max_vertex,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_data(),
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
index_type,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_LINELIST,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_primitives());
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
draw_primitive_up(D3DPT_LINELIST, primitive->get_num_primitives(),
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1259,7 +1261,7 @@ draw_lines(const GeomLines *primitive) {
|
||||
// Description: Draws a series of line strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_linestrips(const GeomLinestrips *primitive) {
|
||||
draw_linestrips(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
}
|
||||
|
||||
@@ -1269,29 +1271,29 @@ draw_linestrips(const GeomLinestrips *primitive) {
|
||||
// Description: Draws a series of disconnected points.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_points(const GeomPoints *primitive) {
|
||||
draw_points(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_other_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_other_pcollector.add_level(1);
|
||||
|
||||
// The munger should have protected us from indexed points--DirectX
|
||||
// doesn't support them.
|
||||
nassertv(!primitive->is_indexed());
|
||||
nassertv(!reader->is_indexed());
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_POINTLIST,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_primitives());
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
draw_primitive_up(D3DPT_POINTLIST, primitive->get_num_primitives(),
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1312,7 +1314,7 @@ end_draw_primitives() {
|
||||
_vertex_blending_enabled = false;
|
||||
}
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
// Restore the projection matrix that we wiped out above.
|
||||
_d3d_device->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)_projection_mat->get_mat().get_data());
|
||||
|
||||
@@ -75,15 +75,15 @@ public:
|
||||
virtual void end_scene();
|
||||
virtual void end_frame();
|
||||
|
||||
virtual bool begin_draw_primitives(const Geom *geom,
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(const GeomTriangles *primitive);
|
||||
virtual void draw_tristrips(const GeomTristrips *primitive);
|
||||
virtual void draw_trifans(const GeomTrifans *primitive);
|
||||
virtual void draw_lines(const GeomLines *primitive);
|
||||
virtual void draw_linestrips(const GeomLinestrips *primitive);
|
||||
virtual void draw_points(const GeomPoints *primitive);
|
||||
const GeomVertexDataPipelineReader *data_reader);
|
||||
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
||||
|
||||
@@ -1144,12 +1144,14 @@ DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E
|
||||
// are ok, false to abort this group of primitives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool DXGraphicsStateGuardian9::
|
||||
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
|
||||
begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger,
|
||||
data_reader)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(_vertex_data != (GeomVertexData *)NULL, false);
|
||||
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
|
||||
|
||||
DBG_SH5 dxgsg9_cat.debug ( ) << "begin_draw_primitives\n"; DBG_E
|
||||
|
||||
@@ -1173,9 +1175,9 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
_vertex_array_shader_expansion = _current_shader_expansion;
|
||||
_vertex_array_shader_context = _current_shader_context;
|
||||
|
||||
const GeomVertexFormat *format = _vertex_data->get_format ( );
|
||||
const GeomVertexArrayData *data;
|
||||
int number_of_arrays = _vertex_data -> get_num_arrays ( );
|
||||
const GeomVertexFormat *format = _data_reader->get_format ( );
|
||||
const GeomVertexArrayDataPipelineReader *data;
|
||||
int number_of_arrays = _data_reader -> get_num_arrays ( );
|
||||
|
||||
if (_current_shader_context && number_of_arrays > 1) {
|
||||
|
||||
@@ -1198,7 +1200,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
// find the one array with the minimum number of elements if possible
|
||||
{
|
||||
for (index = 0; index < number_of_arrays; index++) {
|
||||
data = _vertex_data -> get_array (index);
|
||||
data = _data_reader -> get_array_reader (index);
|
||||
|
||||
const GeomVertexArrayFormat *array_format = data->get_array_format();
|
||||
int number_of_columns = array_format->get_num_columns();
|
||||
@@ -1227,7 +1229,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
// ugh slow, need to find which one
|
||||
for (index = first_index; index < number_of_arrays; index++)
|
||||
{
|
||||
data = _vertex_data -> get_array (index);
|
||||
data = _data_reader -> get_array_reader (index);
|
||||
|
||||
const GeomVertexArrayFormat *array_format = data->get_array_format();
|
||||
int number_of_columns = array_format->get_num_columns();
|
||||
@@ -1247,15 +1249,15 @@ vertex_element_array -> vertex_element_type_array;
|
||||
}
|
||||
}
|
||||
|
||||
// since the check is not implemented yet use first_index for now
|
||||
data = _vertex_data -> get_array (first_index);
|
||||
// since the check is not implemented yet use first_index for now
|
||||
data = _data_reader -> get_array_reader (first_index);
|
||||
|
||||
match = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first_index >= 0) {
|
||||
data = _vertex_data -> get_array (first_index);
|
||||
data = _data_reader -> get_array_reader (first_index);
|
||||
match = true;
|
||||
}
|
||||
}
|
||||
@@ -1268,7 +1270,7 @@ data = _vertex_data -> get_array (first_index);
|
||||
dxgsg9_cat.error ( ) << "could not find matching vertex element data for vertex shader\n";
|
||||
|
||||
// just use the 0 array
|
||||
data = _vertex_data->get_array(0);
|
||||
data = _data_reader->get_array_reader(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1278,15 +1280,15 @@ data = _vertex_data -> get_array (first_index);
|
||||
}
|
||||
else {
|
||||
// The munger should have put the FVF data in the first array.
|
||||
data = _vertex_data->get_array(0);
|
||||
data = _data_reader->get_array_reader(0);
|
||||
}
|
||||
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)(data->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, false);
|
||||
apply_vertex_buffer(vbc, _current_shader_context);
|
||||
|
||||
const GeomVertexAnimationSpec &animation =
|
||||
vertex_data->get_format()->get_animation();
|
||||
data_reader->get_format()->get_animation();
|
||||
if (animation.get_animation_type() == Geom::AT_hardware) {
|
||||
// Set up vertex blending.
|
||||
switch (animation.get_num_transforms()) {
|
||||
@@ -1317,7 +1319,7 @@ data = _vertex_data -> get_array (first_index);
|
||||
set_render_state(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
|
||||
}
|
||||
|
||||
const TransformTable *table = vertex_data->get_transform_table();
|
||||
const TransformTable *table = data_reader->get_transform_table();
|
||||
if (table != (TransformTable *)NULL) {
|
||||
for (int i = 0; i < table->get_num_transforms(); i++) {
|
||||
LMatrix4f mat;
|
||||
@@ -1340,14 +1342,14 @@ data = _vertex_data -> get_array (first_index);
|
||||
_vertex_blending_enabled = false;
|
||||
}
|
||||
|
||||
if (_transform_stale && !_vertex_data->is_vertex_transformed()) {
|
||||
if (_transform_stale && !_data_reader->is_vertex_transformed()) {
|
||||
const D3DMATRIX *d3d_mat = (const D3DMATRIX *)_internal_transform->get_mat().get_data();
|
||||
_d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
|
||||
_transform_stale = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
// If the vertex data claims to be already transformed into clip
|
||||
// coordinates, wipe out the current projection and modelview
|
||||
// matrix (so we don't attempt to transform it again).
|
||||
@@ -1376,20 +1378,20 @@ data = _vertex_data -> get_array (first_index);
|
||||
// Description: Draws a series of disconnected triangles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
draw_triangles(const GeomTriangles *primitive) {
|
||||
draw_triangles(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
|
||||
// DBG_SH5 dxgsg9_cat.debug ( ) << "draw_triangles 1\n"; DBG_E
|
||||
|
||||
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_tri_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_tri_pcollector.add_level(1);
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
@@ -1398,22 +1400,22 @@ draw_triangles(const GeomTriangles *primitive) {
|
||||
_d3d_device->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLELIST, 0,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_primitives());
|
||||
0, reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
|
||||
//DBG_SH2 dxgsg9_cat.debug ( ) << "draw_indexed_primitive_up \n"; DBG_E
|
||||
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
draw_indexed_primitive_up
|
||||
(D3DPT_TRIANGLELIST,
|
||||
min_vertex, max_vertex,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_data(),
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
index_type,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_active_vbuffer != NULL) {
|
||||
@@ -1423,19 +1425,19 @@ draw_triangles(const GeomTriangles *primitive) {
|
||||
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_primitives());
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
|
||||
//DBG_SH2 dxgsg9_cat.debug ( ) << "draw_primitive_up \n"; DBG_E
|
||||
|
||||
draw_primitive_up(D3DPT_TRIANGLELIST, primitive->get_num_primitives(),
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1448,7 +1450,7 @@ draw_triangles(const GeomTriangles *primitive) {
|
||||
// Description: Draws a series of triangle strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
draw_tristrips(const GeomTristrips *primitive) {
|
||||
draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
|
||||
DBG_SH5 dxgsg9_cat.debug ( ) << "draw_tristrips\n"; DBG_E
|
||||
@@ -1456,80 +1458,80 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
|
||||
// One long triangle strip, connected by the degenerate vertices
|
||||
// that have already been set up within the primitive.
|
||||
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_tristrip_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_tristrip_pcollector.add_level(1);
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers, one line triangle strip.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
//dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << primitive->get_num_vertices ( ) << "\n";
|
||||
//dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n";
|
||||
|
||||
_d3d_device->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLESTRIP, 0,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_vertices() - 2);
|
||||
0, reader->get_num_vertices() - 2);
|
||||
|
||||
} else {
|
||||
|
||||
//dxgsg9_cat.error ( ) << "draw_indexed_primitive_up D3DPT_TRIANGLESTRIP VERTICES: " << primitive->get_num_vertices ( ) << "\n";
|
||||
//dxgsg9_cat.error ( ) << "draw_indexed_primitive_up D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n";
|
||||
|
||||
// Indexed, client arrays, one long triangle strip.
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
draw_indexed_primitive_up
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
min_vertex, max_vertex,
|
||||
primitive->get_num_vertices() - 2,
|
||||
primitive->get_data(), index_type,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
reader->get_num_vertices() - 2,
|
||||
reader->get_data(), index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers, one long triangle strip.
|
||||
|
||||
//dxgsg9_cat.error ( ) << "DrawPrimitive D3DPT_TRIANGLESTRIP " << primitive->get_first_vertex ( ) << " VERTICES: " << primitive->get_num_vertices ( ) << "\n";
|
||||
//dxgsg9_cat.error ( ) << "DrawPrimitive D3DPT_TRIANGLESTRIP " << reader->get_first_vertex ( ) << " VERTICES: " << reader->get_num_vertices ( ) << "\n";
|
||||
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_TRIANGLESTRIP,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices() - 2);
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices() - 2);
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays, one long triangle strip.
|
||||
draw_primitive_up(D3DPT_TRIANGLESTRIP,
|
||||
primitive->get_num_vertices() - 2,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
reader->get_num_vertices() - 2,
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Send the individual triangle strips, stepping over the
|
||||
// degenerate vertices.
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_int ends = reader->get_ends();
|
||||
_primitive_batches_tristrip_pcollector.add_level(ends.size());
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
int index_stride = primitive->get_index_stride();
|
||||
if (reader->is_indexed()) {
|
||||
CPTA_int ends = reader->get_ends();
|
||||
int index_stride = reader->get_index_stride();
|
||||
_primitive_batches_tristrip_pcollector.add_level(ends.size());
|
||||
|
||||
GeomVertexReader mins(primitive->get_mins(), 0);
|
||||
GeomVertexReader maxs(primitive->get_maxs(), 0);
|
||||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
GeomVertexReader mins(reader->get_mins(), 0);
|
||||
GeomVertexReader maxs(reader->get_maxs(), 0);
|
||||
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
reader->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers, individual triangle strips.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
@@ -1549,10 +1551,10 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = primitive->get_data();
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1570,7 +1572,7 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned int first_vertex = primitive->get_first_vertex();
|
||||
unsigned int first_vertex = reader->get_first_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers, individual triangle strips.
|
||||
@@ -1586,8 +1588,8 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1610,30 +1612,30 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
// Description: Draws a series of triangle fans.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
draw_trifans(const GeomTrifans *primitive) {
|
||||
draw_trifans(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
|
||||
DBG_SH5 dxgsg9_cat.debug ( ) << "draw_trifans\n"; DBG_E
|
||||
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_int ends = reader->get_ends();
|
||||
_primitive_batches_trifan_pcollector.add_level(ends.size());
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
// Send the individual triangle fans. There's no connecting fans
|
||||
// with degenerate vertices, so no worries about that.
|
||||
int index_stride = primitive->get_index_stride();
|
||||
int index_stride = reader->get_index_stride();
|
||||
|
||||
GeomVertexReader mins(primitive->get_mins(), 0);
|
||||
GeomVertexReader maxs(primitive->get_maxs(), 0);
|
||||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
GeomVertexReader mins(reader->get_mins(), 0);
|
||||
GeomVertexReader maxs(reader->get_maxs(), 0);
|
||||
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
reader->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
@@ -1652,10 +1654,10 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = primitive->get_data();
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1673,7 +1675,7 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
unsigned int first_vertex = primitive->get_first_vertex();
|
||||
unsigned int first_vertex = reader->get_first_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
@@ -1689,8 +1691,8 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1712,18 +1714,18 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
// Description: Draws a series of disconnected line segments.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
draw_lines(const GeomLines *primitive) {
|
||||
draw_lines(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_other_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_other_pcollector.add_level(1);
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
|
||||
int max_vertex = primitive->get_max_vertex();
|
||||
if (reader->is_indexed()) {
|
||||
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
|
||||
int max_vertex = reader->get_max_vertex();
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Indexed, vbuffers.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertv(ibc != (IndexBufferContext *)NULL);
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
@@ -1731,36 +1733,36 @@ draw_lines(const GeomLines *primitive) {
|
||||
(D3DPT_LINELIST,
|
||||
0,
|
||||
min_vertex, max_vertex - min_vertex + 1,
|
||||
0, primitive->get_num_primitives());
|
||||
0, reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
draw_indexed_primitive_up
|
||||
(D3DPT_LINELIST,
|
||||
min_vertex, max_vertex,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_data(),
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
index_type,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_LINELIST,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_primitives());
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
draw_primitive_up(D3DPT_LINELIST, primitive->get_num_primitives(),
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1771,7 +1773,7 @@ draw_lines(const GeomLines *primitive) {
|
||||
// Description: Draws a series of line strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
draw_linestrips(const GeomLinestrips *primitive) {
|
||||
draw_linestrips(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
}
|
||||
|
||||
@@ -1781,29 +1783,29 @@ draw_linestrips(const GeomLinestrips *primitive) {
|
||||
// Description: Draws a series of disconnected points.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian9::
|
||||
draw_points(const GeomPoints *primitive) {
|
||||
draw_points(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
|
||||
_vertices_other_pcollector.add_level(reader->get_num_vertices());
|
||||
_primitive_batches_other_pcollector.add_level(1);
|
||||
|
||||
// The munger should have protected us from indexed points--DirectX
|
||||
// doesn't support them.
|
||||
nassertv(!primitive->is_indexed());
|
||||
nassertv(!reader->is_indexed());
|
||||
|
||||
if (_active_vbuffer != NULL) {
|
||||
// Nonindexed, vbuffers.
|
||||
_d3d_device->DrawPrimitive
|
||||
(D3DPT_POINTLIST,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_primitives());
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_primitives());
|
||||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
draw_primitive_up(D3DPT_POINTLIST, primitive->get_num_primitives(),
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1824,7 +1826,7 @@ end_draw_primitives() {
|
||||
_vertex_blending_enabled = false;
|
||||
}
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
// Restore the projection matrix that we wiped out above.
|
||||
_d3d_device->SetTransform(D3DTS_PROJECTION,
|
||||
(D3DMATRIX*)_projection_mat->get_mat().get_data());
|
||||
|
||||
@@ -111,15 +111,15 @@ public:
|
||||
virtual void end_scene();
|
||||
virtual void end_frame();
|
||||
|
||||
virtual bool begin_draw_primitives(const Geom *geom,
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(const GeomTriangles *primitive);
|
||||
virtual void draw_tristrips(const GeomTristrips *primitive);
|
||||
virtual void draw_trifans(const GeomTrifans *primitive);
|
||||
virtual void draw_lines(const GeomLines *primitive);
|
||||
virtual void draw_linestrips(const GeomLinestrips *primitive);
|
||||
virtual void draw_points(const GeomPoints *primitive);
|
||||
const GeomVertexDataPipelineReader *data_reader);
|
||||
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
||||
|
||||
@@ -714,7 +714,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
{
|
||||
if (_vertex_element_array == 0) {
|
||||
bool error;
|
||||
const GeomVertexArrayData *array_data;
|
||||
const GeomVertexArrayDataPipelineReader *array_reader;
|
||||
Geom::NumericType numeric_type;
|
||||
int start, stride, num_values;
|
||||
int nvarying = _var_spec.size();
|
||||
@@ -744,7 +744,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gsg->_vertex_data->get_array_info(name, array_data, num_values, numeric_type, start, stride)) {
|
||||
if (gsg->_data_reader->get_array_info(name, array_reader, num_values, numeric_type, start, stride)) {
|
||||
|
||||
if (false) {
|
||||
|
||||
|
||||
@@ -252,6 +252,22 @@ test_ref_count_integrity() const {
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCount::test_ref_count_nonzero
|
||||
// Access: Published
|
||||
// Description: Does some easy checks to make sure that the reference
|
||||
// count isn't zero, or completely bogus. Returns true
|
||||
// if ok, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool ReferenceCount::
|
||||
test_ref_count_nonzero() const {
|
||||
#ifndef NDEBUG
|
||||
return do_test_ref_count_nonzero();
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCount::local_object
|
||||
// Access: Public
|
||||
|
||||
@@ -50,6 +50,20 @@ do_test_ref_count_integrity() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCount::do_test_ref_count_nonzero
|
||||
// Access: Protected
|
||||
// Description: Returns true if the reference count is nonzero, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ReferenceCount::
|
||||
do_test_ref_count_nonzero() const {
|
||||
nassertr(do_test_ref_count_integrity(), false);
|
||||
nassertr(_ref_count > 0, false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ReferenceCount::create_weak_list
|
||||
// Access: Private
|
||||
|
||||
@@ -55,6 +55,7 @@ PUBLISHED:
|
||||
INLINE bool unref() const;
|
||||
|
||||
INLINE bool test_ref_count_integrity() const;
|
||||
INLINE bool test_ref_count_nonzero() const;
|
||||
|
||||
public:
|
||||
INLINE void local_object();
|
||||
@@ -66,6 +67,7 @@ public:
|
||||
|
||||
protected:
|
||||
bool do_test_ref_count_integrity() const;
|
||||
bool do_test_ref_count_nonzero() const;
|
||||
|
||||
private:
|
||||
void create_weak_list();
|
||||
|
||||
@@ -1356,23 +1356,24 @@ end_frame() {
|
||||
// are ok, false to abort this group of primitives.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(GraphicsStateGuardian)::
|
||||
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data) {
|
||||
begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader) {
|
||||
#ifndef NDEBUG
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "begin_draw_primitives: " << *vertex_data << "\n";
|
||||
GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
|
||||
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader)) {
|
||||
return false;
|
||||
}
|
||||
nassertr(_vertex_data != (GeomVertexData *)NULL, false);
|
||||
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
|
||||
|
||||
_geom_display_list = 0;
|
||||
|
||||
if (_auto_antialias_mode) {
|
||||
switch (geom->get_primitive_type()) {
|
||||
switch (geom_reader->get_primitive_type()) {
|
||||
case GeomPrimitive::PT_polygons:
|
||||
setup_antialias_polygon();
|
||||
break;
|
||||
@@ -1396,7 +1397,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
}
|
||||
|
||||
const GeomVertexAnimationSpec &animation =
|
||||
_vertex_data->get_format()->get_animation();
|
||||
_data_reader->get_format()->get_animation();
|
||||
bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
|
||||
if (hardware_animation) {
|
||||
// Set up the transform matrices for vertex blending.
|
||||
@@ -1404,7 +1405,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
GLP(Enable)(GL_VERTEX_BLEND_ARB);
|
||||
_glVertexBlendARB(animation.get_num_transforms());
|
||||
|
||||
const TransformTable *table = _vertex_data->get_transform_table();
|
||||
const TransformTable *table = _data_reader->get_transform_table();
|
||||
if (table != (TransformTable *)NULL) {
|
||||
if (animation.get_indexed_transforms()) {
|
||||
nassertr(_supports_matrix_palette, false);
|
||||
@@ -1481,7 +1482,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
}
|
||||
}
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
// If the vertex data claims to be already transformed into clip
|
||||
// coordinates, wipe out the current projection and modelview
|
||||
// matrix (so we don't attempt to transform it again).
|
||||
@@ -1493,8 +1494,8 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
GLP(LoadIdentity)();
|
||||
}
|
||||
|
||||
if (geom->get_usage_hint() == Geom::UH_static &&
|
||||
_vertex_data->get_usage_hint() == Geom::UH_static &&
|
||||
if (geom_reader->get_usage_hint() == Geom::UH_static &&
|
||||
_data_reader->get_usage_hint() == Geom::UH_static &&
|
||||
display_lists && (!hardware_animation || display_list_animation)) {
|
||||
// If the geom claims to be totally static, try to build it into
|
||||
// a display list.
|
||||
@@ -1518,11 +1519,11 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
_current_ibuffer_index = 0;
|
||||
}
|
||||
|
||||
GeomContext *gc = ((Geom *)geom)->prepare_now(get_prepared_objects(), this);
|
||||
GeomContext *gc = ((Geom *)geom_reader->get_object())->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(gc != (GeomContext *)NULL, false);
|
||||
CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
|
||||
const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
|
||||
UpdateSeq modified = max(geom->get_modified(), _vertex_data->get_modified());
|
||||
UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
|
||||
if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
|
||||
// If it hasn't been modified, just play the display list again.
|
||||
if (GLCAT.is_spam()) {
|
||||
@@ -1563,8 +1564,8 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
// Count up the number of vertices used by primitives in the Geom,
|
||||
// for PStats reporting.
|
||||
ggc->_num_verts = 0;
|
||||
for (int i = 0; i < geom->get_num_primitives(); i++) {
|
||||
ggc->_num_verts += geom->get_primitive(i)->get_num_vertices();
|
||||
for (int i = 0; i < geom_reader->get_num_primitives(); i++) {
|
||||
ggc->_num_verts += geom_reader->get_primitive(i)->get_num_vertices();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1610,19 +1611,18 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
|
||||
// for setting up their own vertex arrays.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
update_standard_vertex_arrays()
|
||||
{
|
||||
update_standard_vertex_arrays() {
|
||||
const GeomVertexAnimationSpec &animation =
|
||||
_vertex_data->get_format()->get_animation();
|
||||
_data_reader->get_format()->get_animation();
|
||||
bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
if (_use_sender) {
|
||||
// We must use immediate mode to render primitives.
|
||||
_sender.clear();
|
||||
|
||||
_sender.add_column(_vertex_data, InternalName::get_normal(),
|
||||
_sender.add_column(_data_reader, InternalName::get_normal(),
|
||||
NULL, NULL, GLP(Normal3f), NULL);
|
||||
if (!_sender.add_column(_vertex_data, InternalName::get_color(),
|
||||
if (!_sender.add_column(_data_reader, InternalName::get_color(),
|
||||
NULL, NULL, GLP(Color3f), GLP(Color4f))) {
|
||||
// If we didn't have a color column, the item color is white.
|
||||
GLP(Color4f)(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
@@ -1647,13 +1647,13 @@ update_standard_vertex_arrays()
|
||||
if (stage_index == 0) {
|
||||
// Use the original functions for stage 0, in case we don't
|
||||
// support multitexture.
|
||||
_sender.add_column(_vertex_data, name,
|
||||
_sender.add_column(_data_reader, name,
|
||||
GLP(TexCoord1f), GLP(TexCoord2f),
|
||||
GLP(TexCoord3f), GLP(TexCoord4f));
|
||||
|
||||
} else {
|
||||
// Other stages require the multitexture functions.
|
||||
_sender.add_texcoord_column(_vertex_data, name, stage_index,
|
||||
_sender.add_texcoord_column(_data_reader, name, stage_index,
|
||||
_glMultiTexCoord1f, _glMultiTexCoord2f,
|
||||
_glMultiTexCoord3f, _glMultiTexCoord4f);
|
||||
}
|
||||
@@ -1673,12 +1673,12 @@ update_standard_vertex_arrays()
|
||||
if (_supports_vertex_blend) {
|
||||
if (hardware_animation) {
|
||||
// Issue the weights and/or transform indices for vertex blending.
|
||||
_sender.add_vector_column(_vertex_data, InternalName::get_transform_weight(),
|
||||
_sender.add_vector_column(_data_reader, InternalName::get_transform_weight(),
|
||||
_glWeightfvARB);
|
||||
|
||||
if (animation.get_indexed_transforms()) {
|
||||
// Issue the matrix palette indices.
|
||||
_sender.add_vector_uint_column(_vertex_data, InternalName::get_transform_index(),
|
||||
_sender.add_vector_uint_column(_data_reader, InternalName::get_transform_index(),
|
||||
_glMatrixIndexuivARB);
|
||||
}
|
||||
}
|
||||
@@ -1686,22 +1686,22 @@ update_standard_vertex_arrays()
|
||||
|
||||
// We must add vertex last, because glVertex3f() is the key
|
||||
// function call that actually issues the vertex.
|
||||
_sender.add_column(_vertex_data, InternalName::get_vertex(),
|
||||
_sender.add_column(_data_reader, InternalName::get_vertex(),
|
||||
NULL, GLP(Vertex2f), GLP(Vertex3f), GLP(Vertex4f));
|
||||
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
// We may use vertex arrays or buffers to render primitives.
|
||||
const GeomVertexArrayData *array_data;
|
||||
const GeomVertexArrayDataPipelineReader *array_reader;
|
||||
int num_values;
|
||||
Geom::NumericType numeric_type;
|
||||
int start;
|
||||
int stride;
|
||||
|
||||
if (_vertex_data->get_normal_info(array_data, numeric_type,
|
||||
if (_data_reader->get_normal_info(array_reader, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
const unsigned char *client_pointer = setup_array_data(array_reader);
|
||||
GLP(NormalPointer)(get_numeric_type(numeric_type), stride,
|
||||
client_pointer + start);
|
||||
GLP(EnableClientState)(GL_NORMAL_ARRAY);
|
||||
@@ -1709,10 +1709,10 @@ update_standard_vertex_arrays()
|
||||
GLP(DisableClientState)(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
if (_vertex_data->get_color_info(array_data, num_values, numeric_type,
|
||||
if (_data_reader->get_color_info(array_reader, num_values, numeric_type,
|
||||
start, stride) &&
|
||||
numeric_type != Geom::NT_packed_dabc) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
const unsigned char *client_pointer = setup_array_data(array_reader);
|
||||
GLP(ColorPointer)(num_values, get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
GLP(EnableClientState)(GL_COLOR_ARRAY);
|
||||
@@ -1742,10 +1742,10 @@ update_standard_vertex_arrays()
|
||||
// texcoords issued for it.
|
||||
const InternalName *name = stage->get_texcoord_name();
|
||||
|
||||
if (_vertex_data->get_array_info(name, array_data, num_values,
|
||||
if (_data_reader->get_array_info(name, array_reader, num_values,
|
||||
numeric_type, start, stride)) {
|
||||
// The vertex data does have texcoords for this stage.
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
const unsigned char *client_pointer = setup_array_data(array_reader);
|
||||
GLP(TexCoordPointer)(num_values, get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
GLP(EnableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||
@@ -1774,10 +1774,10 @@ update_standard_vertex_arrays()
|
||||
if (_supports_vertex_blend) {
|
||||
if (hardware_animation) {
|
||||
// Issue the weights and/or transform indices for vertex blending.
|
||||
if (_vertex_data->get_array_info(InternalName::get_transform_weight(),
|
||||
array_data, num_values, numeric_type,
|
||||
if (_data_reader->get_array_info(InternalName::get_transform_weight(),
|
||||
array_reader, num_values, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
const unsigned char *client_pointer = setup_array_data(array_reader);
|
||||
_glWeightPointerARB(num_values, get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
GLP(EnableClientState)(GL_WEIGHT_ARRAY_ARB);
|
||||
@@ -1787,10 +1787,10 @@ update_standard_vertex_arrays()
|
||||
|
||||
if (animation.get_indexed_transforms()) {
|
||||
// Issue the matrix palette indices.
|
||||
if (_vertex_data->get_array_info(InternalName::get_transform_index(),
|
||||
array_data, num_values, numeric_type,
|
||||
if (_data_reader->get_array_info(InternalName::get_transform_index(),
|
||||
array_reader, num_values, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
const unsigned char *client_pointer = setup_array_data(array_reader);
|
||||
_glMatrixIndexPointerARB(num_values, get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
GLP(EnableClientState)(GL_MATRIX_INDEX_ARRAY_ARB);
|
||||
@@ -1809,9 +1809,9 @@ update_standard_vertex_arrays()
|
||||
|
||||
// There's no requirement that we add vertices last, but we do
|
||||
// anyway.
|
||||
if (_vertex_data->get_vertex_info(array_data, num_values, numeric_type,
|
||||
if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
const unsigned char *client_pointer = setup_array_data(array_reader);
|
||||
GLP(VertexPointer)(num_values, get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
GLP(EnableClientState)(GL_VERTEX_ARRAY);
|
||||
@@ -1865,38 +1865,39 @@ disable_standard_vertex_arrays()
|
||||
// Description: Draws a series of disconnected triangles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_triangles(const GeomTriangles *primitive) {
|
||||
draw_triangles(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "draw_triangles: " << *primitive << "\n";
|
||||
GLCAT.spam() << "draw_triangles: " << *(reader->get_object()) << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
if (_use_sender) {
|
||||
draw_immediate_simple_primitives(primitive, GL_TRIANGLES);
|
||||
draw_immediate_simple_primitives(reader, GL_TRIANGLES);
|
||||
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
|
||||
int num_vertices = reader->get_num_vertices();
|
||||
_vertices_tri_pcollector.add_level(num_vertices);
|
||||
_primitive_batches_tri_pcollector.add_level(1);
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(primitive);
|
||||
if (reader->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(reader);
|
||||
|
||||
_glDrawRangeElements(GL_TRIANGLES,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
get_numeric_type(primitive->get_index_type()),
|
||||
reader->get_min_vertex(),
|
||||
reader->get_max_vertex(),
|
||||
num_vertices,
|
||||
get_numeric_type(reader->get_index_type()),
|
||||
client_pointer);
|
||||
} else {
|
||||
GLP(DrawArrays)(GL_TRIANGLES,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices());
|
||||
reader->get_first_vertex(),
|
||||
num_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1909,20 +1910,20 @@ draw_triangles(const GeomTriangles *primitive) {
|
||||
// Description: Draws a series of triangle strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_tristrips(const GeomTristrips *primitive) {
|
||||
draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
|
||||
report_my_gl_errors();
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "draw_tristrips: " << *primitive << "\n";
|
||||
GLCAT.spam() << "draw_tristrips: " << *(reader->get_object()) << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
if (_use_sender) {
|
||||
draw_immediate_composite_primitives(primitive, GL_TRIANGLE_STRIP);
|
||||
draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP);
|
||||
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
@@ -1930,35 +1931,36 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
|
||||
// One long triangle strip, connected by the degenerate vertices
|
||||
// that have already been set up within the primitive.
|
||||
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
||||
int num_vertices = reader->get_num_vertices();
|
||||
_vertices_tristrip_pcollector.add_level(num_vertices);
|
||||
_primitive_batches_tristrip_pcollector.add_level(1);
|
||||
if (primitive->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(primitive);
|
||||
if (reader->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(reader);
|
||||
_glDrawRangeElements(GL_TRIANGLE_STRIP,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
get_numeric_type(primitive->get_index_type()),
|
||||
reader->get_min_vertex(),
|
||||
reader->get_max_vertex(),
|
||||
num_vertices,
|
||||
get_numeric_type(reader->get_index_type()),
|
||||
client_pointer);
|
||||
} else {
|
||||
GLP(DrawArrays)(GL_TRIANGLE_STRIP,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices());
|
||||
reader->get_first_vertex(),
|
||||
num_vertices);
|
||||
}
|
||||
|
||||
} else {
|
||||
// Send the individual triangle strips, stepping over the
|
||||
// degenerate vertices.
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_int ends = reader->get_ends();
|
||||
|
||||
_primitive_batches_tristrip_pcollector.add_level(ends.size());
|
||||
if (primitive->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(primitive);
|
||||
int index_stride = primitive->get_index_stride();
|
||||
GeomVertexReader mins(primitive->get_mins(), 0);
|
||||
GeomVertexReader maxs(primitive->get_maxs(), 0);
|
||||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
if (reader->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(reader);
|
||||
int index_stride = reader->get_index_stride();
|
||||
GeomVertexReader mins(reader->get_mins(), 0);
|
||||
GeomVertexReader maxs(reader->get_maxs(), 0);
|
||||
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
reader->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
@@ -1966,13 +1968,13 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
_glDrawRangeElements(GL_TRIANGLE_STRIP,
|
||||
mins.get_data1i(), maxs.get_data1i(),
|
||||
ends[i] - start,
|
||||
get_numeric_type(primitive->get_index_type()),
|
||||
get_numeric_type(reader->get_index_type()),
|
||||
client_pointer + start * index_stride);
|
||||
start = ends[i] + 2;
|
||||
}
|
||||
} else {
|
||||
unsigned int start = 0;
|
||||
int first_vertex = primitive->get_first_vertex();
|
||||
int first_vertex = reader->get_first_vertex();
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
_vertices_tristrip_pcollector.add_level(ends[i] - start);
|
||||
GLP(DrawArrays)(GL_TRIANGLE_STRIP, first_vertex + start,
|
||||
@@ -1992,45 +1994,45 @@ draw_tristrips(const GeomTristrips *primitive) {
|
||||
// Description: Draws a series of triangle fans.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_trifans(const GeomTrifans *primitive) {
|
||||
draw_trifans(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
#ifndef NDEBUG
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "draw_trifans: " << *primitive << "\n";
|
||||
GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
if (_use_sender) {
|
||||
draw_immediate_composite_primitives(primitive, GL_TRIANGLE_FAN);
|
||||
draw_immediate_composite_primitives(reader, GL_TRIANGLE_FAN);
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
// Send the individual triangle fans. There's no connecting fans
|
||||
// with degenerate vertices, so no worries about that.
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_int ends = reader->get_ends();
|
||||
|
||||
_primitive_batches_trifan_pcollector.add_level(ends.size());
|
||||
if (primitive->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(primitive);
|
||||
int index_stride = primitive->get_index_stride();
|
||||
GeomVertexReader mins(primitive->get_mins(), 0);
|
||||
GeomVertexReader maxs(primitive->get_maxs(), 0);
|
||||
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
primitive->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
if (reader->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(reader);
|
||||
int index_stride = reader->get_index_stride();
|
||||
GeomVertexReader mins(reader->get_mins(), 0);
|
||||
GeomVertexReader maxs(reader->get_maxs(), 0);
|
||||
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
|
||||
reader->get_maxs()->get_num_rows() == (int)ends.size());
|
||||
|
||||
unsigned int start = 0;
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
_vertices_trifan_pcollector.add_level(ends[i] - start);
|
||||
_glDrawRangeElements(GL_TRIANGLE_FAN,
|
||||
mins.get_data1i(), maxs.get_data1i(), ends[i] - start,
|
||||
get_numeric_type(primitive->get_index_type()),
|
||||
get_numeric_type(reader->get_index_type()),
|
||||
client_pointer + start * index_stride);
|
||||
start = ends[i];
|
||||
}
|
||||
} else {
|
||||
unsigned int start = 0;
|
||||
int first_vertex = primitive->get_first_vertex();
|
||||
int first_vertex = reader->get_first_vertex();
|
||||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
_vertices_trifan_pcollector.add_level(ends[i] - start);
|
||||
GLP(DrawArrays)(GL_TRIANGLE_FAN, first_vertex + start,
|
||||
@@ -2049,35 +2051,36 @@ draw_trifans(const GeomTrifans *primitive) {
|
||||
// Description: Draws a series of disconnected line segments.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_lines(const GeomLines *primitive) {
|
||||
draw_lines(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
#ifndef NDEBUG
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "draw_lines: " << *primitive << "\n";
|
||||
GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
if (_use_sender) {
|
||||
draw_immediate_simple_primitives(primitive, GL_LINES);
|
||||
draw_immediate_simple_primitives(reader, GL_LINES);
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
|
||||
int num_vertices = reader->get_num_vertices();
|
||||
_vertices_other_pcollector.add_level(num_vertices);
|
||||
_primitive_batches_other_pcollector.add_level(1);
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(primitive);
|
||||
if (reader->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(reader);
|
||||
_glDrawRangeElements(GL_LINES,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
get_numeric_type(primitive->get_index_type()),
|
||||
reader->get_min_vertex(),
|
||||
reader->get_max_vertex(),
|
||||
num_vertices,
|
||||
get_numeric_type(reader->get_index_type()),
|
||||
client_pointer);
|
||||
} else {
|
||||
GLP(DrawArrays)(GL_LINES,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices());
|
||||
reader->get_first_vertex(),
|
||||
num_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2090,11 +2093,11 @@ draw_lines(const GeomLines *primitive) {
|
||||
// Description: Draws a series of line strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_linestrips(const GeomLinestrips *primitive) {
|
||||
draw_linestrips(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
#ifndef NDEBUG
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "draw_linestrips: " << *primitive << "\n";
|
||||
GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
@@ -2106,35 +2109,36 @@ draw_linestrips(const GeomLinestrips *primitive) {
|
||||
// Description: Draws a series of disconnected points.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_points(const GeomPoints *primitive) {
|
||||
draw_points(const GeomPrimitivePipelineReader *reader) {
|
||||
PStatTimer timer(_draw_primitive_pcollector);
|
||||
#ifndef NDEBUG
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam() << "draw_points: " << *primitive << "\n";
|
||||
GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
if (_use_sender) {
|
||||
draw_immediate_simple_primitives(primitive, GL_POINTS);
|
||||
draw_immediate_simple_primitives(reader, GL_POINTS);
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
|
||||
int num_vertices = reader->get_num_vertices();
|
||||
_vertices_other_pcollector.add_level(num_vertices);
|
||||
_primitive_batches_other_pcollector.add_level(1);
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(primitive);
|
||||
if (reader->is_indexed()) {
|
||||
const unsigned char *client_pointer = setup_primitive(reader);
|
||||
_glDrawRangeElements(GL_POINTS,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
get_numeric_type(primitive->get_index_type()),
|
||||
reader->get_min_vertex(),
|
||||
reader->get_max_vertex(),
|
||||
num_vertices,
|
||||
get_numeric_type(reader->get_index_type()),
|
||||
client_pointer);
|
||||
} else {
|
||||
GLP(DrawArrays)(GL_POINTS,
|
||||
primitive->get_first_vertex(),
|
||||
primitive->get_num_vertices());
|
||||
reader->get_first_vertex(),
|
||||
num_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2176,7 +2180,7 @@ end_draw_primitives() {
|
||||
GLP(LoadMatrixf)(_internal_transform->get_mat().get_data());
|
||||
}
|
||||
|
||||
if (_vertex_data->is_vertex_transformed()) {
|
||||
if (_data_reader->is_vertex_transformed()) {
|
||||
// Restore the matrices that we pushed above.
|
||||
GLP(MatrixMode)(GL_PROJECTION);
|
||||
GLP(PopMatrix)();
|
||||
@@ -2704,19 +2708,19 @@ release_vertex_buffer(VertexBufferContext *vbc) {
|
||||
// memory.
|
||||
//
|
||||
// If the buffer object is bound, this function returns
|
||||
// NULL (reprsenting the start of the buffer object in
|
||||
// NULL (representing the start of the buffer object in
|
||||
// server memory); if the buffer object is not bound,
|
||||
// this function returns the pointer to the data array
|
||||
// in client memory, that is, the data array passed in.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const unsigned char *CLP(GraphicsStateGuardian)::
|
||||
setup_array_data(const GeomVertexArrayData *data) {
|
||||
setup_array_data(const GeomVertexArrayDataPipelineReader *array_reader) {
|
||||
if (!_supports_buffers) {
|
||||
// No support for buffer objects; always render from client.
|
||||
return data->get_data();
|
||||
return array_reader->get_data();
|
||||
}
|
||||
if (!vertex_buffers || _geom_display_list != 0 ||
|
||||
data->get_usage_hint() == Geom::UH_client) {
|
||||
array_reader->get_usage_hint() == Geom::UH_client) {
|
||||
// The array specifies client rendering only, or buffer objects
|
||||
// are configured off.
|
||||
if (_current_vbuffer_index != 0) {
|
||||
@@ -2727,12 +2731,12 @@ setup_array_data(const GeomVertexArrayData *data) {
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
_current_vbuffer_index = 0;
|
||||
}
|
||||
return data->get_data();
|
||||
return array_reader->get_data();
|
||||
}
|
||||
|
||||
// Prepare the buffer object and bind it.
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, data->get_data());
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, array_reader->get_data());
|
||||
apply_vertex_buffer(vbc);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer object.
|
||||
@@ -2780,9 +2784,10 @@ prepare_index_buffer(GeomPrimitive *data) {
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
apply_index_buffer(IndexBufferContext *ibc) {
|
||||
apply_index_buffer(IndexBufferContext *ibc,
|
||||
const GeomPrimitivePipelineReader *reader) {
|
||||
nassertv(_supports_buffers);
|
||||
nassertv(ibc->get_data()->get_modified() != UpdateSeq::initial());
|
||||
nassertv(reader->get_modified() != UpdateSeq::initial());
|
||||
|
||||
CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
|
||||
|
||||
@@ -2798,7 +2803,7 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
||||
|
||||
if (gibc->was_modified()) {
|
||||
PStatTimer timer(_load_index_buffer_pcollector);
|
||||
int num_bytes = gibc->get_data()->get_data_size_bytes();
|
||||
int num_bytes = reader->get_data_size_bytes();
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
<< "copying " << num_bytes
|
||||
@@ -2807,12 +2812,12 @@ apply_index_buffer(IndexBufferContext *ibc) {
|
||||
if (num_bytes != 0) {
|
||||
if (gibc->changed_size() || gibc->changed_usage_hint()) {
|
||||
_glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes,
|
||||
gibc->get_data()->get_data(),
|
||||
get_usage(gibc->get_data()->get_usage_hint()));
|
||||
reader->get_data(),
|
||||
get_usage(reader->get_usage_hint()));
|
||||
|
||||
} else {
|
||||
_glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
|
||||
gibc->get_data()->get_data());
|
||||
reader->get_data());
|
||||
}
|
||||
_data_transferred_pcollector.add_level(num_bytes);
|
||||
}
|
||||
@@ -2877,13 +2882,13 @@ release_index_buffer(IndexBufferContext *ibc) {
|
||||
// in client memory, that is, the data array passed in.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const unsigned char *CLP(GraphicsStateGuardian)::
|
||||
setup_primitive(const GeomPrimitive *data) {
|
||||
setup_primitive(const GeomPrimitivePipelineReader *reader) {
|
||||
if (!_supports_buffers) {
|
||||
// No support for buffer objects; always render from client.
|
||||
return data->get_data();
|
||||
return reader->get_data();
|
||||
}
|
||||
if (!vertex_buffers || _geom_display_list != 0 ||
|
||||
data->get_usage_hint() == Geom::UH_client) {
|
||||
reader->get_usage_hint() == Geom::UH_client) {
|
||||
// The array specifies client rendering only, or buffer objects
|
||||
// are configured off.
|
||||
if (_current_ibuffer_index != 0) {
|
||||
@@ -2894,13 +2899,13 @@ setup_primitive(const GeomPrimitive *data) {
|
||||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
_current_ibuffer_index = 0;
|
||||
}
|
||||
return data->get_data();
|
||||
return reader->get_data();
|
||||
}
|
||||
|
||||
// Prepare the buffer object and bind it.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(ibc != (IndexBufferContext *)NULL, data->get_data());
|
||||
apply_index_buffer(ibc);
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)reader->get_object())->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(ibc != (IndexBufferContext *)NULL, reader->get_data());
|
||||
apply_index_buffer(ibc, reader);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer object.
|
||||
return NULL;
|
||||
@@ -3926,19 +3931,20 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
|
||||
// primitives of the indicated type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode) {
|
||||
_vertices_immediate_pcollector.add_level(primitive->get_num_vertices());
|
||||
draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
|
||||
int num_vertices = reader->get_num_vertices();
|
||||
_vertices_immediate_pcollector.add_level(num_vertices);
|
||||
GLP(Begin)(mode);
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
for (int v = 0; v < primitive->get_num_vertices(); ++v) {
|
||||
_sender.set_vertex(primitive->get_vertex(v));
|
||||
if (reader->is_indexed()) {
|
||||
for (int v = 0; v < num_vertices; ++v) {
|
||||
_sender.set_vertex(reader->get_vertex(v));
|
||||
_sender.issue_vertex();
|
||||
}
|
||||
|
||||
} else {
|
||||
_sender.set_vertex(primitive->get_first_vertex());
|
||||
for (int v = 0; v < primitive->get_num_vertices(); ++v) {
|
||||
_sender.set_vertex(reader->get_first_vertex());
|
||||
for (int v = 0; v < num_vertices; ++v) {
|
||||
_sender.issue_vertex();
|
||||
}
|
||||
}
|
||||
@@ -3957,12 +3963,13 @@ draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode) {
|
||||
// several begin/end groups.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode) {
|
||||
_vertices_immediate_pcollector.add_level(primitive->get_num_vertices());
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
int num_unused_vertices_per_primitive = primitive->get_num_unused_vertices_per_primitive();
|
||||
draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
|
||||
int num_vertices = reader->get_num_vertices();
|
||||
_vertices_immediate_pcollector.add_level(num_vertices);
|
||||
CPTA_int ends = reader->get_ends();
|
||||
int num_unused_vertices_per_primitive = reader->get_object()->get_num_unused_vertices_per_primitive();
|
||||
|
||||
if (primitive->is_indexed()) {
|
||||
if (reader->is_indexed()) {
|
||||
int begin = 0;
|
||||
CPTA_int::const_iterator ei;
|
||||
for (ei = ends.begin(); ei != ends.end(); ++ei) {
|
||||
@@ -3970,7 +3977,7 @@ draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode)
|
||||
|
||||
GLP(Begin)(mode);
|
||||
for (int v = begin; v < end; ++v) {
|
||||
_sender.set_vertex(primitive->get_vertex(v));
|
||||
_sender.set_vertex(reader->get_vertex(v));
|
||||
_sender.issue_vertex();
|
||||
}
|
||||
GLP(End)();
|
||||
@@ -3979,7 +3986,7 @@ draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode)
|
||||
}
|
||||
|
||||
} else {
|
||||
_sender.set_vertex(primitive->get_first_vertex());
|
||||
_sender.set_vertex(reader->get_first_vertex());
|
||||
int begin = 0;
|
||||
CPTA_int::const_iterator ei;
|
||||
for (ei = ends.begin(); ei != ends.end(); ++ei) {
|
||||
|
||||
@@ -96,15 +96,15 @@ public:
|
||||
virtual bool begin_frame();
|
||||
virtual void end_frame();
|
||||
|
||||
virtual bool begin_draw_primitives(const Geom *geom,
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(const GeomTriangles *primitive);
|
||||
virtual void draw_tristrips(const GeomTristrips *primitive);
|
||||
virtual void draw_trifans(const GeomTrifans *primitive);
|
||||
virtual void draw_lines(const GeomLines *primitive);
|
||||
virtual void draw_linestrips(const GeomLinestrips *primitive);
|
||||
virtual void draw_points(const GeomPoints *primitive);
|
||||
const GeomVertexDataPipelineReader *data_reader);
|
||||
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
INLINE bool draw_display_list(GeomContext *gc);
|
||||
@@ -124,12 +124,13 @@ public:
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
|
||||
void apply_vertex_buffer(VertexBufferContext *vbc);
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
const unsigned char *setup_array_data(const GeomVertexArrayData *data);
|
||||
const unsigned char *setup_array_data(const GeomVertexArrayDataPipelineReader *data);
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
|
||||
void apply_index_buffer(IndexBufferContext *ibc);
|
||||
void apply_index_buffer(IndexBufferContext *ibc,
|
||||
const GeomPrimitivePipelineReader *reader);
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc);
|
||||
const unsigned char *setup_primitive(const GeomPrimitive *data);
|
||||
const unsigned char *setup_primitive(const GeomPrimitivePipelineReader *reader);
|
||||
|
||||
virtual void begin_occlusion_query();
|
||||
virtual PT(OcclusionQueryContext) end_occlusion_query();
|
||||
@@ -159,8 +160,8 @@ public:
|
||||
const float *get_light_color(Light *light) const;
|
||||
|
||||
#ifdef SUPPORT_IMMEDIATE_MODE
|
||||
void draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode);
|
||||
void draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode);
|
||||
void draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode);
|
||||
void draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode);
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
|
||||
INLINE static bool report_errors(int line, const char *source_file);
|
||||
|
||||
@@ -89,10 +89,10 @@ issue_vertex() {
|
||||
// named column doesn't exist in the vertex data).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ImmediateModeSender)::
|
||||
add_column(const GeomVertexData *vertex_data, const InternalName *name,
|
||||
add_column(const GeomVertexDataPipelineReader *data_reader, const InternalName *name,
|
||||
Func1f *func1f, Func2f *func2f, Func3f *func3f, Func4f *func4f) {
|
||||
if (vertex_data->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
|
||||
if (data_reader->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
|
||||
ComponentSender *sender = NULL;
|
||||
const GeomVertexColumn *column = reader->get_column();
|
||||
switch (column->get_num_components()) {
|
||||
@@ -151,12 +151,12 @@ add_column(const GeomVertexData *vertex_data, const InternalName *name,
|
||||
// named column doesn't exist in the vertex data).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ImmediateModeSender)::
|
||||
add_texcoord_column(const GeomVertexData *vertex_data,
|
||||
add_texcoord_column(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name, int stage_index,
|
||||
TexcoordFunc1f *func1f, TexcoordFunc2f *func2f,
|
||||
TexcoordFunc3f *func3f, TexcoordFunc4f *func4f) {
|
||||
if (vertex_data->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
|
||||
if (data_reader->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
|
||||
ComponentSender *sender = NULL;
|
||||
const GeomVertexColumn *column = reader->get_column();
|
||||
switch (column->get_num_components()) {
|
||||
@@ -209,10 +209,10 @@ add_texcoord_column(const GeomVertexData *vertex_data,
|
||||
// named column doesn't exist in the vertex data).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ImmediateModeSender)::
|
||||
add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
|
||||
add_vector_column(const GeomVertexDataPipelineReader *data_reader, const InternalName *name,
|
||||
VectorFunc *func) {
|
||||
if (vertex_data->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
|
||||
if (data_reader->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
|
||||
ComponentSender *sender = NULL;
|
||||
const GeomVertexColumn *column = reader->get_column();
|
||||
switch (column->get_num_components()) {
|
||||
@@ -262,10 +262,10 @@ add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
|
||||
// named column doesn't exist in the vertex data).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool CLP(ImmediateModeSender)::
|
||||
add_vector_uint_column(const GeomVertexData *vertex_data,
|
||||
add_vector_uint_column(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name, VectorUintFunc *func) {
|
||||
if (vertex_data->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
|
||||
if (data_reader->has_column(name)) {
|
||||
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
|
||||
ComponentSender *sender = NULL;
|
||||
const GeomVertexColumn *column = reader->get_column();
|
||||
switch (column->get_num_components()) {
|
||||
|
||||
@@ -58,17 +58,18 @@ public:
|
||||
typedef void APIENTRY VectorFunc(GLint, const GLfloat *);
|
||||
typedef void APIENTRY VectorUintFunc(GLint, const GLuint *);
|
||||
|
||||
bool add_column(const GeomVertexData *vertex_data, const InternalName *name,
|
||||
Func1f *func1f, Func2f *func2f, Func3f *func3f, Func4f *func4f);
|
||||
bool add_texcoord_column(const GeomVertexData *vertex_data,
|
||||
bool add_column(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name, Func1f *func1f,
|
||||
Func2f *func2f, Func3f *func3f, Func4f *func4f);
|
||||
bool add_texcoord_column(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name, int stage_index,
|
||||
TexcoordFunc1f *func1f, TexcoordFunc2f *func2f,
|
||||
TexcoordFunc3f *func3f, TexcoordFunc4f *func4f);
|
||||
|
||||
bool add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
|
||||
VectorFunc *func);
|
||||
bool add_vector_uint_column(const GeomVertexData *vertex_data, const InternalName *name,
|
||||
VectorUintFunc *func);
|
||||
bool add_vector_column(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name, VectorFunc *func);
|
||||
bool add_vector_uint_column(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name, VectorUintFunc *func);
|
||||
|
||||
void add_sender(ComponentSender *sender);
|
||||
|
||||
|
||||
@@ -419,8 +419,7 @@ bind(GSG *gsg) {
|
||||
// Description: This function disables a currently-bound shader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
unbind()
|
||||
{
|
||||
unbind() {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context != 0) {
|
||||
cgGLDisableProfile(_cg_profile[SHADER_type_vert]);
|
||||
@@ -445,8 +444,7 @@ unbind()
|
||||
// transforms.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
issue_parameters(GSG *gsg, bool altered)
|
||||
{
|
||||
issue_parameters(GSG *gsg, bool altered) {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context == 0) {
|
||||
return;
|
||||
@@ -482,8 +480,7 @@ issue_parameters(GSG *gsg, bool altered)
|
||||
// Description: Disable all the vertex arrays used by this shader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
disable_shader_vertex_arrays(GSG *gsg)
|
||||
{
|
||||
disable_shader_vertex_arrays(GSG *gsg) {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context == 0) {
|
||||
return;
|
||||
@@ -508,8 +505,7 @@ disable_shader_vertex_arrays(GSG *gsg)
|
||||
// reenable them. We may optimize this someday.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
{
|
||||
update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) {
|
||||
if (prev) prev->disable_shader_vertex_arrays(gsg);
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context == 0) {
|
||||
@@ -522,7 +518,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
const GeomVertexArrayData *array_data;
|
||||
const GeomVertexArrayDataPipelineReader *array_reader;
|
||||
Geom::NumericType numeric_type;
|
||||
int start, stride, num_values;
|
||||
int nvarying = _var_spec.size();
|
||||
@@ -543,10 +539,10 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gsg->_vertex_data->get_array_info(name,
|
||||
array_data, num_values, numeric_type,
|
||||
if (gsg->_data_reader->get_array_info(name,
|
||||
array_reader, num_values, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = gsg->setup_array_data(array_data);
|
||||
const unsigned char *client_pointer = gsg->setup_array_data(array_reader);
|
||||
cgGLSetParameterPointer(p,
|
||||
num_values, gsg->get_numeric_type(numeric_type),
|
||||
stride, client_pointer + start);
|
||||
@@ -565,8 +561,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
// Description: Disable all the texture bindings used by this shader.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
disable_shader_texture_bindings(GSG *gsg)
|
||||
{
|
||||
disable_shader_texture_bindings(GSG *gsg) {
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context == 0) {
|
||||
return;
|
||||
@@ -602,8 +597,7 @@ disable_shader_texture_bindings(GSG *gsg)
|
||||
// reenable them. We may optimize this someday.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(ShaderContext)::
|
||||
update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
|
||||
{
|
||||
update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg) {
|
||||
if (prev) prev->disable_shader_texture_bindings(gsg);
|
||||
#ifdef HAVE_CGGL
|
||||
if (_cg_context == 0) {
|
||||
|
||||
@@ -461,6 +461,174 @@ CData(const Geom::CData ©) :
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::
|
||||
GeomPipelineReader(const Geom *object, int pipeline_stage) :
|
||||
_object(object),
|
||||
_pipeline_stage(pipeline_stage),
|
||||
_cdata(object->_cycler.read_stage(pipeline_stage))
|
||||
{
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::
|
||||
GeomPipelineReader(const GeomPipelineReader &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomPipelineReader::
|
||||
operator = (const GeomPipelineReader &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::
|
||||
~GeomPipelineReader() {
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
|
||||
_object = NULL;
|
||||
_cdata = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const Geom *GeomPipelineReader::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_pipeline_stage
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPipelineReader::
|
||||
get_pipeline_stage() const {
|
||||
return _pipeline_stage;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::check_usage_hint
|
||||
// Access: Public
|
||||
// Description: Ensures that the Geom's usage_hint cache has been
|
||||
// computed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomPipelineReader::
|
||||
check_usage_hint() const {
|
||||
if (!_cdata->_got_usage_hint) {
|
||||
((Geom *)_object)->reset_usage_hint((Geom::CData *)_cdata);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_primitive_type
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::PrimitiveType GeomPipelineReader::
|
||||
get_primitive_type() const {
|
||||
return _cdata->_primitive_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_shade_model
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::ShadeModel GeomPipelineReader::
|
||||
get_shade_model() const {
|
||||
return _cdata->_shade_model;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_geom_rendering
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPipelineReader::
|
||||
get_geom_rendering() const {
|
||||
return _cdata->_geom_rendering;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_usage_hint
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPipelineReader::UsageHint GeomPipelineReader::
|
||||
get_usage_hint() const {
|
||||
nassertr(_cdata->_got_usage_hint, UH_static);
|
||||
return _cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_vertex_data
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(GeomVertexData) GeomPipelineReader::
|
||||
get_vertex_data() const {
|
||||
return _cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_num_primitives
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPipelineReader::
|
||||
get_num_primitives() const {
|
||||
return _cdata->_primitives.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_primitive
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomPrimitive *GeomPipelineReader::
|
||||
get_primitive(int i) const {
|
||||
nassertr(i >= 0 && i < (int)_cdata->_primitives.size(), NULL);
|
||||
return _cdata->_primitives[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::get_modified
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomPipelineReader::
|
||||
get_modified() const {
|
||||
return _cdata->_modified;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const Geom &obj) {
|
||||
obj.output(out);
|
||||
|
||||
+64
-61
@@ -685,18 +685,11 @@ transform_vertices(const LMatrix4f &mat) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Geom::
|
||||
check_valid() const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
if (!(*pi)->check_valid(cdata->_data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
GeomPipelineReader geom_reader(this, pipeline_stage);
|
||||
GeomVertexDataPipelineReader data_reader(geom_reader.get_vertex_data(), pipeline_stage);
|
||||
data_reader.check_array_readers();
|
||||
return geom_reader.check_valid(&data_reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -709,18 +702,11 @@ check_valid() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Geom::
|
||||
check_valid(const GeomVertexData *vertex_data) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
if (!(*pi)->check_valid(vertex_data)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
GeomPipelineReader geom_reader(this, pipeline_stage);
|
||||
GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage);
|
||||
data_reader.check_array_readers();
|
||||
return geom_reader.check_valid(&data_reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -945,21 +931,14 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
void Geom::
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data) const {
|
||||
CDReader cdata(_cycler);
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
GeomPipelineReader geom_reader(this, pipeline_stage);
|
||||
geom_reader.check_usage_hint();
|
||||
|
||||
#ifdef DO_PIPELINING
|
||||
// Make sure the usage_hint is already updated before we start to
|
||||
// draw, so we don't end up with a circular lock if the GSG asks us
|
||||
// to update this while we're holding the read lock.
|
||||
if (!cdata->_got_usage_hint) {
|
||||
{
|
||||
CDWriter cdataw(((Geom *)this)->_cycler, cdata, false);
|
||||
((Geom *)this)->reset_usage_hint(cdataw);
|
||||
do_draw(gsg, munger, vertex_data, cdataw);
|
||||
}
|
||||
} else
|
||||
#endif // DO_PIPELINING
|
||||
do_draw(gsg, munger, vertex_data, cdata);
|
||||
GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage);
|
||||
data_reader.check_array_readers();
|
||||
|
||||
geom_reader.draw(gsg, munger, &data_reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -1083,29 +1062,6 @@ check_will_be_valid(const GeomVertexData *vertex_data) const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::do_draw
|
||||
// Access: Private
|
||||
// Description: The private implementation of draw().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Geom::
|
||||
do_draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data, const Geom::CData *cdata) const {
|
||||
PStatTimer timer(_draw_primitive_setup_pcollector);
|
||||
if (gsg->begin_draw_primitives(this, munger, vertex_data)) {
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
const GeomPrimitive *primitive = (*pi);
|
||||
if (primitive->get_num_vertices() != 0) {
|
||||
(*pi)->draw(gsg);
|
||||
}
|
||||
}
|
||||
gsg->end_draw_primitives();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::reset_usage_hint
|
||||
@@ -1374,3 +1330,50 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_got_usage_hint = false;
|
||||
_modified = Geom::get_next_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::check_valid
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomPipelineReader::
|
||||
check_valid(const GeomVertexDataPipelineReader *data_reader) const {
|
||||
Geom::Primitives::const_iterator pi;
|
||||
for (pi = _cdata->_primitives.begin();
|
||||
pi != _cdata->_primitives.end();
|
||||
++pi) {
|
||||
const GeomPrimitive *primitive = (*pi);
|
||||
GeomPrimitivePipelineReader reader(primitive, _pipeline_stage);
|
||||
reader.check_minmax();
|
||||
if (!reader.check_valid(data_reader)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPipelineReader::draw
|
||||
// Access: Public
|
||||
// Description: The implementation of Geom::draw().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPipelineReader::
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader) const {
|
||||
PStatTimer timer(Geom::_draw_primitive_setup_pcollector);
|
||||
if (gsg->begin_draw_primitives(this, munger, data_reader)) {
|
||||
Geom::Primitives::const_iterator pi;
|
||||
for (pi = _cdata->_primitives.begin();
|
||||
pi != _cdata->_primitives.end();
|
||||
++pi) {
|
||||
const GeomPrimitive *primitive = (*pi);
|
||||
GeomPrimitivePipelineReader reader(primitive, _pipeline_stage);
|
||||
if (reader.get_num_vertices() != 0) {
|
||||
reader.check_minmax();
|
||||
primitive->draw(gsg, &reader);
|
||||
}
|
||||
}
|
||||
gsg->end_draw_primitives();
|
||||
}
|
||||
}
|
||||
|
||||
+43
-5
@@ -156,11 +156,6 @@ private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
bool check_will_be_valid(const GeomVertexData *vertex_data) const;
|
||||
|
||||
void do_draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data,
|
||||
const CData *cdata) const;
|
||||
|
||||
void reset_usage_hint(CData *cdata);
|
||||
void reset_geom_rendering(CData *cdata);
|
||||
|
||||
@@ -296,9 +291,52 @@ private:
|
||||
friend class CacheEntry;
|
||||
friend class GeomMunger;
|
||||
friend class GeomContext;
|
||||
friend class GeomPipelineReader;
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomPipelineReader
|
||||
// Description : Encapsulates the data from a Geom,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomPipelineReader : public GeomEnums {
|
||||
public:
|
||||
INLINE GeomPipelineReader(const Geom *object, int pipeline_stage);
|
||||
private:
|
||||
INLINE GeomPipelineReader(const GeomPipelineReader ©);
|
||||
INLINE void operator = (const GeomPipelineReader ©);
|
||||
|
||||
public:
|
||||
INLINE ~GeomPipelineReader();
|
||||
ALLOC_DELETED_CHAIN(GeomPipelineReader);
|
||||
|
||||
INLINE const Geom *get_object() const;
|
||||
INLINE int get_pipeline_stage() const;
|
||||
|
||||
INLINE void check_usage_hint() const;
|
||||
|
||||
INLINE PrimitiveType get_primitive_type() const;
|
||||
INLINE ShadeModel get_shade_model() const;
|
||||
INLINE int get_geom_rendering() const;
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE CPT(GeomVertexData) get_vertex_data() const;
|
||||
INLINE int get_num_primitives() const;
|
||||
INLINE const GeomPrimitive *get_primitive(int i) const;
|
||||
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
|
||||
|
||||
void draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
|
||||
const GeomVertexDataPipelineReader *data_reader) const;
|
||||
|
||||
private:
|
||||
const Geom *_object;
|
||||
int _pipeline_stage;
|
||||
const Geom::CData *_cdata;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const Geom &obj);
|
||||
|
||||
#include "geom.I"
|
||||
|
||||
@@ -35,8 +35,8 @@ PStatCollector GeomCacheManager::_geom_cache_evict_pcollector("Geom cache operat
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomCacheManager::
|
||||
GeomCacheManager() :
|
||||
_total_size(0),
|
||||
_lock("GeomCacheManager")
|
||||
_lock("GeomCacheManager"),
|
||||
_total_size(0)
|
||||
{
|
||||
// We deliberately hang on to this pointer forever.
|
||||
_list = new GeomCacheEntry;
|
||||
|
||||
@@ -117,8 +117,8 @@ get_min_num_vertices_per_primitive() const {
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomLines::
|
||||
draw(GraphicsStateGuardianBase *gsg) const {
|
||||
gsg->draw_lines(this);
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
|
||||
gsg->draw_lines(reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -40,7 +40,8 @@ public:
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomPrimitivePipelineReader *reader) const;
|
||||
|
||||
protected:
|
||||
virtual CPT(GeomVertexArrayData) rotate_impl() const;
|
||||
|
||||
@@ -117,8 +117,8 @@ get_min_num_vertices_per_primitive() const {
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomLinestrips::
|
||||
draw(GraphicsStateGuardianBase *gsg) const {
|
||||
gsg->draw_linestrips(this);
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
|
||||
gsg->draw_linestrips(reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -39,7 +39,8 @@ public:
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomPrimitivePipelineReader *reader) const;
|
||||
|
||||
protected:
|
||||
virtual CPT(GeomPrimitive) decompose_impl() const;
|
||||
|
||||
@@ -134,8 +134,8 @@ get_min_num_vertices_per_primitive() const {
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPoints::
|
||||
draw(GraphicsStateGuardianBase *gsg) const {
|
||||
gsg->draw_points(this);
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
|
||||
gsg->draw_points(reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -41,7 +41,8 @@ public:
|
||||
virtual int get_min_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomPrimitivePipelineReader *reader) const;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
||||
+281
-42
@@ -111,8 +111,23 @@ is_composite() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomPrimitive::
|
||||
is_indexed() const {
|
||||
CDReader cdata(_cycler);
|
||||
return (cdata->_vertices != (GeomVertexArrayData *)NULL);
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.is_indexed();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_first_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the first vertex number referenced by the
|
||||
// primitive. This is particularly important in the
|
||||
// case of a nonindexed primitive, in which case
|
||||
// get_first_vertex() and get_num_vertices() completely
|
||||
// define the extent of the vertex range.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_first_vertex() const {
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.get_first_vertex();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -123,12 +138,32 @@ is_indexed() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_num_vertices() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_vertices == (GeomVertexArrayData *)NULL) {
|
||||
return cdata->_num_vertices;
|
||||
} else {
|
||||
return cdata->_vertices->get_num_rows();
|
||||
}
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.get_num_vertices();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the ith vertex index in the table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_vertex(int i) const {
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.get_vertex(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_num_primitives
|
||||
// Access: Published
|
||||
// Description: Returns the number of individual primitives stored
|
||||
// within this object. All primitives are the same
|
||||
// type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_num_primitives() const {
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.get_num_primitives();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -179,14 +214,9 @@ get_primitive_num_faces(int n) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_min_vertex() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (!cdata->_got_minmax) {
|
||||
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
|
||||
((GeomPrimitive *)this)->recompute_minmax(cdataw);
|
||||
return cdataw->_min_vertex;
|
||||
}
|
||||
|
||||
return cdata->_min_vertex;
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
reader.check_minmax();
|
||||
return reader.get_min_vertex();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -197,13 +227,9 @@ get_min_vertex() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_max_vertex() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (!cdata->_got_minmax) {
|
||||
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
|
||||
((GeomPrimitive *)this)->recompute_minmax(cdataw);
|
||||
return cdataw->_max_vertex;
|
||||
}
|
||||
return cdata->_max_vertex;
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
reader.check_minmax();
|
||||
return reader.get_max_vertex();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -231,6 +257,24 @@ get_modified() const {
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::check_valid
|
||||
// Access: Published
|
||||
// Description: Verifies that the primitive only references vertices
|
||||
// that actually exist within the indicated
|
||||
// GeomVertexData. Returns true if the primitive
|
||||
// appears to be valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomPrimitive::
|
||||
check_valid(const GeomVertexData *vertex_data) const {
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
GeomPrimitivePipelineReader reader(this, pipeline_stage);
|
||||
reader.check_minmax();
|
||||
GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage);
|
||||
data_reader.check_array_readers();
|
||||
return reader.check_valid(&data_reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_vertices
|
||||
// Access: Public
|
||||
@@ -255,8 +299,8 @@ get_vertices() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitive::
|
||||
get_index_stride() const {
|
||||
nassertr(is_indexed(), 0);
|
||||
return get_vertices()->get_array_format()->get_stride();
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.get_index_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -302,14 +346,9 @@ get_ends() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomPrimitive::
|
||||
get_mins() const {
|
||||
nassertr(is_indexed(), NULL);
|
||||
CDReader cdata(_cycler);
|
||||
if (!cdata->_got_minmax) {
|
||||
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
|
||||
((GeomPrimitive *)this)->recompute_minmax(cdataw);
|
||||
return cdataw->_mins;
|
||||
}
|
||||
return cdata->_mins;
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
reader.check_minmax();
|
||||
return reader.get_mins();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -325,14 +364,9 @@ get_mins() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomPrimitive::
|
||||
get_maxs() const {
|
||||
nassertr(is_indexed(), NULL);
|
||||
CDReader cdata(_cycler);
|
||||
if (!cdata->_got_minmax) {
|
||||
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
|
||||
((GeomPrimitive *)this)->recompute_minmax(cdataw);
|
||||
return cdataw->_maxs;
|
||||
}
|
||||
return cdata->_maxs;
|
||||
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
reader.check_minmax();
|
||||
return reader.get_maxs();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -381,7 +415,7 @@ INLINE CPT(GeomVertexArrayFormat) GeomPrimitive::
|
||||
get_index_format() const {
|
||||
return GeomVertexArrayFormat::register_format
|
||||
(new GeomVertexArrayFormat(InternalName::get_index(), 1,
|
||||
get_index_type(), C_index));
|
||||
get_index_type(), C_index));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -435,6 +469,211 @@ CData(const GeomPrimitive::CData ©) :
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPrimitivePipelineReader::
|
||||
GeomPrimitivePipelineReader(const GeomPrimitivePipelineReader &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomPrimitivePipelineReader::
|
||||
operator = (const GeomPrimitivePipelineReader &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomPrimitive *GeomPrimitivePipelineReader::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_pipeline_stage
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitivePipelineReader::
|
||||
get_pipeline_stage() const {
|
||||
return _pipeline_stage;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::check_minmax
|
||||
// Access: Public
|
||||
// Description: Ensures that the primitive's minmax cache has been
|
||||
// computed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomPrimitivePipelineReader::
|
||||
check_minmax() const {
|
||||
if (!_cdata->_got_minmax) {
|
||||
((GeomPrimitive *)_object)->recompute_minmax((GeomPrimitive::CData *)_cdata);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_shade_model
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPrimitivePipelineReader::ShadeModel GeomPrimitivePipelineReader::
|
||||
get_shade_model() const {
|
||||
return _cdata->_shade_model;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_usage_hint
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPrimitivePipelineReader::UsageHint GeomPrimitivePipelineReader::
|
||||
get_usage_hint() const {
|
||||
return _cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_index_type
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPrimitivePipelineReader::NumericType GeomPrimitivePipelineReader::
|
||||
get_index_type() const {
|
||||
return _cdata->_index_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::is_indexed
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomPrimitivePipelineReader::
|
||||
is_indexed() const {
|
||||
return (_cdata->_vertices != (GeomVertexArrayData *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_num_vertices
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitivePipelineReader::
|
||||
get_num_vertices() const {
|
||||
if (_cdata->_vertices == (GeomVertexArrayData *)NULL) {
|
||||
return _cdata->_num_vertices;
|
||||
} else {
|
||||
return _vertices_reader->get_num_rows();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_min_vertex
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitivePipelineReader::
|
||||
get_min_vertex() const {
|
||||
nassertr(_cdata->_got_minmax, 0);
|
||||
return _cdata->_min_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_max_vertex
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitivePipelineReader::
|
||||
get_max_vertex() const {
|
||||
nassertr(_cdata->_got_minmax, 0);
|
||||
return _cdata->_max_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_data_size_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the number of bytes stored in the vertices
|
||||
// array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitivePipelineReader::
|
||||
get_data_size_bytes() const {
|
||||
return _vertices_reader->get_data_size_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_modified
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomPrimitivePipelineReader::
|
||||
get_modified() const {
|
||||
return _cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_index_stride
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomPrimitivePipelineReader::
|
||||
get_index_stride() const {
|
||||
nassertr(is_indexed(), 0);
|
||||
return _cdata->_vertices->get_array_format()->get_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_data
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar GeomPrimitivePipelineReader::
|
||||
get_data() const {
|
||||
return _vertices_reader->get_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_ends
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_int GeomPrimitivePipelineReader::
|
||||
get_ends() const {
|
||||
return _cdata->_ends;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_mins
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomPrimitivePipelineReader::
|
||||
get_mins() const {
|
||||
nassertr(is_indexed(), NULL);
|
||||
nassertr(_cdata->_got_minmax, NULL);
|
||||
return _cdata->_mins;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_maxs
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomPrimitivePipelineReader::
|
||||
get_maxs() const {
|
||||
nassertr(is_indexed(), NULL);
|
||||
nassertr(_cdata->_got_minmax, NULL);
|
||||
return _cdata->_maxs;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const GeomPrimitive &obj) {
|
||||
obj.output(out);
|
||||
|
||||
@@ -170,51 +170,6 @@ set_index_type(GeomPrimitive::NumericType index_type) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_first_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the first vertex number referenced by the
|
||||
// primitive. This is particularly important in the
|
||||
// case of a nonindexed primitive, in which case
|
||||
// get_first_vertex() and get_num_vertices() completely
|
||||
// define the extent of the vertex range.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitive::
|
||||
get_first_vertex() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (cdata->_vertices == (GeomVertexArrayData *)NULL) {
|
||||
return cdata->_first_vertex;
|
||||
} else if (cdata->_vertices->get_num_rows() == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
GeomVertexReader index(cdata->_vertices, 0);
|
||||
return index.get_data1i();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the ith vertex index in the table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitive::
|
||||
get_vertex(int i) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
if (cdata->_vertices != (GeomVertexArrayData *)NULL) {
|
||||
// The indexed case.
|
||||
nassertr(i >= 0 && i < (int)cdata->_vertices->get_num_rows(), -1);
|
||||
|
||||
GeomVertexReader index(cdata->_vertices, 0);
|
||||
index.set_row(i);
|
||||
return index.get_data1i();
|
||||
|
||||
} else {
|
||||
// The nonindexed case.
|
||||
return cdata->_first_vertex + i;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::add_vertex
|
||||
// Access: Published
|
||||
@@ -545,30 +500,6 @@ make_indexed() {
|
||||
do_make_indexed(cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_num_primitives
|
||||
// Access: Published
|
||||
// Description: Returns the number of individual primitives stored
|
||||
// within this object. All primitives are the same
|
||||
// type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitive::
|
||||
get_num_primitives() const {
|
||||
int num_vertices_per_primitive = get_num_vertices_per_primitive();
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
return cdata->_ends.size();
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
// uses the same number of vertices.
|
||||
return (get_num_vertices() / num_vertices_per_primitive);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_primitive_start
|
||||
// Access: Published
|
||||
@@ -833,20 +764,6 @@ get_num_bytes() const {
|
||||
return num_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::check_valid
|
||||
// Access: Published
|
||||
// Description: Verifies that the primitive only references vertices
|
||||
// that actually exist within the indicated
|
||||
// GeomVertexData. Returns true if the primitive
|
||||
// appears to be valid, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomPrimitive::
|
||||
check_valid(const GeomVertexData *vertex_data) const {
|
||||
return get_num_vertices() == 0 ||
|
||||
get_max_vertex() < vertex_data->get_num_rows();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::output
|
||||
// Access: Published, Virtual
|
||||
@@ -969,6 +886,8 @@ set_nonindexed_vertices(int first_vertex, int num_vertices) {
|
||||
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
cdata->_got_minmax = false;
|
||||
|
||||
// Force the minmax to be recomputed.
|
||||
recompute_minmax(cdata);
|
||||
}
|
||||
|
||||
@@ -1357,7 +1276,7 @@ append_unused_vertices(GeomVertexArrayData *, int) {
|
||||
// necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomPrimitive::
|
||||
recompute_minmax(CData *cdata) {
|
||||
recompute_minmax(GeomPrimitive::CData *cdata) {
|
||||
if (cdata->_vertices == (GeomVertexArrayData *)NULL) {
|
||||
// In the nonindexed case, we don't need to do much (the
|
||||
// minmax is trivial).
|
||||
@@ -1563,3 +1482,118 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
_modified = Geom::get_next_modified();
|
||||
_got_minmax = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomPrimitivePipelineReader::
|
||||
GeomPrimitivePipelineReader(const GeomPrimitive *object,
|
||||
int pipeline_stage) :
|
||||
_object(object),
|
||||
_pipeline_stage(pipeline_stage),
|
||||
_cdata(object->_cycler.read_stage(pipeline_stage)),
|
||||
_vertices_reader(NULL)
|
||||
{
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
if (_cdata->_vertices != (GeomVertexArrayData *)NULL) {
|
||||
_vertices_reader =
|
||||
new GeomVertexArrayDataPipelineReader(_cdata->_vertices, _pipeline_stage);
|
||||
nassertv(_vertices_reader->get_object() == _cdata->_vertices);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomPrimitivePipelineReader::
|
||||
~GeomPrimitivePipelineReader() {
|
||||
if (_vertices_reader != (GeomVertexArrayDataPipelineReader *)NULL) {
|
||||
nassertv(_vertices_reader->get_object() == _cdata->_vertices);
|
||||
delete _vertices_reader;
|
||||
_vertices_reader = NULL;
|
||||
}
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
|
||||
_object = NULL;
|
||||
_cdata = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_first_vertex
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitivePipelineReader::
|
||||
get_first_vertex() const {
|
||||
if (_cdata->_vertices == (GeomVertexArrayData *)NULL) {
|
||||
return _cdata->_first_vertex;
|
||||
} else if (_vertices_reader->get_num_rows() == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
GeomVertexReader index(_cdata->_vertices, 0);
|
||||
return index.get_data1i();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_vertex
|
||||
// Access: Public
|
||||
// Description: Returns the ith vertex index in the table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitivePipelineReader::
|
||||
get_vertex(int i) const {
|
||||
if (_cdata->_vertices != (GeomVertexArrayData *)NULL) {
|
||||
// The indexed case.
|
||||
nassertr(i >= 0 && i < _vertices_reader->get_num_rows(), -1);
|
||||
|
||||
GeomVertexReader index(_cdata->_vertices, 0);
|
||||
index.set_row(i);
|
||||
return index.get_data1i();
|
||||
|
||||
} else {
|
||||
// The nonindexed case.
|
||||
return _cdata->_first_vertex + i;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_num_primitives
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int GeomPrimitivePipelineReader::
|
||||
get_num_primitives() const {
|
||||
int num_vertices_per_primitive = _object->get_num_vertices_per_primitive();
|
||||
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
return _cdata->_ends.size();
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
// uses the same number of vertices.
|
||||
return (get_num_vertices() / num_vertices_per_primitive);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::check_valid
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomPrimitivePipelineReader::
|
||||
check_valid(const GeomVertexDataPipelineReader *data_reader) const {
|
||||
return get_num_vertices() == 0 ||
|
||||
get_max_vertex() < data_reader->get_num_rows();
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "pandabase.h"
|
||||
#include "geomEnums.h"
|
||||
#include "geomVertexArrayData.h"
|
||||
#include "geomVertexData.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "luse.h"
|
||||
#include "updateSeq.h"
|
||||
@@ -31,14 +32,16 @@
|
||||
#include "cycleData.h"
|
||||
#include "cycleDataReader.h"
|
||||
#include "cycleDataWriter.h"
|
||||
#include "cycleDataStageReader.h"
|
||||
#include "cycleDataStageWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "deletedChain.h"
|
||||
|
||||
class GeomVertexData;
|
||||
class PreparedGraphicsObjects;
|
||||
class IndexBufferContext;
|
||||
class GraphicsStateGuardianBase;
|
||||
class FactoryParams;
|
||||
class GeomPrimitivePipelineReader;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomPrimitive
|
||||
@@ -95,9 +98,9 @@ PUBLISHED:
|
||||
|
||||
INLINE bool is_composite() const;
|
||||
INLINE bool is_indexed() const;
|
||||
int get_first_vertex() const;
|
||||
INLINE int get_first_vertex() const;
|
||||
INLINE int get_num_vertices() const;
|
||||
int get_vertex(int i) const;
|
||||
INLINE int get_vertex(int i) const;
|
||||
void add_vertex(int vertex);
|
||||
INLINE void add_vertices(int v1, int v2);
|
||||
INLINE void add_vertices(int v1, int v2, int v3);
|
||||
@@ -111,7 +114,7 @@ PUBLISHED:
|
||||
void pack_vertices(GeomVertexData *dest, const GeomVertexData *source);
|
||||
void make_indexed();
|
||||
|
||||
int get_num_primitives() const;
|
||||
INLINE int get_num_primitives() const;
|
||||
int get_primitive_start(int n) const;
|
||||
int get_primitive_end(int n) const;
|
||||
int get_primitive_num_vertices(int n) const;
|
||||
@@ -132,7 +135,7 @@ PUBLISHED:
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
bool check_valid(const GeomVertexData *vertex_data) const;
|
||||
INLINE bool check_valid(const GeomVertexData *vertex_data) const;
|
||||
|
||||
virtual void output(ostream &out) const;
|
||||
virtual void write(ostream &out, int indent_level) const;
|
||||
@@ -183,7 +186,8 @@ private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const=0;
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomPrimitivePipelineReader *reader) const=0;
|
||||
|
||||
void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
||||
bool &found_any,
|
||||
@@ -218,6 +222,7 @@ private:
|
||||
INLINE CData();
|
||||
INLINE CData(const CData ©);
|
||||
ALLOC_DELETED_CHAIN(CData);
|
||||
|
||||
virtual CycleData *make_copy() const;
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
@@ -225,7 +230,7 @@ private:
|
||||
virtual TypeHandle get_parent_type() const {
|
||||
return GeomPrimitive::get_class_type();
|
||||
}
|
||||
|
||||
|
||||
ShadeModel _shade_model;
|
||||
int _first_vertex;
|
||||
int _num_vertices;
|
||||
@@ -236,16 +241,21 @@ private:
|
||||
PT(GeomVertexArrayData) _mins;
|
||||
PT(GeomVertexArrayData) _maxs;
|
||||
UpdateSeq _modified;
|
||||
|
||||
|
||||
bool _got_minmax;
|
||||
unsigned int _min_vertex;
|
||||
unsigned int _max_vertex;
|
||||
|
||||
friend class GeomPrimitive;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
typedef CycleDataStageReader<CData> CDStageReader;
|
||||
typedef CycleDataStageWriter<CData> CDStageWriter;
|
||||
|
||||
private:
|
||||
static PStatCollector _decompose_pcollector;
|
||||
static PStatCollector _rotate_pcollector;
|
||||
|
||||
@@ -276,6 +286,54 @@ private:
|
||||
|
||||
friend class Geom;
|
||||
friend class PreparedGraphicsObjects;
|
||||
friend class GeomPrimitivePipelineReader;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomPrimitivePipelineReader
|
||||
// Description : Encapsulates the data from a GeomPrimitive,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomPrimitivePipelineReader : public GeomEnums {
|
||||
public:
|
||||
GeomPrimitivePipelineReader(const GeomPrimitive *object, int pipeline_stage);
|
||||
private:
|
||||
INLINE GeomPrimitivePipelineReader(const GeomPrimitivePipelineReader ©);
|
||||
INLINE void operator = (const GeomPrimitivePipelineReader ©);
|
||||
|
||||
public:
|
||||
~GeomPrimitivePipelineReader();
|
||||
ALLOC_DELETED_CHAIN(GeomPrimitivePipelineReader);
|
||||
|
||||
INLINE const GeomPrimitive *get_object() const;
|
||||
INLINE int get_pipeline_stage() const;
|
||||
|
||||
INLINE void check_minmax() const;
|
||||
|
||||
INLINE ShadeModel get_shade_model() const;
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE NumericType get_index_type() const;
|
||||
INLINE bool is_indexed() const;
|
||||
int get_first_vertex() const;
|
||||
INLINE int get_num_vertices() const;
|
||||
int get_vertex(int i) const;
|
||||
int get_num_primitives() const;
|
||||
INLINE int get_min_vertex() const;
|
||||
INLINE int get_max_vertex() const;
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
|
||||
INLINE int get_index_stride() const;
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
INLINE CPTA_int get_ends() const;
|
||||
INLINE const GeomVertexArrayData *get_mins() const;
|
||||
INLINE const GeomVertexArrayData *get_maxs() const;
|
||||
|
||||
private:
|
||||
const GeomPrimitive *_object;
|
||||
int _pipeline_stage;
|
||||
const GeomPrimitive::CData *_cdata;
|
||||
GeomVertexArrayDataPipelineReader *_vertices_reader;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const GeomPrimitive &obj);
|
||||
|
||||
@@ -105,8 +105,8 @@ get_num_vertices_per_primitive() const {
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomTriangles::
|
||||
draw(GraphicsStateGuardianBase *gsg) const {
|
||||
gsg->draw_triangles(this);
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
|
||||
gsg->draw_triangles(reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -39,7 +39,8 @@ public:
|
||||
virtual int get_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomPrimitivePipelineReader *reader) const;
|
||||
|
||||
protected:
|
||||
virtual CPT(GeomVertexArrayData) rotate_impl() const;
|
||||
|
||||
@@ -105,8 +105,8 @@ get_geom_rendering() const {
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomTrifans::
|
||||
draw(GraphicsStateGuardianBase *gsg) const {
|
||||
gsg->draw_trifans(this);
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
|
||||
gsg->draw_trifans(reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -38,7 +38,8 @@ public:
|
||||
virtual int get_geom_rendering() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomPrimitivePipelineReader *reader) const;
|
||||
|
||||
protected:
|
||||
virtual CPT(GeomPrimitive) decompose_impl() const;
|
||||
|
||||
@@ -120,8 +120,8 @@ get_num_unused_vertices_per_primitive() const {
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomTristrips::
|
||||
draw(GraphicsStateGuardianBase *gsg) const {
|
||||
gsg->draw_tristrips(this);
|
||||
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
|
||||
gsg->draw_tristrips(reader);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -39,7 +39,8 @@ public:
|
||||
virtual int get_num_unused_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg,
|
||||
const GeomPrimitivePipelineReader *reader) const;
|
||||
|
||||
protected:
|
||||
virtual CPT(GeomPrimitive) decompose_impl() const;
|
||||
|
||||
@@ -62,7 +62,35 @@ has_column(const InternalName *name) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexArrayData::
|
||||
get_num_rows() const {
|
||||
return get_data_size_bytes() / _array_format->get_stride();
|
||||
GeomVertexArrayDataPipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.get_num_rows();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::set_num_rows
|
||||
// Access: Published
|
||||
// Description: Sets the length of the array to n rows.
|
||||
// Normally, you would not call this directly, since all
|
||||
// of the arrays in a particular GeomVertexData must
|
||||
// have the same number of rows; instead, call
|
||||
// GeomVertexData::set_num_rows().
|
||||
//
|
||||
// The return value is true if the number of rows
|
||||
// was changed, false if the object already contained n
|
||||
// rows (or if there was some error).
|
||||
//
|
||||
// The new vertex data is initialized to 0, including
|
||||
// the "color" column (but see
|
||||
// GeomVertexData::set_num_rows()).
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexArrayData::
|
||||
set_num_rows(int n) {
|
||||
GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
|
||||
return writer.set_num_rows(n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -113,6 +141,39 @@ get_data() const {
|
||||
return cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::modify_data
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the actual vertex
|
||||
// array, so that application code may directly
|
||||
// manipulate it. Use with caution.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_uchar GeomVertexArrayData::
|
||||
modify_data() {
|
||||
GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
|
||||
return writer.modify_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::set_data
|
||||
// Access: Published
|
||||
// Description: Replaces the vertex data array with a completely new
|
||||
// array.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayData::
|
||||
set_data(CPTA_uchar array) {
|
||||
GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
|
||||
writer.set_data(array);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::CData::Constructor
|
||||
// Access: Public
|
||||
@@ -137,6 +198,222 @@ CData(const GeomVertexArrayData::CData ©) :
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineBase::
|
||||
GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object,
|
||||
int pipeline_stage,
|
||||
GeomVertexArrayData::CData *cdata) :
|
||||
_object(object),
|
||||
_pipeline_stage(pipeline_stage),
|
||||
_cdata(cdata)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_pipeline_stage
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexArrayDataPipelineBase::
|
||||
get_pipeline_stage() const {
|
||||
return _pipeline_stage;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_array_format
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayFormat *GeomVertexArrayDataPipelineBase::
|
||||
get_array_format() const {
|
||||
return _object->_array_format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_usage_hint
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineBase::UsageHint GeomVertexArrayDataPipelineBase::
|
||||
get_usage_hint() const {
|
||||
return _cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_data
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar GeomVertexArrayDataPipelineBase::
|
||||
get_data() const {
|
||||
return _cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_num_rows
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexArrayDataPipelineBase::
|
||||
get_num_rows() const {
|
||||
return get_data_size_bytes() / _object->_array_format->get_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_data_size_bytes
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexArrayDataPipelineBase::
|
||||
get_data_size_bytes() const {
|
||||
return _cdata->_data.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_modified
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomVertexArrayDataPipelineBase::
|
||||
get_modified() const {
|
||||
return _cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineReader::
|
||||
GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object,
|
||||
int pipeline_stage) :
|
||||
GeomVertexArrayDataPipelineBase((GeomVertexArrayData *)object,
|
||||
pipeline_stage,
|
||||
(GeomVertexArrayData::CData *)object->_cycler.read_stage(pipeline_stage))
|
||||
{
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineReader::
|
||||
GeomVertexArrayDataPipelineReader(const GeomVertexArrayDataPipelineReader ©) :
|
||||
GeomVertexArrayDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayDataPipelineReader::
|
||||
operator = (const GeomVertexArrayDataPipelineReader &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineReader::
|
||||
~GeomVertexArrayDataPipelineReader() {
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
|
||||
_object = NULL;
|
||||
_cdata = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomVertexArrayDataPipelineReader::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter::
|
||||
GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object,
|
||||
int pipeline_stage, bool force_to_0) :
|
||||
GeomVertexArrayDataPipelineBase(object, pipeline_stage,
|
||||
object->_cycler.write_stage_upstream(pipeline_stage, force_to_0))
|
||||
{
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter::
|
||||
GeomVertexArrayDataPipelineWriter(const GeomVertexArrayDataPipelineWriter ©) :
|
||||
GeomVertexArrayDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayDataPipelineWriter::
|
||||
operator = (const GeomVertexArrayDataPipelineWriter &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter::
|
||||
~GeomVertexArrayDataPipelineWriter() {
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
_object->_cycler.release_write_stage(_pipeline_stage, _cdata);
|
||||
_object = NULL;
|
||||
_cdata = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayData *GeomVertexArrayDataPipelineWriter::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const GeomVertexArrayData &obj) {
|
||||
obj.output(out);
|
||||
|
||||
@@ -105,66 +105,6 @@ GeomVertexArrayData::
|
||||
release_all();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::set_num_rows
|
||||
// Access: Published
|
||||
// Description: Sets the length of the array to n rows.
|
||||
// Normally, you would not call this directly, since all
|
||||
// of the arrays in a particular GeomVertexData must
|
||||
// have the same number of rows; instead, call
|
||||
// GeomVertexData::set_num_rows().
|
||||
//
|
||||
// The return value is true if the number of rows
|
||||
// was changed, false if the object already contained n
|
||||
// rows (or if there was some error).
|
||||
//
|
||||
// The new vertex data is initialized to 0, including
|
||||
// the "color" column (but see
|
||||
// GeomVertexData::set_num_rows()).
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexArrayData::
|
||||
set_num_rows(int n) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
|
||||
int stride = _array_format->get_stride();
|
||||
int delta = n - (cdata->_data.size() / stride);
|
||||
|
||||
if (delta != 0) {
|
||||
if (cdata->_data.get_ref_count() > 1) {
|
||||
// Copy-on-write: the data is already reffed somewhere else,
|
||||
// so we're just going to make a copy.
|
||||
PTA_uchar new_data;
|
||||
new_data.reserve(n * stride);
|
||||
new_data.insert(new_data.end(), n * stride, 0);
|
||||
memcpy(new_data, cdata->_data,
|
||||
min((size_t)(n * stride), cdata->_data.size()));
|
||||
cdata->_data = new_data;
|
||||
|
||||
} else {
|
||||
// We've got the only reference to the data, so we can change
|
||||
// it directly.
|
||||
if (delta > 0) {
|
||||
cdata->_data.insert(cdata->_data.end(), delta * stride, 0);
|
||||
|
||||
} else {
|
||||
cdata->_data.erase(cdata->_data.begin() + n * stride,
|
||||
cdata->_data.end());
|
||||
}
|
||||
}
|
||||
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::set_usage_hint
|
||||
// Access: Published
|
||||
@@ -202,51 +142,6 @@ write(ostream &out, int indent_level) const {
|
||||
_array_format->write_with_data(out, indent_level, this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::modify_data
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the actual vertex
|
||||
// array, so that application code may directly
|
||||
// manipulate it. Use with caution.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar GeomVertexArrayData::
|
||||
modify_data() {
|
||||
// Perform copy-on-write: if the reference count on the vertex data
|
||||
// is greater than 1, assume some other GeomVertexData has the same
|
||||
// pointer, so make a copy of it first.
|
||||
CDWriter cdata(_cycler, true);
|
||||
|
||||
if (cdata->_data.get_ref_count() > 1) {
|
||||
PTA_uchar orig_data = cdata->_data;
|
||||
cdata->_data = PTA_uchar();
|
||||
cdata->_data.v() = orig_data.v();
|
||||
}
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
|
||||
return cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::set_data
|
||||
// Access: Published
|
||||
// Description: Replaces the vertex data array with a completely new
|
||||
// array.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayData::
|
||||
set_data(CPTA_uchar array) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
cdata->_data = (PTA_uchar &)array;
|
||||
cdata->_modified = Geom::get_next_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::prepare
|
||||
// Access: Public
|
||||
@@ -613,3 +508,75 @@ fillin(DatagramIterator &scan, BamReader *manager, void *extra_data) {
|
||||
|
||||
_modified = Geom::get_next_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::set_num_rows
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexArrayDataPipelineWriter::
|
||||
set_num_rows(int n) {
|
||||
int stride = _object->_array_format->get_stride();
|
||||
int delta = n - (_cdata->_data.size() / stride);
|
||||
|
||||
if (delta != 0) {
|
||||
if (_cdata->_data.get_ref_count() > 1) {
|
||||
// Copy-on-write: the data is already reffed somewhere else,
|
||||
// so we're just going to make a copy.
|
||||
PTA_uchar new_data;
|
||||
new_data.reserve(n * stride);
|
||||
new_data.insert(new_data.end(), n * stride, 0);
|
||||
memcpy(new_data, _cdata->_data,
|
||||
min((size_t)(n * stride), _cdata->_data.size()));
|
||||
_cdata->_data = new_data;
|
||||
|
||||
} else {
|
||||
// We've got the only reference to the data, so we can change
|
||||
// it directly.
|
||||
if (delta > 0) {
|
||||
_cdata->_data.insert(_cdata->_data.end(), delta * stride, 0);
|
||||
|
||||
} else {
|
||||
_cdata->_data.erase(_cdata->_data.begin() + n * stride,
|
||||
_cdata->_data.end());
|
||||
}
|
||||
}
|
||||
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::modify_data
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar GeomVertexArrayDataPipelineWriter::
|
||||
modify_data() {
|
||||
// Perform copy-on-write: if the reference count on the vertex data
|
||||
// is greater than 1, assume some other GeomVertexData has the same
|
||||
// pointer, so make a copy of it first.
|
||||
if (_cdata->_data.get_ref_count() > 1) {
|
||||
PTA_uchar orig_data = _cdata->_data;
|
||||
_cdata->_data = PTA_uchar();
|
||||
_cdata->_data.v() = orig_data.v();
|
||||
}
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
|
||||
return _cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::set_data
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayDataPipelineWriter::
|
||||
set_data(CPTA_uchar array) {
|
||||
_cdata->_data = (PTA_uchar &)array;
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ PUBLISHED:
|
||||
INLINE bool has_column(const InternalName *name) const;
|
||||
|
||||
INLINE int get_num_rows() const;
|
||||
bool set_num_rows(int n);
|
||||
INLINE bool set_num_rows(int n);
|
||||
INLINE void clear_rows();
|
||||
|
||||
INLINE int get_data_size_bytes() const;
|
||||
@@ -86,8 +86,8 @@ PUBLISHED:
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
PTA_uchar modify_data();
|
||||
void set_data(CPTA_uchar data);
|
||||
INLINE PTA_uchar modify_data();
|
||||
INLINE void set_data(CPTA_uchar data);
|
||||
|
||||
public:
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
@@ -133,6 +133,8 @@ private:
|
||||
UsageHint _usage_hint;
|
||||
PTA_uchar _data;
|
||||
UpdateSeq _modified;
|
||||
|
||||
friend class GeomVertexArrayData;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
@@ -174,6 +176,80 @@ private:
|
||||
friend class GeomCacheManager;
|
||||
friend class GeomVertexData;
|
||||
friend class PreparedGraphicsObjects;
|
||||
friend class GeomVertexArrayDataPipelineBase;
|
||||
friend class GeomVertexArrayDataPipelineReader;
|
||||
friend class GeomVertexArrayDataPipelineWriter;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexArrayDataPipelineBase
|
||||
// Description : The common code from
|
||||
// GeomVertexArrayDataPipelineReader and
|
||||
// GeomVertexArrayDataPipelineWriter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexArrayDataPipelineBase : public GeomEnums {
|
||||
protected:
|
||||
INLINE GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object,
|
||||
int pipeline_stage,
|
||||
GeomVertexArrayData::CData *cdata);
|
||||
|
||||
public:
|
||||
INLINE int get_pipeline_stage() const;
|
||||
|
||||
INLINE const GeomVertexArrayFormat *get_array_format() const;
|
||||
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
INLINE int get_num_rows() const;
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
protected:
|
||||
GeomVertexArrayData *_object;
|
||||
int _pipeline_stage;
|
||||
GeomVertexArrayData::CData *_cdata;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexArrayDataPipelineReader
|
||||
// Description : Encapsulates the data from a GeomVertexArrayData,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexArrayDataPipelineReader : public GeomVertexArrayDataPipelineBase {
|
||||
public:
|
||||
INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object, int pipeline_stage);
|
||||
private:
|
||||
INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayDataPipelineReader ©);
|
||||
INLINE void operator = (const GeomVertexArrayDataPipelineReader ©);
|
||||
|
||||
public:
|
||||
INLINE ~GeomVertexArrayDataPipelineReader();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexArrayDataPipelineReader);
|
||||
|
||||
INLINE const GeomVertexArrayData *get_object() const;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexArrayDataPipelineWriter
|
||||
// Description : Encapsulates the data from a GeomVertexArrayData,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexArrayDataPipelineWriter : public GeomVertexArrayDataPipelineBase {
|
||||
public:
|
||||
INLINE GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, int pipeline_stage, bool force_to_0);
|
||||
private:
|
||||
INLINE GeomVertexArrayDataPipelineWriter(const GeomVertexArrayDataPipelineWriter ©);
|
||||
INLINE void operator = (const GeomVertexArrayDataPipelineWriter ©);
|
||||
|
||||
public:
|
||||
INLINE ~GeomVertexArrayDataPipelineWriter();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexArrayDataPipelineWriter);
|
||||
|
||||
bool set_num_rows(int n);
|
||||
|
||||
INLINE GeomVertexArrayData *get_object() const;
|
||||
PTA_uchar modify_data();
|
||||
void set_data(CPTA_uchar data);
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const GeomVertexArrayData &obj);
|
||||
|
||||
+412
-65
@@ -29,17 +29,6 @@ get_name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::get_format
|
||||
// Access: Published
|
||||
// Description: Returns a pointer to the GeomVertexFormat structure
|
||||
// that defines this data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexFormat *GeomVertexData::
|
||||
get_format() const {
|
||||
return _format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::get_usage_hint
|
||||
// Access: Published
|
||||
@@ -60,6 +49,18 @@ get_usage_hint() const {
|
||||
return cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::get_format
|
||||
// Access: Published
|
||||
// Description: Returns a pointer to the GeomVertexFormat structure
|
||||
// that defines this data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexFormat *GeomVertexData::
|
||||
get_format() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::has_column
|
||||
// Access: Published
|
||||
@@ -69,7 +70,22 @@ get_usage_hint() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexData::
|
||||
has_column(const InternalName *name) const {
|
||||
return _format->has_column(name);
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_format->has_column(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::get_num_rows
|
||||
// Access: Published
|
||||
// Description: Returns the number of rows stored within all the
|
||||
// arrays. All arrays store data for the same n
|
||||
// rows.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexData::
|
||||
get_num_rows() const {
|
||||
GeomVertexDataPipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
reader.check_array_readers();
|
||||
return reader.get_num_rows();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -99,8 +115,9 @@ has_column(const InternalName *name) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexData::
|
||||
set_num_rows(int n) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
return do_set_num_rows(n, cdata);
|
||||
GeomVertexDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
|
||||
writer.check_array_writers();
|
||||
return writer.set_num_rows(n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -130,6 +147,26 @@ get_array(int i) const {
|
||||
return cdata->_arrays[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::modify_array
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the indicated vertex
|
||||
// array, so that application code may directly
|
||||
// manipulate the data. You should avoid changing
|
||||
// the length of this array, since all of the arrays
|
||||
// should be kept in sync--use set_num_rows()
|
||||
// instead.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayData *GeomVertexData::
|
||||
modify_array(int i) {
|
||||
GeomVertexDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
|
||||
return writer.modify_array(i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::get_transform_table
|
||||
// Access: Published
|
||||
@@ -225,6 +262,18 @@ clear_slider_table() {
|
||||
set_slider_table(NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::get_num_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the total number of bytes consumed by the
|
||||
// different arrays of the vertex data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexData::
|
||||
get_num_bytes() const {
|
||||
GeomVertexDataPipelineReader reader(this, Thread::get_current_pipeline_stage());
|
||||
return reader.get_num_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::get_modified
|
||||
// Access: Published
|
||||
@@ -238,57 +287,6 @@ get_modified() const {
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::has_vertex
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has a "vertex" column, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexData::
|
||||
has_vertex() const {
|
||||
return (_format->get_vertex_column() != (GeomVertexColumn *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::is_vertex_transformed
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has a "vertex" column and it
|
||||
// is indicated as having been transformed into clip
|
||||
// coordinates, false if there is no vertex column or if
|
||||
// it contains ordinary 3-d pre-transformation points.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexData::
|
||||
is_vertex_transformed() const {
|
||||
const GeomVertexColumn *column = _format->get_vertex_column();
|
||||
if (column != (GeomVertexColumn *)NULL) {
|
||||
return column->get_contents() == C_clip_point;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::has_normal
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has a "normal" column, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexData::
|
||||
has_normal() const {
|
||||
return (_format->get_normal_column() != (GeomVertexColumn *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::has_color
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has a "color" column, false
|
||||
// otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexData::
|
||||
has_color() const {
|
||||
return (_format->get_color_column() != (GeomVertexColumn *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexData::pack_abcd
|
||||
// Access: Public, Static
|
||||
@@ -448,6 +446,7 @@ CData() :
|
||||
INLINE GeomVertexData::CData::
|
||||
CData(const GeomVertexData::CData ©) :
|
||||
_usage_hint(copy._usage_hint),
|
||||
_format(copy._format),
|
||||
_arrays(copy._arrays),
|
||||
_transform_table(copy._transform_table),
|
||||
_transform_blend_table(copy._transform_blend_table),
|
||||
@@ -458,6 +457,354 @@ CData(const GeomVertexData::CData ©) :
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineBase::
|
||||
GeomVertexDataPipelineBase(GeomVertexData *object,
|
||||
int pipeline_stage,
|
||||
GeomVertexData::CData *cdata) :
|
||||
_object(object),
|
||||
_pipeline_stage(pipeline_stage),
|
||||
_cdata(cdata)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_pipeline_stage
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexDataPipelineBase::
|
||||
get_pipeline_stage() const {
|
||||
return _pipeline_stage;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_usage_hint
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineBase::UsageHint GeomVertexDataPipelineBase::
|
||||
get_usage_hint() const {
|
||||
return _cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_format
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexFormat *GeomVertexDataPipelineBase::
|
||||
get_format() const {
|
||||
return _cdata->_format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::has_column
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineBase::
|
||||
has_column(const InternalName *name) const {
|
||||
return _cdata->_format->has_column(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_num_arrays
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexDataPipelineBase::
|
||||
get_num_arrays() const {
|
||||
return _cdata->_arrays.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_array
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomVertexDataPipelineBase::
|
||||
get_array(int i) const {
|
||||
nassertr(i >= 0 && i < (int)_cdata->_arrays.size(), NULL);
|
||||
return _cdata->_arrays[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_transform_table
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformTable *GeomVertexDataPipelineBase::
|
||||
get_transform_table() const {
|
||||
return _cdata->_transform_table;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_transform_blend_table
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TransformBlendTable *GeomVertexDataPipelineBase::
|
||||
get_transform_blend_table() const {
|
||||
return _cdata->_transform_blend_table;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_slider_table
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const SliderTable *GeomVertexDataPipelineBase::
|
||||
get_slider_table() const {
|
||||
return _cdata->_slider_table;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineBase::get_modified
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomVertexDataPipelineBase::
|
||||
get_modified() const {
|
||||
return _cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineReader::
|
||||
GeomVertexDataPipelineReader(const GeomVertexData *object,
|
||||
int pipeline_stage) :
|
||||
GeomVertexDataPipelineBase((GeomVertexData *)object, pipeline_stage,
|
||||
(GeomVertexData::CData *)object->_cycler.read_stage(pipeline_stage)),
|
||||
_got_array_readers(false)
|
||||
{
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineReader::
|
||||
GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader ©) :
|
||||
GeomVertexDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexDataPipelineReader::
|
||||
operator = (const GeomVertexDataPipelineReader &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineReader::
|
||||
~GeomVertexDataPipelineReader() {
|
||||
if (_got_array_readers) {
|
||||
delete_array_readers();
|
||||
}
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
|
||||
_object = NULL;
|
||||
_cdata = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexData *GeomVertexDataPipelineReader::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::check_array_readers
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexDataPipelineReader::
|
||||
check_array_readers() const {
|
||||
if (!_got_array_readers) {
|
||||
((GeomVertexDataPipelineReader *)this)->make_array_readers();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::get_array_reader
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayDataPipelineReader *GeomVertexDataPipelineReader::
|
||||
get_array_reader(int i) const {
|
||||
nassertr(_got_array_readers, NULL);
|
||||
nassertr(i >= 0 && i < (int)_array_readers.size(), NULL);
|
||||
return _array_readers[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::has_vertex
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
has_vertex() const {
|
||||
return (_cdata->_format->get_vertex_column() != (GeomVertexColumn *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::is_vertex_transformed
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
is_vertex_transformed() const {
|
||||
const GeomVertexColumn *column = _cdata->_format->get_vertex_column();
|
||||
if (column != (GeomVertexColumn *)NULL) {
|
||||
return column->get_contents() == C_clip_point;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::has_normal
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
has_normal() const {
|
||||
return (_cdata->_format->get_normal_column() != (GeomVertexColumn *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineReader::has_color
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexDataPipelineReader::
|
||||
has_color() const {
|
||||
return (_cdata->_format->get_color_column() != (GeomVertexColumn *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineWriter::
|
||||
GeomVertexDataPipelineWriter(GeomVertexData *object,
|
||||
int pipeline_stage, bool force_to_0) :
|
||||
GeomVertexDataPipelineBase(object, pipeline_stage,
|
||||
object->_cycler.write_stage_upstream(pipeline_stage, force_to_0)),
|
||||
_force_to_0(force_to_0),
|
||||
_got_array_writers(false)
|
||||
{
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineWriter::
|
||||
GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter ©) :
|
||||
GeomVertexDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexDataPipelineWriter::
|
||||
operator = (const GeomVertexDataPipelineWriter &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexDataPipelineWriter::
|
||||
~GeomVertexDataPipelineWriter() {
|
||||
if (_got_array_writers) {
|
||||
delete_array_writers();
|
||||
}
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#ifdef DO_PIPELINING
|
||||
nassertv(_cdata->test_ref_count_nonzero());
|
||||
#endif // DO_PIPELINING
|
||||
_object->_cycler.release_write_stage(_pipeline_stage, _cdata);
|
||||
_object = NULL;
|
||||
_cdata = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData *GeomVertexDataPipelineWriter::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::check_array_writers
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexDataPipelineWriter::
|
||||
check_array_writers() const {
|
||||
if (!_got_array_writers) {
|
||||
((GeomVertexDataPipelineWriter *)this)->make_array_writers();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexDataPipelineWriter::get_array_writer
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter *GeomVertexDataPipelineWriter::
|
||||
get_array_writer(int i) const {
|
||||
nassertr(_got_array_writers, NULL);
|
||||
nassertr(i >= 0 && i < (int)_array_writers.size(), NULL);
|
||||
return _array_writers[i];
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const GeomVertexData &obj) {
|
||||
obj.output(out);
|
||||
|
||||
+437
-351
File diff suppressed because it is too large
Load Diff
+134
-30
@@ -91,22 +91,22 @@ PUBLISHED:
|
||||
INLINE const string &get_name() const;
|
||||
void set_name(const string &name);
|
||||
|
||||
INLINE const GeomVertexFormat *get_format() const;
|
||||
void set_format(const GeomVertexFormat *format);
|
||||
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
void set_usage_hint(UsageHint usage_hint);
|
||||
|
||||
INLINE const GeomVertexFormat *get_format() const;
|
||||
void set_format(const GeomVertexFormat *format);
|
||||
|
||||
INLINE bool has_column(const InternalName *name) const;
|
||||
|
||||
int get_num_rows() const;
|
||||
INLINE int get_num_rows() const;
|
||||
INLINE bool set_num_rows(int n);
|
||||
void clear_rows();
|
||||
|
||||
INLINE int get_num_arrays() const;
|
||||
INLINE const GeomVertexArrayData *get_array(int i) const;
|
||||
GeomVertexArrayData *modify_array(int i);
|
||||
void set_array(int i, const GeomVertexArrayData *array);
|
||||
INLINE GeomVertexArrayData *modify_array(int i);
|
||||
INLINE void set_array(int i, const GeomVertexArrayData *array);
|
||||
|
||||
INLINE const TransformTable *get_transform_table() const;
|
||||
void set_transform_table(const TransformTable *table);
|
||||
@@ -121,7 +121,7 @@ PUBLISHED:
|
||||
void set_slider_table(const SliderTable *table);
|
||||
INLINE void clear_slider_table();
|
||||
|
||||
int get_num_bytes() const;
|
||||
INLINE int get_num_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
void copy_from(const GeomVertexData *source, bool keep_data_objects);
|
||||
@@ -152,27 +152,6 @@ PUBLISHED:
|
||||
void clear_cache_stage();
|
||||
|
||||
public:
|
||||
bool get_array_info(const InternalName *name,
|
||||
const GeomVertexArrayData *&array_data,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_vertex() const;
|
||||
INLINE bool is_vertex_transformed() const;
|
||||
bool get_vertex_info(const GeomVertexArrayData *&array_data,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_normal() const;
|
||||
bool get_normal_info(const GeomVertexArrayData *&array_data,
|
||||
NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_color() const;
|
||||
bool get_color_info(const GeomVertexArrayData *&array_data,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
static INLINE PN_uint32 pack_abcd(unsigned int a, unsigned int b,
|
||||
unsigned int c, unsigned int d);
|
||||
static INLINE unsigned int unpack_abcd_a(PN_uint32 data);
|
||||
@@ -201,7 +180,6 @@ private:
|
||||
|
||||
private:
|
||||
string _name;
|
||||
CPT(GeomVertexFormat) _format;
|
||||
|
||||
typedef pvector< PT(GeomVertexArrayData) > Arrays;
|
||||
|
||||
@@ -256,6 +234,7 @@ private:
|
||||
}
|
||||
|
||||
UsageHint _usage_hint;
|
||||
CPT(GeomVertexFormat) _format;
|
||||
Arrays _arrays;
|
||||
CPT(TransformTable) _transform_table;
|
||||
PT(TransformBlendTable) _transform_blend_table;
|
||||
@@ -274,7 +253,6 @@ private:
|
||||
Cache _cache;
|
||||
|
||||
private:
|
||||
bool do_set_num_rows(int n, CData *cdata);
|
||||
void update_animated_vertices(CData *cdata);
|
||||
|
||||
static PStatCollector _convert_pcollector;
|
||||
@@ -315,6 +293,132 @@ private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class CacheEntry;
|
||||
friend class GeomVertexDataPipelineBase;
|
||||
friend class GeomVertexDataPipelineReader;
|
||||
friend class GeomVertexDataPipelineWriter;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexDataPipelineBase
|
||||
// Description : The common code from
|
||||
// GeomVertexDataPipelineReader and
|
||||
// GeomVertexDataPipelineWriter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexDataPipelineBase : public GeomEnums {
|
||||
protected:
|
||||
INLINE GeomVertexDataPipelineBase(GeomVertexData *object,
|
||||
int pipeline_stage,
|
||||
GeomVertexData::CData *cdata);
|
||||
|
||||
public:
|
||||
INLINE int get_pipeline_stage() const;
|
||||
|
||||
INLINE const GeomVertexFormat *get_format() const;
|
||||
INLINE bool has_column(const InternalName *name) const;
|
||||
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE int get_num_arrays() const;
|
||||
INLINE const GeomVertexArrayData *get_array(int i) const;
|
||||
INLINE const TransformTable *get_transform_table() const;
|
||||
INLINE const TransformBlendTable *get_transform_blend_table() const;
|
||||
INLINE const SliderTable *get_slider_table() const;
|
||||
int get_num_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
protected:
|
||||
GeomVertexData *_object;
|
||||
int _pipeline_stage;
|
||||
GeomVertexData::CData *_cdata;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexDataPipelineReader
|
||||
// Description : Encapsulates the data from a GeomVertexData,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexDataPipelineReader : public GeomVertexDataPipelineBase {
|
||||
public:
|
||||
INLINE GeomVertexDataPipelineReader(const GeomVertexData *object, int pipeline_stage);
|
||||
private:
|
||||
INLINE GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader ©);
|
||||
INLINE void operator = (const GeomVertexDataPipelineReader ©);
|
||||
|
||||
public:
|
||||
INLINE ~GeomVertexDataPipelineReader();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexDataPipelineReader);
|
||||
|
||||
INLINE const GeomVertexData *get_object() const;
|
||||
|
||||
INLINE void check_array_readers() const;
|
||||
INLINE const GeomVertexArrayDataPipelineReader *get_array_reader(int i) const;
|
||||
int get_num_rows() const;
|
||||
|
||||
bool get_array_info(const InternalName *name,
|
||||
const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_vertex() const;
|
||||
INLINE bool is_vertex_transformed() const;
|
||||
bool get_vertex_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_normal() const;
|
||||
bool get_normal_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_color() const;
|
||||
bool get_color_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
private:
|
||||
void make_array_readers();
|
||||
void delete_array_readers();
|
||||
|
||||
bool _got_array_readers;
|
||||
typedef pvector<GeomVertexArrayDataPipelineReader *> ArrayReaders;
|
||||
ArrayReaders _array_readers;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexDataPipelineWriter
|
||||
// Description : Encapsulates the data from a GeomVertexData,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexDataPipelineWriter : public GeomVertexDataPipelineBase {
|
||||
public:
|
||||
INLINE GeomVertexDataPipelineWriter(GeomVertexData *object, int pipeline_stage,
|
||||
bool force_to_0);
|
||||
private:
|
||||
INLINE GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter ©);
|
||||
INLINE void operator = (const GeomVertexDataPipelineWriter ©);
|
||||
|
||||
public:
|
||||
INLINE ~GeomVertexDataPipelineWriter();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexDataPipelineWriter);
|
||||
|
||||
INLINE GeomVertexData *get_object() const;
|
||||
|
||||
INLINE void check_array_writers() const;
|
||||
INLINE GeomVertexArrayDataPipelineWriter *get_array_writer(int i) const;
|
||||
|
||||
GeomVertexArrayData *modify_array(int i);
|
||||
void set_array(int i, const GeomVertexArrayData *array);
|
||||
|
||||
int get_num_rows() const;
|
||||
bool set_num_rows(int n);
|
||||
|
||||
private:
|
||||
void make_array_writers();
|
||||
void delete_array_writers();
|
||||
|
||||
bool _force_to_0;
|
||||
bool _got_array_writers;
|
||||
typedef pvector<GeomVertexArrayDataPipelineWriter *> ArrayWriters;
|
||||
ArrayWriters _array_writers;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const GeomVertexData &obj);
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader() :
|
||||
_vertex_data(NULL)
|
||||
_data_reader(NULL),
|
||||
_array_reader(NULL),
|
||||
_owns_reader(false)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
@@ -40,7 +42,9 @@ GeomVertexReader() :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader(const GeomVertexData *vertex_data) :
|
||||
_vertex_data(vertex_data)
|
||||
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())),
|
||||
_array_reader(NULL),
|
||||
_owns_reader(true)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
@@ -54,7 +58,9 @@ GeomVertexReader(const GeomVertexData *vertex_data) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
|
||||
_vertex_data(vertex_data)
|
||||
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())),
|
||||
_array_reader(NULL),
|
||||
_owns_reader(true)
|
||||
{
|
||||
initialize();
|
||||
set_column(name);
|
||||
@@ -69,8 +75,10 @@ GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader(const GeomVertexData *vertex_data,
|
||||
const InternalName *name) :
|
||||
_vertex_data(vertex_data)
|
||||
const InternalName *name) :
|
||||
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())),
|
||||
_array_reader(NULL),
|
||||
_owns_reader(true)
|
||||
{
|
||||
initialize();
|
||||
set_column(name);
|
||||
@@ -84,7 +92,9 @@ GeomVertexReader(const GeomVertexData *vertex_data,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader(const GeomVertexArrayData *array_data) :
|
||||
_array_data(array_data)
|
||||
_data_reader(NULL),
|
||||
_array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_pipeline_stage())),
|
||||
_owns_reader(true)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
@@ -97,22 +107,44 @@ GeomVertexReader(const GeomVertexArrayData *array_data) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader(const GeomVertexArrayData *array_data, int column) :
|
||||
_array_data(array_data)
|
||||
_data_reader(NULL),
|
||||
_array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_pipeline_stage())),
|
||||
_owns_reader(true)
|
||||
{
|
||||
initialize();
|
||||
set_column(column);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexReader::Constructor
|
||||
// Access: Public
|
||||
// Description: Constructs a new reader to process the vertices of
|
||||
// the indicated data object. This flavor creates the
|
||||
// reader specifically to process the named data type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name) :
|
||||
_data_reader(data_reader),
|
||||
_array_reader(NULL),
|
||||
_owns_reader(false)
|
||||
{
|
||||
initialize();
|
||||
set_column(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexReader::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description: The copy constructor steals ownership of the reader
|
||||
// pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
GeomVertexReader(const GeomVertexReader ©) :
|
||||
_vertex_data(copy._vertex_data),
|
||||
_data_reader(copy._data_reader),
|
||||
_array(copy._array),
|
||||
_array_data(copy._array_data),
|
||||
_array_reader(copy._array_reader),
|
||||
_owns_reader(copy._owns_reader),
|
||||
_packer(copy._packer),
|
||||
_stride(copy._stride),
|
||||
_pointer_begin(copy._pointer_begin),
|
||||
@@ -120,24 +152,33 @@ GeomVertexReader(const GeomVertexReader ©) :
|
||||
_pointer(copy._pointer),
|
||||
_start_row(copy._start_row)
|
||||
{
|
||||
((GeomVertexReader &)copy)._owns_reader = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexReader::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description: The copy constructor steals ownership of the reader
|
||||
// pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexReader::
|
||||
operator = (const GeomVertexReader ©) {
|
||||
_vertex_data = copy._vertex_data;
|
||||
if (_owns_reader) {
|
||||
clear_reader();
|
||||
}
|
||||
|
||||
_data_reader = copy._data_reader;
|
||||
_array = copy._array;
|
||||
_array_data = copy._array_data;
|
||||
_array_reader = copy._array_reader;
|
||||
_owns_reader = copy._owns_reader;
|
||||
_packer = copy._packer;
|
||||
_stride = copy._stride;
|
||||
_pointer_begin = copy._pointer_begin;
|
||||
_pointer_end = copy._pointer_end;
|
||||
_pointer = copy._pointer;
|
||||
_start_row = copy._start_row;
|
||||
|
||||
((GeomVertexReader &)copy)._owns_reader = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -147,6 +188,9 @@ operator = (const GeomVertexReader ©) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexReader::
|
||||
~GeomVertexReader() {
|
||||
if (_owns_reader) {
|
||||
clear_reader();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -158,7 +202,10 @@ INLINE GeomVertexReader::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexData *GeomVertexReader::
|
||||
get_vertex_data() const {
|
||||
return _vertex_data;
|
||||
if (_data_reader != (GeomVertexDataPipelineReader *)NULL) {
|
||||
return _data_reader->get_object();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -169,7 +216,7 @@ get_vertex_data() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomVertexReader::
|
||||
get_array_data() const {
|
||||
return _array_data;
|
||||
return _array_reader->get_object();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -187,12 +234,12 @@ get_array_data() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexReader::
|
||||
set_column(int column) {
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
return set_column(_vertex_data->get_format()->get_array_with(column),
|
||||
_vertex_data->get_format()->get_column(column));
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
|
||||
return set_column(_data_reader->get_format()->get_array_with(column),
|
||||
_data_reader->get_format()->get_column(column));
|
||||
}
|
||||
if (_array_data != (const GeomVertexArrayData *)NULL) {
|
||||
return set_column(0, _array_data->get_array_format()->get_column(column));
|
||||
if (_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL) {
|
||||
return set_column(0, _array_reader->get_array_format()->get_column(column));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -230,12 +277,12 @@ set_column(const string &name) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexReader::
|
||||
set_column(const InternalName *name) {
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
return set_column(_vertex_data->get_format()->get_array_with(name),
|
||||
_vertex_data->get_format()->get_column(name));
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
|
||||
return set_column(_data_reader->get_format()->get_array_with(name),
|
||||
_data_reader->get_format()->get_column(name));
|
||||
}
|
||||
if (_array_data != (const GeomVertexArrayData *)NULL) {
|
||||
return set_column(0, _array_data->get_array_format()->get_column(name));
|
||||
if (_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL) {
|
||||
return set_column(0, _array_reader->get_array_format()->get_column(name));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -454,14 +501,14 @@ get_packer() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexReader::
|
||||
set_pointer(int row) {
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
_pointer_begin = array_data->get_data();
|
||||
_pointer_end = _pointer_begin + array_data->get_data_size_bytes();
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
|
||||
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
|
||||
_pointer_begin = array_reader->get_data();
|
||||
_pointer_end = _pointer_begin + array_reader->get_data_size_bytes();
|
||||
|
||||
} else {
|
||||
_pointer_begin = _array_data->get_data();
|
||||
_pointer_end = _pointer_begin + _array_data->get_data_size_bytes();
|
||||
_pointer_begin = _array_reader->get_data();
|
||||
_pointer_end = _pointer_begin + _array_reader->get_data_size_bytes();
|
||||
}
|
||||
quick_set_pointer(row);
|
||||
}
|
||||
@@ -478,11 +525,11 @@ quick_set_pointer(int row) {
|
||||
nassertv(has_column());
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertv(_pointer_begin == array_data->get_data());
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
|
||||
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
|
||||
nassertv(_pointer_begin == array_reader->get_data());
|
||||
} else {
|
||||
nassertv(_pointer_begin == _array_data->get_data());
|
||||
nassertv(_pointer_begin == _array_reader->get_data());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -499,11 +546,11 @@ INLINE const unsigned char *GeomVertexReader::
|
||||
inc_pointer() {
|
||||
#ifdef _DEBUG
|
||||
nassertr(_pointer < _pointer_end, empty_buffer);
|
||||
if (_vertex_data != (const GeomVertexData *)NULL){
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL){
|
||||
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
|
||||
nassertr(_pointer >= array_reader->get_data().p() && _pointer < array_reader->get_data().p() + array_reader->get_data_size_bytes(), empty_buffer);
|
||||
} else {
|
||||
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
|
||||
nassertr(_pointer >= _array_reader->get_data().p() && _pointer < _array_reader->get_data().p() + _array_reader->get_data_size_bytes(), empty_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ const unsigned char GeomVertexReader::empty_buffer[100] = { 0 };
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexReader::
|
||||
set_column(int array, const GeomVertexColumn *column) {
|
||||
if (_vertex_data == (const GeomVertexData *)NULL &&
|
||||
_array_data == (const GeomVertexArrayData *)NULL) {
|
||||
if (_data_reader == (const GeomVertexDataPipelineReader *)NULL &&
|
||||
_array_reader == (const GeomVertexArrayDataPipelineReader *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -56,18 +56,18 @@ set_column(int array, const GeomVertexColumn *column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
|
||||
#ifndef NDEBUG
|
||||
_array = -1;
|
||||
_packer = NULL;
|
||||
nassertr(array >= 0 && array < _vertex_data->get_num_arrays(), false);
|
||||
nassertr(array >= 0 && array < _data_reader->get_num_arrays(), false);
|
||||
#endif
|
||||
_array = array;
|
||||
const GeomVertexArrayData *array_data =_vertex_data->get_array(_array);
|
||||
_stride = array_data->get_array_format()->get_stride();
|
||||
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
|
||||
_stride = array_reader->get_array_format()->get_stride();
|
||||
|
||||
} else {
|
||||
_stride = _array_data->get_array_format()->get_stride();
|
||||
_stride = _array_reader->get_array_format()->get_stride();
|
||||
}
|
||||
|
||||
_packer = column->_packer;
|
||||
@@ -103,6 +103,10 @@ output(ostream &out) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexReader::
|
||||
initialize() {
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
|
||||
_data_reader->check_array_readers();
|
||||
}
|
||||
|
||||
_array = 0;
|
||||
_packer = NULL;
|
||||
_pointer_begin = NULL;
|
||||
@@ -110,3 +114,25 @@ initialize() {
|
||||
_pointer = NULL;
|
||||
_start_row = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexReader::clear_reader
|
||||
// Access: Private
|
||||
// Description: Destructs the GeomVertexDataPipelineReader, when
|
||||
// necessary, for instance when this object destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexReader::
|
||||
clear_reader() {
|
||||
nassertv(_owns_reader);
|
||||
|
||||
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
|
||||
delete (GeomVertexDataPipelineReader *)_data_reader;
|
||||
_data_reader = NULL;
|
||||
} else {
|
||||
nassertv(_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL);
|
||||
delete (GeomVertexArrayDataPipelineReader *)_array_reader;
|
||||
_array_reader = NULL;
|
||||
}
|
||||
|
||||
_owns_reader = false;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,12 @@ PUBLISHED:
|
||||
INLINE GeomVertexReader(const GeomVertexArrayData *array_data);
|
||||
INLINE GeomVertexReader(const GeomVertexArrayData *array_data,
|
||||
int column);
|
||||
|
||||
public:
|
||||
INLINE GeomVertexReader(const GeomVertexDataPipelineReader *data_reader,
|
||||
const InternalName *name);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE GeomVertexReader(const GeomVertexReader ©);
|
||||
INLINE void operator = (const GeomVertexReader ©);
|
||||
INLINE ~GeomVertexReader();
|
||||
@@ -107,6 +113,7 @@ protected:
|
||||
|
||||
private:
|
||||
void initialize();
|
||||
void clear_reader();
|
||||
|
||||
INLINE void set_pointer(int row);
|
||||
INLINE void quick_set_pointer(int row);
|
||||
@@ -117,9 +124,10 @@ private:
|
||||
// must not keep a pointer to the particular ArrayData we are
|
||||
// working on (if we do, it may result in an extra copy of the data
|
||||
// due to holding the reference count).
|
||||
CPT(GeomVertexData) _vertex_data;
|
||||
const GeomVertexDataPipelineReader *_data_reader;
|
||||
int _array;
|
||||
CPT(GeomVertexArrayData) _array_data;
|
||||
const GeomVertexArrayDataPipelineReader *_array_reader;
|
||||
bool _owns_reader;
|
||||
|
||||
GeomVertexColumn::Packer *_packer;
|
||||
int _stride;
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter() :
|
||||
_vertex_data(NULL)
|
||||
_data_writer(NULL),
|
||||
_array_writer(NULL),
|
||||
_owns_writer(false)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
@@ -40,7 +42,9 @@ GeomVertexWriter() :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter(GeomVertexData *vertex_data) :
|
||||
_vertex_data(vertex_data)
|
||||
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)),
|
||||
_array_writer(NULL),
|
||||
_owns_writer(true)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
@@ -54,7 +58,9 @@ GeomVertexWriter(GeomVertexData *vertex_data) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
|
||||
_vertex_data(vertex_data)
|
||||
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)),
|
||||
_array_writer(NULL),
|
||||
_owns_writer(true)
|
||||
{
|
||||
initialize();
|
||||
set_column(name);
|
||||
@@ -69,7 +75,9 @@ GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
|
||||
_vertex_data(vertex_data)
|
||||
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)),
|
||||
_array_writer(NULL),
|
||||
_owns_writer(true)
|
||||
{
|
||||
initialize();
|
||||
set_column(name);
|
||||
@@ -83,7 +91,9 @@ GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter(GeomVertexArrayData *array_data) :
|
||||
_array_data(array_data)
|
||||
_data_writer(NULL),
|
||||
_array_writer(new GeomVertexArrayDataPipelineWriter(array_data, Thread::get_current_pipeline_stage(), true)),
|
||||
_owns_writer(true)
|
||||
{
|
||||
initialize();
|
||||
}
|
||||
@@ -96,22 +106,44 @@ GeomVertexWriter(GeomVertexArrayData *array_data) :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter(GeomVertexArrayData *array_data, int column) :
|
||||
_array_data(array_data)
|
||||
_data_writer(NULL),
|
||||
_array_writer(new GeomVertexArrayDataPipelineWriter(array_data, Thread::get_current_pipeline_stage(), true)),
|
||||
_owns_writer(true)
|
||||
{
|
||||
initialize();
|
||||
set_column(column);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexWriter::Constructor
|
||||
// Access: Public
|
||||
// Description: Constructs a new writer to process the vertices of
|
||||
// the indicated data object. This flavor creates the
|
||||
// writer specifically to process the named data type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer,
|
||||
const InternalName *name) :
|
||||
_data_writer(data_writer),
|
||||
_array_writer(NULL),
|
||||
_owns_writer(false)
|
||||
{
|
||||
initialize();
|
||||
set_column(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexWriter::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description: The copy constructor steals ownership of the writer
|
||||
// pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
GeomVertexWriter(const GeomVertexWriter ©) :
|
||||
_vertex_data(copy._vertex_data),
|
||||
_data_writer(copy._data_writer),
|
||||
_array(copy._array),
|
||||
_array_data(copy._array_data),
|
||||
_array_writer(copy._array_writer),
|
||||
_owns_writer(copy._owns_writer),
|
||||
_packer(copy._packer),
|
||||
_stride(copy._stride),
|
||||
_pointer_begin(copy._pointer_begin),
|
||||
@@ -119,24 +151,29 @@ GeomVertexWriter(const GeomVertexWriter ©) :
|
||||
_pointer(copy._pointer),
|
||||
_start_row(copy._start_row)
|
||||
{
|
||||
((GeomVertexWriter &)copy)._owns_writer = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexWriter::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Description: The copy constructor steals ownership of the writer
|
||||
// pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexWriter::
|
||||
operator = (const GeomVertexWriter ©) {
|
||||
_vertex_data = copy._vertex_data;
|
||||
_data_writer = copy._data_writer;
|
||||
_array = copy._array;
|
||||
_array_data = copy._array_data;
|
||||
_array_writer = copy._array_writer;
|
||||
_owns_writer = copy._owns_writer;
|
||||
_packer = copy._packer;
|
||||
_stride = copy._stride;
|
||||
_pointer_begin = copy._pointer_begin;
|
||||
_pointer_end = copy._pointer_end;
|
||||
_pointer = copy._pointer;
|
||||
_start_row = copy._start_row;
|
||||
|
||||
((GeomVertexWriter &)copy)._owns_writer = false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -146,6 +183,9 @@ operator = (const GeomVertexWriter ©) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexWriter::
|
||||
~GeomVertexWriter() {
|
||||
if (_owns_writer) {
|
||||
clear_writer();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -157,7 +197,10 @@ INLINE GeomVertexWriter::
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexData *GeomVertexWriter::
|
||||
get_vertex_data() const {
|
||||
return _vertex_data;
|
||||
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
|
||||
return _data_writer->get_object();
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -168,7 +211,7 @@ get_vertex_data() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayData *GeomVertexWriter::
|
||||
get_array_data() const {
|
||||
return _array_data;
|
||||
return _array_writer->get_object();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -186,12 +229,12 @@ get_array_data() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexWriter::
|
||||
set_column(int column) {
|
||||
if (_vertex_data != (GeomVertexData *)NULL) {
|
||||
return set_column(_vertex_data->get_format()->get_array_with(column),
|
||||
_vertex_data->get_format()->get_column(column));
|
||||
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
|
||||
return set_column(_data_writer->get_format()->get_array_with(column),
|
||||
_data_writer->get_format()->get_column(column));
|
||||
}
|
||||
if (_array_data != (GeomVertexArrayData *)NULL) {
|
||||
return set_column(0, _array_data->get_array_format()->get_column(column));
|
||||
if (_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL) {
|
||||
return set_column(0, _array_writer->get_array_format()->get_column(column));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -229,12 +272,12 @@ set_column(const string &name) {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexWriter::
|
||||
set_column(const InternalName *name) {
|
||||
if (_vertex_data != (GeomVertexData *)NULL) {
|
||||
return set_column(_vertex_data->get_format()->get_array_with(name),
|
||||
_vertex_data->get_format()->get_column(name));
|
||||
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
|
||||
return set_column(_data_writer->get_format()->get_array_with(name),
|
||||
_data_writer->get_format()->get_column(name));
|
||||
}
|
||||
if (_array_data != (GeomVertexArrayData *)NULL) {
|
||||
return set_column(0, _array_data->get_array_format()->get_column(name));
|
||||
if (_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL) {
|
||||
return set_column(0, _array_writer->get_array_format()->get_column(name));
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -759,14 +802,15 @@ get_packer() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexWriter::
|
||||
set_pointer(int row) {
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
GeomVertexArrayData *array_data = _vertex_data->modify_array(_array);
|
||||
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
|
||||
_data_writer->modify_array(_array);
|
||||
GeomVertexArrayDataPipelineWriter *array_data = _data_writer->get_array_writer(_array);
|
||||
_pointer_begin = array_data->modify_data();
|
||||
_pointer_end = _pointer_begin + array_data->get_data_size_bytes();
|
||||
|
||||
} else {
|
||||
_pointer_begin = _array_data->modify_data();
|
||||
_pointer_end = _pointer_begin + _array_data->get_data_size_bytes();
|
||||
_pointer_begin = _array_writer->modify_data();
|
||||
_pointer_end = _pointer_begin + _array_writer->get_data_size_bytes();
|
||||
}
|
||||
quick_set_pointer(row);
|
||||
}
|
||||
@@ -783,11 +827,11 @@ quick_set_pointer(int row) {
|
||||
nassertv(has_column());
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertv(_pointer_begin == array_data->get_data());
|
||||
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
|
||||
GeomVertexArrayDataPipelineWriter *array_writer = _data_writer->get_array_writer(_array);
|
||||
nassertv(_pointer_begin == array_writer->get_data());
|
||||
} else {
|
||||
nassertv(_pointer_begin == _array_data->get_data());
|
||||
nassertv(_pointer_begin == _array_writer->get_data());
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -804,11 +848,11 @@ INLINE unsigned char *GeomVertexWriter::
|
||||
inc_pointer() {
|
||||
#ifdef _DEBUG
|
||||
nassertr(_pointer < _pointer_end, empty_buffer);
|
||||
if (_vertex_data != (GeomVertexData *)NULL){
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
|
||||
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL){
|
||||
GeomVertexArrayDataPipelineWriter *array_writer = _data_writer->get_array_writer(_array);
|
||||
nassertr(_pointer >= array_writer->get_data().p() && _pointer < array_writer->get_data().p() + array_writer->get_data_size_bytes(), empty_buffer);
|
||||
} else {
|
||||
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
|
||||
nassertr(_pointer >= _array_writer->get_data().p() && _pointer < _array_writer->get_data().p() + _array_writer->get_data_size_bytes(), empty_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -830,10 +874,10 @@ inc_add_pointer() {
|
||||
if (_pointer >= _pointer_end) {
|
||||
// Reset the data pointer.
|
||||
int write_row = get_write_row();
|
||||
if (_vertex_data != (GeomVertexData *)NULL) {
|
||||
_vertex_data->set_num_rows(max(write_row + 1, _vertex_data->get_num_rows()));
|
||||
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
|
||||
_data_writer->set_num_rows(max(write_row + 1, _data_writer->get_num_rows()));
|
||||
} else {
|
||||
_array_data->set_num_rows(max(write_row + 1, _array_data->get_num_rows()));
|
||||
_array_writer->set_num_rows(max(write_row + 1, _array_writer->get_num_rows()));
|
||||
}
|
||||
set_pointer(write_row);
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ unsigned char GeomVertexWriter::empty_buffer[100] = { 0 };
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexWriter::
|
||||
set_column(int array, const GeomVertexColumn *column) {
|
||||
if (_vertex_data == (GeomVertexData *)NULL &&
|
||||
_array_data == (GeomVertexArrayData *)NULL) {
|
||||
if (_data_writer == (GeomVertexDataPipelineWriter *)NULL &&
|
||||
_array_writer == (GeomVertexArrayDataPipelineWriter *)NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -56,18 +56,18 @@ set_column(int array, const GeomVertexColumn *column) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_vertex_data != (GeomVertexData *)NULL) {
|
||||
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
|
||||
#ifndef NDEBUG
|
||||
_array = -1;
|
||||
_packer = NULL;
|
||||
nassertr(array >= 0 && array < _vertex_data->get_num_arrays(), false);
|
||||
nassertr(array >= 0 && array < _data_writer->get_num_arrays(), false);
|
||||
#endif
|
||||
_array = array;
|
||||
const GeomVertexArrayData *array_data =_vertex_data->get_array(_array);
|
||||
_stride = array_data->get_array_format()->get_stride();
|
||||
GeomVertexArrayDataPipelineWriter *array_writer =_data_writer->get_array_writer(_array);
|
||||
_stride = array_writer->get_array_format()->get_stride();
|
||||
|
||||
} else {
|
||||
_stride = _array_data->get_array_format()->get_stride();
|
||||
_stride = _array_writer->get_array_format()->get_stride();
|
||||
}
|
||||
|
||||
_packer = column->_packer;
|
||||
@@ -103,6 +103,10 @@ output(ostream &out) const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexWriter::
|
||||
initialize() {
|
||||
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
|
||||
_data_writer->check_array_writers();
|
||||
}
|
||||
|
||||
_array = 0;
|
||||
_packer = NULL;
|
||||
_pointer_begin = NULL;
|
||||
@@ -110,3 +114,25 @@ initialize() {
|
||||
_pointer = NULL;
|
||||
_start_row = 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexWriter::clear_writer
|
||||
// Access: Private
|
||||
// Description: Destructs the GeomVertexDataPipelineWriter, when
|
||||
// necessary, for instance when this object destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexWriter::
|
||||
clear_writer() {
|
||||
nassertv(_owns_writer);
|
||||
|
||||
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
|
||||
delete _data_writer;
|
||||
_data_writer = NULL;
|
||||
} else {
|
||||
nassertv(_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL);
|
||||
delete _array_writer;
|
||||
_array_writer = NULL;
|
||||
}
|
||||
|
||||
_owns_writer = false;
|
||||
}
|
||||
|
||||
@@ -81,6 +81,12 @@ PUBLISHED:
|
||||
INLINE GeomVertexWriter(GeomVertexArrayData *array_data);
|
||||
INLINE GeomVertexWriter(GeomVertexArrayData *array_data,
|
||||
int column);
|
||||
|
||||
public:
|
||||
INLINE GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer,
|
||||
const InternalName *name);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE GeomVertexWriter(const GeomVertexWriter ©);
|
||||
INLINE void operator = (const GeomVertexWriter ©);
|
||||
INLINE ~GeomVertexWriter();
|
||||
@@ -144,6 +150,7 @@ private:
|
||||
class Writer;
|
||||
|
||||
void initialize();
|
||||
void clear_writer();
|
||||
|
||||
INLINE void set_pointer(int row);
|
||||
INLINE void quick_set_pointer(int row);
|
||||
@@ -155,9 +162,10 @@ private:
|
||||
// must not keep a pointer to the particular ArrayData we are
|
||||
// working on (if we do, it may result in an extra copy of the data
|
||||
// due to holding the reference count).
|
||||
PT(GeomVertexData) _vertex_data;
|
||||
GeomVertexDataPipelineWriter *_data_writer;
|
||||
int _array;
|
||||
PT(GeomVertexArrayData) _array_data;
|
||||
GeomVertexArrayDataPipelineWriter *_array_writer;
|
||||
bool _owns_writer;
|
||||
|
||||
GeomVertexColumn::Packer *_packer;
|
||||
int _stride;
|
||||
|
||||
@@ -40,7 +40,7 @@ cp_report_error(ShaderArgInfo &p, const string &msg)
|
||||
if (p._direction == SAD_out) dstr = "out ";
|
||||
if (p._direction == SAD_inout) dstr = "inout ";
|
||||
|
||||
string tstr = "unknown ";
|
||||
string tstr = "invalid ";
|
||||
switch (p._type) {
|
||||
case SAT_float1: tstr = "float1 "; break;
|
||||
case SAT_float2: tstr = "float2 "; break;
|
||||
@@ -51,6 +51,7 @@ cp_report_error(ShaderArgInfo &p, const string &msg)
|
||||
case SAT_sampler2d: tstr = "sampler2d "; break;
|
||||
case SAT_sampler3d: tstr = "sampler3d "; break;
|
||||
case SAT_samplercube: tstr = "samplercube "; break;
|
||||
case SAT_unknown: tstr = "unknown "; break;
|
||||
}
|
||||
|
||||
string fn = _shader_expansion->get_name();
|
||||
@@ -70,7 +71,7 @@ cp_errchk_parameter_words(ShaderArgInfo &p, int len)
|
||||
{
|
||||
vector_string words;
|
||||
tokenize(p._name, words, "_");
|
||||
if (words.size() != len) {
|
||||
if ((int)words.size() != len) {
|
||||
cp_report_error(p, "parameter name has wrong number of words");
|
||||
return false;
|
||||
}
|
||||
@@ -138,13 +139,14 @@ cp_errchk_parameter_uniform(ShaderArgInfo &p)
|
||||
bool ShaderContext::
|
||||
cp_errchk_parameter_float(ShaderArgInfo &p, int lo, int hi)
|
||||
{
|
||||
int nfloat = 0;
|
||||
int nfloat;
|
||||
switch (p._type) {
|
||||
case SAT_float1: nfloat = 1; break;
|
||||
case SAT_float2: nfloat = 2; break;
|
||||
case SAT_float3: nfloat = 3; break;
|
||||
case SAT_float4: nfloat = 4; break;
|
||||
case SAT_float4x4: nfloat = 16; break;
|
||||
default: nfloat = 0; break;
|
||||
}
|
||||
if ((nfloat < lo)||(nfloat > hi)) {
|
||||
string msg = "wrong type for parameter: should be float";
|
||||
|
||||
@@ -36,20 +36,12 @@ class OcclusionQueryContext;
|
||||
class GeomContext;
|
||||
class GeomNode;
|
||||
class Geom;
|
||||
class GeomPoint;
|
||||
class GeomLine;
|
||||
class GeomLinestrip;
|
||||
class GeomSprite;
|
||||
class GeomPolygon;
|
||||
class GeomQuad;
|
||||
class GeomTri;
|
||||
class GeomTristrip;
|
||||
class GeomTrifan;
|
||||
class GeomSphere;
|
||||
class Geom;
|
||||
class GeomPipelineReader;
|
||||
class GeomVertexData;
|
||||
class GeomVertexDataPipelineReader;
|
||||
class GeomVertexArrayData;
|
||||
class GeomPrimitive;
|
||||
class GeomPrimitivePipelineReader;
|
||||
class GeomTriangles;
|
||||
class GeomTristrips;
|
||||
class GeomTrifans;
|
||||
@@ -177,26 +169,15 @@ public:
|
||||
// inconvenient to declare each of those types to be friends of this
|
||||
// class.
|
||||
|
||||
virtual void draw_point(GeomPoint *geom, GeomContext *gc) { }
|
||||
virtual void draw_line(GeomLine *geom, GeomContext *gc) { }
|
||||
virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc) { }
|
||||
virtual void draw_sprite(GeomSprite *geom, GeomContext *gc) { }
|
||||
virtual void draw_polygon(GeomPolygon *geom, GeomContext *gc) { }
|
||||
virtual void draw_quad(GeomQuad *geom, GeomContext *gc) { }
|
||||
virtual void draw_tri(GeomTri *geom, GeomContext *gc) { }
|
||||
virtual void draw_tristrip(GeomTristrip *geom, GeomContext *gc) { }
|
||||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc) { }
|
||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc) { }
|
||||
|
||||
virtual bool begin_draw_primitives(const Geom *geom,
|
||||
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
||||
const GeomMunger *munger,
|
||||
const GeomVertexData *vertex_data)=0;
|
||||
virtual void draw_triangles(const GeomTriangles *primitive)=0;
|
||||
virtual void draw_tristrips(const GeomTristrips *primitive)=0;
|
||||
virtual void draw_trifans(const GeomTrifans *primitive)=0;
|
||||
virtual void draw_lines(const GeomLines *primitive)=0;
|
||||
virtual void draw_linestrips(const GeomLinestrips *primitive)=0;
|
||||
virtual void draw_points(const GeomPoints *primitive)=0;
|
||||
const GeomVertexDataPipelineReader *data_reader)=0;
|
||||
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader)=0;
|
||||
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader)=0;
|
||||
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader)=0;
|
||||
virtual void draw_lines(const GeomPrimitivePipelineReader *reader)=0;
|
||||
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader)=0;
|
||||
virtual void draw_points(const GeomPrimitivePipelineReader *reader)=0;
|
||||
virtual void end_draw_primitives()=0;
|
||||
|
||||
virtual void framebuffer_copy_to_texture
|
||||
|
||||
@@ -69,6 +69,10 @@ PUBLISHED:
|
||||
Mersenne(unsigned long seed);
|
||||
unsigned long get_uint31();
|
||||
|
||||
enum {
|
||||
max_value = 0x7fffffff
|
||||
};
|
||||
|
||||
private:
|
||||
enum {
|
||||
// Period parameters
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "pvector.h"
|
||||
#include "vector_int.h"
|
||||
#include "luse.h"
|
||||
#include "mersenne.h"
|
||||
|
||||
@@ -57,7 +58,7 @@ protected:
|
||||
static Mersenne _next_seed;
|
||||
static bool _got_first_seed;
|
||||
|
||||
typedef pvector<int> Index;
|
||||
typedef vector_int Index;
|
||||
Index _index;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "parametricCurveDrawer.h"
|
||||
#include "lineSegs.h"
|
||||
#include "vector_int.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -57,7 +58,7 @@ protected:
|
||||
LVecBase3f _cv_color, _hull_color, _knot_color;
|
||||
int _num_cvs, _num_hull, _num_knots;
|
||||
LineSegs _hull, _knots, _cvs;
|
||||
pvector<int> _knotnums;
|
||||
vector_int _knotnums;
|
||||
|
||||
bool _show_cvs, _show_hull, _show_knots;
|
||||
|
||||
|
||||
@@ -575,7 +575,7 @@ render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
|
||||
// First, since this is the only time we have access to the actual particles, do some delayed initialization.
|
||||
if (_animate_frames || anim_count) {
|
||||
if (!_birth_list.empty()) {
|
||||
for (pvector<int>::iterator vIter = _birth_list.begin(); vIter != _birth_list.end(); ++vIter) {
|
||||
for (vector_int::iterator vIter = _birth_list.begin(); vIter != _birth_list.end(); ++vIter) {
|
||||
cur_particle = (BaseParticle*)po_vector[*vIter].p();
|
||||
i = int(NORMALIZED_RAND()*anim_count);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "geomVertexWriter.h"
|
||||
#include "textureCollection.h"
|
||||
#include "nodePathCollection.h"
|
||||
#include "vector_int.h"
|
||||
|
||||
class NodePath;
|
||||
|
||||
@@ -273,9 +274,9 @@ private:
|
||||
virtual void resize_pool(int new_size);
|
||||
int extract_textures_from_node(const NodePath &node_path, NodePathCollection &np_col, TextureCollection &tex_col);
|
||||
|
||||
pvector<int> _anim_size; // Holds the number of frames in each animation.
|
||||
vector_int _anim_size; // Holds the number of frames in each animation.
|
||||
pvector<int*> _ttl_count; // _ttl_count[i][j] holds the number of particles attached to animation 'i' at frame 'j'.
|
||||
pvector<int> _birth_list; // Holds the list of particles that need a new random animation to start on.
|
||||
vector_int _birth_list; // Holds the list of particles that need a new random animation to start on.
|
||||
};
|
||||
|
||||
#include "spriteParticleRenderer.I"
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
lerp event gsgbase gobj putil linmath \
|
||||
downloader express pandabase pstatclient
|
||||
|
||||
|
||||
#begin lib_target
|
||||
#define TARGET pgraph
|
||||
|
||||
// This directory is too big to combine into a single composite file.
|
||||
#define DONT_COMBINE 1
|
||||
|
||||
#define SOURCES \
|
||||
accumulatedAttribs.I accumulatedAttribs.h \
|
||||
alphaTestAttrib.I alphaTestAttrib.h \
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "sliderTable.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "vector_int.h"
|
||||
|
||||
static PStatCollector apply_vertex_collector("*:Flatten:apply:vertex");
|
||||
static PStatCollector apply_texcoord_collector("*:Flatten:apply:texcoord");
|
||||
@@ -483,7 +484,7 @@ collect_vertex_data(Geom *geom, int collect_bits) {
|
||||
// remapping transform indices in the vertices. Each of these has a
|
||||
// slightly different way to handle the remapping, because they have
|
||||
// slightly different kinds of data.
|
||||
typedef pvector<int> IndexMap;
|
||||
typedef vector_int IndexMap;
|
||||
|
||||
if (vdata->get_transform_table() != (TransformTable *)NULL) {
|
||||
// The TransformTable.
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
|
||||
ShaderPool *ShaderPool::_global_ptr = (ShaderPool *)NULL;
|
||||
|
||||
// ??? Is this needed ???
|
||||
static Loader model_loader;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ShaderPool::write
|
||||
// Access: Published, Static
|
||||
|
||||
@@ -176,3 +176,25 @@
|
||||
|
||||
#end test_bin_target
|
||||
|
||||
|
||||
#begin test_bin_target
|
||||
#define TARGET test_delete
|
||||
#define LOCAL_LIBS $[LOCAL_LIBS] pipeline
|
||||
#define OTHER_LIBS dtoolutil:c dtool:m dtoolconfig:m pystub
|
||||
|
||||
#define SOURCES \
|
||||
test_delete.cxx
|
||||
|
||||
#end test_bin_target
|
||||
|
||||
|
||||
#begin test_bin_target
|
||||
#define TARGET test_atomic
|
||||
#define LOCAL_LIBS $[LOCAL_LIBS] pipeline
|
||||
#define OTHER_LIBS dtoolutil:c dtool:m dtoolconfig:m pystub
|
||||
|
||||
#define SOURCES \
|
||||
test_atomic.cxx
|
||||
|
||||
#end test_bin_target
|
||||
|
||||
|
||||
@@ -33,10 +33,10 @@ ConfigureFn(config_pipeline) {
|
||||
}
|
||||
|
||||
ConfigVariableInt thread_stack_size
|
||||
("thread-stack-size", 16384,
|
||||
PRC_DESC("Specifies the size, in bytes, of the stack that will be created "
|
||||
"for each newly-created thread. Not all thread implementations "
|
||||
"respect this value."));
|
||||
("thread-stack-size", 4194304,
|
||||
PRC_DESC("Specifies the minimum size, in bytes, of the stack that will be "
|
||||
"created for each newly-created thread. Not all thread "
|
||||
"implementations respect this value."));
|
||||
|
||||
ConfigVariableBool threads_always_global
|
||||
("threads-always-global", false,
|
||||
|
||||
@@ -35,6 +35,22 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage) :
|
||||
nassertv(_pointer != (CycleDataType *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Constructor (full)
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataStageWriter<CycleDataType>::
|
||||
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
|
||||
bool force_to_0) :
|
||||
_cycler(&cycler),
|
||||
_stage(stage)
|
||||
{
|
||||
_pointer = _cycler->write_stage_upstream(_stage, force_to_0);
|
||||
nassertv(_pointer != (CycleDataType *)NULL);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Copy Constructor (full)
|
||||
// Access: Public
|
||||
@@ -86,6 +102,25 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
|
||||
_pointer = _cycler->elevate_read_stage(_stage, take_from.take_pointer());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Constructor (full)
|
||||
// Access: Public
|
||||
// Description: This flavor of the constructor elevates the pointer
|
||||
// from the CycleDataStageReader from a read to a write
|
||||
// pointer (and invalidates the reader).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataStageWriter<CycleDataType>::
|
||||
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
|
||||
CycleDataStageReader<CycleDataType> &take_from,
|
||||
bool force_to_0) :
|
||||
_cycler(&cycler),
|
||||
_stage(stage)
|
||||
{
|
||||
_pointer = _cycler->elevate_read_stage_upstream(_stage, take_from.take_pointer(),
|
||||
force_to_0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Destructor (full)
|
||||
// Access: Public
|
||||
@@ -152,6 +187,17 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int) {
|
||||
_pointer = cycler.write();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Constructor (trivial)
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataStageWriter<CycleDataType>::
|
||||
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int, bool) {
|
||||
_pointer = cycler.write();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Copy Constructor (trivial)
|
||||
// Access: Public
|
||||
@@ -190,6 +236,22 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &, int,
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Constructor (trivial)
|
||||
// Access: Public
|
||||
// Description: This flavor of the constructor elevates the pointer
|
||||
// from the CycleDataStageReader from a read to a write
|
||||
// pointer (and invalidates the reader).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataStageWriter<CycleDataType>::
|
||||
CycleDataStageWriter(PipelineCycler<CycleDataType> &, int,
|
||||
CycleDataStageReader<CycleDataType> &take_from,
|
||||
bool) :
|
||||
_pointer((CycleDataType *)take_from.take_pointer())
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CycleDataStageWriter::Destructor (trivial)
|
||||
// Access: Public
|
||||
|
||||
@@ -38,11 +38,16 @@ template<class CycleDataType>
|
||||
class CycleDataStageWriter {
|
||||
public:
|
||||
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage);
|
||||
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
|
||||
bool force_to_0);
|
||||
INLINE CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> ©);
|
||||
INLINE void operator = (const CycleDataStageWriter<CycleDataType> ©);
|
||||
|
||||
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
|
||||
CycleDataStageReader<CycleDataType> &take_from);
|
||||
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
|
||||
CycleDataStageReader<CycleDataType> &take_from,
|
||||
bool force_to_0);
|
||||
|
||||
INLINE ~CycleDataStageWriter();
|
||||
|
||||
|
||||
@@ -140,13 +140,11 @@ do_lock() {
|
||||
}
|
||||
while (_locking_thread != (Thread *)NULL) {
|
||||
_cvar.wait();
|
||||
thread_cat.spam()
|
||||
<< *this_thread << " wakeup\n";
|
||||
}
|
||||
|
||||
if (thread_cat.is_spam()) {
|
||||
thread_cat.spam()
|
||||
<< *this_thread << " awake\n";
|
||||
<< *this_thread << " awake on " << *this << "\n";
|
||||
}
|
||||
|
||||
this_thread->_blocked_on_mutex = NULL;
|
||||
|
||||
@@ -122,6 +122,17 @@ elevate_read_stage(int n, const CycleDataType *pointer) {
|
||||
return (CycleDataType *)PipelineCyclerBase::elevate_read_stage(n, pointer);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::elevate_read_stage_upstream (dummy or true)
|
||||
// Access: Public
|
||||
// Description: See PipelineCyclerBase::elevate_read_stage_upstream().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataType *PipelineCycler<CycleDataType>::
|
||||
elevate_read_stage_upstream(int n, const CycleDataType *pointer, bool force_to_0) {
|
||||
return (CycleDataType *)PipelineCyclerBase::elevate_read_stage_upstream(n, pointer, force_to_0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::write_upstream (dummy or true)
|
||||
// Access: Public
|
||||
@@ -144,6 +155,17 @@ write_stage(int n) {
|
||||
return (CycleDataType *)PipelineCyclerBase::write_stage(n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::write_stage_upstream (dummy or true)
|
||||
// Access: Public
|
||||
// Description: See PipelineCyclerBase::write_stage_upstream().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataType *PipelineCycler<CycleDataType>::
|
||||
write_stage_upstream(int pipeline_stage, bool force_to_0) {
|
||||
return (CycleDataType *)PipelineCyclerBase::write_stage_upstream(pipeline_stage, force_to_0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::cheat (dummy or true)
|
||||
// Access: Public
|
||||
@@ -212,6 +234,17 @@ read() const {
|
||||
return &_typed_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::read_stage (trivial)
|
||||
// Access: Public
|
||||
// Description: See PipelineCyclerBase::read_stage().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
|
||||
read_stage(int) const {
|
||||
return &_typed_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::write (trivial)
|
||||
// Access: Public
|
||||
@@ -245,6 +278,28 @@ elevate_read_upstream(const CycleDataType *, bool) {
|
||||
return &_typed_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::elevate_read_stage (trivial)
|
||||
// Access: Public
|
||||
// Description: See PipelineCyclerBase::elevate_read_stage().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataType *PipelineCycler<CycleDataType>::
|
||||
elevate_read_stage(int, const CycleDataType *) {
|
||||
return &_typed_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::elevate_read_stage_upstream (trivial)
|
||||
// Access: Public
|
||||
// Description: See PipelineCyclerBase::elevate_read_stage_upstream().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataType *PipelineCycler<CycleDataType>::
|
||||
elevate_read_stage_upstream(int, const CycleDataType *, bool) {
|
||||
return &_typed_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::write_upstream (trivial)
|
||||
// Access: Public
|
||||
@@ -267,6 +322,17 @@ write_stage(int) {
|
||||
return &_typed_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::write_stage_upstream (trivial)
|
||||
// Access: Public
|
||||
// Description: See PipelineCyclerBase::write_stage_upstream().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template<class CycleDataType>
|
||||
INLINE CycleDataType *PipelineCycler<CycleDataType>::
|
||||
write_stage_upstream(int, bool) {
|
||||
return &_typed_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCycler::cheat (trivial)
|
||||
// Access: Public
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "pandabase.h"
|
||||
#include "pipelineCyclerBase.h"
|
||||
#include "cyclerHolder.h"
|
||||
#include "thread.h" // for convenience of code that uses PipelineReader classes
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PipelineCycler
|
||||
@@ -68,7 +69,9 @@ public:
|
||||
INLINE CycleDataType *elevate_read(const CycleDataType *pointer);
|
||||
INLINE CycleDataType *elevate_read_upstream(const CycleDataType *pointer, bool force_to_0);
|
||||
INLINE CycleDataType *elevate_read_stage(int n, const CycleDataType *pointer);
|
||||
INLINE CycleDataType *elevate_read_stage_upstream(int n, const CycleDataType *pointer, bool force_to_0);
|
||||
INLINE CycleDataType *write_upstream(bool force_to_0);
|
||||
INLINE CycleDataType *write_stage_upstream(int pipeline_stage, bool force_to_0);
|
||||
INLINE CycleDataType *write_stage(int n);
|
||||
|
||||
INLINE CycleDataType *cheat() const;
|
||||
|
||||
@@ -353,6 +353,24 @@ write_stage(int n) {
|
||||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerDummyImpl::write_stage_upstream
|
||||
// Access: Public
|
||||
// Description: Returns a pointer suitable for writing to the nth
|
||||
// stage of the pipeline. This is for special
|
||||
// applications that need to update the entire pipeline
|
||||
// at once (for instance, to remove an invalid pointer).
|
||||
// This pointer should later be released with
|
||||
// release_write_stage().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CycleData *PipelineCyclerDummyImpl::
|
||||
write_stage_upstream(int n, bool) {
|
||||
TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::write_stage_upstream(int)", " ", TAU_USER);
|
||||
nassertr(n == 0, (CycleData *)NULL);
|
||||
_write_count++;
|
||||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerDummyImpl::elevate_read_stage
|
||||
// Access: Public
|
||||
@@ -370,6 +388,23 @@ elevate_read_stage(int n, const CycleData *pointer) {
|
||||
return write();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerDummyImpl::elevate_read_stage_upstream
|
||||
// Access: Public
|
||||
// Description: Elevates a currently-held read pointer into a write
|
||||
// pointer. This may or may not change the value of the
|
||||
// pointer. It is only valid to do this if this is the
|
||||
// only currently-outstanding read pointer on the
|
||||
// current stage.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CycleData *PipelineCyclerDummyImpl::
|
||||
elevate_read_stage_upstream(int n, const CycleData *pointer, bool) {
|
||||
TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::elevate_read_stage(int, CycleData *)", " ", TAU_USER);
|
||||
nassertr(n == 0, NULL);
|
||||
release_read(pointer);
|
||||
return write();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerDummyImpl::release_write_stage
|
||||
// Access: Public
|
||||
|
||||
@@ -70,7 +70,10 @@ public:
|
||||
INLINE void release_read_stage(int n, const CycleData *pointer) const;
|
||||
INLINE CycleData *write_upstream(bool force_to_0);
|
||||
INLINE CycleData *write_stage(int n);
|
||||
INLINE CycleData *write_stage_upstream(int n, bool force_to_0);
|
||||
INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer);
|
||||
INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer,
|
||||
bool force_to_0);
|
||||
INLINE void release_write_stage(int n, CycleData *pointer);
|
||||
|
||||
INLINE TypeHandle get_parent_type() const;
|
||||
|
||||
@@ -311,6 +311,25 @@ write_stage(int) {
|
||||
#endif // SIMPLE_STRUCT_POINTERS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrivialImpl::write_stage_upstream
|
||||
// Access: Public
|
||||
// Description: Returns a pointer suitable for writing to the nth
|
||||
// stage of the pipeline. This is for special
|
||||
// applications that need to update the entire pipeline
|
||||
// at once (for instance, to remove an invalid pointer).
|
||||
// This pointer should later be released with
|
||||
// release_write_stage().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CycleData *PipelineCyclerTrivialImpl::
|
||||
write_stage_upstream(int, bool) {
|
||||
#ifdef SIMPLE_STRUCT_POINTERS
|
||||
return (CycleData *)this;
|
||||
#else
|
||||
return _data;
|
||||
#endif // SIMPLE_STRUCT_POINTERS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrivialImpl::elevate_read_stage
|
||||
// Access: Public
|
||||
@@ -329,6 +348,24 @@ elevate_read_stage(int, const CycleData *) {
|
||||
#endif // SIMPLE_STRUCT_POINTERS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrivialImpl::elevate_read_stage_upstream
|
||||
// Access: Public
|
||||
// Description: Elevates a currently-held read pointer into a write
|
||||
// pointer. This may or may not change the value of the
|
||||
// pointer. It is only valid to do this if this is the
|
||||
// only currently-outstanding read pointer on the
|
||||
// current stage.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CycleData *PipelineCyclerTrivialImpl::
|
||||
elevate_read_stage_upstream(int, const CycleData *, bool) {
|
||||
#ifdef SIMPLE_STRUCT_POINTERS
|
||||
return (CycleData *)this;
|
||||
#else
|
||||
return _data;
|
||||
#endif // SIMPLE_STRUCT_POINTERS
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrivialImpl::release_write_stage
|
||||
// Access: Public
|
||||
|
||||
@@ -74,7 +74,10 @@ public:
|
||||
INLINE void release_read_stage(int n, const CycleData *pointer) const;
|
||||
INLINE CycleData *write_upstream(bool force_to_0);
|
||||
INLINE CycleData *write_stage(int n);
|
||||
INLINE CycleData *write_stage_upstream(int n, bool force_to_0);
|
||||
INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer);
|
||||
INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer,
|
||||
bool force_to_0);
|
||||
INLINE void release_write_stage(int n, CycleData *pointer);
|
||||
|
||||
INLINE TypeHandle get_parent_type() const;
|
||||
|
||||
@@ -243,6 +243,41 @@ release_read_stage(int n, const CycleData *pointer) const {
|
||||
_lock.release();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::write_upstream
|
||||
// Access: Public
|
||||
// Description: This special variant on write() will automatically
|
||||
// propagate changes back to upstream pipeline stages.
|
||||
// If force_to_0 is false, then it propagates back only
|
||||
// as long as the CycleData pointers are equivalent,
|
||||
// guaranteeing that it does not modify upstream data
|
||||
// (other than the modification that will be performed
|
||||
// by the code that returns this pointer). This is
|
||||
// particularly appropriate for minor updates, where it
|
||||
// doesn't matter much if the update is lost, such as
|
||||
// storing a cached value.
|
||||
//
|
||||
// If force_to_0 is true, then the CycleData pointer for
|
||||
// the current pipeline stage is propagated all the way
|
||||
// back up to stage 0; after this call, there will be
|
||||
// only one CycleData pointer that is duplicated in all
|
||||
// stages between stage 0 and the current stage. This
|
||||
// may undo some recent changes that were made
|
||||
// independently at pipeline stage 0 (or any other
|
||||
// upstream stage). However, it guarantees that the
|
||||
// change that is to be applied at this pipeline stage
|
||||
// will stick. This is slightly dangerous because of
|
||||
// the risk of losing upstream changes; generally, this
|
||||
// should only be done when you are confident that there
|
||||
// are no upstream changes to be lost (for instance, for
|
||||
// an object that has been recently created).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CycleData *PipelineCyclerTrueImpl::
|
||||
write_upstream(bool force_to_0) {
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
return write_stage_upstream(pipeline_stage, force_to_0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::elevate_read_stage
|
||||
// Access: Public
|
||||
@@ -264,6 +299,27 @@ elevate_read_stage(int n, const CycleData *pointer) {
|
||||
return new_pointer;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::elevate_read_stage_upstream
|
||||
// Access: Public
|
||||
// Description: Elevates a currently-held read pointer into a write
|
||||
// pointer. This may or may not change the value of the
|
||||
// pointer. It is only valid to do this if this is the
|
||||
// only currently-outstanding read pointer on the
|
||||
// indicated stage.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CycleData *PipelineCyclerTrueImpl::
|
||||
elevate_read_stage_upstream(int n, const CycleData *pointer, bool force_to_0) {
|
||||
TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::elevate_read_stage(int, const CycleData *)", " ", TAU_USER);
|
||||
#ifdef _DEBUG
|
||||
nassertr(n >= 0 && n < _num_stages, NULL);
|
||||
nassertr(_data[n] == pointer, NULL);
|
||||
#endif
|
||||
CycleData *new_pointer = write_stage_upstream(n, force_to_0);
|
||||
_lock.release();
|
||||
return new_pointer;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::release_write_stage
|
||||
// Access: Public
|
||||
|
||||
@@ -130,39 +130,52 @@ PipelineCyclerTrueImpl::
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::write_upstream
|
||||
// Function: PipelineCyclerTrueImpl::write_stage
|
||||
// Access: Public
|
||||
// Description: This special variant on write() will automatically
|
||||
// propagate changes back to upstream pipeline stages.
|
||||
// If force_to_0 is false, then it propagates back only
|
||||
// as long as the CycleData pointers are equivalent,
|
||||
// guaranteeing that it does not modify upstream data
|
||||
// (other than the modification that will be performed
|
||||
// by the code that returns this pointer). This is
|
||||
// particularly appropriate for minor updates, where it
|
||||
// doesn't matter much if the update is lost, such as
|
||||
// storing a cached value.
|
||||
//
|
||||
// If force_to_0 is true, then the CycleData pointer for
|
||||
// the current pipeline stage is propagated all the way
|
||||
// back up to stage 0; after this call, there will be
|
||||
// only one CycleData pointer that is duplicated in all
|
||||
// stages between stage 0 and the current stage. This
|
||||
// may undo some recent changes that were made
|
||||
// independently at pipeline stage 0 (or any other
|
||||
// upstream stage). However, it guarantees that the
|
||||
// change that is to be applied at this pipeline stage
|
||||
// will stick. This is slightly dangerous because of
|
||||
// the risk of losing upstream changes; generally, this
|
||||
// should only be done when you are confident that there
|
||||
// are no upstream changes to be lost (for instance, for
|
||||
// an object that has been recently created).
|
||||
// Description: Returns a pointer suitable for writing to the nth
|
||||
// stage of the pipeline. This is for special
|
||||
// applications that need to update the entire pipeline
|
||||
// at once (for instance, to remove an invalid pointer).
|
||||
// This pointer should later be released with
|
||||
// release_write_stage().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *PipelineCyclerTrueImpl::
|
||||
write_upstream(bool force_to_0) {
|
||||
write_stage(int pipeline_stage) {
|
||||
_lock.lock();
|
||||
|
||||
#ifndef NDEBUG
|
||||
nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) {
|
||||
_lock.release();
|
||||
return NULL;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
CycleData *old_data = _data[pipeline_stage];
|
||||
|
||||
if (old_data->get_ref_count() != 1) {
|
||||
// Copy-on-write.
|
||||
_data[pipeline_stage] = old_data->make_copy();
|
||||
|
||||
// Now we have differences between some of the data pointers, so
|
||||
// we're "dirty". Mark it so.
|
||||
if (!_dirty) {
|
||||
_pipeline->add_dirty_cycler(this);
|
||||
}
|
||||
}
|
||||
|
||||
return _data[pipeline_stage];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::write_stage_upstream
|
||||
// Access: Public
|
||||
// Description: This special variant on write_stage() will
|
||||
// automatically propagate changes back to upstream
|
||||
// pipeline stages. See write_upstream().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *PipelineCyclerTrueImpl::
|
||||
write_stage_upstream(int pipeline_stage, bool force_to_0) {
|
||||
_lock.lock();
|
||||
|
||||
int pipeline_stage = Thread::get_current_pipeline_stage();
|
||||
|
||||
#ifndef NDEBUG
|
||||
nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) {
|
||||
@@ -218,43 +231,6 @@ write_upstream(bool force_to_0) {
|
||||
return _data[pipeline_stage];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::write_stage
|
||||
// Access: Public
|
||||
// Description: Returns a pointer suitable for writing to the nth
|
||||
// stage of the pipeline. This is for special
|
||||
// applications that need to update the entire pipeline
|
||||
// at once (for instance, to remove an invalid pointer).
|
||||
// This pointer should later be released with
|
||||
// release_write_stage().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *PipelineCyclerTrueImpl::
|
||||
write_stage(int pipeline_stage) {
|
||||
_lock.lock();
|
||||
|
||||
#ifndef NDEBUG
|
||||
nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) {
|
||||
_lock.release();
|
||||
return NULL;
|
||||
}
|
||||
#endif // NDEBUG
|
||||
|
||||
CycleData *old_data = _data[pipeline_stage];
|
||||
|
||||
if (old_data->get_ref_count() != 1) {
|
||||
// Copy-on-write.
|
||||
_data[pipeline_stage] = old_data->make_copy();
|
||||
|
||||
// Now we have differences between some of the data pointers, so
|
||||
// we're "dirty". Mark it so.
|
||||
if (!_dirty) {
|
||||
_pipeline->add_dirty_cycler(this);
|
||||
}
|
||||
}
|
||||
|
||||
return _data[pipeline_stage];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PipelineCyclerTrueImpl::cycle
|
||||
// Access: Private
|
||||
|
||||
@@ -73,9 +73,11 @@ public:
|
||||
INLINE int get_num_stages();
|
||||
INLINE const CycleData *read_stage(int n) const;
|
||||
INLINE void release_read_stage(int n, const CycleData *pointer) const;
|
||||
CycleData *write_upstream(bool force_to_0);
|
||||
INLINE CycleData *write_upstream(bool force_to_0);
|
||||
CycleData *write_stage(int pipeline_stage);
|
||||
CycleData *write_stage_upstream(int pipeline_stage, bool force_to_0);
|
||||
INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer);
|
||||
INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer, bool force_to_0);
|
||||
INLINE void release_write_stage(int n, CycleData *pointer);
|
||||
|
||||
INLINE TypeHandle get_parent_type() const;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
BEGIN_EXCLUDE_LIST
|
||||
void *ThreadPosixImpl::root_func#
|
||||
void *ThreadWin32Impl::root_func#
|
||||
END_EXCLUDE_LIST
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
// Filename: test_delete.cxx
|
||||
// Created by: drose (18Apr06)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "thread.h"
|
||||
#include "pmutex.h"
|
||||
#include "mutexHolder.h"
|
||||
#include "deletedChain.h"
|
||||
|
||||
// This is the number of passes to make per thread.
|
||||
static const int num_passes = 100;
|
||||
|
||||
// This is the number of doobers to allocate in each pass.
|
||||
static const int num_doobers_per_pass = 1000000;
|
||||
|
||||
// This is the max number to allocate in each chunk.
|
||||
static const int max_doobers_per_chunk = 1000;
|
||||
|
||||
// The number of threads to spawn.
|
||||
static const int number_of_threads = 4;
|
||||
|
||||
#ifdef WIN32_VC
|
||||
static int last_rand = 0;
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
Mutex rand_mutex;
|
||||
|
||||
static double
|
||||
random_f(double max) {
|
||||
MutexHolder l(rand_mutex);
|
||||
int i = rand();
|
||||
#ifdef WIN32_VC
|
||||
last_rand = i;
|
||||
#endif /* __WIN32__ */
|
||||
return max * (double)i / (double)RAND_MAX;
|
||||
}
|
||||
|
||||
#define OUTPUT(stuff) { \
|
||||
MutexHolder holder(Mutex::_notify_mutex); \
|
||||
stuff; \
|
||||
}
|
||||
|
||||
class Doober {
|
||||
public:
|
||||
Doober(int counter) : _counter(counter) {
|
||||
}
|
||||
~Doober() {
|
||||
nassertv(_counter != -1);
|
||||
_counter = -1;
|
||||
}
|
||||
ALLOC_DELETED_CHAIN(Doober);
|
||||
|
||||
int _counter;
|
||||
};
|
||||
typedef pvector<Doober *> Doobers;
|
||||
|
||||
|
||||
class MyThread : public Thread {
|
||||
public:
|
||||
MyThread(const string &name) : Thread(name, name)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void
|
||||
thread_main() {
|
||||
OUTPUT(nout << *this << " beginning.\n");
|
||||
|
||||
#ifdef WIN32_VC
|
||||
rand_mutex.lock();
|
||||
srand(last_rand);
|
||||
rand_mutex.release();
|
||||
random_f(1.0);
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
Doobers doobers;
|
||||
|
||||
for (int i = 0; i < num_passes; ++i) {
|
||||
int counter = 0;
|
||||
|
||||
while (counter < num_doobers_per_pass) {
|
||||
int num_alloc = (int)random_f(max_doobers_per_chunk);
|
||||
for (int i = 0; i < num_alloc; ++i) {
|
||||
doobers.push_back(new Doober(++counter));
|
||||
}
|
||||
int num_del = (int)random_f(max_doobers_per_chunk);
|
||||
num_del = min(num_del, (int)doobers.size());
|
||||
|
||||
for (int j = 0; j < num_del; ++j) {
|
||||
assert(!doobers.empty());
|
||||
delete doobers.back();
|
||||
doobers.pop_back();
|
||||
}
|
||||
}
|
||||
OUTPUT(nout << get_name() << " has " << doobers.size() << " doobers.\n");
|
||||
}
|
||||
|
||||
OUTPUT(nout << *this << " ending.\n");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
OUTPUT(nout << "Making " << number_of_threads << " threads.\n");
|
||||
|
||||
typedef pvector< PT(MyThread) > Threads;
|
||||
Threads threads;
|
||||
|
||||
PT(MyThread) thread = new MyThread("a");
|
||||
threads.push_back(thread);
|
||||
thread->start(TP_normal, true, true);
|
||||
|
||||
for (int i = 1; i < number_of_threads; ++i) {
|
||||
char name = 'a' + i;
|
||||
PT(MyThread) thread = new MyThread(string(1, name));
|
||||
threads.push_back(thread);
|
||||
thread->start(TP_normal, true, true);
|
||||
}
|
||||
|
||||
// Now join all the threads.
|
||||
Threads::iterator ti;
|
||||
for (ti = threads.begin(); ti != threads.end(); ++ti) {
|
||||
(*ti)->join();
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -35,8 +35,6 @@
|
||||
static int last_rand = 0;
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#define PRINTMSG(x) { MutexHolder l(Mutex::_notify_mutex); x << flush; }
|
||||
|
||||
Mutex rand_mutex;
|
||||
|
||||
static double random_f(double max)
|
||||
@@ -49,6 +47,8 @@ static double random_f(double max)
|
||||
return max * (double)i / (double)RAND_MAX;
|
||||
}
|
||||
|
||||
#define PRINTMSG(x) { MutexHolder l(Mutex::_notify_mutex); x << flush; }
|
||||
|
||||
// n philosophers sharing n chopsticks. Philosophers are poor folk and can't
|
||||
// afford luxuries like 2 chopsticks per person.
|
||||
#define N_DINERS 5
|
||||
|
||||
@@ -84,9 +84,15 @@ start(ThreadPriority priority, bool global, bool joinable) {
|
||||
_detached = true;
|
||||
}
|
||||
|
||||
int result = pthread_attr_setstacksize(&attr, thread_stack_size);
|
||||
if (result != 0) {
|
||||
thread_cat.warning()
|
||||
<< "Unable to set stack size.\n";
|
||||
}
|
||||
|
||||
// Ensure the thread has "system" scope, which should ensure it can
|
||||
// run in parallel with other threads.
|
||||
int result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
||||
result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
||||
if (result != 0) {
|
||||
thread_cat.warning()
|
||||
<< "Unable to set system scope.\n";
|
||||
|
||||
@@ -146,45 +146,50 @@ join() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DWORD ThreadWin32Impl::
|
||||
root_func(LPVOID data) {
|
||||
ThreadWin32Impl *self = (ThreadWin32Impl *)data;
|
||||
BOOL result = TlsSetValue(_pt_ptr_index, self->_parent_obj);
|
||||
nassertr(result, 1);
|
||||
|
||||
TAU_REGISTER_THREAD();
|
||||
{
|
||||
self->_mutex.lock();
|
||||
nassertd(self->_status == S_start_called) {
|
||||
TAU_PROFILE("void ThreadPosixImpl::root_func()", " ", TAU_USER);
|
||||
|
||||
ThreadWin32Impl *self = (ThreadWin32Impl *)data;
|
||||
BOOL result = TlsSetValue(_pt_ptr_index, self->_parent_obj);
|
||||
nassertr(result, 1);
|
||||
|
||||
{
|
||||
self->_mutex.lock();
|
||||
nassertd(self->_status == S_start_called) {
|
||||
self->_mutex.release();
|
||||
return 1;
|
||||
}
|
||||
self->_status = S_running;
|
||||
self->_cv.signal();
|
||||
self->_mutex.release();
|
||||
return 1;
|
||||
}
|
||||
self->_status = S_running;
|
||||
self->_cv.signal();
|
||||
self->_mutex.release();
|
||||
}
|
||||
|
||||
self->_parent_obj->thread_main();
|
||||
|
||||
if (thread_cat.is_debug()) {
|
||||
thread_cat.debug()
|
||||
<< "Terminating thread " << self->_parent_obj->get_name()
|
||||
<< ", count = " << self->_parent_obj->get_ref_count() << "\n";
|
||||
}
|
||||
|
||||
{
|
||||
self->_mutex.lock();
|
||||
nassertd(self->_status == S_running) {
|
||||
|
||||
self->_parent_obj->thread_main();
|
||||
|
||||
if (thread_cat.is_debug()) {
|
||||
thread_cat.debug()
|
||||
<< "Terminating thread " << self->_parent_obj->get_name()
|
||||
<< ", count = " << self->_parent_obj->get_ref_count() << "\n";
|
||||
}
|
||||
|
||||
{
|
||||
self->_mutex.lock();
|
||||
nassertd(self->_status == S_running) {
|
||||
self->_mutex.release();
|
||||
return 1;
|
||||
}
|
||||
self->_status = S_finished;
|
||||
self->_cv.signal();
|
||||
self->_mutex.release();
|
||||
return 1;
|
||||
}
|
||||
self->_status = S_finished;
|
||||
self->_cv.signal();
|
||||
self->_mutex.release();
|
||||
|
||||
// Now drop the parent object reference that we grabbed in start().
|
||||
// This might delete the parent object, and in turn, delete the
|
||||
// ThreadWin32Impl object.
|
||||
unref_delete(self->_parent_obj);
|
||||
}
|
||||
|
||||
// Now drop the parent object reference that we grabbed in start().
|
||||
// This might delete the parent object, and in turn, delete the
|
||||
// ThreadWin32Impl object.
|
||||
unref_delete(self->_parent_obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@ make_collector_with_name(int parent_index, const string &name) {
|
||||
// initialize_collector_def(this, collector->_def);
|
||||
|
||||
// We need one PerThreadData for each thread.
|
||||
while (collector->_per_thread.size() < _num_threads) {
|
||||
while ((int)collector->_per_thread.size() < _num_threads) {
|
||||
collector->_per_thread.push_back(PerThreadData());
|
||||
}
|
||||
add_collector(collector);
|
||||
@@ -787,8 +787,8 @@ add_level(int collector_index, int thread_index, float increment) {
|
||||
float PStatClient::
|
||||
get_level(int collector_index, int thread_index) const {
|
||||
#ifdef _DEBUG
|
||||
nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
|
||||
nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
|
||||
nassertr(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors), 0.0f);
|
||||
nassertr(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads), 0.0f);
|
||||
#endif
|
||||
|
||||
Collector *collector = get_collector_ptr(collector_index);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#include "datagramInputFile.h"
|
||||
#include "numeric_types.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "profileTimer.h"
|
||||
@@ -24,7 +24,6 @@
|
||||
#include "config_express.h"
|
||||
#include "virtualFileSystem.h"
|
||||
#include "streamReader.h"
|
||||
#include "datagramInputFile.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DatagramInputFile::open
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
config_windisplay.cxx winGraphicsPipe.cxx
|
||||
|
||||
#define SOURCES \
|
||||
winGraphicsWindow.cxx $[INCLUDED_SOURCES] $[INSTALL_HEADERS]
|
||||
winGraphicsWindow.cxx $[INSTALL_HEADERS]
|
||||
|
||||
#define WIN_SYS_LIBS Imm32.lib winmm.lib kernel32.lib oldnames.lib user32.lib gdi32.lib
|
||||
|
||||
|
||||
@@ -336,7 +336,7 @@ convert_triangles(const GeomVertexData *vertex_data,
|
||||
Vertexf vertex = reader.get_data3f();
|
||||
egg_vert.set_pos(LCAST(double, vertex * net_mat));
|
||||
|
||||
if (vertex_data->has_normal()) {
|
||||
if (vertex_data->has_column(InternalName::get_normal())) {
|
||||
reader.set_column(InternalName::get_normal());
|
||||
Normalf normal = reader.get_data3f();
|
||||
egg_vert.set_normal(LCAST(double, normal * net_mat));
|
||||
@@ -346,7 +346,7 @@ convert_triangles(const GeomVertexData *vertex_data,
|
||||
|
||||
} else if (!has_color_off) {
|
||||
Colorf color(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
if (vertex_data->has_color()) {
|
||||
if (vertex_data->has_column(InternalName::get_color())) {
|
||||
reader.set_column(InternalName::get_color());
|
||||
color = reader.get_data4f();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user