ColorMunger

This commit is contained in:
David Rose 2005-03-21 17:52:15 +00:00
parent 92a93e8af0
commit ea51a7a6f7
38 changed files with 624 additions and 58 deletions

View File

@ -11,6 +11,7 @@
#define COMBINED_SOURCES $[TARGET]_composite1.cxx $[TARGET]_composite2.cxx
#define SOURCES \
colorMunger.I colorMunger.h \
config_display.h \
drawableRegion.I drawableRegion.h \
displayRegion.I displayRegion.h \
@ -34,6 +35,7 @@
lensStack.I lensStack.h
#define INCLUDED_SOURCES \
colorMunger.cxx \
config_display.cxx \
drawableRegion.cxx \
displayRegion.cxx \
@ -51,6 +53,7 @@
windowProperties.cxx
#define INSTALL_HEADERS \
colorMunger.I colorMunger.h \
config_display.h \
drawableRegion.I drawableRegion.h \
displayRegion.I displayRegion.h displayRegionStack.I \

View File

@ -0,0 +1,18 @@
// Filename: colorMunger.I
// Created by: drose (21Mar05)
//
////////////////////////////////////////////////////////////////////
//
// 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 .
//
////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,101 @@
// Filename: colorMunger.cxx
// Created by: drose (21Mar05)
//
////////////////////////////////////////////////////////////////////
//
// 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 "colorMunger.h"
#include "renderState.h"
#include "dcast.h"
TypeHandle ColorMunger::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: ColorMunger::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
ColorMunger::
ColorMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state,
int num_components,
qpGeomVertexDataType::NumericType numeric_type) :
qpGeomMunger(gsg, state),
_num_components(num_components),
_numeric_type(numeric_type)
{
_color = state->get_color();
_color_scale = state->get_color_scale();
}
////////////////////////////////////////////////////////////////////
// Function: ColorMunger::Destructor
// Access: Public, Virtual
// Description:
////////////////////////////////////////////////////////////////////
ColorMunger::
~ColorMunger() {
}
////////////////////////////////////////////////////////////////////
// Function: ColorMunger::munge_data_impl
// Access: Protected, Virtual
// Description: Given a source GeomVertexData, converts it as
// necessary for rendering.
////////////////////////////////////////////////////////////////////
CPT(qpGeomVertexData) ColorMunger::
munge_data_impl(const qpGeomVertexData *data) {
CPT(qpGeomVertexData) new_data = data;
if (_color != (ColorAttrib *)NULL &&
_color->get_color_type() == ColorAttrib::T_flat) {
Colorf color = _color->get_color();
if (_color_scale != (ColorScaleAttrib *)NULL &&
_color_scale->has_scale()) {
const LVecBase4f &cs = _color_scale->get_scale();
color.set(color[0] * cs[0],
color[1] * cs[1],
color[2] * cs[2],
color[3] * cs[3]);
}
new_data = new_data->set_color(color, _num_components, _numeric_type);
} 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);
}
return qpGeomMunger::munge_data_impl(new_data);
}
////////////////////////////////////////////////////////////////////
// Function: ColorMunger::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 ColorMunger::
compare_to_impl(const qpGeomMunger *other) const {
const ColorMunger *om = DCAST(ColorMunger, other);
if (_color != om->_color) {
return _color < om->_color ? -1 : 1;
}
if (_color_scale != om->_color_scale) {
return _color_scale < om->_color_scale ? -1 : 1;
}
return 0;
}

View File

