egg loader optimizations; directx vbuffer support

This commit is contained in:
David Rose 2005-03-20 18:47:52 +00:00
parent 0bcbaa6056
commit 720fddb73b
16 changed files with 454 additions and 82 deletions

View File

@ -570,7 +570,6 @@ build_geoms(InputIterator first, InputIterator last,
InputIterator i;
for (i = first; i != last; ++i) {
// Normals.
// Test rule 1.

View File

@ -55,6 +55,7 @@ operator = (const BuilderPrimTempl<VTX> &copy) {
DAttrib::operator = (copy);
_verts = copy._verts;
_components = copy._components;
_texcoord_names = copy._texcoord_names;
_type = copy._type;
_overall = copy._overall;
@ -334,6 +335,9 @@ has_any_pixel_size() const {
template <class VTX>
INLINE TYPENAME BuilderPrimTempl<VTX>::tcn_const_iterator BuilderPrimTempl<VTX>::
tcn_begin() const {
if ((_overall & BAF_overall_updated) == 0) {
((BuilderPrimTempl<VTX> *)this)->update_overall_attrib();
}
return _texcoord_names.begin();
}
@ -347,6 +351,9 @@ tcn_begin() const {
template <class VTX>
INLINE TYPENAME BuilderPrimTempl<VTX>::tcn_const_iterator BuilderPrimTempl<VTX>::
tcn_end() const {
if ((_overall & BAF_overall_updated) == 0) {
((BuilderPrimTempl<VTX> *)this)->update_overall_attrib();
}
return _texcoord_names.end();
}
@ -359,6 +366,9 @@ tcn_end() const {
template <class VTX>
INLINE TYPENAME BuilderPrimTempl<VTX>::tcn_size_type BuilderPrimTempl<VTX>::
tcn_size() const {
if ((_overall & BAF_overall_updated) == 0) {
((BuilderPrimTempl<VTX> *)this)->update_overall_attrib();
}
return _texcoord_names.size();
}

View File

@ -21,6 +21,7 @@
#define INSTALL_HEADERS \
dxgsg8base.h config_dxgsg8.h dxGraphicsStateGuardian8.I dxGraphicsStateGuardian8.h \
dxVertexBufferContext8.h \
dxIndexBufferContext8.h \
dxTextureContext8.h \
dxGeomMunger8.h \
d3dfont8.h \
@ -38,6 +39,7 @@
#define INCLUDED_SOURCES \
config_dxgsg8.cxx \
dxVertexBufferContext8.cxx \
dxIndexBufferContext8.cxx \
dxTextureContext8.cxx \
dxGeomMunger8.cxx \
d3dfont8.cxx \

View File

@ -20,6 +20,7 @@
#include "dxGraphicsStateGuardian8.h"
#include "dxTextureContext8.h"
#include "dxVertexBufferContext8.h"
#include "dxIndexBufferContext8.h"
#include "dxGeomMunger8.h"
#include "graphicsPipeSelection.h"
#include "wdxGraphicsWindow8.h"
@ -146,6 +147,7 @@ init_libdxgsg8() {
DXGraphicsStateGuardian8::init_type();
DXTextureContext8::init_type();
DXVertexBufferContext8::init_type();
DXIndexBufferContext8::init_type();
DXGeomMunger8::init_type();
wdxGraphicsPipe8::init_type();

View File

@ -57,6 +57,7 @@
#include "dxGeomMunger8.h"
#include "config_gobj.h"
#include "dxVertexBufferContext8.h"
#include "dxIndexBufferContext8.h"
#ifdef DO_PSTATS
#include "pStatTimer.h"
@ -2634,7 +2635,11 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_triangles(const qpGeomTriangles *primitive) {
if (_vbuffer_active && _ibuffer_active) {
if (_vbuffer_active) {
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
_pD3DDevice->DrawIndexedPrimitive
(D3DPT_TRIANGLELIST,
primitive->get_min_vertex(),
@ -2669,19 +2674,36 @@ draw_tristrips(const qpGeomTristrips *primitive) {
CPTA_ushort maxs = primitive->get_maxs();
nassertv(mins.size() == ends.size() && maxs.size() == ends.size());
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
if (_vbuffer_active) {
IndexBufferContext *ibc = ((qpGeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
_pD3DDevice->DrawIndexedPrimitiveUP
(D3DPT_TRIANGLESTRIP,
mins[i], maxs[i] - mins[i] + 1,
ends[i] - start - 2,
vertices + start, D3DFMT_INDEX16,
array_data, stride);
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
_pD3DDevice->DrawIndexedPrimitive
(D3DPT_TRIANGLESTRIP,
mins[i], maxs[i] - mins[i] + 1,
start, ends[i] - start - 2);
start = ends[i];
start = ends[i];
}
} else {
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
_pD3DDevice->DrawIndexedPrimitiveUP
(D3DPT_TRIANGLESTRIP,
mins[i], maxs[i] - mins[i] + 1,
ends[i] - start - 2,
vertices + start, D3DFMT_INDEX16,
array_data, stride);
start = ends[i];
}
}
}
@ -2914,7 +2936,7 @@ release_texture(TextureContext *tc) {
// will also delete the pointer).
//
// This function should not be called directly to
// prepare a data. Instead, call Data::prepare().
// prepare a buffer. Instead, call Geom::prepare().
////////////////////////////////////////////////////////////////////
VertexBufferContext *DXGraphicsStateGuardian8::
prepare_vertex_buffer(qpGeomVertexArrayData *data) {
@ -2994,6 +3016,93 @@ release_vertex_buffer(VertexBufferContext *vbc) {
delete dvbc;
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::prepare_index_buffer
// Access: Public, Virtual
// Description: Creates a new retained-mode representation of the
// given data, and returns a newly-allocated
// IndexBufferContext pointer to reference it. It is the
// responsibility of the calling function to later call
// release_index_buffer() with this same pointer (which
// will also delete the pointer).
//
// This function should not be called directly to
// prepare a buffer. Instead, call Geom::prepare().
////////////////////////////////////////////////////////////////////
IndexBufferContext *DXGraphicsStateGuardian8::
prepare_index_buffer(qpGeomPrimitive *data) {
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug()
<< "prepare_index_buffer(" << (void *)data << ")\n";
}
DXIndexBufferContext8 *dibc = new DXIndexBufferContext8(data);
dibc->create_ibuffer(*_pScrn);
dibc->mark_loaded();
return dibc;
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::apply_index_buffer
// Access: Public
// Description: Makes the data the currently available data for
// rendering.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
apply_index_buffer(IndexBufferContext *ibc) {
DXIndexBufferContext8 *dibc = DCAST(DXIndexBufferContext8, ibc);
if (dibc->_ibuffer != NULL) {
add_to_index_buffer_record(dibc);
if (dibc->was_modified()) {
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug()
<< "apply_index_buffer(" << (void *)ibc->get_data() << ")\n";
}
if (dibc->changed_size()) {
// Here we have to destroy the old index buffer and create a
// new one.
dibc->create_ibuffer(*_pScrn);
} else {
// Here we just copy the new data to the index buffer.
dibc->upload_data();
}
dibc->mark_loaded();
}
_pD3DDevice->SetIndices(dibc->_ibuffer, 0);
_ibuffer_active = true;
} else {
_pD3DDevice->SetIndices(NULL, 0);
_ibuffer_active = false;
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::release_index_buffer
// Access: Public, Virtual
// Description: Frees the GL resources previously allocated for the
// data. This function should never be called
// directly; instead, call Data::release() (or simply
// let the Data destruct).
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
release_index_buffer(IndexBufferContext *ibc) {
if (dxgsg8_cat.is_debug()) {
dxgsg8_cat.debug()
<< "release_index_buffer(" << (void *)ibc->get_data() << ")\n";
}
DXIndexBufferContext8 *dibc = DCAST(DXIndexBufferContext8, ibc);
delete dibc;
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian8::get_geom_munger
// Access: Public, Virtual

View File

@ -103,6 +103,10 @@ public:
void apply_vertex_buffer(VertexBufferContext *vbc);
virtual void release_vertex_buffer(VertexBufferContext *vbc);
virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data);
void apply_index_buffer(IndexBufferContext *ibc);
virtual void release_index_buffer(IndexBufferContext *ibc);
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,

View File

@ -0,0 +1,18 @@
// Filename: dxIndexBufferContext8.I
// Created by: drose (18Mar05)
//
////////////////////////////////////////////////////////////////////
//
// 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,100 @@
// Filename: dxIndexBufferContext8.cxx
// Created by: drose (18Mar05)
//
////////////////////////////////////////////////////////////////////
//
// 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 "dxIndexBufferContext8.h"
#include "qpgeomPrimitive.h"
#include "config_dxgsg8.h"
#include <d3dx8.h>
TypeHandle DXIndexBufferContext8::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: DXIndexBufferContext8::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
DXIndexBufferContext8::
DXIndexBufferContext8(qpGeomPrimitive *data) :
IndexBufferContext(data),
_ibuffer(NULL)
{
}
////////////////////////////////////////////////////////////////////
// Function: DXIndexBufferContext8::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
DXIndexBufferContext8::
~DXIndexBufferContext8() {
if (_ibuffer != NULL) {
RELEASE(_ibuffer, dxgsg8, "index buffer", RELEASE_ONCE);
_ibuffer = NULL;
}
}
////////////////////////////////////////////////////////////////////
// Function: DXIndexBufferContext8::create_ibuffer
// Access: Public
// Description: Creates a new index buffer and uploads data to it.
////////////////////////////////////////////////////////////////////
void DXIndexBufferContext8::
create_ibuffer(DXScreenData &scrn) {
if (_ibuffer != NULL) {
RELEASE(_ibuffer, dxgsg8, "index buffer", RELEASE_ONCE);
_ibuffer = NULL;
}
HRESULT hr = scrn.pD3DDevice->CreateIndexBuffer
(get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16, D3DPOOL_MANAGED, &_ibuffer);
if (FAILED(hr)) {
dxgsg8_cat.warning()
<< "CreateIndexBuffer failed" << D3DERRORSTRING(hr);
_ibuffer = NULL;
} else {
upload_data();
}
}
////////////////////////////////////////////////////////////////////
// Function: DXIndexBufferContext8::upload_data
// Access: Public
// Description: Copies the latest data from the client store to
// DirectX.
////////////////////////////////////////////////////////////////////
void DXIndexBufferContext8::
upload_data() {
nassertv(_ibuffer != NULL);
int data_size = get_data()->get_data_size_bytes();
BYTE *local_pointer;
HRESULT hr = _ibuffer->Lock(0, data_size, &local_pointer, 0);
if (FAILED(hr)) {
dxgsg8_cat.error()
<< "IndexBuffer::Lock failed" << D3DERRORSTRING(hr);
return;
}
memcpy(local_pointer, get_data()->get_flat_first_vertices(), data_size);
_ibuffer->Unlock();
}

View File

@ -0,0 +1,63 @@
// Filename: dxIndexBufferContext8.h
// Created by: drose (18Mar05)
//
////////////////////////////////////////////////////////////////////
//
// 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 DXINDEXBUFFERCONTEXT8_H
#define DXINDEXBUFFERCONTEXT8_H
#include "pandabase.h"
#include "dxgsg8base.h"
#include "indexBufferContext.h"
////////////////////////////////////////////////////////////////////
// Class : DXIndexBufferContext8
// Description : Caches a GeomPrimitive in the DirectX device as
// an index buffer.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDADX DXIndexBufferContext8 : public IndexBufferContext {
public:
DXIndexBufferContext8(qpGeomPrimitive *data);
virtual ~DXIndexBufferContext8();
void create_ibuffer(DXScreenData &scrn);
void upload_data();
IDirect3DIndexBuffer8 *_ibuffer;
public:
static TypeHandle get_class_type() {
return _type_handle;
}
static void init_type() {
IndexBufferContext::init_type();
register_type(_type_handle, "DXIndexBufferContext8",
IndexBufferContext::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 "dxIndexBufferContext8.I"
#endif

View File

@ -2,6 +2,7 @@
#include "config_dxgsg8.cxx"
#include "dxTextureContext8.cxx"
#include "dxVertexBufferContext8.cxx"
#include "dxIndexBufferContext8.cxx"
#include "dxGeomMunger8.cxx"
#include "d3dfont8.cxx"
#include "wdxGraphicsPipe8.cxx"

View File

@ -31,7 +31,7 @@ TypeHandle EggPrimitive::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: EggPrimitive::determine_alpha_mode
// Access: Published, Virtual
// Description: Walks back up the hierarchy, looking for an EggPrimitive
// Description: Walks back up the hierarchy, looking for an EggGroup
// or EggPrimitive or some such object at this level or
// above this primitive that has an alpha_mode other than
// AM_unspecified. Returns a valid EggRenderMode pointer
@ -139,7 +139,7 @@ determine_visibility_mode() {
////////////////////////////////////////////////////////////////////
// Function: EggPrimitive::determine_draw_order
// Access: Published, Virtual
// Description: Walks back up the hierarchy, looking for an EggPrimitive
// Description: Walks back up the hierarchy, looking for an EggGroup
// or EggPrimitive or some such object at this level or
// above this primitive that has a draw_order specified.
// Returns a valid EggRenderMode pointer if one is found,
@ -166,7 +166,7 @@ determine_draw_order() {
////////////////////////////////////////////////////////////////////
// Function: EggPrimitive::determine_bin
// Access: Published, Virtual
// Description: Walks back up the hierarchy, looking for an EggPrimitive
// Description: Walks back up the hierarchy, looking for an EggGroup
// or EggPrimitive or some such object at this level or
// above this primitive that has a bin specified. Returns a
// valid EggRenderMode pointer if one is found, or NULL

View File

@ -42,16 +42,3 @@ operator < (const PrimitiveUnifier &other) const {
}
return _shade_model < other._shade_model;
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::VertexPoolTransform::operator <
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool EggLoader::VertexPoolTransform::
operator < (const EggLoader::VertexPoolTransform &other) const {
if (_vertex_pool != other._vertex_pool) {
return _vertex_pool < other._vertex_pool;
}
return _transform.compare_to(other._transform, 0.001) < 0;
}

View File

@ -154,7 +154,13 @@ void EggLoader::
build_graph() {
_deferred_nodes.clear();
// First, load up all of the textures.
// Expand all of the ObjectType flags before we do anything else;
// that might prune out large portions of the scene.
if (!expand_all_object_types(_data)) {
return;
}
// Now, load up all of the textures.
load_textures();
// Clean up the vertices.
@ -1483,7 +1489,8 @@ 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, egg_bin->get_vertex_to_node());
make_vertex_data(render_state, vertex_pool,
egg_bin->get_vertex_to_node());
nassertr(vertex_data != (qpGeomVertexData *)NULL, NULL);
// And create a Geom to hold the primitives.
@ -1565,7 +1572,6 @@ make_lod(EggBin *egg_bin, PandaNode *parent) {
return create_group_arc(egg_bin, parent, lod_node);
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::make_node (EggGroup)
// Access: Private
@ -1575,14 +1581,6 @@ PandaNode *EggLoader::
make_node(EggGroup *egg_group, PandaNode *parent) {
PT(PandaNode) node = NULL;
if (egg_group->get_num_object_types() != 0) {
pset<string> expanded;
pvector<string> expanded_history;
if (!expand_object_types(egg_group, expanded, expanded_history)) {
return NULL;
}
}
if (egg_group->get_dart_type() != EggGroup::DT_none) {
// A group with the <Dart> flag set means to create a character.
CharacterMaker char_maker(egg_group, *this);
@ -1865,7 +1863,10 @@ check_for_polysets(EggGroup *egg_group, bool &all_polysets, bool &any_hidden) {
all_polysets = false;
return;
}
} else {
} else if ((*ci)->is_of_type(EggGroup::get_class_type())) {
// Other kinds of children, like vertex pools, comments,
// textures, etc., are ignored; but groups indicate more nodes,
// so if we find a nested group it means we're not all polysets.
all_polysets = false;
return;
}
@ -1881,9 +1882,11 @@ check_for_polysets(EggGroup *egg_group, bool &all_polysets, bool &any_hidden) {
// transform, just returns it.
////////////////////////////////////////////////////////////////////
PT(qpGeomVertexData) EggLoader::
make_vertex_data(EggVertexPool *vertex_pool, const LMatrix4d &transform) {
make_vertex_data(const EggRenderState *render_state,
EggVertexPool *vertex_pool, const LMatrix4d &transform) {
VertexPoolTransform vpt;
vpt._vertex_pool = vertex_pool;
vpt._bake_in_uvs = render_state->_bake_in_uvs;
vpt._transform = transform;
VertexPoolData::iterator di;
@ -1916,9 +1919,8 @@ make_vertex_data(EggVertexPool *vertex_pool, const LMatrix4d &transform) {
if (name == "default") {
name = string();
}
array_format->add_data_type
(InternalName::get_texcoord_name(name), 2,
qpGeomVertexDataType::NT_float);
PT(InternalName) iname = InternalName::get_texcoord_name(name);
array_format->add_data_type(iname, 2, qpGeomVertexDataType::NT_float);
}
CPT(qpGeomVertexFormat) format =
@ -1950,13 +1952,23 @@ make_vertex_data(EggVertexPool *vertex_pool, const LMatrix4d &transform) {
EggVertex::const_uv_iterator uvi;
for (uvi = vertex->uv_begin(); uvi != vertex->uv_end(); ++uvi) {
EggVertexUV *uv = (*uvi);
string name = uv->get_name();
EggVertexUV *egg_uv = (*uvi);
TexCoordd uv = egg_uv->get_uv();
string name = egg_uv->get_name();
if (name == "default") {
name = string();
}
gvi.set_data_type(InternalName::get_texcoord_name(name));
gvi.set_data2(LCAST(float, uv->get_uv()));
PT(InternalName) iname = InternalName::get_texcoord_name(name);
gvi.set_data_type(iname);
BakeInUVs::const_iterator buv = render_state->_bake_in_uvs.find(iname);
if (buv != render_state->_bake_in_uvs.end()) {
// If we are to bake in a texture matrix, do so now.
uv = uv * (*buv).second->get_transform();
}
gvi.set_data2(LCAST(float, uv));
}
}
@ -2736,6 +2748,52 @@ apply_deferred_nodes(PandaNode *node, const DeferredNodeProperty &prop) {
}
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::expand_all_object_types
// Access: Private
// Description: Walks the hierarchy and calls expand_object_types()
// on each node, to expand all of the ObjectType
// definitions in the file at once. Also prunes any
// nodes that are flagged "backstage".
//
// The return value is true if this node should be kept,
// false if it should be pruned.
////////////////////////////////////////////////////////////////////
bool EggLoader::
expand_all_object_types(EggNode *egg_node) {
if (egg_node->is_of_type(EggGroup::get_class_type())) {
EggGroup *egg_group = DCAST(EggGroup, egg_node);
if (egg_group->get_num_object_types() != 0) {
pset<string> expanded;
pvector<string> expanded_history;
if (!expand_object_types(egg_group, expanded, expanded_history)) {
return false;
}
}
}
// Now recurse on children, and we might prune children from this
// list as we go.
if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
EggGroupNode *egg_group_node = DCAST(EggGroupNode, egg_node);
EggGroupNode::const_iterator ci;
ci = egg_group_node->begin();
while (ci != egg_group_node->end()) {
EggGroupNode::const_iterator cnext = ci;
++cnext;
if (!expand_all_object_types(*ci)) {
// Prune this child.
egg_group_node->erase(ci);
}
ci = cnext;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::expand_object_types
// Access: Private
@ -2797,7 +2855,7 @@ expand_object_types(EggGroup *egg_group, const pset<string> &expanded,
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::expand_object_type
// Function: EggLoader::do_expand_object_types
// Access: Private
// Description: Further implementation of expand_object_types().
////////////////////////////////////////////////////////////////////
@ -3093,5 +3151,37 @@ get_combine_operand(const EggTexture *egg_tex,
return TextureStage::CO_undefined;
}
////////////////////////////////////////////////////////////////////
// Function: EggLoader::VertexPoolTransform::operator <
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool EggLoader::VertexPoolTransform::
operator < (const EggLoader::VertexPoolTransform &other) const {
if (_vertex_pool != other._vertex_pool) {
return _vertex_pool < other._vertex_pool;
}
int compare = _transform.compare_to(other._transform, 0.001);
if (compare != 0) {
return compare < 0;
}
if (_bake_in_uvs.size() != other._bake_in_uvs.size()) {
return _bake_in_uvs.size() < other._bake_in_uvs.size();
}
BakeInUVs::const_iterator ai, bi;
ai = _bake_in_uvs.begin();
bi = other._bake_in_uvs.begin();
while (ai != _bake_in_uvs.end()) {
nassertr(bi != other._bake_in_uvs.end(), false);
if ((*ai) != (*bi)) {
return (*ai) < (*bi);
}
++ai;
++bi;
}
nassertr(bi == other._bake_in_uvs.end(), false);
return false;
}

View File

@ -137,7 +137,8 @@ private:
void check_for_polysets(EggGroup *egg_group, bool &all_polysets,
bool &any_hidden);
PT(qpGeomVertexData) make_vertex_data(EggVertexPool *vertex_pool,
PT(qpGeomVertexData) make_vertex_data(const EggRenderState *render_state,
EggVertexPool *vertex_pool,
const LMatrix4d &transform);
void make_primitive(const EggRenderState *render_state,
EggPrimitive *egg_prim, Primitives &primitives);
@ -173,6 +174,7 @@ private:
EggGroup::CollideFlags flags);
void apply_deferred_nodes(PandaNode *node, const DeferredNodeProperty &prop);
bool expand_all_object_types(EggNode *egg_node);
bool expand_object_types(EggGroup *egg_group, const pset<string> &expanded,
const pvector<string> &expanded_history);
bool do_expand_object_type(EggGroup *egg_group, const pset<string> &expanded,
@ -207,8 +209,9 @@ private:
class VertexPoolTransform {
public:
INLINE bool operator < (const VertexPoolTransform &other) const;
bool operator < (const VertexPoolTransform &other) const;
PT(EggVertexPool) _vertex_pool;
BakeInUVs _bake_in_uvs;
LMatrix4d _transform;
};
typedef pmap<VertexPoolTransform, PT(qpGeomVertexData) > VertexPoolData;

View File

@ -188,7 +188,7 @@ fill_state(EggPrimitive *egg_prim) {
const InternalName *uv_name = (*tmi).first;
const TexMatTransforms &tmt = (*tmi).second;
if (tmt.size() == 1 && !needs_tex_mat && !use_qpgeom) {
if (tmt.size() == 1 && !needs_tex_mat) {
// Only one unique transform sharing this set of UV's. We can
// bake in the transform!
const TexMatTextures &tmtex = (*tmt.begin()).second;
@ -346,8 +346,6 @@ fill_state(EggPrimitive *egg_prim) {
if (use_qpgeom) {
if (_flat_shaded) {
add_attrib(ShadeModelAttrib::make(ShadeModelAttrib::M_flat));
} else {
add_attrib(ShadeModelAttrib::make(ShadeModelAttrib::M_smooth));
}
}

View File

@ -2031,8 +2031,6 @@ draw_sphere(GeomSphere *geom, GeomContext *gc) {
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
DO_PSTATS_STUFF(_draw_primitive_pcollector.start());
if (!GraphicsStateGuardian::begin_draw_primitives(geom, vertex_data)) {
return false;
}
@ -2095,8 +2093,7 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
GLP(EnableClientState)(GL_VERTEX_ARRAY);
}
if (wants_normals() &&
_vertex_data->get_array_info(InternalName::get_normal(),
if (_vertex_data->get_array_info(InternalName::get_normal(),
array_data, num_components, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
@ -2107,27 +2104,18 @@ begin_draw_primitives(const qpGeom *geom, const qpGeomVertexData *vertex_data) {
GLP(DisableClientState)(GL_NORMAL_ARRAY);
}
if (wants_colors()) {
if (_vertex_data->get_array_info(InternalName::get_color(),
array_data, num_components, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
stride, client_pointer + start);
GLP(EnableClientState)(GL_COLOR_ARRAY);
} else {
// We wanted colors, but the geom didn't have any; just issue
// white.
GLP(Color4f)(1.0f, 1.0f, 1.0f, 1.0f);
GLP(DisableClientState)(GL_COLOR_ARRAY);
}
if (_vertex_data->get_array_info(InternalName::get_color(),
array_data, num_components, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
GLP(ColorPointer)(num_components, get_numeric_type(numeric_type),
stride, client_pointer + start);
GLP(EnableClientState)(GL_COLOR_ARRAY);
} else {
GLP(DisableClientState)(GL_COLOR_ARRAY);
}
if (wants_texcoords() &&
_vertex_data->get_array_info(InternalName::get_texcoord(),
if (_vertex_data->get_array_info(InternalName::get_texcoord(),
array_data, num_components, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
@ -2209,8 +2197,6 @@ end_draw_primitives() {
_geom_display_list = NULL;
GraphicsStateGuardian::end_draw_primitives();
DO_PSTATS_STUFF(_draw_primitive_pcollector.stop());
}
////////////////////////////////////////////////////////////////////
@ -2426,7 +2412,7 @@ release_geom(GeomContext *gc) {
// will also delete the pointer).
//
// This function should not be called directly to
// prepare a data. Instead, call Data::prepare().
// prepare a buffer. Instead, call Geom::prepare().
////////////////////////////////////////////////////////////////////
VertexBufferContext *CLP(GraphicsStateGuardian)::
prepare_vertex_buffer(qpGeomVertexArrayData *data) {
@ -2557,7 +2543,7 @@ setup_array_data(const qpGeomVertexArrayData *data) {
// will also delete the pointer).
//
// This function should not be called directly to
// prepare a data. Instead, call Data::prepare().
// prepare a buffer. Instead, call Geom::prepare().
////////////////////////////////////////////////////////////////////
IndexBufferContext *CLP(GraphicsStateGuardian)::
prepare_index_buffer(qpGeomPrimitive *data) {