bring vertex bufs closer to working

This commit is contained in:
cxgeorge 2001-11-08 22:40:32 +00:00
parent 26bdf202ff
commit d18a42e0cd
3 changed files with 106 additions and 42 deletions

View File

@ -147,6 +147,14 @@ set_shademode(D3DSHADEMODE val) {
}
}
INLINE void DXGraphicsStateGuardian::
enable_primitive_clipping(bool val) {
if (_clipping_enabled != val) {
_clipping_enabled = val;
_d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPING, (DWORD)val);
}
}
////////////////////////////////////////////////////////////////////
// Function: DXGraphicsStateGuardian::enable_fog
// Access:

View File

@ -294,6 +294,9 @@ void DXGraphicsStateGuardian::FillFPSMeterTexture(void) {
return;
}
HFONT hfnt = (HFONT) GetStockObject(ANSI_FIXED_FONT);
(void) SelectObject(hDC, hfnt);
SetTextColor(hDC, RGB(255,255,128) );
SetBkMode(hDC, TRANSPARENT );
@ -489,6 +492,9 @@ dx_init( LPDIRECTDRAW7 context,
_cur_clip_plane_enabled = (bool *)NULL;
_d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPLANEENABLE , 0x0);
_d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPING, true);
_clipping_enabled = true;
_CurShadeMode = D3DSHADE_FLAT;
_d3dDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, _CurShadeMode);
@ -1796,10 +1802,10 @@ draw_prim_setup(const Geom *geom) {
#define GET_NEXT_COLOR() { \
if(_color_transform_enabled || _alpha_transform_enabled) { \
Colorf tempcolor = geom->get_next_color(ci); \
transform_color(tempcolor,_curD3Dcolor); \
transform_color(tempcolor,_curD3Dcolor); \
} else { \
p_color = geom->get_next_color(ci); \
_curD3Dcolor = Colorf_to_D3DCOLOR(p_color); \
_curD3Dcolor = Colorf_to_D3DCOLOR(p_color); \
}}
////////
@ -1857,9 +1863,11 @@ draw_prim_setup(const Geom *geom) {
// (note, TNT does the right thing tho). So I guess we must do gouraud shading for all fog rendering for now
// note that if _doFogType==None, _fog_enabled will always be false
if ((_perVertex & (PER_COLOR | (wants_normals() ? PER_NORMAL : 0))) || _fog_enabled)
set_shademode(D3DSHADE_GOURAUD);
else set_shademode(D3DSHADE_FLAT);
D3DSHADEMODE needed_shademode =
(((_perVertex & (PER_COLOR | (wants_normals() ? PER_NORMAL : 0))) || _fog_enabled) ?
D3DSHADE_GOURAUD : D3DSHADE_FLAT);
set_shademode(needed_shademode);
return vertex_size;
}
@ -2336,8 +2344,6 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
#ifdef GSG_VERBOSE
dxgsg_cat.debug() << "draw_sprite()" << endl;
#endif
DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector));
// get the array traversal set up.
int nprims = geom->get_num_prims();
@ -2345,30 +2351,46 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
return;
}
DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(nprims));
DO_PSTATS_STUFF(PStatTimer timer(_draw_primitive_pcollector));
Texture *tex = geom->get_texture();
nassertv(tex != (Texture *) NULL);
DO_PSTATS_STUFF(_vertices_other_pcollector.add_level(nprims));
D3DMATRIX OldD3DWorldMatrix;
_d3dDevice->GetTransform(D3DTRANSFORMSTATE_WORLD, &OldD3DWorldMatrix);
// ATI sez: most applications ignore the fact that since alpha blended primitives
// combine the data in the frame buffer with the data in the current pixel, pixels
// can be dithered multiple times and accentuate the dither pattern. This is particularly
// true in particle systems which rely on the cumulative visual effect of many overlapping
// alpha blended primitives.
bool bReEnableDither=_dither_enabled;
if(bReEnableDither) {
enable_dither(false);
}
bool bReEnableDither=false;
_d3dDevice->GetTransform(D3DTRANSFORMSTATE_WORLD, &OldD3DWorldMatrix);
Geom::VertexIterator vi = geom->make_vertex_iterator();
Geom::ColorIterator ci = geom->make_color_iterator();
// note although sprite particles technically dont require a texture,
// the texture dimensions are used to initialize the size calculations
// the code in spriteParticleRenderer.cxx does not handle the no-texture case now
float tex_xsize = 1.0f;
float tex_ysize = 1.0f;
Texture *tex = geom->get_texture();
if(tex !=NULL) {
// set up the texture-rendering state
NodeTransitions state;
// this sets up texturing. Could just set the renderstates directly, but this is a little cleaner
TextureTransition *ta = new TextureTransition(tex);
state.set_transition(ta);
TextureApplyTransition *taa = new TextureApplyTransition(TextureApplyProperty::M_modulate);
state.set_transition(taa);
modify_state(state);
tex_xsize = tex->_pbuffer->get_xsize();
tex_ysize = tex->_pbuffer->get_ysize();
}
// save the modelview matrix
LMatrix4f modelview_mat;
@ -2392,22 +2414,10 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
float tex_bottom = geom->get_ll_uv()[1];
float tex_top = geom->get_ur_uv()[1];
float half_width = 0.5f * (float) tex->_pbuffer->get_xsize() * fabs(tex_right - tex_left);
float half_height = 0.5f * (float) tex->_pbuffer->get_ysize() * fabs(tex_top - tex_bottom);
float half_width = 0.5f * tex_xsize * fabs(tex_right - tex_left);
float half_height = 0.5f * tex_ysize * fabs(tex_top - tex_bottom);
float scaled_width, scaled_height;
// set up the texture-rendering state
NodeTransitions state;
// this sets up texturing. Could just set the renderstates directly, but this is a little cleaner
TextureTransition *ta = new TextureTransition(tex);
state.set_transition(ta);
TextureApplyTransition *taa = new TextureApplyTransition(TextureApplyProperty::M_modulate);
state.set_transition(taa);
modify_state(state);
// the user can override alpha sorting if they want
bool alpha = false;
@ -2521,8 +2531,19 @@ draw_sprite(GeomSprite *geom, GeomContext *gc) {
// if you want accuracy, use billboards and take the speed hit.
sort(sorted_sprite_vector.begin(), sorted_sprite_vector.end(), draw_sprite_vertex_less());
sorted_vec_iter = sorted_sprite_vector.begin();
// disabling dither for alpha particle-systems.
// ATI sez: most applications ignore the fact that since alpha blended primitives
// combine the data in the frame buffer with the data in the current pixel, pixels
// can be dithered multiple times and accentuate the dither pattern. This is particularly
// true in particle systems which rely on the cumulative visual effect of many overlapping
// alpha blended primitives.
if(_dither_enabled) {
bReEnableDither=true;
enable_dither(false);
}
}
Vertexf ul, ur, ll, lr;
@ -7028,6 +7049,11 @@ prepare_geom_node(GeomNode *node) {
return (GeomNodeContext *)NULL;
}
if(cNumVerts>D3DMAXNUMVERTICES) {
dxgsg_cat.error() << "geom node contains more than " << D3DMAXNUMVERTICES << " vertices, cant create 1 vertex buffer\n";
exit(1);
}
// Ok, we've got something; use it.
DXGeomNodeContext *dx_gnc = new DXGeomNodeContext(node);
@ -7079,7 +7105,7 @@ prepare_geom_node(GeomNode *node) {
pD3D->Release();
dx_gnc->_num_verts=cNumVerts;
dx_gnc->_num_verts=0;
dx_gnc->_start_index=0;
LPVOID pVertData=NULL;
@ -7126,6 +7152,8 @@ prepare_geom_node(GeomNode *node) {
exit(1);
}
assert(cNumVerts==dx_gnc->_num_verts);
hr=dx_gnc->_pVB->Optimize(_d3dDevice,0x0);
if(FAILED(hr)) {
dxgsg_cat.error() << "error optimizing vertex buffer: " << ConvD3DErrorToString(hr) << endl;
@ -7133,6 +7161,9 @@ prepare_geom_node(GeomNode *node) {
exit(1);
}
if(dxgsg_cat.is_spam())
dxgsg_cat.spam() << "creating vertex buffer of size: " << cNumVerts << endl;
#if 0 //DO_PSTATS
float num_verts_after =
_vertices_tristrip_pcollector.get_level() +
@ -7180,8 +7211,7 @@ draw_geom_node(GeomNode *node, GeomNodeContext *gnc) {
#ifdef _DEBUG
assert(dx_gnc->_pVB!=NULL);
if(_bIsTNLDevice)
assert(dx_gnc->_pXformed_VB!=NULL);
assert((!_bIsTNLDevice)==(dx_gnc->_pXformed_VB!=NULL));
#endif
if(!_bIsTNLDevice) {
@ -7197,7 +7227,7 @@ draw_geom_node(GeomNode *node, GeomNodeContext *gnc) {
exit(1);
}
if(VBdesc.dwFVF & D3DFVF_NORMAL) {
if(_lighting_enabled && (VBdesc.dwFVF & D3DFVF_NORMAL)) {
PVOp|=D3DVOP_LIGHT;
}
@ -7206,14 +7236,38 @@ draw_geom_node(GeomNode *node, GeomNodeContext *gnc) {
dxgsg_cat.error() << "error in ProcessVertices: " << ConvD3DErrorToString(hr) << endl;
exit(1);
}
// disable clipping, since VB is already xformed and clipped
if(_clipping_enabled)
_d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPING, false);
}
// need to tell draw_prims to use DrawPrimitiveVB with current vertex buffer
// assume we need gouraud for now. we can make this more complex to select flat conditionally later
set_shademode(D3DSHADE_GOURAUD);
int cur_startvert=dx_gnc->_start_index;
for (i = 0; i < dx_gnc->_cached_geoms.size(); i++) {
dx_gnc->_cached_geoms[i]->draw(this);
// I think we can just draw them directly? since cant account for issued stuff (since
// its already encoded in the VB), and we can set the renderstates here (e.g. gouraud mode)
// dx_gnc->_cached_geoms[i]->draw(this);
DPInfo *dpi=&dx_gnc->_PrimInfo[i];
LPDIRECT3DVERTEXBUFFER7 pVB;
if(_bIsTNLDevice) {
pVB=dx_gnc->_pVB;
} else {
pVB=dx_gnc->_pXformed_VB;
}
HRESULT hr = _d3dDevice->DrawPrimitiveVB(dpi->primtype,pVB,cur_startvert,dpi->nVerts,0x0);
TestDrawPrimFailure(DrawPrim,hr,_pDD,dpi->nVerts,0);
cur_startvert+=dpi->nVerts;
}
// unset the flag above
if((!_bIsTNLDevice) && _clipping_enabled)
_d3dDevice->SetRenderState(D3DRENDERSTATE_CLIPPING, true);
// Also draw all the dynamic Geoms.
for (i = 0; i < dx_gnc->_other_geoms.size(); i++) {

View File

@ -297,6 +297,7 @@ protected:
INLINE D3DCMPFUNC get_stencil_func_type(StencilProperty::Mode m) const;
INLINE D3DSTENCILOP get_stencil_action_type(StencilProperty::Action a) const;
INLINE void enable_primitive_clipping(bool val);
INLINE void enable_alpha_test(bool val);
INLINE void enable_line_smooth(bool val);
INLINE void enable_blend(bool val);
@ -376,6 +377,7 @@ protected:
bool _lighting_enabled;
bool _lighting_enabled_this_frame;
bool _texturing_enabled;
bool _clipping_enabled;
bool _dither_enabled;
bool _stencil_test_enabled;
bool* _clip_plane_enabled; // bool[_max_clip_planes]