@ -0,0 +1,73 @@
// Filename: colorMunger.h
// Created by: drose (21Mar05)
//
////////////////////////////////////////////////////////////////////
//
// 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 COLORMUNGER_H
#define COLORMUNGER_H
#include "pandabase.h"
#include "qpgeomMunger.h"
#include "colorAttrib.h"
#include "colorScaleAttrib.h"
#include "pointerTo.h"
////////////////////////////////////////////////////////////////////
// Class : ColorMunger
// Description : Applies ColorAttrib and ColorScaleAttrib by munging
// the vertex data.
//
// This is part of the experimental Geom rewrite.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA ColorMunger : public qpGeomMunger {
public:
ColorMunger(const GraphicsStateGuardianBase *gsg, const RenderState *state,
int num_components,
qpGeomVertexDataType::NumericType numeric_type);
virtual ~ColorMunger();
protected:
virtual CPT(qpGeomVertexData) munge_data_impl(const qpGeomVertexData *data);
virtual int compare_to_impl(const qpGeomMunger *other) const;
private:
int _num_components;
qpGeomVertexDataType::NumericType _numeric_type;
CPT(ColorAttrib) _color;
CPT(ColorScaleAttrib) _color_scale;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
qpGeomMunger::init_type();
register_type(_type_handle, "ColorMunger",
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 "colorMunger.I"
#endif

View File

@ -18,6 +18,7 @@
#include "config_display.h"
#include "colorMunger.h"
#include "graphicsStateGuardian.h"
#include "graphicsPipe.h"
#include "graphicsOutput.h"
@ -246,7 +247,8 @@ init_libdisplay() {
return;
}
initialized = true;
ColorMunger::init_type();
GraphicsStateGuardian::init_type();
GraphicsPipe::init_type();
GraphicsOutput::init_type();

View File

@ -1,3 +1,4 @@
#include "colorMunger.cxx"
#include "drawableRegion.cxx"
#include "displayRegion.cxx"
#include "graphicsEngine.cxx"

View File

@ -670,7 +670,9 @@ finish_decal() {
// are ok, false to abort this group of primitives.
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
begin_draw_primitives(const qpGeom *, const qpGeomVertexData *data) {
begin_draw_primitives(const qpGeom *, const qpGeomMunger *munger,
const qpGeomVertexData *data) {
_munger = munger;
_vertex_data = data;
return true;
}
@ -719,6 +721,7 @@ draw_trifans(const qpGeomTrifans *primitive) {
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
end_draw_primitives() {
_munger = NULL;
_vertex_data = NULL;
}

View File

@ -148,7 +148,9 @@ public:
virtual CPT(RenderState) begin_decal_base_second();
virtual void finish_decal();
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data);
virtual bool begin_draw_primitives(const qpGeom *geom,
const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data);
virtual void draw_triangles(const qpGeomTriangles *primitive);
virtual void draw_tristrips(const qpGeomTristrips *primitive);
virtual void draw_trifans(const qpGeomTrifans *primitive);
@ -251,6 +253,7 @@ protected:
CPT(RenderState) _state;
CPT(TransformState) _transform;
CPT(qpGeomMunger) _munger;
CPT(qpGeomVertexData) _vertex_data;
int _buffer_mask;

View File

@ -2607,10 +2607,11 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
// are ok, false to abort this group of primitives.
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8::
begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data) {
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
if (!GraphicsStateGuardian::begin_draw_primitives(geom, vertex_data)) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
return false;
}
nassertr(_vertex_data != (qpGeomVertexData *)NULL, false);

View File

@ -90,7 +90,9 @@ public:
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data);
virtual bool begin_draw_primitives(const qpGeom *geom,
const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data);
virtual void draw_triangles(const qpGeomTriangles *primitive);
virtual void draw_tristrips(const qpGeomTristrips *primitive);
virtual void end_draw_primitives();

View File

@ -24,6 +24,8 @@
////////////////////////////////////////////////////////////////////
INLINE CLP(GeomMunger)::
CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state) :
qpGeomMunger(gsg, state)
ColorMunger(gsg, state, 4, qpGeomVertexDataType::NT_uint8),
_texture(state->get_texture()),
_tex_gen(state->get_tex_gen())
{
}

View File

