partial vtx buffer chkin, plus some pipeline tweaks

This commit is contained in:
cxgeorge 2001-08-20 02:30:25 +00:00
parent 9136f22e08
commit 8b6d25c53e
5 changed files with 412 additions and 222 deletions

View File

@ -19,14 +19,13 @@
////////////////////////////////////////////////////////////////////
// Function: dxGeomNodeContext::Constructor
// Access: Public
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE DXGeomNodeContext::
DXGeomNodeContext(GeomNode *node) :
GeomNodeContext(node)
DXGeomNodeContext(GeomNode *node) : GeomNodeContext(node)
{
#ifdef DO_PSTATS
_num_verts = 0;
#endif
_pVB = NULL;
_pXformed_VB = NULL;
}

View File

@ -19,3 +19,15 @@
#include "dxGeomNodeContext.h"
TypeHandle DXGeomNodeContext::_type_handle;
DXGeomNodeContext::~DXGeomNodeContext()
{
if(_pXformed_VB!=NULL)
_pXformed_VB->Release();
_pXformed_VB=NULL;
if(_pVB!=NULL)
_pVB->Release();
_pVB=NULL;
}

View File

@ -32,6 +32,9 @@
#include <geomNode.h>
#include "pvector.h"
#define D3D_OVERLOADS // get D3DVECTOR '+' operator, etc from d3dtypes.h
#include <d3d.h>
////////////////////////////////////////////////////////////////////
// Class : DXGeomNodeContext
// Description :
@ -39,22 +42,22 @@
class EXPCL_PANDADX DXGeomNodeContext : public GeomNodeContext {
public:
INLINE DXGeomNodeContext(GeomNode *node);
~DXGeomNodeContext();
#if 0
// The DX display list index that draws the contents of this
// GeomNode.
DXuint _index;
#endif
// A list of the dynamic Geoms within the GeomNode; these aren't
// part of the above display list.
// part of the above display list and must be drawn separately
typedef pvector<PT(dDrawable) > Geoms;
Geoms _dynamic_geoms;
Geoms _other_geoms;
#ifdef DO_PSTATS
// The number of vertices represented by the display list. This is
// strictly for the benefit of PStats reporting.
int _num_verts;
#endif
// VB's are already reference-counted by D3D, no need to make separate panda object to do that
// but we will want a way to know if VB has already been xformed by ProcessVerts this frame
// if multiple geomnodes share VBs
LPDIRECT3DVERTEXBUFFER7 _pVB;
LPDIRECT3DVERTEXBUFFER7 _pXformed_VB;
int _start_index; // starting offset of this geom's verts within the VB
int _num_verts; // number of verts used by this geomcontext within the VB
public:
static TypeHandle get_class_type() {

View File

@ -85,9 +85,12 @@
// For sparkle particles, we can have 4 vertices per sparkle, and a
// particle pool size of 1024 particles
// for sprites, 1000 prims, 6 verts/prim, 24 bytes/vert
const int VERT_BUFFER_SIZE = (32*6*1024L);
// for sprites, 1000 prims, 6 verts/prim, 24 bytes/vert
// if defined, pandadx only handles 1 panda display region
// note multiple region code doesnt work now (see prepare_display_region,set_clipper)
#define NO_MULTIPLE_DISPLAY_REGIONS
TypeHandle DXGraphicsStateGuardian::_type_handle;
@ -104,8 +107,6 @@ TypeHandle DXGraphicsStateGuardian::_type_handle;
static D3DMATRIX matIdentity;
#define Colorf_to_D3DCOLOR(out_color) (D3DRGBA((out_color)[0], (out_color)[1], (out_color)[2], (out_color)[3]))
#ifdef COUNT_DRAWPRIMS
static DWORD cDPcount=0;
@ -136,6 +137,67 @@ static void CountDPs(DWORD nVerts,DWORD nTris) {
static bool bTexStatsRetrievalImpossible=false;
#endif
//#define Colorf_to_D3DCOLOR(out_color) (D3DRGBA((out_color)[0], (out_color)[1], (out_color)[2], (out_color)[3]))
INLINE DWORD
//Colorf_to_D3DCOLOR(float *alpha,float *red,float *grn,float *blue) {
Colorf_to_D3DCOLOR(Colorf &cColorf) {
// MS VC defines _M_IX86 for x86. gcc should define _X86_
//#if defined(_M_IX86) || defined(_X86_)
#if 1
DWORD d3dcolor,tempcolorval=255;
// DWORD *Colorf_addr=(DWORD*)&cColorf;
// note the default FPU rounding mode will give 255*0.5f=0x80, not 0x7F as VC would force it to by resetting rounding mode
// dont think this makes much difference
__asm {
; push eax
push ebx ; want to save this in case this fn is inlined
push ecx
; mov ecx, Colorf_addr ; must be a better way to do this w/o using ecx
mov ecx, cColorf
fild tempcolorval
fld [ecx]
fmul ST(0),ST(1)
fistp tempcolorval ; no way to store directly to int register
mov eax, tempcolorval
shl eax, 16
fld DWORD PTR [ecx+4] ;grn
fmul ST(0),ST(1)
fistp tempcolorval
mov ebx,tempcolorval
shl ebx, 8
or eax,ebx
fld DWORD PTR [ecx+8] ;blue
fmul ST(0),ST(1)
fistp tempcolorval
or eax,tempcolorval
fld DWORD PTR [ecx+12] ;alpha
fmul ST(0),ST(1)
fistp tempcolorval
; simulate pop 255.0 off FP stack w/o store, mark top as empty and increment stk ptr
ffree ST(0)
fincstp
mov ebx,tempcolorval
shl ebx, 24
or eax,ebx
mov d3dcolor,eax
pop ecx
pop ebx
; pop eax
}
// dxgsg_cat.debug() << (void*)d3dcolor << endl;
return d3dcolor;
#else //!_X86_
return D3DRGBA(cColorf[0], cColorf[1], cColorf[2], cColorf[3]);
#endif //!_X86_
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian::Constructor
// Access: Public
@ -312,6 +374,9 @@ init_dx( LPDIRECTDRAW7 context,
_last_testcooplevel_result = S_OK;
// only 1 channel on dx currently
_panda_gfx_channel = _win->get_channel(0);
HRESULT hr;
if(dx_show_fps_meter) {
@ -617,8 +682,6 @@ enable_light(int light, bool val) {
return TRUE;
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian::prepare_display_region
// Access: Public, Virtual
@ -630,10 +693,10 @@ prepare_display_region() {
if (_current_display_region == (DisplayRegion*)0L) {
dxgsg_cat.error()
<< "Invalid NULL display region in prepare_display_region()\n";
} else if (_current_display_region != _actual_display_region) {
_actual_display_region = _current_display_region;
/*
#ifndef NO_MULTIPLE_DISPLAY_REGIONS
int l, b, w, h;
_actual_display_region->get_region_pixels(l, b, w, h);
GLint x = GLint(l);
@ -641,8 +704,8 @@ prepare_display_region() {
GLsizei width = GLsizei(w);
GLsizei height = GLsizei(h);
#ifdef WBD_GL_MODE
call_glScissor( x, y, width, height );
call_glViewport( x, y, width, height );
// call_glScissor( x, y, width, height );
// call_glViewport( x, y, width, height );
#else
if ( _scissor_x != x || _scissor_y != y ||
_scissor_width != width || _scissor_height != height )
@ -654,11 +717,11 @@ prepare_display_region() {
set_clipper(cliprect);
}
#endif //WBD_GL_MODE
*/
#endif
}
}
#if 0
#ifndef NO_MULTIPLE_DISPLAY_REGIONS
////////////////////////////////////////////////////////////////////
// Function: set_clipper
// Access:
@ -761,20 +824,30 @@ render_frame() {
if (_clear_buffer_type != 0) {
// First, clear the entire window.
PT(DisplayRegion) win_dr =
_win->make_scratch_display_region(_win->get_width(), _win->get_height());
clear(get_render_buffer(_clear_buffer_type), win_dr);
#ifndef NO_MULTIPLE_DISPLAY_REGIONS
PT(DisplayRegion) win_dr = _win->make_scratch_display_region(_win->get_width(), _win->get_height());
clear(get_render_buffer(_clear_buffer_type), win_dr);
#else
clear(get_render_buffer(_clear_buffer_type));
#endif
}
// Now render each of our layers in order.
#if 0
int max_channel_index = _win->get_max_channel_index();
for (int c = 0; c < max_channel_index; c++) {
if (_win->is_channel_defined(c)) {
GraphicsChannel *chan = _win->get_channel(c);
if (chan->is_active()) {
int num_layers = chan->get_num_layers();
#endif
// only 1 channel on dx currently
assert(_win->get_max_channel_index()==1);
assert(_win->is_channel_defined(0));
if(_panda_gfx_channel->is_active()) {
// Now render each of our layers in order.
int num_layers = _panda_gfx_channel->get_num_layers();
for (int l = 0; l < num_layers; l++) {
GraphicsLayer *layer = chan->get_layer(l);
GraphicsLayer *layer = _panda_gfx_channel->get_layer(l);
if (layer->is_active()) {
int num_drs = layer->get_num_drs();
for (int d = 0; d < num_drs; d++) {
@ -793,8 +866,10 @@ render_frame() {
} // if (layer->is_active())
}
} // if (chan->is_active())
#if 0
}
} // for (int c = 0; c < max_channel_index; c++)
#endif
// Now we're done with the frame processing. Clean up.
@ -1125,10 +1200,11 @@ render_subgraph(RenderTraverser *traverser,
}
#endif
HRESULT hr;
// We load the projection matrix directly.
HRESULT res =
_d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,
(LPD3DMATRIX) _current_projection_mat.get_data());
hr = _d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,
(LPD3DMATRIX) _current_projection_mat.get_data());
// We infer the modelview matrix by doing a wrt on the projection
// node.
@ -1159,9 +1235,8 @@ render_subgraph(RenderTraverser *traverser,
// We must now restore the projection matrix from before. We could
// do a push/pop matrix if we were using D3DX
if (_projection_mat_stack_count > 0)
_d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,
(LPD3DMATRIX) _current_projection_mat.get_data());
hr =_d3dDevice->SetTransform(D3DTRANSFORMSTATE_PROJECTION,
(LPD3DMATRIX) _current_projection_mat.get_data());
}
////////////////////////////////////////////////////////////////////
@ -1355,46 +1430,34 @@ wants_colors() const {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_prim_inner_loop(int nVerts, const Geom *geom, DWORD perFlags) {
perFlags &= ~PER_COORD; // should always be set anyway
for(;nVerts > 0;nVerts--) {
GET_NEXT_VERTEX(); // coord info will always be perVertex
switch (perFlags) {
case 0x3:
GET_NEXT_NORMAL();
case 0x1:
break;
case 0x5:
case 0x4:
GET_NEXT_COLOR();
break;
case 0x7:
case 0x6:
GET_NEXT_COLOR();
case 0x2:
GET_NEXT_NORMAL();
break;
case 0x9:
case 0x8:
GET_NEXT_TEXCOORD();
break;
case 0xB:
case 0xA:
GET_NEXT_NORMAL();
GET_NEXT_TEXCOORD();
break;
case 0xD:
case 0xC:
GET_NEXT_COLOR();
GET_NEXT_TEXCOORD();
break;
case 0xF:
case 0xE:
GET_NEXT_NORMAL();
GET_NEXT_COLOR();
GET_NEXT_TEXCOORD();
break;
if(perFlags==0xC) {
// break out the common case first
GET_NEXT_TEXCOORD();
GET_NEXT_COLOR();
} else {
switch (perFlags) {
case 0x4:
GET_NEXT_COLOR();
break;
case 0x6:
GET_NEXT_COLOR();
case 0x2:
GET_NEXT_NORMAL();
break;
case 0xE:
GET_NEXT_COLOR();
case 0xA:
GET_NEXT_NORMAL();
case 0x8:
GET_NEXT_TEXCOORD();
break;
}
}
add_to_FVFBuf((void *)&p_vertex, sizeof(D3DVECTOR));
@ -1570,13 +1633,14 @@ draw_line(GeomLine* geom, GeomContext *gc) {
#ifdef _DEBUG
static BOOL bPrintedMsg=FALSE;
// note: need to implement approximation of non-1.0 width lines with quads
if (!bPrintedMsg && (geom->get_width()!=1.0f)) {
bPrintedMsg=TRUE;
dxgsg_cat.warning() << "DX does not support drawing lines with a non-1.0f pixel width, setting width to 1.0f!\n";
}
#endif
int nPrims = geom->get_num_prims();
if (nPrims==0) {
@ -2628,31 +2692,31 @@ draw_multitri(Geom *geom, D3DPRIMITIVETYPE trilisttype) {
#endif
_pCurFvfBufPtr = _pFvfBufBasePtr; // _pCurFvfBufPtr changes, _pFvfBufBasePtr doesn't
if(perComp==0x0) {
draw_prim_inner_loop(nVerts, geom, perVertex);
} else {
if(trilisttype==D3DPT_TRIANGLEFAN) {
// in flat shade mode, D3D fans color using the 2nd vertex.
// (note: differs from OGL, which always uses last vtx for strips&fans
// perComp attribs should not be fetched for first & last verts, they will
// be associated with middle n-2 verts
draw_prim_inner_loop(1, geom, perVertex);
draw_prim_inner_loop(nVerts-2, geom, perVertex | perComp);
draw_prim_inner_loop(1, geom, perVertex);
} else {
// in flat shade mode, D3D strips color using the 1st vertex.
// (note: differs from OGL, which always uses last vtx for strips&fans
// Store all but last 2 verts
draw_prim_inner_loop(nVerts-2, geom, perVertex | perComp);
// perComp attribs should not be fetched for last 2 verts
draw_prim_inner_loop(2, geom, perVertex);
}
}
if(perComp==0x0) {
draw_prim_inner_loop(nVerts, geom, perVertex);
} else {
if(trilisttype==D3DPT_TRIANGLESTRIP) {
// in flat shade mode, D3D strips color using the 1st vertex.
// (note: differs from OGL, which always uses last vtx for strips&fans
// Store all but last 2 verts
draw_prim_inner_loop(nVerts-2, geom, perVertex | perComp);
// perComp attribs should not be fetched for last 2 verts
draw_prim_inner_loop(2, geom, perVertex);
} else {
// in flat shade mode, D3D fans color using the 2nd vertex.
// (note: differs from OGL, which always uses last vtx for strips&fans
// perComp attribs should not be fetched for first & last verts, they will
// be associated with middle n-2 verts
draw_prim_inner_loop(1, geom, perVertex);
draw_prim_inner_loop(nVerts-2, geom, perVertex | perComp);
draw_prim_inner_loop(1, geom, perVertex);
}
}
HRESULT hr = _d3dDevice->DrawPrimitive(trilisttype, p_flags, _pFvfBufBasePtr, nVerts, NULL);
TestDrawPrimFailure(DrawPrim,hr,_pDD,nVerts,nVerts-2);
@ -6027,9 +6091,8 @@ HRESULT SetViewMatrix( D3DMATRIX& mat, D3DVECTOR& vFrom, D3DVECTOR& vAt,
GeomNodeContext *DXGraphicsStateGuardian::
prepare_geom_node(GeomNode *node) {
if(!link_tristrips)
return NULL;
if(link_tristrips) {
for(int iGeom=0;iGeom<node->get_num_geoms();iGeom++) {
dDrawable *drawable1 = node->get_geom(iGeom);
@ -6272,105 +6335,188 @@ prepare_geom_node(GeomNode *node) {
me->set_##ATTRNAME##s(old_##ATTRNAME##s, ATTRNAME##binding, new_##ATTRNAME##_indices); \
} \
}
/*
int ii;
for( ii=0;ii<old_coords.size();ii++)
dxgsg_cat.debug() << "old coord[" << ii <<"] " << old_coords[ii] << endl;
dxgsg_cat.debug() << "=================\n";
for(ii=0;ii<new_coords.size();ii++)
dxgsg_cat.debug() << "new coord[" << ii <<"] " << new_coords[ii] << endl;
dxgsg_cat.debug() << "=================\n";
/*
int ii;
for( ii=0;ii<old_coords.size();ii++)
dxgsg_cat.debug() << "old coord[" << ii <<"] " << old_coords[ii] << endl;
dxgsg_cat.debug() << "=================\n";
for(ii=0;ii<new_coords.size();ii++)
dxgsg_cat.debug() << "new coord[" << ii <<"] " << new_coords[ii] << endl;
dxgsg_cat.debug() << "=================\n";
for( ii=0;ii<old_normals.size();ii++)
dxgsg_cat.debug() << "old norm[" << ii <<"] " << old_normals[ii] << endl;
dxgsg_cat.debug() << "=================\n";
for(ii=0;ii<new_normals.size();ii++)
dxgsg_cat.debug() << "new norm[" << ii <<"] " << new_normals[ii] << endl;
if(old_color_indices!=NULL) {
for( ii=0;ii<old_color_indices.size();ii++)
dxgsg_cat.debug() << "old colorindex[" << ii <<"] " << old_color_indices[ii] << endl;
dxgsg_cat.debug() << "=================\n";
for( ii=0;ii<new_color_indices.size();ii++)
dxgsg_cat.debug() << "new colorindex[" << ii <<"] " << new_color_indices[ii] << endl;
}
*/
for( ii=0;ii<old_normals.size();ii++)
dxgsg_cat.debug() << "old norm[" << ii <<"] " << old_normals[ii] << endl;
dxgsg_cat.debug() << "=================\n";
for(ii=0;ii<new_normals.size();ii++)
dxgsg_cat.debug() << "new norm[" << ii <<"] " << new_normals[ii] << endl;
SET_NEW_ATTRIBS(color);
SET_NEW_ATTRIBS(normal);
SET_NEW_ATTRIBS(texcoord);
if(old_color_indices!=NULL) {
for( ii=0;ii<old_color_indices.size();ii++)
dxgsg_cat.debug() << "old colorindex[" << ii <<"] " << old_color_indices[ii] << endl;
dxgsg_cat.debug() << "=================\n";
for( ii=0;ii<new_color_indices.size();ii++)
dxgsg_cat.debug() << "new colorindex[" << ii <<"] " << new_color_indices[ii] << endl;
}
*/
SET_NEW_ATTRIBS(color);
SET_NEW_ATTRIBS(normal);
SET_NEW_ATTRIBS(texcoord);
me->make_dirty();
}
return NULL;
#if 0
// Make sure we have at least some static Geoms in the GeomNode;
// otherwise there's no point in building a display list.
int num_geoms = node->get_num_geoms();
bool all_dynamic = true;
int i;
for (i = 0; (i < num_geoms) && all_dynamic; i++) {
dDrawable *geom = node->get_geom(i);
all_dynamic = geom->is_dynamic();
me->make_dirty();
}
if (all_dynamic) {
} // if(link_tristrips)
// for now, only using vertexbufs for static Geom, so
// Make sure we have at least some static Geoms in the GeomNode;
int cNumVerts=0,i,num_geoms = node->get_num_geoms();
// need to always put in space for color because we might have some scene-graph color we need to add?
// will that even work? I think we'd have to overwrite all the VB colors dynamically, and then restore
// them from somewhere if the global color goes away
DWORD fvfFlags=D3DFVF_XYZ;// | D3DFVF_DIFFUSE;
for (i = 0; (i < num_geoms); i++) {
dDrawable *drawable1 = node->get_geom(i);
if(!drawable1->is_of_type(Geom::get_class_type()))
continue;
Geom *geom=DCAST(Geom, drawable1);
assert(geom!=NULL);
if(!geom->is_dynamic()) {
cNumVerts+=geom->get_num_vertices();
if(geom->get_binding(G_COLOR) != G_OFF)
fvfFlags |= D3DFVF_DIFFUSE;
if(geom->get_binding(G_NORMAL) != G_OFF)
fvfFlags |= D3DFVF_NORMAL;
if(geom->get_binding(G_TEXCOORD) != G_OFF)
fvfFlags |= (D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE2(0));
}
}
if(cNumVerts==0) {
// Never mind.
return (GeomNodeContext *)NULL;
}
// Ok, we've got something; use it.
DXGeomNodeContext *ggnc = new DXGeomNodeContext(node);
DXGeomNodeContext *dx_gnc = new DXGeomNodeContext(node);
#if 0
ggnc->_index = DXGenLists(1);
if (ggnc->_index == 0) {
DXgsg_cat.error() << "Ran out of display list indices.\n";
delete ggnc;
return (GeomNodeContext *)NULL;
assert(dx_gnc!=NULL);
// right now there is a 1-1 correspondence b/w vertbufs and geomnodecontexts.
// later multiple geomnodecontexts will use the same vertbuf
HRESULT hr;
LPDIRECT3D7 pD3D;
assert(_d3dDevice!=NULL);
hr=_d3dDevice->GetDirect3D(&pD3D);
assert(!FAILED(hr));
LPDIRECT3DVERTEXBUFFER7 pD3DVertexBuffer;
DX_DECLARE_CLEAN(D3DVERTEXBUFFERDESC, VBdesc);
VBdesc.dwCaps = D3DVBCAPS_WRITEONLY;
VBdesc.dwCaps |= _bIsTNLDevice ? 0x0 : D3DVBCAPS_SYSTEMMEMORY;
VBdesc.dwFVF=fvfFlags;
VBdesc.dwNumVertices=cNumVerts;
hr=pD3D->CreateVertexBuffer(&VBdesc,&pD3DVertexBuffer,0x0);
if(FAILED(hr)) {
dxgsg_cat.error() << "error creating vertex buffer: " << ConvD3DErrorToString(hr) << endl;
delete dx_gnc;
exit(1);
}
#endif
// We need to temporarily force normals and UV's on, so the display
// list will have them built in.
bool old_normals_enabled = _normals_enabled;
bool old_texturing_enabled = _texturing_enabled;
bool old_vertex_colors_enabled = _vertex_colors_enabled;
_normals_enabled = true;
_texturing_enabled = true;
_vertex_colors_enabled = true;
dx_gnc->_pVB = pD3DVertexBuffer;
#ifdef DO_PSTATS
// Count up the number of vertices we're about to render, by
// checking the PStats vertex counters now, and at the end. This is
// kind of hacky, but this is debug code.
float num_verts_before =
_vertices_tristrip_pcollector.get_level() +
_vertices_trifan_pcollector.get_level() +
_vertices_tri_pcollector.get_level() +
_vertices_other_pcollector.get_level();
#endif
if(!_bIsTNLDevice) {
// create VB for ProcessVerts to xform to
// Now define the display list.
DXNewList(ggnc->_index, DX_COMPILE);
for (i = 0; i < num_geoms; i++) {
dDrawable *geom = node->get_geom(i);
if (geom->is_dynamic()) {
// Wait, this is a dynamic Geom. We can't safely put it in the
// display list, because it may change from one frame to the
// next; instead, we'll keep it out.
ggnc->_dynamic_geoms.push_back(geom);
fvfFlags&=~D3DFVF_XYZ; // switch to xformed vert type
fvfFlags&=~D3DFVF_NORMAL; // xformed verts are also lighted, so no normals allowed
fvfFlags|=D3DFVF_XYZRHW;
VBdesc.dwFVF=fvfFlags;
hr=pD3D->CreateVertexBuffer(&VBdesc,&pD3DVertexBuffer,0x0);
if(FAILED(hr)) {
dxgsg_cat.error() << "error creating xformed vertex buffer: " << ConvD3DErrorToString(hr) << endl;
delete dx_gnc;
exit(1);
}
dx_gnc->_pXformed_VB = pD3DVertexBuffer;
}
pD3D->Release();
dx_gnc->_num_verts=cNumVerts;
dx_gnc->_start_index=0;
DWORD *pVertData=NULL;
DWORD dwVBFlags = DDLOCK_NOOVERWRITE | DDLOCK_NOSYSLOCK | DDLOCK_SURFACEMEMORYPTR |
DDLOCK_WAIT | DDLOCK_DISCARDCONTENTS;
hr=dx_gnc->_pVB->Lock(dwVBFlags,(LPVOID*)&pVertData,NULL);
if(FAILED(hr)) {
dxgsg_cat.error() << "error locking vertex buffer: " << ConvD3DErrorToString(hr) << endl;
delete dx_gnc;
exit(1);
}
assert(pVertData!=NULL);
for (i = 0; (i < num_geoms); i++) {
dDrawable *drawable1 = node->get_geom(i);
if(!drawable1->is_of_type(Geom::get_class_type()))
continue;
Geom *geom=DCAST(Geom, drawable1);
assert(geom!=NULL);
if(geom->is_dynamic()) {
dx_gnc->_other_geoms.push_back(geom);
} else {
// A static Geom becomes part of the display list.
geom->draw(this);
#if 0
PTA_Vertexf coords;
PTA_Normalf norms;
PTA_Colorf colors;
PTA_TexCoordf texcoords;
GeomBindType TexCoordBinding,ColorBinding,NormalBinding,CoordBinding;
PTA_ushort vindexes,nindexes,tindexes,cindexes;
geom->get_coords(coords,CoordBinding,vindexes);
geom->get_normals(norms,NormalBinding,nindexes);
geom->get_colors(colors,ColorBinding,cindexes);
geom->get_texcoords(texcoords,TexCoordBinding,tindexes);
//// copy geometry into pVertData
just use lengths array and copy it straight in, we dont need to know type, right
no that wont work because of per-prim and per-component info
need to call draw fns with special flag to not call drawp
#endif
}
}
DXEndList();
#ifdef DO_PSTATS
hr=dx_gnc->_pVB->Unlock();
if(FAILED(hr)) {
dxgsg_cat.error() << "error unlocking vertex buffer: " << ConvD3DErrorToString(hr) << endl;
delete dx_gnc;
exit(1);
}
hr=dx_gnc->_pVB->Optimize(_d3dDevice,0x0);
if(FAILED(hr)) {
dxgsg_cat.error() << "error optimizing vertex buffer: " << ConvD3DErrorToString(hr) << endl;
delete dx_gnc;
exit(1);
}
#if 0 //DO_PSTATS
float num_verts_after =
_vertices_tristrip_pcollector.get_level() +
_vertices_trifan_pcollector.get_level() +
@ -6380,19 +6526,14 @@ for( ii=0;ii<new_color_indices.size();ii++)
ggnc->_num_verts = (int)(num_verts + 0.5);
#endif
_normals_enabled = old_normals_enabled;
_texturing_enabled = old_texturing_enabled;
_vertex_colors_enabled = old_vertex_colors_enabled;
bool inserted = mark_prepared_geom_node(ggnc);
bool inserted = mark_prepared_geom_node(dx_gnc);
// If this assertion fails, the same GeomNode was prepared twice,
// which shouldn't be possible, since the GeomNode itself should
// detect this.
nassertr(inserted, NULL);
return ggnc;
#endif
return dx_gnc;
}
////////////////////////////////////////////////////////////////////
@ -6403,33 +6544,69 @@ for( ii=0;ii<new_color_indices.size();ii++)
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
draw_geom_node(GeomNode *node, GeomNodeContext *gnc) {
#if 0
int i,num_geoms = node->get_num_geoms();
if (gnc == (GeomNodeContext *)NULL) {
// We don't have a saved context; just draw the GeomNode in
// immediate mode.
int num_geoms = node->get_num_geoms();
for (int i = 0; i < num_geoms; i++) {
for (i = 0; i < num_geoms; i++) {
node->get_geom(i)->draw(this);
}
} else {
// We do have a saved context; use it.
add_to_geom_node_record(gnc);
DXGeomNodeContext *ggnc = DCAST(DXGeomNodeContext, gnc);
DXCallList(ggnc->_index);
#ifdef DO_PSTATS
DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector));
_vertices_display_list_pcollector.add_level(ggnc->_num_verts);
#endif
// Also draw all the dynamic Geoms.
int num_geoms = ggnc->_dynamic_geoms.size();
for (int i = 0; i < num_geoms; i++) {
ggnc->_dynamic_geoms[i]->draw(this);
}
return;
}
// We do have a saved context; use it.
add_to_geom_node_record(gnc);
DXGeomNodeContext *dx_gnc = DCAST(DXGeomNodeContext, gnc);
#ifdef _DEBUG
assert(dx_gnc->_pVB!=NULL);
if(_bIsTNLDevice)
assert(dx_gnc->_pXformed_VB!=NULL);
#endif
if(!_bIsTNLDevice) {
HRESULT hr;
DWORD PVOp=D3DVOP_CLIP | D3DVOP_TRANSFORM | D3DVOP_EXTENTS;
D3DVERTEXBUFFERDESC VBdesc;
VBdesc.dwSize=sizeof(VBdesc);
hr=dx_gnc->_pVB->GetVertexBufferDesc(&VBdesc); // would be useful to keep fvf in vertbuf struct to avoid having to do this
if(FAILED(hr)) {
dxgsg_cat.error() << "error in getvbdesc: " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
if(VBdesc.dwFVF & D3DFVF_NORMAL) {
PVOp|=D3DVOP_LIGHT;
}
hr=dx_gnc->_pXformed_VB->ProcessVertices(PVOp,0,dx_gnc->_num_verts,dx_gnc->_pVB,0,_d3dDevice,0x0);
if(FAILED(hr)) {
dxgsg_cat.error() << "error in ProcessVertices: " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
}
for (i = 0; i < num_geoms; i++) {
node->get_geom(i)->draw(this);
}
#if 0 //def DO_PSTATS
DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector));
_vertices_display_list_pcollector.add_level(dx_gnc->_num_verts);
#endif
// Also draw all the dynamic Geoms.
for (i = 0; i < num_geoms; i++) {
dx_gnc->_other_geoms[i]->draw(this);
}
}
////////////////////////////////////////////////////////////////////
@ -6441,19 +6618,16 @@ draw_geom_node(GeomNode *node, GeomNodeContext *gnc) {
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian::
release_geom_node(GeomNodeContext *gnc) {
#if 0
if (gnc != (GeomNodeContext *)NULL) {
DXGeomNodeContext *ggnc = DCAST(DXGeomNodeContext, gnc);
DXDeleteLists(ggnc->_index, 1);
DXGeomNodeContext *dx_gnc = DCAST(DXGeomNodeContext, gnc);
bool erased = unmark_prepared_geom_node(ggnc);
bool erased = unmark_prepared_geom_node(dx_gnc);
// If this assertion fails, a GeomNode was released that hadn't
// been prepared (or a GeomNode was released twice).
nassertv(erased);
ggnc->_node->clear_gsg(this);
delete ggnc;
dx_gnc->_node->clear_gsg(this);
delete dx_gnc; // should release vertex buffer
}
#endif
}

View File

@ -355,6 +355,8 @@ protected:
bool _alpha_test_enabled;
int _decal_level;
GraphicsChannel *_panda_gfx_channel; // cache the 1 channel dx supports
// Cur Texture State
TextureApplyProperty::Mode _CurTexBlendMode;
Texture::FilterType _CurTexMagFilter,_CurTexMinFilter;