diff --git a/panda/src/display/colorMunger.cxx b/panda/src/display/colorMunger.cxx index 771b6a3fec..9a08da748e 100644 --- a/panda/src/display/colorMunger.cxx +++ b/panda/src/display/colorMunger.cxx @@ -30,10 +30,12 @@ TypeHandle ColorMunger::_type_handle; ColorMunger:: ColorMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state, int num_components, - qpGeomVertexDataType::NumericType numeric_type) : + qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents) : qpGeomMunger(gsg, state), _num_components(num_components), - _numeric_type(numeric_type) + _numeric_type(numeric_type), + _contents(contents) { _color = state->get_color(); _color_scale = state->get_color_scale(); @@ -69,12 +71,14 @@ munge_data_impl(const qpGeomVertexData *data) { color[2] * cs[2], color[3] * cs[3]); } - new_data = new_data->set_color(color, _num_components, _numeric_type); + new_data = new_data->set_color(color, _num_components, _numeric_type, + _contents); } else if (_color_scale != (ColorScaleAttrib *)NULL && _color_scale->has_scale()) { const LVecBase4f &cs = _color_scale->get_scale(); - new_data = new_data->scale_color(cs, _num_components, _numeric_type); + new_data = new_data->scale_color(cs, _num_components, _numeric_type, + _contents); } return qpGeomMunger::munge_data_impl(new_data); diff --git a/panda/src/display/colorMunger.h b/panda/src/display/colorMunger.h index 47149fa216..0639d4ffc8 100644 --- a/panda/src/display/colorMunger.h +++ b/panda/src/display/colorMunger.h @@ -36,7 +36,8 @@ class EXPCL_PANDA ColorMunger : public qpGeomMunger { public: ColorMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state, int num_components, - qpGeomVertexDataType::NumericType numeric_type); + qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents); virtual ~ColorMunger(); protected: @@ -47,6 +48,7 @@ protected: private: int _num_components; qpGeomVertexDataType::NumericType _numeric_type; + qpGeomVertexDataType::Contents _contents; CPT(ColorAttrib) _color; CPT(ColorScaleAttrib) _color_scale; diff --git a/panda/src/dxgsg8/dxGeomMunger8.I b/panda/src/dxgsg8/dxGeomMunger8.I index 28d0d78a75..ab8300638d 100644 --- a/panda/src/dxgsg8/dxGeomMunger8.I +++ b/panda/src/dxgsg8/dxGeomMunger8.I @@ -24,7 +24,8 @@ //////////////////////////////////////////////////////////////////// INLINE DXGeomMunger8:: DXGeomMunger8(GraphicsStateGuardian *gsg, const RenderState *state) : - ColorMunger(gsg, state, 1, qpGeomVertexDataType::NT_packed_argb) + ColorMunger(gsg, state, 1, qpGeomVertexDataType::NT_packed_8888, + qpGeomVertexDataType::C_argb) { } diff --git a/panda/src/dxgsg8/dxGeomMunger8.cxx b/panda/src/dxgsg8/dxGeomMunger8.cxx index b134652ea1..c37417a14f 100644 --- a/panda/src/dxgsg8/dxGeomMunger8.cxx +++ b/panda/src/dxgsg8/dxGeomMunger8.cxx @@ -45,7 +45,8 @@ munge_format_impl(const qpGeomVertexFormat *orig) { if (vertex_type != (const qpGeomVertexDataType *)NULL) { new_array_format->add_data_type - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32); + (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point); } else { // If we don't have a vertex type, not much we can do. return orig; @@ -53,12 +54,14 @@ munge_format_impl(const qpGeomVertexFormat *orig) { if (normal_type != (const qpGeomVertexDataType *)NULL) { new_array_format->add_data_type - (InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32); + (InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_vector); } if (color_type != (const qpGeomVertexDataType *)NULL) { new_array_format->add_data_type - (InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb); + (InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_8888, + qpGeomVertexDataType::C_argb); } // To support multitexture, we will need to add all of the relevant @@ -67,7 +70,7 @@ munge_format_impl(const qpGeomVertexFormat *orig) { if (texcoord_type != (const qpGeomVertexDataType *)NULL) { new_array_format->add_data_type (InternalName::get_texcoord(), texcoord_type->get_num_values(), - qpGeomVertexDataType::NT_float32); + qpGeomVertexDataType::NT_float32, qpGeomVertexDataType::C_texcoord); } PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat(new_array_format); diff --git a/panda/src/egg2pg/eggLoader.cxx b/panda/src/egg2pg/eggLoader.cxx index 51306e07fd..a9c111efc4 100644 --- a/panda/src/egg2pg/eggLoader.cxx +++ b/panda/src/egg2pg/eggLoader.cxx @@ -1921,16 +1921,18 @@ make_vertex_data(const EggRenderState *render_state, PT(qpGeomVertexArrayFormat) array_format = new qpGeomVertexArrayFormat; array_format->add_data_type (InternalName::get_vertex(), vertex_pool->get_num_dimensions(), - qpGeomVertexDataType::NT_float32); + qpGeomVertexDataType::NT_float32, qpGeomVertexDataType::C_point); if (vertex_pool->has_normals()) { array_format->add_data_type - (InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32); + (InternalName::get_normal(), 3, + qpGeomVertexDataType::NT_float32, qpGeomVertexDataType::C_vector); } if (vertex_pool->has_colors()) { array_format->add_data_type - (InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb); + (InternalName::get_color(), 1, + qpGeomVertexDataType::NT_packed_8888, qpGeomVertexDataType::C_argb); } vector_string uv_names; @@ -1942,7 +1944,9 @@ make_vertex_data(const EggRenderState *render_state, name = string(); } PT(InternalName) iname = InternalName::get_texcoord_name(name); - array_format->add_data_type(iname, 2, qpGeomVertexDataType::NT_float32); + array_format->add_data_type + (iname, 2, + qpGeomVertexDataType::NT_float32, qpGeomVertexDataType::C_texcoord); } PT(qpGeomVertexFormat) temp_format = new qpGeomVertexFormat(array_format); @@ -1956,7 +1960,8 @@ make_vertex_data(const EggRenderState *render_state, blend_palette = new TransformBlendPalette; PT(qpGeomVertexArrayFormat) blend_array_format = new qpGeomVertexArrayFormat; blend_array_format->add_data_type - (InternalName::get_transform_blend(), 1, qpGeomVertexDataType::NT_uint16); + (InternalName::get_transform_blend(), 1, + qpGeomVertexDataType::NT_uint16, qpGeomVertexDataType::C_index); temp_format->add_array(blend_array_format); // We'll also assign the character name to the vertex data, so it diff --git a/panda/src/glstuff/glGeomMunger_src.I b/panda/src/glstuff/glGeomMunger_src.I index 88a5e55448..139a074da5 100644 --- a/panda/src/glstuff/glGeomMunger_src.I +++ b/panda/src/glstuff/glGeomMunger_src.I @@ -24,7 +24,8 @@ //////////////////////////////////////////////////////////////////// INLINE CLP(GeomMunger):: CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) : - ColorMunger(gsg, state, 4, qpGeomVertexDataType::NT_ufloat8), + ColorMunger(gsg, state, 4, qpGeomVertexDataType::NT_uint8, + qpGeomVertexDataType::C_rgba), _gsg(gsg), _texture(state->get_texture()), _tex_gen(state->get_tex_gen()) diff --git a/panda/src/glstuff/glGeomMunger_src.cxx b/panda/src/glstuff/glGeomMunger_src.cxx index c9795f2291..a22dbe7209 100644 --- a/panda/src/glstuff/glGeomMunger_src.cxx +++ b/panda/src/glstuff/glGeomMunger_src.cxx @@ -50,7 +50,7 @@ munge_format_impl(const qpGeomVertexFormat *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) { + color_type->get_numeric_type() == qpGeomVertexDataType::NT_packed_8888) { // 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()); @@ -60,8 +60,8 @@ munge_format_impl(const qpGeomVertexFormat *orig) { // Replace the existing color format with the new format. new_array_format->add_data_type - (InternalName::get_color(), 4, qpGeomVertexDataType::NT_ufloat8, - color_type->get_start()); + (InternalName::get_color(), 4, qpGeomVertexDataType::NT_uint8, + qpGeomVertexDataType::C_rgba, color_type->get_start()); format = qpGeomVertexFormat::register_format(new_format); } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index eaa7dc059e..83bc71947b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -2162,7 +2162,7 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger, if (_vertex_data->get_array_info(InternalName::get_color(), array_data, num_components, numeric_type, start, stride) && - numeric_type != qpGeomVertexDataType::NT_packed_argb) { + numeric_type != qpGeomVertexDataType::NT_packed_8888) { const unsigned char *client_pointer = setup_array_data(array_data); GLP(ColorPointer)(num_components, get_numeric_type(numeric_type), stride, client_pointer + start); @@ -4435,13 +4435,13 @@ get_numeric_type(qpGeomVertexDataType::NumericType numeric_type) { case qpGeomVertexDataType::NT_uint16: return GL_UNSIGNED_SHORT; - case qpGeomVertexDataType::NT_ufloat8: + case qpGeomVertexDataType::NT_uint8: return GL_UNSIGNED_BYTE; case qpGeomVertexDataType::NT_float32: return GL_FLOAT; - case qpGeomVertexDataType::NT_packed_argb: + case qpGeomVertexDataType::NT_packed_8888: break; } diff --git a/panda/src/gobj/Sources.pp b/panda/src/gobj/Sources.pp index 2aea51abe9..add1846389 100644 --- a/panda/src/gobj/Sources.pp +++ b/panda/src/gobj/Sources.pp @@ -36,6 +36,7 @@ qpgeomVertexDataType.h qpgeomVertexDataType.I \ qpgeomVertexFormat.h qpgeomVertexFormat.I \ qpgeomVertexIterator.h qpgeomVertexIterator.I \ + qpgeomVertexReader.h qpgeomVertexReader.I \ indexBufferContext.I indexBufferContext.h \ internalName.I internalName.h \ material.I material.h materialPool.I materialPool.h \ @@ -81,6 +82,7 @@ qpgeomVertexDataType.cxx \ qpgeomVertexFormat.cxx \ qpgeomVertexIterator.cxx \ + qpgeomVertexReader.cxx \ indexBufferContext.cxx \ material.cxx \ internalName.cxx \ @@ -124,6 +126,7 @@ qpgeomVertexDataType.h qpgeomVertexDataType.I \ qpgeomVertexFormat.h qpgeomVertexFormat.I \ qpgeomVertexIterator.h qpgeomVertexIterator.I \ + qpgeomVertexReader.h qpgeomVertexReader.I \ indexBufferContext.I indexBufferContext.h \ internalName.I internalName.h \ material.I material.h \ diff --git a/panda/src/gobj/gobj_composite1.cxx b/panda/src/gobj/gobj_composite1.cxx index 55922f4812..d3abc281d1 100644 --- a/panda/src/gobj/gobj_composite1.cxx +++ b/panda/src/gobj/gobj_composite1.cxx @@ -28,3 +28,4 @@ #include "qpgeomVertexDataType.cxx" #include "qpgeomVertexFormat.cxx" #include "qpgeomVertexIterator.cxx" +#include "qpgeomVertexReader.cxx" diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.cxx b/panda/src/gobj/qpgeomVertexArrayFormat.cxx index a7e8a43be3..7a3875cf0b 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.cxx +++ b/panda/src/gobj/qpgeomVertexArrayFormat.cxx @@ -48,34 +48,15 @@ qpGeomVertexArrayFormat() : //////////////////////////////////////////////////////////////////// qpGeomVertexArrayFormat:: qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, - qpGeomVertexDataType::NumericType numeric_type0) : + qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0) : _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); + add_data_type(name0, num_components0, numeric_type0, contents0); } //////////////////////////////////////////////////////////////////// @@ -86,19 +67,18 @@ qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, qpGeomVertexArrayFormat:: qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0, const InternalName *name1, int num_components1, qpGeomVertexDataType::NumericType numeric_type1, - const InternalName *name2, int num_components2, - qpGeomVertexDataType::NumericType numeric_type2) : + qpGeomVertexDataType::Contents contents1) : _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(name0, num_components0, numeric_type0, contents0); + add_data_type(name1, num_components1, numeric_type1, contents1); } //////////////////////////////////////////////////////////////////// @@ -109,22 +89,52 @@ qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, qpGeomVertexArrayFormat:: qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0, const InternalName *name1, int num_components1, qpGeomVertexDataType::NumericType numeric_type1, + qpGeomVertexDataType::Contents contents1, const InternalName *name2, int num_components2, qpGeomVertexDataType::NumericType numeric_type2, - const InternalName *name3, int num_components3, - qpGeomVertexDataType::NumericType numeric_type3) : + qpGeomVertexDataType::Contents contents2) : _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); + add_data_type(name0, num_components0, numeric_type0, contents0); + add_data_type(name1, num_components1, numeric_type1, contents1); + add_data_type(name2, num_components2, numeric_type2, contents2); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexArrayFormat::Constructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomVertexArrayFormat:: +qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, + qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0, + const InternalName *name1, int num_components1, + qpGeomVertexDataType::NumericType numeric_type1, + qpGeomVertexDataType::Contents contents1, + const InternalName *name2, int num_components2, + qpGeomVertexDataType::NumericType numeric_type2, + qpGeomVertexDataType::Contents contents2, + const InternalName *name3, int num_components3, + qpGeomVertexDataType::NumericType numeric_type3, + qpGeomVertexDataType::Contents contents3) : + _is_registered(false), + _stride(0), + _total_bytes(0), + _pad_to(1), + _data_types_unsorted(false) +{ + add_data_type(name0, num_components0, numeric_type0, contents0); + add_data_type(name1, num_components1, numeric_type1, contents1); + add_data_type(name2, num_components2, numeric_type2, contents2); + add_data_type(name3, num_components3, numeric_type3, contents3); } //////////////////////////////////////////////////////////////////// @@ -194,17 +204,19 @@ qpGeomVertexArrayFormat:: //////////////////////////////////////////////////////////////////// int qpGeomVertexArrayFormat:: add_data_type(const InternalName *name, int num_components, - qpGeomVertexDataType::NumericType numeric_type, int start) { + qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents, int start) { if (start < 0) { start = _total_bytes; - qpGeomVertexDataType temp_data_type(name, num_components, numeric_type, 0); + qpGeomVertexDataType temp_data_type + (name, num_components, numeric_type, contents, 0); int pad_to = temp_data_type.get_component_bytes(); start = ((start + pad_to - 1) / pad_to) * pad_to; } return add_data_type(qpGeomVertexDataType(name, num_components, - numeric_type, start)); + numeric_type, contents, start)); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomVertexArrayFormat.h b/panda/src/gobj/qpgeomVertexArrayFormat.h index 3c50ee3e1d..52b2b84b6f 100644 --- a/panda/src/gobj/qpgeomVertexArrayFormat.h +++ b/panda/src/gobj/qpgeomVertexArrayFormat.h @@ -53,25 +53,35 @@ 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); + qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0); qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0, const InternalName *name1, int num_components1, qpGeomVertexDataType::NumericType numeric_type1, - const InternalName *name2, int num_components2, - qpGeomVertexDataType::NumericType numeric_type2); + qpGeomVertexDataType::Contents contents1); qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0, const InternalName *name1, int num_components1, qpGeomVertexDataType::NumericType numeric_type1, + qpGeomVertexDataType::Contents contents1, const InternalName *name2, int num_components2, qpGeomVertexDataType::NumericType numeric_type2, + qpGeomVertexDataType::Contents contents2); + qpGeomVertexArrayFormat(const InternalName *name0, int num_components0, + qpGeomVertexDataType::NumericType numeric_type0, + qpGeomVertexDataType::Contents contents0, + const InternalName *name1, int num_components1, + qpGeomVertexDataType::NumericType numeric_type1, + qpGeomVertexDataType::Contents contents1, + const InternalName *name2, int num_components2, + qpGeomVertexDataType::NumericType numeric_type2, + qpGeomVertexDataType::Contents contents2, const InternalName *name3, int num_components3, - qpGeomVertexDataType::NumericType numeric_type3); + qpGeomVertexDataType::NumericType numeric_type3, + qpGeomVertexDataType::Contents contents3); void operator = (const qpGeomVertexArrayFormat ©); ~qpGeomVertexArrayFormat(); @@ -85,6 +95,7 @@ PUBLISHED: int add_data_type(const InternalName *name, int num_components, qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents, int start = -1); int add_data_type(const qpGeomVertexDataType &data_type); void remove_data_type(const InternalName *name); diff --git a/panda/src/gobj/qpgeomVertexData.cxx b/panda/src/gobj/qpgeomVertexData.cxx index 926bb25bcf..71a44e8de5 100644 --- a/panda/src/gobj/qpgeomVertexData.cxx +++ b/panda/src/gobj/qpgeomVertexData.cxx @@ -18,6 +18,7 @@ #include "qpgeomVertexData.h" #include "qpgeomVertexIterator.h" +#include "qpgeomVertexReader.h" #include "pStatTimer.h" #include "bamReader.h" #include "bamWriter.h" @@ -358,7 +359,8 @@ convert_to(const qpGeomVertexFormat *new_format) const { //////////////////////////////////////////////////////////////////// CPT(qpGeomVertexData) qpGeomVertexData:: scale_color(const LVecBase4f &color_scale, int num_components, - qpGeomVertexDataType::NumericType numeric_type) const { + qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents) const { int old_color_array = _format->get_array_with(InternalName::get_color()); if (old_color_array == -1) { // Oops, no color anyway. @@ -376,7 +378,7 @@ scale_color(const LVecBase4f &color_scale, int num_components, PT(qpGeomVertexData) new_data = replace_data_type (InternalName::get_color(), num_components, numeric_type, - get_usage_hint(), true); + contents, get_usage_hint(), true); // Now go through and apply the scale, copying it to the new data. qpGeomVertexIterator from(this, InternalName::get_color()); @@ -385,9 +387,9 @@ scale_color(const LVecBase4f &color_scale, int num_components, for (int i = 0; i < num_vertices; i++) { Colorf color = from.get_data4f(); to.set_data4f(color[0] * color_scale[0], - color[1] * color_scale[1], - color[2] * color_scale[2], - color[3] * color_scale[3]); + color[1] * color_scale[1], + color[2] * color_scale[2], + color[3] * color_scale[3]); } return new_data; @@ -405,7 +407,8 @@ scale_color(const LVecBase4f &color_scale, int num_components, //////////////////////////////////////////////////////////////////// CPT(qpGeomVertexData) qpGeomVertexData:: set_color(const Colorf &color, int num_components, - qpGeomVertexDataType::NumericType numeric_type) const { + qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents) const { int num_vertices = get_num_vertices(); if (gobj_cat.is_debug()) { @@ -417,7 +420,7 @@ set_color(const Colorf &color, int num_components, PT(qpGeomVertexData) new_data = replace_data_type (InternalName::get_color(), num_components, numeric_type, - get_usage_hint(), true); + contents, get_usage_hint(), true); // Now go through and set the new color value. qpGeomVertexIterator to(new_data, InternalName::get_color()); @@ -489,6 +492,7 @@ animate_vertices() const { PT(qpGeomVertexData) qpGeomVertexData:: replace_data_type(const InternalName *name, int num_components, qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents, qpGeomUsageHint::UsageHint usage_hint, bool keep_animation) const { PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat(*_format); @@ -515,7 +519,7 @@ replace_data_type(const InternalName *name, int num_components, int new_type_array = -1; if (num_components != 0) { PT(qpGeomVertexArrayFormat) type_array_format = - new qpGeomVertexArrayFormat(name, num_components, numeric_type); + new qpGeomVertexArrayFormat(name, num_components, numeric_type, contents); new_type_array = new_format->add_array(type_array_format); } @@ -637,7 +641,7 @@ set_data(int array, const qpGeomVertexDataType *data_type, break; - case qpGeomVertexDataType::NT_ufloat8: + case qpGeomVertexDataType::NT_uint8: { int i = 0; int min_values = min(num_values, data_type->get_num_values()); @@ -655,7 +659,7 @@ set_data(int array, const qpGeomVertexDataType *data_type, } break; - case qpGeomVertexDataType::NT_packed_argb: + case qpGeomVertexDataType::NT_packed_8888: { if (num_values == 4) { *(PN_uint32 *)&array_data[element] = pack_argb(data); @@ -734,7 +738,7 @@ get_data(int array, const qpGeomVertexDataType *data_type, } break; - case qpGeomVertexDataType::NT_ufloat8: + case qpGeomVertexDataType::NT_uint8: { int i = 0; int min_values = min(num_values, data_type->get_num_values()); @@ -751,7 +755,7 @@ get_data(int array, const qpGeomVertexDataType *data_type, } break; - case qpGeomVertexDataType::NT_packed_argb: + case qpGeomVertexDataType::NT_packed_8888: { if (num_values == 4) { unpack_argb(data, *(PN_uint32 *)&array_data[element]); @@ -841,7 +845,7 @@ set_data(int array, const qpGeomVertexDataType *data_type, break; - case qpGeomVertexDataType::NT_ufloat8: + case qpGeomVertexDataType::NT_uint8: { int i = 0; int min_values = min(num_values, data_type->get_num_values()); @@ -858,7 +862,7 @@ set_data(int array, const qpGeomVertexDataType *data_type, } break; - case qpGeomVertexDataType::NT_packed_argb: + case qpGeomVertexDataType::NT_packed_8888: { if (num_values == 4) { *(PN_uint32 *)&array_data[element] = pack_argb(data); @@ -929,7 +933,7 @@ get_data(int array, const qpGeomVertexDataType *data_type, } break; - case qpGeomVertexDataType::NT_ufloat8: + case qpGeomVertexDataType::NT_uint8: { int i = 0; int min_values = min(num_values, data_type->get_num_values()); @@ -946,7 +950,7 @@ get_data(int array, const qpGeomVertexDataType *data_type, } break; - case qpGeomVertexDataType::NT_packed_argb: + case qpGeomVertexDataType::NT_packed_8888: { if (num_values == 4) { unpack_argb(data, *(PN_uint32 *)&array_data[element]); @@ -1189,6 +1193,7 @@ make_animated_vertices(qpGeomVertexData::CDWriter &cdata) { // array. cdata->_animated_vertices = replace_data_type (InternalName::get_transform_blend(), 0, qpGeomVertexDataType::NT_uint16, + qpGeomVertexDataType::C_index, min(get_usage_hint(), qpGeomUsageHint::UH_dynamic), false); // Now fill it up with the appropriate data. @@ -1227,8 +1232,8 @@ update_animated_vertices(qpGeomVertexData::CDWriter &cdata) { PT(qpGeomVertexData) new_data = cdata->_animated_vertices; // Now go through and apply the scale, copying it to the new data. - qpGeomVertexIterator from(this, InternalName::get_vertex()); - qpGeomVertexIterator blendi(this, InternalName::get_transform_blend()); + qpGeomVertexReader from(this, InternalName::get_vertex()); + qpGeomVertexReader blendi(this, InternalName::get_transform_blend()); qpGeomVertexIterator to(new_data, InternalName::get_vertex()); if (from.get_data_type()->get_num_values() == 4) { diff --git a/panda/src/gobj/qpgeomVertexData.h b/panda/src/gobj/qpgeomVertexData.h index a102cecebd..1e93010dbe 100644 --- a/panda/src/gobj/qpgeomVertexData.h +++ b/panda/src/gobj/qpgeomVertexData.h @@ -97,16 +97,19 @@ PUBLISHED: CPT(qpGeomVertexData) convert_to(const qpGeomVertexFormat *new_format) const; CPT(qpGeomVertexData) scale_color(const LVecBase4f &color_scale, int num_components, - qpGeomVertexDataType::NumericType numeric_type) const; + qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents) const; CPT(qpGeomVertexData) set_color(const Colorf &color, int num_components, - qpGeomVertexDataType::NumericType numeric_type) const; + qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents) const; CPT(qpGeomVertexData) animate_vertices() const; PT(qpGeomVertexData) replace_data_type(const InternalName *name, int num_components, qpGeomVertexDataType::NumericType numeric_type, + qpGeomVertexDataType::Contents contents, qpGeomUsageHint::UsageHint usage_hint, bool keep_animation) const; diff --git a/panda/src/gobj/qpgeomVertexDataType.I b/panda/src/gobj/qpgeomVertexDataType.I index 2d1e3351ac..56e322476d 100644 --- a/panda/src/gobj/qpgeomVertexDataType.I +++ b/panda/src/gobj/qpgeomVertexDataType.I @@ -28,6 +28,7 @@ qpGeomVertexDataType(const qpGeomVertexDataType ©) : _num_components(copy._num_components), _num_values(copy._num_values), _numeric_type(copy._numeric_type), + _contents(copy._contents), _start(copy._start), _component_bytes(copy._component_bytes), _total_bytes(copy._total_bytes) @@ -45,6 +46,7 @@ operator = (const qpGeomVertexDataType ©) { _num_components = copy._num_components; _num_values = copy._num_values; _numeric_type = copy._numeric_type; + _contents = copy._contents; _start = copy._start; _component_bytes = copy._component_bytes; _total_bytes = copy._total_bytes; @@ -85,7 +87,7 @@ get_num_components() const { // 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 +// like NT_packed_8888, which has four numeric values // per component. //////////////////////////////////////////////////////////////////// INLINE int qpGeomVertexDataType:: @@ -104,6 +106,17 @@ get_numeric_type() const { return _numeric_type; } +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexDataType::get_contents +// Access: Published +// Description: Returns the token representing the semantic meaning of +// the stored value. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexDataType::Contents qpGeomVertexDataType:: +get_contents() const { + return _contents; +} + //////////////////////////////////////////////////////////////////// // Function: qpGeomVertexDataType::get_start // Access: Published @@ -168,6 +181,9 @@ compare_to(const qpGeomVertexDataType &other) const { if (_numeric_type != other._numeric_type) { return (int)_numeric_type - (int)other._numeric_type; } + if (_contents != other._contents) { + return (int)_contents - (int)other._contents; + } if (_start != other._start) { return _start - other._start; } diff --git a/panda/src/gobj/qpgeomVertexDataType.cxx b/panda/src/gobj/qpgeomVertexDataType.cxx index 561ac24d9c..0cfd1ef365 100644 --- a/panda/src/gobj/qpgeomVertexDataType.cxx +++ b/panda/src/gobj/qpgeomVertexDataType.cxx @@ -25,11 +25,13 @@ //////////////////////////////////////////////////////////////////// qpGeomVertexDataType:: qpGeomVertexDataType(const InternalName *name, int num_components, - NumericType numeric_type, int start) : + NumericType numeric_type, Contents contents, + int start) : _name(name), _num_components(num_components), _num_values(num_components), _numeric_type(numeric_type), + _contents(contents), _start(start) { nassertv(num_components > 0 && start >= 0); @@ -39,11 +41,11 @@ qpGeomVertexDataType(const InternalName *name, int num_components, _component_bytes = 2; // sizeof(PN_uint16) break; - case NT_ufloat8: + case NT_uint8: _component_bytes = 1; break; - case NT_packed_argb: + case NT_packed_8888: _component_bytes = 4; // sizeof(PN_uint32) _num_values *= 4; break; @@ -65,7 +67,7 @@ qpGeomVertexDataType(const InternalName *name, int num_components, const qpGeomVertexDataType &qpGeomVertexDataType:: error() { static qpGeomVertexDataType error_result - (InternalName::get_error(), 1, NT_ufloat8, 0); + (InternalName::get_error(), 1, NT_uint8, C_other, 0); return error_result; } @@ -105,10 +107,10 @@ copy_records(unsigned char *to, int to_stride, // An easy case. copy_no_convert(to, to_stride, from, from_stride, from_type, num_records); - } else if (get_numeric_type() == NT_ufloat8 && from_type->get_numeric_type() == NT_packed_argb && + } else if (get_numeric_type() == NT_uint8 && from_type->get_numeric_type() == NT_packed_8888 && 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_ufloat8 && + } else if (get_numeric_type() == NT_packed_8888 && 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 { @@ -230,10 +232,10 @@ get_value(const unsigned char *data, int n) const { case NT_uint16: return (float)data[n]; - case NT_ufloat8: + case NT_uint8: return (float)data[n] / 255.0f; - case qpGeomVertexDataType::NT_packed_argb: + case qpGeomVertexDataType::NT_packed_8888: { int element = n / 4; const PN_uint32 *int_array = (const PN_uint32 *)data; @@ -274,11 +276,11 @@ set_value(unsigned char *data, int n, float value) const { data[n] = (int)value; break; - case NT_ufloat8: + case NT_uint8: data[n] = (int)(value * 255.0f); break; - case qpGeomVertexDataType::NT_packed_argb: + case qpGeomVertexDataType::NT_packed_8888: { int element = n / 4; diff --git a/panda/src/gobj/qpgeomVertexDataType.h b/panda/src/gobj/qpgeomVertexDataType.h index ccc8d398a9..9445e3965e 100644 --- a/panda/src/gobj/qpgeomVertexDataType.h +++ b/panda/src/gobj/qpgeomVertexDataType.h @@ -35,14 +35,25 @@ class EXPCL_PANDA qpGeomVertexDataType { PUBLISHED: enum NumericType { - NT_uint16, // A short integer 0..65535 - NT_ufloat8, // A floating-point number 0..1 packed into a byte - NT_float32, // A true floating-point number - NT_packed_argb, // DirectX style color specification + NT_uint8, // An integer 0..255 + NT_uint16, // An integer 0..65535 + NT_packed_8888, // DirectX style, four byte values packed in a dword + NT_float32, // A floating-point number + }; + + enum Contents { + C_other, // Arbitrary meaning, leave it alone + C_point, // A point in 3-space or 4-space + C_vector, // A surface normal, tangent, or binormal + C_texcoord, // A texture coordinate + C_rgba, // RGB or RGBA, OpenGL-style order + C_argb, // RGBA, DirectX-style packed color + C_index, // An index value into some other table }; INLINE qpGeomVertexDataType(const InternalName *name, int num_components, - NumericType numeric_type, int start); + NumericType numeric_type, Contents contents, + int start); INLINE qpGeomVertexDataType(const qpGeomVertexDataType ©); INLINE void operator = (const qpGeomVertexDataType ©); @@ -52,6 +63,7 @@ PUBLISHED: INLINE int get_num_components() const; INLINE int get_num_values() const; INLINE NumericType get_numeric_type() const; + INLINE Contents get_contents() const; INLINE int get_start() const; INLINE int get_component_bytes() const; INLINE int get_total_bytes() const; @@ -98,6 +110,7 @@ private: int _num_components; int _num_values; NumericType _numeric_type; + Contents _contents; int _start; int _component_bytes; int _total_bytes; diff --git a/panda/src/gobj/qpgeomVertexFormat.cxx b/panda/src/gobj/qpgeomVertexFormat.cxx index 2753136901..462f41aa0a 100644 --- a/panda/src/gobj/qpgeomVertexFormat.cxx +++ b/panda/src/gobj/qpgeomVertexFormat.cxx @@ -526,64 +526,128 @@ fillin(DatagramIterator &scan, BamReader *manager) { qpGeomVertexFormat::Registry:: Registry() { _v3 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point)); _v3n3 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_normal(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_vector)); _v3t2 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_texcoord(), 2, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_texcoord)); _v3n3t2 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_normal(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_vector, + InternalName::get_texcoord(), 2, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_texcoord)); // Define the DirectX-style packed color formats _v3cp = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 1, + qpGeomVertexDataType::NT_packed_8888, + qpGeomVertexDataType::C_argb)); _v3n3cp = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_normal(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 1, + qpGeomVertexDataType::NT_packed_8888, + qpGeomVertexDataType::C_argb)); _v3cpt2 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb, - InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 1, + qpGeomVertexDataType::NT_packed_8888, + qpGeomVertexDataType::C_argb, + InternalName::get_texcoord(), 2, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_texcoord)); _v3n3cpt2 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_color(), 1, qpGeomVertexDataType::NT_packed_argb, - InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_normal(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 1, + qpGeomVertexDataType::NT_packed_8888, + qpGeomVertexDataType::C_argb, + InternalName::get_texcoord(), 2, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_texcoord)); // 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_float32, - InternalName::get_color(), 4, qpGeomVertexDataType::NT_ufloat8)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 4, + qpGeomVertexDataType::NT_uint8, + qpGeomVertexDataType::C_rgba)); _v3n3c4 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_color(), 4, qpGeomVertexDataType::NT_ufloat8)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_normal(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 4, + qpGeomVertexDataType::NT_uint8, + qpGeomVertexDataType::C_rgba)); _v3c4t2 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_color(), 4, qpGeomVertexDataType::NT_ufloat8, - InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 4, + qpGeomVertexDataType::NT_uint8, + qpGeomVertexDataType::C_rgba, + InternalName::get_texcoord(), 2, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_texcoord)); _v3n3c4t2 = register_format(new qpGeomVertexArrayFormat - (InternalName::get_vertex(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_normal(), 3, qpGeomVertexDataType::NT_float32, - InternalName::get_color(), 4, qpGeomVertexDataType::NT_ufloat8, - InternalName::get_texcoord(), 2, qpGeomVertexDataType::NT_float32)); + (InternalName::get_vertex(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_normal(), 3, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_point, + InternalName::get_color(), 4, + qpGeomVertexDataType::NT_uint8, + qpGeomVertexDataType::C_rgba, + InternalName::get_texcoord(), 2, + qpGeomVertexDataType::NT_float32, + qpGeomVertexDataType::C_texcoord)); } //////////////////////////////////////////////////////////////////// diff --git a/panda/src/gobj/qpgeomVertexReader.I b/panda/src/gobj/qpgeomVertexReader.I new file mode 100644 index 0000000000..783b834f97 --- /dev/null +++ b/panda/src/gobj/qpgeomVertexReader.I @@ -0,0 +1,385 @@ +// Filename: qpgeomVertexReader.I +// Created by: drose (25Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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: qpGeomVertexReader::Constructor +// Access: Published +// Description: Constructs a new reader to process the vertices of +// the indicated data object. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexReader:: +qpGeomVertexReader(const qpGeomVertexData *vertex_data) : + _vertex_data(vertex_data), + _array(0), + _data_type(NULL), + _pointer(NULL), + _start_vertex(0), + _read_vertex(0), + _reader(NULL) +{ +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Constructor +// Access: Published +// Description: Constructs a new reader to process the vertices of +// the indicated data object. This flavor creates the +// reader specifically to process the named data type. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexReader:: +qpGeomVertexReader(const qpGeomVertexData *vertex_data, const string &name) : + _vertex_data(vertex_data), + _array(0), + _data_type(NULL), + _pointer(NULL), + _start_vertex(0), + _read_vertex(0), + _reader(NULL) +{ + set_data_type(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Constructor +// Access: Published +// Description: Constructs a new reader to process the vertices of +// the indicated data object. This flavor creates the +// reader specifically to process the named data type. +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexReader:: +qpGeomVertexReader(const qpGeomVertexData *vertex_data, + const InternalName *name) : + _vertex_data(vertex_data), + _array(0), + _data_type(NULL), + _pointer(NULL), + _start_vertex(0), + _read_vertex(0), + _reader(NULL) +{ + set_data_type(name); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Destructor +// Access: Published +// Description: +//////////////////////////////////////////////////////////////////// +INLINE qpGeomVertexReader:: +~qpGeomVertexReader() { + if (_reader != (Reader *)NULL) { + delete _reader; + _reader = NULL; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_vertex_data +// Access: Published +// Description: Returns the vertex data object that the +// reader is processing. +//////////////////////////////////////////////////////////////////// +INLINE const qpGeomVertexData *qpGeomVertexReader:: +get_vertex_data() const { + return _vertex_data; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::set_data_type +// Access: Published +// Description: Sets up the reader to use the nth data type of the +// GeomVertexFormat, numbering from 0. +// +// This also resets the read vertex number 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 qpGeomVertexReader:: +set_data_type(int data_type) { + nassertv(_vertex_data->get_format()->get_array_with(data_type) >= 0); + set_data_type(_vertex_data->get_format()->get_array_with(data_type), + _vertex_data->get_format()->get_data_type(data_type)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::set_data_type +// Access: Published +// Description: Sets up the reader to use the data type with the +// indicated name. +// +// This also resets the read vertex number 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 qpGeomVertexReader:: +set_data_type(const string &name) { + set_data_type(InternalName::make(name)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::set_data_type +// Access: Published +// Description: Sets up the reader to use the data type with the +// indicated name. +// +// This also resets the read vertex number 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 qpGeomVertexReader:: +set_data_type(const InternalName *name) { + nassertv(_vertex_data->get_format()->get_array_with(name) >= 0); + set_data_type(_vertex_data->get_format()->get_array_with(name), + _vertex_data->get_format()->get_data_type(name)); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_array +// Access: Published +// Description: Returns the array index containing the data type that +// the reader is working on. +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexReader:: +get_array() const { + return _array; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_data_type +// Access: Published +// Description: Returns the description of the data type that the +// reader is working on. +//////////////////////////////////////////////////////////////////// +INLINE const qpGeomVertexDataType *qpGeomVertexReader:: +get_data_type() const { + return _data_type; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::set_vertex +// Access: Published +// Description: Sets the start, read, and write index to the +// indicated value. The reader will begin traversing +// from the given vertex. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexReader:: +set_vertex(int vertex) { + _start_vertex = vertex; + _read_vertex = vertex; + set_pointer(); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_start_vertex +// Access: Published +// Description: Returns the vertex index at which the reader +// started. It will return to this vertex if you reset +// the current data_type. +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexReader:: +get_start_vertex() const { + return _start_vertex; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_read_vertex +// Access: Published +// Description: Returns the current read vertex index of the +// reader. This is the index whose value will be +// returned by the next call to get_data*(). +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexReader:: +get_read_vertex() const { + return _read_vertex; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_data1f +// Access: Published +// Description: Returns the data associated with the read vertex, +// expressed as a 1-component value, and advances the +// read vertex. +//////////////////////////////////////////////////////////////////// +INLINE float qpGeomVertexReader:: +get_data1f() { + return _reader->get_data1f(inc_pointer()); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_data2f +// Access: Published +// Description: Returns the data associated with the read vertex, +// expressed as a 2-component value, and advances the +// read vertex. +//////////////////////////////////////////////////////////////////// +INLINE const LVecBase2f &qpGeomVertexReader:: +get_data2f() { + return _reader->get_data2f(inc_pointer()); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_data3f +// Access: Published +// Description: Returns the data associated with the read vertex, +// expressed as a 3-component value, and advances the +// read vertex. +//////////////////////////////////////////////////////////////////// +INLINE const LVecBase3f &qpGeomVertexReader:: +get_data3f() { + return _reader->get_data3f(inc_pointer()); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_data4f +// Access: Published +// Description: Returns the data associated with the read vertex, +// expressed as a 4-component value, and advances the +// read vertex. +//////////////////////////////////////////////////////////////////// +INLINE const LVecBase4f &qpGeomVertexReader:: +get_data4f() { + return _reader->get_data4f(inc_pointer()); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::get_data1i +// Access: Published +// Description: Returns the data associated with the read vertex, +// expressed as a 1-component value, and advances the +// read vertex. +//////////////////////////////////////////////////////////////////// +INLINE int qpGeomVertexReader:: +get_data1i() { + return _reader->get_data1i(inc_pointer()); +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::set_pointer +// Access: Private +// Description: Sets up the internal pointer, etc. to use the vertex +// indicated by _start_vertex. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexReader:: +set_pointer() { + _read_vertex = _start_vertex; + _data = _vertex_data->get_array(_array)->get_data(); + _pointer = _data.p() + _data_type->get_start() + _stride * _read_vertex; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::inc_pointer +// Access: Private +// Description: Increments to the next vertex, and returns the data +// pointer as it was before incrementing. +//////////////////////////////////////////////////////////////////// +INLINE const unsigned char *qpGeomVertexReader:: +inc_pointer() { + const unsigned char *orig_pointer = _pointer; + _pointer += _stride; + ++_read_vertex; + return orig_pointer; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::maybe_scale_color +// Access: Public +// Description: Converts an integer (typically a uint8) value to a +// floating-point value. If the contents value +// indicates this is a color value, scales it into the +// range 0..1 per convention; otherwise leaves it alone. +//////////////////////////////////////////////////////////////////// +INLINE float qpGeomVertexReader::Reader:: +maybe_scale_color(unsigned int value) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + return (float)value / 255.0f; + + default: + return (float)value; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::maybe_scale_color +// Access: Public +// Description: Converts a pair of integers into the _v2 member. See +// one-parameter maybe_scale_color() for more info. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexReader::Reader:: +maybe_scale_color(unsigned int a, unsigned int b) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + _v2.set((float)a / 255.0f, + (float)b / 255.0f); + break; + + default: + _v2.set((float)a, (float)b); + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::maybe_scale_color +// Access: Public +// Description: Converts a pair of integers into the _v3 member. See +// one-parameter maybe_scale_color() for more info. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexReader::Reader:: +maybe_scale_color(unsigned int a, unsigned int b, unsigned int c) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + _v3.set((float)a / 255.0f, + (float)b / 255.0f, + (float)c / 255.0f); + break; + + default: + _v3.set((float)a, (float)b, (float)c); + break; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::maybe_scale_color +// Access: Public +// Description: Converts a pair of integers into the _v4 member. See +// one-parameter maybe_scale_color() for more info. +//////////////////////////////////////////////////////////////////// +INLINE void qpGeomVertexReader::Reader:: +maybe_scale_color(unsigned int a, unsigned int b, unsigned int c, + unsigned int d) { + switch (_data_type->get_contents()) { + case qpGeomVertexDataType::C_rgba: + case qpGeomVertexDataType::C_argb: + _v4.set((float)a / 255.0f, + (float)b / 255.0f, + (float)c / 255.0f, + (float)d / 255.0f); + break; + + default: + _v4.set((float)a, (float)b, (float)c, (float)d); + break; + } +} + diff --git a/panda/src/gobj/qpgeomVertexReader.cxx b/panda/src/gobj/qpgeomVertexReader.cxx new file mode 100644 index 0000000000..a309988a53 --- /dev/null +++ b/panda/src/gobj/qpgeomVertexReader.cxx @@ -0,0 +1,398 @@ +// Filename: qpgeomVertexReader.cxx +// Created by: drose (25Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "qpgeomVertexReader.h" + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::set_data_type +// Access: Published +// Description: Sets up the reader to use the indicated data_type +// description on the given array. +// +// This also resets the current read 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.) +//////////////////////////////////////////////////////////////////// +void qpGeomVertexReader:: +set_data_type(int array, const qpGeomVertexDataType *data_type) { + nassertv(array >= 0 && array < _vertex_data->get_num_arrays()); + nassertv(data_type != (qpGeomVertexDataType *)NULL); + _array = array; + _data_type = data_type; + _stride = _vertex_data->get_format()->get_array(_array)->get_stride(); + + set_pointer(); + + // Delete the old reader, if we've got one. + if (_reader != (Reader *)NULL) { + delete _reader; + _reader = NULL; + } + + // Now set up a new reader. + _reader = make_reader(); + _reader->_data_type = _data_type; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::make_reader +// Access: Private +// Description: Returns a newly-allocated Reader object suitable for +// reading the current data type. +//////////////////////////////////////////////////////////////////// +qpGeomVertexReader::Reader *qpGeomVertexReader:: +make_reader() const { + if (_data_type->get_contents() == qpGeomVertexDataType::C_point && + _data_type->get_num_values() < 4) { + return new Reader_point; + + } else { + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_float32: + if (sizeof(float) == 4) { + switch (_data_type->get_num_components()) { + case 3: + return new Reader_float_3; + + default: + break; + } + } + break; + + case qpGeomVertexDataType::NT_uint16: + switch (_data_type->get_num_components()) { + case 1: + return new Reader_uint16_1; + + default: + break; + } + + default: + break; + } + } + + // If we got here, we have to create a generic reader. + return new Reader; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::Destructor +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +qpGeomVertexReader::Reader:: +~Reader() { +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::get_data1f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +float qpGeomVertexReader::Reader:: +get_data1f(const unsigned char *pointer) { + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + return maybe_scale_color(*pointer); + + case qpGeomVertexDataType::NT_uint16: + return *(PN_uint16 *)pointer; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + return maybe_scale_color(dword._b[0]); + } + + case qpGeomVertexDataType::NT_float32: + return *(PN_float32 *)pointer; + } + + return 0.0f; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::get_data2f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase2f &qpGeomVertexReader::Reader:: +get_data2f(const unsigned char *pointer) { + if (_data_type->get_num_values() == 1) { + _v2.set(get_data1i(pointer), 0.0f); + return _v2; + + } else { + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(pointer[0], pointer[1]); + return _v2; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + _v2.set(pi[0], pi[1]); + } + return _v2; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + maybe_scale_color(dword._b[0], dword._b[1]); + } + return _v2; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + _v2.set(pi[0], pi[1]); + } + return _v2; + } + } + + return _v2; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::get_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase3f &qpGeomVertexReader::Reader:: +get_data3f(const unsigned char *pointer) { + switch (_data_type->get_num_values()) { + case 1: + _v3.set(get_data1i(pointer), 0.0f, 0.0f); + return _v3; + + case 2: + { + const LVecBase2f &v2 = get_data2f(pointer); + _v3.set(v2[0], v2[1], 0.0f); + } + return _v3; + + default: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(pointer[0], pointer[1], pointer[2]); + return _v3; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + _v3.set(pi[0], pi[1], pi[2]); + } + return _v3; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + maybe_scale_color(dword._b[0], dword._b[1], dword._b[2]); + } + return _v3; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + _v3.set(pi[0], pi[1], pi[2]); + } + return _v3; + } + } + + return _v3; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader:: +get_data4f(const unsigned char *pointer) { + switch (_data_type->get_num_values()) { + case 1: + _v4.set(get_data1i(pointer), 0.0f, 0.0f, 0.0f); + return _v4; + + case 2: + { + const LVecBase2f &v2 = get_data2f(pointer); + _v4.set(v2[0], v2[1], 0.0f, 0.0f); + } + return _v4; + + case 3: + { + const LVecBase3f &v3 = get_data3f(pointer); + _v4.set(v3[0], v3[1], v3[2], 0.0f); + } + return _v4; + + default: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(pointer[0], pointer[1], pointer[2], pointer[3]); + return _v4; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + } + return _v4; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + maybe_scale_color(dword._b[0], dword._b[1], dword._b[2], dword._b[3]); + } + return _v4; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + } + return _v4; + } + } + + return _v4; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader::get_data1i +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +int qpGeomVertexReader::Reader:: +get_data1i(const unsigned char *pointer) { + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + return *pointer; + + case qpGeomVertexDataType::NT_uint16: + return *(PN_uint16 *)pointer; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + return dword._b[0]; + } + break; + + case qpGeomVertexDataType::NT_float32: + return (int)*(PN_float32 *)pointer; + } + + return 0; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_point::get_data4f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase4f &qpGeomVertexReader::Reader_point:: +get_data4f(const unsigned char *pointer) { + switch (_data_type->get_num_values()) { + case 1: + _v4.set(get_data1i(pointer), 0.0f, 0.0f, 1.0f); + return _v4; + + case 2: + { + const LVecBase2f &v2 = get_data2f(pointer); + _v4.set(v2[0], v2[1], 0.0f, 1.0f); + } + return _v4; + + case 3: + { + const LVecBase3f &v3 = get_data3f(pointer); + _v4.set(v3[0], v3[1], v3[2], 1.0f); + } + return _v4; + + default: + switch (_data_type->get_numeric_type()) { + case qpGeomVertexDataType::NT_uint8: + maybe_scale_color(pointer[0], pointer[1], pointer[2], pointer[3]); + return _v4; + + case qpGeomVertexDataType::NT_uint16: + { + PN_uint16 *pi = (PN_uint16 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + } + return _v4; + + case qpGeomVertexDataType::NT_packed_8888: + { + packed_8888 dword; + dword._i = *(PN_uint32 *)pointer; + maybe_scale_color(dword._b[0], dword._b[1], dword._b[2], dword._b[3]); + } + return _v4; + + case qpGeomVertexDataType::NT_float32: + { + PN_float32 *pi = (PN_float32 *)pointer; + _v4.set(pi[0], pi[1], pi[2], pi[3]); + } + return _v4; + } + } + + return _v4; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_float_3::get_data3f +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +const LVecBase3f &qpGeomVertexReader::Reader_float_3:: +get_data3f(const unsigned char *pointer) { + // We sneakily cast a float[3] array to an LVecBase3f reference, + // making all kinds of assumptions about how an LVecBase3f is + // stored. + return (LVecBase3f &)(float *)pointer; +} + +//////////////////////////////////////////////////////////////////// +// Function: qpGeomVertexReader::Reader_uint16_1::get_data1i +// Access: Public, Virtual +// Description: +//////////////////////////////////////////////////////////////////// +int qpGeomVertexReader::Reader_uint16_1:: +get_data1i(const unsigned char *pointer) { + return *(PN_uint16 *)pointer; +} diff --git a/panda/src/gobj/qpgeomVertexReader.h b/panda/src/gobj/qpgeomVertexReader.h new file mode 100644 index 0000000000..522ba3824b --- /dev/null +++ b/panda/src/gobj/qpgeomVertexReader.h @@ -0,0 +1,153 @@ +// Filename: qpgeomVertexReader.h +// Created by: drose (25Mar05) +// +//////////////////////////////////////////////////////////////////// +// +// 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 qpGEOMVERTEXREADER_H +#define qpGEOMVERTEXREADER_H + +#include "pandabase.h" +#include "qpgeomVertexData.h" +#include "qpgeomVertexDataType.h" +#include "internalName.h" +#include "luse.h" +#include "pointerTo.h" + +//////////////////////////////////////////////////////////////////// +// Class : qpGeomVertexReader +// Description : This object provides a high-level interface for +// quickly reading a sequence of numeric values from a +// vertex table. +// +// It is particularly optimized for reading a column of +// data values for a series of vertices, without +// changing data types between each number. Although +// you can use one GeomVertexReader to read one complete +// row at a time, by calling set_data_type() repeatedly +// for each vertex, it is faster to use a different +// GeomVertexReader for each data type. +// +// This is part of the experimental Geom rewrite. +//////////////////////////////////////////////////////////////////// +class EXPCL_PANDA qpGeomVertexReader { +PUBLISHED: + INLINE qpGeomVertexReader(const qpGeomVertexData *vertex_data); + INLINE qpGeomVertexReader(const qpGeomVertexData *vertex_data, + const string &name); + INLINE qpGeomVertexReader(const qpGeomVertexData *vertex_data, + const InternalName *name); + INLINE ~qpGeomVertexReader(); + + INLINE const qpGeomVertexData *get_vertex_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); + 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 float get_data1f(); + INLINE const LVecBase2f &get_data2f(); + INLINE const LVecBase3f &get_data3f(); + INLINE const LVecBase4f &get_data4f(); + + INLINE int get_data1i(); + +private: + class Reader; + + INLINE void set_pointer(); + INLINE const unsigned char *inc_pointer(); + Reader *make_reader() const; + + CPT(qpGeomVertexData) _vertex_data; + int _array; + const qpGeomVertexDataType *_data_type; + int _stride; + + CPTA_uchar _data; + const unsigned char *_pointer; + + int _start_vertex; + int _read_vertex; + + Reader *_reader; + + // This union is handy for unpacking an NT_packed_8888 value. + typedef union { + unsigned char _b[4]; + PN_uint32 _i; + } packed_8888; + + // This nested class provides the implementation for unpacking data + // in a very general way, but also provides the hooks for + // implementing the common, very direct code paths (for instance, + // 3-component float32 to LVecBase3f) as quickly as possible. + class Reader { + public: + virtual ~Reader(); + virtual float get_data1f(const unsigned char *pointer); + virtual const LVecBase2f &get_data2f(const unsigned char *pointer); + virtual const LVecBase3f &get_data3f(const unsigned char *pointer); + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + virtual int get_data1i(const unsigned char *pointer); + + INLINE float maybe_scale_color(unsigned int value); + INLINE void maybe_scale_color(unsigned int a, unsigned int b); + INLINE void maybe_scale_color(unsigned int a, unsigned int b, + unsigned int c); + INLINE void maybe_scale_color(unsigned int a, unsigned int b, + unsigned int c, unsigned int d); + + const qpGeomVertexDataType *_data_type; + LVecBase2f _v2; + LVecBase3f _v3; + LVecBase4f _v4; + }; + + // This is a specialization on the generic Reader that handles + // points, which are special because the fourth component, if + // omitted, is 1.0. + class Reader_point : public Reader { + public: + virtual const LVecBase4f &get_data4f(const unsigned char *pointer); + }; + + + // These are the specializations on the generic Reader that handle + // the direct code paths. + + class Reader_float_3 : public Reader { + public: + virtual const LVecBase3f &get_data3f(const unsigned char *pointer); + }; + + class Reader_uint16_1 : public Reader { + public: + virtual int get_data1i(const unsigned char *pointer); + }; +}; + +#include "qpgeomVertexReader.I" + +#endif