mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 02:42:49 -04:00
vertex buffers?
This commit is contained in:
parent
01232c9e6f
commit
85b019feda
@ -20,6 +20,7 @@
|
||||
#include "graphicsStateGuardian.h"
|
||||
#include "config_display.h"
|
||||
#include "textureContext.h"
|
||||
#include "dataContext.h"
|
||||
#include "renderBuffer.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
@ -46,6 +47,8 @@ PStatCollector GraphicsStateGuardian::_total_texusage_pcollector("Texture usage"
|
||||
PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_pcollector("Prepared Geoms");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_pcollector("Prepared Geoms:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffers_pcollector("Prepared Bufferss");
|
||||
PStatCollector GraphicsStateGuardian::_active_buffers_pcollector("Prepared Bufferss:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_node_pcollector("Prepared GeomNodes");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_node_pcollector("Prepared GeomNodes:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory");
|
||||
@ -267,6 +270,28 @@ void GraphicsStateGuardian::
|
||||
release_geom(GeomContext *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::prepare_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Prepares the indicated data array for retained-mode
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *GraphicsStateGuardian::
|
||||
prepare_data(qpGeomVertexArrayData *) {
|
||||
return (DataContext *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::release_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Frees the resources previously allocated via a call
|
||||
// to prepare_data(), including deleting the DataContext
|
||||
// itself, if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
release_data(DataContext *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_geom_munger
|
||||
// Access: Public, Virtual
|
||||
@ -1458,7 +1483,7 @@ add_to_texture_record(TextureContext *tc) {
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated Geom has been drawn this
|
||||
// frame. This function is only used to update the
|
||||
// PStats current_texmem collector; it gets compiled out
|
||||
// PStats active_geom collector; it gets compiled out
|
||||
// if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
@ -1469,6 +1494,23 @@ add_to_geom_record(GeomContext *gc) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_data_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been drawn
|
||||
// this frame. This function is only used to update the
|
||||
// PStats active_buffers collector; it gets compiled out
|
||||
// if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_data_record(DataContext *dc) {
|
||||
if (PStatClient::is_connected()) {
|
||||
if (dc != (DataContext *)NULL && _current_datas.insert(dc).second) {
|
||||
_active_buffers_pcollector.add_level(dc->_data->get_num_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DO_PSTATS
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -107,6 +107,9 @@ public:
|
||||
virtual GeomContext *prepare_geom(Geom *geom);
|
||||
virtual void release_geom(GeomContext *gc);
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data);
|
||||
virtual void release_data(DataContext *gc);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
virtual void set_state_and_transform(const RenderState *state,
|
||||
@ -223,9 +226,11 @@ protected:
|
||||
void init_frame_pstats();
|
||||
void add_to_texture_record(TextureContext *tc);
|
||||
void add_to_geom_record(GeomContext *gc);
|
||||
void add_to_data_record(DataContext *dc);
|
||||
|
||||
pset<TextureContext *> _current_textures;
|
||||
pset<GeomContext *> _current_geoms;
|
||||
pset<DataContext *> _current_datas;
|
||||
#else
|
||||
INLINE void init_frame_pstats() { }
|
||||
INLINE void add_to_texture_record(TextureContext *) { }
|
||||
@ -308,6 +313,8 @@ public:
|
||||
static PStatCollector _active_texusage_pcollector;
|
||||
static PStatCollector _total_geom_pcollector;
|
||||
static PStatCollector _active_geom_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
static PStatCollector _active_buffers_pcollector;
|
||||
static PStatCollector _total_geom_node_pcollector;
|
||||
static PStatCollector _active_geom_node_pcollector;
|
||||
static PStatCollector _total_texmem_pcollector;
|
||||
|
@ -2684,7 +2684,7 @@ draw_triangles(const qpGeomTriangles *primitive) {
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_flat_first_vertices(),
|
||||
D3DFMT_INDEX16,
|
||||
_vertex_data->get_array_data(0),
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
|
||||
@ -2703,7 +2703,7 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
CPTA_ushort maxs = primitive->get_maxs();
|
||||
nassertv(mins.size() == ends.size() && maxs.size() == ends.size());
|
||||
|
||||
CPTA_uchar array_data = _vertex_data->get_array_data(0);
|
||||
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
|
||||
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
|
@ -1925,7 +1925,8 @@ make_vertex_data(EggVertexPool *vertex_pool, const LMatrix4d &transform) {
|
||||
qpGeomVertexFormat::register_format(new qpGeomVertexFormat(array_format));
|
||||
|
||||
// Now create a new GeomVertexData using the indicated format.
|
||||
PT(qpGeomVertexData) vertex_data = new qpGeomVertexData(format);
|
||||
PT(qpGeomVertexData) vertex_data =
|
||||
new qpGeomVertexData(format, qpGeomVertexArrayData::UH_static);
|
||||
|
||||
// And fill the data from the vertex pool.
|
||||
EggVertexPool::const_iterator vi;
|
||||
|
@ -632,7 +632,9 @@ load_default_model(const NodePath &parent) {
|
||||
|
||||
if (use_qpgeom) {
|
||||
// New, experimental Geom code.
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData(qpGeomVertexFormat::get_v3n3cpt2());
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
(qpGeomVertexFormat::get_v3n3cpt2(),
|
||||
qpGeomVertexArrayData::UH_static);
|
||||
qpGeomVertexIterator vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexIterator normal(vdata, InternalName::get_normal());
|
||||
qpGeomVertexIterator color(vdata, InternalName::get_color());
|
||||
@ -1057,7 +1059,9 @@ load_image_as_model(const Filename &filename) {
|
||||
}
|
||||
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData(qpGeomVertexFormat::get_v3t2());
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
(qpGeomVertexFormat::get_v3t2(),
|
||||
qpGeomVertexArrayData::UH_static);
|
||||
qpGeomVertexIterator vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexIterator texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
|
@ -19,6 +19,9 @@
|
||||
glstuff_src.cxx \
|
||||
glstuff_src.h \
|
||||
glstuff_undef_src.h \
|
||||
glDataContext_src.cxx \
|
||||
glDataContext_src.I \
|
||||
glDataContext_src.h \
|
||||
glGeomContext_src.cxx \
|
||||
glGeomContext_src.I \
|
||||
glGeomContext_src.h \
|
||||
|
30
panda/src/glstuff/glDataContext_src.I
Normal file
30
panda/src/glstuff/glDataContext_src.I
Normal file
@ -0,0 +1,30 @@
|
||||
// Filename: glDataContext_src.I
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(DataContext)::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(DataContext)::
|
||||
CLP(DataContext)(qpGeomVertexArrayData *data) :
|
||||
DataContext(data)
|
||||
{
|
||||
_index = 0;
|
||||
}
|
19
panda/src/glstuff/glDataContext_src.cxx
Normal file
19
panda/src/glstuff/glDataContext_src.cxx
Normal file
@ -0,0 +1,19 @@
|
||||
// Filename: glDataContext_src.cxx
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeHandle CLP(DataContext)::_type_handle;
|
52
panda/src/glstuff/glDataContext_src.h
Normal file
52
panda/src/glstuff/glDataContext_src.h
Normal file
@ -0,0 +1,52 @@
|
||||
// Filename: glDataContext_src.h
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "dataContext.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLDataContext
|
||||
// Description :
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(DataContext) : public DataContext {
|
||||
public:
|
||||
INLINE CLP(DataContext)(qpGeomVertexArrayData *data);
|
||||
|
||||
// This is the GL "name" of the data object.
|
||||
GLuint _index;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
DataContext::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "DataContext",
|
||||
DataContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "glDataContext_src.I"
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "vector_string.h"
|
||||
#include "string_utils.h"
|
||||
#include "pnmImage.h"
|
||||
#include "config_gobj.h"
|
||||
#ifdef DO_PSTATS
|
||||
#include "pStatTimer.h"
|
||||
#endif
|
||||
@ -455,6 +456,47 @@ reset() {
|
||||
_glActiveTexture = null_glActiveTexture;
|
||||
}
|
||||
|
||||
_supports_buffers = false;
|
||||
|
||||
if (is_at_least_version(1, 5)) {
|
||||
_supports_buffers = true;
|
||||
|
||||
_glGenBuffers = (PFNGLGENBUFFERSPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "GenBuffers");
|
||||
_glBindBuffer = (PFNGLBINDBUFFERPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "BindBuffer");
|
||||
_glBufferData = (PFNGLBUFFERDATAPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "BufferData");
|
||||
_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "BufferSubData");
|
||||
_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "DeleteBuffers");
|
||||
|
||||
} else if (has_extension("GL_ARB_vertex_buffer_object")) {
|
||||
_supports_buffers = true;
|
||||
|
||||
_glGenBuffers = (PFNGLGENBUFFERSPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "GenBuffersARB");
|
||||
_glBindBuffer = (PFNGLBINDBUFFERPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "BindBufferARB");
|
||||
_glBufferData = (PFNGLBUFFERDATAPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "BufferDataARB");
|
||||
_glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "BufferSubDataARB");
|
||||
_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "DeleteBuffersARB");
|
||||
}
|
||||
|
||||
if (_supports_buffers) {
|
||||
if (_glGenBuffers == NULL || _glBindBuffer == NULL ||
|
||||
_glBufferData == NULL || _glBufferSubData == NULL ||
|
||||
_glDeleteBuffers == NULL) {
|
||||
GLCAT.warning()
|
||||
<< "Buffers advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
|
||||
_supports_buffers = false;
|
||||
}
|
||||
}
|
||||
|
||||
_glBlendEquation = NULL;
|
||||
if (has_extension("GL_EXT_blend_minmax") || is_at_least_version(1, 2)) {
|
||||
_glBlendEquation = (PFNGLBLENDEQUATIONPROC)
|
||||
@ -1984,7 +2026,7 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
||||
}
|
||||
nassertr(_vertex_data != (qpGeomVertexData *)NULL, false);
|
||||
|
||||
CPTA_uchar array_data;
|
||||
const qpGeomVertexArrayData *array_data;
|
||||
int num_components;
|
||||
qpGeomVertexDataType::NumericType numeric_type;
|
||||
int start;
|
||||
@ -1993,8 +2035,9 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
||||
if (_vertex_data->get_array_info(InternalName::get_vertex(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
GLP(VertexPointer)(num_components, get_numeric_type(numeric_type),
|
||||
stride, array_data + start);
|
||||
stride, client_pointer + start);
|
||||
GLP(EnableClientState)(GL_VERTEX_ARRAY);
|
||||
} else {
|
||||
// No vertex data? No primitives!
|
||||
@ -2005,8 +2048,9 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
||||
_vertex_data->get_array_info(InternalName::get_normal(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
GLP(NormalPointer)(get_numeric_type(numeric_type), stride,
|
||||
array_data + start);
|
||||
client_pointer + start);
|
||||
GLP(EnableClientState)(GL_NORMAL_ARRAY);
|
||||
} else {
|
||||
GLP(DisableClientState)(GL_NORMAL_ARRAY);
|
||||
@ -2016,13 +2060,14 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
||||
if (_vertex_data->get_array_info(InternalName::get_color(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
if (numeric_type == qpGeomVertexDataType::NT_packed_argb) {
|
||||
// Temporary hack--this will probably reverse r and b.
|
||||
GLP(ColorPointer)(4, GL_UNSIGNED_BYTE, stride, array_data + start);
|
||||
GLP(ColorPointer)(4, GL_UNSIGNED_BYTE, stride, client_pointer + start);
|
||||
|
||||
} else {
|
||||
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
|
||||
stride, array_data + start);
|
||||
stride, client_pointer + start);
|
||||
}
|
||||
GLP(EnableClientState)(GL_COLOR_ARRAY);
|
||||
|
||||
@ -2040,8 +2085,9 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
||||
_vertex_data->get_array_info(InternalName::get_texcoord(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
const unsigned char *client_pointer = setup_array_data(array_data);
|
||||
GLP(TexCoordPointer)(num_components, get_numeric_type(numeric_type),
|
||||
stride, array_data + start);
|
||||
stride, client_pointer + start);
|
||||
GLP(EnableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||
} else {
|
||||
GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||
@ -2287,6 +2333,130 @@ release_geom(GeomContext *gc) {
|
||||
delete ggc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::prepare_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Creates a new retained-mode representation of the
|
||||
// given data, and returns a newly-allocated
|
||||
// DataContext pointer to reference it. It is the
|
||||
// responsibility of the calling function to later
|
||||
// call release_data() with this same pointer (which
|
||||
// will also delete the pointer).
|
||||
//
|
||||
// This function should not be called directly to
|
||||
// prepare a data. Instead, call Data::prepare().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *CLP(GraphicsStateGuardian)::
|
||||
prepare_data(qpGeomVertexArrayData *data) {
|
||||
cerr << "prepare_data\n";
|
||||
|
||||
if (_supports_buffers) {
|
||||
CLP(DataContext) *gdc = new CLP(DataContext)(data);
|
||||
_glGenBuffers(1, &gdc->_index);
|
||||
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
_glBufferData(GL_ARRAY_BUFFER, gdc->_data->get_num_bytes(),
|
||||
gdc->_data->get_data(),
|
||||
get_usage(gdc->_data->get_usage_hint()));
|
||||
gdc->_modified = gdc->_data->get_modified();
|
||||
|
||||
report_my_gl_errors();
|
||||
return gdc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::apply_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Makes the data the currently available data for
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
apply_data(DataContext *dc) {
|
||||
cerr << "apply_data\n";
|
||||
|
||||
nassertv(_supports_buffers);
|
||||
|
||||
CLP(DataContext) *gdc = DCAST(CLP(DataContext), dc);
|
||||
|
||||
add_to_data_record(gdc);
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
|
||||
if (gdc->_modified != gdc->_data->get_modified()) {
|
||||
_glBufferSubData(GL_ARRAY_BUFFER, 0, gdc->_data->get_num_bytes(),
|
||||
gdc->_data->get_data());
|
||||
|
||||
gdc->_modified = gdc->_data->get_modified();
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::release_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Frees the GL resources previously allocated for the
|
||||
// data. This function should never be called
|
||||
// directly; instead, call Data::release() (or simply
|
||||
// let the Data destruct).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
release_data(DataContext *dc) {
|
||||
cerr << "release_data\n";
|
||||
|
||||
nassertv(_supports_buffers);
|
||||
|
||||
CLP(DataContext) *gdc = DCAST(CLP(DataContext), dc);
|
||||
|
||||
_glDeleteBuffers(1, &gdc->_index);
|
||||
report_my_gl_errors();
|
||||
|
||||
gdc->_index = 0;
|
||||
|
||||
delete gdc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::setup_array_data
|
||||
// Access: Public
|
||||
// Description: Internal function to bind a buffer object for the
|
||||
// indicated data array, if appropriate, or to unbind a
|
||||
// buffer object if it should be rendered from client
|
||||
// memory.
|
||||
//
|
||||
// If the buffer object is bound, this function returns
|
||||
// NULL (reprsenting 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 qpGeomVertexArrayData *data) {
|
||||
if (!_supports_buffers) {
|
||||
// No support for buffer objects; always render from client.
|
||||
return data->get_data();
|
||||
}
|
||||
if (!vertex_buffers ||
|
||||
data->get_usage_hint() == qpGeomVertexArrayData::UH_client) {
|
||||
// The array specifies client rendering only, or buffer objects
|
||||
// are configured off.
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
return data->get_data();
|
||||
}
|
||||
|
||||
// Prepare the buffer object and bind it.
|
||||
DataContext *dc = ((qpGeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(dc != (DataContext *)NULL, data->get_data());
|
||||
|
||||
CLP(DataContext) *gdc = DCAST(CLP(DataContext), dc);
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int logs[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
|
||||
4096, 0 };
|
||||
@ -4406,6 +4576,32 @@ get_blend_func(ColorBlendAttrib::Operand operand) {
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::get_usage
|
||||
// Access: Public, Static
|
||||
// Description: Maps from UsageHint to the GL symbol.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GLenum CLP(GraphicsStateGuardian)::
|
||||
get_usage(qpGeomVertexArrayData::UsageHint usage_hint) {
|
||||
switch (usage_hint) {
|
||||
case qpGeomVertexArrayData::UH_stream:
|
||||
return GL_STREAM_DRAW;
|
||||
|
||||
case qpGeomVertexArrayData::UH_static:
|
||||
return GL_STATIC_DRAW;
|
||||
|
||||
case qpGeomVertexArrayData::UH_dynamic:
|
||||
return GL_DYNAMIC_DRAW;
|
||||
|
||||
case qpGeomVertexArrayData::UH_client:
|
||||
break;
|
||||
}
|
||||
|
||||
GLCAT.error()
|
||||
<< "Unexpected usage_hint " << (int)usage_hint << endl;
|
||||
return GL_STATIC_DRAW;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::print_gfx_visual
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "graphicsWindow.h"
|
||||
#include "pset.h"
|
||||
#include "pmap.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#ifdef HAVE_CGGL
|
||||
#include "cgShader.h"
|
||||
#endif
|
||||
@ -103,6 +104,11 @@ public:
|
||||
virtual GeomContext *prepare_geom(Geom *geom);
|
||||
virtual void release_geom(GeomContext *gc);
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data);
|
||||
virtual void apply_data(DataContext *dc);
|
||||
virtual void release_data(DataContext *dc);
|
||||
const unsigned char *setup_array_data(const qpGeomVertexArrayData *data);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
virtual void framebuffer_copy_to_texture
|
||||
@ -236,6 +242,7 @@ protected:
|
||||
static GLenum get_fog_mode_type(Fog::Mode m);
|
||||
static GLenum get_blend_equation_type(ColorBlendAttrib::Mode mode);
|
||||
static GLenum get_blend_func(ColorBlendAttrib::Operand operand);
|
||||
static GLenum get_usage(qpGeomVertexArrayData::UsageHint usage_hint);
|
||||
|
||||
static CPT(RenderState) get_untextured_state();
|
||||
static CPT(RenderState) get_smooth_state();
|
||||
@ -326,6 +333,13 @@ public:
|
||||
PFNGLACTIVETEXTUREPROC _glActiveTexture;
|
||||
PFNGLMULTITEXCOORD2FVPROC _glMultiTexCoord2fv;
|
||||
|
||||
bool _supports_buffers;
|
||||
PFNGLGENBUFFERSPROC _glGenBuffers;
|
||||
PFNGLBINDBUFFERPROC _glBindBuffer;
|
||||
PFNGLBUFFERDATAPROC _glBufferData;
|
||||
PFNGLBUFFERSUBDATAPROC _glBufferSubData;
|
||||
PFNGLDELETEBUFFERSPROC _glDeleteBuffers;
|
||||
|
||||
PFNGLBLENDEQUATIONPROC _glBlendEquation;
|
||||
PFNGLBLENDCOLORPROC _glBlendColor;
|
||||
|
||||
|
@ -63,6 +63,7 @@ void CLP(init_classes)() {
|
||||
CLP(GraphicsStateGuardian)::init_type();
|
||||
CLP(TextureContext)::init_type();
|
||||
CLP(GeomContext)::init_type();
|
||||
CLP(DataContext)::init_type();
|
||||
|
||||
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||
ps->add_system(GLSYSTEM_NAME);
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "glmisc_src.cxx"
|
||||
#include "glTextureContext_src.cxx"
|
||||
#include "glDataContext_src.cxx"
|
||||
#include "glGeomContext_src.cxx"
|
||||
#include "glGeomMunger_src.cxx"
|
||||
#include "glCgShaderContext_src.cxx"
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "glmisc_src.h"
|
||||
#include "glTextureContext_src.h"
|
||||
#include "glDataContext_src.h"
|
||||
#include "glGeomContext_src.h"
|
||||
#include "glGeomMunger_src.h"
|
||||
#include "glCgShaderContext_src.h"
|
||||
|
@ -11,7 +11,9 @@
|
||||
|
||||
#define SOURCES \
|
||||
boundedObject.I boundedObject.h \
|
||||
config_gobj.h drawable.h \
|
||||
config_gobj.h \
|
||||
dataContext.I dataContext.h \
|
||||
drawable.h \
|
||||
geom.I geom.h \
|
||||
geomContext.I geomContext.h \
|
||||
geomLine.h geomLinestrip.h geomPoint.h geomPolygon.h \
|
||||
@ -23,6 +25,7 @@
|
||||
qpgeomTriangles.h \
|
||||
qpgeomTristrips.h \
|
||||
qpgeomTrifans.h \
|
||||
qpgeomVertexArrayData.h qpgeomVertexArrayData.I \
|
||||
qpgeomVertexArrayFormat.h qpgeomVertexArrayFormat.I \
|
||||
qpgeomVertexCacheManager.h qpgeomVertexCacheManager.I \
|
||||
qpgeomVertexData.h qpgeomVertexData.I \
|
||||
@ -44,7 +47,9 @@
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
boundedObject.cxx \
|
||||
config_gobj.cxx drawable.cxx geom.cxx \
|
||||
config_gobj.cxx \
|
||||
dataContext.cxx \
|
||||
drawable.cxx geom.cxx \
|
||||
geomContext.cxx \
|
||||
geomLine.cxx geomLinestrip.cxx geomPoint.cxx geomPolygon.cxx \
|
||||
geomQuad.cxx geomSphere.cxx geomSprite.cxx geomTri.cxx \
|
||||
@ -55,6 +60,7 @@
|
||||
qpgeomTriangles.cxx \
|
||||
qpgeomTristrips.cxx \
|
||||
qpgeomTrifans.cxx \
|
||||
qpgeomVertexArrayData.cxx \
|
||||
qpgeomVertexArrayFormat.cxx \
|
||||
qpgeomVertexCacheManager.cxx \
|
||||
qpgeomVertexData.cxx \
|
||||
@ -73,6 +79,7 @@
|
||||
#define INSTALL_HEADERS \
|
||||
boundedObject.I boundedObject.h \
|
||||
config_gobj.h \
|
||||
dataContext.I dataContext.h \
|
||||
drawable.h geom.I geom.h \
|
||||
textureContext.I textureContext.h \
|
||||
geomLine.h \
|
||||
@ -85,6 +92,7 @@
|
||||
qpgeomTriangles.h \
|
||||
qpgeomTristrips.h \
|
||||
qpgeomTrifans.h \
|
||||
qpgeomVertexArrayData.h qpgeomVertexArrayData.I \
|
||||
qpgeomVertexArrayFormat.h qpgeomVertexArrayFormat.I \
|
||||
qpgeomVertexCacheManager.h qpgeomVertexCacheManager.I \
|
||||
qpgeomVertexData.h qpgeomVertexData.I \
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomTrifans.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
@ -38,6 +39,9 @@
|
||||
#include "lens.h"
|
||||
#include "texture.h"
|
||||
#include "textureStage.h"
|
||||
#include "textureContext.h"
|
||||
#include "geomContext.h"
|
||||
#include "dataContext.h"
|
||||
#include "internalName.h"
|
||||
|
||||
#include "dconfig.h"
|
||||
@ -81,6 +85,15 @@ ConfigVariableBool retained_mode
|
||||
"GSG. Set it false to use only immediate mode, which sends the "
|
||||
"vertices to the GSG every frame."));
|
||||
|
||||
ConfigVariableBool vertex_buffers
|
||||
("vertex-buffers", false,
|
||||
PRC_DESC("Set this true to allow the use of vertex buffers (or buffer "
|
||||
"objects, as OpenGL dubs them) for rendering vertex data. This "
|
||||
"can greatly improve rendering performance, especially on "
|
||||
"higher-end graphics cards, at the cost of some additional "
|
||||
"graphics memory (which might otherwise be used for textures "
|
||||
"or offscreen buffers)."));
|
||||
|
||||
ConfigVariableBool use_qpgeom
|
||||
("use-qpgeom", false,
|
||||
PRC_DESC("A temporary variable while the experimental Geom rewrite is "
|
||||
@ -163,9 +176,13 @@ ConfigureFn(config_gobj) {
|
||||
qpGeomTriangles::init_type();
|
||||
qpGeomTristrips::init_type();
|
||||
qpGeomTrifans::init_type();
|
||||
qpGeomVertexArrayData::init_type();
|
||||
qpGeomVertexArrayFormat::init_type();
|
||||
qpGeomVertexData::init_type();
|
||||
qpGeomVertexFormat::init_type();
|
||||
TextureContext::init_type();
|
||||
GeomContext::init_type();
|
||||
DataContext::init_type();
|
||||
Material::init_type();
|
||||
OrthographicLens::init_type();
|
||||
MatrixLens::init_type();
|
||||
@ -192,6 +209,7 @@ ConfigureFn(config_gobj) {
|
||||
qpGeomTriangles::register_with_read_factory();
|
||||
qpGeomTristrips::register_with_read_factory();
|
||||
qpGeomTrifans::register_with_read_factory();
|
||||
qpGeomVertexArrayData::register_with_read_factory();
|
||||
qpGeomVertexArrayFormat::register_with_read_factory();
|
||||
qpGeomVertexData::register_with_read_factory();
|
||||
qpGeomVertexFormat::register_with_read_factory();
|
||||
|
@ -51,6 +51,7 @@ extern EXPCL_PANDA ConfigVariableInt max_texture_dimension;
|
||||
extern EXPCL_PANDA ConfigVariableBool keep_texture_ram;
|
||||
extern EXPCL_PANDA ConfigVariableBool keep_geom_ram;
|
||||
extern EXPCL_PANDA ConfigVariableBool retained_mode;
|
||||
extern EXPCL_PANDA ConfigVariableBool vertex_buffers;
|
||||
|
||||
extern EXPCL_PANDA ConfigVariableBool use_qpgeom;
|
||||
|
||||
|
29
panda/src/gobj/dataContext.I
Normal file
29
panda/src/gobj/dataContext.I
Normal file
@ -0,0 +1,29 @@
|
||||
// Filename: dataContext.I
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DataContext::
|
||||
DataContext(qpGeomVertexArrayData *data) :
|
||||
_data(data)
|
||||
{
|
||||
}
|
21
panda/src/gobj/dataContext.cxx
Normal file
21
panda/src/gobj/dataContext.cxx
Normal file
@ -0,0 +1,21 @@
|
||||
// Filename: dataContext.cxx
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "dataContext.h"
|
||||
|
||||
TypeHandle DataContext::_type_handle;
|
71
panda/src/gobj/dataContext.h
Normal file
71
panda/src/gobj/dataContext.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Filename: dataContext.h
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DATACONTEXT_H
|
||||
#define DATACONTEXT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "savedContext.h"
|
||||
#include "updateSeq.h"
|
||||
|
||||
class qpGeomVertexArrayData;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DataContext
|
||||
// Description : This is a special class object that holds all the
|
||||
// information returned by a particular GSG to indicate
|
||||
// the vertex data array's internal context identifier.
|
||||
//
|
||||
// This allows the GSG to cache the vertex data array in
|
||||
// whatever way makes sense. For instance, DirectX can
|
||||
// allocate a vertex buffer for the array. OpenGL can
|
||||
// create a buffer object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA DataContext : public SavedContext {
|
||||
public:
|
||||
INLINE DataContext(qpGeomVertexArrayData *data);
|
||||
|
||||
// This cannot be a PT(qpGeomVertexArrayData), because the data and
|
||||
// the GSG both own their DataContexts! That would create a
|
||||
// circular reference count.
|
||||
qpGeomVertexArrayData *_data;
|
||||
UpdateSeq _modified;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
SavedContext::init_type();
|
||||
register_type(_type_handle, "DataContext",
|
||||
SavedContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "dataContext.I"
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,6 @@
|
||||
|
||||
#include "boundedObject.cxx"
|
||||
#include "dataContext.cxx"
|
||||
#include "geom.cxx"
|
||||
#include "geomLine.cxx"
|
||||
#include "geomLinestrip.cxx"
|
||||
@ -17,6 +18,7 @@
|
||||
#include "qpgeomTriangles.cxx"
|
||||
#include "qpgeomTristrips.cxx"
|
||||
#include "qpgeomTrifans.cxx"
|
||||
#include "qpgeomVertexArrayData.cxx"
|
||||
#include "qpgeomVertexArrayFormat.cxx"
|
||||
#include "qpgeomVertexCacheManager.cxx"
|
||||
#include "qpgeomVertexData.cxx"
|
||||
|
@ -357,6 +357,146 @@ prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg) {
|
||||
return gc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::enqueue_data
|
||||
// Access: Public
|
||||
// Description: Indicates that a data array would like to be put on the
|
||||
// list to be prepared when the GSG is next ready to
|
||||
// do this (presumably at the next frame).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
enqueue_data(qpGeomVertexArrayData *data) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
_enqueued_datas.insert(data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::dequeue_data
|
||||
// Access: Public
|
||||
// Description: Removes a data array from the queued list of data
|
||||
// arrays to be prepared. Normally it is not necessary
|
||||
// to call this, unless you change your mind about
|
||||
// preparing it at the last minute, since the data will
|
||||
// automatically be dequeued and prepared at the next
|
||||
// frame.
|
||||
//
|
||||
// The return value is true if the data array is
|
||||
// successfully dequeued, false if it had not been
|
||||
// queued.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PreparedGraphicsObjects::
|
||||
dequeue_data(qpGeomVertexArrayData *data) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
EnqueuedDatas::iterator qi = _enqueued_datas.find(data);
|
||||
if (qi != _enqueued_datas.end()) {
|
||||
_enqueued_datas.erase(qi);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::release_data
|
||||
// Access: Public
|
||||
// Description: Indicates that a data context, created by a
|
||||
// previous call to prepare_data(), is no longer
|
||||
// needed. The driver resources will not be freed until
|
||||
// some GSG calls update(), indicating it is at a
|
||||
// stage where it is ready to release datas--this
|
||||
// prevents conflicts from threading or multiple GSG's
|
||||
// sharing datas (we have no way of knowing which
|
||||
// graphics context is currently active, or what state
|
||||
// it's in, at the time release_data is called).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
release_data(DataContext *gc) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
gc->_data->clear_prepared(this);
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since
|
||||
// the Data itself might destruct at any time after it has been
|
||||
// released.
|
||||
gc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
|
||||
bool removed = (_prepared_datas.erase(gc) != 0);
|
||||
nassertv(removed);
|
||||
|
||||
_released_datas.insert(gc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::release_all_datas
|
||||
// Access: Public
|
||||
// Description: Releases all datas at once. This will force them
|
||||
// to be reloaded into data memory for all GSG's that
|
||||
// share this object. Returns the number of datas
|
||||
// released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PreparedGraphicsObjects::
|
||||
release_all_datas() {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
int num_datas = (int)_prepared_datas.size();
|
||||
|
||||
Datas::iterator gci;
|
||||
for (gci = _prepared_datas.begin();
|
||||
gci != _prepared_datas.end();
|
||||
++gci) {
|
||||
DataContext *gc = (*gci);
|
||||
gc->_data->clear_prepared(this);
|
||||
gc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
|
||||
_released_datas.insert(gc);
|
||||
}
|
||||
|
||||
_prepared_datas.clear();
|
||||
|
||||
return num_datas;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::prepare_data_now
|
||||
// Access: Public
|
||||
// Description: Immediately creates a new DataContext for the
|
||||
// indicated data and returns it. This assumes that
|
||||
// the GraphicsStateGuardian is the currently active
|
||||
// rendering context and that it is ready to accept new
|
||||
// datas. If this is not necessarily the case, you
|
||||
// should use enqueue_data() instead.
|
||||
//
|
||||
// Normally, this function is not called directly. Call
|
||||
// Data::prepare_now() instead.
|
||||
//
|
||||
// The DataContext contains all of the pertinent
|
||||
// information needed by the GSG to keep track of this
|
||||
// one particular data, and will exist as long as the
|
||||
// data is ready to be rendered.
|
||||
//
|
||||
// When either the Data or the
|
||||
// PreparedGraphicsObjects object destructs, the
|
||||
// DataContext will be deleted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *PreparedGraphicsObjects::
|
||||
prepare_data_now(qpGeomVertexArrayData *data, GraphicsStateGuardianBase *gsg) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
// Ask the GSG to create a brand new DataContext. There might
|
||||
// be several GSG's sharing the same set of datas; if so, it
|
||||
// doesn't matter which of them creates the context (since they're
|
||||
// all shared anyway).
|
||||
DataContext *gc = gsg->prepare_data(data);
|
||||
|
||||
if (gc != (DataContext *)NULL) {
|
||||
bool prepared = _prepared_datas.insert(gc).second;
|
||||
nassertr(prepared, gc);
|
||||
}
|
||||
|
||||
return gc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::update
|
||||
// Access: Public
|
||||
|
@ -22,12 +22,16 @@
|
||||
#include "pandabase.h"
|
||||
#include "referenceCount.h"
|
||||
#include "texture.h"
|
||||
#include "geom.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "pset.h"
|
||||
#include "pmutex.h"
|
||||
|
||||
class TextureContext;
|
||||
class GeomContext;
|
||||
class DataContext;
|
||||
class GraphicsStateGuardianBase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -68,6 +72,14 @@ public:
|
||||
|
||||
GeomContext *prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void enqueue_data(qpGeomVertexArrayData *data);
|
||||
bool dequeue_data(qpGeomVertexArrayData *data);
|
||||
void release_data(DataContext *gc);
|
||||
int release_all_datas();
|
||||
|
||||
DataContext *prepare_data_now(qpGeomVertexArrayData *data,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void update(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
private:
|
||||
@ -75,12 +87,16 @@ private:
|
||||
typedef phash_set< PT(Texture) > EnqueuedTextures;
|
||||
typedef phash_set<GeomContext *, pointer_hash> Geoms;
|
||||
typedef phash_set< PT(Geom) > EnqueuedGeoms;
|
||||
typedef phash_set<DataContext *, pointer_hash> Datas;
|
||||
typedef phash_set< PT(qpGeomVertexArrayData) > EnqueuedDatas;
|
||||
|
||||
Mutex _lock;
|
||||
Textures _prepared_textures, _released_textures;
|
||||
EnqueuedTextures _enqueued_textures;
|
||||
Geoms _prepared_geoms, _released_geoms;
|
||||
EnqueuedGeoms _enqueued_geoms;
|
||||
Datas _prepared_datas, _released_datas;
|
||||
EnqueuedDatas _enqueued_datas;
|
||||
|
||||
static PStatCollector _total_texusage_pcollector;
|
||||
|
||||
|
@ -389,7 +389,7 @@ recompute_bound() {
|
||||
int start = data_type->get_start();
|
||||
int num_components = data_type->get_num_components();
|
||||
|
||||
CPTA_uchar array_data = cdata->_data->get_array_data(array_index);
|
||||
CPTA_uchar array_data = cdata->_data->get_array(array_index)->get_data();
|
||||
|
||||
if (stride == 3 * sizeof(PN_float32) && start == 0 && num_components == 3 &&
|
||||
(array_data.size() % stride) == 0) {
|
||||
|
@ -560,7 +560,7 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
||||
int start = data_type->get_start();
|
||||
int num_components = data_type->get_num_components();
|
||||
|
||||
CPTA_uchar array_data = vertex_data->get_array_data(array_index);
|
||||
CPTA_uchar array_data = vertex_data->get_array(array_index)->get_data();
|
||||
|
||||
PTA_ushort::const_iterator ii;
|
||||
for (ii = cdata->_vertices.begin(); ii != cdata->_vertices.end(); ++ii) {
|
||||
|
167
panda/src/gobj/qpgeomVertexArrayData.I
Normal file
167
panda/src/gobj/qpgeomVertexArrayData.I
Normal file
@ -0,0 +1,167 @@
|
||||
// Filename: qpgeomVertexArrayData.I
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::get_array_format
|
||||
// Access: Published
|
||||
// Description: Returns the format object that describes this array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexArrayFormat *qpGeomVertexArrayData::
|
||||
get_array_format() const {
|
||||
return _array_format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::get_usage_hint
|
||||
// Access: Published
|
||||
// Description: Returns the usage hint that describes to the
|
||||
// rendering backend how often the vertex data will be
|
||||
// modified and/or rendered. This is provided as a
|
||||
// performance optimization only, and does not
|
||||
// constraing actual usage; although it may be an
|
||||
// important optimization.
|
||||
//
|
||||
// This may only be specified to the GeomVertexArrayData
|
||||
// constructor. If you need to change it, you must
|
||||
// create a new GeomVertexArrayData object (but you can
|
||||
// just assign the same data pointer to the new object).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData::UsageHint qpGeomVertexArrayData::
|
||||
get_usage_hint() const {
|
||||
return _usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::get_data
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the actual vertex data,
|
||||
// for application code to directly examine (but not
|
||||
// modify).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar qpGeomVertexArrayData::
|
||||
get_data() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::modify_data
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the actual vertex
|
||||
// array, so that application code may directly
|
||||
// manipulate the vertices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_uchar qpGeomVertexArrayData::
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
return cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::set_data
|
||||
// Access: Published
|
||||
// Description: Replaces the vertex data array with a completely new
|
||||
// array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexArrayData::
|
||||
set_data(CPTA_uchar array) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_data = (PTA_uchar &)array;
|
||||
++(cdata->_modified);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertices stored in the array,
|
||||
// based on the number of bytes and the stride. This
|
||||
// should be the same for all arrays within a given
|
||||
// GeomVertexData object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayData::
|
||||
get_num_vertices() const {
|
||||
return get_num_bytes() / _array_format->get_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::clear_vertices
|
||||
// Access: Published
|
||||
// Description: Removes all of the vertices in the array.
|
||||
// Functionally equivalent to set_num_vertices(0).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexArrayData::
|
||||
clear_vertices() {
|
||||
set_data(PTA_uchar());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::get_num_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the number of bytes stored in the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayData::
|
||||
get_num_bytes() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_data.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::get_modified
|
||||
// Access: Published
|
||||
// Description: Returns a sequence number which is guaranteed to
|
||||
// change at least every time the array vertex data is
|
||||
// modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq qpGeomVertexArrayData::
|
||||
get_modified() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData::CData::
|
||||
CData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData::CData::
|
||||
CData(const qpGeomVertexArrayData::CData ©) :
|
||||
_data(copy._data),
|
||||
_modified(copy._modified)
|
||||
{
|
||||
}
|
360
panda/src/gobj/qpgeomVertexArrayData.cxx
Normal file
360
panda/src/gobj/qpgeomVertexArrayData.cxx
Normal file
@ -0,0 +1,360 @@
|
||||
// Filename: qpgeomVertexArrayData.cxx
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomVertexArrayData.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "pset.h"
|
||||
|
||||
TypeHandle qpGeomVertexArrayData::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::Default Constructor
|
||||
// Access: Private
|
||||
// Description: Constructs an invalid object. This is only used when
|
||||
// reading from the bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayData::
|
||||
qpGeomVertexArrayData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayData::
|
||||
qpGeomVertexArrayData(const qpGeomVertexArrayFormat *array_format,
|
||||
qpGeomVertexArrayData::UsageHint usage_hint) :
|
||||
_array_format(array_format),
|
||||
_usage_hint(usage_hint)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayData::
|
||||
qpGeomVertexArrayData(const qpGeomVertexArrayData ©) :
|
||||
_array_format(copy._array_format),
|
||||
_usage_hint(copy._usage_hint),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Directly copying ArrayData objects by assignment is
|
||||
// disallowed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
operator = (const qpGeomVertexArrayData &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayData::
|
||||
~qpGeomVertexArrayData() {
|
||||
release_all();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::set_num_vertices
|
||||
// Access: Published
|
||||
// Description: Sets the length of the array to n vertices.
|
||||
// Normally, you would not call this directly, since all
|
||||
// of the arrays in a particular GeomVertexData must
|
||||
// have the same number of vertices; instead, call
|
||||
// GeomVertexData::set_num_vertices().
|
||||
//
|
||||
// The return value is true if the number of vertices
|
||||
// was changed, false if the object already contained n
|
||||
// vertices (or if there was some error).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexArrayData::
|
||||
set_num_vertices(int n) {
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
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, uchar());
|
||||
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, uchar());
|
||||
|
||||
} else {
|
||||
cdata->_data.erase(cdata->_data.begin() + n * stride,
|
||||
cdata->_data.end());
|
||||
}
|
||||
}
|
||||
|
||||
++(cdata->_modified);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::prepare
|
||||
// Access: Published
|
||||
// Description: Indicates that the data should be enqueued to be
|
||||
// prepared in the indicated prepared_objects at the
|
||||
// beginning of the next frame. This will ensure the
|
||||
// data is already loaded into the GSG if it is expected
|
||||
// to be rendered soon.
|
||||
//
|
||||
// Use this function instead of prepare_now() to preload
|
||||
// datas from a user interface standpoint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
prepare(PreparedGraphicsObjects *prepared_objects) {
|
||||
prepared_objects->enqueue_data(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::prepare_now
|
||||
// Access: Public
|
||||
// Description: Creates a context for the data on the particular
|
||||
// GSG, if it does not already exist. Returns the new
|
||||
// (or old) DataContext. This assumes that the
|
||||
// GraphicsStateGuardian is the currently active
|
||||
// rendering context and that it is ready to accept new
|
||||
// datas. If this is not necessarily the case, you
|
||||
// should use prepare() instead.
|
||||
//
|
||||
// Normally, this is not called directly except by the
|
||||
// GraphicsStateGuardian; a data does not need to be
|
||||
// explicitly prepared by the user before it may be
|
||||
// rendered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *qpGeomVertexArrayData::
|
||||
prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg) {
|
||||
Contexts::const_iterator ci;
|
||||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
return (*ci).second;
|
||||
}
|
||||
|
||||
DataContext *dc = prepared_objects->prepare_data_now(this, gsg);
|
||||
if (dc != (DataContext *)NULL) {
|
||||
_contexts[prepared_objects] = dc;
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::release
|
||||
// Access: Public
|
||||
// Description: Frees the data context only on the indicated object,
|
||||
// if it exists there. Returns true if it was released,
|
||||
// false if it had not been prepared.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexArrayData::
|
||||
release(PreparedGraphicsObjects *prepared_objects) {
|
||||
Contexts::iterator ci;
|
||||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
DataContext *dc = (*ci).second;
|
||||
prepared_objects->release_data(dc);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Maybe it wasn't prepared yet, but it's about to be.
|
||||
return prepared_objects->dequeue_data(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::release_all
|
||||
// Access: Public
|
||||
// Description: Frees the context allocated on all objects for which
|
||||
// the data has been declared. Returns the number of
|
||||
// contexts which have been freed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexArrayData::
|
||||
release_all() {
|
||||
// We have to traverse a copy of the _contexts list, because the
|
||||
// PreparedGraphicsObjects object will call clear_prepared() in response
|
||||
// to each release_data(), and we don't want to be modifying the
|
||||
// _contexts list while we're traversing it.
|
||||
Contexts temp = _contexts;
|
||||
int num_freed = (int)_contexts.size();
|
||||
|
||||
Contexts::const_iterator ci;
|
||||
for (ci = temp.begin(); ci != temp.end(); ++ci) {
|
||||
PreparedGraphicsObjects *prepared_objects = (*ci).first;
|
||||
DataContext *dc = (*ci).second;
|
||||
prepared_objects->release_data(dc);
|
||||
}
|
||||
|
||||
// Now that we've called release_data() on every known context,
|
||||
// the _contexts list should have completely emptied itself.
|
||||
nassertr(_contexts.empty(), num_freed);
|
||||
|
||||
return num_freed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::clear_prepared
|
||||
// Access: Private
|
||||
// Description: Removes the indicated PreparedGraphicsObjects table
|
||||
// from the data array's table, without actually
|
||||
// releasing the data array. This is intended to be
|
||||
// called only from
|
||||
// PreparedGraphicsObjects::release_data(); it should
|
||||
// never be called by user code.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
Contexts::iterator ci;
|
||||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
_contexts.erase(ci);
|
||||
} else {
|
||||
// If this assertion fails, clear_prepared() was given a
|
||||
// prepared_objects which the data array didn't know about.
|
||||
nassertv(false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeomVertexArrayData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritable::write_datagram(manager, dg);
|
||||
|
||||
manager->write_cdata(dg, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeomVertexArrayData is encountered
|
||||
// in the Bam file. It should create the qpGeomVertexArrayData
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomVertexArrayData::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomVertexArrayData *object = new qpGeomVertexArrayData;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::fillin
|
||||
// Access: Protected
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new qpGeomVertexArrayData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritable::fillin(scan, manager);
|
||||
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *qpGeomVertexArrayData::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::CData::complete_pointers
|
||||
// Access: Public, Virtual
|
||||
// Description: Receives an array of pointers, one for each time
|
||||
// manager->read_pointer() was called in fillin().
|
||||
// Returns the number of pointers processed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexArrayData::CData::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = CycleData::complete_pointers(p_list, manager);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::CData::fillin
|
||||
// Access: Public, Virtual
|
||||
// Description: This internal function is called by make_from_bam to
|
||||
// read in all of the relevant data from the BamFile for
|
||||
// the new qpGeomVertexArrayData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
164
panda/src/gobj/qpgeomVertexArrayData.h
Normal file
164
panda/src/gobj/qpgeomVertexArrayData.h
Normal file
@ -0,0 +1,164 @@
|
||||
// Filename: qpgeomVertexArrayData.h
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef qpGEOMVERTEXARRAYDATA_H
|
||||
#define qpGEOMVERTEXARRAYDATA_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "pta_uchar.h"
|
||||
#include "updateSeq.h"
|
||||
#include "cycleData.h"
|
||||
#include "cycleDataReader.h"
|
||||
#include "cycleDataWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class PreparedGraphicsObjects;
|
||||
class DataContext;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexArrayData
|
||||
// Description : This is the data for one array of a GeomVertexData
|
||||
// structure. Many GeomVertexData structures will only
|
||||
// define one array; some will define multiple arrays.
|
||||
// DirectX calls this concept a "stream".
|
||||
//
|
||||
// This object is just a block of data. See
|
||||
// GeomVertexData for the organizing structure.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexArrayData : public TypedWritableReferenceCount {
|
||||
private:
|
||||
qpGeomVertexArrayData();
|
||||
|
||||
PUBLISHED:
|
||||
enum UsageHint {
|
||||
// UH_client: don't attempt to upload the data as a "vertex
|
||||
// buffer"; always keep it on the client.
|
||||
UH_client,
|
||||
|
||||
// UH_stream: the data will be created once, used to render a few
|
||||
// times, and then discarded.
|
||||
UH_stream,
|
||||
|
||||
// UH_static: the data will be created once, and used to render
|
||||
// many times, without modification.
|
||||
UH_static,
|
||||
|
||||
// UH_dynamic: the data will be repeatedly modified and
|
||||
// re-rendered.
|
||||
UH_dynamic,
|
||||
};
|
||||
|
||||
qpGeomVertexArrayData(const qpGeomVertexArrayFormat *array_format,
|
||||
UsageHint usage_hint);
|
||||
qpGeomVertexArrayData(const qpGeomVertexArrayData ©);
|
||||
private:
|
||||
void operator = (const qpGeomVertexArrayData ©);
|
||||
PUBLISHED:
|
||||
virtual ~qpGeomVertexArrayData();
|
||||
|
||||
INLINE const qpGeomVertexArrayFormat *get_array_format() const;
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
INLINE PTA_uchar modify_data();
|
||||
INLINE void set_data(CPTA_uchar data);
|
||||
|
||||
INLINE int get_num_vertices() const;
|
||||
bool set_num_vertices(int n);
|
||||
INLINE void clear_vertices();
|
||||
|
||||
INLINE int get_num_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
public:
|
||||
DataContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
CPT(qpGeomVertexArrayFormat) _array_format;
|
||||
UsageHint _usage_hint;
|
||||
|
||||
// A GeomVertexArrayData keeps a list (actually, a map) of all the
|
||||
// PreparedGraphicsObjects tables that it has been prepared into.
|
||||
// Each PGO conversely keeps a list (a set) of all the Geoms that
|
||||
// have been prepared there. When either destructs, it removes
|
||||
// itself from the other's list.
|
||||
typedef pmap<PreparedGraphicsObjects *, DataContext *> Contexts;
|
||||
Contexts _contexts;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
INLINE CData();
|
||||
INLINE CData(const CData ©);
|
||||
virtual CycleData *make_copy() const;
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
virtual void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
PTA_uchar _data;
|
||||
UpdateSeq _modified;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
void fillin(DatagramIterator &scan, BamReader *manager);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedWritableReferenceCount::init_type();
|
||||
register_type(_type_handle, "qpGeomVertexArrayData",
|
||||
TypedWritableReferenceCount::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
}
|
||||
virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class qpGeomVertexCacheManager;
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
#include "qpgeomVertexArrayData.I"
|
||||
|
||||
#endif
|
@ -34,11 +34,15 @@ get_format() const {
|
||||
// Description: Sets the length of the array to n vertices in all of
|
||||
// the various arrays (presumably by adding vertices).
|
||||
// The new vertex data is uninitialized.
|
||||
//
|
||||
// The return value is true if the number of vertices
|
||||
// was changed, false if the object already contained n
|
||||
// vertices (or if there was some error).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexData::
|
||||
INLINE bool qpGeomVertexData::
|
||||
set_num_vertices(int n) {
|
||||
CDWriter cdata(_cycler);
|
||||
do_set_num_vertices(n, cdata);
|
||||
return do_set_num_vertices(n, cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -55,17 +59,17 @@ get_num_arrays() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::get_array_data
|
||||
// Function: qpGeomVertexData::get_array
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the vertex data for the
|
||||
// indicated array, for application code to directly
|
||||
// examine (but not modify) the underlying vertex data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar qpGeomVertexData::
|
||||
get_array_data(int array) const {
|
||||
INLINE const qpGeomVertexArrayData *qpGeomVertexData::
|
||||
get_array(int i) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(array >= 0 && array < (int)cdata->_arrays.size(), CPTA_uchar());
|
||||
return cdata->_arrays[array];
|
||||
nassertr(i >= 0 && i < (int)cdata->_arrays.size(), NULL);
|
||||
return cdata->_arrays[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,15 +43,21 @@ qpGeomVertexData() {
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexData::
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format) :
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format,
|
||||
qpGeomVertexArrayData::UsageHint usage_hint) :
|
||||
_format(format)
|
||||
{
|
||||
nassertv(_format->is_registered());
|
||||
|
||||
// Create some empty arrays as required by the format.
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_arrays.insert(cdata->_arrays.end(), _format->get_num_arrays(),
|
||||
PTA_uchar());
|
||||
|
||||
int num_arrays = _format->get_num_arrays();
|
||||
for (int i = 0; i < num_arrays; i++) {
|
||||
PT(qpGeomVertexArrayData) array = new qpGeomVertexArrayData
|
||||
(_format->get_array(i), usage_hint);
|
||||
cdata->_arrays.push_back(array);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -125,7 +131,7 @@ get_num_vertices() const {
|
||||
|
||||
// Look up the answer on the first array (since any array will do).
|
||||
int stride = _format->get_array(0)->get_stride();
|
||||
return cdata->_arrays[0].size() / stride;
|
||||
return cdata->_arrays[0]->get_num_bytes() / stride;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -137,6 +143,7 @@ get_num_vertices() const {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
clear_vertices() {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(_format->get_num_arrays() == (int)cdata->_arrays.size());
|
||||
|
||||
@ -144,12 +151,12 @@ clear_vertices() {
|
||||
for (ai = cdata->_arrays.begin();
|
||||
ai != cdata->_arrays.end();
|
||||
++ai) {
|
||||
(*ai).clear();
|
||||
(*ai)->clear_vertices();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::modify_array_data
|
||||
// Function: qpGeomVertexData::modify_array
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the indicated vertex
|
||||
// array, so that application code may directly
|
||||
@ -157,27 +164,24 @@ clear_vertices() {
|
||||
// the length of this array, since all of the arrays
|
||||
// should be kept in sync--use add_vertices() instead.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar qpGeomVertexData::
|
||||
modify_array_data(int array) {
|
||||
qpGeomVertexArrayData *qpGeomVertexData::
|
||||
modify_array(int i) {
|
||||
// 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.
|
||||
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
nassertr(array >= 0 && array < (int)cdata->_arrays.size(), PTA_uchar());
|
||||
nassertr(i >= 0 && i < (int)cdata->_arrays.size(), NULL);
|
||||
|
||||
if (cdata->_arrays[array].get_ref_count() > 1) {
|
||||
PTA_uchar orig_data = cdata->_arrays[array];
|
||||
cdata->_arrays[array] = PTA_uchar();
|
||||
cdata->_arrays[array].v() = orig_data.v();
|
||||
if (cdata->_arrays[i]->get_ref_count() > 1) {
|
||||
cdata->_arrays[i] = new qpGeomVertexArrayData(*cdata->_arrays[i]);
|
||||
}
|
||||
|
||||
clear_cache();
|
||||
return cdata->_arrays[array];
|
||||
return cdata->_arrays[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::set_array_data
|
||||
// Function: qpGeomVertexData::set_array
|
||||
// Access: Published
|
||||
// Description: Replaces the indicated vertex data array with
|
||||
// a completely new array. You should be careful that
|
||||
@ -185,10 +189,11 @@ modify_array_data(int array) {
|
||||
// unless you know what you are doing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
set_array_data(int array, PTA_uchar array_data) {
|
||||
set_array(int i, const qpGeomVertexArrayData *array) {
|
||||
clear_cache();
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(array >= 0 && array < (int)cdata->_arrays.size());
|
||||
cdata->_arrays[array] = array_data;
|
||||
nassertv(i >= 0 && i < (int)cdata->_arrays.size());
|
||||
cdata->_arrays[i] = (qpGeomVertexArrayData *)array;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -205,7 +210,7 @@ get_num_bytes() const {
|
||||
|
||||
Arrays::const_iterator ai;
|
||||
for (ai = cdata->_arrays.begin(); ai != cdata->_arrays.end(); ++ai) {
|
||||
num_bytes += (*ai).size();
|
||||
num_bytes += (*ai)->get_num_bytes();
|
||||
}
|
||||
|
||||
return num_bytes;
|
||||
@ -257,33 +262,34 @@ convert_to(const qpGeomVertexFormat *new_format) const {
|
||||
}
|
||||
PStatTimer timer(_munge_data_pcollector);
|
||||
|
||||
PT(qpGeomVertexData) new_data = new qpGeomVertexData(new_format);
|
||||
PT(qpGeomVertexData) new_data =
|
||||
new qpGeomVertexData(new_format, qpGeomVertexArrayData::UH_client);
|
||||
|
||||
pset<int> done_arrays;
|
||||
|
||||
int num_arrays = _format->get_num_arrays();
|
||||
int array;
|
||||
int i;
|
||||
|
||||
// First, check to see if any arrays can be simply appropriated for
|
||||
// the new format, without changing the data.
|
||||
for (array = 0; array < num_arrays; ++array) {
|
||||
for (i = 0; i < num_arrays; ++i) {
|
||||
const qpGeomVertexArrayFormat *array_format =
|
||||
_format->get_array(array);
|
||||
_format->get_array(i);
|
||||
|
||||
bool array_done = false;
|
||||
|
||||
int new_num_arrays = new_format->get_num_arrays();
|
||||
for (int new_array = 0;
|
||||
new_array < new_num_arrays && !array_done;
|
||||
++new_array) {
|
||||
for (int new_i = 0;
|
||||
new_i < new_num_arrays && !array_done;
|
||||
++new_i) {
|
||||
const qpGeomVertexArrayFormat *new_array_format =
|
||||
new_format->get_array(new_array);
|
||||
new_format->get_array(new_i);
|
||||
if (new_array_format->is_data_subset_of(*array_format)) {
|
||||
// Great! Just use the same data for this one.
|
||||
new_data->set_array_data(new_array, (PTA_uchar &)get_array_data(array));
|
||||
new_data->set_array(new_i, get_array(i));
|
||||
array_done = true;
|
||||
|
||||
done_arrays.insert(new_array);
|
||||
done_arrays.insert(new_i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,27 +298,30 @@ convert_to(const qpGeomVertexFormat *new_format) const {
|
||||
new_data->set_num_vertices(num_vertices);
|
||||
|
||||
// Now go back through and copy any data that's left over.
|
||||
for (array = 0; array < num_arrays; ++array) {
|
||||
CPTA_uchar array_data = get_array_data(array);
|
||||
const qpGeomVertexArrayFormat *array_format =
|
||||
_format->get_array(array);
|
||||
for (i = 0; i < num_arrays; ++i) {
|
||||
CPTA_uchar data = get_array(i)->get_data();
|
||||
const qpGeomVertexArrayFormat *array_format = _format->get_array(i);
|
||||
int num_data_types = array_format->get_num_data_types();
|
||||
for (int di = 0; di < num_data_types; ++di) {
|
||||
const qpGeomVertexDataType *data_type = array_format->get_data_type(di);
|
||||
|
||||
int new_array = new_format->get_array_with(data_type->get_name());
|
||||
if (new_array >= 0 && done_arrays.count(new_array) == 0) {
|
||||
int new_i = new_format->get_array_with(data_type->get_name());
|
||||
if (new_i >= 0 && done_arrays.count(new_i) == 0) {
|
||||
// The data type exists in the new format; we have to copy it.
|
||||
PTA_uchar new_array_data = new_data->modify_array_data(new_array);
|
||||
PT(qpGeomVertexArrayData) new_array_data = new
|
||||
qpGeomVertexArrayData(*get_array(i));
|
||||
new_data->set_array(new_i, new_array_data);
|
||||
PTA_uchar new_data = new_array_data->modify_data();
|
||||
|
||||
const qpGeomVertexArrayFormat *new_array_format =
|
||||
new_format->get_array(new_array);
|
||||
new_format->get_array(new_i);
|
||||
const qpGeomVertexDataType *new_data_type =
|
||||
new_array_format->get_data_type(data_type->get_name());
|
||||
|
||||
new_data_type->copy_records
|
||||
(new_array_data + new_data_type->get_start(),
|
||||
(new_data + new_data_type->get_start(),
|
||||
new_array_format->get_stride(),
|
||||
array_data + data_type->get_start(), array_format->get_stride(),
|
||||
data + data_type->get_start(), array_format->get_stride(),
|
||||
data_type, num_vertices);
|
||||
}
|
||||
}
|
||||
@ -397,7 +406,7 @@ set_data(int array, const qpGeomVertexDataType *data_type,
|
||||
|
||||
{
|
||||
CDReader cdata(_cycler);
|
||||
int array_size = (int)cdata->_arrays[array].size();
|
||||
int array_size = (int)cdata->_arrays[array]->get_num_bytes();
|
||||
if (element + data_type->get_total_bytes() > array_size) {
|
||||
// Whoops, we need more vertices!
|
||||
CDWriter cdataw(_cycler, cdata);
|
||||
@ -405,7 +414,7 @@ set_data(int array, const qpGeomVertexDataType *data_type,
|
||||
}
|
||||
}
|
||||
|
||||
PTA_uchar array_data = modify_array_data(array);
|
||||
PTA_uchar array_data = modify_array(array)->modify_data();
|
||||
nassertv(element >= 0 && element + data_type->get_total_bytes() <= (int)array_data.size());
|
||||
|
||||
switch (data_type->get_numeric_type()) {
|
||||
@ -484,7 +493,7 @@ set_data(int array, const qpGeomVertexDataType *data_type,
|
||||
void qpGeomVertexData::
|
||||
get_data(int array, const qpGeomVertexDataType *data_type,
|
||||
int vertex, float *data, int num_values) const {
|
||||
CPTA_uchar array_data = get_array_data(array);
|
||||
CPTA_uchar array_data = get_array(array)->get_data();
|
||||
int stride = _format->get_array(array)->get_stride();
|
||||
int element = vertex * stride + data_type->get_start();
|
||||
nassertv(element >= 0 && element + data_type->get_total_bytes() <= (int)array_data.size());
|
||||
@ -561,7 +570,8 @@ get_data(int array, const qpGeomVertexDataType *data_type,
|
||||
// which case none of the output parameters are valid).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexData::
|
||||
get_array_info(const InternalName *name, CPTA_uchar &array_data,
|
||||
get_array_info(const InternalName *name,
|
||||
const qpGeomVertexArrayData *&array_data,
|
||||
int &num_components,
|
||||
qpGeomVertexDataType::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
@ -712,45 +722,23 @@ remove_cache_entry(const qpGeomVertexFormat *modifier) const {
|
||||
// Access: Private
|
||||
// Description: The private implementation of set_num_vertices().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
do_set_num_vertices(int n, CDWriter &cdata) {
|
||||
nassertv(_format->get_num_arrays() == (int)cdata->_arrays.size());
|
||||
bool qpGeomVertexData::
|
||||
do_set_num_vertices(int n, qpGeomVertexData::CDWriter &cdata) {
|
||||
nassertr(_format->get_num_arrays() == (int)cdata->_arrays.size(), false);
|
||||
|
||||
bool any_changed = false;
|
||||
|
||||
for (size_t i = 0; i < cdata->_arrays.size(); i++) {
|
||||
int stride = _format->get_array(i)->get_stride();
|
||||
int delta = n - (cdata->_arrays[i].size() / stride);
|
||||
|
||||
if (delta != 0) {
|
||||
if (cdata->_arrays[i]->set_num_vertices(n)) {
|
||||
any_changed = true;
|
||||
if (cdata->_arrays[i].get_ref_count() > 1) {
|
||||
// Copy-on-write: the array is already reffed somewhere else,
|
||||
// so we're just going to make a copy.
|
||||
PTA_uchar new_array;
|
||||
new_array.reserve(n * stride);
|
||||
new_array.insert(new_array.end(), n * stride, uchar());
|
||||
memcpy(new_array, cdata->_arrays[i],
|
||||
min((size_t)(n * stride), cdata->_arrays[i].size()));
|
||||
cdata->_arrays[i] = new_array;
|
||||
|
||||
} else {
|
||||
// We've got the only reference to the array, so we can change
|
||||
// it directly.
|
||||
if (delta > 0) {
|
||||
cdata->_arrays[i].insert(cdata->_arrays[i].end(), delta * stride, uchar());
|
||||
|
||||
} else {
|
||||
cdata->_arrays[i].erase(cdata->_arrays[i].begin() + n * stride,
|
||||
cdata->_arrays[i].end());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (any_changed) {
|
||||
clear_cache();
|
||||
}
|
||||
|
||||
return any_changed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "internalName.h"
|
||||
#include "cycleData.h"
|
||||
#include "cycleDataReader.h"
|
||||
@ -32,7 +33,6 @@
|
||||
#include "pointerTo.h"
|
||||
#include "pmap.h"
|
||||
#include "pvector.h"
|
||||
#include "pta_uchar.h"
|
||||
|
||||
class FactoryParams;
|
||||
class qpGeomVertexDataType;
|
||||
@ -62,7 +62,8 @@ class EXPCL_PANDA qpGeomVertexData : public TypedWritableReferenceCount {
|
||||
private:
|
||||
qpGeomVertexData();
|
||||
PUBLISHED:
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format);
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format,
|
||||
qpGeomVertexArrayData::UsageHint usage_hint);
|
||||
qpGeomVertexData(const qpGeomVertexData ©);
|
||||
void operator = (const qpGeomVertexData ©);
|
||||
virtual ~qpGeomVertexData();
|
||||
@ -70,13 +71,13 @@ PUBLISHED:
|
||||
INLINE const qpGeomVertexFormat *get_format() const;
|
||||
|
||||
int get_num_vertices() const;
|
||||
INLINE void set_num_vertices(int n);
|
||||
INLINE bool set_num_vertices(int n);
|
||||
void clear_vertices();
|
||||
|
||||
INLINE int get_num_arrays() const;
|
||||
INLINE CPTA_uchar get_array_data(int array) const;
|
||||
PTA_uchar modify_array_data(int array);
|
||||
void set_array_data(int array, PTA_uchar array_data);
|
||||
INLINE const qpGeomVertexArrayData *get_array(int i) const;
|
||||
qpGeomVertexArrayData *modify_array(int i);
|
||||
void set_array(int i, const qpGeomVertexArrayData *array);
|
||||
|
||||
int get_num_bytes() const;
|
||||
|
||||
@ -93,7 +94,8 @@ public:
|
||||
void get_data(int array, const qpGeomVertexDataType *data_type,
|
||||
int vertex, float *data, int num_values) const;
|
||||
|
||||
bool get_array_info(const InternalName *name, CPTA_uchar &array_data,
|
||||
bool get_array_info(const InternalName *name,
|
||||
const qpGeomVertexArrayData *&array_data,
|
||||
int &num_components,
|
||||
qpGeomVertexDataType::NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
@ -111,7 +113,7 @@ private:
|
||||
private:
|
||||
CPT(qpGeomVertexFormat) _format;
|
||||
|
||||
typedef pvector<PTA_uchar> Arrays;
|
||||
typedef pvector< PT(qpGeomVertexArrayData) > Arrays;
|
||||
|
||||
// We have to use reference-counting pointers here instead of having
|
||||
// explicit cleanup in the GeomVertexFormat destructor, because the
|
||||
@ -139,7 +141,7 @@ private:
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
private:
|
||||
void do_set_num_vertices(int n, CDWriter &cdata);
|
||||
bool do_set_num_vertices(int n, CDWriter &cdata);
|
||||
|
||||
static PStatCollector _munge_data_pcollector;
|
||||
|
||||
|
@ -321,7 +321,7 @@ write_with_data(ostream &out, int indent_level,
|
||||
indent(out, indent_level)
|
||||
<< data->get_num_vertices() << " vertices.\n";
|
||||
for (size_t i = 0; i < _arrays.size(); i++) {
|
||||
CPTA_uchar array_data = data->get_array_data(i);
|
||||
CPTA_uchar array_data = data->get_array(i)->get_data();
|
||||
indent(out, indent_level)
|
||||
<< "Array " << i << " (" << (void *)array_data.p() << "):\n";
|
||||
_arrays[i]->write_with_data(out, indent_level + 2, data, i);
|
||||
|
@ -30,6 +30,7 @@ class RenderBuffer;
|
||||
class GraphicsWindow;
|
||||
class NodePath;
|
||||
|
||||
class DataContext;
|
||||
class GeomContext;
|
||||
class GeomNode;
|
||||
class Geom;
|
||||
@ -44,6 +45,7 @@ class GeomTristrip;
|
||||
class GeomTrifan;
|
||||
class GeomSphere;
|
||||
class qpGeomVertexData;
|
||||
class qpGeomVertexArrayData;
|
||||
class qpGeomTriangles;
|
||||
class qpGeomTristrips;
|
||||
class qpGeomTrifans;
|
||||
@ -132,6 +134,9 @@ public:
|
||||
virtual GeomContext *prepare_geom(Geom *geom)=0;
|
||||
virtual void release_geom(GeomContext *gc)=0;
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data)=0;
|
||||
virtual void release_data(DataContext *gc)=0;
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state)=0;
|
||||
|
||||
virtual void set_state_and_transform(const RenderState *state,
|
||||
|
Loading…
x
Reference in New Issue
Block a user