beginning dx8 vbuffer support
This commit is contained in:
parent
aeeca93186
commit
0edc10b609
|
|
@ -47,8 +47,8 @@ PStatCollector GraphicsStateGuardian::_total_texusage_pcollector("Texture usage"
|
|||
PStatCollector GraphicsStateGuardian::_active_texusage_pcollector("Texture usage:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_pcollector("Prepared Geoms");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_pcollector("Prepared Geoms:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffers_pcollector("Prepared Bufferss");
|
||||
PStatCollector GraphicsStateGuardian::_active_buffers_pcollector("Prepared Bufferss:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_buffers_pcollector("Vertex Buffers");
|
||||
PStatCollector GraphicsStateGuardian::_active_buffers_pcollector("Vertex Buffers:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_geom_node_pcollector("Prepared GeomNodes");
|
||||
PStatCollector GraphicsStateGuardian::_active_geom_node_pcollector("Prepared GeomNodes:Active");
|
||||
PStatCollector GraphicsStateGuardian::_total_texmem_pcollector("Texture memory");
|
||||
|
|
@ -1446,6 +1446,7 @@ init_frame_pstats() {
|
|||
_active_texusage_pcollector.clear_level();
|
||||
_active_geom_pcollector.clear_level();
|
||||
_active_geom_node_pcollector.clear_level();
|
||||
_active_buffers_pcollector.clear_level();
|
||||
|
||||
// Also clear out our other counters while we're here.
|
||||
_vertices_tristrip_pcollector.clear_level();
|
||||
|
|
@ -1507,7 +1508,9 @@ void GraphicsStateGuardian::
|
|||
add_to_data_record(DataContext *dc) {
|
||||
if (PStatClient::is_connected()) {
|
||||
if (dc != (DataContext *)NULL && _current_datas.insert(dc).second) {
|
||||
_active_buffers_pcollector.add_level(dc->_data->get_num_bytes());
|
||||
int delta = dc->get_data()->get_num_bytes() - dc->get_num_bytes();
|
||||
_total_buffers_pcollector.add_level(delta);
|
||||
_active_buffers_pcollector.add_level(dc->get_data()->get_num_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1555,6 +1558,13 @@ get_untextured_state() {
|
|||
return state;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsStateGuardian::traverse_prepared_textures
|
||||
// Access: Public
|
||||
// Description: Calls the indicated function on all
|
||||
// currently-prepared textures, or until the callback
|
||||
// function returns false.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GraphicsStateGuardian::
|
||||
traverse_prepared_textures(bool (*pertex_callbackfn)(TextureContext *,void *),void *callback_arg) {
|
||||
PreparedGraphicsObjects::Textures::const_iterator ti;
|
||||
|
|
|
|||
|
|
@ -20,6 +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 \
|
||||
dxTextureContext8.h \
|
||||
dxGeomMunger8.h \
|
||||
d3dfont8.h \
|
||||
|
|
@ -36,6 +37,7 @@
|
|||
|
||||
#define INCLUDED_SOURCES \
|
||||
config_dxgsg8.cxx \
|
||||
dxDataContext8.cxx \
|
||||
dxTextureContext8.cxx \
|
||||
dxGeomMunger8.cxx \
|
||||
d3dfont8.cxx \
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "config_dxgsg8.h"
|
||||
#include "dxGraphicsStateGuardian8.h"
|
||||
#include "dxTextureContext8.h"
|
||||
#include "dxDataContext8.h"
|
||||
#include "dxGeomMunger8.h"
|
||||
#include "graphicsPipeSelection.h"
|
||||
#include "wdxGraphicsWindow8.h"
|
||||
|
|
@ -144,6 +145,7 @@ init_libdxgsg8() {
|
|||
|
||||
DXGraphicsStateGuardian8::init_type();
|
||||
DXTextureContext8::init_type();
|
||||
DXDataContext8::init_type();
|
||||
DXGeomMunger8::init_type();
|
||||
|
||||
wdxGraphicsPipe8::init_type();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
// Filename: dxDataContext8.I
|
||||
// Created by: drose (18Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
// Filename: dxDataContext8.cxx
|
||||
// Created by: drose (18Mar05)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
|
||||
//
|
||||
// All use of this software is subject to the terms of the Panda 3d
|
||||
// Software license. You should have received a copy of this license
|
||||
// along with this source code; you will also find a current copy of
|
||||
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
|
||||
//
|
||||
// To contact the maintainers of this program write to
|
||||
// panda3d-general@lists.sourceforge.net .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dxDataContext8.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "qpgeomVertexArrayFormat.h"
|
||||
#include "internalName.h"
|
||||
#include "config_dxgsg8.h"
|
||||
#include <d3dx8.h>
|
||||
|
||||
TypeHandle DXDataContext8::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXDataContext8::
|
||||
DXDataContext8(qpGeomVertexArrayData *data) :
|
||||
DataContext(data),
|
||||
_vbuffer(NULL)
|
||||
{
|
||||
// Now fill in the FVF code.
|
||||
const qpGeomVertexArrayFormat *array_format = data->get_array_format();
|
||||
|
||||
// We have to start with the vertex data, and work up from there in
|
||||
// order, since that's the way the FVF is defined.
|
||||
int n = 0;
|
||||
int num_data_types = array_format->get_num_data_types();
|
||||
|
||||
_fvf = 0;
|
||||
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_vertex()) {
|
||||
_fvf |= D3DFVF_XYZ;
|
||||
++n;
|
||||
}
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_normal()) {
|
||||
_fvf |= D3DFVF_NORMAL;
|
||||
++n;
|
||||
}
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_color()) {
|
||||
_fvf |= D3DFVF_DIFFUSE;
|
||||
++n;
|
||||
}
|
||||
|
||||
// For multitexture support, we will need to look for all of the
|
||||
// texcoord names and enable them in order.
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_texcoord()) {
|
||||
const qpGeomVertexDataType *data_type = array_format->get_data_type(n);
|
||||
switch (data_type->get_num_values()) {
|
||||
case 1:
|
||||
_fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0);
|
||||
++n;
|
||||
break;
|
||||
case 2:
|
||||
_fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0);
|
||||
++n;
|
||||
break;
|
||||
case 3:
|
||||
_fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0);
|
||||
++n;
|
||||
break;
|
||||
case 4:
|
||||
_fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0);
|
||||
++n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
DXDataContext8::
|
||||
~DXDataContext8() {
|
||||
if (_vbuffer != NULL) {
|
||||
RELEASE(_vbuffer, dxgsg8, "vertex buffer", RELEASE_ONCE);
|
||||
_vbuffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::create_vbuffer
|
||||
// Access: Public
|
||||
// Description: Creates a new vertex buffer and uploads data to it.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXDataContext8::
|
||||
create_vbuffer(DXScreenData &scrn) {
|
||||
if (_vbuffer != NULL) {
|
||||
RELEASE(_vbuffer, dxgsg8, "vertex buffer", RELEASE_ONCE);
|
||||
_vbuffer = NULL;
|
||||
}
|
||||
|
||||
HRESULT hr = scrn.pD3DDevice->CreateVertexBuffer
|
||||
(get_data()->get_num_bytes(), D3DUSAGE_WRITEONLY,
|
||||
_fvf, D3DPOOL_MANAGED, &_vbuffer);
|
||||
if (FAILED(hr)) {
|
||||
dxgsg8_cat.warning()
|
||||
<< "CreateVertexBuffer failed" << D3DERRORSTRING(hr);
|
||||
_vbuffer = NULL;
|
||||
|
||||
} else {
|
||||
upload_data();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXDataContext8::upload_data
|
||||
// Access: Public
|
||||
// Description: Copies the latest data from the client store to
|
||||
// DirectX.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXDataContext8::
|
||||
upload_data() {
|
||||
nassertv(_vbuffer != NULL);
|
||||
|
||||
BYTE *local_pointer;
|
||||
HRESULT hr = _vbuffer->Lock(0, 0, &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());
|
||||
|
||||
_vbuffer->Unlock();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
// Filename: dxDataContext8.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 DXDATACONTEXT8_H
|
||||
#define DXDATACONTEXT8_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "dxgsg8base.h"
|
||||
#include "dataContext.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DXDataContext8
|
||||
// Description : Caches a GeomVertexArrayData in the DirectX device as
|
||||
// a vertex buffer.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDADX DXDataContext8 : public DataContext {
|
||||
public:
|
||||
DXDataContext8(qpGeomVertexArrayData *data);
|
||||
virtual ~DXDataContext8();
|
||||
|
||||
void create_vbuffer(DXScreenData &scrn);
|
||||
void upload_data();
|
||||
|
||||
IDirect3DVertexBuffer8 *_vbuffer;
|
||||
int _fvf;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
DataContext::init_type();
|
||||
register_type(_type_handle, "DXDataContext8",
|
||||
DataContext::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 "dxDataContext8.I"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
@ -55,6 +55,8 @@
|
|||
#include "qpgeomTristrips.h"
|
||||
#include "qpgeomTrifans.h"
|
||||
#include "dxGeomMunger8.h"
|
||||
#include "config_gobj.h"
|
||||
#include "dxDataContext8.h"
|
||||
|
||||
#ifdef DO_PSTATS
|
||||
#include "pStatTimer.h"
|
||||
|
|
@ -198,6 +200,9 @@ DXGraphicsStateGuardian8(const FrameBufferProperties &properties) :
|
|||
_pFvfBufBasePtr = NULL;
|
||||
_index_buf=NULL;
|
||||
|
||||
_vbuffer_active = false;
|
||||
_ibuffer_active = false;
|
||||
|
||||
// _max_light_range = __D3DLIGHT_RANGE_MAX;
|
||||
|
||||
// non-dx obj values inited here should not change if resize is
|
||||
|
|
@ -2613,60 +2618,12 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
|||
|
||||
// The munger should have put the "vertex" data at the beginning of
|
||||
// the first array.
|
||||
const qpGeomVertexArrayFormat *array_format = format->get_array(0);
|
||||
const qpGeomVertexArrayData *data = _vertex_data->get_array(0);
|
||||
|
||||
// Now we have to start with the vertex data, and work up from there
|
||||
// in order, since that's the way the FVF is defined.
|
||||
int n = 0;
|
||||
int num_data_types = array_format->get_num_data_types();
|
||||
DataContext *dc = ((qpGeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(dc != (DataContext *)NULL, false);
|
||||
apply_data(dc);
|
||||
|
||||
DWORD fvf = 0;
|
||||
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_vertex()) {
|
||||
fvf |= D3DFVF_XYZ;
|
||||
++n;
|
||||
} else {
|
||||
// No vertex data, no vertices.
|
||||
return false;
|
||||
}
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_normal()) {
|
||||
fvf |= D3DFVF_NORMAL;
|
||||
++n;
|
||||
}
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_color()) {
|
||||
fvf |= D3DFVF_DIFFUSE;
|
||||
++n;
|
||||
}
|
||||
|
||||
// For multitexture support, we will need to look for all of the
|
||||
// texcoord names and enable them in order.
|
||||
if (n < num_data_types &&
|
||||
array_format->get_data_type(n)->get_name() == InternalName::get_texcoord()) {
|
||||
const qpGeomVertexDataType *data_type = array_format->get_data_type(n);
|
||||
switch (data_type->get_num_values()) {
|
||||
case 1:
|
||||
fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE1(0);
|
||||
++n;
|
||||
break;
|
||||
case 2:
|
||||
fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0);
|
||||
++n;
|
||||
break;
|
||||
case 3:
|
||||
fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0);
|
||||
++n;
|
||||
break;
|
||||
case 4:
|
||||
fvf |= D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE4(0);
|
||||
++n;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
set_vertex_format(fvf);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -2677,15 +2634,24 @@ begin_draw_primitives(const qpGeomVertexData *vertex_data) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
draw_triangles(const qpGeomTriangles *primitive) {
|
||||
_pD3DDevice->DrawIndexedPrimitiveUP
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_flat_first_vertices(),
|
||||
D3DFMT_INDEX16,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
if (_vbuffer_active && _ibuffer_active) {
|
||||
_pD3DDevice->DrawIndexedPrimitive
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
0, primitive->get_num_primitives());
|
||||
|
||||
} else {
|
||||
_pD3DDevice->DrawIndexedPrimitiveUP
|
||||
(D3DPT_TRIANGLELIST,
|
||||
primitive->get_min_vertex(),
|
||||
primitive->get_max_vertex() - primitive->get_min_vertex() + 1,
|
||||
primitive->get_num_primitives(),
|
||||
primitive->get_flat_first_vertices(),
|
||||
D3DFMT_INDEX16,
|
||||
_vertex_data->get_array(0)->get_data(),
|
||||
_vertex_data->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -2936,6 +2902,97 @@ release_texture(TextureContext *tc) {
|
|||
delete gtc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::prepare_data
|
||||
// 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
|
||||
// responsibility of the calling function to later
|
||||
// call release_data() 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) {
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "prepare_data(" << (void *)data << ")\n";
|
||||
}
|
||||
|
||||
DXDataContext8 *ddc = new DXDataContext8(data);
|
||||
|
||||
if (vertex_buffers) {
|
||||
ddc->create_vbuffer(*_pScrn);
|
||||
ddc->mark_loaded();
|
||||
}
|
||||
|
||||
return ddc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::apply_data
|
||||
// Access: Public
|
||||
// Description: Makes the data the currently available data for
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
apply_data(DataContext *dc) {
|
||||
DXDataContext8 *ddc = DCAST(DXDataContext8, dc);
|
||||
|
||||
if (ddc->_vbuffer != NULL) {
|
||||
add_to_data_record(ddc);
|
||||
|
||||
if (ddc->was_modified()) {
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "apply_data(" << (void *)dc->get_data() << ")\n";
|
||||
}
|
||||
if (ddc->changed_size()) {
|
||||
// Here we have to destroy the old vertex buffer and create a
|
||||
// new one.
|
||||
ddc->create_vbuffer(*_pScrn);
|
||||
|
||||
} else {
|
||||
// Here we just copy the new data to the vertex buffer.
|
||||
ddc->upload_data();
|
||||
}
|
||||
|
||||
ddc->mark_loaded();
|
||||
}
|
||||
|
||||
_pD3DDevice->SetStreamSource
|
||||
(0, ddc->_vbuffer, ddc->get_data()->get_array_format()->get_stride());
|
||||
_vbuffer_active = true;
|
||||
|
||||
} else {
|
||||
_vbuffer_active = false;
|
||||
}
|
||||
|
||||
set_vertex_format(ddc->_fvf);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::release_data
|
||||
// Access: Public, Virtual
|
||||
// Description: Frees the GL resources previously allocated for the
|
||||
// data. This function should never be called
|
||||
// directly; instead, call Data::release() (or simply
|
||||
// let the Data destruct).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
release_data(DataContext *dc) {
|
||||
if (dxgsg8_cat.is_debug()) {
|
||||
dxgsg8_cat.debug()
|
||||
<< "release_data(" << (void *)dc->get_data() << ")\n";
|
||||
}
|
||||
|
||||
DXDataContext8 *ddc = DCAST(DXDataContext8, dc);
|
||||
delete ddc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DXGraphicsStateGuardian8::get_geom_munger
|
||||
// Access: Public, Virtual
|
||||
|
|
|
|||
|
|
@ -99,6 +99,10 @@ 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 CPT(qpGeomMunger) get_geom_munger(const RenderState *state);
|
||||
|
||||
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
|
||||
|
|
@ -313,6 +317,8 @@ protected:
|
|||
int _projection_mat_stack_count;
|
||||
|
||||
CPT(DisplayRegion) _actual_display_region;
|
||||
bool _vbuffer_active;
|
||||
bool _ibuffer_active;
|
||||
|
||||
// Color/Alpha Matrix Transition stuff
|
||||
INLINE void transform_color(Colorf &InColor,D3DCOLOR &OutColor);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "dxgsg8base.h"
|
||||
#include "config_dxgsg8.cxx"
|
||||
#include "dxTextureContext8.cxx"
|
||||
#include "dxDataContext8.cxx"
|
||||
#include "dxGeomMunger8.cxx"
|
||||
#include "d3dfont8.cxx"
|
||||
#include "wdxGraphicsPipe8.cxx"
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GLDataContext
|
||||
// Description :
|
||||
// Description : Caches a GeomVertexArrayData on the GL as a buffer
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_GL CLP(DataContext) : public DataContext {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -2357,11 +2357,12 @@ prepare_data(qpGeomVertexArrayData *data) {
|
|||
CLP(DataContext) *gdc = new CLP(DataContext)(data);
|
||||
_glGenBuffers(1, &gdc->_index);
|
||||
|
||||
add_to_data_record(gdc);
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
_glBufferData(GL_ARRAY_BUFFER, gdc->_data->get_num_bytes(),
|
||||
gdc->_data->get_data(),
|
||||
get_usage(gdc->_data->get_usage_hint()));
|
||||
gdc->_modified = gdc->_data->get_modified();
|
||||
_glBufferData(GL_ARRAY_BUFFER, gdc->get_data()->get_num_bytes(),
|
||||
gdc->get_data()->get_data(),
|
||||
get_usage(gdc->get_data()->get_usage_hint()));
|
||||
gdc->mark_loaded();
|
||||
|
||||
report_my_gl_errors();
|
||||
return gdc;
|
||||
|
|
@ -2372,17 +2373,12 @@ prepare_data(qpGeomVertexArrayData *data) {
|
|||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: CLP(GraphicsStateGuardian)::apply_data
|
||||
// Access: Public, Virtual
|
||||
// Access: Public
|
||||
// Description: Makes the data the currently available data for
|
||||
// rendering.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
apply_data(DataContext *dc) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "apply_data(" << (void *)dc->_data << ")\n";
|
||||
}
|
||||
|
||||
nassertv(_supports_buffers);
|
||||
|
||||
CLP(DataContext) *gdc = DCAST(CLP(DataContext), dc);
|
||||
|
|
@ -2390,11 +2386,22 @@ apply_data(DataContext *dc) {
|
|||
add_to_data_record(gdc);
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
|
||||
if (gdc->_modified != gdc->_data->get_modified()) {
|
||||
_glBufferSubData(GL_ARRAY_BUFFER, 0, gdc->_data->get_num_bytes(),
|
||||
gdc->_data->get_data());
|
||||
if (gdc->was_modified()) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "apply_data(" << (void *)dc->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()));
|
||||
|
||||
gdc->_modified = gdc->_data->get_modified();
|
||||
} else {
|
||||
_glBufferSubData(GL_ARRAY_BUFFER, 0, gdc->get_num_bytes(),
|
||||
gdc->get_data()->get_data());
|
||||
}
|
||||
|
||||
gdc->mark_loaded();
|
||||
}
|
||||
|
||||
report_my_gl_errors();
|
||||
|
|
@ -2412,7 +2419,7 @@ void CLP(GraphicsStateGuardian)::
|
|||
release_data(DataContext *dc) {
|
||||
if (GLCAT.is_debug()) {
|
||||
GLCAT.debug()
|
||||
<< "release_data(" << (void *)dc->_data << ")\n";
|
||||
<< "release_data(" << (void *)dc->get_data() << ")\n";
|
||||
}
|
||||
|
||||
nassertv(_supports_buffers);
|
||||
|
|
@ -2458,9 +2465,7 @@ 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());
|
||||
|
||||
CLP(DataContext) *gdc = DCAST(CLP(DataContext), dc);
|
||||
_glBindBuffer(GL_ARRAY_BUFFER, gdc->_index);
|
||||
apply_data(dc);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer.
|
||||
return NULL;
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ public:
|
|||
virtual void release_geom(GeomContext *gc);
|
||||
|
||||
virtual DataContext *prepare_data(qpGeomVertexArrayData *data);
|
||||
virtual void apply_data(DataContext *dc);
|
||||
void apply_data(DataContext *dc);
|
||||
virtual void release_data(DataContext *dc);
|
||||
const unsigned char *setup_array_data(const qpGeomVertexArrayData *data);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,68 @@
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE DataContext::
|
||||
DataContext(qpGeomVertexArrayData *data) :
|
||||
_data(data)
|
||||
_data(data),
|
||||
// Initially, the number of bytes is zero, until the data has been
|
||||
// loaded (and mark_loaded() is called).
|
||||
_num_bytes(0)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::get_data
|
||||
// Access: Public
|
||||
// Description: Returns the pointer to the client-side array data
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE qpGeomVertexArrayData *DataContext::
|
||||
get_data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::get_num_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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::changed_size
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has changed size since the
|
||||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DataContext::
|
||||
changed_size() const {
|
||||
return get_num_bytes() != _data->get_num_bytes();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::was_modified
|
||||
// Access: Public
|
||||
// Description: Returns true if the data has been modified since the
|
||||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool DataContext::
|
||||
was_modified() const {
|
||||
return _modified != _data->get_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: DataContext::mark_loaded
|
||||
// Access: Public
|
||||
// Description: Should be called after the DataContext has been
|
||||
// loaded into graphics memory, this updates the
|
||||
// internal flags for changed_size() and modified().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void DataContext::
|
||||
mark_loaded() {
|
||||
_num_bytes = _data->get_num_bytes();
|
||||
_modified = _data->get_modified();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@
|
|||
|
||||
#include "savedContext.h"
|
||||
#include "updateSeq.h"
|
||||
|
||||
class qpGeomVertexArrayData;
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : DataContext
|
||||
|
|
@ -41,11 +40,21 @@ class EXPCL_PANDA DataContext : public SavedContext {
|
|||
public:
|
||||
INLINE DataContext(qpGeomVertexArrayData *data);
|
||||
|
||||
INLINE qpGeomVertexArrayData *get_data() const;
|
||||
|
||||
INLINE int get_num_bytes() const;
|
||||
INLINE bool changed_size() const;
|
||||
INLINE bool was_modified() const;
|
||||
|
||||
INLINE void mark_loaded();
|
||||
|
||||
private:
|
||||
// This cannot be a PT(qpGeomVertexArrayData), because the data and
|
||||
// the GSG both own their DataContexts! That would create a
|
||||
// circular reference count.
|
||||
qpGeomVertexArrayData *_data;
|
||||
UpdateSeq _modified;
|
||||
int _num_bytes;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -63,6 +72,8 @@ public:
|
|||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
|
||||
friend class PreparedGraphicsObjects;
|
||||
};
|
||||
|
||||
#include "dataContext.I"
|
||||
|
|
|
|||
|
|
@ -18,9 +18,13 @@
|
|||
|
||||
#include "preparedGraphicsObjects.h"
|
||||
#include "textureContext.h"
|
||||
#include "texture.h"
|
||||
#include "geom.h"
|
||||
#include "qpgeomVertexArrayData.h"
|
||||
#include "mutexHolder.h"
|
||||
|
||||
PStatCollector PreparedGraphicsObjects::_total_texusage_pcollector("Texture usage");
|
||||
PStatCollector PreparedGraphicsObjects::_total_buffers_pcollector("Vertex Buffers");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: PreparedGraphicsObjects::Constructor
|
||||
|
|
@ -69,6 +73,19 @@ PreparedGraphicsObjects::
|
|||
_prepared_geoms.clear();
|
||||
_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);
|
||||
}
|
||||
|
||||
_prepared_datas.clear();
|
||||
_released_datas.clear();
|
||||
_enqueued_datas.clear();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -411,20 +428,21 @@ dequeue_data(qpGeomVertexArrayData *data) {
|
|||
// it's in, at the time release_data is called).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PreparedGraphicsObjects::
|
||||
release_data(DataContext *gc) {
|
||||
release_data(DataContext *dc) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
gc->_data->clear_prepared(this);
|
||||
dc->_data->clear_prepared(this);
|
||||
_total_buffers_pcollector.sub_level(dc->get_num_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.
|
||||
gc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
dc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
|
||||
bool removed = (_prepared_datas.erase(gc) != 0);
|
||||
bool removed = (_prepared_datas.erase(dc) != 0);
|
||||
nassertv(removed);
|
||||
|
||||
_released_datas.insert(gc);
|
||||
_released_datas.insert(dc);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -441,15 +459,16 @@ release_all_datas() {
|
|||
|
||||
int num_datas = (int)_prepared_datas.size();
|
||||
|
||||
Datas::iterator gci;
|
||||
for (gci = _prepared_datas.begin();
|
||||
gci != _prepared_datas.end();
|
||||
++gci) {
|
||||
DataContext *gc = (*gci);
|
||||
gc->_data->clear_prepared(this);
|
||||
gc->_data = (qpGeomVertexArrayData *)NULL;
|
||||
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;
|
||||
|
||||
_released_datas.insert(gc);
|
||||
_released_datas.insert(dc);
|
||||
}
|
||||
|
||||
_prepared_datas.clear();
|
||||
|
|
@ -487,14 +506,16 @@ prepare_data_now(qpGeomVertexArrayData *data, GraphicsStateGuardianBase *gsg) {
|
|||
// 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 *gc = gsg->prepare_data(data);
|
||||
DataContext *dc = gsg->prepare_data(data);
|
||||
|
||||
if (gc != (DataContext *)NULL) {
|
||||
bool prepared = _prepared_datas.insert(gc).second;
|
||||
nassertr(prepared, gc);
|
||||
if (dc != (DataContext *)NULL) {
|
||||
bool prepared = _prepared_datas.insert(dc).second;
|
||||
nassertr(prepared, dc);
|
||||
|
||||
_total_buffers_pcollector.add_level(dc->get_num_bytes());
|
||||
}
|
||||
|
||||
return gc;
|
||||
return dc;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -513,7 +534,8 @@ void PreparedGraphicsObjects::
|
|||
update(GraphicsStateGuardianBase *gsg) {
|
||||
MutexHolder holder(_lock);
|
||||
|
||||
// First, release all the textures awaiting release.
|
||||
// First, release all the textures, geoms, and data arrays awaiting
|
||||
// release.
|
||||
Textures::iterator tci;
|
||||
for (tci = _released_textures.begin();
|
||||
tci != _released_textures.end();
|
||||
|
|
@ -524,7 +546,6 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
|
||||
_released_textures.clear();
|
||||
|
||||
// Next, release all the geoms awaiting release.
|
||||
Geoms::iterator gci;
|
||||
for (gci = _released_geoms.begin();
|
||||
gci != _released_geoms.end();
|
||||
|
|
@ -535,7 +556,18 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
|
||||
_released_geoms.clear();
|
||||
|
||||
// Now prepare all the textures awaiting preparation.
|
||||
Datas::iterator dci;
|
||||
for (dci = _released_datas.begin();
|
||||
dci != _released_datas.end();
|
||||
++dci) {
|
||||
DataContext *dc = (*dci);
|
||||
gsg->release_data(dc);
|
||||
}
|
||||
|
||||
_released_datas.clear();
|
||||
|
||||
// Now prepare all the textures, geoms, and data arrays awaiting
|
||||
// preparation.
|
||||
EnqueuedTextures::iterator qti;
|
||||
for (qti = _enqueued_textures.begin();
|
||||
qti != _enqueued_textures.end();
|
||||
|
|
@ -546,7 +578,6 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
|
||||
_enqueued_textures.clear();
|
||||
|
||||
// And finally prepare all the geoms awaiting preparation.
|
||||
EnqueuedGeoms::iterator qgi;
|
||||
for (qgi = _enqueued_geoms.begin();
|
||||
qgi != _enqueued_geoms.end();
|
||||
|
|
@ -555,5 +586,13 @@ update(GraphicsStateGuardianBase *gsg) {
|
|||
geom->prepare_now(this, gsg);
|
||||
}
|
||||
|
||||
_enqueued_geoms.clear();
|
||||
EnqueuedDatas::iterator qdi;
|
||||
for (qdi = _enqueued_datas.begin();
|
||||
qdi != _enqueued_datas.end();
|
||||
++qdi) {
|
||||
qpGeomVertexArrayData *data = (*qdi);
|
||||
data->prepare_now(this, gsg);
|
||||
}
|
||||
|
||||
_enqueued_datas.clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ private:
|
|||
EnqueuedDatas _enqueued_datas;
|
||||
|
||||
static PStatCollector _total_texusage_pcollector;
|
||||
static PStatCollector _total_buffers_pcollector;
|
||||
|
||||
friend class GraphicsStateGuardian;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,13 +32,16 @@
|
|||
|
||||
class PreparedGraphicsObjects;
|
||||
class DataContext;
|
||||
class GraphicsStateGuardianBase;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : qpGeomVertexArrayData
|
||||
// Description : This is the data for one array of a GeomVertexData
|
||||
// structure. Many GeomVertexData structures will only
|
||||
// define one array; some will define multiple arrays.
|
||||
// DirectX calls this concept a "stream".
|
||||
// define one array, with all data elements interleaved
|
||||
// (DirectX 8.0 and before insisted on this format);
|
||||
// some will define multiple arrays. DirectX calls this
|
||||
// concept a "stream".
|
||||
//
|
||||
// This object is just a block of data. See
|
||||
// GeomVertexData for the organizing structure.
|
||||
|
|
|
|||
Loading…
Reference in New Issue