mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
egg loader optimizations; directx vbuffer support
This commit is contained in:
parent
0bcbaa6056
commit
720fddb73b
@ -570,7 +570,6 @@ build_geoms(InputIterator first, InputIterator last,
|
||||
|
||||
InputIterator i;
|
||||
for (i = first; i != last; ++i) {
|
||||
|
||||
// Normals.
|
||||
|
||||
// Test rule 1.
|
||||
|
@ -55,6 +55,7 @@ operator = (const BuilderPrimTempl<VTX> ©) {
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
18
panda/src/dxgsg8/dxIndexBufferContext8.I
Normal file
18
panda/src/dxgsg8/dxIndexBufferContext8.I
Normal 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
100
panda/src/dxgsg8/dxIndexBufferContext8.cxx
Normal file
100
panda/src/dxgsg8/dxIndexBufferContext8.cxx
Normal 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();
|
||||
}
|
||||
|
63
panda/src/dxgsg8/dxIndexBufferContext8.h
Normal file
63
panda/src/dxgsg8/dxIndexBufferContext8.h
Normal 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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user