more egg features for new geom

This commit is contained in:
David Rose 2005-03-17 21:45:05 +00:00
parent 6ef748f7ab
commit acfa6978db
15 changed files with 175 additions and 28 deletions

View File

@ -2677,7 +2677,7 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_triangles(const qpGeomTriangles *primitive) {
HRESULT hr = _pD3DDevice->DrawIndexedPrimitiveUP
_pD3DDevice->DrawIndexedPrimitiveUP
(D3DPT_TRIANGLELIST,
primitive->get_min_vertex(),
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
@ -2686,8 +2686,37 @@ draw_triangles(const qpGeomTriangles *primitive) {
D3DFMT_INDEX16,
_vertex_data->get_array_data(0),
_vertex_data->get_format()->get_array(0)->get_stride());
}
TestDrawPrimFailure(DrawPrim,hr,_pD3DDevice,nPrims,0);
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::draw_tristrips
// Access: Public, Virtual
// Description: Draws a series of triangle strips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_tristrips(const qpGeomTristrips *primitive) {
int min_vertex = primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
CPTA_ushort vertices = primitive->get_flat_first_vertices();
CPTA_int ends = primitive->get_ends();
CPTA_uchar array_data = _vertex_data->get_array_data(0);
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
int num_primitives = primitive->get_num_primitives();
int start = 0;
for (CPTA_int::const_iterator pi = ends.begin(); pi != ends.end(); ++pi) {
int end = (*pi);
_pD3DDevice->DrawIndexedPrimitiveUP
(D3DPT_TRIANGLESTRIP,
min_vertex, max_vertex - min_vertex + 1,
end - start - 2,
vertices + start, D3DFMT_INDEX16,
array_data, stride);
start = end;
}
}
////////////////////////////////////////////////////////////////////

View File

@ -92,6 +92,7 @@ public:
virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data);
virtual void draw_triangles(const qpGeomTriangles *primitive);
virtual void draw_tristrips(const qpGeomTristrips *primitive);
virtual void end_draw_primitives();
virtual TextureContext *prepare_texture(Texture *tex);

View File