@ -16,8 +16,9 @@
//
////////////////////////////////////////////////////////////////////
TypeHandle CLP(GeomMunger)::_type_handle;
#include "dcast.h"
TypeHandle CLP(GeomMunger)::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::munge_format_impl
@ -65,3 +66,39 @@ munge_format_impl(const qpGeomVertexFormat *orig) {
return format;
}
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::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 CLP(GeomMunger)::
compare_to_impl(const qpGeomMunger *other) const {
const CLP(GeomMunger) *om = DCAST(CLP(GeomMunger), other);
if (_texture != om->_texture) {
return _texture < om->_texture ? -1 : 1;
}
if (_tex_gen != om->_tex_gen) {
return _tex_gen < om->_tex_gen ? -1 : 1;
}
return ColorMunger::compare_to_impl(other);
}
////////////////////////////////////////////////////////////////////
// Function: CLP(GeomMunger)::geom_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 CLP(GeomMunger)::
geom_compare_to_impl(const qpGeomMunger *other) const {
// We don't consider _texture and _tex_gen for these purposes; they
// affect only whether the GL display list should be regenerated or
// not.
return ColorMunger::compare_to_impl(other);
}

View File

@ -17,8 +17,11 @@
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "qpgeomMunger.h"
#include "colorMunger.h"
#include "graphicsStateGuardian.h"
#include "textureAttrib.h"
#include "texGenAttrib.h"
#include "renderState.h"
////////////////////////////////////////////////////////////////////
// Class : GLGeomMunger
@ -26,21 +29,27 @@
// 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 {
class EXPCL_GL CLP(GeomMunger) : public ColorMunger {
public:
INLINE CLP(GeomMunger)(GraphicsStateGuardian *gsg, const RenderState *state);
protected:
virtual CPT(qpGeomVertexFormat) munge_format_impl(const qpGeomVertexFormat *orig);
virtual int compare_to_impl(const qpGeomMunger *other) const;
virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
private:
CPT(TextureAttrib) _texture;
CPT(TexGenAttrib) _tex_gen;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
qpGeomMunger::init_type();
ColorMunger::init_type();
register_type(_type_handle, CLASSPREFIX_QUOTED "GeomMunger",
qpGeomMunger::get_class_type());
ColorMunger::get_class_type());
}
virtual TypeHandle get_type() const {
return get_class_type();

View File

@ -2037,8 +2037,9 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
// are ok, false to abort this group of primitives.
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom, vertex_data)) {
begin_draw_primitives(const qpGeom *geom, const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
return false;
}
nassertr(_vertex_data != (qpGeomVertexData *)NULL, false);

View File

@ -92,7 +92,9 @@ public:
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc);
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc);
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data);
virtual bool begin_draw_primitives(const qpGeom *geom,
const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data);
virtual void draw_triangles(const qpGeomTriangles *primitive);
virtual void draw_tristrips(const qpGeomTristrips *primitive);
virtual void end_draw_primitives();

View File

