ibuffers as well as vbuffers
This commit is contained in:
parent
7a305f825f
commit
dbed74e410
|
|
@ -20,7 +20,8 @@
|
|||
#include "graphicsStateGuardian.h"
|
||||
#include "config_display.h"
|
||||
#include "textureContext.h"
|
||||
#include "dataContext.h"
|
||||
#include "vertexBufferContext.h"
|
||||
#include "indexBufferContext.h"
|
||||
#include "renderBuffer.h"
|
||||
#include "colorAttrib.h"
|
||||
#include "colorScaleAttrib.h"
|
||||
|
|
@ -48,7 +49,8 @@ PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage
|
|||
PStatCollector GraphicsStateGuardian::_total_geom_pcollector("Prepared Geoms");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_pcollector("Prepared Geoms:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffers_pcollector("Vertex buffers");
|
||||
PStatCollector GraphicsStateGuardian::_active_buffers_pcollector("Vertex buffers:Active");
|
||||
PStatCollector GraphicsStateGuardian::_active_vertex_buffers_pcollector("Vertex buffers:Active vertex");
|
||||
PStatCollector GraphicsStateGuardian::_active_index_buffers_pcollector("Vertex buffers:Active index");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_node_pcollector("Prepared GeomNodes");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_node_pcollector("Prepared GeomNodes:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory");
|
||||
|
|
@ -271,25 +273,47 @@ release_geom(GeomContext *) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::prepare_data
|
||||
// Function: GraphicsStateGuardian::prepare_vertex_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Prepares the indicated data array for retained-mode
|
||||
// Description: Prepares the indicated buffer for retained-mode
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *GraphicsStateGuardian::
|
||||
prepare_data(qpGeomVertexArrayData *) {
|
||||
return (DataContext *)NULL;
|
||||
VertexBufferContext *GraphicsStateGuardian::
|
||||
prepare_vertex_buffer(qpGeomVertexArrayData *) {
|
||||
return (VertexBufferContext *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::release_data
|
||||
// Function: GraphicsStateGuardian::release_vertex_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Frees the resources previously allocated via a call
|
||||
// to prepare_data(), including deleting the DataContext
|
||||
// itself, if necessary.
|
||||
// to prepare_data(), including deleting the
|
||||
// VertexBufferContext itself, if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
release_data(DataContext *) {
|
||||
release_vertex_buffer(VertexBufferContext *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::prepare_index_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Prepares the indicated buffer for retained-mode
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
IndexBufferContext *GraphicsStateGuardian::
|
||||
prepare_index_buffer(qpGeomPrimitive *) {
|
||||
return (IndexBufferContext *)NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::release_index_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Frees the resources previously allocated via a call
|
||||
// to prepare_data(), including deleting the
|
||||
// IndexBufferContext itself, if necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
release_index_buffer(IndexBufferContext *) {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1443,11 +1467,13 @@ init_frame_pstats() {
|
|||
if (PStatClient::is_connected()) {
|
||||
_current_textures.clear();
|
||||
_current_geoms.clear();
|
||||
_current_datas.clear();
|
||||
_current_vertex_buffers.clear();
|
||||
_current_index_buffers.clear();
|
||||
_active_texusage_pcollector.clear_level();
|
||||
_active_geom_pcollector.clear_level();
|
||||
_active_geom_node_pcollector.clear_level();
|
||||
_active_buffers_pcollector.clear_level();
|
||||
_active_vertex_buffers_pcollector.clear_level();
|
||||
_active_index_buffers_pcollector.clear_level();
|
||||
|
||||
// Also clear out our other counters while we're here.
|
||||
_vertices_tristrip_pcollector.clear_level();
|
||||
|
|
@ -1498,21 +1524,42 @@ add_to_geom_record(GeomContext *gc) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_data_record
|
||||
// Function: GraphicsStateGuardian::add_to_vertex_buffer_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been drawn
|
||||
// this frame. This function is only used to update the
|
||||
// PStats active_buffers collector; it gets compiled out
|
||||
// PStats active_vertex_buffers collector; it gets compiled out
|
||||
// if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_data_record(DataContext *dc) {
|
||||
if (dc != (DataContext *)NULL) {
|
||||
int delta = dc->get_data()->get_num_bytes() - dc->get_num_bytes();
|
||||
add_to_vertex_buffer_record(VertexBufferContext *vbc) {
|
||||
if (vbc != (VertexBufferContext *)NULL) {
|
||||
int delta = vbc->get_data()->get_data_size_bytes() - vbc->get_data_size_bytes();
|
||||
_total_buffers_pcollector.add_level(delta);
|
||||
if (PStatClient::is_connected()) {
|
||||
if (_current_datas.insert(dc).second) {
|
||||
_active_buffers_pcollector.add_level(dc->get_data()->get_num_bytes());
|
||||
if (_current_vertex_buffers.insert(vbc).second) {
|
||||
_active_vertex_buffers_pcollector.add_level(vbc->get_data()->get_data_size_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::add_to_index_buffer_record
|
||||
// Access: Protected
|
||||
// Description: Records that the indicated data array has been drawn
|
||||
// this frame. This function is only used to update the
|
||||
// PStats active_index_buffers collector; it gets compiled out
|
||||
// if we aren't using PStats.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
add_to_index_buffer_record(IndexBufferContext *ibc) {
|
||||
if (ibc != (IndexBufferContext *)NULL) {
|
||||
int delta = ibc->get_data()->get_data_size_bytes() - ibc->get_data_size_bytes();
|
||||
_total_buffers_pcollector.add_level(delta);
|
||||
if (PStatClient::is_connected()) {
|
||||
if (_current_index_buffers.insert(ibc).second) {
|
||||
_active_index_buffers_pcollector.add_level(ibc->get_data()->get_data_size_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,8 +107,11 @@ public:
|
|||
virtual GeomContext *prepare_geom(Geom *geom);
|
||||
virtual void release_geom(GeomContext *gc);
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data);
|
||||
virtual void release_data(DataContext *gc);
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(qpGeomVertexArrayData *data);
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data);
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
|
|
@ -226,11 +229,13 @@ protected:
|
|||
void init_frame_pstats();
|
||||
void add_to_texture_record(TextureContext *tc);
|
||||
void add_to_geom_record(GeomContext *gc);
|
||||
void add_to_data_record(DataContext *dc);
|
||||
void add_to_vertex_buffer_record(VertexBufferContext *vbc);
|
||||
void add_to_index_buffer_record(IndexBufferContext *ibc);
|
||||
|
||||
pset<TextureContext *> _current_textures;
|
||||
pset<GeomContext *> _current_geoms;
|
||||
pset<DataContext *> _current_datas;
|
||||
pset<VertexBufferContext *> _current_vertex_buffers;
|
||||
pset<IndexBufferContext *> _current_index_buffers;
|
||||
#else
|
||||
INLINE void init_frame_pstats() { }
|
||||
INLINE void add_to_texture_record(TextureContext *) { }
|
||||
|
|
@ -314,7 +319,8 @@ public:
|
|||
static PStatCollector _total_geom_pcollector;
|
||||
static PStatCollector _active_geom_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
static PStatCollector _active_buffers_pcollector;
|
||||
static PStatCollector _active_vertex_buffers_pcollector;
|
||||
static PStatCollector _active_index_buffers_pcollector;
|
||||
static PStatCollector _total_geom_node_pcollector;
|
||||
static PStatCollector _active_geom_node_pcollector;
|
||||
static PStatCollector _total_texmem_pcollector;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@
|
|||
// need to install these due to external projects that link directly with libpandadx (bartop)
|
||||
#define INSTALL_HEADERS \
|
||||
dxgsg8base.h config_dxgsg8.h dxGraphicsStateGuardian8.I dxGraphicsStateGuardian8.h \
|
||||
dxDataContext8.h \
|
||||
dxVertexBufferContext8.h \
|
||||
dxTextureContext8.h \
|
||||
dxGeomMunger8.h \
|
||||
d3dfont8.h \
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_dxgsg8.cxx \
|
||||
dxDataContext8.cxx \
|
||||
dxVertexBufferContext8.cxx \
|
||||
dxTextureContext8.cxx \
|
||||
dxGeomMunger8.cxx \
|
||||
d3dfont8.cxx \
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
#include "config_dxgsg8.h"
|
||||
#include "dxGraphicsStateGuardian8.h"
|
||||
#include "dxTextureContext8.h"
|
||||
#include "dxDataContext8.h"
|
||||
#include "dxVertexBufferContext8.h"
|
||||
#include "dxGeomMunger8.h"
|
||||
#include "graphicsPipeSelection.h"
|
||||
#include "wdxGraphicsWindow8.h"
|
||||
|
|
@ -145,7 +145,7 @@ init_libdxgsg8() {
|
|||
|
||||
DXGraphicsStateGuardian8::init_type();
|
||||
DXTextureContext8::init_type();
|
||||
DXDataContext8::init_type();
|
||||
DXVertexBufferContext8::init_type();
|
||||
DXGeomMunger8::init_type();
|
||||
|
||||
wdxGraphicsPipe8::init_type();
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
#include "qpgeomTrifans.h"
|
||||
#include "dxGeomMunger8.h"
|
||||
#include "config_gobj.h"
|
||||
#include "dxDataContext8.h"
|
||||
#include "dxVertexBufferContext8.h"
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
#include "pStatTimer.h"
|
||||
|
|
@ -2620,8 +2620,8 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
|||
// the first array.
|
||||
const qpGeomVertexArrayData *data = _vertex_data->get_array(0);
|
||||
|
||||
DataContext *dc = ((qpGeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(dc != (DataContext *)NULL, false);
|
||||
VertexBufferContext *dc = ((qpGeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(dc != (VertexBufferContext *)NULL, false);
|
||||
apply_data(dc);
|
||||
|
||||
return true;
|
||||
|
|
@ -2903,79 +2903,79 @@ release_texture(TextureContext *tc) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::prepare_data
|
||||
// Function: DXGraphicsStateGuardian8::prepare_vertex_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Creates a new retained-mode representation of the
|
||||
// given data, and returns a newly-allocated
|
||||
// DataContext pointer to reference it. It is the
|
||||
// VertexBufferContext pointer to reference it. It is the
|
||||
// responsibility of the calling function to later
|
||||
// call release_data() with this same pointer (which
|
||||
// call release_vertex_buffer() with this same pointer (which
|
||||
// will also delete the pointer).
|
||||
//
|
||||
// This function should not be called directly to
|
||||
// prepare a data. Instead, call Data::prepare().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *DXGraphicsStateGuardian8::
|
||||
prepare_data(qpGeomVertexArrayData *data) {
|
||||
VertexBufferContext *DXGraphicsStateGuardian8::
|
||||
prepare_vertex_buffer(qpGeomVertexArrayData *data) {
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "prepare_data(" << (void *)data << ")\n";
|
||||
<< "prepare_vertex_buffer(" << (void *)data << ")\n";
|
||||
}
|
||||
|
||||
DXDataContext8 *ddc = new DXDataContext8(data);
|
||||
DXVertexBufferContext8 *dvbc = new DXVertexBufferContext8(data);
|
||||
|
||||
if (vertex_buffers) {
|
||||
ddc->create_vbuffer(*_pScrn);
|
||||
ddc->mark_loaded();
|
||||
dvbc->create_vbuffer(*_pScrn);
|
||||
dvbc->mark_loaded();
|
||||
}
|
||||
|
||||
return ddc;
|
||||
return dvbc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::apply_data
|
||||
// Function: DXGraphicsStateGuardian8::apply_vertex_buffer
|
||||
// Access: Public
|
||||
// Description: Makes the data the currently available data for
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
apply_data(DataContext *dc) {
|
||||
DXDataContext8 *ddc = DCAST(DXDataContext8, dc);
|
||||
apply_vertex_buffer(VertexBufferContext *vbc) {
|
||||
DXVertexBufferContext8 *dvbc = DCAST(DXVertexBufferContext8, vbc);
|
||||
|
||||
if (ddc->_vbuffer != NULL) {
|
||||
add_to_data_record(ddc);
|
||||
if (dvbc->_vbuffer != NULL) {
|
||||
add_to_vertex_buffer_record(dvbc);
|
||||
|
||||
if (ddc->was_modified()) {
|
||||
if (dvbc->was_modified()) {
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "apply_data(" << (void *)dc->get_data() << ")\n";
|
||||
<< "apply_vertex_buffer(" << (void *)vbc->get_data() << ")\n";
|
||||
}
|
||||
if (ddc->changed_size()) {
|
||||
if (dvbc->changed_size()) {
|
||||
// Here we have to destroy the old vertex buffer and create a
|
||||
// new one.
|
||||
ddc->create_vbuffer(*_pScrn);
|
||||
dvbc->create_vbuffer(*_pScrn);
|
||||
|
||||
} else {
|
||||
// Here we just copy the new data to the vertex buffer.
|
||||
ddc->upload_data();
|
||||
dvbc->upload_data();
|
||||
}
|
||||
|
||||
ddc->mark_loaded();
|
||||
dvbc->mark_loaded();
|
||||
}
|
||||
|
||||
_pD3DDevice->SetStreamSource
|
||||
(0, ddc->_vbuffer, ddc->get_data()->get_array_format()->get_stride());
|
||||
(0, dvbc->_vbuffer, dvbc->get_data()->get_array_format()->get_stride());
|
||||
_vbuffer_active = true;
|
||||
|
||||
} else {
|
||||
_vbuffer_active = false;
|
||||
}
|
||||
|
||||
set_vertex_format(ddc->_fvf);
|
||||
set_vertex_format(dvbc->_fvf);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::release_data
|
||||
// Function: DXGraphicsStateGuardian8::release_vertex_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Frees the GL resources previously allocated for the
|
||||
// data. This function should never be called
|
||||
|
|
@ -2983,14 +2983,14 @@ apply_data(DataContext *dc) {
|
|||
// let the Data destruct).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
release_data(DataContext *dc) {
|
||||
release_vertex_buffer(VertexBufferContext *vbc) {
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "release_data(" << (void *)dc->get_data() << ")\n";
|
||||
<< "release_vertex_buffer(" << (void *)vbc->get_data() << ")\n";
|
||||
}
|
||||
|
||||
DXDataContext8 *ddc = DCAST(DXDataContext8, dc);
|
||||
delete ddc;
|
||||
DXVertexBufferContext8 *dvbc = DCAST(DXVertexBufferContext8, vbc);
|
||||
delete dvbc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@ public:
|
|||
virtual void apply_texture(TextureContext *tc);
|
||||
virtual void release_texture(TextureContext *tc);
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data);
|
||||
void apply_data(DataContext *dc);
|
||||
virtual void release_data(DataContext *dc);
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(qpGeomVertexArrayData *data);
|
||||
void apply_vertex_buffer(VertexBufferContext *vbc);
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: dxDataContext8.I
|
||||
// Filename: dxVertexBufferContext8.I
|
||||
// Created by: drose (18Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: dxDataContext8.cxx
|
||||
// Filename: dxVertexBufferContext8.cxx
|
||||
// Created by: drose (18Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -16,23 +16,23 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dxDataContext8.h"
|
||||
#include "dxVertexBufferContext8.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "internalName.h"
|
||||
#include "config_dxgsg8.h"
|
||||
#include <d3dx8.h>
|
||||
|
||||
TypeHandle DXDataContext8::_type_handle;
|
||||
TypeHandle DXVertexBufferContext8::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::Constructor
|
||||
// Function: DXVertexBufferContext8::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXDataContext8::
|
||||
DXDataContext8(qpGeomVertexArrayData *data) :
|
||||
DataContext(data),
|
||||
DXVertexBufferContext8::
|
||||
DXVertexBufferContext8(qpGeomVertexArrayData *data) :
|
||||
VertexBufferContext(data),
|
||||
_vbuffer(NULL)
|
||||
{
|
||||
// Now fill in the FVF code.
|
||||
|
|
@ -88,12 +88,12 @@ DXDataContext8(qpGeomVertexArrayData *data) :
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::Destructor
|
||||
// Function: DXVertexBufferContext8::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXDataContext8::
|
||||
~DXDataContext8() {
|
||||
DXVertexBufferContext8::
|
||||
~DXVertexBufferContext8() {
|
||||
if (_vbuffer != NULL) {
|
||||
RELEASE(_vbuffer, dxgsg8, "vertex buffer", RELEASE_ONCE);
|
||||
_vbuffer = NULL;
|
||||
|
|
@ -101,11 +101,11 @@ DXDataContext8::
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::create_vbuffer
|
||||
// Function: DXVertexBufferContext8::create_vbuffer
|
||||
// Access: Public
|
||||
// Description: Creates a new vertex buffer and uploads data to it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXDataContext8::
|
||||
void DXVertexBufferContext8::
|
||||
create_vbuffer(DXScreenData &scrn) {
|
||||
if (_vbuffer != NULL) {
|
||||
RELEASE(_vbuffer, dxgsg8, "vertex buffer", RELEASE_ONCE);
|
||||
|
|
@ -113,7 +113,7 @@ create_vbuffer(DXScreenData &scrn) {
|
|||
}
|
||||
|
||||
HRESULT hr = scrn.pD3DDevice->CreateVertexBuffer
|
||||
(get_data()->get_num_bytes(), D3DUSAGE_WRITEONLY,
|
||||
(get_data()->get_data_size_bytes(), D3DUSAGE_WRITEONLY,
|
||||
_fvf, D3DPOOL_MANAGED, &_vbuffer);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.warning()
|
||||
|
|
@ -126,24 +126,26 @@ create_vbuffer(DXScreenData &scrn) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::upload_data
|
||||
// Function: DXVertexBufferContext8::upload_data
|
||||
// Access: Public
|
||||
// Description: Copies the latest data from the client store to
|
||||
// DirectX.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXDataContext8::
|
||||
void DXVertexBufferContext8::
|
||||
upload_data() {
|
||||
nassertv(_vbuffer != NULL);
|
||||
|
||||
int data_size = get_data()->get_data_size_bytes();
|
||||
|
||||
BYTE *local_pointer;
|
||||
HRESULT hr = _vbuffer->Lock(0, 0, &local_pointer, 0);
|
||||
HRESULT hr = _vbuffer->Lock(0, data_size, &local_pointer, 0);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.error()
|
||||
<< "VertexBuffer::Lock failed" << D3DERRORSTRING(hr);
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(local_pointer, get_data()->get_data(), get_data()->get_num_bytes());
|
||||
memcpy(local_pointer, get_data()->get_data(), data_size);
|
||||
|
||||
_vbuffer->Unlock();
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: dxDataContext8.h
|
||||
// Filename: dxVertexBufferContext8.h
|
||||
// Created by: drose (18Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -16,22 +16,22 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DXDATACONTEXT8_H
|
||||
#define DXDATACONTEXT8_H
|
||||
#ifndef DXVERTEXBUFFERCONTEXT8_H
|
||||
#define DXVERTEXBUFFERCONTEXT8_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "dxgsg8base.h"
|
||||
#include "dataContext.h"
|
||||
#include "vertexBufferContext.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DXDataContext8
|
||||
// Class : DXVertexBufferContext8
|
||||
// Description : Caches a GeomVertexArrayData in the DirectX device as
|
||||
// a vertex buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXDataContext8 : public DataContext {
|
||||
class EXPCL_PANDADX DXVertexBufferContext8 : public VertexBufferContext {
|
||||
public:
|
||||
DXDataContext8(qpGeomVertexArrayData *data);
|
||||
virtual ~DXDataContext8();
|
||||
DXVertexBufferContext8(qpGeomVertexArrayData *data);
|
||||
virtual ~DXVertexBufferContext8();
|
||||
|
||||
void create_vbuffer(DXScreenData &scrn);
|
||||
void upload_data();
|
||||
|
|
@ -44,9 +44,9 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
DataContext::init_type();
|
||||
register_type(_type_handle, "DXDataContext8",
|
||||
DataContext::get_class_type());
|
||||
VertexBufferContext::init_type();
|
||||
register_type(_type_handle, "DXVertexBufferContext8",
|
||||
VertexBufferContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
@ -57,7 +57,7 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "dxDataContext8.I"
|
||||
#include "dxVertexBufferContext8.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include "dxgsg8base.h"
|
||||
#include "config_dxgsg8.cxx"
|
||||
#include "dxTextureContext8.cxx"
|
||||
#include "dxDataContext8.cxx"
|
||||
#include "dxVertexBufferContext8.cxx"
|
||||
#include "dxGeomMunger8.cxx"
|
||||
#include "d3dfont8.cxx"
|
||||
#include "wdxGraphicsPipe8.cxx"
|
||||
|
|
|
|||
|
|
@ -1926,7 +1926,7 @@ make_vertex_data(EggVertexPool *vertex_pool, const LMatrix4d &transform) {
|
|||
|
||||
// Now create a new GeomVertexData using the indicated format.
|
||||
PT(qpGeomVertexData) vertex_data =
|
||||
new qpGeomVertexData(format, qpGeomVertexArrayData::UH_static);
|
||||
new qpGeomVertexData(format, qpGeomUsageHint::UH_static);
|
||||
|
||||
// And fill the data from the vertex pool.
|
||||
EggVertexPool::const_iterator vi;
|
||||
|
|
@ -1979,10 +1979,10 @@ make_primitive(const EggRenderState *render_state, EggPrimitive *egg_prim,
|
|||
PT(qpGeomPrimitive) primitive;
|
||||
if (egg_prim->is_of_type(EggPolygon::get_class_type())) {
|
||||
if (egg_prim->size() == 3) {
|
||||
primitive = new qpGeomTriangles;
|
||||
primitive = new qpGeomTriangles(qpGeomUsageHint::UH_static);
|
||||
}
|
||||
} else if (egg_prim->is_of_type(EggTriangleStrip::get_class_type())) {
|
||||
primitive = new qpGeomTristrips;
|
||||
primitive = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
}
|
||||
|
||||
if (primitive == (qpGeomPrimitive *)NULL) {
|
||||
|
|
|
|||
|
|
@ -634,7 +634,7 @@ load_default_model(const NodePath &parent) {
|
|||
// New, experimental Geom code.
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
(qpGeomVertexFormat::get_v3n3cpt2(),
|
||||
qpGeomVertexArrayData::UH_static);
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexIterator vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexIterator normal(vdata, InternalName::get_normal());
|
||||
qpGeomVertexIterator color(vdata, InternalName::get_color());
|
||||
|
|
@ -656,7 +656,7 @@ load_default_model(const NodePath &parent) {
|
|||
texcoord.set_data2(1.0, 0.0);
|
||||
texcoord.set_data2(0.0, 1.0);
|
||||
|
||||
PT(qpGeomTriangles) tri = new qpGeomTriangles;
|
||||
PT(qpGeomTriangles) tri = new qpGeomTriangles(qpGeomUsageHint::UH_static);
|
||||
tri->add_consecutive_vertices(0, 3);
|
||||
tri->close_primitive();
|
||||
|
||||
|
|
@ -1061,7 +1061,7 @@ load_image_as_model(const Filename &filename) {
|
|||
if (use_qpgeom) {
|
||||
PT(qpGeomVertexData) vdata = new qpGeomVertexData
|
||||
(qpGeomVertexFormat::get_v3t2(),
|
||||
qpGeomVertexArrayData::UH_static);
|
||||
qpGeomUsageHint::UH_static);
|
||||
qpGeomVertexIterator vertex(vdata, InternalName::get_vertex());
|
||||
qpGeomVertexIterator texcoord(vdata, InternalName::get_texcoord());
|
||||
|
||||
|
|
@ -1075,7 +1075,7 @@ load_image_as_model(const Filename &filename) {
|
|||
texcoord.set_data2(1.0f, 1.0f);
|
||||
texcoord.set_data2(1.0f, 0.0f);
|
||||
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips;
|
||||
PT(qpGeomTristrips) strip = new qpGeomTristrips(qpGeomUsageHint::UH_static);
|
||||
strip->add_consecutive_vertices(0, 4);
|
||||
strip->close_primitive();
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,12 @@
|
|||
glstuff_src.cxx \
|
||||
glstuff_src.h \
|
||||
glstuff_undef_src.h \
|
||||
glDataContext_src.cxx \
|
||||
glDataContext_src.I \
|
||||
glDataContext_src.h \
|
||||
glVertexBufferContext_src.cxx \
|
||||
glVertexBufferContext_src.I \
|
||||
glVertexBufferContext_src.h \
|
||||
glIndexBufferContext_src.cxx \
|
||||
glIndexBufferContext_src.I \
|
||||
glIndexBufferContext_src.h \
|
||||
glGeomContext_src.cxx \
|
||||
glGeomContext_src.I \
|
||||
glGeomContext_src.h \
|
||||
|
|
|
|||
|
|
@ -596,6 +596,18 @@ reset() {
|
|||
GLCAT.debug()
|
||||
<< "max_elements_vertices = " << max_elements_vertices
|
||||
<< ", max_elements_indices = " << max_elements_indices << "\n";
|
||||
if (_supports_buffers) {
|
||||
if (vertex_buffers) {
|
||||
GLCAT.debug()
|
||||
<< "vertex buffer objects are supported.\n";
|
||||
} else {
|
||||
GLCAT.debug()
|
||||
<< "vertex buffer objects are supported (but not enabled).\n";
|
||||
}
|
||||
} else {
|
||||
GLCAT.debug()
|
||||
<< "vertex buffer objects are NOT supported.\n";
|
||||
}
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
|
|
@ -2107,11 +2119,14 @@ void CLP(GraphicsStateGuardian)::
|
|||
draw_triangles(const qpGeomTriangles *primitive) {
|
||||
setup_antialias_polygon();
|
||||
|
||||
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
|
||||
const unsigned short *client_pointer = setup_primitive(primitive);
|
||||
|
||||
_glDrawRangeElements(GL_TRIANGLES,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex(),
|
||||
primitive->get_num_vertices(),
|
||||
GL_UNSIGNED_SHORT, primitive->get_flat_last_vertices());
|
||||
GL_UNSIGNED_SHORT, client_pointer);
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
|
@ -2125,7 +2140,9 @@ void CLP(GraphicsStateGuardian)::
|
|||
draw_tristrips(const qpGeomTristrips *primitive) {
|
||||
setup_antialias_polygon();
|
||||
|
||||
CPTA_ushort vertices = primitive->get_flat_last_vertices();
|
||||
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
|
||||
const unsigned short *client_pointer = setup_primitive(primitive);
|
||||
|
||||
CPTA_int ends = primitive->get_ends();
|
||||
CPTA_ushort mins = primitive->get_mins();
|
||||
CPTA_ushort maxs = primitive->get_maxs();
|
||||
|
|
@ -2135,7 +2152,7 @@ draw_tristrips(const qpGeomTristrips *primitive) {
|
|||
for (size_t i = 0; i < ends.size(); i++) {
|
||||
_glDrawRangeElements(GL_TRIANGLE_STRIP,
|
||||
mins[i], maxs[i], ends[i] - start,
|
||||
GL_UNSIGNED_SHORT, vertices + start);
|
||||
GL_UNSIGNED_SHORT, client_pointer + start);
|
||||
start = ends[i];
|
||||
}
|
||||
|
||||
|
|
@ -2334,83 +2351,74 @@ release_geom(GeomContext *gc) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::prepare_data
|
||||
// Function: CLP(GraphicsStateGuardian)::prepare_vertex_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Creates a new retained-mode representation of the
|
||||
// given data, and returns a newly-allocated
|
||||
// DataContext pointer to reference it. It is the
|
||||
// VertexBufferContext pointer to reference it. It is the
|
||||
// responsibility of the calling function to later
|
||||
// call release_data() with this same pointer (which
|
||||
// call release_vertex_buffer() with this same pointer (which
|
||||
// will also delete the pointer).
|
||||
//
|
||||
// This function should not be called directly to
|
||||
// prepare a data. Instead, call Data::prepare().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *CLP(GraphicsStateGuardian)::
|
||||
prepare_data(qpGeomVertexArrayData *data) {
|
||||
VertexBufferContext *CLP(GraphicsStateGuardian)::
|
||||
prepare_vertex_buffer(qpGeomVertexArrayData *data) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "prepare_data(" << (void *)data << ")\n";
|
||||
<< "prepare_vertex_buffer(" << (void *)data << ")\n";
|
||||
}
|
||||
|
||||
if (_supports_buffers) {
|
||||
CLP(DataContext) *gdc = new CLP(DataContext)(data);
|
||||
_glGenBuffers(1, &gdc->_index);
|
||||
|
||||
/*
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
_glBufferData(GL_ARRAY_BUFFER, gdc->get_data()->get_num_bytes(),
|
||||
gdc->get_data()->get_data(),
|
||||
get_usage(gdc->get_data()->get_usage_hint()));
|
||||
add_to_data_record(gdc);
|
||||
gdc->mark_loaded();
|
||||
*/
|
||||
CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(data);
|
||||
_glGenBuffers(1, &gvbc->_index);
|
||||
|
||||
report_my_gl_errors();
|
||||
return gdc;
|
||||
return gvbc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::apply_data
|
||||
// Function: CLP(GraphicsStateGuardian)::apply_vertex_buffer
|
||||
// Access: Public
|
||||
// Description: Makes the data the currently available data for
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
apply_data(DataContext *dc) {
|
||||
apply_vertex_buffer(VertexBufferContext *vbc) {
|
||||
nassertv(_supports_buffers);
|
||||
|
||||
CLP(DataContext) *gdc = DCAST(CLP(DataContext), dc);
|
||||
CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
|
||||
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
|
||||
|
||||
add_to_data_record(gdc);
|
||||
if (gdc->was_modified()) {
|
||||
add_to_vertex_buffer_record(gvbc);
|
||||
if (gvbc->was_modified()) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "apply_data(" << (void *)dc->get_data() << ")\n";
|
||||
<< "apply_vertex_buffer(" << (void *)vbc->get_data() << ")\n";
|
||||
}
|
||||
if (gdc->changed_size()) {
|
||||
_glBufferData(GL_ARRAY_BUFFER, gdc->get_data()->get_num_bytes(),
|
||||
gdc->get_data()->get_data(),
|
||||
get_usage(gdc->get_data()->get_usage_hint()));
|
||||
if (gvbc->changed_size()) {
|
||||
_glBufferData(GL_ARRAY_BUFFER, gvbc->get_data()->get_data_size_bytes(),
|
||||
gvbc->get_data()->get_data(),
|
||||
get_usage(gvbc->get_data()->get_usage_hint()));
|
||||
|
||||
} else {
|
||||
_glBufferSubData(GL_ARRAY_BUFFER, 0, gdc->get_num_bytes(),
|
||||
gdc->get_data()->get_data());
|
||||
_glBufferSubData(GL_ARRAY_BUFFER, 0, gvbc->get_data_size_bytes(),
|
||||
gvbc->get_data()->get_data());
|
||||
}
|
||||
|
||||
gdc->mark_loaded();
|
||||
gvbc->mark_loaded();
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::release_data
|
||||
// Function: CLP(GraphicsStateGuardian)::release_vertex_buffer
|
||||
// Access: Public, Virtual
|
||||
// Description: Frees the GL resources previously allocated for the
|
||||
// data. This function should never be called
|
||||
|
|
@ -2418,22 +2426,22 @@ apply_data(DataContext *dc) {
|
|||
// let the Data destruct).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
release_data(DataContext *dc) {
|
||||
release_vertex_buffer(VertexBufferContext *vbc) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "release_data(" << (void *)dc->get_data() << ")\n";
|
||||
<< "release_vertex_buffer(" << (void *)vbc->get_data() << ")\n";
|
||||
}
|
||||
|
||||
nassertv(_supports_buffers);
|
||||
|
||||
CLP(DataContext) *gdc = DCAST(CLP(DataContext), dc);
|
||||
CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
|
||||
|
||||
_glDeleteBuffers(1, &gdc->_index);
|
||||
_glDeleteBuffers(1, &gvbc->_index);
|
||||
report_my_gl_errors();
|
||||
|
||||
gdc->_index = 0;
|
||||
gvbc->_index = 0;
|
||||
|
||||
delete gdc;
|
||||
delete gvbc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2457,7 +2465,7 @@ setup_array_data(const qpGeomVertexArrayData *data) {
|
|||
return data->get_data();
|
||||
}
|
||||
if (!vertex_buffers ||
|
||||
data->get_usage_hint() == qpGeomVertexArrayData::UH_client) {
|
||||
data->get_usage_hint() == qpGeomUsageHint::UH_client) {
|
||||
// The array specifies client rendering only, or buffer objects
|
||||
// are configured off.
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
|
@ -2465,28 +2473,144 @@ setup_array_data(const qpGeomVertexArrayData *data) {
|
|||
}
|
||||
|
||||
// Prepare the buffer object and bind it.
|
||||
DataContext *dc = ((qpGeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(dc != (DataContext *)NULL, data->get_data());
|
||||
apply_data(dc);
|
||||
VertexBufferContext *vbc = ((qpGeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, data->get_data());
|
||||
apply_vertex_buffer(vbc);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer.
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int logs[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
|
||||
4096, 0 };
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::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 data. Instead, call Data::prepare().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
IndexBufferContext *CLP(GraphicsStateGuardian)::
|
||||
prepare_index_buffer(qpGeomPrimitive *data) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "prepare_index_buffer(" << (void *)data << ")\n";
|
||||
}
|
||||
|
||||
// This function returns the smallest power of two greater than or
|
||||
// equal to x.
|
||||
static int binary_log_cap(const int x) {
|
||||
int i = 0;
|
||||
for (; (x > logs[i]) && (logs[i] != 0); ++i);
|
||||
if (logs[i] == 0)
|
||||
return 4096;
|
||||
return logs[i];
|
||||
if (_supports_buffers) {
|
||||
CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(data);
|
||||
_glGenBuffers(1, &gibc->_index);
|
||||
|
||||
report_my_gl_errors();
|
||||
return gibc;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::apply_index_buffer
|
||||
// Access: Public
|
||||
// Description: Makes the data the currently available data for
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
apply_index_buffer(IndexBufferContext *ibc) {
|
||||
nassertv(_supports_buffers);
|
||||
|
||||
CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
|
||||
|
||||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gibc->_index);
|
||||
|
||||
add_to_index_buffer_record(gibc);
|
||||
if (gibc->was_modified()) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "apply_index_buffer(" << (void *)ibc->get_data() << ")\n";
|
||||
}
|
||||
if (gibc->changed_size()) {
|
||||
_glBufferData(GL_ELEMENT_ARRAY_BUFFER, gibc->get_data()->get_data_size_bytes(),
|
||||
gibc->get_data()->get_vertices(),
|
||||
get_usage(gibc->get_data()->get_usage_hint()));
|
||||
|
||||
} else {
|
||||
_glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, gibc->get_data_size_bytes(),
|
||||
gibc->get_data()->get_vertices());
|
||||
}
|
||||
|
||||
gibc->mark_loaded();
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::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 CLP(GraphicsStateGuardian)::
|
||||
release_index_buffer(IndexBufferContext *ibc) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "release_index_buffer(" << (void *)ibc->get_data() << ")\n";
|
||||
}
|
||||
|
||||
nassertv(_supports_buffers);
|
||||
|
||||
CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
|
||||
|
||||
_glDeleteBuffers(1, &gibc->_index);
|
||||
report_my_gl_errors();
|
||||
|
||||
gibc->_index = 0;
|
||||
|
||||
delete gibc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::setup_primitive
|
||||
// Access: Public
|
||||
// Description: Internal function to bind a buffer object for the
|
||||
// indicated primitive's index list, if appropriate, or
|
||||
// to unbind a buffer object if it should be rendered
|
||||
// from client memory.
|
||||
//
|
||||
// If the buffer object is bound, this function returns
|
||||
// NULL (reprsenting the start of the buffer object in
|
||||
// server memory); if the buffer object is not bound,
|
||||
// this function returns the pointer to the data array
|
||||
// in client memory, that is, the data array passed in.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const unsigned short *CLP(GraphicsStateGuardian)::
|
||||
setup_primitive(const qpGeomPrimitive *data) {
|
||||
if (!_supports_buffers) {
|
||||
// No support for buffer objects; always render from client.
|
||||
return data->get_vertices();
|
||||
}
|
||||
if (!vertex_buffers ||
|
||||
data->get_usage_hint() == qpGeomUsageHint::UH_client) {
|
||||
// The array specifies client rendering only, or buffer objects
|
||||
// are configured off.
|
||||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
return data->get_vertices();
|
||||
}
|
||||
|
||||
// Prepare the buffer object and bind it.
|
||||
IndexBufferContext *ibc = ((qpGeomPrimitive *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(ibc != (IndexBufferContext *)NULL, data->get_vertices());
|
||||
apply_index_buffer(ibc);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer.
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::get_geom_munger
|
||||
|
|
@ -4598,18 +4722,18 @@ get_blend_func(ColorBlendAttrib::Operand operand) {
|
|||
// Description: Maps from UsageHint to the GL symbol.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GLenum CLP(GraphicsStateGuardian)::
|
||||
get_usage(qpGeomVertexArrayData::UsageHint usage_hint) {
|
||||
get_usage(qpGeomUsageHint::UsageHint usage_hint) {
|
||||
switch (usage_hint) {
|
||||
case qpGeomVertexArrayData::UH_stream:
|
||||
case qpGeomUsageHint::UH_stream:
|
||||
return GL_STREAM_DRAW;
|
||||
|
||||
case qpGeomVertexArrayData::UH_static:
|
||||
case qpGeomUsageHint::UH_static:
|
||||
return GL_STATIC_DRAW;
|
||||
|
||||
case qpGeomVertexArrayData::UH_dynamic:
|
||||
case qpGeomUsageHint::UH_dynamic:
|
||||
return GL_DYNAMIC_DRAW;
|
||||
|
||||
case qpGeomVertexArrayData::UH_client:
|
||||
case qpGeomUsageHint::UH_client:
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,11 +104,16 @@ public:
|
|||
virtual GeomContext *prepare_geom(Geom *geom);
|
||||
virtual void release_geom(GeomContext *gc);
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data);
|
||||
void apply_data(DataContext *dc);
|
||||
virtual void release_data(DataContext *dc);
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(qpGeomVertexArrayData *data);
|
||||
void apply_vertex_buffer(VertexBufferContext *vbc);
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
const unsigned char *setup_array_data(const qpGeomVertexArrayData *data);
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data);
|
||||
void apply_index_buffer(IndexBufferContext *ibc);
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc);
|
||||
const unsigned short *setup_primitive(const qpGeomPrimitive *data);
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
virtual void framebuffer_copy_to_texture
|
||||
|
|
@ -242,7 +247,7 @@ protected:
|
|||
static GLenum get_fog_mode_type(Fog::Mode m);
|
||||
static GLenum get_blend_equation_type(ColorBlendAttrib::Mode mode);
|
||||
static GLenum get_blend_func(ColorBlendAttrib::Operand operand);
|
||||
static GLenum get_usage(qpGeomVertexArrayData::UsageHint usage_hint);
|
||||
static GLenum get_usage(qpGeomUsageHint::UsageHint usage_hint);
|
||||
|
||||
static CPT(RenderState) get_untextured_state();
|
||||
static CPT(RenderState) get_smooth_state();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: glDataContext_src.I
|
||||
// Filename: glIndexBufferContext_src.I
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(DataContext)::Constructor
|
||||
// Function: CLP(IndexBufferContext)::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(DataContext)::
|
||||
CLP(DataContext)(qpGeomVertexArrayData *data) :
|
||||
DataContext(data)
|
||||
INLINE CLP(IndexBufferContext)::
|
||||
CLP(IndexBufferContext)(qpGeomPrimitive *data) :
|
||||
IndexBufferContext(data)
|
||||
{
|
||||
_index = 0;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: glDataContext_src.cxx
|
||||
// Filename: glIndexBufferContext_src.cxx
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -16,4 +16,4 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
TypeHandle CLP(DataContext)::_type_handle;
|
||||
TypeHandle CLP(IndexBufferContext)::_type_handle;
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
// Filename: glIndexBufferContext_src.h
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "pandabase.h"
|
||||
#include "indexBufferContext.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLIndexBufferContext
|
||||
// Description : Caches a GeomPrimitive on the GL as a buffer
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(IndexBufferContext) : public IndexBufferContext {
|
||||
public:
|
||||
INLINE CLP(IndexBufferContext)(qpGeomPrimitive *data);
|
||||
|
||||
// This is the GL "name" of the data object.
|
||||
GLuint _index;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
IndexBufferContext::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "IndexBufferContext",
|
||||
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 "glIndexBufferContext_src.I"
|
||||
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Filename: glVertexBufferContext_src.I
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(VertexBufferContext)::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CLP(VertexBufferContext)::
|
||||
CLP(VertexBufferContext)(qpGeomVertexArrayData *data) :
|
||||
VertexBufferContext(data)
|
||||
{
|
||||
_index = 0;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: dataContext.cxx
|
||||
// Filename: glVertexBufferContext_src.cxx
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -16,6 +16,4 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dataContext.h"
|
||||
|
||||
TypeHandle DataContext::_type_handle;
|
||||
TypeHandle CLP(VertexBufferContext)::_type_handle;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: glDataContext_src.h
|
||||
// Filename: glVertexBufferContext_src.h
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -17,16 +17,16 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "dataContext.h"
|
||||
#include "vertexBufferContext.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLDataContext
|
||||
// Class : GLVertexBufferContext
|
||||
// Description : Caches a GeomVertexArrayData on the GL as a buffer
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(DataContext) : public DataContext {
|
||||
class EXPCL_GL CLP(VertexBufferContext) : public VertexBufferContext {
|
||||
public:
|
||||
INLINE CLP(DataContext)(qpGeomVertexArrayData *data);
|
||||
INLINE CLP(VertexBufferContext)(qpGeomVertexArrayData *data);
|
||||
|
||||
// This is the GL "name" of the data object.
|
||||
GLuint _index;
|
||||
|
|
@ -36,9 +36,9 @@ public:
|
|||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
DataContext::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "DataContext",
|
||||
DataContext::get_class_type());
|
||||
VertexBufferContext::init_type();
|
||||
register_type(_type_handle, CLASSPREFIX_QUOTED "VertexBufferContext",
|
||||
VertexBufferContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
return get_class_type();
|
||||
|
|
@ -49,5 +49,5 @@ private:
|
|||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
#include "glDataContext_src.I"
|
||||
#include "glVertexBufferContext_src.I"
|
||||
|
||||
|
|
@ -63,7 +63,8 @@ void CLP(init_classes)() {
|
|||
CLP(GraphicsStateGuardian)::init_type();
|
||||
CLP(TextureContext)::init_type();
|
||||
CLP(GeomContext)::init_type();
|
||||
CLP(DataContext)::init_type();
|
||||
CLP(VertexBufferContext)::init_type();
|
||||
CLP(IndexBufferContext)::init_type();
|
||||
|
||||
PandaSystem *ps = PandaSystem::get_global_ptr();
|
||||
ps->add_system(GLSYSTEM_NAME);
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@
|
|||
|
||||
#include "glmisc_src.cxx"
|
||||
#include "glTextureContext_src.cxx"
|
||||
#include "glDataContext_src.cxx"
|
||||
#include "glVertexBufferContext_src.cxx"
|
||||
#include "glIndexBufferContext_src.cxx"
|
||||
#include "glGeomContext_src.cxx"
|
||||
#include "glGeomMunger_src.cxx"
|
||||
#include "glCgShaderContext_src.cxx"
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@
|
|||
|
||||
#include "glmisc_src.h"
|
||||
#include "glTextureContext_src.h"
|
||||
#include "glDataContext_src.h"
|
||||
#include "glVertexBufferContext_src.h"
|
||||
#include "glIndexBufferContext_src.h"
|
||||
#include "glGeomContext_src.h"
|
||||
#include "glGeomMunger_src.h"
|
||||
#include "glCgShaderContext_src.h"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
#define SOURCES \
|
||||
boundedObject.I boundedObject.h \
|
||||
config_gobj.h \
|
||||
dataContext.I dataContext.h \
|
||||
drawable.h \
|
||||
geom.I geom.h \
|
||||
geomContext.I geomContext.h \
|
||||
|
|
@ -25,6 +24,7 @@
|
|||
qpgeomTriangles.h \
|
||||
qpgeomTristrips.h \
|
||||
qpgeomTrifans.h \
|
||||
qpgeomUsageHint.h \
|
||||
qpgeomVertexArrayData.h qpgeomVertexArrayData.I \
|
||||
qpgeomVertexArrayFormat.h qpgeomVertexArrayFormat.I \
|
||||
qpgeomVertexCacheManager.h qpgeomVertexCacheManager.I \
|
||||
|
|
@ -32,6 +32,7 @@
|
|||
qpgeomVertexDataType.h qpgeomVertexDataType.I \
|
||||
qpgeomVertexFormat.h qpgeomVertexFormat.I \
|
||||
qpgeomVertexIterator.h qpgeomVertexIterator.I \
|
||||
indexBufferContext.I indexBufferContext.h \
|
||||
internalName.I internalName.h \
|
||||
material.I material.h materialPool.I materialPool.h \
|
||||
matrixLens.I matrixLens.h \
|
||||
|
|
@ -43,12 +44,12 @@
|
|||
texture.I texture.h \
|
||||
textureContext.I textureContext.h \
|
||||
texturePool.I texturePool.h \
|
||||
textureStage.I textureStage.h
|
||||
textureStage.I textureStage.h \
|
||||
vertexBufferContext.I vertexBufferContext.h
|
||||
|
||||
#define INCLUDED_SOURCES \
|
||||
boundedObject.cxx \
|
||||
config_gobj.cxx \
|
||||
dataContext.cxx \
|
||||
drawable.cxx geom.cxx \
|
||||
geomContext.cxx \
|
||||
geomLine.cxx geomLinestrip.cxx geomPoint.cxx geomPolygon.cxx \
|
||||
|
|
@ -67,6 +68,7 @@
|
|||
qpgeomVertexDataType.cxx \
|
||||
qpgeomVertexFormat.cxx \
|
||||
qpgeomVertexIterator.cxx \
|
||||
indexBufferContext.cxx \
|
||||
material.cxx \
|
||||
internalName.cxx \
|
||||
materialPool.cxx matrixLens.cxx orthographicLens.cxx \
|
||||
|
|
@ -74,12 +76,12 @@
|
|||
preparedGraphicsObjects.cxx \
|
||||
lens.cxx \
|
||||
savedContext.cxx texture.cxx textureContext.cxx texturePool.cxx \
|
||||
textureStage.cxx
|
||||
textureStage.cxx \
|
||||
vertexBufferContext.cxx
|
||||
|
||||
#define INSTALL_HEADERS \
|
||||
boundedObject.I boundedObject.h \
|
||||
config_gobj.h \
|
||||
dataContext.I dataContext.h \
|
||||
drawable.h geom.I geom.h \
|
||||
textureContext.I textureContext.h \
|
||||
geomLine.h \
|
||||
|
|
@ -92,6 +94,7 @@
|
|||
qpgeomTriangles.h \
|
||||
qpgeomTristrips.h \
|
||||
qpgeomTrifans.h \
|
||||
qpgeomUsageHint.h \
|
||||
qpgeomVertexArrayData.h qpgeomVertexArrayData.I \
|
||||
qpgeomVertexArrayFormat.h qpgeomVertexArrayFormat.I \
|
||||
qpgeomVertexCacheManager.h qpgeomVertexCacheManager.I \
|
||||
|
|
@ -99,6 +102,7 @@
|
|||
qpgeomVertexDataType.h qpgeomVertexDataType.I \
|
||||
qpgeomVertexFormat.h qpgeomVertexFormat.I \
|
||||
qpgeomVertexIterator.h qpgeomVertexIterator.I \
|
||||
indexBufferContext.I indexBufferContext.h \
|
||||
internalName.I internalName.h \
|
||||
material.I material.h \
|
||||
materialPool.I materialPool.h matrixLens.I matrixLens.h \
|
||||
|
|
@ -110,7 +114,9 @@
|
|||
texture.I texture.h \
|
||||
textureContext.I textureContext.h \
|
||||
texturePool.I texturePool.h \
|
||||
textureStage.I textureStage.h
|
||||
textureStage.I textureStage.h \
|
||||
vertexBufferContext.I vertexBufferContext.h
|
||||
|
||||
|
||||
#define IGATESCAN all
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@
|
|||
#include "textureStage.h"
|
||||
#include "textureContext.h"
|
||||
#include "geomContext.h"
|
||||
#include "dataContext.h"
|
||||
#include "vertexBufferContext.h"
|
||||
#include "indexBufferContext.h"
|
||||
#include "internalName.h"
|
||||
|
||||
#include "dconfig.h"
|
||||
|
|
@ -182,7 +183,8 @@ ConfigureFn(config_gobj) {
|
|||
qpGeomVertexFormat::init_type();
|
||||
TextureContext::init_type();
|
||||
GeomContext::init_type();
|
||||
DataContext::init_type();
|
||||
VertexBufferContext::init_type();
|
||||
IndexBufferContext::init_type();
|
||||
Material::init_type();
|
||||
OrthographicLens::init_type();
|
||||
MatrixLens::init_type();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
#include "boundedObject.cxx"
|
||||
#include "dataContext.cxx"
|
||||
#include "geom.cxx"
|
||||
#include "geomLine.cxx"
|
||||
#include "geomLinestrip.cxx"
|
||||
|
|
|
|||
|
|
@ -2,16 +2,18 @@
|
|||
#include "config_gobj.cxx"
|
||||
#include "drawable.cxx"
|
||||
#include "geomContext.cxx"
|
||||
#include "indexBufferContext.cxx"
|
||||
#include "internalName.cxx"
|
||||
#include "lens.cxx"
|
||||
#include "material.cxx"
|
||||
#include "materialPool.cxx"
|
||||
#include "orthographicLens.cxx"
|
||||
#include "matrixLens.cxx"
|
||||
#include "orthographicLens.cxx"
|
||||
#include "perspectiveLens.cxx"
|
||||
#include "preparedGraphicsObjects.cxx"
|
||||
#include "lens.cxx"
|
||||
#include "savedContext.cxx"
|
||||
#include "texture.cxx"
|
||||
#include "textureContext.cxx"
|
||||
#include "texturePool.cxx"
|
||||
#include "textureStage.cxx"
|
||||
#include "vertexBufferContext.cxx"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: dataContext.I
|
||||
// Filename: indexBufferContext.I
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -18,74 +18,74 @@
|
|||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::Constructor
|
||||
// Function: IndexBufferContext::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DataContext::
|
||||
DataContext(qpGeomVertexArrayData *data) :
|
||||
INLINE IndexBufferContext::
|
||||
IndexBufferContext(qpGeomPrimitive *data) :
|
||||
_data(data),
|
||||
// Initially, the number of bytes is zero, until the data has been
|
||||
// loaded (and mark_loaded() is called).
|
||||
_num_bytes(0)
|
||||
_data_size_bytes(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::get_data
|
||||
// Function: IndexBufferContext::get_data
|
||||
// Access: Public
|
||||
// Description: Returns the pointer to the client-side array data
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData *DataContext::
|
||||
INLINE qpGeomPrimitive *IndexBufferContext::
|
||||
get_data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::get_num_bytes
|
||||
// Function: IndexBufferContext::get_data_size_bytes
|
||||
// Access: Public
|
||||
// Description: Returns the number of bytes previously reported for
|
||||
// the data object. This is used to track changes in
|
||||
// the data object's allocated size; if it changes from
|
||||
// this, we need to create a new buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int DataContext::
|
||||
get_num_bytes() const {
|
||||
return _num_bytes;
|
||||
INLINE int IndexBufferContext::
|
||||
get_data_size_bytes() const {
|
||||
return _data_size_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::changed_size
|
||||
// Function: IndexBufferContext::changed_size
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has changed size since the
|
||||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DataContext::
|
||||
INLINE bool IndexBufferContext::
|
||||
changed_size() const {
|
||||
return get_num_bytes() != _data->get_num_bytes();
|
||||
return get_data_size_bytes() != _data->get_data_size_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::was_modified
|
||||
// Function: IndexBufferContext::was_modified
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has been modified since the
|
||||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DataContext::
|
||||
INLINE bool IndexBufferContext::
|
||||
was_modified() const {
|
||||
return _modified != _data->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::mark_loaded
|
||||
// Function: IndexBufferContext::mark_loaded
|
||||
// Access: Public
|
||||
// Description: Should be called after the DataContext has been
|
||||
// Description: Should be called after the IndexBufferContext has been
|
||||
// loaded into graphics memory, this updates the
|
||||
// internal flags for changed_size() and modified().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DataContext::
|
||||
INLINE void IndexBufferContext::
|
||||
mark_loaded() {
|
||||
_num_bytes = _data->get_num_bytes();
|
||||
_data_size_bytes = _data->get_data_size_bytes();
|
||||
_modified = _data->get_modified();
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Filename: indexBufferContext.cxx
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "indexBufferContext.h"
|
||||
|
||||
TypeHandle IndexBufferContext::_type_handle;
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Filename: indexBufferContext.h
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 INDEXBUFFERCONTEXT_H
|
||||
#define INDEXBUFFERCONTEXT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
#include "savedContext.h"
|
||||
#include "updateSeq.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : IndexBufferContext
|
||||
// Description : This is a special class object that holds all the
|
||||
// information returned by a particular GSG to indicate
|
||||
// the vertex data array's internal context identifier.
|
||||
//
|
||||
// This allows the GSG to cache the vertex data array in
|
||||
// whatever way makes sense. For instance, DirectX can
|
||||
// allocate a vertex buffer for the array. OpenGL can
|
||||
// create a buffer object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA IndexBufferContext : public SavedContext {
|
||||
public:
|
||||
INLINE IndexBufferContext(qpGeomPrimitive *data);
|
||||
|
||||
INLINE qpGeomPrimitive *get_data() const;
|
||||
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE bool changed_size() const;
|
||||
INLINE bool was_modified() const;
|
||||
|
||||
INLINE void mark_loaded();
|
||||
|
||||
private:
|
||||
// This cannot be a PT(qpGeomPrimitive), because the data and
|
||||
// the GSG both own their IndexBufferContexts! That would create a
|
||||
// circular reference count.
|
||||
qpGeomPrimitive *_data;
|
||||
UpdateSeq _modified;
|
||||
int _data_size_bytes;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
SavedContext::init_type();
|
||||
register_type(_type_handle, "IndexBufferContext",
|
||||
SavedContext::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;
|
||||
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
#include "indexBufferContext.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -18,9 +18,12 @@
|
|||
|
||||
#include "preparedGraphicsObjects.h"
|
||||
#include "textureContext.h"
|
||||
#include "vertexBufferContext.h"
|
||||
#include "indexBufferContext.h"
|
||||
#include "texture.h"
|
||||
#include "geom.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
#include "mutexHolder.h"
|
||||
|
||||
PStatCollector PreparedGraphicsObjects::_total_texusage_pcollector("Texture usage");
|
||||
|
|
@ -74,18 +77,31 @@ PreparedGraphicsObjects::
|
|||
_released_geoms.clear();
|
||||
_enqueued_geoms.clear();
|
||||
|
||||
Datas::iterator dci;
|
||||
for (dci = _prepared_datas.begin();
|
||||
dci != _prepared_datas.end();
|
||||
++dci) {
|
||||
DataContext *dc = (*dci);
|
||||
_total_texusage_pcollector.sub_level(dc->get_num_bytes());
|
||||
dc->_data->clear_prepared(this);
|
||||
VertexBuffers::iterator vbci;
|
||||
for (vbci = _prepared_vertex_buffers.begin();
|
||||
vbci != _prepared_vertex_buffers.end();
|
||||
++vbci) {
|
||||
VertexBufferContext *vbc = (*vbci);
|
||||
_total_texusage_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
vbc->_data->clear_prepared(this);
|
||||
}
|
||||
|
||||
_prepared_datas.clear();
|
||||
_released_datas.clear();
|
||||
_enqueued_datas.clear();
|
||||
_prepared_vertex_buffers.clear();
|
||||
_released_vertex_buffers.clear();
|
||||
_enqueued_vertex_buffers.clear();
|
||||
|
||||
IndexBuffers::iterator ibci;
|
||||
for (ibci = _prepared_index_buffers.begin();
|
||||
ibci != _prepared_index_buffers.end();
|
||||
++ibci) {
|
||||
IndexBufferContext *ibc = (*ibci);
|
||||
_total_texusage_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
ibc->_data->clear_prepared(this);
|
||||
}
|
||||
|
||||
_prepared_index_buffers.clear();
|
||||
_released_index_buffers.clear();
|
||||
_enqueued_index_buffers.clear();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -375,78 +391,78 @@ prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::enqueue_data
|
||||
// Function: PreparedGraphicsObjects::enqueue_vertex_buffer
|
||||
// Access: Public
|
||||
// Description: Indicates that a data array would like to be put on the
|
||||
// Description: Indicates that a buffer would like to be put on the
|
||||
// list to be prepared when the GSG is next ready to
|
||||
// do this (presumably at the next frame).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
enqueue_data(qpGeomVertexArrayData *data) {
|
||||
enqueue_vertex_buffer(qpGeomVertexArrayData *data) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
_enqueued_datas.insert(data);
|
||||
_enqueued_vertex_buffers.insert(data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::dequeue_data
|
||||
// Function: PreparedGraphicsObjects::dequeue_vertex_buffer
|
||||
// Access: Public
|
||||
// Description: Removes a data array from the queued list of data
|
||||
// Description: Removes a buffer from the queued list of data
|
||||
// arrays to be prepared. Normally it is not necessary
|
||||
// to call this, unless you change your mind about
|
||||
// preparing it at the last minute, since the data will
|
||||
// automatically be dequeued and prepared at the next
|
||||
// frame.
|
||||
//
|
||||
// The return value is true if the data array is
|
||||
// The return value is true if the buffer is
|
||||
// successfully dequeued, false if it had not been
|
||||
// queued.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PreparedGraphicsObjects::
|
||||
dequeue_data(qpGeomVertexArrayData *data) {
|
||||
dequeue_vertex_buffer(qpGeomVertexArrayData *data) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
EnqueuedDatas::iterator qi = _enqueued_datas.find(data);
|
||||
if (qi != _enqueued_datas.end()) {
|
||||
_enqueued_datas.erase(qi);
|
||||
EnqueuedVertexBuffers::iterator qi = _enqueued_vertex_buffers.find(data);
|
||||
if (qi != _enqueued_vertex_buffers.end()) {
|
||||
_enqueued_vertex_buffers.erase(qi);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::release_data
|
||||
// Function: PreparedGraphicsObjects::release_vertex_buffer
|
||||
// Access: Public
|
||||
// Description: Indicates that a data context, created by a
|
||||
// previous call to prepare_data(), is no longer
|
||||
// previous call to prepare_vertex_buffer(), is no longer
|
||||
// needed. The driver resources will not be freed until
|
||||
// some GSG calls update(), indicating it is at a
|
||||
// stage where it is ready to release datas--this
|
||||
// prevents conflicts from threading or multiple GSG's
|
||||
// sharing datas (we have no way of knowing which
|
||||
// graphics context is currently active, or what state
|
||||
// it's in, at the time release_data is called).
|
||||
// it's in, at the time release_vertex_buffer is called).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
release_data(DataContext *dc) {
|
||||
release_vertex_buffer(VertexBufferContext *vbc) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
dc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(dc->get_num_bytes());
|
||||
vbc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since
|
||||
// the Data itself might destruct at any time after it has been
|
||||
// released.
|
||||
dc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
vbc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
|
||||
bool removed = (_prepared_datas.erase(dc) != 0);
|
||||
bool removed = (_prepared_vertex_buffers.erase(vbc) != 0);
|
||||
nassertv(removed);
|
||||
|
||||
_released_datas.insert(dc);
|
||||
_released_vertex_buffers.insert(vbc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::release_all_datas
|
||||
// Function: PreparedGraphicsObjects::release_all_vertex_buffers
|
||||
// Access: Public
|
||||
// Description: Releases all datas at once. This will force them
|
||||
// to be reloaded into data memory for all GSG's that
|
||||
|
|
@ -454,71 +470,218 @@ release_data(DataContext *dc) {
|
|||
// released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PreparedGraphicsObjects::
|
||||
release_all_datas() {
|
||||
release_all_vertex_buffers() {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
int num_datas = (int)_prepared_datas.size();
|
||||
int num_vertex_buffers = (int)_prepared_vertex_buffers.size();
|
||||
|
||||
Datas::iterator dci;
|
||||
for (dci = _prepared_datas.begin();
|
||||
dci != _prepared_datas.end();
|
||||
++dci) {
|
||||
DataContext *dc = (*dci);
|
||||
dc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(dc->get_num_bytes());
|
||||
dc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
VertexBuffers::iterator vbci;
|
||||
for (vbci = _prepared_vertex_buffers.begin();
|
||||
vbci != _prepared_vertex_buffers.end();
|
||||
++vbci) {
|
||||
VertexBufferContext *vbc = (*vbci);
|
||||
vbc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(vbc->get_data_size_bytes());
|
||||
vbc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
|
||||
_released_datas.insert(dc);
|
||||
_released_vertex_buffers.insert(vbc);
|
||||
}
|
||||
|
||||
_prepared_datas.clear();
|
||||
_prepared_vertex_buffers.clear();
|
||||
|
||||
return num_datas;
|
||||
return num_vertex_buffers;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::prepare_data_now
|
||||
// Function: PreparedGraphicsObjects::prepare_vertex_buffer_now
|
||||
// Access: Public
|
||||
// Description: Immediately creates a new DataContext for the
|
||||
// Description: Immediately creates a new VertexBufferContext for the
|
||||
// indicated data and returns it. This assumes that
|
||||
// the GraphicsStateGuardian is the currently active
|
||||
// rendering context and that it is ready to accept new
|
||||
// datas. If this is not necessarily the case, you
|
||||
// should use enqueue_data() instead.
|
||||
// should use enqueue_vertex_buffer() instead.
|
||||
//
|
||||
// Normally, this function is not called directly. Call
|
||||
// Data::prepare_now() instead.
|
||||
//
|
||||
// The DataContext contains all of the pertinent
|
||||
// The VertexBufferContext contains all of the pertinent
|
||||
// information needed by the GSG to keep track of this
|
||||
// one particular data, and will exist as long as the
|
||||
// data is ready to be rendered.
|
||||
//
|
||||
// When either the Data or the
|
||||
// PreparedGraphicsObjects object destructs, the
|
||||
// DataContext will be deleted.
|
||||
// VertexBufferContext will be deleted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *PreparedGraphicsObjects::
|
||||
prepare_data_now(qpGeomVertexArrayData *data, GraphicsStateGuardianBase *gsg) {
|
||||
VertexBufferContext *PreparedGraphicsObjects::
|
||||
prepare_vertex_buffer_now(qpGeomVertexArrayData *data, GraphicsStateGuardianBase *gsg) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
// Ask the GSG to create a brand new DataContext. There might
|
||||
// Ask the GSG to create a brand new VertexBufferContext. There might
|
||||
// be several GSG's sharing the same set of datas; if so, it
|
||||
// doesn't matter which of them creates the context (since they're
|
||||
// all shared anyway).
|
||||
DataContext *dc = gsg->prepare_data(data);
|
||||
VertexBufferContext *vbc = gsg->prepare_vertex_buffer(data);
|
||||
|
||||
if (dc != (DataContext *)NULL) {
|
||||
bool prepared = _prepared_datas.insert(dc).second;
|
||||
nassertr(prepared, dc);
|
||||
if (vbc != (VertexBufferContext *)NULL) {
|
||||
bool prepared = _prepared_vertex_buffers.insert(vbc).second;
|
||||
nassertr(prepared, vbc);
|
||||
|
||||
// The size has already been counted by
|
||||
// GraphicsStateGuardian::add_to_data_record(); we don't need to
|
||||
// GraphicsStateGuardian::add_to_vertex_buffer_record(); we don't need to
|
||||
// count it again here.
|
||||
//_total_buffers_pcollector.add_level(dc->get_num_bytes());
|
||||
//_total_buffers_pcollector.add_level(vbc->get_data_size_bytes());
|
||||
}
|
||||
|
||||
return dc;
|
||||
return vbc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::enqueue_index_buffer
|
||||
// Access: Public
|
||||
// Description: Indicates that a buffer would like to be put on the
|
||||
// list to be prepared when the GSG is next ready to
|
||||
// do this (presumably at the next frame).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
enqueue_index_buffer(qpGeomPrimitive *data) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
_enqueued_index_buffers.insert(data);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::dequeue_index_buffer
|
||||
// Access: Public
|
||||
// Description: Removes a buffer from the queued list of data
|
||||
// arrays to be prepared. Normally it is not necessary
|
||||
// to call this, unless you change your mind about
|
||||
// preparing it at the last minute, since the data will
|
||||
// automatically be dequeued and prepared at the next
|
||||
// frame.
|
||||
//
|
||||
// The return value is true if the buffer is
|
||||
// successfully dequeued, false if it had not been
|
||||
// queued.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PreparedGraphicsObjects::
|
||||
dequeue_index_buffer(qpGeomPrimitive *data) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
EnqueuedIndexBuffers::iterator qi = _enqueued_index_buffers.find(data);
|
||||
if (qi != _enqueued_index_buffers.end()) {
|
||||
_enqueued_index_buffers.erase(qi);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::release_index_buffer
|
||||
// Access: Public
|
||||
// Description: Indicates that a data context, created by a
|
||||
// previous call to prepare_index_buffer(), is no longer
|
||||
// needed. The driver resources will not be freed until
|
||||
// some GSG calls update(), indicating it is at a
|
||||
// stage where it is ready to release datas--this
|
||||
// prevents conflicts from threading or multiple GSG's
|
||||
// sharing datas (we have no way of knowing which
|
||||
// graphics context is currently active, or what state
|
||||
// it's in, at the time release_index_buffer is called).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
release_index_buffer(IndexBufferContext *ibc) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
ibc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
|
||||
// We have to set the Data pointer to NULL at this point, since
|
||||
// the Data itself might destruct at any time after it has been
|
||||
// released.
|
||||
ibc->_data = (qpGeomPrimitive *)NULL;
|
||||
|
||||
bool removed = (_prepared_index_buffers.erase(ibc) != 0);
|
||||
nassertv(removed);
|
||||
|
||||
_released_index_buffers.insert(ibc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::release_all_index_buffers
|
||||
// Access: Public
|
||||
// Description: Releases all datas at once. This will force them
|
||||
// to be reloaded into data memory for all GSG's that
|
||||
// share this object. Returns the number of datas
|
||||
// released.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PreparedGraphicsObjects::
|
||||
release_all_index_buffers() {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
int num_index_buffers = (int)_prepared_index_buffers.size();
|
||||
|
||||
IndexBuffers::iterator ibci;
|
||||
for (ibci = _prepared_index_buffers.begin();
|
||||
ibci != _prepared_index_buffers.end();
|
||||
++ibci) {
|
||||
IndexBufferContext *ibc = (*ibci);
|
||||
ibc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(ibc->get_data_size_bytes());
|
||||
ibc->_data = (qpGeomPrimitive *)NULL;
|
||||
|
||||
_released_index_buffers.insert(ibc);
|
||||
}
|
||||
|
||||
_prepared_index_buffers.clear();
|
||||
|
||||
return num_index_buffers;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::prepare_index_buffer_now
|
||||
// Access: Public
|
||||
// Description: Immediately creates a new IndexBufferContext for the
|
||||
// indicated data and returns it. This assumes that
|
||||
// the GraphicsStateGuardian is the currently active
|
||||
// rendering context and that it is ready to accept new
|
||||
// datas. If this is not necessarily the case, you
|
||||
// should use enqueue_index_buffer() instead.
|
||||
//
|
||||
// Normally, this function is not called directly. Call
|
||||
// Data::prepare_now() instead.
|
||||
//
|
||||
// The IndexBufferContext contains all of the pertinent
|
||||
// information needed by the GSG to keep track of this
|
||||
// one particular data, and will exist as long as the
|
||||
// data is ready to be rendered.
|
||||
//
|
||||
// When either the Data or the
|
||||
// PreparedGraphicsObjects object destructs, the
|
||||
// IndexBufferContext will be deleted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
IndexBufferContext *PreparedGraphicsObjects::
|
||||
prepare_index_buffer_now(qpGeomPrimitive *data, GraphicsStateGuardianBase *gsg) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
// Ask the GSG to create a brand new IndexBufferContext. There might
|
||||
// be several GSG's sharing the same set of datas; if so, it
|
||||
// doesn't matter which of them creates the context (since they're
|
||||
// all shared anyway).
|
||||
IndexBufferContext *ibc = gsg->prepare_index_buffer(data);
|
||||
|
||||
if (ibc != (IndexBufferContext *)NULL) {
|
||||
bool prepared = _prepared_index_buffers.insert(ibc).second;
|
||||
nassertr(prepared, ibc);
|
||||
|
||||
// The size has already been counted by
|
||||
// GraphicsStateGuardian::add_to_index_buffer_record(); we don't need to
|
||||
// count it again here.
|
||||
//_total_buffers_pcollector.add_level(ibc->get_data_size_bytes());
|
||||
}
|
||||
|
||||
return ibc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -537,7 +700,7 @@ void PreparedGraphicsObjects::
|
|||
update(GraphicsStateGuardianBase *gsg) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
// First, release all the textures, geoms, and data arrays awaiting
|
||||
// First, release all the textures, geoms, and buffers awaiting
|
||||
// release.
|
||||
Textures::iterator tci;
|
||||
for (tci = _released_textures.begin();
|
||||
|
|
@ -559,17 +722,27 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
|
||||
_released_geoms.clear();
|
||||
|
||||
Datas::iterator dci;
|
||||
for (dci = _released_datas.begin();
|
||||
dci != _released_datas.end();
|
||||
++dci) {
|
||||
DataContext *dc = (*dci);
|
||||
gsg->release_data(dc);
|
||||
VertexBuffers::iterator vbci;
|
||||
for (vbci = _released_vertex_buffers.begin();
|
||||
vbci != _released_vertex_buffers.end();
|
||||
++vbci) {
|
||||
VertexBufferContext *vbc = (*vbci);
|
||||
gsg->release_vertex_buffer(vbc);
|
||||
}
|
||||
|
||||
_released_datas.clear();
|
||||
_released_vertex_buffers.clear();
|
||||
|
||||
// Now prepare all the textures, geoms, and data arrays awaiting
|
||||
IndexBuffers::iterator ibci;
|
||||
for (ibci = _released_index_buffers.begin();
|
||||
ibci != _released_index_buffers.end();
|
||||
++ibci) {
|
||||
IndexBufferContext *ibc = (*ibci);
|
||||
gsg->release_index_buffer(ibc);
|
||||
}
|
||||
|
||||
_released_index_buffers.clear();
|
||||
|
||||
// Now prepare all the textures, geoms, and buffers awaiting
|
||||
// preparation.
|
||||
EnqueuedTextures::iterator qti;
|
||||
for (qti = _enqueued_textures.begin();
|
||||
|
|
@ -589,13 +762,25 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
geom->prepare_now(this, gsg);
|
||||
}
|
||||
|
||||
EnqueuedDatas::iterator qdi;
|
||||
for (qdi = _enqueued_datas.begin();
|
||||
qdi != _enqueued_datas.end();
|
||||
++qdi) {
|
||||
qpGeomVertexArrayData *data = (*qdi);
|
||||
_enqueued_geoms.clear();
|
||||
|
||||
EnqueuedVertexBuffers::iterator qvbi;
|
||||
for (qvbi = _enqueued_vertex_buffers.begin();
|
||||
qvbi != _enqueued_vertex_buffers.end();
|
||||
++qvbi) {
|
||||
qpGeomVertexArrayData *data = (*qvbi);
|
||||
data->prepare_now(this, gsg);
|
||||
}
|
||||
|
||||
_enqueued_datas.clear();
|
||||
_enqueued_vertex_buffers.clear();
|
||||
|
||||
EnqueuedIndexBuffers::iterator qibi;
|
||||
for (qibi = _enqueued_index_buffers.begin();
|
||||
qibi != _enqueued_index_buffers.end();
|
||||
++qibi) {
|
||||
qpGeomPrimitive *data = (*qibi);
|
||||
data->prepare_now(this, gsg);
|
||||
}
|
||||
|
||||
_enqueued_index_buffers.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "texture.h"
|
||||
#include "geom.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "qpgeomPrimitive.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "pset.h"
|
||||
|
|
@ -31,7 +32,8 @@
|
|||
|
||||
class TextureContext;
|
||||
class GeomContext;
|
||||
class DataContext;
|
||||
class VertexBufferContext;
|
||||
class IndexBufferContext;
|
||||
class GraphicsStateGuardianBase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -72,13 +74,23 @@ public:
|
|||
|
||||
GeomContext *prepare_geom_now(Geom *geom, GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void enqueue_data(qpGeomVertexArrayData *data);
|
||||
bool dequeue_data(qpGeomVertexArrayData *data);
|
||||
void release_data(DataContext *gc);
|
||||
int release_all_datas();
|
||||
void enqueue_vertex_buffer(qpGeomVertexArrayData *data);
|
||||
bool dequeue_vertex_buffer(qpGeomVertexArrayData *data);
|
||||
void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
int release_all_vertex_buffers();
|
||||
|
||||
DataContext *prepare_data_now(qpGeomVertexArrayData *data,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
VertexBufferContext *
|
||||
prepare_vertex_buffer_now(qpGeomVertexArrayData *data,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void enqueue_index_buffer(qpGeomPrimitive *data);
|
||||
bool dequeue_index_buffer(qpGeomPrimitive *data);
|
||||
void release_index_buffer(IndexBufferContext *ibc);
|
||||
int release_all_index_buffers();
|
||||
|
||||
IndexBufferContext *
|
||||
prepare_index_buffer_now(qpGeomPrimitive *data,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
|
||||
void update(GraphicsStateGuardianBase *gsg);
|
||||
|
||||
|
|
@ -87,16 +99,20 @@ private:
|
|||
typedef phash_set< PT(Texture) > EnqueuedTextures;
|
||||
typedef phash_set<GeomContext *, pointer_hash> Geoms;
|
||||
typedef phash_set< PT(Geom) > EnqueuedGeoms;
|
||||
typedef phash_set<DataContext *, pointer_hash> Datas;
|
||||
typedef phash_set< PT(qpGeomVertexArrayData) > EnqueuedDatas;
|
||||
typedef phash_set<VertexBufferContext *, pointer_hash> VertexBuffers;
|
||||
typedef phash_set< PT(qpGeomVertexArrayData) > EnqueuedVertexBuffers;
|
||||
typedef phash_set<IndexBufferContext *, pointer_hash> IndexBuffers;
|
||||
typedef phash_set< PT(qpGeomPrimitive) > EnqueuedIndexBuffers;
|
||||
|
||||
Mutex _lock;
|
||||
Textures _prepared_textures, _released_textures;
|
||||
EnqueuedTextures _enqueued_textures;
|
||||
Geoms _prepared_geoms, _released_geoms;
|
||||
EnqueuedGeoms _enqueued_geoms;
|
||||
Datas _prepared_datas, _released_datas;
|
||||
EnqueuedDatas _enqueued_datas;
|
||||
VertexBuffers _prepared_vertex_buffers, _released_vertex_buffers;
|
||||
EnqueuedVertexBuffers _enqueued_vertex_buffers;
|
||||
IndexBuffers _prepared_index_buffers, _released_index_buffers;
|
||||
EnqueuedIndexBuffers _enqueued_index_buffers;
|
||||
|
||||
static PStatCollector _total_texusage_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,27 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_usage_hint
|
||||
// Access: Published
|
||||
// Description: Returns the usage hint for this primitive. See
|
||||
// GeomUsageHint. This has nothing to do with the usage
|
||||
// hint associated with the primitive's vertices; this
|
||||
// only specifies how often the vertex indices that
|
||||
// define the primitive will be modified.
|
||||
//
|
||||
// It is perfectly legal (and, in fact, common) for a
|
||||
// GeomPrimitive to have UH_static on itself, while
|
||||
// referencing vertex data with UH_dynamic. This means
|
||||
// that the vertices themselves will be animated, but
|
||||
// the primitive will always reference the same set of
|
||||
// vertices from the pool.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomUsageHint::UsageHint qpGeomPrimitive::
|
||||
get_usage_hint() const {
|
||||
return _usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_shade_model
|
||||
// Access: Published
|
||||
|
|
@ -196,6 +217,31 @@ get_maxs() const {
|
|||
return cdata->_maxs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_data_size_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the number of bytes stored in the vertices
|
||||
// array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomPrimitive::
|
||||
get_data_size_bytes() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_vertices.size() * sizeof(short);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_modified
|
||||
// Access: Published
|
||||
// Description: Returns a sequence number which is guaranteed to
|
||||
// change at least every time the vertex index array is
|
||||
// modified.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq qpGeomPrimitive::
|
||||
get_modified() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::get_min_vertex
|
||||
// Access: Published
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "qpgeomVertexCacheManager.h"
|
||||
#include "preparedGraphicsObjects.h"
|
||||
#include "internalName.h"
|
||||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
|
|
@ -36,7 +37,9 @@ PStatCollector qpGeomPrimitive::_rotate_pcollector("Draw:Rotate");
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomPrimitive::
|
||||
qpGeomPrimitive() {
|
||||
qpGeomPrimitive(qpGeomUsageHint::UsageHint usage_hint) :
|
||||
_usage_hint(usage_hint)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -47,6 +50,7 @@ qpGeomPrimitive() {
|
|||
qpGeomPrimitive::
|
||||
qpGeomPrimitive(const qpGeomPrimitive ©) :
|
||||
TypedWritableReferenceCount(copy),
|
||||
_usage_hint(copy._usage_hint),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
}
|
||||
|
|
@ -75,6 +79,8 @@ qpGeomPrimitive::
|
|||
_cycler.release_write_stage(i, cdata);
|
||||
}
|
||||
}
|
||||
|
||||
release_all();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -527,6 +533,134 @@ clear_cache() {
|
|||
cache_mgr->remove_primitive(this);
|
||||
cdata->_decomposed = NULL;
|
||||
}
|
||||
|
||||
// This, on the other hand, should be applied to the current
|
||||
// pipeline stage.
|
||||
++(cdata->_modified);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::prepare
|
||||
// Access: Published
|
||||
// Description: Indicates that the data should be enqueued to be
|
||||
// prepared in the indicated prepared_objects at the
|
||||
// beginning of the next frame. This will ensure the
|
||||
// data is already loaded into the GSG if it is expected
|
||||
// to be rendered soon.
|
||||
//
|
||||
// Use this function instead of prepare_now() to preload
|
||||
// datas from a user interface standpoint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
prepare(PreparedGraphicsObjects *prepared_objects) {
|
||||
prepared_objects->enqueue_index_buffer(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::prepare_now
|
||||
// Access: Public
|
||||
// Description: Creates a context for the data on the particular
|
||||
// GSG, if it does not already exist. Returns the new
|
||||
// (or old) IndexBufferContext. This assumes that the
|
||||
// GraphicsStateGuardian is the currently active
|
||||
// rendering context and that it is ready to accept new
|
||||
// datas. If this is not necessarily the case, you
|
||||
// should use prepare() instead.
|
||||
//
|
||||
// Normally, this is not called directly except by the
|
||||
// GraphicsStateGuardian; a data does not need to be
|
||||
// explicitly prepared by the user before it may be
|
||||
// rendered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
IndexBufferContext *qpGeomPrimitive::
|
||||
prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg) {
|
||||
Contexts::const_iterator ci;
|
||||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
return (*ci).second;
|
||||
}
|
||||
|
||||
IndexBufferContext *ibc = prepared_objects->prepare_index_buffer_now(this, gsg);
|
||||
if (ibc != (IndexBufferContext *)NULL) {
|
||||
_contexts[prepared_objects] = ibc;
|
||||
}
|
||||
return ibc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::release
|
||||
// Access: Public
|
||||
// Description: Frees the data context only on the indicated object,
|
||||
// if it exists there. Returns true if it was released,
|
||||
// false if it had not been prepared.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool qpGeomPrimitive::
|
||||
release(PreparedGraphicsObjects *prepared_objects) {
|
||||
Contexts::iterator ci;
|
||||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
IndexBufferContext *ibc = (*ci).second;
|
||||
prepared_objects->release_index_buffer(ibc);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Maybe it wasn't prepared yet, but it's about to be.
|
||||
return prepared_objects->dequeue_index_buffer(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::release_all
|
||||
// Access: Public
|
||||
// Description: Frees the context allocated on all objects for which
|
||||
// the data has been declared. Returns the number of
|
||||
// contexts which have been freed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int qpGeomPrimitive::
|
||||
release_all() {
|
||||
// We have to traverse a copy of the _contexts list, because the
|
||||
// PreparedGraphicsObjects object will call clear_prepared() in response
|
||||
// to each release_index_buffer(), and we don't want to be modifying the
|
||||
// _contexts list while we're traversing it.
|
||||
Contexts temp = _contexts;
|
||||
int num_freed = (int)_contexts.size();
|
||||
|
||||
Contexts::const_iterator ci;
|
||||
for (ci = temp.begin(); ci != temp.end(); ++ci) {
|
||||
PreparedGraphicsObjects *prepared_objects = (*ci).first;
|
||||
IndexBufferContext *ibc = (*ci).second;
|
||||
prepared_objects->release_index_buffer(ibc);
|
||||
}
|
||||
|
||||
// Now that we've called release_index_buffer() on every known context,
|
||||
// the _contexts list should have completely emptied itself.
|
||||
nassertr(_contexts.empty(), num_freed);
|
||||
|
||||
return num_freed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomPrimitive::clear_prepared
|
||||
// Access: Private
|
||||
// Description: Removes the indicated PreparedGraphicsObjects table
|
||||
// from the data array's table, without actually
|
||||
// releasing the data array. This is intended to be
|
||||
// called only from
|
||||
// PreparedGraphicsObjects::release_index_buffer(); it should
|
||||
// never be called by user code.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomPrimitive::
|
||||
clear_prepared(PreparedGraphicsObjects *prepared_objects) {
|
||||
Contexts::iterator ci;
|
||||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
_contexts.erase(ci);
|
||||
} else {
|
||||
// If this assertion fails, clear_prepared() was given a
|
||||
// prepared_objects which the data array didn't know about.
|
||||
nassertv(false);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -20,8 +20,10 @@
|
|||
#define qpGEOMPRIMITIVE_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "qpgeomUsageHint.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "luse.h"
|
||||
#include "updateSeq.h"
|
||||
#include "pointerTo.h"
|
||||
#include "pta_ushort.h"
|
||||
#include "pta_int.h"
|
||||
|
|
@ -32,8 +34,9 @@
|
|||
#include "pipelineCycler.h"
|
||||
|
||||
class qpGeomVertexData;
|
||||
class PreparedGraphicsObjects;
|
||||
class IndexBufferContext;
|
||||
class GraphicsStateGuardianBase;
|
||||
class GeomContext;
|
||||
class FactoryParams;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -61,7 +64,7 @@ class FactoryParams;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomPrimitive : public TypedWritableReferenceCount {
|
||||
PUBLISHED:
|
||||
qpGeomPrimitive();
|
||||
qpGeomPrimitive(qpGeomUsageHint::UsageHint usage_hint);
|
||||
qpGeomPrimitive(const qpGeomPrimitive ©);
|
||||
virtual ~qpGeomPrimitive();
|
||||
|
||||
|
|
@ -88,6 +91,8 @@ PUBLISHED:
|
|||
SM_flat_last_vertex,
|
||||
};
|
||||
|
||||
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
||||
|
||||
INLINE ShadeModel get_shade_model() const;
|
||||
INLINE void set_shade_model(ShadeModel shade_model);
|
||||
|
||||
|
|
@ -112,6 +117,8 @@ PUBLISHED:
|
|||
INLINE CPTA_ushort get_maxs() const;
|
||||
|
||||
int get_num_bytes() const;
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
INLINE int get_min_vertex() const;
|
||||
INLINE int get_min_vertex(int i) const;
|
||||
|
|
@ -132,6 +139,17 @@ PUBLISHED:
|
|||
|
||||
void clear_cache();
|
||||
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
public:
|
||||
IndexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
public:
|
||||
virtual void draw(GraphicsStateGuardianBase *gsg) const=0;
|
||||
|
||||
|
|
@ -151,6 +169,16 @@ protected:
|
|||
static PStatCollector _rotate_pcollector;
|
||||
|
||||
private:
|
||||
qpGeomUsageHint::UsageHint _usage_hint;
|
||||
|
||||
// A GeomPrimitive keeps a list (actually, a map) of all the
|
||||
// PreparedGraphicsObjects tables that it has been prepared into.
|
||||
// Each PGO conversely keeps a list (a set) of all the Geoms that
|
||||
// have been prepared there. When either destructs, it removes
|
||||
// itself from the other's list.
|
||||
typedef pmap<PreparedGraphicsObjects *, IndexBufferContext *> Contexts;
|
||||
Contexts _contexts;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
|
|
@ -167,6 +195,7 @@ private:
|
|||
PTA_int _ends;
|
||||
PTA_ushort _mins;
|
||||
PTA_ushort _maxs;
|
||||
UpdateSeq _modified;
|
||||
|
||||
bool _got_minmax;
|
||||
unsigned short _min_vertex;
|
||||
|
|
@ -206,6 +235,7 @@ private:
|
|||
|
||||
friend class qpGeom;
|
||||
friend class qpGeomVertexCacheManager;
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
#include "qpgeomPrimitive.I"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ TypeHandle qpGeomTriangles::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTriangles::
|
||||
qpGeomTriangles() {
|
||||
qpGeomTriangles(qpGeomUsageHint::UsageHint usage_hint) :
|
||||
qpGeomPrimitive(usage_hint)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -158,7 +160,7 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomTriangles::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomTriangles *object = new qpGeomTriangles;
|
||||
qpGeomTriangles *object = new qpGeomTriangles(qpGeomUsageHint::UH_client);
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomTriangles : public qpGeomPrimitive {
|
||||
PUBLISHED:
|
||||
qpGeomTriangles();
|
||||
qpGeomTriangles(qpGeomUsageHint::UsageHint usage_hint);
|
||||
qpGeomTriangles(const qpGeomTriangles ©);
|
||||
virtual ~qpGeomTriangles();
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,9 @@ TypeHandle qpGeomTrifans::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTrifans::
|
||||
qpGeomTrifans() {
|
||||
qpGeomTrifans(qpGeomUsageHint::UsageHint usage_hint) :
|
||||
qpGeomPrimitive(usage_hint)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -89,7 +91,7 @@ draw(GraphicsStateGuardianBase *gsg) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomPrimitive) qpGeomTrifans::
|
||||
decompose_impl() const {
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles;
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles(get_usage_hint());
|
||||
triangles->set_shade_model(get_shade_model());
|
||||
CPTA_ushort vertices = get_vertices();
|
||||
CPTA_int ends = get_ends();
|
||||
|
|
@ -154,7 +156,7 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomTrifans::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomTrifans *object = new qpGeomTrifans;
|
||||
qpGeomTrifans *object = new qpGeomTrifans(qpGeomUsageHint::UH_client);
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomTrifans : public qpGeomPrimitive {
|
||||
PUBLISHED:
|
||||
qpGeomTrifans();
|
||||
qpGeomTrifans(qpGeomUsageHint::UsageHint usage_hint);
|
||||
qpGeomTrifans(const qpGeomTrifans ©);
|
||||
virtual ~qpGeomTrifans();
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ TypeHandle qpGeomTristrips::_type_handle;
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomTristrips::
|
||||
qpGeomTristrips() {
|
||||
qpGeomTristrips(qpGeomUsageHint::UsageHint usage_hint) :
|
||||
qpGeomPrimitive(usage_hint)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -90,7 +92,7 @@ draw(GraphicsStateGuardianBase *gsg) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
CPT(qpGeomPrimitive) qpGeomTristrips::
|
||||
decompose_impl() const {
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles;
|
||||
PT(qpGeomTriangles) triangles = new qpGeomTriangles(get_usage_hint());
|
||||
triangles->set_shade_model(get_shade_model());
|
||||
CPTA_ushort vertices = get_vertices();
|
||||
CPTA_int ends = get_ends();
|
||||
|
|
@ -240,7 +242,7 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
TypedWritable *qpGeomTristrips::
|
||||
make_from_bam(const FactoryParams ¶ms) {
|
||||
qpGeomTristrips *object = new qpGeomTristrips;
|
||||
qpGeomTristrips *object = new qpGeomTristrips(qpGeomUsageHint::UH_client);
|
||||
DatagramIterator scan;
|
||||
BamReader *manager;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomTristrips : public qpGeomPrimitive {
|
||||
PUBLISHED:
|
||||
qpGeomTristrips();
|
||||
qpGeomTristrips(qpGeomUsageHint::UsageHint usage_hint);
|
||||
qpGeomTristrips(const qpGeomTristrips ©);
|
||||
virtual ~qpGeomTristrips();
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
// Filename: qpgeomUsageHint.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 qpGEOMUSAGEHINT_H
|
||||
#define qpGEOMUSAGEHINT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomUsageHint
|
||||
// Description : This class exists just to provide scoping for the
|
||||
// UsageHint enumerated type, which is used by
|
||||
// GeomVertexData, GeomVertexArrayData, and
|
||||
// GeomPrimitive.
|
||||
//
|
||||
// The usage hint describes to the rendering backend how
|
||||
// often the data in question will be modified and/or
|
||||
// rendered. It allows the backend to make appropriate
|
||||
// choices about what part of memory the data should be
|
||||
// stored in.
|
||||
//
|
||||
// The hint is provided as a performance optimization
|
||||
// only, and does not constraing actual usage; although
|
||||
// it may be an important optimization.
|
||||
//
|
||||
// In general, the hint may only be specified at the
|
||||
// time the data object is constructed. If you need to
|
||||
// change it, you must create a new object (but in many
|
||||
// cases you can just assign the same internal data
|
||||
// pointer to the new object, to keep the same
|
||||
// client-side memory).
|
||||
//
|
||||
// This is part of the experimental Geom rewrite.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA qpGeomUsageHint {
|
||||
PUBLISHED:
|
||||
enum UsageHint {
|
||||
// UH_client: don't attempt to upload the data; always keep it on
|
||||
// the client.
|
||||
UH_client,
|
||||
|
||||
// UH_stream: the data will be created once, used to render a few
|
||||
// times, and then discarded. This should be used for short-lived
|
||||
// temporary arrays.
|
||||
UH_stream,
|
||||
|
||||
// UH_static: the data will be created once, and used to render
|
||||
// many times, without modification. This is the most common
|
||||
// case, since typically vertex data is not directly animated
|
||||
// (this is not related to scene graph animation, e.g. from
|
||||
// adjusting transforms on a node).
|
||||
UH_static,
|
||||
|
||||
// UH_dynamic: the data will be repeatedly modified and
|
||||
// re-rendered. This is for data that will be modified at
|
||||
// runtime, such as animated or soft-skinned vertices.
|
||||
UH_dynamic,
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -32,17 +32,9 @@ get_array_format() const {
|
|||
// Access: Published
|
||||
// Description: Returns the usage hint that describes to the
|
||||
// rendering backend how often the vertex data will be
|
||||
// modified and/or rendered. This is provided as a
|
||||
// performance optimization only, and does not
|
||||
// constraing actual usage; although it may be an
|
||||
// important optimization.
|
||||
//
|
||||
// This may only be specified to the GeomVertexArrayData
|
||||
// constructor. If you need to change it, you must
|
||||
// create a new GeomVertexArrayData object (but you can
|
||||
// just assign the same data pointer to the new object).
|
||||
// modified and/or rendered. See GeomUsageHint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData::UsageHint qpGeomVertexArrayData::
|
||||
INLINE qpGeomUsageHint::UsageHint qpGeomVertexArrayData::
|
||||
get_usage_hint() const {
|
||||
return _usage_hint;
|
||||
}
|
||||
|
|
@ -107,7 +99,7 @@ set_data(CPTA_uchar array) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayData::
|
||||
get_num_vertices() const {
|
||||
return get_num_bytes() / _array_format->get_stride();
|
||||
return get_data_size_bytes() / _array_format->get_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -122,12 +114,12 @@ clear_vertices() {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: qpGeomVertexArrayData::get_num_bytes
|
||||
// Function: qpGeomVertexArrayData::get_data_size_bytes
|
||||
// Access: Published
|
||||
// Description: Returns the number of bytes stored in the array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int qpGeomVertexArrayData::
|
||||
get_num_bytes() const {
|
||||
get_data_size_bytes() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_data.size();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ qpGeomVertexArrayData() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexArrayData::
|
||||
qpGeomVertexArrayData(const qpGeomVertexArrayFormat *array_format,
|
||||
qpGeomVertexArrayData::UsageHint usage_hint) :
|
||||
qpGeomUsageHint::UsageHint usage_hint) :
|
||||
_array_format(array_format),
|
||||
_usage_hint(usage_hint)
|
||||
{
|
||||
|
|
@ -147,7 +147,7 @@ set_num_vertices(int n) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
prepare(PreparedGraphicsObjects *prepared_objects) {
|
||||
prepared_objects->enqueue_data(this);
|
||||
prepared_objects->enqueue_vertex_buffer(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -155,7 +155,7 @@ prepare(PreparedGraphicsObjects *prepared_objects) {
|
|||
// Access: Public
|
||||
// Description: Creates a context for the data on the particular
|
||||
// GSG, if it does not already exist. Returns the new
|
||||
// (or old) DataContext. This assumes that the
|
||||
// (or old) VertexBufferContext. This assumes that the
|
||||
// GraphicsStateGuardian is the currently active
|
||||
// rendering context and that it is ready to accept new
|
||||
// datas. If this is not necessarily the case, you
|
||||
|
|
@ -166,7 +166,7 @@ prepare(PreparedGraphicsObjects *prepared_objects) {
|
|||
// explicitly prepared by the user before it may be
|
||||
// rendered.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DataContext *qpGeomVertexArrayData::
|
||||
VertexBufferContext *qpGeomVertexArrayData::
|
||||
prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg) {
|
||||
Contexts::const_iterator ci;
|
||||
|
|
@ -175,11 +175,11 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
|
|||
return (*ci).second;
|
||||
}
|
||||
|
||||
DataContext *dc = prepared_objects->prepare_data_now(this, gsg);
|
||||
if (dc != (DataContext *)NULL) {
|
||||
_contexts[prepared_objects] = dc;
|
||||
VertexBufferContext *vbc = prepared_objects->prepare_vertex_buffer_now(this, gsg);
|
||||
if (vbc != (VertexBufferContext *)NULL) {
|
||||
_contexts[prepared_objects] = vbc;
|
||||
}
|
||||
return dc;
|
||||
return vbc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -194,13 +194,13 @@ release(PreparedGraphicsObjects *prepared_objects) {
|
|||
Contexts::iterator ci;
|
||||
ci = _contexts.find(prepared_objects);
|
||||
if (ci != _contexts.end()) {
|
||||
DataContext *dc = (*ci).second;
|
||||
prepared_objects->release_data(dc);
|
||||
VertexBufferContext *vbc = (*ci).second;
|
||||
prepared_objects->release_vertex_buffer(vbc);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Maybe it wasn't prepared yet, but it's about to be.
|
||||
return prepared_objects->dequeue_data(this);
|
||||
return prepared_objects->dequeue_vertex_buffer(this);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -214,7 +214,7 @@ int qpGeomVertexArrayData::
|
|||
release_all() {
|
||||
// We have to traverse a copy of the _contexts list, because the
|
||||
// PreparedGraphicsObjects object will call clear_prepared() in response
|
||||
// to each release_data(), and we don't want to be modifying the
|
||||
// to each release_vertex_buffer(), and we don't want to be modifying the
|
||||
// _contexts list while we're traversing it.
|
||||
Contexts temp = _contexts;
|
||||
int num_freed = (int)_contexts.size();
|
||||
|
|
@ -222,11 +222,11 @@ release_all() {
|
|||
Contexts::const_iterator ci;
|
||||
for (ci = temp.begin(); ci != temp.end(); ++ci) {
|
||||
PreparedGraphicsObjects *prepared_objects = (*ci).first;
|
||||
DataContext *dc = (*ci).second;
|
||||
prepared_objects->release_data(dc);
|
||||
VertexBufferContext *vbc = (*ci).second;
|
||||
prepared_objects->release_vertex_buffer(vbc);
|
||||
}
|
||||
|
||||
// Now that we've called release_data() on every known context,
|
||||
// Now that we've called release_vertex_buffer() on every known context,
|
||||
// the _contexts list should have completely emptied itself.
|
||||
nassertr(_contexts.empty(), num_freed);
|
||||
|
||||
|
|
@ -240,7 +240,7 @@ release_all() {
|
|||
// from the data array's table, without actually
|
||||
// releasing the data array. This is intended to be
|
||||
// called only from
|
||||
// PreparedGraphicsObjects::release_data(); it should
|
||||
// PreparedGraphicsObjects::release_vertex_buffer(); it should
|
||||
// never be called by user code.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void qpGeomVertexArrayData::
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "pandabase.h"
|
||||
#include "typedWritableReferenceCount.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "qpgeomUsageHint.h"
|
||||
#include "pta_uchar.h"
|
||||
#include "updateSeq.h"
|
||||
#include "cycleData.h"
|
||||
|
|
@ -31,7 +32,7 @@
|
|||
#include "pmap.h"
|
||||
|
||||
class PreparedGraphicsObjects;
|
||||
class DataContext;
|
||||
class VertexBufferContext;
|
||||
class GraphicsStateGuardianBase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -53,26 +54,8 @@ private:
|
|||
qpGeomVertexArrayData();
|
||||
|
||||
PUBLISHED:
|
||||
enum UsageHint {
|
||||
// UH_client: don't attempt to upload the data as a "vertex
|
||||
// buffer"; always keep it on the client.
|
||||
UH_client,
|
||||
|
||||
// UH_stream: the data will be created once, used to render a few
|
||||
// times, and then discarded.
|
||||
UH_stream,
|
||||
|
||||
// UH_static: the data will be created once, and used to render
|
||||
// many times, without modification.
|
||||
UH_static,
|
||||
|
||||
// UH_dynamic: the data will be repeatedly modified and
|
||||
// re-rendered.
|
||||
UH_dynamic,
|
||||
};
|
||||
|
||||
qpGeomVertexArrayData(const qpGeomVertexArrayFormat *array_format,
|
||||
UsageHint usage_hint);
|
||||
qpGeomUsageHint::UsageHint usage_hint);
|
||||
qpGeomVertexArrayData(const qpGeomVertexArrayData ©);
|
||||
private:
|
||||
void operator = (const qpGeomVertexArrayData ©);
|
||||
|
|
@ -80,7 +63,7 @@ PUBLISHED:
|
|||
virtual ~qpGeomVertexArrayData();
|
||||
|
||||
INLINE const qpGeomVertexArrayFormat *get_array_format() const;
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
||||
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
INLINE PTA_uchar modify_data();
|
||||
|
|
@ -90,14 +73,14 @@ PUBLISHED:
|
|||
bool set_num_vertices(int n);
|
||||
INLINE void clear_vertices();
|
||||
|
||||
INLINE int get_num_bytes() const;
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
public:
|
||||
DataContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
VertexBufferContext *prepare_now(PreparedGraphicsObjects *prepared_objects,
|
||||
GraphicsStateGuardianBase *gsg);
|
||||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
|
|
@ -105,14 +88,14 @@ private:
|
|||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
|
||||
CPT(qpGeomVertexArrayFormat) _array_format;
|
||||
UsageHint _usage_hint;
|
||||
qpGeomUsageHint::UsageHint _usage_hint;
|
||||
|
||||
// A GeomVertexArrayData keeps a list (actually, a map) of all the
|
||||
// PreparedGraphicsObjects tables that it has been prepared into.
|
||||
// Each PGO conversely keeps a list (a set) of all the Geoms that
|
||||
// have been prepared there. When either destructs, it removes
|
||||
// itself from the other's list.
|
||||
typedef pmap<PreparedGraphicsObjects *, DataContext *> Contexts;
|
||||
typedef pmap<PreparedGraphicsObjects *, VertexBufferContext *> Contexts;
|
||||
Contexts _contexts;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
|
|
|
|||
|
|
@ -33,14 +33,16 @@ get_format() const {
|
|||
// Access: Published
|
||||
// Description: Returns the usage hint that was passed to the
|
||||
// constructor, and which will be passed to each array
|
||||
// data object created initially. However, each
|
||||
// individual array may be replaced with a different
|
||||
// array object with an independent usage hint
|
||||
// specified.
|
||||
// data object created initially, and arrays created as
|
||||
// the result of a convert_to() operation. See
|
||||
// GeomUsageHint.
|
||||
//
|
||||
// See GeomVertexArrayData::get_usage_hint().
|
||||
// However, each individual array may be replaced with a
|
||||
// different array object with an independent usage hint
|
||||
// specified, so there is no guarantee that the
|
||||
// individual arrays all have the same usage_hint.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData::UsageHint qpGeomVertexData::
|
||||
INLINE qpGeomUsageHint::UsageHint qpGeomVertexData::
|
||||
get_usage_hint() const {
|
||||
return _usage_hint;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ qpGeomVertexData() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
qpGeomVertexData::
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format,
|
||||
qpGeomVertexArrayData::UsageHint usage_hint) :
|
||||
qpGeomUsageHint::UsageHint usage_hint) :
|
||||
_format(format),
|
||||
_usage_hint(usage_hint)
|
||||
{
|
||||
|
|
@ -132,7 +132,7 @@ get_num_vertices() const {
|
|||
|
||||
// Look up the answer on the first array (since any array will do).
|
||||
int stride = _format->get_array(0)->get_stride();
|
||||
return cdata->_arrays[0]->get_num_bytes() / stride;
|
||||
return cdata->_arrays[0]->get_data_size_bytes() / stride;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -211,7 +211,7 @@ get_num_bytes() const {
|
|||
|
||||
Arrays::const_iterator ai;
|
||||
for (ai = cdata->_arrays.begin(); ai != cdata->_arrays.end(); ++ai) {
|
||||
num_bytes += (*ai)->get_num_bytes();
|
||||
num_bytes += (*ai)->get_data_size_bytes();
|
||||
}
|
||||
|
||||
return num_bytes;
|
||||
|
|
@ -405,7 +405,7 @@ set_data(int array, const qpGeomVertexDataType *data_type,
|
|||
|
||||
{
|
||||
CDReader cdata(_cycler);
|
||||
int array_size = (int)cdata->_arrays[array]->get_num_bytes();
|
||||
int array_size = (int)cdata->_arrays[array]->get_data_size_bytes();
|
||||
if (element + data_type->get_total_bytes() > array_size) {
|
||||
// Whoops, we need more vertices!
|
||||
CDWriter cdataw(_cycler, cdata);
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "qpgeomVertexFormat.h"
|
||||
#include "qpgeomVertexDataType.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "qpgeomUsageHint.h"
|
||||
#include "internalName.h"
|
||||
#include "cycleData.h"
|
||||
#include "cycleDataReader.h"
|
||||
|
|
@ -63,13 +64,13 @@ private:
|
|||
qpGeomVertexData();
|
||||
PUBLISHED:
|
||||
qpGeomVertexData(const qpGeomVertexFormat *format,
|
||||
qpGeomVertexArrayData::UsageHint usage_hint);
|
||||
qpGeomUsageHint::UsageHint usage_hint);
|
||||
qpGeomVertexData(const qpGeomVertexData ©);
|
||||
void operator = (const qpGeomVertexData ©);
|
||||
virtual ~qpGeomVertexData();
|
||||
|
||||
INLINE const qpGeomVertexFormat *get_format() const;
|
||||
INLINE qpGeomVertexArrayData::UsageHint get_usage_hint() const;
|
||||
INLINE qpGeomUsageHint::UsageHint get_usage_hint() const;
|
||||
|
||||
int get_num_vertices() const;
|
||||
INLINE bool set_num_vertices(int n);
|
||||
|
|
@ -113,7 +114,7 @@ private:
|
|||
|
||||
private:
|
||||
CPT(qpGeomVertexFormat) _format;
|
||||
qpGeomVertexArrayData::UsageHint _usage_hint;
|
||||
qpGeomUsageHint::UsageHint _usage_hint;
|
||||
|
||||
typedef pvector< PT(qpGeomVertexArrayData) > Arrays;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
// Filename: vertexBufferContext.I
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE VertexBufferContext::
|
||||
VertexBufferContext(qpGeomVertexArrayData *data) :
|
||||
_data(data),
|
||||
// Initially, the number of bytes is zero, until the data has been
|
||||
// loaded (and mark_loaded() is called).
|
||||
_data_size_bytes(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::get_data
|
||||
// Access: Public
|
||||
// Description: Returns the pointer to the client-side array data
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData *VertexBufferContext::
|
||||
get_data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::get_data_size_bytes
|
||||
// Access: Public
|
||||
// Description: Returns the number of bytes previously reported for
|
||||
// the data object. This is used to track changes in
|
||||
// the data object's allocated size; if it changes from
|
||||
// this, we need to create a new buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int VertexBufferContext::
|
||||
get_data_size_bytes() const {
|
||||
return _data_size_bytes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::changed_size
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has changed size since the
|
||||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VertexBufferContext::
|
||||
changed_size() const {
|
||||
return get_data_size_bytes() != _data->get_data_size_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::was_modified
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has been modified since the
|
||||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VertexBufferContext::
|
||||
was_modified() const {
|
||||
return _modified != _data->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: VertexBufferContext::mark_loaded
|
||||
// Access: Public
|
||||
// Description: Should be called after the VertexBufferContext has been
|
||||
// loaded into graphics memory, this updates the
|
||||
// internal flags for changed_size() and modified().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void VertexBufferContext::
|
||||
mark_loaded() {
|
||||
_data_size_bytes = _data->get_data_size_bytes();
|
||||
_modified = _data->get_modified();
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
// Filename: vertexBufferContext.cxx
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "vertexBufferContext.h"
|
||||
|
||||
TypeHandle VertexBufferContext::_type_handle;
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// Filename: dataContext.h
|
||||
// Filename: vertexBufferContext.h
|
||||
// Created by: drose (17Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -16,8 +16,8 @@
|
|||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef DATACONTEXT_H
|
||||
#define DATACONTEXT_H
|
||||
#ifndef VERTEXBUFFERCONTEXT_H
|
||||
#define VERTEXBUFFERCONTEXT_H
|
||||
|
||||
#include "pandabase.h"
|
||||
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
#include "qpgeomVertexArrayData.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DataContext
|
||||
// Class : VertexBufferContext
|
||||
// Description : This is a special class object that holds all the
|
||||
// information returned by a particular GSG to indicate
|
||||
// the vertex data array's internal context identifier.
|
||||
|
|
@ -36,13 +36,13 @@
|
|||
// allocate a vertex buffer for the array. OpenGL can
|
||||
// create a buffer object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA DataContext : public SavedContext {
|
||||
class EXPCL_PANDA VertexBufferContext : public SavedContext {
|
||||
public:
|
||||
INLINE DataContext(qpGeomVertexArrayData *data);
|
||||
INLINE VertexBufferContext(qpGeomVertexArrayData *data);
|
||||
|
||||
INLINE qpGeomVertexArrayData *get_data() const;
|
||||
|
||||
INLINE int get_num_bytes() const;
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE bool changed_size() const;
|
||||
INLINE bool was_modified() const;
|
||||
|
||||
|
|
@ -50,11 +50,11 @@ public:
|
|||
|
||||
private:
|
||||
// This cannot be a PT(qpGeomVertexArrayData), because the data and
|
||||
// the GSG both own their DataContexts! That would create a
|
||||
// the GSG both own their VertexBufferContexts! That would create a
|
||||
// circular reference count.
|
||||
qpGeomVertexArrayData *_data;
|
||||
UpdateSeq _modified;
|
||||
int _num_bytes;
|
||||
int _data_size_bytes;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -62,7 +62,7 @@ public:
|
|||
}
|
||||
static void init_type() {
|
||||
SavedContext::init_type();
|
||||
register_type(_type_handle, "DataContext",
|
||||
register_type(_type_handle, "VertexBufferContext",
|
||||
SavedContext::get_class_type());
|
||||
}
|
||||
virtual TypeHandle get_type() const {
|
||||
|
|
@ -76,7 +76,7 @@ private:
|
|||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
#include "dataContext.I"
|
||||
#include "vertexBufferContext.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -30,7 +30,8 @@ class RenderBuffer;
|
|||
class GraphicsWindow;
|
||||
class NodePath;
|
||||
|
||||
class DataContext;
|
||||
class VertexBufferContext;
|
||||
class IndexBufferContext;
|
||||
class GeomContext;
|
||||
class GeomNode;
|
||||
class Geom;
|
||||
|
|
@ -46,6 +47,7 @@ class GeomTrifan;
|
|||
class GeomSphere;
|
||||
class qpGeomVertexData;
|
||||
class qpGeomVertexArrayData;
|
||||
class qpGeomPrimitive;
|
||||
class qpGeomTriangles;
|
||||
class qpGeomTristrips;
|
||||
class qpGeomTrifans;
|
||||
|
|
@ -134,8 +136,11 @@ public:
|
|||
virtual GeomContext *prepare_geom(Geom *geom)=0;
|
||||
virtual void release_geom(GeomContext *gc)=0;
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data)=0;
|
||||
virtual void release_data(DataContext *gc)=0;
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(qpGeomVertexArrayData *data)=0;
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc)=0;
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(qpGeomPrimitive *data)=0;
|
||||
virtual void release_index_buffer(IndexBufferContext *ibc)=0;
|
||||
|
||||
virtual CPT(qpGeomMunger) get_geom_munger(const RenderState *state)=0;
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,8 @@ static LevelCollectorProperties level_properties[] = {
|
|||
{ 1, "Prepared Geoms:Active", { 0.5, 1.0, 0.8 } },
|
||||
{ 1, "Prepared GeomNodes", { 1.0, 0.0, 0.5 }, "", 500 },
|
||||
{ 1, "Prepared GeomNodes:Active", { 0.5, 1.0, 0.8 } },
|
||||
{ 1, "Vertex buffers:Active", { 1.0, 0.0, 0.5 } },
|
||||
{ 1, "Vertex buffers:Active vertex", { 1.0, 0.0, 0.5 } },
|
||||
{ 1, "Vertex buffers:Active index" , { 0.5, 0.6, 1.0 } },
|
||||
{ 1, "Vertex buffers", { 0.0, 0.0, 1.0 }, "MB", 12, 1048576 },
|
||||
{ 1, "Vertices", { 0.5, 0.2, 0.0 }, "K", 10, 1000 },
|
||||
{ 1, "Vertices:Other", { 0.2, 0.2, 0.2 } },
|
||||
|
|
|
|||
Loading…
Reference in New Issue