@ -145,6 +145,11 @@ unify_attributes(EggPrimitive::Shading shading) {
shading = get_shading();
}
// Not having a color is implicitly white.
if (!has_color()) {
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
}
switch (shading) {
case S_per_vertex:
// Propagate everything to the vertices.

View File

@ -771,9 +771,11 @@ mesh_triangles(int flags) {
// Access: Published
// Description: Removes all vertices from VertexPools within this
// group or below that are not referenced by at least
// one primitive. Also renumbers all vertices after the
// one primitive. Also collapses together equivalent
// vertices, and renumbers all vertices after the
// operation so their indices are consecutive, beginning
// at zero. Returns the total number of vertices removed.
// at zero. Returns the total number of vertices
// removed.
//
// Note that this operates on the VertexPools within
// this group level, without respect to primitives that

View File

@ -102,9 +102,9 @@ clear_connected_shading() {
// EggGroupNode).
////////////////////////////////////////////////////////////////////
INLINE EggPrimitive::Shading EggPrimitive::
get_connected_shading() {
get_connected_shading() const {
if (_connected_shading == S_unknown) {
set_connected_shading(S_unknown, this);
((EggPrimitive *)this)->set_connected_shading(S_unknown, this);
}
return _connected_shading;
@ -150,7 +150,7 @@ has_texture() const {
INLINE bool EggPrimitive::
has_texture(EggTexture *texture) const {
PT_EggTexture t = texture;
return (find(_textures.begin(), _textures.end(), t) != _textures.end());
return (::find(_textures.begin(), _textures.end(), t) != _textures.end());
}
////////////////////////////////////////////////////////////////////

View File

@ -352,6 +352,11 @@ unify_attributes(EggPrimitive::Shading shading) {
shading = get_shading();
}
// Not having a color is implicitly white.
if (!has_color()) {
set_color(Colorf(1.0f, 1.0f, 1.0f, 1.0f));
}
switch (shading) {
case S_per_vertex:
// Propagate everything to the vertices.
@ -659,6 +664,19 @@ erase(iterator first, iterator last) {
return result;
}
////////////////////////////////////////////////////////////////////
// Function: EggPrimitive::find
// Access: Public
// Description: Returns the iterator pointing to the indicated
// vertex, or end() if the vertex is not part of the
// primitive.
////////////////////////////////////////////////////////////////////
EggPrimitive::iterator EggPrimitive::
find(EggVertex *vertex) {
PT_EggVertex vpt = vertex;
return ::find(begin(), end(), vpt);
}
////////////////////////////////////////////////////////////////////
// Function: EggPrimitive::add_vertex
@ -688,7 +706,7 @@ add_vertex(EggVertex *vertex) {
EggVertex *EggPrimitive::
remove_vertex(EggVertex *vertex) {
PT_EggVertex vpt = vertex;
iterator i = find(begin(), end(), vpt);
iterator i = ::find(begin(), end(), vpt);
if (i == end()) {
return PT_EggVertex();
} else {
@ -1129,7 +1147,21 @@ set_connected_shading(EggPrimitive::Shading shading,
// If both neighbors are overall shaded, check if the two
// neighbors have different properties. If they do, elevate to
// per_face.
if (!matches_normal(*neighbor) || !matches_color(*neighbor)) {
bool matches_normal = this->matches_normal(*neighbor);
bool matches_color = this->matches_color(*neighbor);
if (!matches_color) {
// Make a special case for not having an overall color: that's
// implicitly white.
if (!neighbor->has_color() && has_color() && _drgbas.empty() &&
get_color() == Colorf(1.0f, 1.0f, 1.0f, 1.0f)) {
matches_color = true;
} else if (!has_color() && neighbor->has_color() && neighbor->_drgbas.empty() &&
neighbor->get_color() == Colorf(1.0f, 1.0f, 1.0f, 1.0f)) {
matches_color = true;
}
}
if (!matches_normal || !matches_color) {
_connected_shading = S_per_face;
propagate = true;
}

View File

@ -89,7 +89,7 @@ PUBLISHED:
virtual Shading get_shading() const;
INLINE void clear_connected_shading();
INLINE Shading get_connected_shading();
INLINE Shading get_connected_shading() const;
INLINE void set_texture(EggTexture *texture);
INLINE bool has_texture() const;
@ -163,6 +163,7 @@ public:
INLINE iterator erase(iterator position);
iterator erase(iterator first, iterator last);
INLINE void replace(iterator position, EggVertex *vertex);
iterator find(EggVertex *vertex);
PUBLISHED:
INLINE void clear();
@ -178,6 +179,8 @@ PUBLISHED:
INLINE EggVertexPool *get_pool() const;
virtual void write(ostream &out, int indent_level) const=0;
#ifndef NDEBUG
void test_vref_integrity() const;
#else

View File

@ -475,8 +475,9 @@ remove_vertex(EggVertex *vertex) {
// Function: EggVertexPool::remove_unused_vertices
// Access: Public
// Description: Removes all vertices from the pool that are not
// referenced by at least one primitive. Also renumbers
// all vertices after the operation so their indices are
// referenced by at least one primitive. Also collapses
// together equivalent vertices, and renumbers all
// vertices after the operation so their indices are
// consecutive, beginning at zero. Returns the number
// of vertices removed.
////////////////////////////////////////////////////////////////////
@ -497,11 +498,38 @@ remove_unused_vertices() {
num_removed++;
} else {
// The vertex *is* used somewhere. Renumber it and add it to
// the new lists.
vertex->_index = new_index_vertices.size();
new_index_vertices.insert(IndexVertices::value_type(vertex->_index, vertex));
new_unique_vertices.insert(vertex);
// The vertex *is* used somewhere. Is it identical to an
// existing vertex?
UniqueVertices::iterator uvi;
uvi = new_unique_vertices.find(vertex);
if (uvi != new_unique_vertices.end()) {
// Yes, there's already another vertex just like this one.
// Redirect all the primitives currently referencing this
// vertex to reference the other one instead.
EggVertex *orig_vertex = (*uvi);
EggVertex::PrimitiveRef pref = vertex->_pref;
EggVertex::PrimitiveRef::iterator pi;
for (pi = pref.begin(); pi != pref.end(); ++pi) {
EggPrimitive *prim = (*pi);
EggPrimitive::iterator pvi = prim->find(vertex);
nassertr(pvi != prim->end(), 0);
prim->replace(pvi, orig_vertex);
}
vertex->test_pref_integrity();
orig_vertex->test_pref_integrity();
nassertr(vertex->pref_size() == 0, 0);
vertex->clear_grefs();
vertex->_pool = NULL;
num_removed++;
} else {
// It's a unique vertex. Renumber it and add it to the new
// lists.
vertex->_index = new_index_vertices.size();
new_index_vertices.insert(IndexVertices::value_type(vertex->_index, vertex));
new_unique_vertices.insert(vertex);
}
}
}

View File

@ -160,6 +160,7 @@ build_graph() {
// Clean up the vertices.
_data->clear_connected_shading();
_data->remove_unused_vertices(true);
_data->get_connected_shading();
_data->unify_attributes(true, true);
// Then bin up the polysets and LOD nodes.
@ -1462,7 +1463,7 @@ make_polyset(EggBin *egg_bin, PandaNode *parent) {
// Now that we've meshed, apply the per-prim attributes onto the
// vertices, so we can copy them to the GeomVertexData.
egg_bin->apply_first_attribute(false);
egg_bin->apply_last_attribute(false);
egg_bin->post_apply_flat_attribute(false);
vertex_pool->remove_unused_vertices();
@ -1482,7 +1483,7 @@ make_polyset(EggBin *egg_bin, PandaNode *parent) {
// Now convert the vertex pool to a GeomVertexData.
nassertr(vertex_pool != (EggVertexPool *)NULL, NULL);
PT(qpGeomVertexData) vertex_data =
make_vertex_data(vertex_pool, first_prim->get_vertex_to_node());
make_vertex_data(vertex_pool, egg_bin->get_vertex_to_node());
nassertr(vertex_data != (qpGeomVertexData *)NULL, NULL);
// And create a Geom to hold the primitives.
@ -1934,11 +1935,11 @@ make_vertex_data(EggVertexPool *vertex_pool, const LMatrix4d &transform) {
gvi.set_vertex(vertex->get_index());
gvi.set_data_type(InternalName::get_vertex());
gvi.set_data4(LCAST(float, vertex->get_pos4()));
gvi.set_data4(LCAST(float, vertex->get_pos4() * transform));
if (vertex->has_normal()) {
gvi.set_data_type(InternalName::get_normal());
gvi.set_data3(LCAST(float, vertex->get_normal()));
gvi.set_data3(LCAST(float, vertex->get_normal() * transform));
}
if (vertex->has_color()) {
@ -1986,12 +1987,12 @@ make_primitive(const EggRenderState *render_state, EggPrimitive *egg_prim,
if (primitive == (qpGeomPrimitive *)NULL) {
// Don't know how to make this kind of primitive.
egg2pg_cat.warning()
<< "Ignoring " << egg_prim->get_class_type() << "\n";
<< "Ignoring " << egg_prim->get_type() << "\n";
return;
}
if (render_state->_flat_shaded) {
primitive->set_shade_model(qpGeomPrimitive::SM_flat_first_vertex);
primitive->set_shade_model(qpGeomPrimitive::SM_flat_last_vertex);
} else if (egg_prim->get_shading() == EggPrimitive::S_overall) {
primitive->set_shade_model(qpGeomPrimitive::SM_uniform);

View File

@ -48,5 +48,20 @@ munge_format_impl(const qpGeomVertexFormat *orig) {
format = qpGeomVertexFormat::register_format(new_format);
}
/*
if (true) {
// Split out the interleaved array into n parallel arrays.
PT(qpGeomVertexFormat) new_format = new qpGeomVertexFormat;
for (int i = 0; i < format->get_num_data_types(); i++) {
const qpGeomVertexDataType *data_type = format->get_data_type(i);
PT(qpGeomVertexArrayFormat) new_array_format = new qpGeomVertexArrayFormat;
new_array_format->add_data_type(data_type->get_name(), data_type->get_num_components(),
data_type->get_numeric_type());
new_format->add_array(new_array_format);
}
format = qpGeomVertexFormat::register_format(new_format);
}
*/
return format;
}

View File

@ -2070,6 +2070,34 @@ draw_triangles(const qpGeomTriangles *primitive) {
report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CLP(GraphicsStateGuardian)::draw_tristrips
// Access: Public, Virtual
// Description: Draws a series of triangle strips.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_tristrips(const qpGeomTristrips *primitive) {
setup_antialias_polygon();
int min_vertex = primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
CPTA_ushort vertices = primitive->get_flat_last_vertices();
CPTA_int ends = primitive->get_ends();
int num_primitives = primitive->get_num_primitives();
int start = 0;
for (CPTA_int::const_iterator pi = ends.begin(); pi != ends.end(); ++pi) {
int end = (*pi);
_glDrawRangeElements(GL_TRIANGLE_STRIP,
min_vertex, max_vertex, end - start,
GL_UNSIGNED_SHORT, vertices + start);
start = end;
}
report_my_gl_errors();
}
////////////////////////////////////////////////////////////////////
// Function: CLP(GraphicsStateGuardian)::end_draw_primitives()
// Access: Public, Virtual

View File

@ -91,6 +91,7 @@ public:
virtual bool begin_draw_primitives(const qpGeomVertexData *vertex_data);
virtual void draw_triangles(const qpGeomTriangles *primitive);
virtual void draw_tristrips(const qpGeomTristrips *primitive);
virtual void end_draw_primitives();
INLINE bool draw_display_list(GeomContext *gc);

View File

@ -217,8 +217,7 @@ get_num_bytes() const {
void qpGeom::
munge_geom(const qpGeomMunger *munger,
CPT(qpGeom) &result, CPT(qpGeomVertexData) &data) const {
// Look up the format in our cache--maybe we've recently applied the
// indicated munger.
// Look up the munger in our cache--maybe we've recently applied it.
{
// Use read() and release_read() instead of CDReader, because the
// call to record_geom() might recursively call back into this
@ -249,7 +248,7 @@ munge_geom(const qpGeomMunger *munger,
data = munger->munge_data(get_vertex_data());
((qpGeomMunger *)munger)->munge_geom_impl(result, data);
if (result.p() != this) {
{
// Record the new result in the cache.
{
CDWriter cdata(((qpGeom *)this)->_cycler);

View File

@ -148,7 +148,6 @@ do_munge_format(const qpGeomVertexFormat *format) {
CPT(qpGeomVertexData) qpGeomMunger::
do_munge_data(const qpGeomVertexData *data) {
nassertr(_is_registered, NULL);
PStatTimer timer(_munge_pcollector);
CPT(qpGeomVertexFormat) orig_format = data->get_format();
CPT(qpGeomVertexFormat) new_format = munge_format(orig_format);

View File

@ -24,6 +24,9 @@
TypeHandle qpGeomVertexData::_type_handle;
// Temporarily not a member of the class.
static PStatCollector _munge_pcollector("Cull:Munge:Data");
////////////////////////////////////////////////////////////////////
// Function: qpGeomVertexData::Default Constructor
// Access: Private
@ -301,6 +304,7 @@ convert_to(const qpGeomVertexFormat *new_format) const {
gobj_cat.debug()
<< "Converting " << num_vertices << " vertices.\n";
}
PStatTimer timer(_munge_pcollector);
PT(qpGeomVertexData) new_data = new qpGeomVertexData(new_format);