@ -75,6 +75,7 @@ void CLP(init_classes)() {
CLP(GeomContext)::init_type();
CLP(VertexBufferContext)::init_type();
CLP(IndexBufferContext)::init_type();
CLP(GeomMunger)::init_type();
PandaSystem *ps = PandaSystem::get_global_ptr();
ps->add_system(GLSYSTEM_NAME);

View File

@ -48,7 +48,8 @@ dDrawable::
// At this level, this doesn't do very much.
////////////////////////////////////////////////////////////////////
void dDrawable::
draw(GraphicsStateGuardianBase *, const qpGeomVertexData *) const {
draw(GraphicsStateGuardianBase *, const qpGeomMunger *,
const qpGeomVertexData *) const {
if (is_dirty()) {
((dDrawable *)this)->config();
}

View File

@ -34,6 +34,7 @@ class Datagram;
class DatagramIterator;
class BamReader;
class BamWriter;
class qpGeomMunger;
class qpGeomVertexData;
////////////////////////////////////////////////////////////////////
@ -52,6 +53,7 @@ public:
virtual ~dDrawable();
virtual void draw(GraphicsStateGuardianBase *gsg,
const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data) const;
virtual bool is_dynamic() const;

View File

@ -915,7 +915,8 @@ release_all() {
// Description: Actually draws the Geom with the indicated GSG.
////////////////////////////////////////////////////////////////////
void Geom::
draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *) const {
draw(GraphicsStateGuardianBase *gsg,
const qpGeomMunger *, const qpGeomVertexData *) const {
PreparedGraphicsObjects *prepared_objects = gsg->get_prepared_objects();
if (is_dirty()) {
((Geom *)this)->config();

View File

@ -241,6 +241,7 @@ public:
// From parent dDrawable
virtual void draw(GraphicsStateGuardianBase *gsg,
const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data) const;
// From parent Configurable

View File

@ -354,7 +354,8 @@ clear_cache() {
// pre-munged to support the GSG's needs).
////////////////////////////////////////////////////////////////////
void qpGeom::
draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *vertex_data) const {
draw(GraphicsStateGuardianBase *gsg, const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data) const {
#ifdef DO_PIPELINING
// Make sure the usage_hint is already updated before we start to
// draw, so we don't end up with a circular lock if the GSG asks us
@ -373,7 +374,7 @@ draw(GraphicsStateGuardianBase *gsg, const qpGeomVertexData *vertex_data) const
CDReader cdata(_cycler);
if (gsg->begin_draw_primitives(this, vertex_data)) {
if (gsg->begin_draw_primitives(this, munger, vertex_data)) {
Primitives::const_iterator pi;
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();

View File

@ -90,6 +90,7 @@ PUBLISHED:
public:
void draw(GraphicsStateGuardianBase *gsg,
const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data) const;
static UpdateSeq get_next_modified();

View File

@ -71,6 +71,30 @@ compare_to(const qpGeomMunger &other) const {
return compare_to_impl(&other);
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::geom_compare_to
// Access: Public
// Description: Compares two GeomMungers, considering only whether
// they would produce a different answer to
// munge_format(), munge_data(), or munge_geom(). (They
// still might be different in other ways, but if they
// would produce the same answer, this function consider
// them to be the same.)
////////////////////////////////////////////////////////////////////
INLINE int qpGeomMunger::
geom_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 geom_compare_to_impl(&other);
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::munge_format
// Access: Public
@ -96,7 +120,7 @@ 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);
return ((qpGeomMunger *)this)->munge_data_impl(data);
}
////////////////////////////////////////////////////////////////////

View File

@ -140,13 +140,24 @@ do_munge_format(const qpGeomVertexFormat *format) {
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::do_munge_data
// Access: Protected
// Description: The protected implementation of munge_data(). This
// exists just to cast away the const pointer.
// 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::munge_data_impl
// Access: Protected, Virtual
// Description: Given a source GeomVertexData, converts it as
// necessary for rendering.
////////////////////////////////////////////////////////////////////
CPT(qpGeomVertexData) qpGeomMunger::
do_munge_data(const qpGeomVertexData *data) {
munge_data_impl(const qpGeomVertexData *data) {
nassertr(_is_registered, NULL);
CPT(qpGeomVertexFormat) orig_format = data->get_format();
@ -160,17 +171,6 @@ do_munge_data(const qpGeomVertexData *data) {
return data->convert_to(new_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::munge_geom_impl
// Access: Protected, Virtual
@ -178,7 +178,8 @@ munge_format_impl(const qpGeomVertexFormat *orig) {
////////////////////////////////////////////////////////////////////
void qpGeomMunger::
munge_geom_impl(CPT(qpGeom) &, CPT(qpGeomVertexData) &) {
// The default implementation does nothing.
// The default implementation does nothing (the work has already
// been done in munge_format_impl).
}
////////////////////////////////////////////////////////////////////
@ -194,6 +195,19 @@ compare_to_impl(const qpGeomMunger *other) const {
return 0;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::geom_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::
geom_compare_to_impl(const qpGeomMunger *other) const {
return compare_to_impl(other);
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomMunger::make_registry
// Access: Private

View File

@ -74,14 +74,16 @@ public:
public:
INLINE int compare_to(const qpGeomMunger &other) const;
INLINE int geom_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 CPT(qpGeomVertexData) munge_data_impl(const qpGeomVertexData *data);
virtual void munge_geom_impl(CPT(qpGeom) &geom, CPT(qpGeomVertexData) &data);
virtual int compare_to_impl(const qpGeomMunger *other) const;
virtual int geom_compare_to_impl(const qpGeomMunger *other) const;
private:
class Registry;
@ -91,6 +93,7 @@ private:
void do_register();
void do_unregister();
private:
typedef pmap<const qpGeomVertexFormat *, const qpGeomVertexFormat *> Formats;
Formats _formats;

View File

@ -188,8 +188,11 @@ qpGeomVertexArrayFormat::
// "vertex" or "normal"; you must specify where in each
// record the table starts, and how many components
// (dimensions) exist per vertex.
//
// The return value is the index number of the new data
// type.
////////////////////////////////////////////////////////////////////
void qpGeomVertexArrayFormat::
int qpGeomVertexArrayFormat::
add_data_type(const InternalName *name, int num_components,
qpGeomVertexDataType::NumericType numeric_type, int start) {
if (start < 0) {
@ -200,8 +203,8 @@ add_data_type(const InternalName *name, int num_components,
start = ((start + pad_to - 1) / pad_to) * pad_to;
}
add_data_type(qpGeomVertexDataType(name, num_components,
numeric_type, start));
return add_data_type(qpGeomVertexDataType(name, num_components,
numeric_type, start));
}
////////////////////////////////////////////////////////////////////
@ -216,10 +219,13 @@ add_data_type(const InternalName *name, int num_components,
// 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).
//
// The return value is the index number of the new data
// type.
////////////////////////////////////////////////////////////////////
void qpGeomVertexArrayFormat::
int qpGeomVertexArrayFormat::
add_data_type(const qpGeomVertexDataType &data_type) {
nassertv(!_is_registered);
nassertr(!_is_registered, -1);
// Make sure there isn't already a data type with this name.
remove_data_type(data_type.get_name());
@ -242,8 +248,11 @@ add_data_type(const qpGeomVertexDataType &data_type) {
_data_types_unsorted = true;
}
int new_index = (int)_data_types.size();
_data_types.push_back(new_data_type);
_data_types_by_name.insert(DataTypesByName::value_type(new_data_type->get_name(), new_data_type));
return new_index;
}
////////////////////////////////////////////////////////////////////

View File

@ -83,10 +83,10 @@ PUBLISHED:
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);
int add_data_type(const InternalName *name, int num_components,
qpGeomVertexDataType::NumericType numeric_type,
int start = -1);
int add_data_type(const qpGeomVertexDataType &data_type);
void remove_data_type(const InternalName *name);
void clear_data_types();

View File

@ -286,7 +286,10 @@ operator < (const qpGeomVertexCacheManager::Entry &other) const {
if (_u._geom._source != other._u._geom._source) {
return _u._geom._source < other._u._geom._source;
}
return _u._geom._modifier < other._u._geom._modifier;
if (_u._geom._modifier != other._u._geom._modifier) {
return _u._geom._modifier->geom_compare_to(*other._u._geom._modifier) < 0;
}
return 0;
}
return false;

View File

@ -17,6 +17,7 @@
////////////////////////////////////////////////////////////////////
#include "qpgeomVertexData.h"
#include "qpgeomVertexIterator.h"
#include "pStatTimer.h"
#include "bamReader.h"
#include "bamWriter.h"
@ -24,7 +25,9 @@
TypeHandle qpGeomVertexData::_type_handle;
PStatCollector qpGeomVertexData::_munge_data_pcollector("Cull:Munge:Data");
PStatCollector qpGeomVertexData::_convert_pcollector("Cull:Munge:Convert");
PStatCollector qpGeomVertexData::_scale_color_pcollector("Cull:Munge:Scale color");
PStatCollector qpGeomVertexData::_set_color_pcollector("Cull:Munge:Set color");
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexData::Default Constructor
@ -219,7 +222,7 @@ convert_to(const qpGeomVertexFormat *new_format) const {
gobj_cat.debug()
<< "Converting " << num_vertices << " vertices.\n";
}
PStatTimer timer(_munge_data_pcollector);
PStatTimer timer(_convert_pcollector);
PT(qpGeomVertexData) new_data =
new qpGeomVertexData(new_format, get_usage_hint());
@ -287,6 +290,159 @@ convert_to(const qpGeomVertexFormat *new_format) const {
return new_data;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexData::scale_color
// Access: Published
// Description: Returns a new GeomVertexData object with the color
// table replaced with a new color table that has been
// scaled by the indicated value. The new color table
// will be added as a new array; if the old color table
// was interleaved with a previous array, the previous
// array will not be repacked.
////////////////////////////////////////////////////////////////////
CPT(qpGeomVertexData) qpGeomVertexData::
scale_color(const LVecBase4f &color_scale, int num_components,
qpGeomVertexDataType::NumericType numeric_type) const {
int old_color_array = _format->get_array_with(InternalName::get_color());
if (old_color_array == -1) {
// Oops, no color anyway.
return this;
}
int num_vertices = get_num_vertices();
if (gobj_cat.is_debug()) {
gobj_cat.debug()
<< "Scaling color for " << num_vertices << " vertices by "
<< color_scale << ".\n";
}
PStatTimer timer(_scale_color_pcollector);
PT(qpGeomVertexData) new_data = replace_data_type
(InternalName::get_color(), num_components, numeric_type);
// Now go through and apply the scale, copying it to the new data.
qpGeomVertexIterator from(this, InternalName::get_color());
qpGeomVertexIterator to(new_data, InternalName::get_color());
for (int i = 0; i < num_vertices; i++) {
Colorf color = from.get_data4();
to.set_data4(color[0] * color_scale[0],
color[1] * color_scale[1],
color[2] * color_scale[2],
color[3] * color_scale[3]);
}
return new_data;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexData::set_color
// Access: Published
// Description: Returns a new GeomVertexData object with the color
// table replaced with a new color table for which each
// vertex has the indicated value. The new color table
// will be added as a new array; if the old color table
// was interleaved with a previous array, the previous
// array will not be repacked.
////////////////////////////////////////////////////////////////////
CPT(qpGeomVertexData) qpGeomVertexData::
set_color(const Colorf &color, int num_components,
qpGeomVertexDataType::NumericType numeric_type) const {
int num_vertices = get_num_vertices();
if (gobj_cat.is_debug()) {
gobj_cat.debug()
<< "Setting color for " << num_vertices << " vertices to "
<< color << ".\n";
}
PStatTimer timer(_set_color_pcollector);
PT(qpGeomVertexData) new_data = replace_data_type
(InternalName::get_color(), num_components, numeric_type);
// Now go through and set the new color value.
qpGeomVertexIterator to(new_data, InternalName::get_color());
for (int i = 0; i < num_vertices; i++) {
to.set_data4(color);
}
return new_data;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexData::replace_data_type
// Access: Published
// Description: Returns a new GeomVertexData object, suitable for
// modification, with the indicated data type replaced
// with a new table filled with undefined values. The
// new table will be added as a new array; if the old
// table was interleaved with a previous array, the
// previous array will not be repacked.
////////////////////////////////////////////////////////////////////
PT(qpGeomVertexData) qpGeomVertexData::
replace_data_type(const InternalName *name, int num_components,
qpGeomVertexDataType::NumericType numeric_type) const {
PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat(*_format);
// Remove the old description of the type from the format.
bool removed_type_array = false;
int old_type_array = _format->get_array_with(name);
if (old_type_array != -1) {
qpGeomVertexArrayFormat *array_format = new_format->modify_array(old_type_array);
if (array_format->get_num_data_types() == 1) {
// Actually, this array didn't have any other data types, so
// just drop the whole array.
new_format->remove_array(old_type_array);
removed_type_array = true;
} else {
// Remove the description for the type, but don't bother to
// repack the array.
array_format->remove_data_type(name);
}
}
// Now define a new array to contain just the type.
PT(qpGeomVertexArrayFormat) type_array_format =
new qpGeomVertexArrayFormat(name, num_components, numeric_type);
int new_type_array = new_format->add_array(type_array_format);
PT(qpGeomVertexData) new_data =
new qpGeomVertexData(qpGeomVertexFormat::register_format(new_format),
get_usage_hint());
int j = 0;
int num_arrays = get_num_arrays();
for (int i = 0; i < num_arrays; ++i) {
if (i == old_type_array) {
if (!removed_type_array) {
// Pointer-copy the original array that includes the type
// (since it also includes other data).
new_data->set_array(j, get_array(i));
++j;
}
} else {
// Just pointer-copy any arrays other than type.
new_data->set_array(j, get_array(i));
++j;
}
}
nassertr(j == new_type_array, new_data);
// For the new type array, we set up a temporary array that has
// room for the right number of vertices.
PT(qpGeomVertexArrayData) new_array = new qpGeomVertexArrayData
(new_format->get_array(j), get_usage_hint());
new_array->set_num_vertices(get_num_vertices());
new_data->set_array(j, new_array);
return new_data;
}
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexData::output
// Access: Published

View File

@ -85,6 +85,16 @@ PUBLISHED:
INLINE UpdateSeq get_modified() const;
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;
CPT(qpGeomVertexData)
set_color(const Colorf &color, int num_components,
qpGeomVertexDataType::NumericType numeric_type) const;
PT(qpGeomVertexData)
replace_data_type(const InternalName *name, int num_components,
qpGeomVertexDataType::NumericType numeric_type) const;
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
@ -135,7 +145,9 @@ private:
private:
bool do_set_num_vertices(int n, CDWriter &cdata);
static PStatCollector _munge_data_pcollector;
static PStatCollector _convert_pcollector;
static PStatCollector _scale_color_pcollector;
static PStatCollector _set_color_pcollector;
public:
static void register_with_read_factory();

View File

@ -138,12 +138,16 @@ remove_array(int array) {
// Access: Published
// Description: Adds the indicated array definition to the list of
// arrays included within this vertex format definition.
// The return value is the index number of the new
// array.
////////////////////////////////////////////////////////////////////
void qpGeomVertexFormat::
int qpGeomVertexFormat::
add_array(qpGeomVertexArrayFormat *array_format) {
nassertv(!_is_registered);
nassertr(!_is_registered, -1);
int new_array = (int)_arrays.size();
_arrays.push_back(array_format);
return new_array;
}
////////////////////////////////////////////////////////////////////

View File

@ -71,7 +71,7 @@ PUBLISHED:
qpGeomVertexArrayFormat *modify_array(int array);
void set_array(int array, qpGeomVertexArrayFormat *format);
void remove_array(int array);
void add_array(qpGeomVertexArrayFormat *array_format);
int add_array(qpGeomVertexArrayFormat *array_format);
void clear_arrays();
int get_num_data_types() const;

View File

@ -26,6 +26,7 @@
INLINE qpGeomVertexIterator::
qpGeomVertexIterator(qpGeomVertexData *data) :
_data(data),
_const_data(false),
_array(0),
_data_type(NULL),
_start_vertex(0),
@ -44,6 +45,7 @@ qpGeomVertexIterator(qpGeomVertexData *data) :
INLINE qpGeomVertexIterator::
qpGeomVertexIterator(qpGeomVertexData *data, const string &name) :
_data(data),
_const_data(false),
_array(0),
_data_type(NULL),
_start_vertex(0),
@ -63,6 +65,65 @@ qpGeomVertexIterator(qpGeomVertexData *data, const string &name) :
INLINE qpGeomVertexIterator::
qpGeomVertexIterator(qpGeomVertexData *data, const InternalName *name) :
_data(data),
_const_data(false),
_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.
////////////////////////////////////////////////////////////////////
INLINE qpGeomVertexIterator::
qpGeomVertexIterator(const qpGeomVertexData *data) :
_data((qpGeomVertexData *)data),
_const_data(true),
_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(const qpGeomVertexData *data, const string &name) :
_data((qpGeomVertexData *)data),
_const_data(true),
_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(const qpGeomVertexData *data, const InternalName *name) :
_data((qpGeomVertexData *)data),
_const_data(true),
_array(0),
_data_type(NULL),
_start_vertex(0),
@ -78,7 +139,7 @@ qpGeomVertexIterator(qpGeomVertexData *data, const InternalName *name) :
// Description: Returns the current data object that the iterator is
// processing.
////////////////////////////////////////////////////////////////////
INLINE qpGeomVertexData *qpGeomVertexIterator::
INLINE const qpGeomVertexData *qpGeomVertexIterator::
get_data() const {
return _data;
}
@ -237,6 +298,7 @@ get_write_vertex() const {
////////////////////////////////////////////////////////////////////
INLINE void qpGeomVertexIterator::
set_data1(float data) {
nassertv(!_const_data);
_data->set_data(_array, _data_type, _write_vertex, &data, 1);
++_write_vertex;
}
@ -260,6 +322,7 @@ set_data2(float x, float y) {
////////////////////////////////////////////////////////////////////
INLINE void qpGeomVertexIterator::
set_data2(const LVecBase2f &data) {
nassertv(!_const_data);
_data->set_data(_array, _data_type, _write_vertex, data.get_data(), 2);
++_write_vertex;
}
@ -283,6 +346,7 @@ set_data3(float x, float y, float z) {
////////////////////////////////////////////////////////////////////
INLINE void qpGeomVertexIterator::
set_data3(const LVecBase3f &data) {
nassertv(!_const_data);
_data->set_data(_array, _data_type, _write_vertex, data.get_data(), 3);
++_write_vertex;
}
@ -306,6 +370,7 @@ set_data4(float x, float y, float z, float w) {
////////////////////////////////////////////////////////////////////
INLINE void qpGeomVertexIterator::
set_data4(const LVecBase4f &data) {
nassertv(!_const_data);
_data->set_data(_array, _data_type, _write_vertex, data.get_data(), 4);
++_write_vertex;
}

View File

@ -41,8 +41,13 @@ PUBLISHED:
const string &name);
INLINE qpGeomVertexIterator(qpGeomVertexData *data,
const InternalName *name);
INLINE qpGeomVertexIterator(const qpGeomVertexData *data);
INLINE qpGeomVertexIterator(const qpGeomVertexData *data,
const string &name);
INLINE qpGeomVertexIterator(const qpGeomVertexData *data,
const InternalName *name);
INLINE qpGeomVertexData *get_data() const;
INLINE const qpGeomVertexData *get_data() const;
INLINE void set_data_type(int data_type);
INLINE void set_data_type(const string &name);
@ -73,6 +78,7 @@ PUBLISHED:
private:
PT(qpGeomVertexData) _data;
bool _const_data;
int _array;
const qpGeomVertexDataType *_data_type;

View File

@ -184,7 +184,9 @@ public:
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc)=0;
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc)=0;
virtual bool begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data)=0;
virtual bool begin_draw_primitives(const qpGeom *geom,
const qpGeomMunger *munger,
const qpGeomVertexData *vertex_data)=0;
virtual void draw_triangles(const qpGeomTriangles *primitive)=0;
virtual void draw_tristrips(const qpGeomTristrips *primitive)=0;
virtual void draw_trifans(const qpGeomTrifans *primitive)=0;

View File

@ -124,7 +124,7 @@ munge_geom(GraphicsStateGuardianBase *gsg) {
////////////////////////////////////////////////////////////////////
INLINE void CullableObject::
draw(GraphicsStateGuardianBase *gsg) {
_geom->draw(gsg, _munged_data);
_geom->draw(gsg, _munger, _munged_data);
}
////////////////////////////////////////////////////////////////////

View File

@ -35,6 +35,7 @@ munge_geom(const qpGeomMunger *munger) {
// Temporary test and dcast until the experimental Geom rewrite
// becomes the actual Geom rewrite.
if (_geom->is_exact_type(qpGeom::get_class_type())) {
_munger = munger;
CPT(qpGeom) qpgeom = DCAST(qpGeom, _geom);
qpgeom->munge_geom(munger, qpgeom, _munged_data);
_geom = qpgeom;

View File

@ -74,6 +74,7 @@ PUBLISHED:
public:
CPT(Geom) _geom;
CPT(qpGeomMunger) _munger;
CPT(qpGeomVertexData) _munged_data;
CPT(RenderState) _state;
CPT(TransformState) _transform;