initial checkin of experimental Geom rewrite--preliminary
This commit is contained in:
parent
8303d57800
commit
c975b7cd49
|
|
@ -73,7 +73,7 @@ get_normals() const {
|
|||
// associated with this bucket.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BuilderBucket::
|
||||
set_texcoords(const TexCoordName *name, const PTA_TexCoordf &texcoords) {
|
||||
set_texcoords(const InternalName *name, const PTA_TexCoordf &texcoords) {
|
||||
_texcoords[name] = texcoords;
|
||||
}
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ set_texcoords(const TexCoordName *name, const PTA_TexCoordf &texcoords) {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_TexCoordf BuilderBucket::
|
||||
get_texcoords(const TexCoordName *name) const {
|
||||
get_texcoords(const InternalName *name) const {
|
||||
TexCoords::const_iterator ti = _texcoords.find(name);
|
||||
if (ti != _texcoords.end()) {
|
||||
return (*ti).second;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "pta_Normalf.h"
|
||||
#include "pta_Colorf.h"
|
||||
#include "pta_TexCoordf.h"
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
#include "renderState.h"
|
||||
|
||||
#include "stdlib.h"
|
||||
|
|
@ -77,8 +77,8 @@ public:
|
|||
INLINE void set_normals(const PTA_Normalf &normals);
|
||||
INLINE PTA_Normalf get_normals() const;
|
||||
|
||||
INLINE void set_texcoords(const TexCoordName *name, const PTA_TexCoordf &texcoords);
|
||||
INLINE PTA_TexCoordf get_texcoords(const TexCoordName *name) const;
|
||||
INLINE void set_texcoords(const InternalName *name, const PTA_TexCoordf &texcoords);
|
||||
INLINE PTA_TexCoordf get_texcoords(const InternalName *name) const;
|
||||
|
||||
INLINE void set_colors(const PTA_Colorf &colors);
|
||||
INLINE PTA_Colorf get_colors() const;
|
||||
|
|
@ -96,7 +96,7 @@ protected:
|
|||
PTA_Normalf _normals;
|
||||
PTA_Colorf _colors;
|
||||
|
||||
typedef pmap<CPT(TexCoordName), PTA_TexCoordf> TexCoords;
|
||||
typedef pmap<CPT(InternalName), PTA_TexCoordf> TexCoords;
|
||||
TexCoords _texcoords;
|
||||
|
||||
static BuilderBucket *_default_bucket;
|
||||
|
|
|
|||
|
|
@ -555,13 +555,13 @@ build_geoms(InputIterator first, InputIterator last,
|
|||
//
|
||||
// Texcoords are an exception to the above, since they are either
|
||||
// per vertex or not at all, and since there may be a different set
|
||||
// of texcoords for each of a number of TexCoordName objects.
|
||||
// of texcoords for each of a number of InternalName objects.
|
||||
|
||||
GeomBindType bind_normals = G_OVERALL;
|
||||
GeomBindType bind_colors = G_OVERALL;
|
||||
|
||||
typedef pset<const TexCoordName *> TexCoordNames;
|
||||
TexCoordNames texcoord_names;
|
||||
typedef pset<const InternalName *> InternalNames;
|
||||
InternalNames texcoord_names;
|
||||
|
||||
NType overall_normal(0);
|
||||
CType overall_color(0);
|
||||
|
|
@ -623,11 +623,11 @@ build_geoms(InputIterator first, InputIterator last,
|
|||
}
|
||||
}
|
||||
|
||||
// Texcoords. Get the union of all TexCoordNames defined on the
|
||||
// Texcoords. Get the union of all InternalNames defined on the
|
||||
// prims.
|
||||
TYPENAME PrimType::tcn_const_iterator tni;
|
||||
for (tni = (*i).tcn_begin(); tni != (*i).tcn_end(); ++tni) {
|
||||
const TexCoordName *name = (*tni);
|
||||
const InternalName *name = (*tni);
|
||||
texcoord_names.insert(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -719,7 +719,7 @@ build_geoms(InputIterator first, InputIterator last,
|
|||
|
||||
typedef TYPENAME PrimType::TexCoordFill TexCoordFill;
|
||||
TexCoordFill texcoords;
|
||||
TexCoordNames::const_iterator tni;
|
||||
InternalNames::const_iterator tni;
|
||||
for (tni = texcoord_names.begin(); tni != texcoord_names.end(); ++tni) {
|
||||
texcoords[*tni] = PTA(TType)::empty_array(0);
|
||||
}
|
||||
|
|
@ -744,7 +744,7 @@ build_geoms(InputIterator first, InputIterator last,
|
|||
}
|
||||
TYPENAME TexCoordFill::iterator tci;
|
||||
for (tci = texcoords.begin(); tci != texcoords.end(); ++tci) {
|
||||
const TexCoordName *name = (*tci).first;
|
||||
const InternalName *name = (*tci).first;
|
||||
if ((*i).get_vertex(v).has_texcoord(name)) {
|
||||
(*tci).second.push_back((*i).get_vertex(v).get_texcoord(name));
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ nonindexed_copy(const BuilderPrimTempl<BuilderVertexI> ©,
|
|||
|
||||
BuilderVertexI::tc_const_iterator tci;
|
||||
for (tci = cv.tc_begin(); tci != cv.tc_end(); ++tci) {
|
||||
const TexCoordName *name = (*tci).first;
|
||||
const InternalName *name = (*tci).first;
|
||||
v.set_texcoord(name, cv.get_texcoord_value(name, bucket));
|
||||
}
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ fill_geom(Geom *geom, const PTA_BuilderV &v_array,
|
|||
|
||||
TexCoordFill::const_iterator tci;
|
||||
for (tci = texcoords.begin(); tci != texcoords.end(); ++tci) {
|
||||
const TexCoordName *name = (*tci).first;
|
||||
const InternalName *name = (*tci).first;
|
||||
geom->set_texcoords(name, (*tci).second);
|
||||
}
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ fill_geom(Geom *geom, const PTA_ushort &v_array,
|
|||
|
||||
TexCoordFill::const_iterator tci;
|
||||
for (tci = texcoords.begin(); tci != texcoords.end(); ++tci) {
|
||||
const TexCoordName *name = (*tci).first;
|
||||
const InternalName *name = (*tci).first;
|
||||
PTA_ushort t_array = (*tci).second;
|
||||
|
||||
PTA_TexCoordf t_data = bucket.get_texcoords(name);
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ has_any_pixel_size() const {
|
|||
// Function: BuilderPrimTempl::tcn_begin
|
||||
// Access: Public
|
||||
// Description: Returns an iterator that can be used to walk through
|
||||
// the list of TexCoordNames that are common to all
|
||||
// the list of InternalNames that are common to all
|
||||
// vertices on this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class VTX>
|
||||
|
|
@ -341,7 +341,7 @@ tcn_begin() const {
|
|||
// Function: BuilderPrimTempl::tcn_end
|
||||
// Access: Public
|
||||
// Description: Returns an iterator that can be used to walk through
|
||||
// the list of TexCoordNames that are common to all
|
||||
// the list of InternalNames that are common to all
|
||||
// vertices on this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class VTX>
|
||||
|
|
@ -353,7 +353,7 @@ tcn_end() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: BuilderPrimTempl::tcn_size
|
||||
// Access: Public
|
||||
// Description: Returns the number of TexCoordNames that are common
|
||||
// Description: Returns the number of InternalNames that are common
|
||||
// to all vertices on this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
template <class VTX>
|
||||
|
|
@ -885,12 +885,12 @@ update_overall_attrib() {
|
|||
|
||||
int i;
|
||||
if (num_verts > 0) {
|
||||
// Get the intersection of TexCoordNames that are defined on all
|
||||
// Get the intersection of InternalNames that are defined on all
|
||||
// vertices.
|
||||
const Vertex &vtx = get_vertex(0);
|
||||
TYPENAME Vertex::tc_const_iterator tci;
|
||||
for (tci = vtx.tc_begin(); tci != vtx.tc_end(); ++tci) {
|
||||
const TexCoordName *name = (*tci).first;
|
||||
const InternalName *name = (*tci).first;
|
||||
bool has_texcoord = true;
|
||||
for (i = 1; i < num_verts && has_texcoord; i++) {
|
||||
has_texcoord = get_vertex(i).has_texcoord(name);
|
||||
|
|
|
|||
|
|
@ -45,12 +45,12 @@ public:
|
|||
typedef TYPENAME VTX::TType TType;
|
||||
typedef TYPENAME VTX::CType CType;
|
||||
typedef TYPENAME VTX::Attrib DAttrib;
|
||||
typedef pset<const TexCoordName *> TexCoordNames;
|
||||
typedef TexCoordNames::const_iterator tcn_const_iterator;
|
||||
typedef TexCoordNames::size_type tcn_size_type;
|
||||
typedef pset<const InternalName *> InternalNames;
|
||||
typedef InternalNames::const_iterator tcn_const_iterator;
|
||||
typedef InternalNames::size_type tcn_size_type;
|
||||
|
||||
// This type is passed to fill_geom() for the texcoords.
|
||||
typedef pmap<const TexCoordName *, PTA(TType) > TexCoordFill;
|
||||
typedef pmap<const InternalName *, PTA(TType) > TexCoordFill;
|
||||
|
||||
INLINE BuilderPrimTempl();
|
||||
INLINE BuilderPrimTempl(const BuilderPrimTempl ©);
|
||||
|
|
@ -151,7 +151,7 @@ protected:
|
|||
|
||||
Verts _verts;
|
||||
Components _components;
|
||||
TexCoordNames _texcoord_names;
|
||||
InternalNames _texcoord_names;
|
||||
BuilderPrimType _type;
|
||||
int _overall;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ set_normal_value(const BuilderN *array, ushort index) {
|
|||
// assumes the array is the same one it's indexing on).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BuilderVertex::
|
||||
set_texcoord_value(const TexCoordName *name, const BuilderTC *array, ushort index) {
|
||||
set_texcoord_value(const InternalName *name, const BuilderTC *array, ushort index) {
|
||||
set_texcoord(name, array[index]);
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ get_normal_value(const BuilderBucket &) const {
|
|||
// get_coord_value().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BuilderTC BuilderVertex::
|
||||
get_texcoord_value(const TexCoordName *name, const BuilderBucket &) const {
|
||||
get_texcoord_value(const InternalName *name, const BuilderBucket &) const {
|
||||
return get_texcoord(name);
|
||||
}
|
||||
|
||||
|
|
@ -191,7 +191,7 @@ set_normal_value(const BuilderN *, ushort index) {
|
|||
// assumes the array is the same one it's indexing on).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void BuilderVertexI::
|
||||
set_texcoord_value(const TexCoordName *name,const BuilderTC *, ushort index) {
|
||||
set_texcoord_value(const InternalName *name,const BuilderTC *, ushort index) {
|
||||
set_texcoord(name, index);
|
||||
}
|
||||
|
||||
|
|
@ -259,7 +259,7 @@ get_normal_value(const BuilderBucket &bucket) const {
|
|||
// get_coord_value().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE BuilderTC BuilderVertexI::
|
||||
get_texcoord_value(const TexCoordName *name, const BuilderBucket &bucket) const {
|
||||
get_texcoord_value(const InternalName *name, const BuilderBucket &bucket) const {
|
||||
nassertr(bucket.get_texcoords(name) != (TexCoordf *)NULL, BuilderTC());
|
||||
return bucket.get_texcoords(name)[get_texcoord(name)];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,12 +80,12 @@ public:
|
|||
|
||||
INLINE void set_coord_value(const BuilderV *array, ushort index);
|
||||
INLINE void set_normal_value(const BuilderN *array, ushort index);
|
||||
INLINE void set_texcoord_value(const TexCoordName *name, const BuilderTC *array, ushort index);
|
||||
INLINE void set_texcoord_value(const InternalName *name, const BuilderTC *array, ushort index);
|
||||
INLINE void set_color_value(const BuilderC *array, ushort index);
|
||||
|
||||
INLINE BuilderV get_coord_value(const BuilderBucket &bucket) const;
|
||||
INLINE BuilderN get_normal_value(const BuilderBucket &bucket) const;
|
||||
INLINE BuilderTC get_texcoord_value(const TexCoordName *name, const BuilderBucket &bucket) const;
|
||||
INLINE BuilderTC get_texcoord_value(const InternalName *name, const BuilderBucket &bucket) const;
|
||||
INLINE BuilderC get_color_value(const BuilderBucket &bucket) const;
|
||||
|
||||
};
|
||||
|
|
@ -111,12 +111,12 @@ public:
|
|||
|
||||
INLINE void set_coord_value(const BuilderV *array, ushort index);
|
||||
INLINE void set_normal_value(const BuilderN *array, ushort index);
|
||||
INLINE void set_texcoord_value(const TexCoordName *name, const BuilderTC *array, ushort index);
|
||||
INLINE void set_texcoord_value(const InternalName *name, const BuilderTC *array, ushort index);
|
||||
INLINE void set_color_value(const BuilderC *array, ushort index);
|
||||
|
||||
INLINE BuilderV get_coord_value(const BuilderBucket &bucket) const;
|
||||
INLINE BuilderN get_normal_value(const BuilderBucket &bucket) const;
|
||||
INLINE BuilderTC get_texcoord_value(const TexCoordName *name, const BuilderBucket &bucket) const;
|
||||
INLINE BuilderTC get_texcoord_value(const InternalName *name, const BuilderBucket &bucket) const;
|
||||
INLINE BuilderC get_color_value(const BuilderBucket &bucket) const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ clear_normal() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template <class VT, class NT, class TT, class CT>
|
||||
INLINE bool BuilderVertexTempl<VT, NT, TT, CT>::
|
||||
has_texcoord(const TexCoordName *name) const {
|
||||
has_texcoord(const InternalName *name) const {
|
||||
TYPENAME TexCoords::const_iterator ti = _texcoords.find(name);
|
||||
return (ti != _texcoords.end());
|
||||
}
|
||||
|
|
@ -185,7 +185,7 @@ has_texcoord(const TexCoordName *name) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template <class VT, class NT, class TT, class CT>
|
||||
INLINE TYPENAME BuilderVertexTempl<VT, NT, TT, CT>::TType BuilderVertexTempl<VT, NT, TT, CT>::
|
||||
get_texcoord(const TexCoordName *name) const {
|
||||
get_texcoord(const InternalName *name) const {
|
||||
TYPENAME TexCoords::const_iterator ti = _texcoords.find(name);
|
||||
nassertr(ti != _texcoords.end(), (*ti).second);
|
||||
return (*ti).second;
|
||||
|
|
@ -199,7 +199,7 @@ get_texcoord(const TexCoordName *name) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template <class VT, class NT, class TT, class CT>
|
||||
INLINE BuilderVertexTempl<VT, NT, TT, CT> &BuilderVertexTempl<VT, NT, TT, CT>::
|
||||
set_texcoord(const TexCoordName *name, const TType &t) {
|
||||
set_texcoord(const InternalName *name, const TType &t) {
|
||||
_texcoords[name] = t;
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -211,7 +211,7 @@ set_texcoord(const TexCoordName *name, const TType &t) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template <class VT, class NT, class TT, class CT>
|
||||
INLINE BuilderVertexTempl<VT, NT, TT, CT> &BuilderVertexTempl<VT, NT, TT, CT>::
|
||||
clear_texcoord(const TexCoordName *name) {
|
||||
clear_texcoord(const InternalName *name) {
|
||||
_texcoords.erase(name);
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -422,7 +422,7 @@ output(ostream &out) const {
|
|||
|
||||
TYPENAME TexCoords::const_iterator ti;
|
||||
for (ti = _texcoords.begin(); ti != _texcoords.end(); ++ti) {
|
||||
const TexCoordName *name = (*ti).first;
|
||||
const InternalName *name = (*ti).first;
|
||||
out << " texcoord \"" << name->get_name() << "\" " << (*ti).second;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
#include "builderTypes.h"
|
||||
#include "builderAttribTempl.h"
|
||||
#include "builder_compare.h"
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
#include "notify.h"
|
||||
|
|
@ -45,7 +45,7 @@ public:
|
|||
typedef NT NType;
|
||||
typedef TT TType;
|
||||
typedef CT CType;
|
||||
typedef pmap<CPT(TexCoordName), TType> TexCoords;
|
||||
typedef pmap<CPT(InternalName), TType> TexCoords;
|
||||
typedef TYPENAME TexCoords::const_iterator tc_const_iterator;
|
||||
typedef TYPENAME TexCoords::size_type tc_size_type;
|
||||
|
||||
|
|
@ -64,10 +64,10 @@ public:
|
|||
INLINE BuilderVertexTempl &set_normal(const NType &c);
|
||||
INLINE BuilderVertexTempl &clear_normal();
|
||||
|
||||
INLINE bool has_texcoord(const TexCoordName *name) const;
|
||||
INLINE TType get_texcoord(const TexCoordName *name) const;
|
||||
INLINE BuilderVertexTempl &set_texcoord(const TexCoordName *name, const TType &t);
|
||||
INLINE BuilderVertexTempl &clear_texcoord(const TexCoordName *name);
|
||||
INLINE bool has_texcoord(const InternalName *name) const;
|
||||
INLINE TType get_texcoord(const InternalName *name) const;
|
||||
INLINE BuilderVertexTempl &set_texcoord(const InternalName *name, const TType &t);
|
||||
INLINE BuilderVertexTempl &clear_texcoord(const InternalName *name);
|
||||
INLINE tc_const_iterator tc_begin() const;
|
||||
INLINE tc_const_iterator tc_end() const;
|
||||
INLINE tc_size_type tc_size() const;
|
||||
|
|
|
|||
|
|
@ -285,6 +285,16 @@ get_scene() const {
|
|||
return _scene_setup;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::get_geom_munger
|
||||
// Access: Public
|
||||
// Description: Returns the current GeomMunger object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomMunger *GraphicsStateGuardian::
|
||||
get_geom_munger() const {
|
||||
return _geom_munger;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::clear
|
||||
// Access: Public
|
||||
|
|
@ -373,6 +383,7 @@ modify_state(const RenderState *state) {
|
|||
_state_pcollector.add_level(1);
|
||||
_state = _state->issue_delta_modify(state, this);
|
||||
finish_modify_state();
|
||||
setup_geom_munger(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -400,6 +411,7 @@ set_state(const RenderState *state) {
|
|||
_state_pcollector.add_level(1);
|
||||
_state = _state->issue_delta_set(state, this);
|
||||
finish_modify_state();
|
||||
setup_geom_munger(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "throw_event.h"
|
||||
#include "clockObject.h"
|
||||
#include "pStatTimer.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomTrifans.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
|
@ -592,6 +594,58 @@ finish_decal() {
|
|||
// No need to do anything special here.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::begin_draw_primitives()
|
||||
// Access: Public, Virtual
|
||||
// Description: Called before a sequence of draw_primitive()
|
||||
// functions are called, this should prepare the vertex
|
||||
// data for rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
begin_draw_primitives(const qpGeomVertexData *data) {
|
||||
_vertex_data = get_geom_munger()->munge_data(data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::draw_triangles
|
||||
// Access: Public, Virtual
|
||||
// Description: Draws a series of disconnected triangles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_triangles(qpGeomTriangles *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::draw_tristrips
|
||||
// Access: Public, Virtual
|
||||
// Description: Draws a series of triangle strips.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_tristrips(qpGeomTristrips *primitive) {
|
||||
primitive->decompose(_vertex_data)->draw(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::draw_trifans
|
||||
// Access: Public, Virtual
|
||||
// Description: Draws a series of triangle fans.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
draw_trifans(qpGeomTrifans *primitive) {
|
||||
primitive->decompose(_vertex_data)->draw(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::end_draw_primitives()
|
||||
// Access: Public, Virtual
|
||||
// Description: Called after a sequence of draw_primitive()
|
||||
// functions are called, this should do whatever cleanup
|
||||
// is appropriate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
end_draw_primitives() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::framebuffer_bind_to_texture
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -1270,6 +1324,21 @@ finish_modify_state() {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::setup_geom_munger
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called after finish_modify_state has completed, this
|
||||
// method sets up the GeomMunger for rendering with the
|
||||
// current state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
setup_geom_munger(PT(qpGeomMunger) munger) {
|
||||
if (munger == (qpGeomMunger *)NULL) {
|
||||
munger = new qpGeomMunger;
|
||||
}
|
||||
_geom_munger = qpGeomMunger::register_munger(munger);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::free_pointers
|
||||
// Access: Protected, Virtual
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@
|
|||
#include "textureAttrib.h"
|
||||
#include "transparencyAttrib.h"
|
||||
#include "config_display.h"
|
||||
#include "qpgeomMunger.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
|
||||
#include "notify.h"
|
||||
#include "pvector.h"
|
||||
|
|
@ -95,6 +97,7 @@ PUBLISHED:
|
|||
public:
|
||||
INLINE bool set_scene(SceneSetup *scene_setup);
|
||||
INLINE SceneSetup *get_scene() const;
|
||||
INLINE const qpGeomMunger *get_geom_munger() const;
|
||||
|
||||
virtual PreparedGraphicsObjects *get_prepared_objects();
|
||||
|
||||
|
|
@ -139,6 +142,12 @@ public:
|
|||
virtual CPT(RenderState) begin_decal_base_second();
|
||||
virtual void finish_decal();
|
||||
|
||||
virtual void begin_draw_primitives(const qpGeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(qpGeomTriangles *primitive);
|
||||
virtual void draw_tristrips(qpGeomTristrips *primitive);
|
||||
virtual void draw_trifans(qpGeomTrifans *primitive);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
virtual bool framebuffer_bind_to_texture(GraphicsOutput *win, Texture *tex);
|
||||
virtual void framebuffer_release_texture(GraphicsOutput *win, Texture *tex);
|
||||
|
||||
|
|
@ -200,6 +209,7 @@ protected:
|
|||
virtual void set_blend_mode();
|
||||
|
||||
virtual void finish_modify_state();
|
||||
virtual void setup_geom_munger(PT(qpGeomMunger) munger);
|
||||
|
||||
virtual void free_pointers();
|
||||
virtual void close_gsg();
|
||||
|
|
@ -232,6 +242,8 @@ protected:
|
|||
|
||||
CPT(RenderState) _state;
|
||||
CPT(TransformState) _transform;
|
||||
CPT(qpGeomMunger) _geom_munger;
|
||||
CPT(qpGeomVertexData) _vertex_data;
|
||||
|
||||
int _buffer_mask;
|
||||
Colorf _color_clear_value;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ get_projector() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ProjectionScreen::
|
||||
set_texcoord_name(const string &texcoord_name) {
|
||||
_texcoord_name = TexCoordName::make(texcoord_name);
|
||||
_texcoord_name = InternalName::get_texcoord_name(texcoord_name);
|
||||
_stale = true;
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ set_texcoord_name(const string &texcoord_name) {
|
|||
// will be generated by this particular
|
||||
// ProjectionScreen, as set by set_texcoord_name().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &ProjectionScreen::
|
||||
INLINE string ProjectionScreen::
|
||||
get_texcoord_name() const {
|
||||
return _texcoord_name->get_name();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ TypeHandle ProjectionScreen::_type_handle;
|
|||
ProjectionScreen::
|
||||
ProjectionScreen(const string &name) : PandaNode(name)
|
||||
{
|
||||
_texcoord_name = TexCoordName::get_default();
|
||||
_texcoord_name = InternalName::get_texcoord();
|
||||
|
||||
_invert_uvs = project_invert_uvs;
|
||||
_vignette_on = false;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include "lensNode.h"
|
||||
#include "geomNode.h"
|
||||
#include "nodePath.h"
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
class Geom;
|
||||
|
|
@ -82,7 +82,7 @@ PUBLISHED:
|
|||
PT(PandaNode) make_flat_mesh(const NodePath &this_np, const NodePath &camera);
|
||||
|
||||
INLINE void set_texcoord_name(const string &texcoord_name);
|
||||
INLINE const string &get_texcoord_name() const;
|
||||
INLINE string get_texcoord_name() const;
|
||||
|
||||
INLINE void set_invert_uvs(bool invert_uvs);
|
||||
INLINE bool get_invert_uvs() const;
|
||||
|
|
@ -124,7 +124,7 @@ private:
|
|||
|
||||
NodePath _projector;
|
||||
PT(LensNode) _projector_node;
|
||||
CPT(TexCoordName) _texcoord_name;
|
||||
CPT(InternalName) _texcoord_name;
|
||||
bool _invert_uvs;
|
||||
bool _vignette_on;
|
||||
Colorf _vignette_color;
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@
|
|||
#include "depthOffsetAttrib.h"
|
||||
#include "fog.h"
|
||||
#include "throw_event.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomTrifans.h"
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
#include "pStatTimer.h"
|
||||
|
|
@ -2575,6 +2580,78 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
|
|||
_pCurFvfBufPtr = NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::begin_draw_primitives
|
||||
// Access: Public, Virtual
|
||||
// Description: Called before a sequence of draw_primitive()
|
||||
// functions are called, this should prepare the vertex
|
||||
// buffer if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
|
||||
|
||||
GraphicsStateGuardian::begin_draw_primitives(vertex_data);
|
||||
|
||||
const qpGeomVertexFormat *format = _vertex_data->get_format();
|
||||
|
||||
if (format == qpGeomVertexFormat::get_v3()) {
|
||||
set_vertex_format(D3DFVF_XYZ);
|
||||
} else if (format == qpGeomVertexFormat::get_v3n3()) {
|
||||
set_vertex_format(D3DFVF_XYZ | D3DFVF_NORMAL);
|
||||
} else if (format == qpGeomVertexFormat::get_v3t2()) {
|
||||
set_vertex_format(D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
|
||||
} else if (format == qpGeomVertexFormat::get_v3n3t2()) {
|
||||
set_vertex_format(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
|
||||
} else if (format == qpGeomVertexFormat::get_v3cp() ||
|
||||
format == qpGeomVertexFormat::get_v3c4()) {
|
||||
set_vertex_format(D3DFVF_XYZ | D3DFVF_DIFFUSE);
|
||||
} else if (format == qpGeomVertexFormat::get_v3n3cp() ||
|
||||
format == qpGeomVertexFormat::get_v3n3c4()) {
|
||||
set_vertex_format(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL);
|
||||
} else if (format == qpGeomVertexFormat::get_v3cpt2() ||
|
||||
format == qpGeomVertexFormat::get_v3c4t2()) {
|
||||
set_vertex_format(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
|
||||
} else if (format == qpGeomVertexFormat::get_v3n3cpt2() ||
|
||||
format == qpGeomVertexFormat::get_v3n3c4t2()) {
|
||||
set_vertex_format(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
|
||||
} else {
|
||||
nassert_raise("Unexpected vertex format");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::draw_triangles
|
||||
// Access: Public, Virtual
|
||||
// Description: Draws a series of disconnected triangles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_triangles(qpGeomTriangles *primitive) {
|
||||
HRESULT hr = _pD3DDevice->DrawIndexedPrimitiveUP
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_vertices(),
|
||||
D3DFMT_INDEX16,
|
||||
vertex_data->get_array_data(0),
|
||||
vertex_data->get_format()->get_array_format(0)->get_stride());
|
||||
|
||||
TestDrawPrimFailure(DrawPrim,hr,_pD3DDevice,nPrims,0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::end_draw_primitives()
|
||||
// Access: Public, Virtual
|
||||
// Description: Called after a sequence of draw_primitive()
|
||||
// functions are called, this should do whatever cleanup
|
||||
// is appropriate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
end_draw_primitives() {
|
||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::prepare_texture
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -89,6 +89,10 @@ public:
|
|||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
|
||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
|
||||
|
||||
virtual void begin_draw_primitives(const qpGeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(qpGeomTriangles *primitive);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
virtual TextureContext *prepare_texture(Texture *tex);
|
||||
virtual void apply_texture(TextureContext *tc);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
#include "eggNode.h"
|
||||
#include "eggGroup.h"
|
||||
#include "eggVertex.h"
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
|
|
@ -257,7 +257,7 @@ add_normal(const Normald &normal, const EggMorphNormalList &morphs,
|
|||
// array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ComputedVerticesMaker::
|
||||
add_texcoord(const TexCoordName *name,
|
||||
add_texcoord(const InternalName *name,
|
||||
const TexCoordd &texcoord, const EggMorphTexCoordList &morphs,
|
||||
const LMatrix3d &transform) {
|
||||
TexCoordDef &def = _tdefmap[name];
|
||||
|
|
@ -389,7 +389,7 @@ make_computed_vertices(Character *character, CharacterMaker &char_maker) {
|
|||
|
||||
// Temporary: the ComputedVertices object currently doesn't support
|
||||
// multitexture.
|
||||
character->_cv._texcoords = _texcoords[TexCoordName::get_default()];
|
||||
character->_cv._texcoords = _texcoords[InternalName::get_texcoord()];
|
||||
|
||||
// Finally, add in all the morph definitions.
|
||||
Morphs::const_iterator mi;
|
||||
|
|
@ -446,12 +446,12 @@ make_computed_vertices(Character *character, CharacterMaker &char_maker) {
|
|||
|
||||
TexCoordMorphMap::const_iterator mmi;
|
||||
for (mmi = mlist._tmorphs.begin(); mmi != mlist._tmorphs.end(); ++mmi) {
|
||||
const TexCoordName *name = (*mmi).first;
|
||||
const InternalName *name = (*mmi).first;
|
||||
const TexCoordMorphList &tmorphs = (*mmi).second;
|
||||
|
||||
// Temporary check: the ComputedVertices object currently
|
||||
// doesn't support multitexture.
|
||||
if (name == TexCoordName::get_default()) {
|
||||
if (name == InternalName::get_texcoord()) {
|
||||
comp_verts->_texcoord_morphs.push_back(ComputedVerticesMorphTexCoord());
|
||||
ComputedVerticesMorphTexCoord &mv = comp_verts->_texcoord_morphs.back();
|
||||
mv._slider_index = slider_index;
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class ComputedVertices;
|
|||
class CharacterMaker;
|
||||
class EggNode;
|
||||
class EggVertex;
|
||||
class TexCoordName;
|
||||
class InternalName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : ComputedVerticesMaker
|
||||
|
|
@ -74,7 +74,7 @@ public:
|
|||
const LMatrix4d &transform);
|
||||
int add_normal(const Normald &normal, const EggMorphNormalList &morphs,
|
||||
const LMatrix4d &transform);
|
||||
int add_texcoord(const TexCoordName *name,
|
||||
int add_texcoord(const InternalName *name,
|
||||
const TexCoordd &texcoord,
|
||||
const EggMorphTexCoordList &morphs,
|
||||
const LMatrix3d &transform);
|
||||
|
|
@ -90,7 +90,7 @@ public:
|
|||
PTA_Normalf _norms;
|
||||
PTA_Colorf _colors;
|
||||
|
||||
typedef pmap<const TexCoordName *, PTA_TexCoordf> TexCoords;
|
||||
typedef pmap<const InternalName *, PTA_TexCoordf> TexCoords;
|
||||
TexCoords _texcoords;
|
||||
|
||||
protected:
|
||||
|
|
@ -98,7 +98,7 @@ protected:
|
|||
typedef pmap<int, LVector3f> NormalMorphList;
|
||||
typedef pmap<int, LVector2f> TexCoordMorphList;
|
||||
typedef pmap<int, LVector4f> ColorMorphList;
|
||||
typedef pmap<const TexCoordName *, TexCoordMorphList> TexCoordMorphMap;
|
||||
typedef pmap<const InternalName *, TexCoordMorphList> TexCoordMorphMap;
|
||||
class MorphList {
|
||||
public:
|
||||
VertexMorphList _vmorphs;
|
||||
|
|
@ -120,7 +120,7 @@ protected:
|
|||
ComputedVerticesMakerTexCoordMap _tmap;
|
||||
};
|
||||
|
||||
typedef pmap<const TexCoordName *, TexCoordDef> TexCoordDefMap;
|
||||
typedef pmap<const InternalName *, TexCoordDef> TexCoordDefMap;
|
||||
TexCoordDefMap _tdefmap;
|
||||
|
||||
ComputedVerticesMakerColorMap _cmap;
|
||||
|
|
|
|||
|
|
@ -320,11 +320,11 @@ make_nonindexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
|
|||
for (ui = egg_vert->uv_begin(); ui != egg_vert->uv_end(); ++ui) {
|
||||
EggVertexUV *uv_obj = (*ui);
|
||||
TexCoordd uv = uv_obj->get_uv();
|
||||
CPT(TexCoordName) uv_name;
|
||||
if (uv_obj->has_name()) {
|
||||
uv_name = TexCoordName::make(uv_obj->get_name());
|
||||
CPT(InternalName) uv_name;
|
||||
if (uv_obj->has_name() && uv_obj->get_name() != string("default")) {
|
||||
uv_name = InternalName::get_texcoord_name(uv_obj->get_name());
|
||||
} else {
|
||||
uv_name = TexCoordName::get_default();
|
||||
uv_name = InternalName::get_texcoord();
|
||||
}
|
||||
|
||||
BakeInUVs::const_iterator buv = bake_in_uvs.find(uv_name);
|
||||
|
|
@ -453,11 +453,11 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
|
|||
for (ui = egg_vert->uv_begin(); ui != egg_vert->uv_end(); ++ui) {
|
||||
EggVertexUV *uv_obj = (*ui);
|
||||
TexCoordd uv = uv_obj->get_uv();
|
||||
CPT(TexCoordName) uv_name;
|
||||
if (uv_obj->has_name()) {
|
||||
uv_name = TexCoordName::make(uv_obj->get_name());
|
||||
CPT(InternalName) uv_name;
|
||||
if (uv_obj->has_name() && uv_obj->get_name() != string("default")) {
|
||||
uv_name = InternalName::get_texcoord_name(uv_obj->get_name());
|
||||
} else {
|
||||
uv_name = TexCoordName::get_default();
|
||||
uv_name = InternalName::get_texcoord();
|
||||
}
|
||||
|
||||
LMatrix3d mat = LMatrix3d::ident_mat();
|
||||
|
|
@ -498,7 +498,7 @@ make_indexed_primitive(EggPrimitive *egg_prim, PandaNode *parent,
|
|||
for (tci = comp_verts_maker._texcoords.begin();
|
||||
tci != comp_verts_maker._texcoords.end();
|
||||
++tci) {
|
||||
const TexCoordName *name = (*tci).first;
|
||||
const InternalName *name = (*tci).first;
|
||||
bucket.set_texcoords(name, (*tci).second);
|
||||
}
|
||||
|
||||
|
|
@ -1248,9 +1248,10 @@ make_texture_stage(const EggTexture *egg_tex) {
|
|||
}
|
||||
|
||||
|
||||
if (egg_tex->has_uv_name() && !egg_tex->get_uv_name().empty()) {
|
||||
CPT(TexCoordName) name =
|
||||
TexCoordName::make(egg_tex->get_uv_name());
|
||||
if (egg_tex->has_uv_name() && !egg_tex->get_uv_name().empty() &&
|
||||
egg_tex->get_uv_name() != string("default")) {
|
||||
CPT(InternalName) name =
|
||||
InternalName::get_texcoord_name(egg_tex->get_uv_name());
|
||||
stage->set_texcoord_name(name);
|
||||
}
|
||||
|
||||
|
|
@ -1461,11 +1462,11 @@ setup_bucket(BuilderBucket &bucket, EggLoader::BakeInUVs &bake_in_uvs,
|
|||
// if we can safely bake it into the UV's. (We need to get the
|
||||
// complete list of textures that share this same set of UV's
|
||||
// per each unique texture matrix. Whew!)
|
||||
CPT(TexCoordName) uv_name;
|
||||
if (egg_tex->has_uv_name()) {
|
||||
uv_name = TexCoordName::make(egg_tex->get_uv_name());
|
||||
CPT(InternalName) uv_name;
|
||||
if (egg_tex->has_uv_name() && egg_tex->get_uv_name() != string("default")) {
|
||||
uv_name = InternalName::get_texcoord_name(egg_tex->get_uv_name());
|
||||
} else {
|
||||
uv_name = TexCoordName::get_default();
|
||||
uv_name = InternalName::get_texcoord();
|
||||
}
|
||||
|
||||
if (has_tex_gen) {
|
||||
|
|
@ -1503,7 +1504,7 @@ setup_bucket(BuilderBucket &bucket, EggLoader::BakeInUVs &bake_in_uvs,
|
|||
// texture matrix.
|
||||
TexMats::const_iterator tmi;
|
||||
for (tmi = tex_mats.begin(); tmi != tex_mats.end(); ++tmi) {
|
||||
const TexCoordName *uv_name = (*tmi).first;
|
||||
const InternalName *uv_name = (*tmi).first;
|
||||
const TexMatTransforms &tmt = (*tmi).second;
|
||||
|
||||
if (tmt.size() == 1 && !needs_tex_mat) {
|
||||
|
|
|
|||
|
|
@ -91,10 +91,10 @@ private:
|
|||
// This structure is used internally in setup_bucket().
|
||||
typedef pvector<const TextureDef *> TexMatTextures;
|
||||
typedef pmap<LMatrix3d, TexMatTextures> TexMatTransforms;
|
||||
typedef pmap<CPT(TexCoordName), TexMatTransforms> TexMats;
|
||||
typedef pmap<CPT(InternalName), TexMatTransforms> TexMats;
|
||||
|
||||
// This structure is returned by setup_bucket().
|
||||
typedef pmap<CPT(TexCoordName), const EggTexture *> BakeInUVs;
|
||||
typedef pmap<CPT(InternalName), const EggTexture *> BakeInUVs;
|
||||
|
||||
void make_nurbs_curve(EggNurbsCurve *egg_curve, PandaNode *parent,
|
||||
const LMatrix4d &mat);
|
||||
|
|
|
|||
|
|
@ -44,6 +44,9 @@ typedef PRUint64 PN_uint64;
|
|||
|
||||
typedef PRFloat64 PN_float64;
|
||||
|
||||
// NSPR doesn't define a float32.
|
||||
typedef float PN_float32;
|
||||
|
||||
#else // HAVE_NSPR
|
||||
|
||||
// Without NSPR, and without any other information, we need some
|
||||
|
|
@ -66,6 +69,7 @@ typedef unsigned short PN_uint16;
|
|||
typedef unsigned long PN_uint32;
|
||||
|
||||
typedef double PN_float64;
|
||||
typedef float PN_float32;
|
||||
|
||||
#endif // HAVE_NSPR
|
||||
|
||||
|
|
|
|||
|
|
@ -228,8 +228,11 @@ back() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE TYPENAME PointerToArray<Element>::iterator PointerToArray<Element>::
|
||||
insert(iterator position, const Element &x) const {
|
||||
nassertr((this->_void_ptr) != NULL, position);
|
||||
insert(iterator position, const Element &x) {
|
||||
if ((this->_void_ptr) == NULL) {
|
||||
reassign(new RefCountObj<pvector<Element> >);
|
||||
position = end();
|
||||
}
|
||||
nassertr(position >= ((To *)(this->_void_ptr))->begin() &&
|
||||
position <= ((To *)(this->_void_ptr))->end(), position);
|
||||
return ((To *)(this->_void_ptr))->insert(position, x);
|
||||
|
|
@ -242,8 +245,11 @@ insert(iterator position, const Element &x) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void PointerToArray<Element>::
|
||||
insert(iterator position, size_type n, const Element &x) const {
|
||||
nassertv((this->_void_ptr) != NULL);
|
||||
insert(iterator position, size_type n, const Element &x) {
|
||||
if ((this->_void_ptr) == NULL) {
|
||||
reassign(new RefCountObj<pvector<Element> >);
|
||||
position = end();
|
||||
}
|
||||
nassertv(position >= ((To *)(this->_void_ptr))->begin() &&
|
||||
position <= ((To *)(this->_void_ptr))->end());
|
||||
((To *)(this->_void_ptr))->insert(position, n, x);
|
||||
|
|
@ -256,10 +262,8 @@ insert(iterator position, size_type n, const Element &x) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void PointerToArray<Element>::
|
||||
erase(iterator position) const {
|
||||
nassertd((this->_void_ptr) != NULL) {
|
||||
((PointerToArray<Element> *)this)->reassign(new RefCountObj<pvector<Element> >);
|
||||
}
|
||||
erase(iterator position) {
|
||||
nassertv((this->_void_ptr) != NULL);
|
||||
nassertv(position >= ((To *)(this->_void_ptr))->begin() &&
|
||||
position <= ((To *)(this->_void_ptr))->end());
|
||||
((To *)(this->_void_ptr))->erase(position);
|
||||
|
|
@ -272,10 +276,8 @@ erase(iterator position) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
template<class Element>
|
||||
INLINE void PointerToArray<Element>::
|
||||
erase(iterator first, iterator last) const {
|
||||
nassertd((this->_void_ptr) != NULL) {
|
||||
((PointerToArray<Element> *)this)->reassign(new RefCountObj<pvector<Element> >);
|
||||
}
|
||||
erase(iterator first, iterator last) {
|
||||
nassertv((this->_void_ptr) != NULL);
|
||||
nassertv(first >= ((To *)(this->_void_ptr))->begin() && first <= ((To *)(this->_void_ptr))->end());
|
||||
nassertv(last >= ((To *)(this->_void_ptr))->begin() && last <= ((To *)(this->_void_ptr))->end());
|
||||
((To *)(this->_void_ptr))->erase(first, last);
|
||||
|
|
|
|||
|
|
@ -135,8 +135,8 @@ public:
|
|||
INLINE size_type capacity() const;
|
||||
INLINE reference front() const;
|
||||
INLINE reference back() const;
|
||||
INLINE iterator insert(iterator position, const Element &x) const;
|
||||
INLINE void insert(iterator position, size_type n, const Element &x) const;
|
||||
INLINE iterator insert(iterator position, const Element &x);
|
||||
INLINE void insert(iterator position, size_type n, const Element &x);
|
||||
|
||||
// We don't define the insert() method that accepts a pair of
|
||||
// iterators to copy from. That's problematic because of the whole
|
||||
|
|
@ -145,8 +145,8 @@ public:
|
|||
// be exported from the DLL, you should use
|
||||
// insert_into_vector(pta.v(), ...).
|
||||
|
||||
INLINE void erase(iterator position) const;
|
||||
INLINE void erase(iterator first, iterator last) const;
|
||||
INLINE void erase(iterator position);
|
||||
INLINE void erase(iterator first, iterator last);
|
||||
|
||||
PUBLISHED:
|
||||
#if !defined(WIN32_VC)
|
||||
|
|
|
|||
|
|
@ -26,8 +26,15 @@
|
|||
#include "loader.h"
|
||||
#include "keyboardButton.h"
|
||||
#include "geomTri.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
#include "qpgeomVertexIterator.h"
|
||||
#include "texturePool.h"
|
||||
#include "textureAttrib.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "perspectiveLens.h"
|
||||
#include "orthographicLens.h"
|
||||
#include "auto_bind.h"
|
||||
|
|
@ -603,31 +610,6 @@ load_model(const NodePath &parent, Filename filename) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
NodePath WindowFramework::
|
||||
load_default_model(const NodePath &parent) {
|
||||
PTA_Vertexf coords;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Normalf norms;
|
||||
PTA_Colorf colors;
|
||||
PTA_ushort cindex;
|
||||
|
||||
coords.push_back(Vertexf::rfu(0.0, 0.0, 0.0));
|
||||
coords.push_back(Vertexf::rfu(1.0, 0.0, 0.0));
|
||||
coords.push_back(Vertexf::rfu(0.0, 0.0, 1.0));
|
||||
uvs.push_back(TexCoordf(0.0, 0.0));
|
||||
uvs.push_back(TexCoordf(1.0, 0.0));
|
||||
uvs.push_back(TexCoordf(0.0, 1.0));
|
||||
norms.push_back(Normalf::back());
|
||||
colors.push_back(Colorf(0.5, 0.5, 1.0, 1.0));
|
||||
cindex.push_back(0);
|
||||
cindex.push_back(0);
|
||||
cindex.push_back(0);
|
||||
|
||||
PT(GeomTri) geom = new GeomTri;
|
||||
geom->set_num_prims(1);
|
||||
geom->set_coords(coords);
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
geom->set_normals(norms, G_PER_PRIM);
|
||||
geom->set_colors(colors, G_PER_VERTEX, cindex);
|
||||
|
||||
CPT(RenderState) state = RenderState::make_empty();
|
||||
|
||||
// Get the default texture to apply to the triangle; it's compiled
|
||||
|
|
@ -645,7 +627,70 @@ load_default_model(const NodePath &parent) {
|
|||
}
|
||||
|
||||
GeomNode *geomnode = new GeomNode("tri");
|
||||
geomnode->add_geom(geom, state);
|
||||
|
||||
if (use_qpgeom) {
|
||||
// New, experimental Geom code.
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData(qpGeomVertexFormat::get_v3n3cpt2());
|
||||
qpGeomVertexIterator vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexIterator normal(vdata, InternalName::get_normal());
|
||||
qpGeomVertexIterator color(vdata, InternalName::get_color());
|
||||
qpGeomVertexIterator texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
vertex.set_data3(Vertexf::rfu(0.0, 0.0, 0.0));
|
||||
vertex.set_data3(Vertexf::rfu(1.0, 0.0, 0.0));
|
||||
vertex.set_data3(Vertexf::rfu(0.0, 0.0, 1.0));
|
||||
|
||||
normal.set_data3(Normalf::back());
|
||||
normal.set_data3(Normalf::back());
|
||||
normal.set_data3(Normalf::back());
|
||||
|
||||
color.set_data4(0.5, 0.5, 1.0, 1.0);
|
||||
color.set_data4(0.5, 0.5, 1.0, 1.0);
|
||||
color.set_data4(0.5, 0.5, 1.0, 1.0);
|
||||
|
||||
texcoord.set_data2(0.0, 0.0);
|
||||
texcoord.set_data2(1.0, 0.0);
|
||||
texcoord.set_data2(0.0, 1.0);
|
||||
|
||||
PT(qpGeomTriangles) tri = new qpGeomTriangles;
|
||||
tri->add_consecutive_vertices(0, 3);
|
||||
tri->close_primitive();
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(tri);
|
||||
|
||||
geomnode->add_geom(geom, state);
|
||||
|
||||
} else {
|
||||
// Original, tried-and-true Geom code.
|
||||
PTA_Vertexf coords;
|
||||
PTA_TexCoordf uvs;
|
||||
PTA_Normalf norms;
|
||||
PTA_Colorf colors;
|
||||
PTA_ushort cindex;
|
||||
|
||||
coords.push_back(Vertexf::rfu(0.0, 0.0, 0.0));
|
||||
coords.push_back(Vertexf::rfu(1.0, 0.0, 0.0));
|
||||
coords.push_back(Vertexf::rfu(0.0, 0.0, 1.0));
|
||||
uvs.push_back(TexCoordf(0.0, 0.0));
|
||||
uvs.push_back(TexCoordf(1.0, 0.0));
|
||||
uvs.push_back(TexCoordf(0.0, 1.0));
|
||||
norms.push_back(Normalf::back());
|
||||
colors.push_back(Colorf(0.5, 0.5, 1.0, 1.0));
|
||||
cindex.push_back(0);
|
||||
cindex.push_back(0);
|
||||
cindex.push_back(0);
|
||||
|
||||
PT(GeomTri) geom = new GeomTri;
|
||||
geom->set_num_prims(1);
|
||||
geom->set_coords(coords);
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
geom->set_normals(norms, G_PER_PRIM);
|
||||
geom->set_colors(colors, G_PER_VERTEX, cindex);
|
||||
|
||||
geomnode->add_geom(geom, state);
|
||||
}
|
||||
|
||||
return parent.attach_new_node(geomnode);
|
||||
}
|
||||
|
|
@ -995,7 +1040,6 @@ load_image_as_model(const Filename &filename) {
|
|||
tex->set_magfilter(Texture::FT_linear);
|
||||
|
||||
// Ok, now make a polygon to show the texture.
|
||||
PT(GeomNode) card_geode = new GeomNode("card");
|
||||
|
||||
// Choose the dimensions of the polygon appropriately.
|
||||
float left = -x_size / 2.0;
|
||||
|
|
@ -1003,34 +1047,64 @@ load_image_as_model(const Filename &filename) {
|
|||
float bottom = -y_size / 2.0;
|
||||
float top = y_size / 2.0;
|
||||
|
||||
GeomTristrip *geoset = new GeomTristrip;
|
||||
PTA_int lengths=PTA_int::empty_array(0);
|
||||
lengths.push_back(4);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
verts.push_back(Vertexf::rfu(left, 0.02f, top));
|
||||
verts.push_back(Vertexf::rfu(left, 0.02f, bottom));
|
||||
verts.push_back(Vertexf::rfu(right, 0.02f, top));
|
||||
verts.push_back(Vertexf::rfu(right, 0.02f, bottom));
|
||||
|
||||
geoset->set_num_prims(1);
|
||||
geoset->set_lengths(lengths);
|
||||
|
||||
geoset->set_coords(verts);
|
||||
|
||||
PTA_TexCoordf uvs;
|
||||
uvs.push_back(TexCoordf(0.0f, 1.0f));
|
||||
uvs.push_back(TexCoordf(0.0f, 0.0f));
|
||||
uvs.push_back(TexCoordf(1.0f, 1.0f));
|
||||
uvs.push_back(TexCoordf(1.0f, 0.0f));
|
||||
|
||||
geoset->set_texcoords(uvs, G_PER_VERTEX);
|
||||
|
||||
card_geode->add_geom(geoset);
|
||||
card_geode->set_attrib(TextureAttrib::make(tex));
|
||||
PT(GeomNode) card_node = new GeomNode("card");
|
||||
card_node->set_attrib(ColorAttrib::make_flat(Colorf(1.0f, 1.0f, 1.0f, 1.0f)));
|
||||
card_node->set_attrib(TextureAttrib::make(tex));
|
||||
if (has_alpha) {
|
||||
card_geode->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
|
||||
card_node->set_attrib(TransparencyAttrib::make(TransparencyAttrib::M_alpha));
|
||||
}
|
||||
|
||||
return card_geode.p();
|
||||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData(qpGeomVertexFormat::get_v3t2());
|
||||
qpGeomVertexIterator vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexIterator texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
vertex.set_data3(Vertexf::rfu(left, 0.02f, top));
|
||||
vertex.set_data3(Vertexf::rfu(left, 0.02f, bottom));
|
||||
vertex.set_data3(Vertexf::rfu(right, 0.02f, top));
|
||||
vertex.set_data3(Vertexf::rfu(right, 0.02f, bottom));
|
||||
|
||||
texcoord.set_data2(0.0f, 1.0f);
|
||||
texcoord.set_data2(0.0f, 0.0f);
|
||||
texcoord.set_data2(1.0f, 1.0f);
|
||||
texcoord.set_data2(1.0f, 0.0f);
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips;
|
||||
strip->add_consecutive_vertices(0, 4);
|
||||
strip->close_primitive();
|
||||
|
||||
PT(qpGeom) geom = new qpGeom;
|
||||
geom->set_vertex_data(vdata);
|
||||
geom->add_primitive(strip);
|
||||
|
||||
card_node->add_geom(geom);
|
||||
|
||||
} else {
|
||||
GeomTristrip *geom = new GeomTristrip;
|
||||
PTA_int lengths=PTA_int::empty_array(0);
|
||||
lengths.push_back(4);
|
||||
|
||||
PTA_Vertexf verts;
|
||||
verts.push_back(Vertexf::rfu(left, 0.02f, top));
|
||||
verts.push_back(Vertexf::rfu(left, 0.02f, bottom));
|
||||
verts.push_back(Vertexf::rfu(right, 0.02f, top));
|
||||
verts.push_back(Vertexf::rfu(right, 0.02f, bottom));
|
||||
|
||||
geom->set_num_prims(1);
|
||||
geom->set_lengths(lengths);
|
||||
|
||||
geom->set_coords(verts);
|
||||
|
||||
PTA_TexCoordf uvs;
|
||||
uvs.push_back(TexCoordf(0.0f, 1.0f));
|
||||
uvs.push_back(TexCoordf(0.0f, 0.0f));
|
||||
uvs.push_back(TexCoordf(1.0f, 1.0f));
|
||||
uvs.push_back(TexCoordf(1.0f, 0.0f));
|
||||
|
||||
geom->set_texcoords(uvs, G_PER_VERTEX);
|
||||
|
||||
card_node->add_geom(geom);
|
||||
}
|
||||
|
||||
return card_node.p();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@
|
|||
glGeomContext_src.cxx \
|
||||
glGeomContext_src.I \
|
||||
glGeomContext_src.h \
|
||||
glGeomMunger_src.cxx \
|
||||
glGeomMunger_src.I \
|
||||
glGeomMunger_src.h \
|
||||
glGraphicsStateGuardian_src.cxx \
|
||||
glGraphicsStateGuardian_src.I \
|
||||
glGraphicsStateGuardian_src.h \
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
// Filename: glGeomMunger_src.I
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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(GeomMunger)::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(GeomMunger)::
|
||||
CLP(GeomMunger)() {
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
// Filename: glGeomMunger_src.cxx
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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(GeomMunger)::_type_handle;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GeomMunger)::munge_format_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Given a source GeomVertexFormat, converts it if
|
||||
// necessary to the appropriate format for rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexFormat) CLP(GeomMunger)::
|
||||
munge_format_impl(const qpGeomVertexFormat *orig) {
|
||||
CPT(qpGeomVertexFormat) format = orig;
|
||||
|
||||
const qpGeomVertexDataType *color_type =
|
||||
format->get_data_type(InternalName::get_color());
|
||||
if (color_type != (qpGeomVertexDataType *)NULL &&
|
||||
color_type->get_numeric_type() == qpGeomVertexDataType::NT_packed_argb) {
|
||||
// We need to convert the color format; OpenGL doesn't support the
|
||||
// byte order of DirectX's packed_argb format.
|
||||
int color_array = format->get_array_with(InternalName::get_color());
|
||||
|
||||
PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat(*format);
|
||||
PT(qpGeomVertexArrayFormat) new_array_format = new_format->modify_array(color_array);
|
||||
|
||||
// Replace the existing color format with the new format.
|
||||
new_array_format->add_data_type
|
||||
(InternalName::get_color(), 4, qpGeomVertexDataType::NT_uint8,
|
||||
color_type->get_start());
|
||||
|
||||
format = qpGeomVertexFormat::register_format(new_format);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
// Filename: glGeomMunger_src.h
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomMunger.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLGeomMunger
|
||||
// Description : This specialization on GeomMunger finesses vertices
|
||||
// for OpenGL rendering. In particular, it makes sure
|
||||
// colors aren't stored in DirectX's packed_argb format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(GeomMunger) : public qpGeomMunger {
|
||||
public:
|
||||
INLINE CLP(GeomMunger)();
|
||||
|
||||
protected:
|
||||
virtual CPT(qpGeomVertexFormat) munge_format_impl(const qpGeomVertexFormat *orig);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpGeomMunger::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "GeomMunger",
|
||||
qpGeomMunger::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 "glGeomMunger_src.I"
|
||||
|
||||
|
|
@ -21,6 +21,10 @@
|
|||
#include "renderBuffer.h"
|
||||
#include "geom.h"
|
||||
#include "geomIssuer.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomTrifans.h"
|
||||
#include "graphicsWindow.h"
|
||||
#include "lens.h"
|
||||
#include "perspectiveLens.h"
|
||||
|
|
@ -128,6 +132,14 @@ issue_scaled_color_gl(const Geom *geom, Geom::ColorIterator &citerator,
|
|||
// defined by the GL, just so it will always be safe to call the
|
||||
// extension functions.
|
||||
|
||||
static void APIENTRY
|
||||
null_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
|
||||
GLsizei count, GLenum type, const GLvoid *indices) {
|
||||
// If we don't support glDrawRangeElements(), just use the original
|
||||
// glDrawElements() instead.
|
||||
GLP(DrawElements)(mode, count, type, indices);
|
||||
}
|
||||
|
||||
static void APIENTRY
|
||||
null_glActiveTexture(GLenum gl_texture_stage) {
|
||||
// If we don't support multitexture, we'd better not try to request
|
||||
|
|
@ -346,6 +358,27 @@ reset() {
|
|||
get_extra_extensions();
|
||||
report_extensions();
|
||||
|
||||
if (is_at_least_version(1, 2)) {
|
||||
_supports_draw_range_elements = true;
|
||||
_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "DrawRangeElements");
|
||||
|
||||
} else if (has_extension("EXT_draw_range_elements")) {
|
||||
_supports_draw_range_elements = true;
|
||||
_glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
|
||||
get_extension_func(GLPREFIX_QUOTED, "DrawRangeElementsEXT");
|
||||
}
|
||||
if (_supports_draw_range_elements) {
|
||||
if (_glDrawRangeElements == NULL) {
|
||||
GLCAT.warning()
|
||||
<< "glDrawRangeElements advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
|
||||
_supports_draw_range_elements = false;
|
||||
}
|
||||
}
|
||||
if (!_supports_draw_range_elements) {
|
||||
_glDrawRangeElements = null_glDrawRangeElements;
|
||||
}
|
||||
|
||||
_supports_3d_texture =
|
||||
has_extension("GL_EXT_texture3D") || is_at_least_version(1, 2);
|
||||
|
||||
|
|
@ -1975,6 +2008,128 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
|
|||
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::begin_draw_primitives
|
||||
// Access: Public, Virtual
|
||||
// Description: Called before a sequence of draw_primitive()
|
||||
// functions are called, this should prepare the vertex
|
||||
// buffer if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
|
||||
|
||||
GraphicsStateGuardian::begin_draw_primitives(vertex_data);
|
||||
|
||||
CPTA_uchar array_data;
|
||||
int num_components;
|
||||
qpGeomVertexDataType::NumericType numeric_type;
|
||||
int start;
|
||||
int stride;
|
||||
|
||||
if (_vertex_data->get_array_info(InternalName::get_vertex(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
GLP(VertexPointer)(num_components, get_numeric_type(numeric_type),
|
||||
stride, array_data + start);
|
||||
GLP(EnableClientState)(GL_VERTEX_ARRAY);
|
||||
} else {
|
||||
GLP(DisableClientState)(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
bool has_normals = false;
|
||||
if (wants_normals() &&
|
||||
_vertex_data->get_array_info(InternalName::get_normal(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
GLP(NormalPointer)(get_numeric_type(numeric_type), stride,
|
||||
array_data + start);
|
||||
GLP(EnableClientState)(GL_NORMAL_ARRAY);
|
||||
has_normals = true;
|
||||
} else {
|
||||
GLP(DisableClientState)(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
bool has_colors = false;
|
||||
if (wants_colors()) {
|
||||
if (_vertex_data->get_array_info(InternalName::get_color(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
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);
|
||||
|
||||
} else {
|
||||
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
|
||||
stride, array_data + start);
|
||||
}
|
||||
GLP(EnableClientState)(GL_COLOR_ARRAY);
|
||||
has_colors = true;
|
||||
|
||||
} else {
|
||||
// We wanted colors, but the geom didn't have any; just issue
|
||||
// white.
|
||||
GLP(Color4f)(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
GLP(DisableClientState)(GL_COLOR_ARRAY);
|
||||
}
|
||||
} else {
|
||||
GLP(DisableClientState)(GL_COLOR_ARRAY);
|
||||
}
|
||||
|
||||
if (wants_texcoords() &&
|
||||
_vertex_data->get_array_info(InternalName::get_texcoord(),
|
||||
array_data, num_components, numeric_type,
|
||||
start, stride)) {
|
||||
GLP(TexCoordPointer)(num_components, get_numeric_type(numeric_type),
|
||||
stride, array_data + start);
|
||||
GLP(EnableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||
} else {
|
||||
GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
// If we have per-vertex colors or normals, we need smooth shading.
|
||||
// Otherwise we want flat shading for performance reasons.
|
||||
if (has_colors || has_normals) {
|
||||
GLP(ShadeModel)(GL_SMOOTH);
|
||||
} else {
|
||||
GLP(ShadeModel)(GL_FLAT);
|
||||
}
|
||||
|
||||
issue_scene_graph_color();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::draw_triangles
|
||||
// Access: Public, Virtual
|
||||
// Description: Draws a series of disconnected triangles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
draw_triangles(qpGeomTriangles *primitive) {
|
||||
setup_antialias_polygon();
|
||||
|
||||
_glDrawRangeElements(GL_TRIANGLES,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
GL_UNSIGNED_SHORT, primitive->get_vertices());
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::end_draw_primitives()
|
||||
// Access: Public, Virtual
|
||||
// Description: Called after a sequence of draw_primitive()
|
||||
// functions are called, this should do whatever cleanup
|
||||
// is appropriate.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
end_draw_primitives() {
|
||||
GLP(DisableClientState)(GL_VERTEX_ARRAY);
|
||||
|
||||
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::prepare_texture
|
||||
// Access: Public, Virtual
|
||||
|
|
@ -3762,6 +3917,30 @@ upload_texture_image(CLP(TextureContext) *gtc,
|
|||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::get_numeric_type
|
||||
// Access: Protected, Static
|
||||
// Description: Maps from the Geom's internal numeric type symbols
|
||||
// to GL's.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GLenum CLP(GraphicsStateGuardian)::
|
||||
get_numeric_type(qpGeomVertexDataType::NumericType numeric_type) {
|
||||
switch (numeric_type) {
|
||||
case qpGeomVertexDataType::NT_uint8:
|
||||
return GL_UNSIGNED_BYTE;
|
||||
|
||||
case qpGeomVertexDataType::NT_packed_argb:
|
||||
return GL_UNSIGNED_INT;
|
||||
|
||||
case qpGeomVertexDataType::NT_float:
|
||||
return GL_FLOAT;
|
||||
}
|
||||
|
||||
GLCAT.error()
|
||||
<< "Invalid NumericType value (" << (int)numeric_type << ")\n";
|
||||
return GL_UNSIGNED_BYTE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::get_texture_target
|
||||
// Access: Protected
|
||||
|
|
@ -4843,6 +5022,19 @@ finish_modify_state() {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::setup_geom_munger
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called after finish_modify_state has completed, this
|
||||
// method sets up the GeomMunger for rendering with the
|
||||
// current state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
setup_geom_munger(PT(qpGeomMunger) munger) {
|
||||
munger = new CLP(GeomMunger);
|
||||
GraphicsStateGuardian::setup_geom_munger(munger);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::free_pointers
|
||||
// Access: Protected, Virtual
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "graphicsStateGuardian.h"
|
||||
#include "geomprimitives.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "texture.h"
|
||||
#include "displayRegion.h"
|
||||
#include "material.h"
|
||||
|
|
@ -48,6 +49,7 @@ class Light;
|
|||
// system GL version matches or exceeds the GL version in which these
|
||||
// functions are defined, and the system gl.h sometimes doesn't
|
||||
// declare these typedefs.
|
||||
typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices);
|
||||
typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels);
|
||||
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
|
||||
|
|
@ -87,6 +89,10 @@ public:
|
|||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
|
||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
|
||||
|
||||
virtual void begin_draw_primitives(const qpGeomVertexData *vertex_data);
|
||||
virtual void draw_triangles(qpGeomTriangles *primitive);
|
||||
virtual void end_draw_primitives();
|
||||
|
||||
INLINE bool draw_display_list(GeomContext *gc);
|
||||
|
||||
virtual TextureContext *prepare_texture(Texture *tex);
|
||||
|
|
@ -174,6 +180,7 @@ protected:
|
|||
virtual void set_blend_mode();
|
||||
|
||||
virtual void finish_modify_state();
|
||||
virtual void setup_geom_munger(PT(qpGeomMunger) munger);
|
||||
|
||||
virtual void free_pointers();
|
||||
|
||||
|
|
@ -212,6 +219,7 @@ protected:
|
|||
GLint external_format, GLenum component_type,
|
||||
const unsigned char *image);
|
||||
|
||||
static GLenum get_numeric_type(qpGeomVertexDataType::NumericType numeric_type);
|
||||
GLenum get_texture_target(Texture::TextureType texture_type) const;
|
||||
GLenum get_texture_wrap_mode(Texture::WrapMode wm);
|
||||
static GLenum get_texture_filter_type(Texture::FilterType ft, bool ignore_mipmaps);
|
||||
|
|
@ -296,6 +304,9 @@ protected:
|
|||
pset<string> _extensions;
|
||||
|
||||
public:
|
||||
bool _supports_draw_range_elements;
|
||||
PFNGLDRAWRANGEELEMENTSPROC _glDrawRangeElements;
|
||||
|
||||
bool _supports_3d_texture;
|
||||
PFNGLTEXIMAGE3DPROC _glTexImage3D;
|
||||
PFNGLTEXSUBIMAGE3DPROC _glTexSubImage3D;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "glmisc_src.cxx"
|
||||
#include "glTextureContext_src.cxx"
|
||||
#include "glGeomContext_src.cxx"
|
||||
#include "glGeomMunger_src.cxx"
|
||||
#include "glCgShaderContext_src.cxx"
|
||||
#include "glGraphicsStateGuardian_src.cxx"
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "glmisc_src.h"
|
||||
#include "glTextureContext_src.h"
|
||||
#include "glGeomContext_src.h"
|
||||
#include "glGeomMunger_src.h"
|
||||
#include "glCgShaderContext_src.h"
|
||||
#include "glGraphicsStateGuardian_src.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,18 @@
|
|||
geomLine.h geomLinestrip.h geomPoint.h geomPolygon.h \
|
||||
geomQuad.h geomSphere.h geomSprite.I geomSprite.h geomTri.h \
|
||||
geomTrifan.h geomTristrip.h \
|
||||
qpgeom.h qpgeom.I \
|
||||
qpgeomMunger.h qpgeomMunger.I \
|
||||
qpgeomPrimitive.h qpgeomPrimitive.I \
|
||||
qpgeomTriangles.h \
|
||||
qpgeomTristrips.h \
|
||||
qpgeomTrifans.h \
|
||||
qpgeomVertexArrayFormat.h qpgeomVertexArrayFormat.I \
|
||||
qpgeomVertexData.h qpgeomVertexData.I \
|
||||
qpgeomVertexDataType.h qpgeomVertexDataType.I \
|
||||
qpgeomVertexFormat.h qpgeomVertexFormat.I \
|
||||
qpgeomVertexIterator.h qpgeomVertexIterator.I \
|
||||
internalName.I internalName.h \
|
||||
material.I material.h materialPool.I materialPool.h \
|
||||
matrixLens.I matrixLens.h \
|
||||
orthographicLens.I orthographicLens.h perspectiveLens.I \
|
||||
|
|
@ -27,7 +39,6 @@
|
|||
texture.I texture.h \
|
||||
textureContext.I textureContext.h \
|
||||
texturePool.I texturePool.h \
|
||||
texCoordName.I texCoordName.h \
|
||||
textureStage.I textureStage.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
|
|
@ -36,13 +47,26 @@
|
|||
geomContext.cxx \
|
||||
geomLine.cxx geomLinestrip.cxx geomPoint.cxx geomPolygon.cxx \
|
||||
geomQuad.cxx geomSphere.cxx geomSprite.cxx geomTri.cxx \
|
||||
geomTrifan.cxx geomTristrip.cxx material.cxx \
|
||||
geomTrifan.cxx geomTristrip.cxx \
|
||||
qpgeom.cxx \
|
||||
qpgeomMunger.cxx \
|
||||
qpgeomPrimitive.cxx \
|
||||
qpgeomTriangles.cxx \
|
||||
qpgeomTristrips.cxx \
|
||||
qpgeomTrifans.cxx \
|
||||
qpgeomVertexArrayFormat.cxx \
|
||||
qpgeomVertexData.cxx \
|
||||
qpgeomVertexDataType.cxx \
|
||||
qpgeomVertexFormat.cxx \
|
||||
qpgeomVertexIterator.cxx \
|
||||
material.cxx \
|
||||
internalName.cxx \
|
||||
materialPool.cxx matrixLens.cxx orthographicLens.cxx \
|
||||
perspectiveLens.cxx \
|
||||
preparedGraphicsObjects.cxx \
|
||||
lens.cxx \
|
||||
savedContext.cxx texture.cxx textureContext.cxx texturePool.cxx \
|
||||
texCoordName.cxx textureStage.cxx
|
||||
textureStage.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
boundedObject.I boundedObject.h \
|
||||
|
|
@ -52,7 +76,9 @@
|
|||
geomLine.h \
|
||||
geomLinestrip.h geomPoint.h geomPolygon.h geomQuad.h geomSphere.h \
|
||||
geomSprite.I geomSprite.h geomTri.h geomTrifan.h geomTristrip.h \
|
||||
geomprimitives.h material.I material.h \
|
||||
geomprimitives.h \
|
||||
internalName.I internalName.h \
|
||||
material.I material.h \
|
||||
materialPool.I materialPool.h matrixLens.I matrixLens.h \
|
||||
orthographicLens.I orthographicLens.h perspectiveLens.I \
|
||||
perspectiveLens.h \
|
||||
|
|
@ -62,7 +88,6 @@
|
|||
texture.I texture.h \
|
||||
textureContext.I textureContext.h \
|
||||
texturePool.I texturePool.h \
|
||||
texCoordName.I texCoordName.h \
|
||||
textureStage.I textureStage.h
|
||||
|
||||
#define IGATESCAN all
|
||||
|
|
|
|||
|
|
@ -22,6 +22,15 @@
|
|||
#include "drawable.h"
|
||||
#include "geom.h"
|
||||
#include "geomprimitives.h"
|
||||
#include "qpgeom.h"
|
||||
#include "qpgeomMunger.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomTrifans.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
#include "material.h"
|
||||
#include "orthographicLens.h"
|
||||
#include "matrixLens.h"
|
||||
|
|
@ -29,7 +38,7 @@
|
|||
#include "lens.h"
|
||||
#include "texture.h"
|
||||
#include "textureStage.h"
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
|
||||
#include "dconfig.h"
|
||||
#include "string_utils.h"
|
||||
|
|
@ -72,6 +81,12 @@ ConfigVariableBool retained_mode
|
|||
"GSG. Set it false to use only immediate mode, which sends the "
|
||||
"vertices to the GSG every frame."));
|
||||
|
||||
ConfigVariableBool use_qpgeom
|
||||
("use-qpgeom", false,
|
||||
PRC_DESC("A temporary variable while the experimental Geom rewrite is "
|
||||
"underway. Set this true if you want to use the experimental "
|
||||
"code. You don't really want to set this true."));
|
||||
|
||||
|
||||
ConfigVariableEnum<BamTextureMode> bam_texture_mode
|
||||
("bam-texture-mode", BTM_relative,
|
||||
|
|
@ -133,6 +148,15 @@ ConfigureFn(config_gobj) {
|
|||
GeomTri::init_type();
|
||||
GeomTrifan::init_type();
|
||||
GeomTristrip::init_type();
|
||||
qpGeom::init_type();
|
||||
qpGeomMunger::init_type();
|
||||
qpGeomPrimitive::init_type();
|
||||
qpGeomTriangles::init_type();
|
||||
qpGeomTristrips::init_type();
|
||||
qpGeomTrifans::init_type();
|
||||
qpGeomVertexArrayFormat::init_type();
|
||||
qpGeomVertexData::init_type();
|
||||
qpGeomVertexFormat::init_type();
|
||||
Material::init_type();
|
||||
OrthographicLens::init_type();
|
||||
MatrixLens::init_type();
|
||||
|
|
@ -141,7 +165,7 @@ ConfigureFn(config_gobj) {
|
|||
Texture::init_type();
|
||||
dDrawable::init_type();
|
||||
TextureStage::init_type();
|
||||
TexCoordName::init_type();
|
||||
InternalName::init_type();
|
||||
|
||||
//Registration of writeable object's creation
|
||||
//functions with BamReader's factory
|
||||
|
|
@ -155,13 +179,20 @@ ConfigureFn(config_gobj) {
|
|||
GeomTristrip::register_with_read_factory();
|
||||
GeomTrifan::register_with_read_factory();
|
||||
GeomSphere::register_with_read_factory();
|
||||
qpGeom::register_with_read_factory();
|
||||
qpGeomTriangles::register_with_read_factory();
|
||||
qpGeomTristrips::register_with_read_factory();
|
||||
qpGeomTrifans::register_with_read_factory();
|
||||
qpGeomVertexArrayFormat::register_with_read_factory();
|
||||
qpGeomVertexData::register_with_read_factory();
|
||||
qpGeomVertexFormat::register_with_read_factory();
|
||||
Material::register_with_read_factory();
|
||||
OrthographicLens::register_with_read_factory();
|
||||
MatrixLens::register_with_read_factory();
|
||||
PerspectiveLens::register_with_read_factory();
|
||||
Texture::register_with_read_factory();
|
||||
TextureStage::register_with_read_factory();
|
||||
TexCoordName::register_with_read_factory();
|
||||
InternalName::register_with_read_factory();
|
||||
}
|
||||
|
||||
ostream &
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ extern EXPCL_PANDA ConfigVariableBool keep_texture_ram;
|
|||
extern EXPCL_PANDA ConfigVariableBool keep_geom_ram;
|
||||
extern EXPCL_PANDA ConfigVariableBool retained_mode;
|
||||
|
||||
extern EXPCL_PANDA ConfigVariableBool use_qpgeom;
|
||||
|
||||
extern EXPCL_PANDA ConfigVariableEnum<BamTextureMode> bam_texture_mode;
|
||||
extern EXPCL_PANDA ConfigVariableEnum<AutoTextureScale> textures_power_2;
|
||||
extern EXPCL_PANDA ConfigVariableEnum<AutoTextureScale> textures_square;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ has_any_texcoords() const {
|
|||
// name, or false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool Geom::
|
||||
has_texcoords(const TexCoordName *name) const {
|
||||
has_texcoords(const InternalName *name) const {
|
||||
TexCoordsByName::const_iterator tci = _texcoords_by_name.find(name);
|
||||
return (tci != _texcoords_by_name.end());
|
||||
}
|
||||
|
|
@ -106,11 +106,11 @@ get_colors_array() const {
|
|||
// returns the default texture coordinates only. In the
|
||||
// presence of multitexturing, use the version of
|
||||
// get_texcoords_array() method that takes a
|
||||
// TexCoordName parameter.
|
||||
// InternalName parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_TexCoordf Geom::
|
||||
get_texcoords_array() const {
|
||||
return get_texcoords_array(TexCoordName::get_default());
|
||||
return get_texcoords_array(InternalName::get_texcoord());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -123,7 +123,7 @@ get_texcoords_array() const {
|
|||
// texture coordinates with the indicated name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_TexCoordf Geom::
|
||||
get_texcoords_array(const TexCoordName *name) const {
|
||||
get_texcoords_array(const InternalName *name) const {
|
||||
TexCoordsByName::const_iterator tci = _texcoords_by_name.find(name);
|
||||
if (tci != _texcoords_by_name.end()) {
|
||||
return (*tci).second._texcoords;
|
||||
|
|
@ -174,11 +174,11 @@ get_colors_index() const {
|
|||
// returns the default texture coordinates only. In the
|
||||
// presence of multitexturing, use the version of
|
||||
// get_texcoords_array() method that takes a
|
||||
// TexCoordName parameter.
|
||||
// InternalName parameter.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_ushort Geom::
|
||||
get_texcoords_index() const {
|
||||
return get_texcoords_index(TexCoordName::get_default());
|
||||
return get_texcoords_index(InternalName::get_texcoord());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -192,7 +192,7 @@ get_texcoords_index() const {
|
|||
// the geom does not use indexed texcoords.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_ushort Geom::
|
||||
get_texcoords_index(const TexCoordName *name) const {
|
||||
get_texcoords_index(const InternalName *name) const {
|
||||
TexCoordsByName::const_iterator tci = _texcoords_by_name.find(name);
|
||||
if (tci != _texcoords_by_name.end()) {
|
||||
return (*tci).second._tindex;
|
||||
|
|
@ -368,7 +368,7 @@ get_next_normal(NormalIterator &niterator) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::TexCoordIterator Geom::
|
||||
make_texcoord_iterator() const {
|
||||
return make_texcoord_iterator(TexCoordName::get_default());
|
||||
return make_texcoord_iterator(InternalName::get_texcoord());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -377,7 +377,7 @@ make_texcoord_iterator() const {
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Geom::TexCoordIterator Geom::
|
||||
make_texcoord_iterator(const TexCoordName *texcoord_name) const {
|
||||
make_texcoord_iterator(const InternalName *texcoord_name) const {
|
||||
check_config();
|
||||
TexCoordIterator i;
|
||||
|
||||
|
|
|
|||
|
|
@ -392,7 +392,7 @@ set_colors(const PTA_Colorf &colors, GeomBindType bind,
|
|||
// Access: Published
|
||||
// Description: This single-texturing version of set_texcoords() only
|
||||
// changes the default texcoords name. Use the version
|
||||
// of set_texcoords() that takes a TexCoordName
|
||||
// of set_texcoords() that takes a InternalName
|
||||
// parameter to set up different texture coordinates for
|
||||
// different stages of a multitexture pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -402,9 +402,9 @@ set_texcoords(const PTA_TexCoordf &texcoords, GeomBindType bind,
|
|||
nassertv(bind == G_PER_VERTEX || bind == G_OFF);
|
||||
|
||||
if (bind == G_OFF) {
|
||||
remove_texcoords(TexCoordName::get_default());
|
||||
remove_texcoords(InternalName::get_texcoord());
|
||||
} else {
|
||||
set_texcoords(TexCoordName::get_default(), texcoords, tindex);
|
||||
set_texcoords(InternalName::get_texcoord(), texcoords, tindex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -417,9 +417,9 @@ set_texcoords(const PTA_TexCoordf &texcoords, GeomBindType bind,
|
|||
// remove_texcoords().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Geom::
|
||||
set_texcoords(const TexCoordName *name, const PTA_TexCoordf &texcoords,
|
||||
set_texcoords(const InternalName *name, const PTA_TexCoordf &texcoords,
|
||||
const PTA_ushort &tindex) {
|
||||
nassertv(name != (TexCoordName *)NULL);
|
||||
nassertv(name != (InternalName *)NULL);
|
||||
|
||||
#ifndef NDEBUG
|
||||
// All of the texture coordinates must be either nonindexed, or all
|
||||
|
|
@ -438,7 +438,7 @@ set_texcoords(const TexCoordName *name, const PTA_TexCoordf &texcoords,
|
|||
def._texcoords = texcoords;
|
||||
def._tindex = tindex;
|
||||
|
||||
if (name == TexCoordName::get_default()) {
|
||||
if (name == InternalName::get_texcoord()) {
|
||||
_bind[G_TEXCOORD] = G_PER_VERTEX;
|
||||
}
|
||||
|
||||
|
|
@ -454,10 +454,10 @@ set_texcoords(const TexCoordName *name, const PTA_TexCoordf &texcoords,
|
|||
// set_texcoords().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Geom::
|
||||
remove_texcoords(const TexCoordName *name) {
|
||||
remove_texcoords(const InternalName *name) {
|
||||
_texcoords_by_name.erase(name);
|
||||
|
||||
if (name == TexCoordName::get_default()) {
|
||||
if (name == InternalName::get_texcoord()) {
|
||||
_bind[G_TEXCOORD] = G_OFF;
|
||||
}
|
||||
|
||||
|
|
@ -529,7 +529,7 @@ void Geom::
|
|||
get_texcoords(PTA_TexCoordf &texcoords, GeomBindType &bind,
|
||||
PTA_ushort &tindex) const {
|
||||
TexCoordsByName::const_iterator tci =
|
||||
_texcoords_by_name.find(TexCoordName::get_default());
|
||||
_texcoords_by_name.find(InternalName::get_texcoord());
|
||||
if (tci != _texcoords_by_name.end()) {
|
||||
const TexCoordDef &def = (*tci).second;
|
||||
texcoords = def._texcoords;
|
||||
|
|
@ -573,6 +573,46 @@ prepare(PreparedGraphicsObjects *prepared_objects) {
|
|||
prepared_objects->enqueue_geom(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::get_num_vertices_per_prim
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Geom::
|
||||
get_num_vertices_per_prim() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::get_num_more_vertices_than_components
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Geom::
|
||||
get_num_more_vertices_than_components() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::uses_components
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool Geom::
|
||||
uses_components() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::get_length
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int Geom::
|
||||
get_length(int) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::explode
|
||||
// Access: Published, Virtual
|
||||
|
|
@ -721,7 +761,7 @@ write_verbose(ostream &out, int indent_level) const {
|
|||
for (tci = _texcoords_by_name.begin();
|
||||
tci != _texcoords_by_name.end();
|
||||
++tci) {
|
||||
const TexCoordName *name = (*tci).first;
|
||||
const InternalName *name = (*tci).first;
|
||||
const TexCoordDef &def = (*tci).second;
|
||||
if (def._tindex != (ushort *)NULL) {
|
||||
indent(out, indent_level)
|
||||
|
|
@ -762,7 +802,7 @@ setup_multitexcoord_iterator(MultiTexCoordIterator &iterator,
|
|||
if (no_texcoords.find(stage) == no_texcoords.end()) {
|
||||
// This stage is not one of the stages that doesn't need
|
||||
// texcoords issued for it.
|
||||
const TexCoordName *name = stage->get_texcoord_name();
|
||||
const InternalName *name = stage->get_texcoord_name();
|
||||
TexCoordsByName::const_iterator tci = _texcoords_by_name.find(name);
|
||||
if (tci != _texcoords_by_name.end()) {
|
||||
// This Geom does have texcoords for this stage.
|
||||
|
|
@ -952,6 +992,24 @@ config() {
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::draw_immediate
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Geom::
|
||||
draw_immediate(GraphicsStateGuardianBase *, GeomContext *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::print_draw_immediate
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void Geom::
|
||||
print_draw_immediate() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: Geom::calc_tight_bounds
|
||||
// Access: Public
|
||||
|
|
@ -1118,7 +1176,7 @@ write_datagram(BamWriter *manager, Datagram &me) {
|
|||
// write the TexCoordsByName pointers if any
|
||||
TexCoordsByName::const_iterator tci;
|
||||
for (tci = _texcoords_by_name.begin(); tci != _texcoords_by_name.end(); ++tci) {
|
||||
CPT(TexCoordName) tc = (*tci).first;
|
||||
CPT(InternalName) tc = (*tci).first;
|
||||
manager->write_pointer(me, tc);
|
||||
WRITE_PTA(manager, me, IPD_TexCoordf::write_datagram, (*tci).second._texcoords);
|
||||
WRITE_PTA(manager, me, IPD_ushort::write_datagram, (*tci).second._tindex);
|
||||
|
|
@ -1160,16 +1218,16 @@ complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
|||
for (ci = _temp_texcoord_set.begin();
|
||||
ci != _temp_texcoord_set.end();
|
||||
++ci) {
|
||||
CPT(TexCoordName) tc = DCAST(TexCoordName, p_list[pi++]);
|
||||
CPT(InternalName) tc = DCAST(InternalName, p_list[pi++]);
|
||||
TexCoordDef *def = (*ci);
|
||||
_texcoords_by_name[tc] = *def;
|
||||
/*
|
||||
cerr << "TexCoordName from Geom " << (void *)this
|
||||
cerr << "InternalName from Geom " << (void *)this
|
||||
<< " complete pointers " << tc << " " << *tc
|
||||
<< " = " << def->_texcoords << " and " << def->_tindex << "\n";
|
||||
*/
|
||||
delete def;
|
||||
if (tc == TexCoordName::get_default()) {
|
||||
if (tc == InternalName::get_texcoord()) {
|
||||
_bind[G_TEXCOORD] = G_PER_VERTEX;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "pta_TexCoordf.h"
|
||||
#include "pta_ushort.h"
|
||||
#include "pta_int.h"
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
#include "textureStage.h"
|
||||
#include "pset.h"
|
||||
|
||||
|
|
@ -146,9 +146,9 @@ PUBLISHED:
|
|||
const PTA_ushort &cindex = PTA_ushort());
|
||||
void set_texcoords(const PTA_TexCoordf &texcoords, GeomBindType bind,
|
||||
const PTA_ushort &tindex = PTA_ushort());
|
||||
void set_texcoords(const TexCoordName *name, const PTA_TexCoordf &texcoords,
|
||||
void set_texcoords(const InternalName *name, const PTA_TexCoordf &texcoords,
|
||||
const PTA_ushort &tindex = PTA_ushort());
|
||||
void remove_texcoords(const TexCoordName *name);
|
||||
void remove_texcoords(const InternalName *name);
|
||||
|
||||
public:
|
||||
// These can't be published because of the pass-by-reference
|
||||
|
|
@ -171,19 +171,19 @@ PUBLISHED:
|
|||
|
||||
INLINE GeomBindType get_binding(int attr) const;
|
||||
INLINE bool has_any_texcoords() const;
|
||||
INLINE bool has_texcoords(const TexCoordName *name) const;
|
||||
INLINE bool has_texcoords(const InternalName *name) const;
|
||||
|
||||
INLINE PTA_Vertexf get_coords_array() const;
|
||||
INLINE PTA_Normalf get_normals_array() const;
|
||||
INLINE PTA_Colorf get_colors_array() const;
|
||||
INLINE PTA_TexCoordf get_texcoords_array() const;
|
||||
INLINE PTA_TexCoordf get_texcoords_array(const TexCoordName *name) const;
|
||||
INLINE PTA_TexCoordf get_texcoords_array(const InternalName *name) const;
|
||||
|
||||
INLINE PTA_ushort get_coords_index() const;
|
||||
INLINE PTA_ushort get_normals_index() const;
|
||||
INLINE PTA_ushort get_colors_index() const;
|
||||
INLINE PTA_ushort get_texcoords_index() const;
|
||||
INLINE PTA_ushort get_texcoords_index(const TexCoordName *name) const;
|
||||
INLINE PTA_ushort get_texcoords_index(const InternalName *name) const;
|
||||
INLINE bool are_texcoords_indexed() const;
|
||||
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
|
|
@ -194,16 +194,16 @@ PUBLISHED:
|
|||
INLINE void set_lengths(const PTA_int &lengths);
|
||||
INLINE PTA_int get_lengths() const;
|
||||
|
||||
virtual int get_num_vertices_per_prim() const=0;
|
||||
virtual int get_num_more_vertices_than_components() const=0;
|
||||
virtual bool uses_components() const=0;
|
||||
virtual int get_num_vertices_per_prim() const;
|
||||
virtual int get_num_more_vertices_than_components() const;
|
||||
virtual bool uses_components() const;
|
||||
|
||||
INLINE int get_num_vertices() const;
|
||||
|
||||
// Returns the length of the indicated primitive. Often this is the
|
||||
// same for all primitives in the Geom. However, geoms which use
|
||||
// the lengths array will redefine this appropriately.
|
||||
virtual int get_length(int prim) const=0;
|
||||
virtual int get_length(int prim) const;
|
||||
|
||||
virtual Geom *explode() const;
|
||||
virtual PTA_ushort get_tris() const;
|
||||
|
|
@ -223,7 +223,7 @@ public:
|
|||
INLINE const Normalf &get_next_normal(NormalIterator &niterator) const;
|
||||
|
||||
INLINE TexCoordIterator make_texcoord_iterator() const;
|
||||
INLINE TexCoordIterator make_texcoord_iterator(const TexCoordName *texcoord_name) const;
|
||||
INLINE TexCoordIterator make_texcoord_iterator(const InternalName *texcoord_name) const;
|
||||
INLINE const TexCoordf &get_next_texcoord(TexCoordIterator &tciterator) const;
|
||||
void setup_multitexcoord_iterator(MultiTexCoordIterator &iterator,
|
||||
const ActiveTextureStages &active_stages,
|
||||
|
|
@ -245,8 +245,8 @@ public:
|
|||
virtual void config();
|
||||
|
||||
// Immediate mode drawing functions - issue graphics commands
|
||||
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc) = 0;
|
||||
virtual void print_draw_immediate() const = 0;
|
||||
virtual void draw_immediate(GraphicsStateGuardianBase *gsg, GeomContext *gc);
|
||||
virtual void print_draw_immediate() const;
|
||||
|
||||
void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
||||
bool &found_any) const;
|
||||
|
|
@ -277,7 +277,7 @@ protected:
|
|||
|
||||
// A pmap, not a phash_map, to save space because it will probably
|
||||
// have only one element.
|
||||
typedef pmap<CPT(TexCoordName), TexCoordDef> TexCoordsByName;
|
||||
typedef pmap<CPT(InternalName), TexCoordDef> TexCoordsByName;
|
||||
TexCoordsByName _texcoords_by_name;
|
||||
|
||||
// Functions to extract component values, one at a time.
|
||||
|
|
@ -286,7 +286,7 @@ protected:
|
|||
GetNextColor *_get_color;
|
||||
GetNextTexCoord *_get_texcoord;
|
||||
|
||||
// temporary storage until complete_pointers fills in _texcoords_by_name's TexCoordName *
|
||||
// temporary storage until complete_pointers fills in _texcoords_by_name's InternalName *
|
||||
typedef pvector<TexCoordDef *> TexCoordDefSet;
|
||||
TexCoordDefSet _temp_texcoord_set;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,4 +11,14 @@
|
|||
#include "geomTri.cxx"
|
||||
#include "geomTrifan.cxx"
|
||||
#include "geomTristrip.cxx"
|
||||
|
||||
#include "qpgeom.cxx"
|
||||
#include "qpgeomMunger.cxx"
|
||||
#include "qpgeomPrimitive.cxx"
|
||||
#include "qpgeomTriangles.cxx"
|
||||
#include "qpgeomTristrips.cxx"
|
||||
#include "qpgeomTrifans.cxx"
|
||||
#include "qpgeomVertexArrayFormat.cxx"
|
||||
#include "qpgeomVertexData.cxx"
|
||||
#include "qpgeomVertexDataType.cxx"
|
||||
#include "qpgeomVertexFormat.cxx"
|
||||
#include "qpgeomVertexIterator.cxx"
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
#include "config_gobj.cxx"
|
||||
#include "drawable.cxx"
|
||||
#include "geomContext.cxx"
|
||||
#include "internalName.cxx"
|
||||
#include "material.cxx"
|
||||
#include "materialPool.cxx"
|
||||
#include "orthographicLens.cxx"
|
||||
|
|
@ -13,5 +14,4 @@
|
|||
#include "texture.cxx"
|
||||
#include "textureContext.cxx"
|
||||
#include "texturePool.cxx"
|
||||
#include "texCoordName.cxx"
|
||||
#include "textureStage.cxx"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
// Filename: internalName.I
|
||||
// Created by: masad (15Jul04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: InternalName::make
|
||||
// Access: Published, Static
|
||||
// Description: The public interface for constructing an InternalName
|
||||
// pointer. This will return a new InternalName
|
||||
// representing the indicated name, if this is the first
|
||||
// time the particular name has been requested; if the
|
||||
// name is already in use, it will return the existing
|
||||
// pointer.
|
||||
//
|
||||
// If the string contains the '.' character, the string
|
||||
// will be divided at the dots and the so-defined
|
||||
// hierarchy of names will be registered. This is
|
||||
// handled transparently.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
make(const string &name) {
|
||||
return get_root()->append(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_parent
|
||||
// Access: Published
|
||||
// Description: Return the parent of this InternalName. All names
|
||||
// have a parent, except the root name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE InternalName *InternalName::
|
||||
get_parent() const {
|
||||
return _parent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_basename
|
||||
// Access: Published
|
||||
// Description: Return the name represented by just this particular
|
||||
// InternalName object, ignoring its parents names.
|
||||
// This is everything after the rightmost dot.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &InternalName::
|
||||
get_basename() const {
|
||||
return _basename;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_root
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard root InternalName. This is the
|
||||
// root of all other InternalNames. It has no name
|
||||
// itself, and it is the only InternalName with no
|
||||
// parent.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_root() {
|
||||
if (_root == (InternalName *)NULL) {
|
||||
_root = new InternalName(NULL, "");
|
||||
}
|
||||
return _root;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_error
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard InternalName "error".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_error() {
|
||||
if (_error == (InternalName *)NULL) {
|
||||
_error = InternalName::make("error");
|
||||
}
|
||||
return _error;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_vertex
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard InternalName "vertex".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_vertex() {
|
||||
if (_vertex == (InternalName *)NULL) {
|
||||
_vertex = InternalName::make("vertex");
|
||||
}
|
||||
return _vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_normal
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard InternalName "normal".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_normal() {
|
||||
if (_normal == (InternalName *)NULL) {
|
||||
_normal = InternalName::make("normal");
|
||||
}
|
||||
return _normal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_tangent
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard InternalName "tangent".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_tangent() {
|
||||
if (_tangent == (InternalName *)NULL) {
|
||||
_tangent = InternalName::make("tangent");
|
||||
}
|
||||
return _tangent;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_binormal
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard InternalName "binormal".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_binormal() {
|
||||
if (_binormal == (InternalName *)NULL) {
|
||||
_binormal = InternalName::make("binormal");
|
||||
}
|
||||
return _binormal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_texcoord
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard InternalName "texcoord".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_texcoord() {
|
||||
if (_texcoord == (InternalName *)NULL) {
|
||||
_texcoord = InternalName::make("texcoord");
|
||||
}
|
||||
return _texcoord;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_texcoord_name
|
||||
// Access: Published, Static
|
||||
// Description: Returns the InternalName "texcoord.name", where name
|
||||
// is the supplied string. This, by convention,
|
||||
// represents the named texture coordinate set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_texcoord_name(const string &name) {
|
||||
return get_texcoord()->append(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_color
|
||||
// Access: Published, Static
|
||||
// Description: Returns the standard InternalName "color".
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(InternalName) InternalName::
|
||||
get_color() {
|
||||
if (_color == (InternalName *)NULL) {
|
||||
_color = InternalName::make("color");
|
||||
}
|
||||
return _color;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const InternalName &tcn) {
|
||||
tcn.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
// Filename: internalName.cxx
|
||||
// Created by: masad (15Jul04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "internalName.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "bamReader.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
|
||||
PT(InternalName) InternalName::_root;
|
||||
PT(InternalName) InternalName::_error;
|
||||
PT(InternalName) InternalName::_default;
|
||||
PT(InternalName) InternalName::_vertex;
|
||||
PT(InternalName) InternalName::_normal;
|
||||
PT(InternalName) InternalName::_tangent;
|
||||
PT(InternalName) InternalName::_binormal;
|
||||
PT(InternalName) InternalName::_texcoord;
|
||||
PT(InternalName) InternalName::_color;
|
||||
|
||||
TypeHandle InternalName::_type_handle;
|
||||
TypeHandle InternalName::_texcoord_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::Constructor
|
||||
// Access: Private
|
||||
// Description: Use make() to make a new InternalName instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InternalName::
|
||||
InternalName(InternalName *parent, const string &basename) :
|
||||
_parent(parent),
|
||||
_basename(basename)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
InternalName::
|
||||
~InternalName() {
|
||||
if (_parent != (const InternalName *)NULL) {
|
||||
NameTable::iterator ni = _parent->_name_table.find(_basename);
|
||||
nassertv(ni != _parent->_name_table.end());
|
||||
_parent->_name_table.erase(ni);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::append
|
||||
// Access: Published
|
||||
// Description: Constructs a new InternalName based on this name,
|
||||
// with the indicated string following it. This is a
|
||||
// cheaper way to construct a hierarchical name than
|
||||
// InternalName::make(parent->get_name() + ".basename").
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(InternalName) InternalName::
|
||||
append(const string &name) {
|
||||
if (name.empty()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
size_t dot = name.rfind('.');
|
||||
if (dot != string::npos) {
|
||||
return append(name.substr(0, dot))->append(name.substr(dot + 1));
|
||||
}
|
||||
|
||||
NameTable::iterator ni = _name_table.find(name);
|
||||
if (ni != _name_table.end()) {
|
||||
return (*ni).second;
|
||||
}
|
||||
|
||||
PT(InternalName) internal_name = new InternalName(this, name);
|
||||
_name_table[name] = internal_name;
|
||||
return internal_name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::get_name
|
||||
// Access: Published
|
||||
// Description: Returns the complete name represented by the
|
||||
// InternalName and all of its parents.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string InternalName::
|
||||
get_name() const {
|
||||
if (_parent == get_root()) {
|
||||
return _basename;
|
||||
|
||||
} else if (_parent == (InternalName *)NULL) {
|
||||
return string();
|
||||
|
||||
} else {
|
||||
return _parent->get_name() + "." + _basename;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InternalName::
|
||||
output(ostream &out) const {
|
||||
if (_parent == get_root()) {
|
||||
out << _basename;
|
||||
|
||||
} else if (_parent == (InternalName *)NULL) {
|
||||
out << "(root)";
|
||||
|
||||
} else {
|
||||
_parent->output(out);
|
||||
out << '.' << _basename;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Factory method to generate a InternalName object
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InternalName::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
BamReader::get_factory()->register_factory(_texcoord_type_handle, make_texcoord_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::finalize
|
||||
// Access: Public, Virtual
|
||||
// Description: Method to ensure that any necessary clean up tasks
|
||||
// that have to be performed by this object are performed
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InternalName::
|
||||
finalize() {
|
||||
// Unref the pointer that we explicitly reffed in make_from_bam().
|
||||
unref();
|
||||
|
||||
// We should never get back to zero after unreffing our own count,
|
||||
// because we expect to have been stored in a pointer somewhere. If
|
||||
// we do get to zero, it's a memory leak; the way to avoid this is
|
||||
// to call unref_delete() above instead of unref(), but this is
|
||||
// dangerous to do from within a virtual function.
|
||||
nassertv(get_ref_count() != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type InternalName is encountered
|
||||
// in the Bam file. It should create the InternalName
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *InternalName::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
// The process of making a InternalName is slightly
|
||||
// different than making other Writable objects.
|
||||
// That is because all creation of InternalNames should
|
||||
// be done through the make() constructor.
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
|
||||
// The name is the only thing written to the data stream.
|
||||
string name = scan.get_string();
|
||||
|
||||
// Make a new InternalName with that name (or get the previous one
|
||||
// if there is one already).
|
||||
PT(InternalName) me = make(name);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
me->ref();
|
||||
manager->register_finalize(me);
|
||||
|
||||
return me.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::make_texcoord_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This is a temporary method; it exists only to support
|
||||
// old bam files (4.11 through 4.17) generated before we
|
||||
// renamed this class from TexCoordName to InternalName.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *InternalName::
|
||||
make_texcoord_from_bam(const FactoryParams ¶ms) {
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
parse_params(params, scan, manager);
|
||||
|
||||
string name = scan.get_string();
|
||||
PT(InternalName) me = get_texcoord_name(name);
|
||||
|
||||
me->ref();
|
||||
manager->register_finalize(me);
|
||||
|
||||
return me.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalName::write_datagram
|
||||
// Access: Public
|
||||
// Description: Function to write the important information in
|
||||
// the particular object to a Datagram
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InternalName::
|
||||
write_datagram(BamWriter *manager, Datagram &me) {
|
||||
me.add_string(get_name());
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
// Filename: internalName.h
|
||||
// Created by: drose (15Jul04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 INTERNALNAME_H
|
||||
#define INTERNALNAME_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class FactoryParams;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : InternalName
|
||||
// Description : Encodes a string name in a hash table, mapping it to
|
||||
// a pointer. This is used to tokenify names so they
|
||||
// may be used efficiently in low-level Panda
|
||||
// structures, for instance to differentiate the
|
||||
// multiple sets of texture coordinates that might be
|
||||
// stored on a Geom.
|
||||
//
|
||||
// InternalNames are hierarchical, with the '.' used by
|
||||
// convention as a separator character. You can
|
||||
// construct a single InternalName as a composition of
|
||||
// one or more other names, or by giving it a source
|
||||
// string directly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA InternalName : public TypedWritableReferenceCount {
|
||||
private:
|
||||
InternalName(InternalName *parent, const string &basename);
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~InternalName();
|
||||
INLINE static PT(InternalName) make(const string &name);
|
||||
PT(InternalName) append(const string &basename);
|
||||
|
||||
INLINE InternalName *get_parent() const;
|
||||
string get_name() const;
|
||||
INLINE const string &get_basename() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
// Some predefined built-in names.
|
||||
INLINE static PT(InternalName) get_root();
|
||||
INLINE static PT(InternalName) get_error();
|
||||
INLINE static PT(InternalName) get_vertex();
|
||||
INLINE static PT(InternalName) get_normal();
|
||||
INLINE static PT(InternalName) get_tangent();
|
||||
INLINE static PT(InternalName) get_binormal();
|
||||
INLINE static PT(InternalName) get_texcoord();
|
||||
INLINE static PT(InternalName) get_texcoord_name(const string &name);
|
||||
INLINE static PT(InternalName) get_color();
|
||||
|
||||
private:
|
||||
PT(InternalName) _parent;
|
||||
string _basename;
|
||||
|
||||
typedef phash_map<string, InternalName *, string_hash> NameTable;
|
||||
NameTable _name_table;
|
||||
|
||||
static PT(InternalName) _root;
|
||||
static PT(InternalName) _error;
|
||||
static PT(InternalName) _default;
|
||||
static PT(InternalName) _vertex;
|
||||
static PT(InternalName) _normal;
|
||||
static PT(InternalName) _tangent;
|
||||
static PT(InternalName) _binormal;
|
||||
static PT(InternalName) _texcoord;
|
||||
static PT(InternalName) _color;
|
||||
|
||||
public:
|
||||
// Datagram stuff
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
|
||||
virtual void finalize();
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
static TypedWritable *make_texcoord_from_bam(const FactoryParams ¶ms);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedWritableReferenceCount::init_type();
|
||||
register_type(_type_handle, "InternalName",
|
||||
TypedWritableReferenceCount::get_class_type());
|
||||
// The _texcoord_type_handle is defined only to support older bam
|
||||
// files, generated before we renamed the type to InternalName.
|
||||
register_type(_texcoord_type_handle, "TexCoordName",
|
||||
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;
|
||||
static TypeHandle _texcoord_type_handle;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const InternalName &tcn);
|
||||
|
||||
#include "internalName.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
// Filename: qpgeom.I
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeom::get_vertex_data
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the GeomVertexData,
|
||||
// for application code to directly examine (but not
|
||||
// modify) the geom's underlying data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexData) qpGeom::
|
||||
get_vertex_data() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_num_primitives
|
||||
// Access: Published
|
||||
// Description: Returns the number of GeomPrimitive objects stored
|
||||
// within the Geom, each of which represents a number of
|
||||
// primitives of a particular type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeom::
|
||||
get_num_primitives() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_primitives.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::get_primitive
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the ith GeomPrimitive
|
||||
// object stored within the Geom. Use this call only to
|
||||
// inspect the ith object; use modify_primitive() or
|
||||
// set_primitive() if you want to modify it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomPrimitive *qpGeom::
|
||||
get_primitive(int i) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL);
|
||||
return cdata->_primitives[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::modify_primitive
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the ith GeomPrimitive
|
||||
// object stored within the Geom, so application code
|
||||
// can directly manipulate the properties of this
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomPrimitive *qpGeom::
|
||||
modify_primitive(int i) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertr(i >= 0 && i < (int)cdata->_primitives.size(), NULL);
|
||||
return cdata->_primitives[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::set_primitive
|
||||
// Access: Published
|
||||
// Description: Replaces the ith GeomPrimitive object stored within
|
||||
// the Geom with the new object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeom::
|
||||
set_primitive(int i, qpGeomPrimitive *primitive) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
||||
cdata->_primitives[i] = primitive;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeom::CData::
|
||||
CData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeom::CData::
|
||||
CData(const qpGeom::CData ©) :
|
||||
_data(copy._data),
|
||||
_primitives(copy._primitives)
|
||||
{
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const qpGeom &obj) {
|
||||
obj.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,395 @@
|
|||
// Filename: qpgeom.cxx
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeom.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
|
||||
TypeHandle qpGeom::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeom::
|
||||
qpGeom() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeom::
|
||||
qpGeom(const qpGeom ©) :
|
||||
/*
|
||||
TypedWritableReferenceCount(copy),
|
||||
BoundedObject(copy),
|
||||
*/
|
||||
Geom(copy),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
operator = (const qpGeom ©) {
|
||||
/*
|
||||
TypedWritableReferenceCount::operator = (copy);
|
||||
BoundedObject::operator = (copy);
|
||||
*/
|
||||
Geom::operator = (copy);
|
||||
_cycler = copy._cycler;
|
||||
mark_bound_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeom::
|
||||
~qpGeom() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::make_copy
|
||||
// Access: Published, Virtual
|
||||
// Description: Temporarily redefined from Geom base class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
Geom *qpGeom::
|
||||
make_copy() const {
|
||||
return new qpGeom(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::modify_vertex_data
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the GeomVertexData,
|
||||
// so that application code may directly maniuplate the
|
||||
// geom's underlying data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(qpGeomVertexData) qpGeom::
|
||||
modify_vertex_data() {
|
||||
// Perform copy-on-write: if the reference count on the vertex data
|
||||
// is greater than 1, assume some other Geom has the same pointer,
|
||||
// so make a copy of it first.
|
||||
|
||||
CDWriter cdata(_cycler);
|
||||
if (cdata->_data->get_ref_count() > 1) {
|
||||
cdata->_data = new qpGeomVertexData(*cdata->_data);
|
||||
}
|
||||
mark_bound_stale();
|
||||
return cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::set_vertex_data
|
||||
// Access: Published
|
||||
// Description: Replaces the Geom's underlying vertex data table with
|
||||
// a completely new table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
set_vertex_data(PT(qpGeomVertexData) data) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_data = data;
|
||||
mark_bound_stale();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::add_primitive
|
||||
// Access: Published
|
||||
// Description: Adds a new GeomPrimitive structure to the Geom
|
||||
// object. This specifies a particular subset of
|
||||
// vertices that are used to define geometric primitives
|
||||
// of the indicated type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
add_primitive(qpGeomPrimitive *primitive) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_primitives.push_back(primitive);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::remove_primitive
|
||||
// Access: Published
|
||||
// Description: Removes the ith primitive from the list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
remove_primitive(int i) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(i >= 0 && i < (int)cdata->_primitives.size());
|
||||
cdata->_primitives.erase(cdata->_primitives.begin() + i);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::clear_primitives
|
||||
// Access: Published
|
||||
// Description: Removes all the primitives from the Geom object (but
|
||||
// keeps the same table of vertices). You may then
|
||||
// re-add primitives one at a time via calls to
|
||||
// add_primitive().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
clear_primitives() {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_primitives.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
output(ostream &out) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
// Get a list of the primitive types contained within this object.
|
||||
pset<TypeHandle> types;
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
types.insert((*pi)->get_type());
|
||||
}
|
||||
|
||||
out << "Geom [";
|
||||
pset<TypeHandle>::iterator ti;
|
||||
for (ti = types.begin(); ti != types.end(); ++ti) {
|
||||
out << " " << (*ti);
|
||||
}
|
||||
out << " ], " << cdata->_data->get_num_vertices() << " vertices.";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
write(ostream &out, int indent_level) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
// Get a list of the primitive types contained within this object.
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
(*pi)->write(out, cdata->_data, indent_level);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::draw
|
||||
// Access: Public
|
||||
// Description: Actually draws the Geom with the indicated GSG.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
draw(GraphicsStateGuardianBase *gsg) const {
|
||||
// PreparedGraphicsObjects *prepared_objects = gsg->get_prepared_objects();
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
gsg->begin_draw_primitives(cdata->_data);
|
||||
|
||||
Primitives::const_iterator pi;
|
||||
for (pi = cdata->_primitives.begin();
|
||||
pi != cdata->_primitives.end();
|
||||
++pi) {
|
||||
(*pi)->draw(gsg);
|
||||
}
|
||||
|
||||
gsg->end_draw_primitives();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::recompute_bound
|
||||
// Access: Protected, Virtual
|
||||
// Description: Recomputes the dynamic bounding volume for this Geom.
|
||||
// This includes all of the vertices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
BoundingVolume *qpGeom::
|
||||
recompute_bound() {
|
||||
// First, get ourselves a fresh, empty bounding volume.
|
||||
BoundingVolume *bound = BoundedObject::recompute_bound();
|
||||
nassertr(bound != (BoundingVolume*)0L, bound);
|
||||
|
||||
GeometricBoundingVolume *gbv = DCAST(GeometricBoundingVolume, bound);
|
||||
|
||||
// Now actually compute the bounding volume by putting it around all
|
||||
// of our vertices.
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
const qpGeomVertexFormat *format = cdata->_data->get_format();
|
||||
|
||||
int array_index = format->get_array_with(InternalName::get_vertex());
|
||||
if (array_index < 0) {
|
||||
// No vertex data.
|
||||
return bound;
|
||||
}
|
||||
|
||||
const qpGeomVertexArrayFormat *array_format = format->get_array(array_index);
|
||||
const qpGeomVertexDataType *data_type =
|
||||
array_format->get_data_type(InternalName::get_vertex());
|
||||
|
||||
int stride = array_format->get_stride();
|
||||
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);
|
||||
|
||||
if (stride == 3 * sizeof(PN_float32) && start == 0 && num_components == 3 &&
|
||||
(array_data.size() % stride) == 0) {
|
||||
// Here's an easy special case: it's a standalone table of vertex
|
||||
// positions, with nothing else in the middle, so we can use
|
||||
// directly as an array of LPoint3f's.
|
||||
const LPoint3f *vertices_begin = (const LPoint3f *)&array_data[0];
|
||||
const LPoint3f *vertices_end = (const LPoint3f *)&array_data[array_data.size()];
|
||||
gbv->around(vertices_begin, vertices_end);
|
||||
|
||||
} else {
|
||||
// Otherwise, we have to copy the vertex positions out one at time.
|
||||
pvector<LPoint3f> vertices;
|
||||
|
||||
size_t p = start;
|
||||
while (p + stride <= array_data.size()) {
|
||||
const PN_float32 *v = (const PN_float32 *)&array_data[p];
|
||||
|
||||
LPoint3f vertex;
|
||||
qpGeomVertexData::to_vec3(vertex, v, num_components);
|
||||
|
||||
vertices.push_back(vertex);
|
||||
p += stride;
|
||||
}
|
||||
|
||||
const LPoint3f *vertices_begin = &vertices[0];
|
||||
const LPoint3f *vertices_end = vertices_begin + vertices.size();
|
||||
|
||||
gbv->around(vertices_begin, vertices_end);
|
||||
}
|
||||
|
||||
return bound;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritable::write_datagram(manager, dg);
|
||||
|
||||
manager->write_cdata(dg, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeom is encountered
|
||||
// in the Bam file. It should create the qpGeom
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeom::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeom *object = new qpGeom;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::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 qpGeom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritable::fillin(scan, manager);
|
||||
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *qpGeom::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::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 qpGeom::CData::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = CycleData::complete_pointers(p_list, manager);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeom::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 qpGeom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeom::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
// Filename: qpgeom.h
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOM_H
|
||||
#define qpGEOM_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "boundedObject.h"
|
||||
#include "cycleData.h"
|
||||
#include "cycleDataReader.h"
|
||||
#include "cycleDataWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
#include "pointerTo.h"
|
||||
#include "geom.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeom
|
||||
// Description : A container for geometry primitives. This class
|
||||
// associates one or more GeomPrimitive objects with a
|
||||
// table of vertices defined by a GeomVertexData object.
|
||||
// All of the primitives stored in a particular Geom are
|
||||
// drawn from the same set of vertices (each primitive
|
||||
// uses a subset of all of the vertices in the table),
|
||||
// and all of them must be rendered at the same time, in
|
||||
// the same graphics state.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeom /* : public TypedWritableReferenceCount, public BoundedObject */
|
||||
// We temporarily inherit from Geom, merely so we can store this
|
||||
// pointer where a Geom should go, while we have both implementations
|
||||
// in the codebase. We pick up some additional cruft from Geom that
|
||||
// we're not really using.
|
||||
: public Geom
|
||||
{
|
||||
PUBLISHED:
|
||||
qpGeom();
|
||||
qpGeom(const qpGeom ©);
|
||||
void operator = (const qpGeom ©);
|
||||
virtual ~qpGeom();
|
||||
|
||||
// Temporary.
|
||||
virtual Geom *make_copy() const;
|
||||
|
||||
INLINE CPT(qpGeomVertexData) get_vertex_data() const;
|
||||
PT(qpGeomVertexData) modify_vertex_data();
|
||||
void set_vertex_data(PT(qpGeomVertexData) data);
|
||||
|
||||
INLINE int get_num_primitives() const;
|
||||
INLINE const qpGeomPrimitive *get_primitive(int i) const;
|
||||
INLINE qpGeomPrimitive *modify_primitive(int i);
|
||||
INLINE void set_primitive(int i, qpGeomPrimitive *primitive);
|
||||
void add_primitive(qpGeomPrimitive *primitive);
|
||||
void remove_primitive(int i);
|
||||
void clear_primitives();
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
public:
|
||||
void draw(GraphicsStateGuardianBase *gsg) const;
|
||||
|
||||
protected:
|
||||
virtual BoundingVolume *recompute_bound();
|
||||
|
||||
private:
|
||||
typedef pvector<PT(qpGeomPrimitive) > Primitives;
|
||||
|
||||
// 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);
|
||||
|
||||
PT(qpGeomVertexData) _data;
|
||||
Primitives _primitives;
|
||||
};
|
||||
|
||||
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();
|
||||
BoundedObject::init_type();*/
|
||||
Geom::init_type();
|
||||
register_type(_type_handle, "qpGeom",
|
||||
Geom::get_class_type()
|
||||
/*TypedWritableReferenceCount::get_class_type(),
|
||||
BoundedObject::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;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpGeom &obj);
|
||||
|
||||
#include "qpgeom.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
// Filename: qpgeomMunger.I
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeomMunger::is_registered
|
||||
// Access: Published
|
||||
// Description: Returns true if this munger has been registered,
|
||||
// false if it has not. It may not be used for a Geom
|
||||
// until it has been registered, but once registered, it
|
||||
// may no longer be modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomMunger::
|
||||
is_registered() const {
|
||||
return _is_registered;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::register_munger
|
||||
// Access: Published, Static
|
||||
// Description: Adds the indicated munger to the registry, if there
|
||||
// is not an equivalent munger already there; in either
|
||||
// case, returns the pointer to the equivalent munger
|
||||
// now in the registry.
|
||||
//
|
||||
// This must be called before a munger may be used in a
|
||||
// Geom. After this call, you should discard the
|
||||
// original pointer you passed in (which may or may not
|
||||
// now be invalid) and let its reference count decrement
|
||||
// normally; you should use only the returned value from
|
||||
// this point on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomMunger) qpGeomMunger::
|
||||
register_munger(qpGeomMunger *munger) {
|
||||
return get_registry()->register_munger(munger);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::compare_to
|
||||
// Access: Public
|
||||
// Description: Provides an arbitrary ordering among all unique
|
||||
// GeomMungers, so we can store the essentially
|
||||
// different ones in a big set and throw away the rest.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomMunger::
|
||||
compare_to(const qpGeomMunger &other) const {
|
||||
// First, we compare the types; if they are of different types then
|
||||
// they sort differently.
|
||||
TypeHandle type = get_type();
|
||||
TypeHandle other_type = other.get_type();
|
||||
if (type != other_type) {
|
||||
return type.get_index() - other_type.get_index();
|
||||
}
|
||||
|
||||
// We only call compare_to_impl() if they have the same type.
|
||||
return compare_to_impl(&other);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::munge_data
|
||||
// Access: Public
|
||||
// Description: Given a source GeomVertexData, converts it if
|
||||
// necessary to the appropriate data for rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexData) qpGeomMunger::
|
||||
munge_data(const qpGeomVertexData *data) const {
|
||||
// We cast away the const pointer, because do_munge_data() needs to
|
||||
// update caches and stuff, but we trust it not to change any
|
||||
// user-definable parameters.
|
||||
return ((qpGeomMunger *)this)->do_munge_data(data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::munge_format
|
||||
// Access: Public
|
||||
// Description: Given a source GeomVertexFormat, converts it if
|
||||
// necessary to the appropriate format for rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexFormat) qpGeomMunger::
|
||||
munge_format(const qpGeomVertexFormat *format) const {
|
||||
// We cast away the const pointer, because do_munge_format() needs
|
||||
// to update caches and stuff, but we trust it not to change any
|
||||
// user-definable parameters.
|
||||
return ((qpGeomMunger *)this)->do_munge_format(format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::get_registry
|
||||
// Access: Private
|
||||
// Description: Returns the global registry object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomMunger::Registry *qpGeomMunger::
|
||||
get_registry() {
|
||||
if (_registry == (Registry *)NULL) {
|
||||
make_registry();
|
||||
}
|
||||
return _registry;
|
||||
}
|
||||
|
|
@ -0,0 +1,282 @@
|
|||
// Filename: qpgeomMunger.cxx
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomMunger.h"
|
||||
|
||||
qpGeomMunger::Registry *qpGeomMunger::_registry = NULL;
|
||||
TypeHandle qpGeomMunger::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomMunger::
|
||||
qpGeomMunger() :
|
||||
_is_registered(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::Destructor
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomMunger::
|
||||
~qpGeomMunger() {
|
||||
if (is_registered()) {
|
||||
get_registry()->unregister_munger(this);
|
||||
}
|
||||
nassertv(_formats.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::remove_format
|
||||
// Access: Public
|
||||
// Description: Removes a prepared GeomVertexFormat from the cache.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomMunger::
|
||||
remove_format(const qpGeomVertexFormat *format) {
|
||||
// If this assertion is triggered, maybe we accidentally deleted a
|
||||
// GeomVertexFormat while we were in the process of unregistering,
|
||||
// causing a recursive re-entry.
|
||||
nassertv(_is_registered);
|
||||
|
||||
Formats::iterator fi;
|
||||
fi = _formats.find(format);
|
||||
nassertv(fi != _formats.end());
|
||||
|
||||
CPT(qpGeomVertexFormat) derived_format = (*fi).second;
|
||||
_formats.erase(fi);
|
||||
|
||||
// We need to unref the derived format, if we reffed it earlier.
|
||||
if (derived_format != format) {
|
||||
derived_format->unref();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::remove_data
|
||||
// Access: Public
|
||||
// Description: Removes a prepared GeomVertexData from the cache.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomMunger::
|
||||
remove_data(const qpGeomVertexData *data) {
|
||||
// If this assertion is triggered, maybe we accidentally deleted a
|
||||
// GeomVertexData while we were in the process of unregistering,
|
||||
// causing a recursive re-entry.
|
||||
nassertv(_is_registered);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::do_munge_data
|
||||
// Access: Protected
|
||||
// Description: The protected implementation of munge_data(). This
|
||||
// exists just to cast away the const pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexData) qpGeomMunger::
|
||||
do_munge_data(const qpGeomVertexData *data) {
|
||||
nassertr(_is_registered, NULL);
|
||||
|
||||
CPT(qpGeomVertexFormat) orig_format = data->get_format();
|
||||
CPT(qpGeomVertexFormat) new_format = munge_format(orig_format);
|
||||
|
||||
if (new_format == orig_format) {
|
||||
// Trivial case.
|
||||
return data;
|
||||
}
|
||||
|
||||
return data->convert_to(new_format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::do_munge_format
|
||||
// Access: Protected
|
||||
// Description: The protected implementation of munge_format(). This
|
||||
// exists just to cast away the const pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexFormat) qpGeomMunger::
|
||||
do_munge_format(const qpGeomVertexFormat *format) {
|
||||
nassertr(_is_registered, NULL);
|
||||
nassertr(format->is_registered(), NULL);
|
||||
|
||||
Formats::iterator fi;
|
||||
fi = _formats.find(format);
|
||||
if (fi != _formats.end()) {
|
||||
// This format was previously munged, so the answer will be the
|
||||
// same.
|
||||
return (*fi).second;
|
||||
}
|
||||
|
||||
// We have to munge this format for the first time.
|
||||
CPT(qpGeomVertexFormat) derived_format = munge_format_impl(format);
|
||||
nassertr(derived_format->is_registered(), NULL);
|
||||
|
||||
// Store the answer in the map, so we can quickly get it next time.
|
||||
bool inserted = _formats.insert(Formats::value_type(format, derived_format)).second;
|
||||
nassertr(inserted, NULL);
|
||||
|
||||
// Tell the source format that we have its pointer.
|
||||
inserted = ((qpGeomVertexFormat *)format)->_mungers.insert(this).second;
|
||||
nassertr(inserted, NULL);
|
||||
|
||||
// We also want to keep a reference count on the derived format, but
|
||||
// only if it is actually a different pointer from the original
|
||||
// format--otherwise it would cause a self-referential reference
|
||||
// count.
|
||||
if (derived_format != format) {
|
||||
derived_format->ref();
|
||||
}
|
||||
|
||||
return derived_format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::munge_format_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Given a source GeomVertexFormat, converts it if
|
||||
// necessary to the appropriate format for rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexFormat) qpGeomMunger::
|
||||
munge_format_impl(const qpGeomVertexFormat *orig) {
|
||||
return orig;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::compare_to_impl
|
||||
// Access: Protected, Virtual
|
||||
// Description: Called to compare two GeomMungers who are known to be
|
||||
// of the same type, for an apples-to-apples comparison.
|
||||
// This will never be called on two pointers of a
|
||||
// different type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomMunger::
|
||||
compare_to_impl(const qpGeomMunger *other) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::make_registry
|
||||
// Access: Private
|
||||
// Description: Returns the global registry object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomMunger::
|
||||
make_registry() {
|
||||
if (_registry == (Registry *)NULL) {
|
||||
_registry = new Registry;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::do_register
|
||||
// Access: Private
|
||||
// Description: Called internally when the munger is registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomMunger::
|
||||
do_register() {
|
||||
nassertv(!_is_registered);
|
||||
nassertv(_formats.empty());
|
||||
|
||||
_is_registered = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::do_unregister
|
||||
// Access: Private
|
||||
// Description: Called internally when the munger is unregistered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomMunger::
|
||||
do_unregister() {
|
||||
nassertv(_is_registered);
|
||||
_is_registered = false;
|
||||
|
||||
// Unregistering means we should blow away the cache.
|
||||
Formats::iterator fi;
|
||||
for (fi = _formats.begin(); fi != _formats.end(); ++fi) {
|
||||
const qpGeomVertexFormat *format = (*fi).first;
|
||||
CPT(qpGeomVertexFormat) derived_format = (*fi).second;
|
||||
|
||||
size_t num_erased = ((qpGeomVertexFormat *)format)->_mungers.erase(this);
|
||||
nassertv(num_erased == 1);
|
||||
|
||||
if (derived_format != format) {
|
||||
derived_format->unref();
|
||||
}
|
||||
}
|
||||
_formats.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::Registry::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomMunger::Registry::
|
||||
Registry() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::Registry::register_munger
|
||||
// Access: Public
|
||||
// Description: Adds the indicated munger to the registry, if there
|
||||
// is not an equivalent munger already there; in either
|
||||
// case, returns the pointer to the equivalent munger
|
||||
// now in the registry.
|
||||
//
|
||||
// This must be called before a munger may be used in a
|
||||
// Geom. After this call, you should discard the
|
||||
// original pointer you passed in (which may or may not
|
||||
// now be invalid) and let its reference count decrement
|
||||
// normally; you should use only the returned value from
|
||||
// this point on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomMunger) qpGeomMunger::Registry::
|
||||
register_munger(qpGeomMunger *munger) {
|
||||
if (munger->is_registered()) {
|
||||
return munger;
|
||||
}
|
||||
|
||||
// Save the incoming pointer in a local PointerTo, so that if it has
|
||||
// a zero reference count and is not added into the map below, it
|
||||
// will be automatically deleted when this function returns.
|
||||
PT(qpGeomMunger) pt_munger = munger;
|
||||
|
||||
Mungers::iterator mi = _mungers.insert(munger).first;
|
||||
qpGeomMunger *new_munger = (*mi);
|
||||
if (!new_munger->is_registered()) {
|
||||
new_munger->do_register();
|
||||
}
|
||||
|
||||
return new_munger;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomMunger::Registry::unregister_munger
|
||||
// Access: Public
|
||||
// Description: Removes the indicated munger from the registry.
|
||||
// Normally this should not be done until the munger is
|
||||
// destructing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomMunger::Registry::
|
||||
unregister_munger(qpGeomMunger *munger) {
|
||||
nassertv(munger->is_registered());
|
||||
Mungers::iterator mi = _mungers.find(munger);
|
||||
nassertv(mi != _mungers.end());
|
||||
_mungers.erase(mi);
|
||||
munger->do_unregister();
|
||||
}
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
// Filename: qpgeomMunger.h
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMMUNGER_H
|
||||
#define qpGEOMMUNGER_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedReferenceCount.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
#include "indirectCompareTo.h"
|
||||
#include "pmap.h"
|
||||
#include "pset.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomMunger
|
||||
// Description : Objects of this class are used to convert vertex data
|
||||
// from a Geom into a format suitable for passing to the
|
||||
// rendering backend. Typically, the rendering backend
|
||||
// will create a specialization of this class to handle
|
||||
// its particular needs (e.g. DXGeomMunger). This class
|
||||
// is necessary because DirectX and OpenGL have somewhat
|
||||
// different requirements for vertex format.
|
||||
//
|
||||
// This also performs runtime application of state
|
||||
// changes to the vertex data; for instance, by scaling
|
||||
// all of the color values in response to a
|
||||
// ColorScaleAttrib.
|
||||
//
|
||||
// A GeomMunger must be registered before it can be
|
||||
// used, and once registered, the object is constant and
|
||||
// cannot be changed. All registered GeomMungers that
|
||||
// perform the same operation will have the same
|
||||
// pointer.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomMunger : public TypedReferenceCount {
|
||||
public:
|
||||
qpGeomMunger();
|
||||
virtual ~qpGeomMunger();
|
||||
|
||||
INLINE bool is_registered() const;
|
||||
INLINE static CPT(qpGeomMunger) register_munger(qpGeomMunger *munger);
|
||||
|
||||
INLINE CPT(qpGeomVertexFormat) munge_format(const qpGeomVertexFormat *format) const;
|
||||
void remove_format(const qpGeomVertexFormat *format);
|
||||
|
||||
INLINE CPT(qpGeomVertexData) munge_data(const qpGeomVertexData *data) const;
|
||||
void remove_data(const qpGeomVertexData *data);
|
||||
|
||||
public:
|
||||
INLINE int compare_to(const qpGeomMunger &other) const;
|
||||
|
||||
protected:
|
||||
CPT(qpGeomVertexFormat) do_munge_format(const qpGeomVertexFormat *format);
|
||||
CPT(qpGeomVertexData) do_munge_data(const qpGeomVertexData *data);
|
||||
|
||||
virtual CPT(qpGeomVertexFormat) munge_format_impl(const qpGeomVertexFormat *orig);
|
||||
virtual int compare_to_impl(const qpGeomMunger *other) const;
|
||||
|
||||
private:
|
||||
class Registry;
|
||||
INLINE static Registry *get_registry();
|
||||
static void make_registry();
|
||||
|
||||
void do_register();
|
||||
void do_unregister();
|
||||
|
||||
typedef pmap<const qpGeomVertexFormat *, const qpGeomVertexFormat *> Formats;
|
||||
Formats _formats;
|
||||
|
||||
bool _is_registered;
|
||||
typedef pset<qpGeomMunger *, IndirectCompareTo<qpGeomMunger> > Mungers;
|
||||
class Registry {
|
||||
public:
|
||||
Registry();
|
||||
CPT(qpGeomMunger) register_munger(qpGeomMunger *munger);
|
||||
void unregister_munger(qpGeomMunger *munger);
|
||||
|
||||
Mungers _mungers;
|
||||
};
|
||||
|
||||
static Registry *_registry;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedReferenceCount::init_type();
|
||||
register_type(_type_handle, "qpGeomMunger",
|
||||
TypedReferenceCount::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 "qpgeomMunger.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
// Filename: qpgeomPrimitive.I
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeomPrimitive::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertex vertices used by all the
|
||||
// primitives in this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomPrimitive::
|
||||
get_num_vertices() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_vertices.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the ith vertex index in the table.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomPrimitive::
|
||||
get_vertex(int i) const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(i >= 0 && i < (int)cdata->_vertices.size(), -1);
|
||||
return cdata->_vertices[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_vertices
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the vertex index array so
|
||||
// application code can read it directly. Do not
|
||||
// attempt to modify the returned array; use
|
||||
// modify_vertices() or set_vertices() for this.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_ushort qpGeomPrimitive::
|
||||
get_vertices() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_vertices
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the primitive lengths
|
||||
// array so application code can read it directly. Do
|
||||
// not attempt to modify the returned array; use
|
||||
// modify_lengths() or set_lengths() for this.
|
||||
//
|
||||
// Note that simple primitive types, like triangles, do
|
||||
// not have a lengths array: since all the primitives
|
||||
// have the same number of vertices, it is not needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_int qpGeomPrimitive::
|
||||
get_lengths() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_lengths;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_min_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the minimum vertex index number used by the
|
||||
// primitives in this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomPrimitive::
|
||||
get_min_vertex() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (!cdata->_got_minmax) {
|
||||
((qpGeomPrimitive *)this)->recompute_minmax();
|
||||
}
|
||||
return cdata->_min_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_max_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the maximum vertex index number used by the
|
||||
// primitives in this object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomPrimitive::
|
||||
get_max_vertex() const {
|
||||
CDReader cdata(_cycler);
|
||||
if (!cdata->_got_minmax) {
|
||||
((qpGeomPrimitive *)this)->recompute_minmax();
|
||||
}
|
||||
return cdata->_max_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomPrimitive::CData::
|
||||
CData() :
|
||||
_got_minmax(true),
|
||||
_min_vertex(0),
|
||||
_max_vertex(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomPrimitive::CData::
|
||||
CData(const qpGeomPrimitive::CData ©) :
|
||||
_vertices(copy._vertices),
|
||||
_lengths(copy._lengths),
|
||||
_got_minmax(copy._got_minmax),
|
||||
_min_vertex(copy._min_vertex),
|
||||
_max_vertex(copy._max_vertex)
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,520 @@
|
|||
// Filename: qpgeomPrimitive.cxx
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomPrimitive.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "internalName.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "indent.h"
|
||||
|
||||
TypeHandle qpGeomPrimitive::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomPrimitive::
|
||||
qpGeomPrimitive() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomPrimitive::
|
||||
qpGeomPrimitive(const qpGeomPrimitive ©) :
|
||||
TypedWritableReferenceCount(copy),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomPrimitive::
|
||||
~qpGeomPrimitive() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::add_vertex
|
||||
// Access: Published
|
||||
// Description: Adds the indicated vertex to the list of vertex
|
||||
// indices used by the graphics primitive type. To
|
||||
// define primitive, you must call add_vertex() for each
|
||||
// vertex of the new primitve, and then call
|
||||
// close_primitive() after you have specified the last
|
||||
// vertex of each primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
add_vertex(int vertex) {
|
||||
unsigned short short_vertex = vertex;
|
||||
nassertv((int)short_vertex == vertex);
|
||||
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_vertices.push_back(short_vertex);
|
||||
|
||||
if (cdata->_got_minmax) {
|
||||
cdata->_min_vertex = min(cdata->_min_vertex, short_vertex);
|
||||
cdata->_max_vertex = max(cdata->_min_vertex, short_vertex);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::add_consecutive_vertices
|
||||
// Access: Published
|
||||
// Description: Adds a consecutive sequence of vertices, beginning at
|
||||
// start, to the primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
add_consecutive_vertices(int start, int num_vertices) {
|
||||
int end = (start + num_vertices) - 1;
|
||||
unsigned short short_start = start;
|
||||
unsigned short short_end = end;
|
||||
nassertv((int)short_start == start && (int)short_end == end);
|
||||
|
||||
CDWriter cdata(_cycler);
|
||||
for (unsigned short v = short_start; v <= short_end; ++v) {
|
||||
cdata->_vertices.push_back(v);
|
||||
}
|
||||
|
||||
if (cdata->_got_minmax) {
|
||||
cdata->_min_vertex = min(cdata->_min_vertex, short_start);
|
||||
cdata->_max_vertex = max(cdata->_min_vertex, short_end);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::close_primitive
|
||||
// Access: Published
|
||||
// Description: Indicates that the previous n calls to add_vertex(),
|
||||
// since the last call to close_primitive(), have fully
|
||||
// defined a new primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
close_primitive() {
|
||||
int num_vertices_per_primitive = get_num_vertices_per_primitive();
|
||||
|
||||
CDWriter cdata(_cycler);
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
if (cdata->_lengths.empty() ||
|
||||
cdata->_lengths.back() != (int)cdata->_vertices.size()) {
|
||||
cdata->_lengths.push_back((int)cdata->_vertices.size());
|
||||
}
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
// uses the same number of vertices. Assert that we added the
|
||||
// correct number of vertices.
|
||||
nassertv((int)cdata->_vertices.size() % num_vertices_per_primitive == 0);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::clear_vertices
|
||||
// Access: Published
|
||||
// Description: Removes all of the vertices and primitives from the
|
||||
// object, so they can be re-added.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
clear_vertices() {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_vertices.clear();
|
||||
cdata->_lengths.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::modify_vertices
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the vertex index
|
||||
// list, so application code can directly fiddle with
|
||||
// this data. Use with caution, since there are no
|
||||
// checks that the data will be left in a stable state.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_ushort qpGeomPrimitive::
|
||||
modify_vertices() {
|
||||
CDWriter cdata(_cycler);
|
||||
return cdata->_vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::set_vertices
|
||||
// Access: Published
|
||||
// Description: Completely replaces the vertex index list with a new
|
||||
// table. Chances are good that you should also replace
|
||||
// the lengths list with set_lengths() at the same time.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
set_vertices(PTA_ushort vertices) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_vertices = vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::modify_lengths
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the primitive lengths
|
||||
// array, so application code can directly fiddle with
|
||||
// this data. Use with caution, since there are no
|
||||
// checks that the data will be left in a stable state.
|
||||
//
|
||||
// Note that simple primitive types, like triangles, do
|
||||
// not have a lengths array: since all the primitives
|
||||
// have the same number of vertices, it is not needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_int qpGeomPrimitive::
|
||||
modify_lengths() {
|
||||
CDWriter cdata(_cycler);
|
||||
return cdata->_lengths;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::set_lengths
|
||||
// Access: Published
|
||||
// Description: Completely replaces the primitive lengths array with
|
||||
// a new table. Chances are good that you should also
|
||||
// replace the vertices list with set_vertices() at the
|
||||
// same time.
|
||||
//
|
||||
// Note that simple primitive types, like triangles, do
|
||||
// not have a lengths array: since all the primitives
|
||||
// have the same number of vertices, it is not needed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
set_lengths(PTA_int lengths) {
|
||||
CDWriter cdata(_cycler);
|
||||
cdata->_lengths = lengths;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_num_vertices_per_primitive
|
||||
// Access: Published, Virtual
|
||||
// Description: If the primitive type is a simple type in which all
|
||||
// primitives have the same number of vertices, like
|
||||
// triangles, returns the number of vertices per
|
||||
// primitive. If the primitive type is a more complex
|
||||
// type in which different primitives might have
|
||||
// different numbers of vertices, for instance a
|
||||
// triangle strip, returns 0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::
|
||||
get_num_vertices_per_primitive() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_num_primitives
|
||||
// Access: Published
|
||||
// Description: Returns the number of individual primitives stored
|
||||
// within this object. All primitives are the same
|
||||
// type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::
|
||||
get_num_primitives() const {
|
||||
int num_vertices_per_primitive = get_num_vertices_per_primitive();
|
||||
|
||||
CDReader cdata(_cycler);
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
return cdata->_lengths.size();
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
// uses the same number of vertices.
|
||||
return ((int)cdata->_vertices.size() / num_vertices_per_primitive);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_primitive_start
|
||||
// Access: Published
|
||||
// Description: Returns the element within the _vertices list at which
|
||||
// the ith primitive starts.
|
||||
//
|
||||
// If i is one more than the highest valid primitive
|
||||
// vertex, the return value will be one more than the
|
||||
// last valid vertex. Thus, it is always true that the
|
||||
// vertices used by a particular primitive i are the set
|
||||
// get_primitive_start(i) <= vi < get_primitive_start(i
|
||||
// + 1).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::
|
||||
get_primitive_start(int i) const {
|
||||
int num_vertices_per_primitive = get_num_vertices_per_primitive();
|
||||
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(i >= 0 && i <= (int)cdata->_lengths.size(), -1);
|
||||
if (i == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return cdata->_lengths[i - 1];
|
||||
}
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
// uses the same number of vertices.
|
||||
return i * num_vertices_per_primitive;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_primitive_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertices used by the ith
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::
|
||||
get_primitive_num_vertices(int i) const {
|
||||
int num_vertices_per_primitive = get_num_vertices_per_primitive();
|
||||
|
||||
if (num_vertices_per_primitive == 0) {
|
||||
// This is a complex primitive type like a triangle strip: each
|
||||
// primitive uses a different number of vertices.
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(i >= 0 && i < (int)cdata->_lengths.size(), 0);
|
||||
return cdata->_lengths[i];
|
||||
|
||||
} else {
|
||||
// This is a simple primitive type like a triangle: each primitive
|
||||
// uses the same number of vertices.
|
||||
return num_vertices_per_primitive;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::decompose
|
||||
// Access: Published, Virtual
|
||||
// Description: Decomposes a complex primitive type into a simpler
|
||||
// primitive type, for instance triangle strips to
|
||||
// triangles, and returns a pointer to the new primitive
|
||||
// definition. If the decomposition cannot be
|
||||
// performed, this might return the original object.
|
||||
//
|
||||
// This method is useful for application code that wants
|
||||
// to iterate through the set of triangles on the
|
||||
// primitive without having to write handlers for each
|
||||
// possible kind of primitive type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(qpGeomPrimitive) qpGeomPrimitive::
|
||||
decompose(const qpGeomVertexData *vertex_data) {
|
||||
return this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::output
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
output(ostream &out, const qpGeomVertexData *vertex_data) const {
|
||||
out << get_type() << ", " << get_num_primitives()
|
||||
<< ", " << get_num_vertices();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::write
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
write(ostream &out, const qpGeomVertexData *vertex_data,
|
||||
int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< get_type() << ":\n";
|
||||
int num_primitives = get_num_primitives();
|
||||
for (int i = 0; i < num_primitives; i++) {
|
||||
indent(out, indent_level + 2)
|
||||
<< "[";
|
||||
int begin = get_primitive_start(i);
|
||||
int end = get_primitive_start(i + 1);
|
||||
for (int vi = begin; vi < end; vi++) {
|
||||
out << " " << get_vertex(vi);
|
||||
}
|
||||
out << " ]\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::calc_tight_bounds
|
||||
// Access: Public, Virtual
|
||||
// Description: Expands min_point and max_point to include all of the
|
||||
// vertices in the Geom, if any. found_any is set true
|
||||
// if any points are found. It is the caller's
|
||||
// responsibility to initialize min_point, max_point,
|
||||
// and found_any before calling this function.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
||||
bool &found_any,
|
||||
const qpGeomVertexData *vertex_data) const {
|
||||
CDReader cdata(_cycler);
|
||||
|
||||
const qpGeomVertexFormat *format = vertex_data->get_format();
|
||||
|
||||
int array_index = format->get_array_with(InternalName::get_vertex());
|
||||
if (array_index < 0) {
|
||||
// No vertex data.
|
||||
return;
|
||||
}
|
||||
|
||||
const qpGeomVertexArrayFormat *array_format = format->get_array(array_index);
|
||||
const qpGeomVertexDataType *data_type =
|
||||
array_format->get_data_type(InternalName::get_vertex());
|
||||
|
||||
int stride = array_format->get_stride();
|
||||
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);
|
||||
|
||||
PTA_ushort::const_iterator ii;
|
||||
for (ii = cdata->_vertices.begin(); ii != cdata->_vertices.end(); ++ii) {
|
||||
int index = (int)(*ii);
|
||||
const PN_float32 *v = (const PN_float32 *)&array_data[start + index * stride];
|
||||
|
||||
LPoint3f vertex;
|
||||
qpGeomVertexData::to_vec3(vertex, v, num_components);
|
||||
|
||||
if (found_any) {
|
||||
min_point.set(min(min_point[0], vertex[0]),
|
||||
min(min_point[1], vertex[1]),
|
||||
min(min_point[2], vertex[2]));
|
||||
max_point.set(max(max_point[0], vertex[0]),
|
||||
max(max_point[1], vertex[1]),
|
||||
max(max_point[2], vertex[2]));
|
||||
} else {
|
||||
min_point = vertex;
|
||||
max_point = vertex;
|
||||
found_any = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::recompute_minmax
|
||||
// Access: Private
|
||||
// Description: Recomputes the _min_vertex and _max_vertex values if
|
||||
// necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
recompute_minmax() {
|
||||
CDWriter cdata(_cycler);
|
||||
|
||||
if (cdata->_vertices.empty()) {
|
||||
cdata->_min_vertex = 0;
|
||||
cdata->_max_vertex = 0;
|
||||
} else {
|
||||
PTA_ushort::const_iterator ii = cdata->_vertices.begin();
|
||||
cdata->_min_vertex = (*ii);
|
||||
cdata->_max_vertex = (*ii);
|
||||
|
||||
++ii;
|
||||
while (ii != cdata->_vertices.end()) {
|
||||
cdata->_min_vertex = min(cdata->_min_vertex, (*ii));
|
||||
cdata->_max_vertex = max(cdata->_min_vertex, (*ii));
|
||||
|
||||
++ii;
|
||||
}
|
||||
}
|
||||
|
||||
cdata->_got_minmax = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritable::write_datagram(manager, dg);
|
||||
|
||||
manager->write_cdata(dg, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::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 qpGeomPrimitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritable::fillin(scan, manager);
|
||||
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *qpGeomPrimitive::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::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 qpGeomPrimitive::CData::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = CycleData::complete_pointers(p_list, manager);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::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 qpGeomPrimitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
||||
|
|
@ -0,0 +1,156 @@
|
|||
// Filename: qpgeomPrimitive.h
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMPRIMITIVE_H
|
||||
#define qpGEOMPRIMITIVE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "luse.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pta_ushort.h"
|
||||
#include "pta_int.h"
|
||||
#include "cycleData.h"
|
||||
#include "cycleDataReader.h"
|
||||
#include "cycleDataWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
|
||||
class qpGeomVertexData;
|
||||
class GraphicsStateGuardianBase;
|
||||
class GeomContext;
|
||||
class FactoryParams;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomPrimitive
|
||||
// Description : This is an abstract base class for a family of
|
||||
// classes that represent the fundamental geometry
|
||||
// primitives that may be stored in a Geom.
|
||||
//
|
||||
// They all have in common the fact that they are
|
||||
// defined by tables of vertex data stored in a
|
||||
// GeomVertexData object. Each GeomPrimitive object
|
||||
// contains an ordered list of integers, which index
|
||||
// into the vertex array defined by the GeomVertexData
|
||||
// and define the particular vertices of the
|
||||
// GeomVertexData that are used for this primitive.
|
||||
//
|
||||
// The meaning of a given arrangement of vertices is
|
||||
// defined by each individual primitive type; for
|
||||
// instance, a GeomTriangle renders a triangle from each
|
||||
// three consecutive vertices, while a GeomTriangleStrip
|
||||
// renders a strip of (n - 2) connected triangles from
|
||||
// each sequence of n vertices.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomPrimitive : public TypedWritableReferenceCount {
|
||||
PUBLISHED:
|
||||
qpGeomPrimitive();
|
||||
qpGeomPrimitive(const qpGeomPrimitive ©);
|
||||
virtual ~qpGeomPrimitive();
|
||||
|
||||
INLINE int get_num_vertices() const;
|
||||
INLINE int get_vertex(int i) const;
|
||||
void add_vertex(int vertex);
|
||||
void add_consecutive_vertices(int start, int num_vertices);
|
||||
void close_primitive();
|
||||
void clear_vertices();
|
||||
|
||||
INLINE CPTA_ushort get_vertices() const;
|
||||
PTA_ushort modify_vertices();
|
||||
void set_vertices(PTA_ushort vertices);
|
||||
|
||||
INLINE CPTA_int get_lengths() const;
|
||||
PTA_int modify_lengths();
|
||||
void set_lengths(PTA_int lengths);
|
||||
|
||||
INLINE int get_min_vertex() const;
|
||||
INLINE int get_max_vertex() const;
|
||||
|
||||
virtual int get_num_vertices_per_primitive() const;
|
||||
int get_num_primitives() const;
|
||||
int get_primitive_start(int i) const;
|
||||
int get_primitive_num_vertices(int i) const;
|
||||
|
||||
virtual PT(qpGeomPrimitive) decompose(const qpGeomVertexData *vertex_data);
|
||||
|
||||
virtual void output(ostream &out, const qpGeomVertexData *vertex_data) const;
|
||||
virtual void write(ostream &out, const qpGeomVertexData *vertex_data,
|
||||
int indent_level) const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg)=0;
|
||||
|
||||
virtual void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
||||
bool &found_any,
|
||||
const qpGeomVertexData *vertex_data) const;
|
||||
|
||||
private:
|
||||
// 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_ushort _vertices;
|
||||
PTA_int _lengths;
|
||||
|
||||
bool _got_minmax;
|
||||
unsigned short _min_vertex;
|
||||
unsigned short _max_vertex;
|
||||
};
|
||||
|
||||
PipelineCycler<CData> _cycler;
|
||||
typedef CycleDataReader<CData> CDReader;
|
||||
typedef CycleDataWriter<CData> CDWriter;
|
||||
|
||||
void recompute_minmax();
|
||||
|
||||
public:
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
||||
protected:
|
||||
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, "qpGeomPrimitive",
|
||||
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 qpGeom;
|
||||
};
|
||||
|
||||
#include "qpgeomPrimitive.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
// Filename: qpgeomTriangles.cxx
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomTriangles.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
|
||||
TypeHandle qpGeomTriangles::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTriangles::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTriangles::
|
||||
qpGeomTriangles() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTriangles::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTriangles::
|
||||
qpGeomTriangles(const qpGeomTriangles ©) :
|
||||
qpGeomPrimitive(copy)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTriangles::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTriangles::
|
||||
~qpGeomTriangles() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTriangles::get_num_vertices_per_primitive
|
||||
// Access: Published, Virtual
|
||||
// Description: If the primitive type is a simple type in which all
|
||||
// primitives have the same number of vertices, like
|
||||
// triangles, returns the number of vertices per
|
||||
// primitive. If the primitive type is a more complex
|
||||
// type in which different primitives might have
|
||||
// different numbers of vertices, for instance a
|
||||
// triangle strip, returns 0.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomTriangles::
|
||||
get_num_vertices_per_primitive() const {
|
||||
return 3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTriangles::draw
|
||||
// Access: Public, Virtual
|
||||
// Description: Calls the appropriate method on the GSG to draw the
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomTriangles::
|
||||
draw(GraphicsStateGuardianBase *gsg) {
|
||||
gsg->draw_triangles(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTriangles::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomTriangles::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTriangles::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeom is encountered
|
||||
// in the Bam file. It should create the qpGeom
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomTriangles::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomTriangles *object = new qpGeomTriangles;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// Filename: qpgeomTriangles.h
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMTRIANGLES_H
|
||||
#define qpGEOMTRIANGLES_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomTriangles
|
||||
// Description : Defines a series of disconnected triangles.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomTriangles : public qpGeomPrimitive {
|
||||
PUBLISHED:
|
||||
qpGeomTriangles();
|
||||
qpGeomTriangles(const qpGeomTriangles ©);
|
||||
virtual ~qpGeomTriangles();
|
||||
|
||||
virtual int get_num_vertices_per_primitive() const;
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpGeomPrimitive::init_type();
|
||||
register_type(_type_handle, "qpGeomTriangles",
|
||||
qpGeomPrimitive::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 qpGeom;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
// Filename: qpgeomTrifans.cxx
|
||||
// Created by: drose (08Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomTrifans.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
|
||||
TypeHandle qpGeomTrifans::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTrifans::
|
||||
qpGeomTrifans() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTrifans::
|
||||
qpGeomTrifans(const qpGeomTrifans ©) :
|
||||
qpGeomPrimitive(copy)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTrifans::
|
||||
~qpGeomTrifans() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::decompose
|
||||
// Access: Published, Virtual
|
||||
// Description: Decomposes a complex primitive type into a simpler
|
||||
// primitive type, for instance triangle strips to
|
||||
// triangles, and returns a pointer to the new primitive
|
||||
// definition. If the decomposition cannot be
|
||||
// performed, this might return the original object.
|
||||
//
|
||||
// This method is useful for application code that wants
|
||||
// to iterate through the set of triangles on the
|
||||
// primitive without having to write handlers for each
|
||||
// possible kind of primitive type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(qpGeomPrimitive) qpGeomTrifans::
|
||||
decompose(const qpGeomVertexData *) {
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles;
|
||||
CPTA_ushort vertices = get_vertices();
|
||||
CPTA_int lengths = get_lengths();
|
||||
|
||||
CPTA_ushort::const_iterator vi;
|
||||
vi = vertices.begin();
|
||||
|
||||
CPTA_int::const_iterator li;
|
||||
for (li = lengths.begin(); li != lengths.end(); ++li) {
|
||||
int length = (*li);
|
||||
nassertr(length >= 2, triangles.p());
|
||||
int v0 = (*vi);
|
||||
++vi;
|
||||
int v1 = (*vi);
|
||||
++vi;
|
||||
for (int i = 2; i < length; i++) {
|
||||
triangles->add_vertex(v0);
|
||||
triangles->add_vertex(v1);
|
||||
triangles->add_vertex(*vi);
|
||||
triangles->close_primitive();
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
|
||||
return triangles.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::draw
|
||||
// Access: Public, Virtual
|
||||
// Description: Calls the appropriate method on the GSG to draw the
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomTrifans::
|
||||
draw(GraphicsStateGuardianBase *gsg) {
|
||||
gsg->draw_trifans(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomTrifans::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTrifans::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeom is encountered
|
||||
// in the Bam file. It should create the qpGeom
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomTrifans::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomTrifans *object = new qpGeomTrifans;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// Filename: qpgeomTrifans.h
|
||||
// Created by: drose (08Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMTRIFANS_H
|
||||
#define qpGEOMTRIFANS_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomTrifans
|
||||
// Description : Defines a series of triangle fans.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomTrifans : public qpGeomPrimitive {
|
||||
PUBLISHED:
|
||||
qpGeomTrifans();
|
||||
qpGeomTrifans(const qpGeomTrifans ©);
|
||||
virtual ~qpGeomTrifans();
|
||||
|
||||
virtual PT(qpGeomPrimitive) decompose(const qpGeomVertexData *vertex_data);
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpGeomPrimitive::init_type();
|
||||
register_type(_type_handle, "qpGeomTrifans",
|
||||
qpGeomPrimitive::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 qpGeom;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
// Filename: qpgeomTristrips.cxx
|
||||
// Created by: drose (08Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomTristrips.h"
|
||||
#include "qpgeomTriangles.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
|
||||
TypeHandle qpGeomTristrips::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTristrips::
|
||||
qpGeomTristrips() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTristrips::
|
||||
qpGeomTristrips(const qpGeomTristrips ©) :
|
||||
qpGeomPrimitive(copy)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTristrips::
|
||||
~qpGeomTristrips() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::decompose
|
||||
// Access: Published, Virtual
|
||||
// Description: Decomposes a complex primitive type into a simpler
|
||||
// primitive type, for instance triangle strips to
|
||||
// triangles, and returns a pointer to the new primitive
|
||||
// definition. If the decomposition cannot be
|
||||
// performed, this might return the original object.
|
||||
//
|
||||
// This method is useful for application code that wants
|
||||
// to iterate through the set of triangles on the
|
||||
// primitive without having to write handlers for each
|
||||
// possible kind of primitive type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(qpGeomPrimitive) qpGeomTristrips::
|
||||
decompose(const qpGeomVertexData *) {
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles;
|
||||
CPTA_ushort vertices = get_vertices();
|
||||
CPTA_int lengths = get_lengths();
|
||||
|
||||
CPTA_ushort::const_iterator vi;
|
||||
vi = vertices.begin();
|
||||
|
||||
CPTA_int::const_iterator li;
|
||||
for (li = lengths.begin(); li != lengths.end(); ++li) {
|
||||
int length = (*li);
|
||||
nassertr(length >= 2, triangles.p());
|
||||
int v0 = (*vi);
|
||||
++vi;
|
||||
int v1 = (*vi);
|
||||
++vi;
|
||||
bool reversed = false;
|
||||
for (int i = 2; i < length; i++) {
|
||||
if (reversed) {
|
||||
triangles->add_vertex(v1);
|
||||
triangles->add_vertex(v0);
|
||||
reversed = false;
|
||||
} else {
|
||||
triangles->add_vertex(v0);
|
||||
triangles->add_vertex(v1);
|
||||
reversed = true;
|
||||
}
|
||||
triangles->add_vertex(*vi);
|
||||
v0 = v1;
|
||||
v1 = *vi;
|
||||
triangles->close_primitive();
|
||||
++vi;
|
||||
}
|
||||
}
|
||||
|
||||
return triangles.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::draw
|
||||
// Access: Public, Virtual
|
||||
// Description: Calls the appropriate method on the GSG to draw the
|
||||
// primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomTristrips::
|
||||
draw(GraphicsStateGuardianBase *gsg) {
|
||||
gsg->draw_tristrips(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomTristrips::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomTristrips::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeom is encountered
|
||||
// in the Bam file. It should create the qpGeom
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomTristrips::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomTristrips *object = new qpGeomTristrips;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
// Filename: qpgeomTristrips.h
|
||||
// Created by: drose (08Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMTRISTRIPS_H
|
||||
#define qpGEOMTRISTRIPS_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomTristrips
|
||||
// Description : Defines a series of triangle strips.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomTristrips : public qpGeomPrimitive {
|
||||
PUBLISHED:
|
||||
qpGeomTristrips();
|
||||
qpGeomTristrips(const qpGeomTristrips ©);
|
||||
virtual ~qpGeomTristrips();
|
||||
|
||||
virtual PT(qpGeomPrimitive) decompose(const qpGeomVertexData *vertex_data);
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
qpGeomPrimitive::init_type();
|
||||
register_type(_type_handle, "qpGeomTristrips",
|
||||
qpGeomPrimitive::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 qpGeom;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
// Filename: qpgeomVertexArrayFormat.I
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeomVertexArrayFormat::is_registered
|
||||
// Access: Published
|
||||
// Description: Returns true if this format has been registered,
|
||||
// false if it has not. It may not be used for a Geom
|
||||
// until it has been registered, but once registered, it
|
||||
// may no longer be modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexArrayFormat::
|
||||
is_registered() const {
|
||||
return _is_registered;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::get_stride
|
||||
// Access: Published
|
||||
// Description: Returns the total number of bytes reserved in the
|
||||
// array for each vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayFormat::
|
||||
get_stride() const {
|
||||
return _stride;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::set_stride
|
||||
// Access: Published
|
||||
// Description: Changes the total number of bytes reserved in the
|
||||
// array for each vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexArrayFormat::
|
||||
set_stride(int stride) {
|
||||
nassertv(!_is_registered);
|
||||
_stride = stride;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::get_total_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the total number of bytes used by the data
|
||||
// types within the format, including gaps between
|
||||
// elements.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayFormat::
|
||||
get_total_bytes() const {
|
||||
return _total_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::get_pad_to
|
||||
// Access: Published
|
||||
// Description: Returns the byte divisor to which the data record
|
||||
// must be padded to meet hardware limitations. For
|
||||
// instance, if this is 4, the stride will be
|
||||
// automatically rounded up to the next multiple of 4
|
||||
// bytes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayFormat::
|
||||
get_pad_to() const {
|
||||
return _pad_to;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::get_num_data_types
|
||||
// Access: Published
|
||||
// Description: Returns the number of different data types in the
|
||||
// specification.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayFormat::
|
||||
get_num_data_types() const {
|
||||
return (int)_data_types.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::get_data_type
|
||||
// Access: Published
|
||||
// Description: Returns the ith data types of the specification.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexDataType *qpGeomVertexArrayFormat::
|
||||
get_data_type(int i) const {
|
||||
nassertr(i >= 0 && i < (int)_data_types.size(), NULL);
|
||||
consider_sort_data_types();
|
||||
return _data_types[i];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::consider_sort_data_types
|
||||
// Access: Private
|
||||
// Description: Resorts the _data_types vector if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexArrayFormat::
|
||||
consider_sort_data_types() const {
|
||||
if (_data_types_unsorted) {
|
||||
((qpGeomVertexArrayFormat *)this)->sort_data_types();
|
||||
}
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const qpGeomVertexArrayFormat &obj) {
|
||||
obj.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,556 @@
|
|||
// Filename: qpgeomVertexArrayFormat.cxx
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomVertexFormat.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "indent.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "indirectLess.h"
|
||||
|
||||
TypeHandle qpGeomVertexArrayFormat::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat::
|
||||
qpGeomVertexArrayFormat() :
|
||||
_is_registered(false),
|
||||
_stride(0),
|
||||
_total_bytes(0),
|
||||
_pad_to(1),
|
||||
_data_types_unsorted(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat::
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0) :
|
||||
_is_registered(false),
|
||||
_stride(0),
|
||||
_total_bytes(0),
|
||||
_pad_to(1),
|
||||
_data_types_unsorted(false)
|
||||
{
|
||||
add_data_type(name0, num_components0, numeric_type0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat::
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0,
|
||||
const InternalName *name1, int num_components1,
|
||||
qpGeomVertexDataType::NumericType numeric_type1) :
|
||||
_is_registered(false),
|
||||
_stride(0),
|
||||
_total_bytes(0),
|
||||
_pad_to(1),
|
||||
_data_types_unsorted(false)
|
||||
{
|
||||
add_data_type(name0, num_components0, numeric_type0);
|
||||
add_data_type(name1, num_components1, numeric_type1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat::
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0,
|
||||
const InternalName *name1, int num_components1,
|
||||
qpGeomVertexDataType::NumericType numeric_type1,
|
||||
const InternalName *name2, int num_components2,
|
||||
qpGeomVertexDataType::NumericType numeric_type2) :
|
||||
_is_registered(false),
|
||||
_stride(0),
|
||||
_total_bytes(0),
|
||||
_pad_to(1),
|
||||
_data_types_unsorted(false)
|
||||
{
|
||||
add_data_type(name0, num_components0, numeric_type0);
|
||||
add_data_type(name1, num_components1, numeric_type1);
|
||||
add_data_type(name2, num_components2, numeric_type2);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat::
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0,
|
||||
const InternalName *name1, int num_components1,
|
||||
qpGeomVertexDataType::NumericType numeric_type1,
|
||||
const InternalName *name2, int num_components2,
|
||||
qpGeomVertexDataType::NumericType numeric_type2,
|
||||
const InternalName *name3, int num_components3,
|
||||
qpGeomVertexDataType::NumericType numeric_type3) :
|
||||
_is_registered(false),
|
||||
_stride(0),
|
||||
_total_bytes(0),
|
||||
_pad_to(1),
|
||||
_data_types_unsorted(false)
|
||||
{
|
||||
add_data_type(name0, num_components0, numeric_type0);
|
||||
add_data_type(name1, num_components1, numeric_type1);
|
||||
add_data_type(name2, num_components2, numeric_type2);
|
||||
add_data_type(name3, num_components3, numeric_type3);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat::
|
||||
qpGeomVertexArrayFormat(const qpGeomVertexArrayFormat ©) :
|
||||
_is_registered(false),
|
||||
_stride(copy._stride),
|
||||
_total_bytes(copy._total_bytes),
|
||||
_pad_to(copy._pad_to),
|
||||
_data_types_unsorted(copy._data_types_unsorted)
|
||||
{
|
||||
DataTypes::const_iterator dti;
|
||||
for (dti = copy._data_types.begin(); dti != copy._data_types.end(); ++dti) {
|
||||
add_data_type(*(*dti));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
operator = (const qpGeomVertexArrayFormat ©) {
|
||||
nassertv(!_is_registered);
|
||||
_stride = copy._stride;
|
||||
_total_bytes = copy._total_bytes;
|
||||
_pad_to = copy._pad_to;
|
||||
|
||||
_data_types.clear();
|
||||
_data_types_by_name.clear();
|
||||
_data_types_unsorted = false;
|
||||
DataTypes::const_iterator dti;
|
||||
for (dti = copy._data_types.begin(); dti != copy._data_types.end(); ++dti) {
|
||||
add_data_type(*(*dti));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat::
|
||||
~qpGeomVertexArrayFormat() {
|
||||
// Once registered, these things should not be deallocated.
|
||||
nassertv(!_is_registered);
|
||||
|
||||
DataTypes::iterator dti;
|
||||
for (dti = _data_types.begin(); dti != _data_types.end(); ++dti) {
|
||||
delete (*dti);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::add_data_type
|
||||
// Access: Published
|
||||
// Description: Adds a new data type to the specification. This is a
|
||||
// table of per-vertex floating-point numbers such as
|
||||
// "vertex" or "normal"; you must specify where in each
|
||||
// record the table starts, and how many components
|
||||
// (dimensions) exist per vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
add_data_type(const InternalName *name, int num_components,
|
||||
qpGeomVertexDataType::NumericType numeric_type, int start) {
|
||||
if (start < 0) {
|
||||
start = _total_bytes;
|
||||
|
||||
qpGeomVertexDataType temp_data_type(name, num_components, numeric_type, 0);
|
||||
int pad_to = temp_data_type.get_component_bytes();
|
||||
start = ((start + pad_to - 1) / pad_to) * pad_to;
|
||||
}
|
||||
|
||||
add_data_type(qpGeomVertexDataType(name, num_components,
|
||||
numeric_type, start));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::add_data_type
|
||||
// Access: Published
|
||||
// Description: Adds a new data type to the specification. This is a
|
||||
// table of per-vertex floating-point numbers such as
|
||||
// "vertex" or "normal"; you must specify where in each
|
||||
// record the table starts, and how many components
|
||||
// (dimensions) exist per vertex.
|
||||
//
|
||||
// Adding a data type with the same name as a previous
|
||||
// type, or that overlaps with one or more previous
|
||||
// types, quietly removes the previous type(s).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
add_data_type(const qpGeomVertexDataType &data_type) {
|
||||
nassertv(!_is_registered);
|
||||
|
||||
// Make sure there isn't already a data type with this name.
|
||||
remove_data_type(data_type.get_name());
|
||||
|
||||
// Also make sure there aren't any data types that overlap with this
|
||||
// one.
|
||||
const qpGeomVertexDataType *orig_data_type = get_data_type(data_type.get_start(), data_type.get_total_bytes());
|
||||
while (orig_data_type != (const qpGeomVertexDataType *)NULL) {
|
||||
remove_data_type(orig_data_type->get_name());
|
||||
orig_data_type = get_data_type(data_type.get_start(), data_type.get_total_bytes());
|
||||
}
|
||||
|
||||
_total_bytes = max(_total_bytes, data_type.get_start() + data_type.get_total_bytes());
|
||||
_pad_to = max(_pad_to, data_type.get_component_bytes());
|
||||
_stride = max(_stride, ((_total_bytes + _pad_to - 1) / _pad_to) * _pad_to);
|
||||
|
||||
qpGeomVertexDataType *new_data_type = new qpGeomVertexDataType(data_type);
|
||||
|
||||
if (!_data_types.empty() && *new_data_type < *_data_types.back()) {
|
||||
_data_types_unsorted = true;
|
||||
}
|
||||
|
||||
_data_types.push_back(new_data_type);
|
||||
_data_types_by_name.insert(DataTypesByName::value_type(new_data_type->get_name(), new_data_type));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::remove_data_type
|
||||
// Access: Published
|
||||
// Description: Removes the data type with the indicated name, if
|
||||
// any. This leaves a gap in the byte structure.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
remove_data_type(const InternalName *name) {
|
||||
nassertv(!_is_registered);
|
||||
DataTypesByName::iterator ni;
|
||||
ni = _data_types_by_name.find(name);
|
||||
if (ni != _data_types_by_name.end()) {
|
||||
qpGeomVertexDataType *data_type = (*ni).second;
|
||||
_data_types_by_name.erase(ni);
|
||||
|
||||
DataTypes::iterator dti;
|
||||
dti = find(_data_types.begin(), _data_types.end(), data_type);
|
||||
nassertv(dti != _data_types.end());
|
||||
_data_types.erase(dti);
|
||||
|
||||
delete data_type;
|
||||
|
||||
// Maybe we just removed the tail data_type. If that's so, we
|
||||
// should recompute _total_bytes to reflect the new tail.
|
||||
if (_data_types.empty()) {
|
||||
_total_bytes = 0;
|
||||
} else {
|
||||
consider_sort_data_types();
|
||||
qpGeomVertexDataType *last = _data_types.back();
|
||||
_total_bytes = last->get_start() + last->get_total_bytes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::clear_data_types
|
||||
// Access: Published
|
||||
// Description: Removes all data types previously added, sets the
|
||||
// stride to zero, and prepares to start over.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
clear_data_types() {
|
||||
_data_types.clear();
|
||||
_data_types_by_name.clear();
|
||||
_data_types_unsorted = false;
|
||||
_stride = 0;
|
||||
_total_bytes = 0;
|
||||
_pad_to = 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::get_data_type
|
||||
// Access: Published
|
||||
// Description: Returns the specification with the indicated name, or
|
||||
// NULL if the name is not used.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const qpGeomVertexDataType *qpGeomVertexArrayFormat::
|
||||
get_data_type(const InternalName *name) const {
|
||||
DataTypesByName::const_iterator ni;
|
||||
ni = _data_types_by_name.find(name);
|
||||
if (ni != _data_types_by_name.end()) {
|
||||
return (*ni).second;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::get_data_type
|
||||
// Access: Published
|
||||
// Description: Returns the first specification that overlaps with
|
||||
// any of the indicated bytes in the range, or NULL if
|
||||
// none do.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const qpGeomVertexDataType *qpGeomVertexArrayFormat::
|
||||
get_data_type(int start_byte, int num_bytes) const {
|
||||
consider_sort_data_types();
|
||||
DataTypes::const_iterator dti;
|
||||
for (dti = _data_types.begin(); dti != _data_types.end(); ++dti) {
|
||||
const qpGeomVertexDataType *data_type = (*dti);
|
||||
if (data_type->overlaps_with(start_byte, num_bytes)) {
|
||||
return data_type;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::is_data_subset_of
|
||||
// Access: Published
|
||||
// Description: Returns true if all of the fields in this array
|
||||
// format are also present and equivalent in the other
|
||||
// array format, and in the same byte positions, and the
|
||||
// stride is the same. That is, true if this format can
|
||||
// share the same data pointer as the other format (with
|
||||
// possibly some unused gaps).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexArrayFormat::
|
||||
is_data_subset_of(const qpGeomVertexArrayFormat &other) const {
|
||||
if (_data_types.size() > other._data_types.size() ||
|
||||
get_stride() != other.get_stride()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
consider_sort_data_types();
|
||||
other.consider_sort_data_types();
|
||||
size_t i = 0;
|
||||
size_t j = 0;
|
||||
while (i < _data_types.size() && j < other._data_types.size()) {
|
||||
if (*_data_types[i] == *other._data_types[j]) {
|
||||
++i;
|
||||
}
|
||||
++j;
|
||||
}
|
||||
|
||||
// If we reached the end of our list, all fields matched.
|
||||
return (i == _data_types.size());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
output(ostream &out) const {
|
||||
DataTypes::const_iterator dti;
|
||||
out << "[";
|
||||
for (dti = _data_types.begin(); dti != _data_types.end(); ++dti) {
|
||||
const qpGeomVertexDataType *data_type = (*dti);
|
||||
out << " " << *data_type;
|
||||
}
|
||||
out << " ]";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
write(ostream &out, int indent_level) const {
|
||||
indent(out, indent_level)
|
||||
<< "Array format (stride = " << get_stride() << "):\n";
|
||||
consider_sort_data_types();
|
||||
DataTypes::const_iterator dti;
|
||||
for (dti = _data_types.begin(); dti != _data_types.end(); ++dti) {
|
||||
const qpGeomVertexDataType *data_type = (*dti);
|
||||
indent(out, indent_level + 2)
|
||||
<< *data_type << " start at " << data_type->get_start() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::write_with_data
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
write_with_data(ostream &out, int indent_level,
|
||||
const qpGeomVertexData *data, int array_index) const {
|
||||
consider_sort_data_types();
|
||||
int num_vertices = data->get_num_vertices();
|
||||
for (int i = 0; i < num_vertices; i++) {
|
||||
indent(out, indent_level)
|
||||
<< "vertex index " << i << ":\n";
|
||||
DataTypes::const_iterator dti;
|
||||
for (dti = _data_types.begin(); dti != _data_types.end(); ++dti) {
|
||||
const qpGeomVertexDataType *data_type = (*dti);
|
||||
int num_values = min(data_type->get_num_values(), 4);
|
||||
float data_values[4];
|
||||
data->get_data(array_index, data_type, i, data_values, num_values);
|
||||
|
||||
indent(out, indent_level + 2)
|
||||
<< *data_type->get_name();
|
||||
for (int v = 0; v < num_values; v++) {
|
||||
out << " " << data_values[v];
|
||||
}
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::compare_to
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexArrayFormat::
|
||||
compare_to(const qpGeomVertexArrayFormat &other) const {
|
||||
if (_stride != other._stride) {
|
||||
return _stride - other._stride;
|
||||
}
|
||||
if (_total_bytes != other._total_bytes) {
|
||||
return _total_bytes - other._total_bytes;
|
||||
}
|
||||
if (_pad_to != other._pad_to) {
|
||||
return _pad_to - other._pad_to;
|
||||
}
|
||||
if (_data_types.size() != other._data_types.size()) {
|
||||
return (int)_data_types.size() - (int)other._data_types.size();
|
||||
}
|
||||
consider_sort_data_types();
|
||||
other.consider_sort_data_types();
|
||||
for (size_t i = 0; i < _data_types.size(); i++) {
|
||||
int compare = _data_types[i]->compare_to(*other._data_types[i]);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::sort_data_types
|
||||
// Access: Private
|
||||
// Description: Resorts the _data_types vector so that the data types
|
||||
// are listed in the same order they appear in the
|
||||
// record.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
sort_data_types() {
|
||||
sort(_data_types.begin(), _data_types.end(), IndirectLess<qpGeomVertexDataType>());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::do_register
|
||||
// Access: Private
|
||||
// Description: Called internally when the format is registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
do_register() {
|
||||
nassertv(!_is_registered);
|
||||
_is_registered = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeomVertexArrayFormat.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritableReferenceCount::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::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 qpGeomVertexArrayFormat::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeomVertexArrayFormat is
|
||||
// encountered in the Bam file. It should create the
|
||||
// qpGeomVertexArrayFormat and extract its information from
|
||||
// the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomVertexArrayFormat::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomVertexArrayFormat *object = new qpGeomVertexArrayFormat;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayFormat::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 qpGeomVertexArrayFormat.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayFormat::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritableReferenceCount::fillin(scan, manager);
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
// Filename: qpgeomVertexArrayFormat.h
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMVERTEXARRAYFORMAT_H
|
||||
#define qpGEOMVERTEXARRAYFORMAT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "pvector.h"
|
||||
#include "pmap.h"
|
||||
|
||||
class qpGeomVertexFormat;
|
||||
class qpGeomVertexData;
|
||||
class InternalName;
|
||||
class FactoryParams;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexArrayFormat
|
||||
// Description : This describes the structure of a single array within
|
||||
// a Geom data. See GeomVertexFormat for the parent
|
||||
// class which collects together all of the individual
|
||||
// GeomVertexArrayFormat objects.
|
||||
//
|
||||
// A particular array may include any number of standard
|
||||
// or user-defined data types. All data types consist
|
||||
// of a sequence of one or more floating-point numbers;
|
||||
// the semantic meaning of the data type is implicit
|
||||
// from its name. The standard array types are named
|
||||
// "vertex", "normal", "texcoord", "color", "tangent",
|
||||
// and "binormal"; other data may be stored simply by
|
||||
// choosing a different name.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexArrayFormat : public TypedWritableReferenceCount {
|
||||
PUBLISHED:
|
||||
qpGeomVertexArrayFormat();
|
||||
qpGeomVertexArrayFormat(const qpGeomVertexArrayFormat ©);
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0);
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0,
|
||||
const InternalName *name1, int num_components1,
|
||||
qpGeomVertexDataType::NumericType numeric_type1);
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0,
|
||||
const InternalName *name1, int num_components1,
|
||||
qpGeomVertexDataType::NumericType numeric_type1,
|
||||
const InternalName *name2, int num_components2,
|
||||
qpGeomVertexDataType::NumericType numeric_type2);
|
||||
qpGeomVertexArrayFormat(const InternalName *name0, int num_components0,
|
||||
qpGeomVertexDataType::NumericType numeric_type0,
|
||||
const InternalName *name1, int num_components1,
|
||||
qpGeomVertexDataType::NumericType numeric_type1,
|
||||
const InternalName *name2, int num_components2,
|
||||
qpGeomVertexDataType::NumericType numeric_type2,
|
||||
const InternalName *name3, int num_components3,
|
||||
qpGeomVertexDataType::NumericType numeric_type3);
|
||||
void operator = (const qpGeomVertexArrayFormat ©);
|
||||
~qpGeomVertexArrayFormat();
|
||||
|
||||
INLINE bool is_registered() const;
|
||||
|
||||
INLINE int get_stride() const;
|
||||
INLINE void set_stride(int stride);
|
||||
|
||||
INLINE int get_total_bytes() const;
|
||||
INLINE int get_pad_to() const;
|
||||
|
||||
void add_data_type(const InternalName *name, int num_components,
|
||||
qpGeomVertexDataType::NumericType numeric_type,
|
||||
int start = -1);
|
||||
void add_data_type(const qpGeomVertexDataType &data_type);
|
||||
void remove_data_type(const InternalName *name);
|
||||
void clear_data_types();
|
||||
|
||||
INLINE int get_num_data_types() const;
|
||||
INLINE const qpGeomVertexDataType *get_data_type(int i) const;
|
||||
|
||||
const qpGeomVertexDataType *get_data_type(const InternalName *name) const;
|
||||
const qpGeomVertexDataType *get_data_type(int start_byte, int num_bytes) const;
|
||||
|
||||
bool is_data_subset_of(const qpGeomVertexArrayFormat &other) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
void write_with_data(ostream &out, int indent_level,
|
||||
const qpGeomVertexData *data, int array_index) const;
|
||||
|
||||
public:
|
||||
int compare_to(const qpGeomVertexArrayFormat &other) const;
|
||||
|
||||
private:
|
||||
INLINE void consider_sort_data_types() const;
|
||||
void sort_data_types();
|
||||
void do_register();
|
||||
|
||||
bool _is_registered;
|
||||
const qpGeomVertexFormat *_root_format;
|
||||
const qpGeomVertexFormat *_parent_format;
|
||||
|
||||
int _stride;
|
||||
int _total_bytes;
|
||||
int _pad_to;
|
||||
|
||||
typedef pvector<qpGeomVertexDataType *> DataTypes;
|
||||
DataTypes _data_types;
|
||||
bool _data_types_unsorted;
|
||||
|
||||
typedef pmap<const InternalName *, qpGeomVertexDataType *> DataTypesByName;
|
||||
DataTypesByName _data_types_by_name;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
|
||||
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, "qpGeomVertexArrayFormat",
|
||||
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 qpGeomVertexFormat;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpGeomVertexArrayFormat &obj);
|
||||
|
||||
#include "qpgeomVertexArrayFormat.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Filename: qpgeomVertexData.I
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeomVertexData::get_format
|
||||
// Access: Published
|
||||
// Description: Returns a pointer to the GeomVertexFormat structure
|
||||
// that defines this data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexData::
|
||||
get_format() const {
|
||||
return _format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::get_num_arrays
|
||||
// Access: Published
|
||||
// Description: Returns the number of individual arrays stored within
|
||||
// the data. This must match
|
||||
// get_format()->get_num_arrays().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexData::
|
||||
get_num_arrays() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_arrays.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::get_array_data
|
||||
// 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 {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(array >= 0 && array < (int)cdata->_arrays.size(), CPTA_uchar());
|
||||
return cdata->_arrays[array];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::CData::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexData::CData::
|
||||
CData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::CData::Copy Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexData::CData::
|
||||
CData(const qpGeomVertexData::CData ©) :
|
||||
_arrays(copy._arrays)
|
||||
{
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const qpGeomVertexData &obj) {
|
||||
obj.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,650 @@
|
|||
// Filename: qpgeomVertexData.cxx
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomVertexData.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "pset.h"
|
||||
|
||||
TypeHandle qpGeomVertexData::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::Default Constructor
|
||||
// Access: Private
|
||||
// Description: Constructs an invalid object. This is only used when
|
||||
// reading from the bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexData::
|
||||
qpGeomVertexData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexData::
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format) :
|
||||
_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());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexData::
|
||||
qpGeomVertexData(const qpGeomVertexData ©) :
|
||||
TypedWritableReferenceCount(copy),
|
||||
_format(copy._format),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
operator = (const qpGeomVertexData ©) {
|
||||
TypedWritableReferenceCount::operator = (copy);
|
||||
_format = copy._format;
|
||||
_cycler = copy._cycler;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexData::
|
||||
~qpGeomVertexData() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::get_num_vertices
|
||||
// Access: Published
|
||||
// Description: Returns the number of vertices stored within all the
|
||||
// arrays. All arrays store data for the same n
|
||||
// vertices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexData::
|
||||
get_num_vertices() const {
|
||||
CDReader cdata(_cycler);
|
||||
nassertr(_format->get_num_arrays() == (int)cdata->_arrays.size(), 0);
|
||||
if (_format->get_num_arrays() == 0) {
|
||||
// No arrays means no vertices. Weird but legal.
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// 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());
|
||||
|
||||
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].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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::clear_vertices
|
||||
// Access: Published
|
||||
// Description: Removes all of the vertices from the arrays;
|
||||
// functionally equivalent to set_num_vertices(0) (but
|
||||
// faster).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
clear_vertices() {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(_format->get_num_arrays() == (int)cdata->_arrays.size());
|
||||
|
||||
Arrays::iterator ai;
|
||||
for (ai = cdata->_arrays.begin();
|
||||
ai != cdata->_arrays.end();
|
||||
++ai) {
|
||||
(*ai).clear();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::modify_array_data
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the indicated vertex
|
||||
// array, so that application code may directly
|
||||
// manipulate the vertices. You should avoid changing
|
||||
// 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) {
|
||||
// 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);
|
||||
nassertr(array >= 0 && array < (int)cdata->_arrays.size(), PTA_uchar());
|
||||
|
||||
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();
|
||||
}
|
||||
return cdata->_arrays[array];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::set_array_data
|
||||
// Access: Published
|
||||
// Description: Replaces the indicated vertex data array with
|
||||
// a completely new array. You should be careful that
|
||||
// the new array has the same length as the old one,
|
||||
// unless you know what you are doing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
set_array_data(int array, PTA_uchar array_data) {
|
||||
CDWriter cdata(_cycler);
|
||||
nassertv(array >= 0 && array < (int)cdata->_arrays.size());
|
||||
cdata->_arrays[array] = array_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::set_data
|
||||
// Access: Published
|
||||
// Description: Sets the nth vertex to a particular value. Query the
|
||||
// format to get the array index and data_type
|
||||
// parameters for the particular data type you want to
|
||||
// set.
|
||||
//
|
||||
// This flavor of set_data() accepts a generic float
|
||||
// array and a specific number of dimensions. The new
|
||||
// data will be copied from the num_values elements
|
||||
// of data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
set_data(int array, const qpGeomVertexDataType *data_type,
|
||||
int vertex, const float *data, int num_values) {
|
||||
int stride = _format->get_array(array)->get_stride();
|
||||
int element = vertex * stride + data_type->get_start();
|
||||
|
||||
{
|
||||
CDReader cdata(_cycler);
|
||||
int array_size = (int)cdata->_arrays[array].size();
|
||||
if (element + data_type->get_total_bytes() > array_size) {
|
||||
// Whoops, we need more vertices!
|
||||
set_num_vertices(vertex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
PTA_uchar array_data = modify_array_data(array);
|
||||
nassertv(element >= 0 && element + data_type->get_total_bytes() <= (int)array_data.size());
|
||||
|
||||
switch (data_type->get_numeric_type()) {
|
||||
case qpGeomVertexDataType::NT_uint8:
|
||||
{
|
||||
nassertv(num_values <= data_type->get_num_values());
|
||||
for (int i = 0; i < num_values; i++) {
|
||||
int value = (int)(data[i] * 255.0f);
|
||||
*(unsigned char *)&array_data[element] = value;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case qpGeomVertexDataType::NT_packed_argb:
|
||||
{
|
||||
nassertv(num_values == 4);
|
||||
*(PN_uint32 *)&array_data[element] = pack_argb(data);
|
||||
}
|
||||
break;
|
||||
|
||||
case qpGeomVertexDataType::NT_float:
|
||||
nassertv(num_values == data_type->get_num_values());
|
||||
memcpy(&array_data[element], data, data_type->get_total_bytes());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::get_data
|
||||
// Access: Published
|
||||
// Description: Returns the data associated with the nth vertex for a
|
||||
// particular value. Query the format to get the array
|
||||
// index and data_type parameters for the particular
|
||||
// data type you want to get.
|
||||
//
|
||||
// This flavor of get_data() copies its data into a
|
||||
// generic float array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
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);
|
||||
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());
|
||||
|
||||
switch (data_type->get_numeric_type()) {
|
||||
case qpGeomVertexDataType::NT_uint8:
|
||||
{
|
||||
nassertv(num_values <= data_type->get_num_values());
|
||||
for (int i = 0; i < num_values; i++) {
|
||||
int value = *(unsigned char *)&array_data[element];
|
||||
element += 1;
|
||||
data[i] = (float)value / 255.0f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case qpGeomVertexDataType::NT_packed_argb:
|
||||
{
|
||||
nassertv(num_values == 4);
|
||||
unpack_argb(data, *(PN_uint32 *)&array_data[element]);
|
||||
}
|
||||
break;
|
||||
|
||||
case qpGeomVertexDataType::NT_float:
|
||||
nassertv(num_values <= data_type->get_num_values());
|
||||
memcpy(data, &array_data[element], num_values * sizeof(PN_float32));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::convert_to
|
||||
// Access: Published
|
||||
// Description: Matches up the data types of this format with the
|
||||
// data types of the other format by name, and copies
|
||||
// the data vertex-by-vertex to a new set of data arrays
|
||||
// in the new format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PT(qpGeomVertexData) qpGeomVertexData::
|
||||
convert_to(const qpGeomVertexFormat *new_format) const {
|
||||
int num_vertices = get_num_vertices();
|
||||
|
||||
PT(qpGeomVertexData) new_data = new qpGeomVertexData(new_format);
|
||||
|
||||
pset<int> done_arrays;
|
||||
|
||||
int num_arrays = _format->get_num_arrays();
|
||||
int array;
|
||||
|
||||
// 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) {
|
||||
const qpGeomVertexArrayFormat *array_format =
|
||||
_format->get_array(array);
|
||||
|
||||
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) {
|
||||
const qpGeomVertexArrayFormat *new_array_format =
|
||||
new_format->get_array(new_array);
|
||||
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));
|
||||
array_done = true;
|
||||
|
||||
done_arrays.insert(new_array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now make sure the arrays we didn't share are all filled in.
|
||||
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);
|
||||
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) {
|
||||
// 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);
|
||||
const qpGeomVertexArrayFormat *new_array_format =
|
||||
new_format->get_array(new_array);
|
||||
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_array_format->get_stride(),
|
||||
array_data + data_type->get_start(), array_format->get_stride(),
|
||||
data_type, num_vertices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
output(ostream &out) const {
|
||||
out << get_num_vertices() << ": " << *get_format();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
write(ostream &out, int indent_level) const {
|
||||
_format->write_with_data(out, indent_level, this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::get_array_info
|
||||
// Access: Public
|
||||
// Description: A convenience function to collect together the
|
||||
// important parts of the array data for rendering.
|
||||
// Given the name of a data type, fills in the start of
|
||||
// the array, the number of floats for each vertex, the
|
||||
// starting bytes number, and the number of bytes to
|
||||
// increment for each consecutive vertex.
|
||||
//
|
||||
// The return value is true if the named array data
|
||||
// exists in this record, or false if it does not (in
|
||||
// which case none of the output parameters are valid).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexData::
|
||||
get_array_info(const InternalName *name, CPTA_uchar &array_data,
|
||||
int &num_components,
|
||||
qpGeomVertexDataType::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
int array_index;
|
||||
const qpGeomVertexDataType *data_type;
|
||||
if (_format->get_array_info(name, array_index, data_type)) {
|
||||
CDReader cdata(_cycler);
|
||||
array_data = cdata->_arrays[array_index];
|
||||
num_components = data_type->get_num_components();
|
||||
numeric_type = data_type->get_numeric_type();
|
||||
start = data_type->get_start();
|
||||
stride = _format->get_array(array_index)->get_stride();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::to_vec2
|
||||
// Access: Public, Static
|
||||
// Description: Converts a data element of arbitrary number of
|
||||
// dimensions (1 - 4) into a vec2 in a sensible way.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
to_vec2(LVecBase2f &vec, const float *data, int num_values) {
|
||||
switch (num_values) {
|
||||
case 1:
|
||||
vec.set(data[0], 0.0f);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
vec.set(data[0], data[1]);
|
||||
break;
|
||||
|
||||
default: // 4 or more.
|
||||
vec.set(data[0] / data[3], data[1] / data[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::to_vec3
|
||||
// Access: Public, Static
|
||||
// Description: Converts a data element of arbitrary number of
|
||||
// dimensions (1 - 4) into a vec3 in a sensible way.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
to_vec3(LVecBase3f &vec, const float *data, int num_values) {
|
||||
switch (num_values) {
|
||||
case 1:
|
||||
vec.set(data[0], 0.0f, 0.0f);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
vec.set(data[0], data[1], 0.0f);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
vec.set(data[0], data[1], data[2]);
|
||||
break;
|
||||
|
||||
default: // 4 or more.
|
||||
vec.set(data[0] / data[3], data[1] / data[3], data[2] / data[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::to_vec4
|
||||
// Access: Public, Static
|
||||
// Description: Converts a data element of arbitrary number of
|
||||
// dimensions (1 - 4) into a vec4 in a sensible way.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
to_vec4(LVecBase4f &vec, const float *data, int num_values) {
|
||||
switch (num_values) {
|
||||
case 1:
|
||||
vec.set(data[0], 0.0f, 0.0f, 1.0f);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
vec.set(data[0], data[1], 0.0f, 1.0f);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
vec.set(data[0], data[1], data[2], 1.0f);
|
||||
break;
|
||||
|
||||
default: // 4 or more.
|
||||
vec.set(data[0], data[1], data[2], data[3]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::pack_argb
|
||||
// Access: Public, Static
|
||||
// Description: Packs four floats, stored R, G, B, A, into a
|
||||
// packed_argb value.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
unsigned int qpGeomVertexData::
|
||||
pack_argb(const float data[4]) {
|
||||
unsigned int r = ((unsigned int)(data[0] * 255.0f)) & 0xff;
|
||||
unsigned int g = ((unsigned int)(data[1] * 255.0f)) & 0xff;
|
||||
unsigned int b = ((unsigned int)(data[2] * 255.0f)) & 0xff;
|
||||
unsigned int a = ((unsigned int)(data[3] * 255.0f)) & 0xff;
|
||||
return ((a << 24) | (r << 16) | (g << 8) | b);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::unpack_argb
|
||||
// Access: Public, Static
|
||||
// Description: Unpacks a packed_argb value into four floats, stored
|
||||
// R, G, B, A.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
unpack_argb(float data[4], unsigned int packed_argb) {
|
||||
data[0] = (float)((packed_argb >> 16) & 0xff) / 255.0f;
|
||||
data[1] = (float)((packed_argb >> 8) & 0xff) / 255.0f;
|
||||
data[2] = (float)(packed_argb & 0xff) / 255.0f;
|
||||
data[3] = (float)((packed_argb >> 24) & 0xff) / 255.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeomVertexData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritable::write_datagram(manager, dg);
|
||||
|
||||
manager->write_cdata(dg, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeomVertexData is encountered
|
||||
// in the Bam file. It should create the qpGeomVertexData
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomVertexData::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomVertexData *object = new qpGeomVertexData;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::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 qpGeomVertexData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritable::fillin(scan, manager);
|
||||
|
||||
manager->read_cdata(scan, _cycler);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::CData::make_copy
|
||||
// Access: Public, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CycleData *qpGeomVertexData::CData::
|
||||
make_copy() const {
|
||||
return new CData(*this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::CData::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::CData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::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 qpGeomVertexData::CData::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = CycleData::complete_pointers(p_list, manager);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexData::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 qpGeomVertexData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexData::CData::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
// Filename: qpgeomVertexData.h
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMVERTEXDATA_H
|
||||
#define qpGEOMVERTEXDATA_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "qpgeomVertexFormat.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "internalName.h"
|
||||
#include "cycleData.h"
|
||||
#include "cycleDataReader.h"
|
||||
#include "cycleDataWriter.h"
|
||||
#include "pipelineCycler.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pmap.h"
|
||||
#include "pvector.h"
|
||||
#include "pta_uchar.h"
|
||||
|
||||
class FactoryParams;
|
||||
class qpGeomVertexDataType;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexData
|
||||
// Description : This defines the actual numeric vertex data stored in
|
||||
// a Geom, in the structure defined by a particular
|
||||
// GeomVertexFormat object.
|
||||
//
|
||||
// The data consists of one or more arrays of floats.
|
||||
// Typically, there will be only one array per Geom, and
|
||||
// the various data types defined in the
|
||||
// GeomVertexFormat will be interleaved throughout that
|
||||
// array. However, it is possible to have multiple
|
||||
// different arrays, with different combinations of data
|
||||
// types through each one.
|
||||
//
|
||||
// However the data is distributed, the effect is of a
|
||||
// table of vertices, with a value for each of the
|
||||
// GeomVertexFormat's data types, stored for each
|
||||
// vertex.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexData : public TypedWritableReferenceCount {
|
||||
private:
|
||||
qpGeomVertexData();
|
||||
PUBLISHED:
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format);
|
||||
qpGeomVertexData(const qpGeomVertexData ©);
|
||||
void operator = (const qpGeomVertexData ©);
|
||||
virtual ~qpGeomVertexData();
|
||||
|
||||
INLINE const qpGeomVertexFormat *get_format() const;
|
||||
|
||||
int get_num_vertices() const;
|
||||
void 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);
|
||||
|
||||
void set_data(int array, const qpGeomVertexDataType *data_type,
|
||||
int vertex, const float *data, int num_values);
|
||||
void get_data(int array, const qpGeomVertexDataType *data_type,
|
||||
int vertex, float *data, int num_values) const;
|
||||
|
||||
PT(qpGeomVertexData) convert_to(const qpGeomVertexFormat *new_format) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
public:
|
||||
bool get_array_info(const InternalName *name, CPTA_uchar &array_data,
|
||||
int &num_components,
|
||||
qpGeomVertexDataType::NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
static void to_vec2(LVecBase2f &vec, const float *data, int num_values);
|
||||
static void to_vec3(LVecBase3f &vec, const float *data, int num_values);
|
||||
static void to_vec4(LVecBase4f &vec, const float *data, int num_values);
|
||||
|
||||
static unsigned int pack_argb(const float data[4]);
|
||||
static void unpack_argb(float data[4], unsigned int packed_argb);
|
||||
|
||||
private:
|
||||
typedef pvector<PTA_uchar> Arrays;
|
||||
|
||||
CPT(qpGeomVertexFormat) _format;
|
||||
|
||||
// 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);
|
||||
|
||||
Arrays _arrays;
|
||||
};
|
||||
|
||||
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, "qpGeomVertexData",
|
||||
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;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpGeomVertexData &obj);
|
||||
|
||||
#include "qpgeomVertexData.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
// Filename: qpgeomVertexDataType.I
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeomVertexDataType::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexDataType::
|
||||
qpGeomVertexDataType(const qpGeomVertexDataType ©) :
|
||||
_name(copy._name),
|
||||
_num_components(copy._num_components),
|
||||
_num_values(copy._num_values),
|
||||
_numeric_type(copy._numeric_type),
|
||||
_start(copy._start),
|
||||
_component_bytes(copy._component_bytes),
|
||||
_total_bytes(copy._total_bytes)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexDataType::
|
||||
operator = (const qpGeomVertexDataType ©) {
|
||||
_name = copy._name;
|
||||
_num_components = copy._num_components;
|
||||
_num_values = copy._num_values;
|
||||
_numeric_type = copy._numeric_type;
|
||||
_start = copy._start;
|
||||
_component_bytes = copy._component_bytes;
|
||||
_total_bytes = copy._total_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_name
|
||||
// Access: Published
|
||||
// Description: Returns the name of this particular data field,
|
||||
// e.g. "vertex" or "normal". The name may be a
|
||||
// user-defined string, or it may be one of the standard
|
||||
// system-defined field types. Only the system-defined
|
||||
// field types are used for the actual rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const InternalName *qpGeomVertexDataType::
|
||||
get_name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_num_components
|
||||
// Access: Published
|
||||
// Description: Returns the number of components of each data type:
|
||||
// the number of instances of the NumericType in each
|
||||
// element. This is usually, but not always, the same
|
||||
// thing as get_num_values().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexDataType::
|
||||
get_num_components() const {
|
||||
return _num_components;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_num_values
|
||||
// Access: Published
|
||||
// Description: Returns the number of numeric values of each data
|
||||
// type: the number of distinct numeric values that go
|
||||
// into each element. This is usually, but not always,
|
||||
// the same thing as get_num_components(); the
|
||||
// difference is in the case of a composite numeric type
|
||||
// like NT_packed_argb, which has four numeric values
|
||||
// per component.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexDataType::
|
||||
get_num_values() const {
|
||||
return _num_values;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_numeric_type
|
||||
// Access: Published
|
||||
// Description: Returns the token representing the numeric type of
|
||||
// the data storage.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexDataType::NumericType qpGeomVertexDataType::
|
||||
get_numeric_type() const {
|
||||
return _numeric_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_start
|
||||
// Access: Published
|
||||
// Description: Returns the byte within the array record at which
|
||||
// this data type starts. This can be set to non-zero
|
||||
// to implement interleaved arrays.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexDataType::
|
||||
get_start() const {
|
||||
return _start;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_component_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the number of bytes used by each component
|
||||
// (that is, by one element of the numeric type).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexDataType::
|
||||
get_component_bytes() const {
|
||||
return _component_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_total_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the number of bytes used by the data type:
|
||||
// component_bytes * num_components.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexDataType::
|
||||
get_total_bytes() const {
|
||||
return _total_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::overlaps_with
|
||||
// Access: Published
|
||||
// Description: Returns true if this data type overlaps with any of
|
||||
// the bytes in the indicated range, false if it does
|
||||
// not.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexDataType::
|
||||
overlaps_with(int start_byte, int num_bytes) const {
|
||||
return (_start < start_byte + num_bytes &&
|
||||
_start + _total_bytes > start_byte);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::compare_to
|
||||
// Access: Public
|
||||
// Description: This is used to unquify data types, and hence
|
||||
// formats, for the GeomVertexFormat registry.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexDataType::
|
||||
compare_to(const qpGeomVertexDataType &other) const {
|
||||
if (_name != other._name) {
|
||||
return _name < other._name ? -1 : 1;
|
||||
}
|
||||
if (_num_components != other._num_components) {
|
||||
return _num_components - other._num_components;
|
||||
}
|
||||
if (_numeric_type != other._numeric_type) {
|
||||
return (int)_numeric_type - (int)other._numeric_type;
|
||||
}
|
||||
if (_start != other._start) {
|
||||
return _start - other._start;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::operator ==
|
||||
// Access: Public
|
||||
// Description: Returns true if the two data types are exactly
|
||||
// equivalent, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexDataType::
|
||||
operator == (const qpGeomVertexDataType &other) const {
|
||||
return compare_to(other) == 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::operator !=
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexDataType::
|
||||
operator != (const qpGeomVertexDataType &other) const {
|
||||
return compare_to(other) != 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::operator <
|
||||
// Access: Public
|
||||
// Description: This is used to put data types in order within a
|
||||
// particular GeomVertexArrayFormat. Note that it is
|
||||
// *not* in the same space as operator == and operator
|
||||
// !=.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexDataType::
|
||||
operator < (const qpGeomVertexDataType &other) const {
|
||||
if (_start != other._start) {
|
||||
return _start < other._start;
|
||||
}
|
||||
if (_total_bytes < other._total_bytes) {
|
||||
return _total_bytes < other._total_bytes;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const qpGeomVertexDataType &obj) {
|
||||
obj.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
// Filename: qpgeomVertexDataType.cxx
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomVertexDataType.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexDataType::
|
||||
qpGeomVertexDataType(const InternalName *name, int num_components,
|
||||
NumericType numeric_type, int start) :
|
||||
_name(name),
|
||||
_num_components(num_components),
|
||||
_num_values(num_components),
|
||||
_numeric_type(numeric_type),
|
||||
_start(start)
|
||||
{
|
||||
nassertv(num_components > 0 && start >= 0);
|
||||
|
||||
switch (numeric_type) {
|
||||
case NT_uint8:
|
||||
_component_bytes = 1;
|
||||
break;
|
||||
|
||||
case NT_packed_argb:
|
||||
_component_bytes = 4; // sizeof(PN_uint32)
|
||||
_num_values *= 4;
|
||||
break;
|
||||
|
||||
case NT_float:
|
||||
_component_bytes = 4; // sizeof(PN_float32)
|
||||
break;
|
||||
}
|
||||
|
||||
_total_bytes = _component_bytes * _num_components;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::error named constructor
|
||||
// Access: Published
|
||||
// Description: Returns a data type specifically to represent an
|
||||
// error condition.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const qpGeomVertexDataType &qpGeomVertexDataType::
|
||||
error() {
|
||||
static qpGeomVertexDataType error_result
|
||||
(InternalName::get_error(), 1, NT_uint8, 0);
|
||||
return error_result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexDataType::
|
||||
output(ostream &out) const {
|
||||
out << *get_name() << "(" << get_num_components() << ")";
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::copy_records
|
||||
// Access: Published
|
||||
// Description: Copies and converts from one data type to another.
|
||||
// Copies the num_records records from the "from"
|
||||
// buffer, encoded with from_type, to the "to" buffer,
|
||||
// encoded with this current type, converting each one
|
||||
// as necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexDataType::
|
||||
copy_records(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const {
|
||||
// Temp for debugging.
|
||||
static ConfigVariableBool do_copy_generic("copy-generic", false);
|
||||
if (do_copy_generic) {
|
||||
copy_generic(to, to_stride, from, from_stride, from_type, num_records);
|
||||
return;
|
||||
}
|
||||
|
||||
if (get_numeric_type() == from_type->get_numeric_type() &&
|
||||
get_num_values() == from_type->get_num_values()) {
|
||||
// An easy case.
|
||||
copy_no_convert(to, to_stride, from, from_stride, from_type, num_records);
|
||||
|
||||
} else if (get_numeric_type() == NT_uint8 && from_type->get_numeric_type() == NT_packed_argb &&
|
||||
get_num_values() == from_type->get_num_values()) {
|
||||
copy_argb_to_uint8(to, to_stride, from, from_stride, from_type, num_records);
|
||||
} else if (get_numeric_type() == NT_packed_argb && from_type->get_numeric_type() == NT_uint8 &&
|
||||
get_num_values() == from_type->get_num_values()) {
|
||||
copy_uint8_to_argb(to, to_stride, from, from_stride, from_type, num_records);
|
||||
} else {
|
||||
copy_generic(to, to_stride, from, from_stride, from_type, num_records);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::copy_no_convert
|
||||
// Access: Private
|
||||
// Description: Quickly copies data without the need to convert it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexDataType::
|
||||
copy_no_convert(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const {
|
||||
if (to_stride == _total_bytes && from_stride == _total_bytes) {
|
||||
// Fantastic! It's just a linear array of this one data type.
|
||||
// Copy the whole thing all at once.
|
||||
memcpy(to, from, num_records * _total_bytes);
|
||||
|
||||
} else {
|
||||
// Ok, it's interleaved in with other data. Copy them one record
|
||||
// at a time.
|
||||
while (num_records > 0) {
|
||||
memcpy(to, from, _total_bytes);
|
||||
to += to_stride;
|
||||
from += from_stride;
|
||||
num_records--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::copy_argb_to_uint8
|
||||
// Access: Private
|
||||
// Description: Converts packed_argb to uint8-based r, g, b, a.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexDataType::
|
||||
copy_argb_to_uint8(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const {
|
||||
while (num_records > 0) {
|
||||
PN_uint32 packed_argb = *(const PN_uint32 *)from;
|
||||
to[0] = ((packed_argb >> 16) & 0xff);
|
||||
to[1] = ((packed_argb >> 8) & 0xff);
|
||||
to[2] = (packed_argb & 0xff);
|
||||
to[3] = ((packed_argb >> 24) & 0xff);
|
||||
|
||||
to += to_stride;
|
||||
from += from_stride;
|
||||
num_records--;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::copy_uint8_to_argb
|
||||
// Access: Private
|
||||
// Description: Converts uint8-based r, g, b, a to packed_argb.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexDataType::
|
||||
copy_uint8_to_argb(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const {
|
||||
while (num_records > 0) {
|
||||
PN_uint32 packed_argb = ((from[3] << 24) | (from[0] << 16) | (from[1] << 8) | from[2]);
|
||||
*(PN_uint32 *)to = packed_argb;
|
||||
|
||||
to += to_stride;
|
||||
from += from_stride;
|
||||
num_records--;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::copy_generic
|
||||
// Access: Private
|
||||
// Description: A more general anything-to-anything copy (somewhat
|
||||
// more expensive than the above).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexDataType::
|
||||
copy_generic(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const {
|
||||
int num_values_to_copy = min(get_num_values(), from_type->get_num_values());
|
||||
int num_values_to_fill = get_num_values() - num_values_to_copy;
|
||||
|
||||
while (num_records > 0) {
|
||||
int vi = 0;
|
||||
while (vi < num_values_to_copy) {
|
||||
float value = from_type->get_value(from, vi);
|
||||
set_value(to, vi, value);
|
||||
++vi;
|
||||
}
|
||||
while (vi < num_values_to_fill) {
|
||||
set_value(to, vi, 0.0f);
|
||||
++vi;
|
||||
}
|
||||
|
||||
to += to_stride;
|
||||
from += from_stride;
|
||||
num_records--;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::get_value
|
||||
// Access: Private
|
||||
// Description: Returns the nth value of the data type, expressed as
|
||||
// a float.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
float qpGeomVertexDataType::
|
||||
get_value(const unsigned char *data, int n) const {
|
||||
switch (get_numeric_type()) {
|
||||
case NT_uint8:
|
||||
return (float)data[n] / 255.0f;
|
||||
|
||||
case qpGeomVertexDataType::NT_packed_argb:
|
||||
{
|
||||
int element = n / 4;
|
||||
const PN_uint32 *int_array = (const PN_uint32 *)data;
|
||||
|
||||
PN_uint32 packed_argb = int_array[element];
|
||||
switch (n % 4) {
|
||||
case 0:
|
||||
return (float)((packed_argb >> 16) & 0xff) / 255.0f;
|
||||
case 1:
|
||||
return (float)((packed_argb >> 8) & 0xff) / 255.0f;
|
||||
case 2:
|
||||
return (float)(packed_argb & 0xff) / 255.0f;
|
||||
case 3:
|
||||
return (float)((packed_argb >> 24) & 0xff) / 255.0f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case qpGeomVertexDataType::NT_float:
|
||||
{
|
||||
const PN_float32 *float_array = (const PN_float32 *)data;
|
||||
return float_array[n];
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexDataType::set_value
|
||||
// Access: Private
|
||||
// Description: Modifies the nth value of the data type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexDataType::
|
||||
set_value(unsigned char *data, int n, float value) const {
|
||||
switch (get_numeric_type()) {
|
||||
case NT_uint8:
|
||||
data[n] = (int)(value * 255.0f);
|
||||
break;
|
||||
|
||||
case qpGeomVertexDataType::NT_packed_argb:
|
||||
{
|
||||
int element = n / 4;
|
||||
|
||||
union {
|
||||
PN_uint32 _packed_argb;
|
||||
struct {
|
||||
unsigned char _a;
|
||||
unsigned char _r;
|
||||
unsigned char _g;
|
||||
unsigned char _b;
|
||||
} _argb;
|
||||
} color;
|
||||
|
||||
PN_uint32 *int_array = (PN_uint32 *)data;
|
||||
color._packed_argb = int_array[element];
|
||||
switch (n % 4) {
|
||||
case 0:
|
||||
color._argb._r = (int)(value * 255.0f);
|
||||
break;
|
||||
case 1:
|
||||
color._argb._g = (int)(value * 255.0f);
|
||||
break;
|
||||
case 2:
|
||||
color._argb._b = (int)(value * 255.0f);
|
||||
break;
|
||||
case 3:
|
||||
color._argb._a = (int)(value * 255.0f);
|
||||
break;
|
||||
}
|
||||
int_array[element] = color._packed_argb;
|
||||
}
|
||||
break;
|
||||
|
||||
case qpGeomVertexDataType::NT_float:
|
||||
PN_float32 *float_array = (PN_float32 *)data;
|
||||
float_array[n] = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
// Filename: qpgeomVertexDataType.h
|
||||
// Created by: drose (06Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMVERTEXDATATYPE_H
|
||||
#define qpGEOMVERTEXDATATYPE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "internalName.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexDataType
|
||||
// Description : This defines how a single data type is interleaved
|
||||
// within a vertex array stored within a Geom. The
|
||||
// GeomVertexArrayFormat class maintains a list of these
|
||||
// to completely define a particular array structure.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexDataType {
|
||||
PUBLISHED:
|
||||
enum NumericType {
|
||||
NT_uint8,
|
||||
NT_packed_argb, // DirectX style
|
||||
NT_float,
|
||||
};
|
||||
|
||||
INLINE qpGeomVertexDataType(const InternalName *name, int num_components,
|
||||
NumericType numeric_type, int start);
|
||||
INLINE qpGeomVertexDataType(const qpGeomVertexDataType ©);
|
||||
INLINE void operator = (const qpGeomVertexDataType ©);
|
||||
|
||||
static const qpGeomVertexDataType &error();
|
||||
|
||||
INLINE const InternalName *get_name() const;
|
||||
INLINE int get_num_components() const;
|
||||
INLINE int get_num_values() const;
|
||||
INLINE NumericType get_numeric_type() const;
|
||||
INLINE int get_start() const;
|
||||
INLINE int get_component_bytes() const;
|
||||
INLINE int get_total_bytes() const;
|
||||
|
||||
INLINE bool overlaps_with(int start_byte, int num_bytes) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
public:
|
||||
INLINE int compare_to(const qpGeomVertexDataType &other) const;
|
||||
INLINE bool operator == (const qpGeomVertexDataType &other) const;
|
||||
INLINE bool operator != (const qpGeomVertexDataType &other) const;
|
||||
INLINE bool operator < (const qpGeomVertexDataType &other) const;
|
||||
|
||||
void copy_records(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const;
|
||||
|
||||
private:
|
||||
void copy_no_convert(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const;
|
||||
void copy_argb_to_uint8(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const;
|
||||
void copy_uint8_to_argb(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const;
|
||||
|
||||
void copy_generic(unsigned char *to, int to_stride,
|
||||
const unsigned char *from, int from_stride,
|
||||
const qpGeomVertexDataType *from_type,
|
||||
int num_records) const;
|
||||
|
||||
float get_value(const unsigned char *data, int n) const;
|
||||
void set_value(unsigned char *data, int n, float value) const;
|
||||
|
||||
private:
|
||||
CPT(InternalName) _name;
|
||||
int _num_components;
|
||||
int _num_values;
|
||||
NumericType _numeric_type;
|
||||
int _start;
|
||||
int _component_bytes;
|
||||
int _total_bytes;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpGeomVertexDataType &obj);
|
||||
|
||||
#include "qpgeomVertexDataType.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,260 @@
|
|||
// Filename: qpgeomVertexFormat.I
|
||||
// Created by: drose (07Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const qpGeomVertexFormat &obj) {
|
||||
obj.output(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::is_registered
|
||||
// Access: Published
|
||||
// Description: Returns true if this format has been registered,
|
||||
// false if it has not. It may not be used for a Geom
|
||||
// until it has been registered, but once registered, it
|
||||
// may no longer be modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool qpGeomVertexFormat::
|
||||
is_registered() const {
|
||||
return _is_registered;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::register_format
|
||||
// Access: Published, Static
|
||||
// Description: Adds the indicated format to the registry, if there
|
||||
// is not an equivalent format already there; in either
|
||||
// case, returns the pointer to the equivalent format
|
||||
// now in the registry.
|
||||
//
|
||||
// This must be called before a format may be used in a
|
||||
// Geom. After this call, you should discard the
|
||||
// original pointer you passed in (which may or may not
|
||||
// now be invalid) and let its reference count decrement
|
||||
// normally; you should use only the returned value from
|
||||
// this point on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexFormat) qpGeomVertexFormat::
|
||||
register_format(qpGeomVertexFormat *format) {
|
||||
return get_registry()->register_format(format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::register_format
|
||||
// Access: Published, Static
|
||||
// Description: This flavor of register_format() implicitly creates a
|
||||
// one-array vertex format from the array definition.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexFormat) qpGeomVertexFormat::
|
||||
register_format(qpGeomVertexArrayFormat *format) {
|
||||
return get_registry()->register_format(format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_num_arrays
|
||||
// Access: Published
|
||||
// Description: Returns the number of individual arrays required by
|
||||
// the format. If the array data is completely
|
||||
// interleaved, this will be 1; if it is completely
|
||||
// parallel, this will be the same as the number of data
|
||||
// types.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexFormat::
|
||||
get_num_arrays() const {
|
||||
return _arrays.size();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_array
|
||||
// Access: Published
|
||||
// Description: Returns the description of the nth array used by the
|
||||
// format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexArrayFormat *qpGeomVertexFormat::
|
||||
get_array(int array) const {
|
||||
nassertr(array >= 0 && array < (int)_arrays.size(), NULL);
|
||||
return _arrays[array];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with just a
|
||||
// 3-component vertex position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3() {
|
||||
return get_registry()->_v3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3n3
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 3-component
|
||||
// normal and a 3-component vertex position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3n3() {
|
||||
return get_registry()->_v3n3;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3t2
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 2-component
|
||||
// texture coordinate pair and a 3-component vertex
|
||||
// position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3t2() {
|
||||
return get_registry()->_v3t2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3n3t2
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 2-component
|
||||
// texture coordinate pair, a 3-component normal, and a
|
||||
// 3-component vertex position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3n3t2() {
|
||||
return get_registry()->_v3n3t2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3cp
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a packed
|
||||
// color and a 3-component vertex position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3cp() {
|
||||
return get_registry()->_v3cp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3n3cp
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a packed
|
||||
// color, a 3-component normal, and a 3-component vertex
|
||||
// position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3n3cp() {
|
||||
return get_registry()->_v3n3cp;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3cpt2
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 2-component
|
||||
// texture coordinate pair, a packed color, and a
|
||||
// 3-component vertex position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3cpt2() {
|
||||
return get_registry()->_v3cpt2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3n3cpt2
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 2-component
|
||||
// texture coordinate pair, a packed color, a
|
||||
// 3-component normal, and a 3-component vertex
|
||||
// position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3n3cpt2() {
|
||||
return get_registry()->_v3n3cpt2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3c4
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 4-component
|
||||
// color and a 3-component vertex position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3c4() {
|
||||
return get_registry()->_v3c4;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3n3c4
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 4-component
|
||||
// color, a 3-component normal, and a 3-component vertex
|
||||
// position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3n3c4() {
|
||||
return get_registry()->_v3n3c4;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3c4t2
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 2-component
|
||||
// texture coordinate pair, a 4-component color, and a
|
||||
// 3-component vertex position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3c4t2() {
|
||||
return get_registry()->_v3c4t2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_v3n3c4t2
|
||||
// Access: Published, Static
|
||||
// Description: Returns a standard vertex format with a 2-component
|
||||
// texture coordinate pair, a 4-component color, a
|
||||
// 3-component normal, and a 3-component vertex
|
||||
// position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexFormat *qpGeomVertexFormat::
|
||||
get_v3n3c4t2() {
|
||||
return get_registry()->_v3n3c4t2;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_registry
|
||||
// Access: Private
|
||||
// Description: Returns the global registry object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexFormat::Registry *qpGeomVertexFormat::
|
||||
get_registry() {
|
||||
if (_registry == (Registry *)NULL) {
|
||||
make_registry();
|
||||
}
|
||||
return _registry;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Registry::register_format
|
||||
// Access: Public
|
||||
// Description: This flavor of register_format() implicitly creates a
|
||||
// one-array vertex format from the array definition.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPT(qpGeomVertexFormat) qpGeomVertexFormat::Registry::
|
||||
register_format(qpGeomVertexArrayFormat *format) {
|
||||
return register_format(new qpGeomVertexFormat(format));
|
||||
}
|
||||
|
|
@ -0,0 +1,632 @@
|
|||
// Filename: qpgeomVertexFormat.cxx
|
||||
// Created by: drose (07Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomVertexFormat.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomMunger.h"
|
||||
#include "indent.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
|
||||
qpGeomVertexFormat::Registry *qpGeomVertexFormat::_registry = NULL;
|
||||
TypeHandle qpGeomVertexFormat::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexFormat::
|
||||
qpGeomVertexFormat() :
|
||||
_is_registered(false)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexFormat::
|
||||
qpGeomVertexFormat(qpGeomVertexArrayFormat *array_format) :
|
||||
_is_registered(false)
|
||||
{
|
||||
add_array(array_format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Copy Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexFormat::
|
||||
qpGeomVertexFormat(const qpGeomVertexFormat ©) :
|
||||
_is_registered(false),
|
||||
_arrays(copy._arrays)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
operator = (const qpGeomVertexFormat ©) {
|
||||
nassertv(!_is_registered);
|
||||
|
||||
_arrays = copy._arrays;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexFormat::
|
||||
~qpGeomVertexFormat() {
|
||||
if (is_registered()) {
|
||||
get_registry()->unregister_format(this);
|
||||
}
|
||||
nassertv(_mungers.empty());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::modify_array
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the indicated array.
|
||||
// This means duplicating it if it is shared or
|
||||
// registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayFormat *qpGeomVertexFormat::
|
||||
modify_array(int array) {
|
||||
nassertr(!_is_registered, NULL);
|
||||
nassertr(array >= 0 && array < (int)_arrays.size(), NULL);
|
||||
|
||||
if (_arrays[array]->is_registered() ||
|
||||
_arrays[array]->get_ref_count() > 1) {
|
||||
_arrays[array] = new qpGeomVertexArrayFormat(*_arrays[array]);
|
||||
}
|
||||
|
||||
return _arrays[array];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::set_array
|
||||
// Access: Published
|
||||
// Description: Replaces the definition of the indicated array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
set_array(int array, qpGeomVertexArrayFormat *format) {
|
||||
nassertv(!_is_registered);
|
||||
nassertv(array >= 0 && array < (int)_arrays.size());
|
||||
_arrays[array] = format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::remove_array
|
||||
// Access: Published
|
||||
// Description: Removes the nth array from the format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
remove_array(int array) {
|
||||
nassertv(!_is_registered);
|
||||
|
||||
nassertv(array >= 0 && array < (int)_arrays.size());
|
||||
_arrays.erase(_arrays.begin() + array);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::add_array
|
||||
// Access: Published
|
||||
// Description: Adds the indicated array definition to the list of
|
||||
// arrays included within this vertex format definition.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
add_array(qpGeomVertexArrayFormat *array_format) {
|
||||
nassertv(!_is_registered);
|
||||
|
||||
_arrays.push_back(array_format);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::clear_arrays
|
||||
// Access: Published
|
||||
// Description: Removes all of the array definitions from the format
|
||||
// and starts over.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
clear_arrays() {
|
||||
nassertv(!_is_registered);
|
||||
|
||||
_arrays.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_num_data_types
|
||||
// Access: Published
|
||||
// Description: Returns the total number of different data types in
|
||||
// the specification, across all arrays.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexFormat::
|
||||
get_num_data_types() const {
|
||||
int num_data_types = 0;
|
||||
Arrays::const_iterator ai;
|
||||
for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
|
||||
num_data_types += (*ai)->get_num_data_types();
|
||||
}
|
||||
return num_data_types;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_data_type
|
||||
// Access: Published
|
||||
// Description: Returns the ith data type of the specification,
|
||||
// across all arrays.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const qpGeomVertexDataType *qpGeomVertexFormat::
|
||||
get_data_type(int i) const {
|
||||
Arrays::const_iterator ai;
|
||||
for (ai = _arrays.begin(); ai != _arrays.end(); ++ai) {
|
||||
if (i < (*ai)->get_num_data_types()) {
|
||||
return (*ai)->get_data_type(i);
|
||||
}
|
||||
i -= (*ai)->get_num_data_types();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_array_with
|
||||
// Access: Published
|
||||
// Description: Returns the index number of the array with the
|
||||
// ith data type.
|
||||
//
|
||||
// The return value can be passed to get_array_format()
|
||||
// to get the format of the array. It may also be
|
||||
// passed to GeomVertexData::get_array_data() or
|
||||
// get_data() or set_data() to manipulate the actual
|
||||
// array data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexFormat::
|
||||
get_array_with(int i) const {
|
||||
int array_index = 0;
|
||||
for (array_index = 0; array_index < (int)_arrays.size(); array_index++) {
|
||||
if (i < _arrays[array_index]->get_num_data_types()) {
|
||||
return array_index;
|
||||
}
|
||||
i -= _arrays[array_index]->get_num_data_types();
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_array_with
|
||||
// Access: Published
|
||||
// Description: Returns the index number of the array with the
|
||||
// indicated data type, or -1 if no arrays contained
|
||||
// that name.
|
||||
//
|
||||
// The return value can be passed to get_array_format()
|
||||
// to get the format of the array. It may also be
|
||||
// passed to GeomVertexData::get_array_data() or
|
||||
// get_data() or set_data() to manipulate the actual
|
||||
// array data.
|
||||
//
|
||||
// This may only be called after the format has been
|
||||
// registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexFormat::
|
||||
get_array_with(const InternalName *name) const {
|
||||
nassertr(_is_registered, -1);
|
||||
|
||||
DataTypesByName::const_iterator ai;
|
||||
ai = _data_types_by_name.find(name);
|
||||
if (ai != _data_types_by_name.end()) {
|
||||
return (*ai).second._array_index;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_data_type
|
||||
// Access: Published
|
||||
// Description: Returns the specification with the indicated name, or
|
||||
// NULL if the name is not used. Use get_array_with()
|
||||
// to determine which array this data type is associated
|
||||
// with.
|
||||
//
|
||||
// This may only be called after the format has been
|
||||
// registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const qpGeomVertexDataType *qpGeomVertexFormat::
|
||||
get_data_type(const InternalName *name) const {
|
||||
nassertr(_is_registered, NULL);
|
||||
|
||||
DataTypesByName::const_iterator ai;
|
||||
ai = _data_types_by_name.find(name);
|
||||
if (ai != _data_types_by_name.end()) {
|
||||
int array_index = (*ai).second._array_index;
|
||||
int data_type_index = (*ai).second._data_type_index;
|
||||
|
||||
nassertr(array_index >= 0 && array_index < (int)_arrays.size(), NULL);
|
||||
return _arrays[array_index]->get_data_type(data_type_index);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::output
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
output(ostream &out) const {
|
||||
if (_arrays.empty()) {
|
||||
out << "(empty)";
|
||||
|
||||
} else {
|
||||
Arrays::const_iterator ai;
|
||||
ai = _arrays.begin();
|
||||
out << *(*ai);
|
||||
++ai;
|
||||
while (ai != _arrays.end()) {
|
||||
out << ", " << *(*ai);
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::write
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
write(ostream &out, int indent_level) const {
|
||||
for (size_t i = 0; i < _arrays.size(); i++) {
|
||||
indent(out, indent_level)
|
||||
<< "Array " << i << ":\n";
|
||||
_arrays[i]->write(out, indent_level + 2);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::write_with_data
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
write_with_data(ostream &out, int indent_level,
|
||||
const qpGeomVertexData *data) const {
|
||||
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);
|
||||
indent(out, indent_level)
|
||||
<< "Array " << i << " (" << (void *)array_data.p() << "):\n";
|
||||
_arrays[i]->write_with_data(out, indent_level + 2, data, i);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::get_array_info
|
||||
// Access: Public
|
||||
// Description: Quickly looks up the indicated data type within all
|
||||
// of the nested arrays and sets array_index and
|
||||
// data_type appropriately. Returns true if the data
|
||||
// type exists in this format, false if it does not.
|
||||
//
|
||||
// This may only be called after the format has been
|
||||
// registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomVertexFormat::
|
||||
get_array_info(const InternalName *name, int &array_index,
|
||||
const qpGeomVertexDataType *&data_type) const {
|
||||
nassertr(_is_registered, false);
|
||||
|
||||
DataTypesByName::const_iterator ai;
|
||||
ai = _data_types_by_name.find(name);
|
||||
if (ai != _data_types_by_name.end()) {
|
||||
array_index = (*ai).second._array_index;
|
||||
data_type = _arrays[array_index]->get_data_type((*ai).second._data_type_index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::compare_to
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomVertexFormat::
|
||||
compare_to(const qpGeomVertexFormat &other) const {
|
||||
if (_arrays.size() != other._arrays.size()) {
|
||||
return (int)_arrays.size() - (int)other._arrays.size();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < _arrays.size(); i++) {
|
||||
int compare = _arrays[i]->compare_to(*other._arrays[i]);
|
||||
if (compare != 0) {
|
||||
return compare;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::make_registry
|
||||
// Access: Private
|
||||
// Description: Returns the global registry object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
make_registry() {
|
||||
if (_registry == (Registry *)NULL) {
|
||||
_registry = new Registry;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::do_register
|
||||
// Access: Private
|
||||
// Description: Called internally when the format is registered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
do_register() {
|
||||
nassertv(!_is_registered);
|
||||
nassertv(_data_types_by_name.empty());
|
||||
nassertv(_mungers.empty());
|
||||
|
||||
int array = 0;
|
||||
for (array = 0; array < (int)_arrays.size(); ++array) {
|
||||
const qpGeomVertexArrayFormat *array_format = _arrays[array];
|
||||
if (!array_format->is_registered()) {
|
||||
((qpGeomVertexArrayFormat *)array_format)->do_register();
|
||||
}
|
||||
|
||||
// Now add the names to the index.
|
||||
int num_data_types = array_format->get_num_data_types();
|
||||
for (int i = 0; i < num_data_types; i++) {
|
||||
const qpGeomVertexDataType *data_type = array_format->get_data_type(i);
|
||||
pair<DataTypesByName::iterator, bool> result;
|
||||
result = _data_types_by_name.insert(DataTypesByName::value_type(data_type->get_name(), DataTypeRecord()));
|
||||
if (!result.second) {
|
||||
gobj_cat.warning()
|
||||
<< "Data type " << data_type->get_name() << " repeated in format.\n";
|
||||
} else {
|
||||
DataTypeRecord &record = (*result.first).second;
|
||||
record._array_index = array;
|
||||
record._data_type_index = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_is_registered = true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::do_unregister
|
||||
// Access: Private
|
||||
// Description: Called internally when the format is unregistered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
do_unregister() {
|
||||
nassertv(_is_registered);
|
||||
_is_registered = false;
|
||||
|
||||
_data_types_by_name.clear();
|
||||
|
||||
Mungers::iterator mi;
|
||||
for (mi = _mungers.begin(); mi != _mungers.end(); ++mi) {
|
||||
(*mi)->remove_format(this);
|
||||
}
|
||||
_mungers.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Tells the BamReader how to create objects of type
|
||||
// qpGeomVertexFormat.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::write_datagram
|
||||
// Access: Public, Virtual
|
||||
// Description: Writes the contents of this object to the datagram
|
||||
// for shipping out to a Bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
TypedWritableReferenceCount::write_datagram(manager, dg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::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 qpGeomVertexFormat::
|
||||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type qpGeomVertexFormat is
|
||||
// encountered in the Bam file. It should create the
|
||||
// qpGeomVertexFormat and extract its information from
|
||||
// the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomVertexFormat::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomVertexFormat *object = new qpGeomVertexFormat;
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
object->fillin(scan, manager);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::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 qpGeomVertexFormat.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::
|
||||
fillin(DatagramIterator &scan, BamReader *manager) {
|
||||
TypedWritableReferenceCount::fillin(scan, manager);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Registry::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexFormat::Registry::
|
||||
Registry() {
|
||||
_v3 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float));
|
||||
|
||||
_v3n3 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float));
|
||||
|
||||
_v3t2 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float));
|
||||
|
||||
_v3n3t2 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float));
|
||||
|
||||
// Define the DirectX-style packed color formats
|
||||
_v3cp = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb));
|
||||
|
||||
_v3n3cp = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb));
|
||||
|
||||
_v3cpt2 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb,
|
||||
InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float));
|
||||
|
||||
_v3n3cpt2 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb,
|
||||
InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float));
|
||||
|
||||
// Define the OpenGL-style per-byte color formats. This is not the
|
||||
// same as a packed format, above, because the resulting byte order
|
||||
// is endian-independent.
|
||||
_v3c4 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 4, qpGeomVertexDataType::NT_uint8));
|
||||
|
||||
_v3n3c4 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 4, qpGeomVertexDataType::NT_uint8));
|
||||
|
||||
_v3c4t2 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 4, qpGeomVertexDataType::NT_uint8,
|
||||
InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float));
|
||||
|
||||
_v3n3c4t2 = register_format(new qpGeomVertexArrayFormat
|
||||
(InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float,
|
||||
InternalName::get_color(), 4, qpGeomVertexDataType::NT_uint8,
|
||||
InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Registry::register_format
|
||||
// Access: Public
|
||||
// Description: Adds the indicated format to the registry, if there
|
||||
// is not an equivalent format already there; in either
|
||||
// case, returns the pointer to the equivalent format
|
||||
// now in the registry.
|
||||
//
|
||||
// This must be called before a format may be used in a
|
||||
// Geom. After this call, you should discard the
|
||||
// original pointer you passed in (which may or may not
|
||||
// now be invalid) and let its reference count decrement
|
||||
// normally; you should use only the returned value from
|
||||
// this point on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomVertexFormat) qpGeomVertexFormat::Registry::
|
||||
register_format(qpGeomVertexFormat *format) {
|
||||
if (format->is_registered()) {
|
||||
return format;
|
||||
}
|
||||
|
||||
// Save the incoming pointer in a local PointerTo, so that if it has
|
||||
// a zero reference count and is not added into the map below, it
|
||||
// will be automatically deleted when this function returns.
|
||||
PT(qpGeomVertexFormat) pt_format = format;
|
||||
|
||||
Formats::iterator fi = _formats.insert(format).first;
|
||||
|
||||
qpGeomVertexFormat *new_format = (*fi);
|
||||
if (!new_format->is_registered()) {
|
||||
new_format->do_register();
|
||||
}
|
||||
|
||||
return new_format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexFormat::Registry::unregister_format
|
||||
// Access: Public
|
||||
// Description: Removes the indicated format from the registry.
|
||||
// Normally this should not be done until the format is
|
||||
// destructing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexFormat::Registry::
|
||||
unregister_format(qpGeomVertexFormat *format) {
|
||||
nassertv(format->is_registered());
|
||||
Formats::iterator fi = _formats.find(format);
|
||||
nassertv(fi != _formats.end());
|
||||
_formats.erase(fi);
|
||||
format->do_unregister();
|
||||
}
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
// Filename: qpgeomVertexFormat.h
|
||||
// Created by: drose (07Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMVERTEXFORMAT_H
|
||||
#define qpGEOMVERTEXFORMAT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "internalName.h"
|
||||
#include "luse.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pmap.h"
|
||||
#include "pset.h"
|
||||
#include "pvector.h"
|
||||
#include "pta_float.h"
|
||||
#include "indirectCompareTo.h"
|
||||
|
||||
class FactoryParams;
|
||||
class qpGeomVertexData;
|
||||
class qpGeomMunger;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexFormat
|
||||
// Description : This class defines the layout of the vertex data
|
||||
// arrays stored within a Geom. The data within a Geom
|
||||
// is typically stored within a single interleaved
|
||||
// array, but it may also be distributed among multiple
|
||||
// different arrays. Each array is described by a
|
||||
// qpGeomVertexArrayFormat object, referenced within
|
||||
// this object.
|
||||
//
|
||||
// There are a number of standard pre-defined
|
||||
// GeomVertexFormat objects, or you may define your own
|
||||
// as needed. You may also record any combination of
|
||||
// standard and/or user-defined data types in your
|
||||
// custom GeomVertexFormat constructions.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexFormat : public TypedWritableReferenceCount {
|
||||
PUBLISHED:
|
||||
qpGeomVertexFormat();
|
||||
qpGeomVertexFormat(qpGeomVertexArrayFormat *array_format);
|
||||
qpGeomVertexFormat(const qpGeomVertexFormat ©);
|
||||
void operator = (const qpGeomVertexFormat ©);
|
||||
virtual ~qpGeomVertexFormat();
|
||||
|
||||
INLINE bool is_registered() const;
|
||||
INLINE static CPT(qpGeomVertexFormat) register_format(qpGeomVertexFormat *format);
|
||||
INLINE static CPT(qpGeomVertexFormat) register_format(qpGeomVertexArrayFormat *format);
|
||||
|
||||
INLINE int get_num_arrays() const;
|
||||
INLINE const qpGeomVertexArrayFormat *get_array(int array) const;
|
||||
qpGeomVertexArrayFormat *modify_array(int array);
|
||||
void set_array(int array, qpGeomVertexArrayFormat *format);
|
||||
void remove_array(int array);
|
||||
void add_array(qpGeomVertexArrayFormat *array_format);
|
||||
void clear_arrays();
|
||||
|
||||
int get_num_data_types() const;
|
||||
int get_array_with(int i) const;
|
||||
const qpGeomVertexDataType *get_data_type(int i) const;
|
||||
|
||||
int get_array_with(const InternalName *name) const;
|
||||
const qpGeomVertexDataType *get_data_type(const InternalName *name) const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
void write_with_data(ostream &out, int indent_level,
|
||||
const qpGeomVertexData *data) const;
|
||||
|
||||
// Some standard vertex formats. No particular requirement to use
|
||||
// one of these, but the DirectX renderers can use these formats
|
||||
// directly, whereas any other format will have to be converted
|
||||
// first.
|
||||
INLINE static const qpGeomVertexFormat *get_v3();
|
||||
INLINE static const qpGeomVertexFormat *get_v3n3();
|
||||
INLINE static const qpGeomVertexFormat *get_v3t2();
|
||||
INLINE static const qpGeomVertexFormat *get_v3n3t2();
|
||||
|
||||
// These formats, with the DirectX-style packed color, are not
|
||||
// supported directly by OpenGL. If you use them, the
|
||||
// GLGraphicsStateGuardian will automatically convert to OpenGL
|
||||
// form (with a small runtime overhead).
|
||||
INLINE static const qpGeomVertexFormat *get_v3cp();
|
||||
INLINE static const qpGeomVertexFormat *get_v3cpt2();
|
||||
INLINE static const qpGeomVertexFormat *get_v3n3cp();
|
||||
INLINE static const qpGeomVertexFormat *get_v3n3cpt2();
|
||||
|
||||
// These formats, with an OpenGL-style four-byte color, are not
|
||||
// supported directly by DirectX. If you use them, the
|
||||
// DXGraphicsStateGuardian will automatically convert to DirectX
|
||||
// form (with a larger runtime overhead, since DirectX8, and old
|
||||
// DirectX9 drivers, require everything to be interleaved together).
|
||||
INLINE static const qpGeomVertexFormat *get_v3c4();
|
||||
INLINE static const qpGeomVertexFormat *get_v3c4t2();
|
||||
INLINE static const qpGeomVertexFormat *get_v3n3c4();
|
||||
INLINE static const qpGeomVertexFormat *get_v3n3c4t2();
|
||||
|
||||
public:
|
||||
bool get_array_info(const InternalName *name,
|
||||
int &array_index,
|
||||
const qpGeomVertexDataType *&data_type) const;
|
||||
|
||||
int compare_to(const qpGeomVertexFormat &other) const;
|
||||
|
||||
private:
|
||||
class Registry;
|
||||
INLINE static Registry *get_registry();
|
||||
static void make_registry();
|
||||
|
||||
void do_register();
|
||||
void do_unregister();
|
||||
|
||||
bool _is_registered;
|
||||
|
||||
typedef pvector< PT(qpGeomVertexArrayFormat) > Arrays;
|
||||
Arrays _arrays;
|
||||
|
||||
class DataTypeRecord {
|
||||
public:
|
||||
int _array_index;
|
||||
int _data_type_index;
|
||||
};
|
||||
|
||||
typedef pmap<const InternalName *, DataTypeRecord> DataTypesByName;
|
||||
DataTypesByName _data_types_by_name;
|
||||
|
||||
typedef pset<qpGeomMunger *> Mungers;
|
||||
Mungers _mungers;
|
||||
|
||||
typedef pset<qpGeomVertexFormat *, IndirectCompareTo<qpGeomVertexFormat> > Formats;
|
||||
class Registry {
|
||||
public:
|
||||
Registry();
|
||||
CPT(qpGeomVertexFormat) register_format(qpGeomVertexFormat *format);
|
||||
INLINE CPT(qpGeomVertexFormat) register_format(qpGeomVertexArrayFormat *format);
|
||||
void unregister_format(qpGeomVertexFormat *format);
|
||||
|
||||
Formats _formats;
|
||||
|
||||
CPT(qpGeomVertexFormat) _v3;
|
||||
CPT(qpGeomVertexFormat) _v3n3;
|
||||
CPT(qpGeomVertexFormat) _v3t2;
|
||||
CPT(qpGeomVertexFormat) _v3n3t2;
|
||||
|
||||
CPT(qpGeomVertexFormat) _v3cp;
|
||||
CPT(qpGeomVertexFormat) _v3n3cp;
|
||||
CPT(qpGeomVertexFormat) _v3cpt2;
|
||||
CPT(qpGeomVertexFormat) _v3n3cpt2;
|
||||
|
||||
CPT(qpGeomVertexFormat) _v3c4;
|
||||
CPT(qpGeomVertexFormat) _v3n3c4;
|
||||
CPT(qpGeomVertexFormat) _v3c4t2;
|
||||
CPT(qpGeomVertexFormat) _v3n3c4t2;
|
||||
};
|
||||
|
||||
static Registry *_registry;
|
||||
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
|
||||
|
||||
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, "qpGeomVertexFormat",
|
||||
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 qpGeomVertexFormat::Registry;
|
||||
friend class qpGeomMunger;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const qpGeomVertexFormat &obj);
|
||||
|
||||
#include "qpgeomVertexFormat.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,380 @@
|
|||
// Filename: qpgeomVertexIterator.I
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: qpGeomVertexIterator::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a new iterator to process the vertices of
|
||||
// the indicated data object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexIterator::
|
||||
qpGeomVertexIterator(qpGeomVertexData *data) :
|
||||
_data(data),
|
||||
_array(0),
|
||||
_data_type(NULL),
|
||||
_start_vertex(0),
|
||||
_read_vertex(0),
|
||||
_write_vertex(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a new iterator to process the vertices of
|
||||
// the indicated data object. This flavor creates the
|
||||
// iterator specifically to process the named data type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexIterator::
|
||||
qpGeomVertexIterator(qpGeomVertexData *data, const string &name) :
|
||||
_data(data),
|
||||
_array(0),
|
||||
_data_type(NULL),
|
||||
_start_vertex(0),
|
||||
_read_vertex(0),
|
||||
_write_vertex(0)
|
||||
{
|
||||
set_data_type(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::Constructor
|
||||
// Access: Published
|
||||
// Description: Constructs a new iterator to process the vertices of
|
||||
// the indicated data object. This flavor creates the
|
||||
// iterator specifically to process the named data type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexIterator::
|
||||
qpGeomVertexIterator(qpGeomVertexData *data, const InternalName *name) :
|
||||
_data(data),
|
||||
_array(0),
|
||||
_data_type(NULL),
|
||||
_start_vertex(0),
|
||||
_read_vertex(0),
|
||||
_write_vertex(0)
|
||||
{
|
||||
set_data_type(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_data
|
||||
// Access: Published
|
||||
// Description: Returns the current data object that the iterator is
|
||||
// processing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexData *qpGeomVertexIterator::
|
||||
get_data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the iterator to use the nth data type of the
|
||||
// GeomVertexFormat, numbering from 0.
|
||||
//
|
||||
// This also resets the read and write vertex numbers to
|
||||
// the start vertex (the same value passed to a previous
|
||||
// call to set_vertex(), or 0 if set_vertex() was never
|
||||
// called.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data_type(int data_type) {
|
||||
nassertv(_data->get_format()->get_array_with(data_type) >= 0);
|
||||
set_data_type(_data->get_format()->get_array_with(data_type),
|
||||
_data->get_format()->get_data_type(data_type));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the iterator to use the data type with the
|
||||
// indicated name.
|
||||
//
|
||||
// This also resets the read and write vertex numbers to
|
||||
// the start vertex (the same value passed to a previous
|
||||
// call to set_vertex(), or 0 if set_vertex() was never
|
||||
// called.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data_type(const string &name) {
|
||||
set_data_type(InternalName::make(name));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the iterator to use the data type with the
|
||||
// indicated name.
|
||||
//
|
||||
// This also resets the read and write vertex numbers to
|
||||
// the start vertex (the same value passed to a previous
|
||||
// call to set_vertex(), or 0 if set_vertex() was never
|
||||
// called.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data_type(const InternalName *name) {
|
||||
nassertv(_data->get_format()->get_array_with(name) >= 0);
|
||||
set_data_type(_data->get_format()->get_array_with(name),
|
||||
_data->get_format()->get_data_type(name));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data_type
|
||||
// Access: Published
|
||||
// Description: Sets up the iterator to use the indicated data_type
|
||||
// description on the given array.
|
||||
//
|
||||
// This also resets the read and write vertex numbers to
|
||||
// the start vertex (the same value passed to a previous
|
||||
// call to set_vertex(), or 0 if set_vertex() was never
|
||||
// called.)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data_type(int array, const qpGeomVertexDataType *data_type) {
|
||||
nassertv(array >= 0 && array < _data->get_num_arrays());
|
||||
nassertv(data_type != (qpGeomVertexDataType *)NULL);
|
||||
_array = array;
|
||||
_data_type = data_type;
|
||||
|
||||
_read_vertex = _start_vertex;
|
||||
_write_vertex = _start_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_array
|
||||
// Access: Published
|
||||
// Description: Returns the array index containing the data type that
|
||||
// the iterator is working on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexIterator::
|
||||
get_array() const {
|
||||
return _array;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_data_type
|
||||
// Access: Published
|
||||
// Description: Returns the description of the data type that the
|
||||
// iterator is working on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const qpGeomVertexDataType *qpGeomVertexIterator::
|
||||
get_data_type() const {
|
||||
return _data_type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_vertex
|
||||
// Access: Published
|
||||
// Description: Sets the start, read, and write index to the
|
||||
// indicated value. The iterator will begin traversing
|
||||
// from the given vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_vertex(int vertex) {
|
||||
_start_vertex = vertex;
|
||||
_read_vertex = vertex;
|
||||
_write_vertex = vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_start_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the vertex index at which the iterator
|
||||
// started. It will return to this vertex if you reset
|
||||
// the current data_type.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexIterator::
|
||||
get_start_vertex() const {
|
||||
return _start_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_read_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the current read vertex index of the
|
||||
// iterator. This is the index whose value will be
|
||||
// returned by the next call to get_vertex().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexIterator::
|
||||
get_read_vertex() const {
|
||||
return _read_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_write_vertex
|
||||
// Access: Published
|
||||
// Description: Returns the current write vertex index of the
|
||||
// iterator. This is the index whose value will be
|
||||
// modified by the next call to set_vertex().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexIterator::
|
||||
get_write_vertex() const {
|
||||
return _write_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data1
|
||||
// Access: Published
|
||||
// Description: Sets the write vertex to a particular 1-component
|
||||
// value, and advances the write vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data1(float data) {
|
||||
_data->set_data(_array, _data_type, _write_vertex, &data, 1);
|
||||
++_write_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data2
|
||||
// Access: Published
|
||||
// Description: Sets the write vertex to a particular 2-component
|
||||
// value, and advances the write vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data2(float x, float y) {
|
||||
set_data2(LVecBase2f(x, y));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data2
|
||||
// Access: Published
|
||||
// Description: Sets the write vertex to a particular 2-component
|
||||
// value, and advances the write vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data2(const LVecBase2f &data) {
|
||||
_data->set_data(_array, _data_type, _write_vertex, data.get_data(), 2);
|
||||
++_write_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data3
|
||||
// Access: Published
|
||||
// Description: Sets the write vertex to a particular 3-component
|
||||
// value, and advances the write vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data3(float x, float y, float z) {
|
||||
set_data3(LVecBase3f(x, y, z));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data3
|
||||
// Access: Published
|
||||
// Description: Sets the write vertex to a particular 3-component
|
||||
// value, and advances the write vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data3(const LVecBase3f &data) {
|
||||
_data->set_data(_array, _data_type, _write_vertex, data.get_data(), 3);
|
||||
++_write_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data4
|
||||
// Access: Published
|
||||
// Description: Sets the write vertex to a particular 4-component
|
||||
// value, and advances the write vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data4(float x, float y, float z, float w) {
|
||||
set_data4(LVecBase4f(x, y, z, w));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::set_data4
|
||||
// Access: Published
|
||||
// Description: Sets the write vertex to a particular 4-component
|
||||
// value, and advances the write vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void qpGeomVertexIterator::
|
||||
set_data4(const LVecBase4f &data) {
|
||||
_data->set_data(_array, _data_type, _write_vertex, data.get_data(), 4);
|
||||
++_write_vertex;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_data1
|
||||
// Access: Published
|
||||
// Description: Returns the data associated with the read vertex,
|
||||
// expressed as a 1-component value, and advances the
|
||||
// read vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE float qpGeomVertexIterator::
|
||||
get_data1() {
|
||||
float data;
|
||||
_data->get_data(_array, _data_type, _read_vertex, &data, 1);
|
||||
++_read_vertex;
|
||||
return data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_data2
|
||||
// Access: Published
|
||||
// Description: Returns the data associated with the read vertex,
|
||||
// expressed as a 2-component value, and advances the
|
||||
// read vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LVecBase2f qpGeomVertexIterator::
|
||||
get_data2() {
|
||||
float data[4];
|
||||
int num_values = min(_data_type->get_num_values(), 4);
|
||||
_data->get_data(_array, _data_type, _read_vertex, data, num_values);
|
||||
++_read_vertex;
|
||||
LVecBase2f result;
|
||||
qpGeomVertexData::to_vec2(result, data, num_values);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_data3
|
||||
// Access: Published
|
||||
// Description: Returns the data associated with the read vertex,
|
||||
// expressed as a 3-component value, and advances the
|
||||
// read vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LVecBase3f qpGeomVertexIterator::
|
||||
get_data3() {
|
||||
float data[4];
|
||||
int num_values = min(_data_type->get_num_values(), 4);
|
||||
_data->get_data(_array, _data_type, _read_vertex, data, num_values);
|
||||
++_read_vertex;
|
||||
LVecBase3f result;
|
||||
qpGeomVertexData::to_vec3(result, data, num_values);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexIterator::get_data4
|
||||
// Access: Published
|
||||
// Description: Returns the data associated with the read vertex,
|
||||
// expressed as a 4-component value, and advances the
|
||||
// read vertex.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE LVecBase4f qpGeomVertexIterator::
|
||||
get_data4() {
|
||||
float data[4];
|
||||
int num_values = min(_data_type->get_num_values(), 4);
|
||||
_data->get_data(_array, _data_type, _read_vertex, data, num_values);
|
||||
++_read_vertex;
|
||||
LVecBase4f result;
|
||||
qpGeomVertexData::to_vec4(result, data, num_values);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// Filename: qpgeomVertexIterator.cxx
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "qpgeomVertexIterator.h"
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
// Filename: qpgeomVertexIterator.h
|
||||
// Created by: drose (10Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 qpGEOMVERTEXITERATOR_H
|
||||
#define qpGEOMVERTEXITERATOR_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomVertexData.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "internalName.h"
|
||||
#include "luse.h"
|
||||
#include "pointerTo.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexIterator
|
||||
// Description : This is used to read or write the vertices of a
|
||||
// GeomVertexData structure, one vertex and data type at
|
||||
// a time.
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomVertexIterator {
|
||||
PUBLISHED:
|
||||
INLINE qpGeomVertexIterator(qpGeomVertexData *data);
|
||||
INLINE qpGeomVertexIterator(qpGeomVertexData *data,
|
||||
const string &name);
|
||||
INLINE qpGeomVertexIterator(qpGeomVertexData *data,
|
||||
const InternalName *name);
|
||||
|
||||
INLINE qpGeomVertexData *get_data() const;
|
||||
|
||||
INLINE void set_data_type(int data_type);
|
||||
INLINE void set_data_type(const string &name);
|
||||
INLINE void set_data_type(const InternalName *name);
|
||||
INLINE void set_data_type(int array, const qpGeomVertexDataType *data_type);
|
||||
|
||||
INLINE int get_array() const;
|
||||
INLINE const qpGeomVertexDataType *get_data_type() const;
|
||||
|
||||
INLINE void set_vertex(int vertex);
|
||||
|
||||
INLINE int get_start_vertex() const;
|
||||
INLINE int get_read_vertex() const;
|
||||
INLINE int get_write_vertex() const;
|
||||
|
||||
INLINE void set_data1(float data);
|
||||
INLINE void set_data2(float x, float y);
|
||||
INLINE void set_data2(const LVecBase2f &data);
|
||||
INLINE void set_data3(float x, float y, float z);
|
||||
INLINE void set_data3(const LVecBase3f &data);
|
||||
INLINE void set_data4(float x, float y, float z, float w);
|
||||
INLINE void set_data4(const LVecBase4f &data);
|
||||
|
||||
INLINE float get_data1();
|
||||
INLINE LVecBase2f get_data2();
|
||||
INLINE LVecBase3f get_data3();
|
||||
INLINE LVecBase4f get_data4();
|
||||
|
||||
private:
|
||||
PT(qpGeomVertexData) _data;
|
||||
int _array;
|
||||
const qpGeomVertexDataType *_data_type;
|
||||
|
||||
int _start_vertex;
|
||||
int _read_vertex;
|
||||
int _write_vertex;
|
||||
};
|
||||
|
||||
#include "qpgeomVertexIterator.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
// Filename: texCoordName.I
|
||||
// Created by: masad (15Jul04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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: TexCoordName::get_name
|
||||
// Access: Published
|
||||
// Description: Return the name string of this texcoordname
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const string &TexCoordName::
|
||||
get_name() const {
|
||||
return _name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::get_default
|
||||
// Access: Published, Static
|
||||
// Description: Returns the default TexCoordName that will be used
|
||||
// for all geometry that does not give a particular name
|
||||
// for its UV's
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TexCoordName *TexCoordName::
|
||||
get_default() {
|
||||
if (_default_name == (TexCoordName *)NULL) {
|
||||
_default_name = TexCoordName::make("default");
|
||||
}
|
||||
return _default_name;
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
operator << (ostream &out, const TexCoordName &tcn) {
|
||||
tcn.output(out);
|
||||
return out;
|
||||
}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
// Filename: texCoordName.cxx
|
||||
// Created by: masad (15Jul04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "texCoordName.h"
|
||||
#include "datagram.h"
|
||||
#include "datagramIterator.h"
|
||||
#include "bamReader.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
|
||||
TexCoordName::TexCoordsByName TexCoordName::_texcoords_by_name;
|
||||
CPT(TexCoordName) TexCoordName::_default_name;
|
||||
|
||||
TypeHandle TexCoordName::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::Constructor
|
||||
// Access: Private
|
||||
// Description: Use make() to make a new TexCoordName instance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TexCoordName::
|
||||
TexCoordName(const string &name) {
|
||||
_name = name;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TexCoordName::
|
||||
~TexCoordName() {
|
||||
TexCoordsByName::iterator ni = _texcoords_by_name.find(_name);
|
||||
nassertv(ni != _texcoords_by_name.end());
|
||||
_texcoords_by_name.erase(ni);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::make
|
||||
// Access: Published
|
||||
// Description: The public interface for constructing a TexCoordName
|
||||
// pointer. This will return a new TexCoordName
|
||||
// associated with the indicated name, if this is the
|
||||
// first time the particular name has been requested; if
|
||||
// the name is already in use, it will return the
|
||||
// existing pointer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const TexCoordName *TexCoordName::
|
||||
make(const string &name) {
|
||||
TexCoordsByName::iterator ni = _texcoords_by_name.find(name);
|
||||
if (ni != _texcoords_by_name.end()) {
|
||||
return (*ni).second;
|
||||
}
|
||||
|
||||
TexCoordName *texcoord = new TexCoordName(name);
|
||||
_texcoords_by_name[name] = texcoord;
|
||||
return texcoord;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::output
|
||||
// Access: Published
|
||||
// Description: output the TexCoordName and its member data
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TexCoordName::
|
||||
output(ostream &out) const {
|
||||
out << get_name();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::register_with_read_factory
|
||||
// Access: Public, Static
|
||||
// Description: Factory method to generate a TexCoordName object
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TexCoordName::
|
||||
register_with_read_factory() {
|
||||
BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::finalize
|
||||
// Access: Public, Virtual
|
||||
// Description: Method to ensure that any necessary clean up tasks
|
||||
// that have to be performed by this object are performed
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TexCoordName::
|
||||
finalize() {
|
||||
// Unref the pointer that we explicitly reffed in make_from_bam().
|
||||
unref();
|
||||
|
||||
// We should never get back to zero after unreffing our own count,
|
||||
// because we expect to have been stored in a pointer somewhere. If
|
||||
// we do get to zero, it's a memory leak; the way to avoid this is
|
||||
// to call unref_delete() above instead of unref(), but this is
|
||||
// dangerous to do from within a virtual function.
|
||||
nassertv(get_ref_count() != 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::make_from_bam
|
||||
// Access: Protected, Static
|
||||
// Description: This function is called by the BamReader's factory
|
||||
// when a new object of type TexCoordName is encountered
|
||||
// in the Bam file. It should create the TexCoordName
|
||||
// and extract its information from the file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *TexCoordName::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
// The process of making a TexCoordName is slightly
|
||||
// different than making other Writable objects.
|
||||
// That is because all creation of TexCoordNames should
|
||||
// be done through the make() constructor.
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
parse_params(params, scan, manager);
|
||||
|
||||
// The name is the only thing written to the data stream.
|
||||
string name = scan.get_string();
|
||||
|
||||
// Make a new TexCoordName with that name (or get the previous one
|
||||
// if there is one already).
|
||||
PT(TexCoordName) me = (TexCoordName *)make(name);
|
||||
|
||||
// But now we have a problem, since we have to hold the reference
|
||||
// count and there's no way to return a TypedWritable while still
|
||||
// holding the reference count! We work around this by explicitly
|
||||
// upping the count, and also setting a finalize() callback to down
|
||||
// it later.
|
||||
me->ref();
|
||||
manager->register_finalize(me);
|
||||
|
||||
return me.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TexCoordName::write_datagram
|
||||
// Access: Public
|
||||
// Description: Function to write the important information in
|
||||
// the particular object to a Datagram
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TexCoordName::
|
||||
write_datagram(BamWriter *manager, Datagram &me) {
|
||||
me.add_string(_name);
|
||||
}
|
||||
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
// Filename: texCoordName.h
|
||||
// Created by: drose (15Jul04)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 TEXCOORDNAME_H
|
||||
#define TEXCOORDNAME_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "typedWritableReferenceCount.h"
|
||||
|
||||
class FactoryParams;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : TexCoordName
|
||||
// Description : Associates a name with a set of texture coordinates,
|
||||
// for the purpose of storing within a Geom. This is
|
||||
// used in conjunction with TextureStage to support
|
||||
// multitexturing.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA TexCoordName : public TypedWritableReferenceCount {
|
||||
private:
|
||||
TexCoordName(const string &name);
|
||||
|
||||
PUBLISHED:
|
||||
virtual ~TexCoordName();
|
||||
|
||||
static const TexCoordName *make(const string &name);
|
||||
INLINE const string &get_name() const;
|
||||
|
||||
void output(ostream &out) const;
|
||||
|
||||
INLINE static const TexCoordName *get_default();
|
||||
|
||||
private:
|
||||
string _name;
|
||||
|
||||
typedef phash_map<string, TexCoordName *, string_hash> TexCoordsByName;
|
||||
static TexCoordsByName _texcoords_by_name;
|
||||
|
||||
static CPT(TexCoordName) _default_name;
|
||||
|
||||
public:
|
||||
// Datagram stuff
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &me);
|
||||
|
||||
virtual void finalize();
|
||||
|
||||
protected:
|
||||
static TypedWritable *make_from_bam(const FactoryParams ¶ms);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
TypedWritableReferenceCount::init_type();
|
||||
register_type(_type_handle, "TexCoordName",
|
||||
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;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const TexCoordName &tcn);
|
||||
|
||||
#include "texCoordName.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -136,7 +136,7 @@ operator < (const TextureStage &other) const {
|
|||
// sets, each of which must have a unique name.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TextureStage::
|
||||
set_texcoord_name(const TexCoordName *name) {
|
||||
set_texcoord_name(const InternalName *name) {
|
||||
_texcoord_name = name;
|
||||
}
|
||||
|
||||
|
|
@ -149,15 +149,15 @@ set_texcoord_name(const TexCoordName *name) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void TextureStage::
|
||||
set_texcoord_name(const string &name) {
|
||||
_texcoord_name = TexCoordName::make(name);
|
||||
_texcoord_name = InternalName::get_texcoord_name(name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureStage::get_texcoord_name
|
||||
// Access: Published
|
||||
// Description: Returns the TexCoordName
|
||||
// Description: Returns the InternalName
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const TexCoordName *TextureStage::
|
||||
INLINE const InternalName *TextureStage::
|
||||
get_texcoord_name() const {
|
||||
return _texcoord_name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "textureStage.h"
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
|
||||
PT(TextureStage) TextureStage::_default_stage;
|
||||
UpdateSeq TextureStage::_sort_seq;
|
||||
|
|
@ -34,7 +34,7 @@ TextureStage(const string &name) {
|
|||
_name = name;
|
||||
_sort = 0;
|
||||
_priority = 0;
|
||||
_texcoord_name = TexCoordName::get_default();
|
||||
_texcoord_name = InternalName::get_texcoord();
|
||||
_mode = M_modulate;
|
||||
_color.set(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
_rgb_scale = 1;
|
||||
|
|
@ -319,7 +319,7 @@ int TextureStage::
|
|||
complete_pointers(TypedWritable **p_list, BamReader *manager) {
|
||||
int pi = TypedWritableReferenceCount::complete_pointers(p_list, manager);
|
||||
|
||||
_texcoord_name = DCAST(TexCoordName, p_list[pi++]);
|
||||
_texcoord_name = DCAST(InternalName, p_list[pi++]);
|
||||
|
||||
return pi;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "texCoordName.h"
|
||||
#include "internalName.h"
|
||||
#include "pointerTo.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "updateSeq.h"
|
||||
|
|
@ -100,9 +100,9 @@ PUBLISHED:
|
|||
|
||||
INLINE bool operator < (const TextureStage &other) const;
|
||||
|
||||
INLINE void set_texcoord_name(const TexCoordName *name);
|
||||
INLINE void set_texcoord_name(const InternalName *name);
|
||||
INLINE void set_texcoord_name(const string &texcoord_name);
|
||||
INLINE const TexCoordName *get_texcoord_name() const;
|
||||
INLINE const InternalName *get_texcoord_name() const;
|
||||
|
||||
INLINE void set_mode(Mode mode);
|
||||
INLINE Mode get_mode() const;
|
||||
|
|
@ -170,7 +170,7 @@ private:
|
|||
string _name;
|
||||
int _sort;
|
||||
int _priority;
|
||||
CPT(TexCoordName) _texcoord_name;
|
||||
CPT(InternalName) _texcoord_name;
|
||||
Mode _mode;
|
||||
Colorf _color;
|
||||
int _rgb_scale;
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ scan(PandaNode *node, const RenderState *state, const TransformState *transform)
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MultitexReducer::set_target
|
||||
// Access: Published
|
||||
// Description: Specifies the target TextureStage (and TexCoordName)
|
||||
// Description: Specifies the target TextureStage (and InternalName)
|
||||
// that will be left on each multitexture node after the
|
||||
// flatten operation has completed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -544,7 +544,7 @@ bool MultitexReducer::
|
|||
determine_uv_range(TexCoordf &min_uv, TexCoordf &max_uv,
|
||||
const MultitexReducer::StageInfo &model_stage,
|
||||
const MultitexReducer::GeomList &geom_list) const {
|
||||
const TexCoordName *model_name = model_stage._stage->get_texcoord_name();
|
||||
const InternalName *model_name = model_stage._stage->get_texcoord_name();
|
||||
bool got_any = false;
|
||||
|
||||
GeomList::const_iterator gi;
|
||||
|
|
@ -799,7 +799,7 @@ make_texture_layer(const NodePath &render,
|
|||
// coordinates to the target set.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MultitexReducer::
|
||||
transfer_geom(GeomNode *geom_node, const TexCoordName *texcoord_name,
|
||||
transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
|
||||
const MultitexReducer::GeomList &geom_list,
|
||||
bool preserve_color) {
|
||||
GeomList::const_iterator gi;
|
||||
|
|
@ -820,8 +820,8 @@ transfer_geom(GeomNode *geom_node, const TexCoordName *texcoord_name,
|
|||
}
|
||||
|
||||
geom->set_coords(coords, geom->get_texcoords_index(_target_stage->get_texcoord_name()));
|
||||
if (texcoord_name != (const TexCoordName *)NULL) {
|
||||
geom->set_texcoords(TexCoordName::get_default(),
|
||||
if (texcoord_name != (const InternalName *)NULL) {
|
||||
geom->set_texcoords(InternalName::get_texcoord(),
|
||||
geom->get_texcoords_array(texcoord_name),
|
||||
geom->get_texcoords_index(texcoord_name));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ private:
|
|||
const StageInfo &stage_info,
|
||||
const GeomList &geom_list,
|
||||
bool force_use_geom);
|
||||
void transfer_geom(GeomNode *geom_node, const TexCoordName *texcoord_name,
|
||||
void transfer_geom(GeomNode *geom_node, const InternalName *texcoord_name,
|
||||
const GeomList &geom_list, bool preserve_color);
|
||||
|
||||
void scan_color(const GeomList &geom_list, Colorf &geom_color,
|
||||
|
|
|
|||
|
|
@ -43,6 +43,10 @@ class GeomTri;
|
|||
class GeomTristrip;
|
||||
class GeomTrifan;
|
||||
class GeomSphere;
|
||||
class qpGeomVertexData;
|
||||
class qpGeomTriangles;
|
||||
class qpGeomTristrips;
|
||||
class qpGeomTrifans;
|
||||
|
||||
class PreparedGraphicsObjects;
|
||||
class GraphicsOutput;
|
||||
|
|
@ -165,6 +169,12 @@ public:
|
|||
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0;
|
||||
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0;
|
||||
|
||||
virtual void begin_draw_primitives(const qpGeomVertexData *vertex_data)=0;
|
||||
virtual void draw_triangles(qpGeomTriangles *primitive)=0;
|
||||
virtual void draw_tristrips(qpGeomTristrips *primitive)=0;
|
||||
virtual void draw_trifans(qpGeomTrifans *primitive)=0;
|
||||
virtual void end_draw_primitives()=0;
|
||||
|
||||
virtual void framebuffer_copy_to_texture
|
||||
(Texture *tex, int z, const DisplayRegion *dr, const RenderBuffer &rb)=0;
|
||||
virtual bool framebuffer_copy_to_ram
|
||||
|
|
|
|||
|
|
@ -182,10 +182,10 @@ get_default_collide_mask() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::count_name
|
||||
// Access: Private
|
||||
// Description: Increments the count for the indicated TexCoordName.
|
||||
// Description: Increments the count for the indicated InternalName.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomNode::
|
||||
count_name(GeomNode::NameCount &name_count, const TexCoordName *name) {
|
||||
count_name(GeomNode::NameCount &name_count, const InternalName *name) {
|
||||
pair<NameCount::iterator, bool> result =
|
||||
name_count.insert(NameCount::value_type(name, 1));
|
||||
if (!result.second) {
|
||||
|
|
@ -196,10 +196,10 @@ count_name(GeomNode::NameCount &name_count, const TexCoordName *name) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomNode::get_name_count
|
||||
// Access: Private
|
||||
// Description: Returns the count for the indicated TexCoordName.
|
||||
// Description: Returns the count for the indicated InternalName.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomNode::
|
||||
get_name_count(const GeomNode::NameCount &name_count, const TexCoordName *name) {
|
||||
get_name_count(const GeomNode::NameCount &name_count, const InternalName *name) {
|
||||
NameCount::const_iterator ni;
|
||||
ni = name_count.find(name);
|
||||
if (ni != name_count.end()) {
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||
int num_on_stages = ta->get_num_on_stages();
|
||||
for (int si = 0; si < num_on_stages; si++) {
|
||||
TextureStage *stage = ta->get_on_stage(si);
|
||||
const TexCoordName *name = stage->get_texcoord_name();
|
||||
const InternalName *name = stage->get_texcoord_name();
|
||||
count_name(name_count, name);
|
||||
}
|
||||
}
|
||||
|
|
@ -248,7 +248,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
|
|||
int num_stages = tma->get_num_stages();
|
||||
for (int i = 0; i < num_stages; i++) {
|
||||
TextureStage *stage = tma->get_stage(i);
|
||||
const TexCoordName *name = stage->get_texcoord_name();
|
||||
const InternalName *name = stage->get_texcoord_name();
|
||||
if (get_name_count(name_count, name) > 1) {
|
||||
// We can't transform these texcoords, since the name is
|
||||
// used by more than one active stage.
|
||||
|
|
|
|||
|
|
@ -92,10 +92,10 @@ public:
|
|||
|
||||
private:
|
||||
typedef pvector<GeomEntry> Geoms;
|
||||
typedef pmap<const TexCoordName *, int> NameCount;
|
||||
typedef pmap<const InternalName *, int> NameCount;
|
||||
|
||||
INLINE void count_name(NameCount &name_count, const TexCoordName *name);
|
||||
INLINE int get_name_count(const NameCount &name_count, const TexCoordName *name);
|
||||
INLINE void count_name(NameCount &name_count, const InternalName *name);
|
||||
INLINE int get_name_count(const NameCount &name_count, const InternalName *name);
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
|
|
|
|||
|
|
@ -150,8 +150,8 @@ transform_vertices(GeomNode *node, const LMatrix4f &mat) {
|
|||
// Geom was changed, false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomTransformer::
|
||||
transform_texcoords(Geom *geom, const TexCoordName *from_name,
|
||||
const TexCoordName *to_name, const LMatrix4f &mat) {
|
||||
transform_texcoords(Geom *geom, const InternalName *from_name,
|
||||
const InternalName *to_name, const LMatrix4f &mat) {
|
||||
bool transformed = false;
|
||||
|
||||
nassertr(geom != (Geom *)NULL, false);
|
||||
|
|
@ -201,8 +201,8 @@ transform_texcoords(Geom *geom, const TexCoordName *from_name,
|
|||
// false otherwise.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomTransformer::
|
||||
transform_texcoords(GeomNode *node, const TexCoordName *from_name,
|
||||
const TexCoordName *to_name, const LMatrix4f &mat) {
|
||||
transform_texcoords(GeomNode *node, const InternalName *from_name,
|
||||
const InternalName *to_name, const LMatrix4f &mat) {
|
||||
bool any_changed = false;
|
||||
|
||||
GeomNode::CDWriter cdata(node->_cycler);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
class GeomNode;
|
||||
class RenderState;
|
||||
class TexCoordName;
|
||||
class InternalName;
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
// Class : GeomTransformer
|
||||
|
|
@ -52,11 +52,11 @@ public:
|
|||
bool transform_vertices(Geom *geom, const LMatrix4f &mat);
|
||||
bool transform_vertices(GeomNode *node, const LMatrix4f &mat);
|
||||
|
||||
bool transform_texcoords(Geom *geom, const TexCoordName *from_name,
|
||||
const TexCoordName *to_name,
|
||||
bool transform_texcoords(Geom *geom, const InternalName *from_name,
|
||||
const InternalName *to_name,
|
||||
const LMatrix4f &mat);
|
||||
bool transform_texcoords(GeomNode *node, const TexCoordName *from_name,
|
||||
const TexCoordName *to_name,
|
||||
bool transform_texcoords(GeomNode *node, const InternalName *from_name,
|
||||
const InternalName *to_name,
|
||||
const LMatrix4f &mat);
|
||||
|
||||
bool set_color(Geom *geom, const Colorf &color);
|
||||
|
|
|
|||
Loading…
Reference in New Issue