mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
per-primitive minmax
This commit is contained in:
parent
acfa6978db
commit
25c3988698
@ -2079,20 +2079,18 @@ void CLP(GraphicsStateGuardian)::
|
|||||||
draw_tristrips(const qpGeomTristrips *primitive) {
|
draw_tristrips(const qpGeomTristrips *primitive) {
|
||||||
setup_antialias_polygon();
|
setup_antialias_polygon();
|
||||||
|
|
||||||
int min_vertex = primitive->get_min_vertex();
|
|
||||||
int max_vertex = primitive->get_max_vertex();
|
|
||||||
CPTA_ushort vertices = primitive->get_flat_last_vertices();
|
CPTA_ushort vertices = primitive->get_flat_last_vertices();
|
||||||
CPTA_int ends = primitive->get_ends();
|
CPTA_int ends = primitive->get_ends();
|
||||||
|
CPTA_ushort mins = primitive->get_mins();
|
||||||
|
CPTA_ushort maxs = primitive->get_maxs();
|
||||||
|
nassertv(mins.size() == ends.size() && maxs.size() == ends.size());
|
||||||
|
|
||||||
int num_primitives = primitive->get_num_primitives();
|
unsigned int start = 0;
|
||||||
int start = 0;
|
for (size_t i = 0; i < ends.size(); i++) {
|
||||||
for (CPTA_int::const_iterator pi = ends.begin(); pi != ends.end(); ++pi) {
|
|
||||||
int end = (*pi);
|
|
||||||
|
|
||||||
_glDrawRangeElements(GL_TRIANGLE_STRIP,
|
_glDrawRangeElements(GL_TRIANGLE_STRIP,
|
||||||
min_vertex, max_vertex, end - start,
|
mins[i], maxs[i], ends[i] - start,
|
||||||
GL_UNSIGNED_SHORT, vertices + start);
|
GL_UNSIGNED_SHORT, vertices + start);
|
||||||
start = end;
|
start = ends[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
report_my_gl_errors();
|
report_my_gl_errors();
|
||||||
|
@ -145,7 +145,7 @@ get_flat_last_vertices() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomPrimitive::get_vertices
|
// Function: qpGeomPrimitive::get_ends
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns a const pointer to the primitive ends
|
// Description: Returns a const pointer to the primitive ends
|
||||||
// array so application code can read it directly. Do
|
// array so application code can read it directly. Do
|
||||||
@ -162,6 +162,40 @@ get_ends() const {
|
|||||||
return cdata->_ends;
|
return cdata->_ends;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomPrimitive::get_mins
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a const pointer to the primitive mins
|
||||||
|
// array so application code can read it directly. Do
|
||||||
|
// not attempt to modify the returned array; use
|
||||||
|
// modify_mins() or set_mins() for this.
|
||||||
|
//
|
||||||
|
// Note that simple primitive types, like triangles, do
|
||||||
|
// not have a mins array.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPTA_ushort qpGeomPrimitive::
|
||||||
|
get_mins() const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
return cdata->_mins;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomPrimitive::get_maxs
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns a const pointer to the primitive maxs
|
||||||
|
// array so application code can read it directly. Do
|
||||||
|
// not attempt to modify the returned array; use
|
||||||
|
// modify_maxs() or set_maxs() for this.
|
||||||
|
//
|
||||||
|
// Note that simple primitive types, like triangles, do
|
||||||
|
// not have a maxs array.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE CPTA_ushort qpGeomPrimitive::
|
||||||
|
get_maxs() const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
return cdata->_maxs;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomPrimitive::get_min_vertex
|
// Function: qpGeomPrimitive::get_min_vertex
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -177,6 +211,22 @@ get_min_vertex() const {
|
|||||||
return cdata->_min_vertex;
|
return cdata->_min_vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomPrimitive::get_min_vertex
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the minimum vertex index number used by the
|
||||||
|
// ith primitive in this object.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int qpGeomPrimitive::
|
||||||
|
get_min_vertex(int i) const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
if (!cdata->_got_minmax) {
|
||||||
|
((qpGeomPrimitive *)this)->recompute_minmax();
|
||||||
|
}
|
||||||
|
nassertr(i >= 0 && i < (int)cdata->_mins.size(), -1);
|
||||||
|
return cdata->_mins[i];
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomPrimitive::get_max_vertex
|
// Function: qpGeomPrimitive::get_max_vertex
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -192,6 +242,22 @@ get_max_vertex() const {
|
|||||||
return cdata->_max_vertex;
|
return cdata->_max_vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomPrimitive::get_max_vertex
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns the maximum vertex index number used by the
|
||||||
|
// ith primitive in this object.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE int qpGeomPrimitive::
|
||||||
|
get_max_vertex(int i) const {
|
||||||
|
CDReader cdata(_cycler);
|
||||||
|
if (!cdata->_got_minmax) {
|
||||||
|
((qpGeomPrimitive *)this)->recompute_minmax();
|
||||||
|
}
|
||||||
|
nassertr(i >= 0 && i < (int)cdata->_maxs.size(), -1);
|
||||||
|
return cdata->_maxs[i];
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomPrimitive::get_primitive_end
|
// Function: qpGeomPrimitive::get_primitive_end
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -228,6 +294,8 @@ CData(const qpGeomPrimitive::CData ©) :
|
|||||||
_vertices(copy._vertices),
|
_vertices(copy._vertices),
|
||||||
_rotated_vertices(copy._rotated_vertices),
|
_rotated_vertices(copy._rotated_vertices),
|
||||||
_ends(copy._ends),
|
_ends(copy._ends),
|
||||||
|
_mins(copy._mins),
|
||||||
|
_maxs(copy._maxs),
|
||||||
_got_minmax(copy._got_minmax),
|
_got_minmax(copy._got_minmax),
|
||||||
_min_vertex(copy._min_vertex),
|
_min_vertex(copy._min_vertex),
|
||||||
_max_vertex(copy._max_vertex)
|
_max_vertex(copy._max_vertex)
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
TypeHandle qpGeomPrimitive::_type_handle;
|
TypeHandle qpGeomPrimitive::_type_handle;
|
||||||
|
|
||||||
PStatCollector qpGeomPrimitive::_rotate_pcollector("Cull:Rotate");
|
PStatCollector qpGeomPrimitive::_rotate_pcollector("Draw:Rotate");
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomPrimitive::Constructor
|
// Function: qpGeomPrimitive::Constructor
|
||||||
@ -100,6 +100,20 @@ add_vertex(int vertex) {
|
|||||||
if (cdata->_got_minmax) {
|
if (cdata->_got_minmax) {
|
||||||
cdata->_min_vertex = min(cdata->_min_vertex, short_vertex);
|
cdata->_min_vertex = min(cdata->_min_vertex, short_vertex);
|
||||||
cdata->_max_vertex = max(cdata->_max_vertex, short_vertex);
|
cdata->_max_vertex = max(cdata->_max_vertex, short_vertex);
|
||||||
|
|
||||||
|
if (get_num_vertices_per_primitive() == 0) {
|
||||||
|
// Complex primitives also update their per-primitive minmax.
|
||||||
|
size_t pi = cdata->_ends.size();
|
||||||
|
if (pi < cdata->_mins.size()) {
|
||||||
|
cdata->_mins[pi] = min(cdata->_mins[pi], short_vertex);
|
||||||
|
cdata->_maxs[pi] = max(cdata->_maxs[pi], short_vertex);
|
||||||
|
} else {
|
||||||
|
cdata->_mins.push_back(short_vertex);
|
||||||
|
cdata->_maxs.push_back(short_vertex);
|
||||||
|
}
|
||||||
|
nassertv((cdata->_mins.size() == cdata->_ends.size() + 1) &&
|
||||||
|
(cdata->_maxs.size() == cdata->_ends.size() + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,6 +140,20 @@ add_consecutive_vertices(int start, int num_vertices) {
|
|||||||
if (cdata->_got_minmax) {
|
if (cdata->_got_minmax) {
|
||||||
cdata->_min_vertex = min(cdata->_min_vertex, short_start);
|
cdata->_min_vertex = min(cdata->_min_vertex, short_start);
|
||||||
cdata->_max_vertex = max(cdata->_max_vertex, short_end);
|
cdata->_max_vertex = max(cdata->_max_vertex, short_end);
|
||||||
|
|
||||||
|
if (get_num_vertices_per_primitive() == 0) {
|
||||||
|
// Complex primitives also update their per-primitive minmax.
|
||||||
|
size_t pi = cdata->_ends.size();
|
||||||
|
if (pi < cdata->_mins.size()) {
|
||||||
|
cdata->_mins[pi] = min(cdata->_mins[pi], short_start);
|
||||||
|
cdata->_maxs[pi] = max(cdata->_maxs[pi], short_end);
|
||||||
|
} else {
|
||||||
|
cdata->_mins.push_back(short_start);
|
||||||
|
cdata->_maxs.push_back(short_end);
|
||||||
|
}
|
||||||
|
nassertv((cdata->_mins.size() == cdata->_ends.size() + 1) &&
|
||||||
|
(cdata->_maxs.size() == cdata->_ends.size() + 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -156,6 +184,11 @@ close_primitive() {
|
|||||||
#endif
|
#endif
|
||||||
cdata->_ends.push_back((int)cdata->_vertices.size());
|
cdata->_ends.push_back((int)cdata->_vertices.size());
|
||||||
|
|
||||||
|
if (cdata->_got_minmax) {
|
||||||
|
nassertv((cdata->_mins.size() == cdata->_ends.size()) &&
|
||||||
|
(cdata->_maxs.size() == cdata->_ends.size()));
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// This is a simple primitive type like a triangle: each primitive
|
// This is a simple primitive type like a triangle: each primitive
|
||||||
// uses the same number of vertices. Assert that we added the
|
// uses the same number of vertices. Assert that we added the
|
||||||
@ -177,6 +210,9 @@ clear_vertices() {
|
|||||||
cdata->_vertices.clear();
|
cdata->_vertices.clear();
|
||||||
cdata->_rotated_vertices.clear();
|
cdata->_rotated_vertices.clear();
|
||||||
cdata->_ends.clear();
|
cdata->_ends.clear();
|
||||||
|
cdata->_mins.clear();
|
||||||
|
cdata->_maxs.clear();
|
||||||
|
cdata->_got_minmax = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -192,6 +228,7 @@ modify_vertices() {
|
|||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
cdata->_rotated_vertices.clear();
|
cdata->_rotated_vertices.clear();
|
||||||
|
cdata->_got_minmax = false;
|
||||||
return cdata->_vertices;
|
return cdata->_vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -203,11 +240,12 @@ modify_vertices() {
|
|||||||
// the ends list with set_ends() at the same time.
|
// the ends list with set_ends() at the same time.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void qpGeomPrimitive::
|
void qpGeomPrimitive::
|
||||||
set_vertices(PTA_ushort vertices) {
|
set_vertices(CPTA_ushort vertices) {
|
||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
cdata->_vertices = vertices;
|
cdata->_vertices = (PTA_ushort &)vertices;
|
||||||
cdata->_rotated_vertices.clear();
|
cdata->_rotated_vertices.clear();
|
||||||
|
cdata->_got_minmax = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -226,6 +264,8 @@ PTA_int qpGeomPrimitive::
|
|||||||
modify_ends() {
|
modify_ends() {
|
||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
|
cdata->_rotated_vertices.clear();
|
||||||
|
cdata->_got_minmax = false;
|
||||||
return cdata->_ends;
|
return cdata->_ends;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,10 +282,12 @@ modify_ends() {
|
|||||||
// have the same number of vertices, it is not needed.
|
// have the same number of vertices, it is not needed.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
void qpGeomPrimitive::
|
void qpGeomPrimitive::
|
||||||
set_ends(PTA_int ends) {
|
set_ends(CPTA_int ends) {
|
||||||
clear_cache();
|
clear_cache();
|
||||||
CDWriter cdata(_cycler);
|
CDWriter cdata(_cycler);
|
||||||
cdata->_ends = ends;
|
cdata->_ends = (PTA_int &)ends;
|
||||||
|
cdata->_rotated_vertices.clear();
|
||||||
|
cdata->_got_minmax = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -257,7 +299,7 @@ set_ends(PTA_int ends) {
|
|||||||
int qpGeomPrimitive::
|
int qpGeomPrimitive::
|
||||||
get_num_bytes() const {
|
get_num_bytes() const {
|
||||||
CDReader cdata(_cycler);
|
CDReader cdata(_cycler);
|
||||||
return cdata->_vertices.size() * sizeof(short) +
|
return (cdata->_vertices.size() + cdata->_mins.size() + cdata->_maxs.size()) * sizeof(short) +
|
||||||
cdata->_ends.size() * sizeof(int) + sizeof(qpGeomPrimitive);
|
cdata->_ends.size() * sizeof(int) + sizeof(qpGeomPrimitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,10 +675,54 @@ recompute_minmax() {
|
|||||||
if (cdata->_vertices.empty()) {
|
if (cdata->_vertices.empty()) {
|
||||||
cdata->_min_vertex = 0;
|
cdata->_min_vertex = 0;
|
||||||
cdata->_max_vertex = 0;
|
cdata->_max_vertex = 0;
|
||||||
|
cdata->_mins.clear();
|
||||||
|
cdata->_maxs.clear();
|
||||||
|
|
||||||
|
} else if (get_num_vertices_per_primitive() == 0) {
|
||||||
|
// This is a complex primitive type like a triangle strip; compute
|
||||||
|
// the minmax of each primitive (as well as the overall minmax).
|
||||||
|
cdata->_mins = PTA_ushort::empty_array(cdata->_ends.size());
|
||||||
|
cdata->_maxs = PTA_ushort::empty_array(cdata->_ends.size());
|
||||||
|
|
||||||
|
int pi = 0;
|
||||||
|
int vi = 0;
|
||||||
|
int num_vertices = (int)cdata->_vertices.size();
|
||||||
|
|
||||||
|
unsigned short vertex = cdata->_vertices[vi];
|
||||||
|
cdata->_min_vertex = vertex;
|
||||||
|
cdata->_mins[pi] = vertex;
|
||||||
|
cdata->_max_vertex = vertex;
|
||||||
|
cdata->_maxs[pi] = vertex;
|
||||||
|
|
||||||
|
++vi;
|
||||||
|
while (vi < num_vertices) {
|
||||||
|
unsigned short vertex = cdata->_vertices[vi];
|
||||||
|
cdata->_min_vertex = min(cdata->_min_vertex, vertex);
|
||||||
|
cdata->_max_vertex = max(cdata->_max_vertex, vertex);
|
||||||
|
|
||||||
|
if (vi == cdata->_ends[pi]) {
|
||||||
|
++pi;
|
||||||
|
if (pi < (int)cdata->_ends.size()) {
|
||||||
|
cdata->_mins[pi] = vertex;
|
||||||
|
cdata->_maxs[pi] = vertex;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
nassertv(pi < (int)cdata->_ends.size());
|
||||||
|
cdata->_mins[pi] = min(cdata->_mins[pi], vertex);
|
||||||
|
cdata->_maxs[pi] = max(cdata->_maxs[pi], vertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
++vi;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
// This is a simple primitive type like a triangle; just compute
|
||||||
|
// the overall minmax.
|
||||||
PTA_ushort::const_iterator ii = cdata->_vertices.begin();
|
PTA_ushort::const_iterator ii = cdata->_vertices.begin();
|
||||||
cdata->_min_vertex = (*ii);
|
cdata->_min_vertex = (*ii);
|
||||||
cdata->_max_vertex = (*ii);
|
cdata->_max_vertex = (*ii);
|
||||||
|
cdata->_mins.clear();
|
||||||
|
cdata->_maxs.clear();
|
||||||
|
|
||||||
++ii;
|
++ii;
|
||||||
while (ii != cdata->_vertices.end()) {
|
while (ii != cdata->_vertices.end()) {
|
||||||
|
@ -68,8 +68,22 @@ PUBLISHED:
|
|||||||
virtual PT(qpGeomPrimitive) make_copy() const=0;
|
virtual PT(qpGeomPrimitive) make_copy() const=0;
|
||||||
|
|
||||||
enum ShadeModel {
|
enum ShadeModel {
|
||||||
SM_smooth,
|
// SM_smooth: vertices within a single face have different
|
||||||
SM_uniform,
|
// colors/normals that should be smoothed across the face. This
|
||||||
|
// primitive should be rendered with SmoothModelAttrib::M_smooth.
|
||||||
|
SM_smooth,
|
||||||
|
|
||||||
|
// SM_uniform: all vertices across all faces have the same colors
|
||||||
|
// and normals. It doesn't matter which ShadeModelAttrib mode is
|
||||||
|
// used to render this primitive.
|
||||||
|
SM_uniform,
|
||||||
|
|
||||||
|
// SM_flat_(first,last)_vertex: each face within the primitive
|
||||||
|
// might have a different color/normal than the other faces, but
|
||||||
|
// across a particular face there is only one color/normal. Each
|
||||||
|
// face's color/normal is taken from the (first, last) vertex of
|
||||||
|
// the face. This primitive should be rendered with
|
||||||
|
// SmoothModelAttrib::M_flat.
|
||||||
SM_flat_first_vertex,
|
SM_flat_first_vertex,
|
||||||
SM_flat_last_vertex,
|
SM_flat_last_vertex,
|
||||||
};
|
};
|
||||||
@ -88,16 +102,21 @@ PUBLISHED:
|
|||||||
INLINE CPTA_ushort get_flat_first_vertices() const;
|
INLINE CPTA_ushort get_flat_first_vertices() const;
|
||||||
INLINE CPTA_ushort get_flat_last_vertices() const;
|
INLINE CPTA_ushort get_flat_last_vertices() const;
|
||||||
PTA_ushort modify_vertices();
|
PTA_ushort modify_vertices();
|
||||||
void set_vertices(PTA_ushort vertices);
|
void set_vertices(CPTA_ushort vertices);
|
||||||
|
|
||||||
INLINE CPTA_int get_ends() const;
|
INLINE CPTA_int get_ends() const;
|
||||||
PTA_int modify_ends();
|
PTA_int modify_ends();
|
||||||
void set_ends(PTA_int ends);
|
void set_ends(CPTA_int ends);
|
||||||
|
|
||||||
|
INLINE CPTA_ushort get_mins() const;
|
||||||
|
INLINE CPTA_ushort get_maxs() const;
|
||||||
|
|
||||||
int get_num_bytes() const;
|
int get_num_bytes() const;
|
||||||
|
|
||||||
INLINE int get_min_vertex() const;
|
INLINE int get_min_vertex() const;
|
||||||
|
INLINE int get_min_vertex(int i) const;
|
||||||
INLINE int get_max_vertex() const;
|
INLINE int get_max_vertex() const;
|
||||||
|
INLINE int get_max_vertex(int i) const;
|
||||||
|
|
||||||
virtual int get_num_vertices_per_primitive() const;
|
virtual int get_num_vertices_per_primitive() const;
|
||||||
virtual int get_min_num_vertices_per_primitive() const;
|
virtual int get_min_num_vertices_per_primitive() const;
|
||||||
@ -146,6 +165,8 @@ private:
|
|||||||
PTA_ushort _vertices;
|
PTA_ushort _vertices;
|
||||||
CPTA_ushort _rotated_vertices;
|
CPTA_ushort _rotated_vertices;
|
||||||
PTA_int _ends;
|
PTA_int _ends;
|
||||||
|
PTA_ushort _mins;
|
||||||
|
PTA_ushort _maxs;
|
||||||
|
|
||||||
bool _got_minmax;
|
bool _got_minmax;
|
||||||
unsigned short _min_vertex;
|
unsigned short _min_vertex;
|
||||||
|
@ -28,6 +28,19 @@ get_format() const {
|
|||||||
return _format;
|
return _format;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomVertexData::set_num_vertices
|
||||||
|
// Access: Published
|
||||||
|
// 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.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE void qpGeomVertexData::
|
||||||
|
set_num_vertices(int n) {
|
||||||
|
CDWriter cdata(_cycler);
|
||||||
|
do_set_num_vertices(n, cdata);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexData::get_num_arrays
|
// Function: qpGeomVertexData::get_num_arrays
|
||||||
// Access: Published
|
// Access: Published
|
||||||
|
@ -18,14 +18,14 @@
|
|||||||
|
|
||||||
#include "qpgeomVertexData.h"
|
#include "qpgeomVertexData.h"
|
||||||
#include "qpgeomVertexCacheManager.h"
|
#include "qpgeomVertexCacheManager.h"
|
||||||
|
#include "pStatTimer.h"
|
||||||
#include "bamReader.h"
|
#include "bamReader.h"
|
||||||
#include "bamWriter.h"
|
#include "bamWriter.h"
|
||||||
#include "pset.h"
|
#include "pset.h"
|
||||||
|
|
||||||
TypeHandle qpGeomVertexData::_type_handle;
|
TypeHandle qpGeomVertexData::_type_handle;
|
||||||
|
|
||||||
// Temporarily not a member of the class.
|
PStatCollector qpGeomVertexData::_munge_data_pcollector("Cull:Munge:Data");
|
||||||
static PStatCollector _munge_pcollector("Cull:Munge:Data");
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexData::Default Constructor
|
// Function: qpGeomVertexData::Default Constructor
|
||||||
@ -128,55 +128,6 @@ get_num_vertices() const {
|
|||||||
return cdata->_arrays[0].size() / stride;
|
return cdata->_arrays[0].size() / stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
// Function: qpGeomVertexData::set_num_vertices
|
|
||||||
// Access: Published
|
|
||||||
// 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.
|
|
||||||
////////////////////////////////////////////////////////////////////
|
|
||||||
void qpGeomVertexData::
|
|
||||||
set_num_vertices(int n) {
|
|
||||||
CDWriter cdata(_cycler);
|
|
||||||
nassertv(_format->get_num_arrays() == (int)cdata->_arrays.size());
|
|
||||||
|
|
||||||
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) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexData::clear_vertices
|
// Function: qpGeomVertexData::clear_vertices
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -304,7 +255,7 @@ convert_to(const qpGeomVertexFormat *new_format) const {
|
|||||||
gobj_cat.debug()
|
gobj_cat.debug()
|
||||||
<< "Converting " << num_vertices << " vertices.\n";
|
<< "Converting " << num_vertices << " vertices.\n";
|
||||||
}
|
}
|
||||||
PStatTimer timer(_munge_pcollector);
|
PStatTimer timer(_munge_data_pcollector);
|
||||||
|
|
||||||
PT(qpGeomVertexData) new_data = new qpGeomVertexData(new_format);
|
PT(qpGeomVertexData) new_data = new qpGeomVertexData(new_format);
|
||||||
|
|
||||||
@ -449,7 +400,8 @@ set_data(int array, const qpGeomVertexDataType *data_type,
|
|||||||
int array_size = (int)cdata->_arrays[array].size();
|
int array_size = (int)cdata->_arrays[array].size();
|
||||||
if (element + data_type->get_total_bytes() > array_size) {
|
if (element + data_type->get_total_bytes() > array_size) {
|
||||||
// Whoops, we need more vertices!
|
// Whoops, we need more vertices!
|
||||||
set_num_vertices(vertex + 1);
|
CDWriter cdataw(_cycler, cdata);
|
||||||
|
do_set_num_vertices(vertex + 1, cdataw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -755,6 +707,52 @@ remove_cache_entry(const qpGeomVertexFormat *modifier) const {
|
|||||||
((qpGeomVertexData *)this)->_cycler.release_write_stage(0, cdata);
|
((qpGeomVertexData *)this)->_cycler.release_write_stage(0, cdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: qpGeomVertexData::do_set_num_vertices
|
||||||
|
// 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 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) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: qpGeomVertexData::register_with_read_factory
|
// Function: qpGeomVertexData::register_with_read_factory
|
||||||
// Access: Public, Static
|
// Access: Public, Static
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "cycleDataReader.h"
|
#include "cycleDataReader.h"
|
||||||
#include "cycleDataWriter.h"
|
#include "cycleDataWriter.h"
|
||||||
#include "pipelineCycler.h"
|
#include "pipelineCycler.h"
|
||||||
|
#include "pStatCollector.h"
|
||||||
#include "pointerTo.h"
|
#include "pointerTo.h"
|
||||||
#include "pmap.h"
|
#include "pmap.h"
|
||||||
#include "pvector.h"
|
#include "pvector.h"
|
||||||
@ -69,7 +70,7 @@ PUBLISHED:
|
|||||||
INLINE const qpGeomVertexFormat *get_format() const;
|
INLINE const qpGeomVertexFormat *get_format() const;
|
||||||
|
|
||||||
int get_num_vertices() const;
|
int get_num_vertices() const;
|
||||||
void set_num_vertices(int n);
|
INLINE void set_num_vertices(int n);
|
||||||
void clear_vertices();
|
void clear_vertices();
|
||||||
|
|
||||||
INLINE int get_num_arrays() const;
|
INLINE int get_num_arrays() const;
|
||||||
@ -137,6 +138,11 @@ private:
|
|||||||
typedef CycleDataReader<CData> CDReader;
|
typedef CycleDataReader<CData> CDReader;
|
||||||
typedef CycleDataWriter<CData> CDWriter;
|
typedef CycleDataWriter<CData> CDWriter;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void do_set_num_vertices(int n, CDWriter &cdata);
|
||||||
|
|
||||||
|
static PStatCollector _munge_data_pcollector;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void register_with_read_factory();
|
static void register_with_read_factory();
|
||||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||||
|
@ -126,7 +126,7 @@ static TimeCollectorProperties time_properties[] = {
|
|||||||
{ 1, "Cull:Show fps", { 0.5, 0.8, 1.0 } },
|
{ 1, "Cull:Show fps", { 0.5, 0.8, 1.0 } },
|
||||||
{ 1, "Cull:Bins", { 0.3, 0.6, 0.3 } },
|
{ 1, "Cull:Bins", { 0.3, 0.6, 0.3 } },
|
||||||
{ 1, "Cull:Munge", { 0.3, 0.3, 0.9 } },
|
{ 1, "Cull:Munge", { 0.3, 0.3, 0.9 } },
|
||||||
{ 1, "Cull:Rotate", { 0.9, 0.8, 0.5 } },
|
{ 1, "Cull:Munge:Data" { 0.7, 0.5, 0.2 } },
|
||||||
{ 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 },
|
{ 1, "Draw", { 1.0, 0.0, 0.0 }, 1.0 / 30.0 },
|
||||||
{ 1, "Draw:Make current", { 0.4, 0.2, 0.6 } },
|
{ 1, "Draw:Make current", { 0.4, 0.2, 0.6 } },
|
||||||
{ 1, "Draw:Copy texture", { 0.2, 0.6, 0.4 } },
|
{ 1, "Draw:Copy texture", { 0.2, 0.6, 0.4 } },
|
||||||
@ -138,6 +138,7 @@ static TimeCollectorProperties time_properties[] = {
|
|||||||
{ 1, "Draw:Flip:End", { 0.9, 0.3, 0.6 } },
|
{ 1, "Draw:Flip:End", { 0.9, 0.3, 0.6 } },
|
||||||
{ 1, "Draw:Bins", { 0.3, 0.6, 0.0 } },
|
{ 1, "Draw:Bins", { 0.3, 0.6, 0.0 } },
|
||||||
{ 0, "Draw:Primitive", { 0.0, 0.0, 0.5 } },
|
{ 0, "Draw:Primitive", { 0.0, 0.0, 0.5 } },
|
||||||
|
{ 1, "Draw:Rotate", { 0.9, 0.8, 0.5 } },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user