fix decaling

This commit is contained in:
georges 2000-10-17 02:32:44 +00:00
parent 4e8a15ccd0
commit 396daaa3cb
4 changed files with 71 additions and 43 deletions

View File

@ -1,7 +1,5 @@
// Filename: config_dxgsg.cxx // Filename: config_dxgsg.cxx
// Created by: drose (06Oct99) // Created by: drose (06Oct99)
//
////////////////////////////////////////////////////////////////////
#include "config_dxgsg.h" #include "config_dxgsg.h"
#include "dxGraphicsStateGuardian.h" #include "dxGraphicsStateGuardian.h"
@ -31,7 +29,7 @@ bool dx_cheap_textures = config_dxgsg.GetBool("dx-cheap-textures", false);
// for state-sorting, z-sorting, and binning. // for state-sorting, z-sorting, and binning.
bool dx_cull_traversal = config_dxgsg.GetBool("dx-cull-traversal", true); bool dx_cull_traversal = config_dxgsg.GetBool("dx-cull-traversal", true);
DXDecalType dx_decal_type = GDT_blend; DXDecalType dx_decal_type = GDT_offset;
static DXDecalType static DXDecalType
parse_decal_type(const string &type) { parse_decal_type(const string &type) {

View File

@ -350,26 +350,51 @@ init_dx( LPDIRECTDRAW7 context,
LPDIRECTDRAWSURFACE7 pri, LPDIRECTDRAWSURFACE7 pri,
LPDIRECTDRAWSURFACE7 back, LPDIRECTDRAWSURFACE7 back,
LPDIRECTDRAWSURFACE7 zbuf, LPDIRECTDRAWSURFACE7 zbuf,
LPDIRECT3D7 d3d, LPDIRECT3D7 pD3D,
LPDIRECT3DDEVICE7 d3dDevice, LPDIRECT3DDEVICE7 pDevice,
RECT viewrect) RECT viewrect)
{ {
_pDD = context; _pDD = context;
_pri = pri; _pri = pri;
_back = back; _back = back;
_zbuf = zbuf; _zbuf = zbuf;
_d3d = d3d; _d3d = pD3D;
_d3dDevice = d3dDevice; _d3dDevice = pDevice;
_view_rect = viewrect; _view_rect = viewrect;
HRESULT hr;
_pTexPixFmts = new DDPIXELFORMAT[MAX_DX_TEXPIXFMTS]; _pTexPixFmts = new DDPIXELFORMAT[MAX_DX_TEXPIXFMTS];
assert(_pTexPixFmts!=NULL); assert(_pTexPixFmts!=NULL);
if (d3dDevice->EnumTextureFormats(EnumTexFmtsCallback, this) != S_OK) { if (pDevice->EnumTextureFormats(EnumTexFmtsCallback, this) != S_OK) {
dxgsg_cat.error() << "EnumTextureFormats failed!!\n"; dxgsg_cat.error() << "EnumTextureFormats failed!!\n";
} }
D3DDEVICEDESC7 D3DDevDesc;
if(FAILED(hr = pDevice->GetCaps(&D3DDevDesc))) {
dxgsg_cat.fatal() << "GetCaps failed on Device\n";
exit(1);
}
if((dx_decal_type==GDT_offset) && !(D3DDevDesc.dpcTriCaps.dwRasterCaps & D3DPRASTERCAPS_ZBIAS)) {
#ifdef _DEBUG
dxgsg_cat.error() << "dx-decal-type 'offset' not supported by hardware, switching to decal masking\n";
#endif
dx_decal_type = GDT_mask;
}
if((dx_decal_type==GDT_mask) && !(D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKPLANES)) {
#ifdef _DEBUG
dxgsg_cat.error() << "No hardware support for colorwrite disabling, switching to dx-decal-type 'mask' to 'blend'\n";
#endif
dx_decal_type = GDT_blend;
}
if(((dx_decal_type==GDT_blend)||(dx_decal_type==GDT_mask)) && !(D3DDevDesc.dpcTriCaps.dwMiscCaps & D3DPMISCCAPS_MASKZ))
dxgsg_cat.error() << "dx-decal-type mask impossible to implement, no hardware support for Z-masking, decals will not appear correctly\n";
SetRect(&clip_rect, 0,0,0,0); // no clip rect set SetRect(&clip_rect, 0,0,0,0); // no clip rect set
_d3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1); _d3dDevice->SetRenderState(D3DRENDERSTATE_AMBIENTMATERIALSOURCE, D3DMCS_COLOR1);
@ -3532,17 +3557,18 @@ begin_decal(GeomNode *base_geom) {
_decal_level++; _decal_level++;
nassertv(4*_decal_level < 16); nassertv(4*_decal_level < 16);
if (dx_decal_type == GDT_offset) if (dx_decal_type == GDT_offset) {
{
#define POLYGON_OFFSET_MULTIPLIER 2
// Just draw the base geometry normally. // Just draw the base geometry normally.
base_geom->draw(this); base_geom->draw(this);
//bugbug: restoring zbias properly requires a stack of values!!! this is wrong, need to save old value on stack _d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, POLYGON_OFFSET_MULTIPLIER * _decal_level); // _decal_level better not be higher than 4!
_d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, 4 * _decal_level); // _decal_level better not be higher than 8! } else {
} else {
if (_decal_level > 1) if (_decal_level > 1)
base_geom->draw(this); // If we're already decaling, just draw the geometry. base_geom->draw(this); // If we're already decaling, just draw the geometry.
else { else {
// Turn off writing the depth buffer to render the base geometry. // First turn off writing the depth buffer to render the base geometry.
_d3dDevice->GetRenderState(D3DRENDERSTATE_ZWRITEENABLE, (unsigned long *)&_depth_write_enabled); //save cur val
_d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE); _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, FALSE);
// Now render the base geometry. // Now render the base geometry.
@ -3551,8 +3577,7 @@ begin_decal(GeomNode *base_geom) {
// Render all of the decal geometry, too. We'll keep the depth // Render all of the decal geometry, too. We'll keep the depth
// buffer write off during this. // buffer write off during this.
} }
} }
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@ -3569,16 +3594,11 @@ end_decal(GeomNode *base_geom) {
_decal_level--; _decal_level--;
// nassertv(_decal_level >= 1); // nassertv(_decal_level >= 1);
if (dx_decal_type == GDT_offset) if (dx_decal_type == GDT_offset) {
{
// Restore the Zbias offset. // Restore the Zbias offset.
//bugbug: restoring zbias properly requires a stack of values!!! this is wrong, need to save old value on stack _d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, POLYGON_OFFSET_MULTIPLIER * _decal_level); // _decal_level better not be higher than 8!
_d3dDevice->SetRenderState(D3DRENDERSTATE_ZBIAS, 4 * _decal_level); // _decal_level better not be higher than 8! } else { // for GDT_mask
} if (_decal_level == 0) {
else
{
if (_decal_level == 0)
{
// Now we need to re-render the base geometry with the depth write // Now we need to re-render the base geometry with the depth write
// on and the color mask off, so we update the depth buffer // on and the color mask off, so we update the depth buffer
// properly. // properly.
@ -3591,14 +3611,16 @@ end_decal(GeomNode *base_geom) {
_d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE); _d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, TRUE);
// Disable the writing to the color buffer, however we have to // Disable the writing to the color buffer, however we have to
// do this. (I don't think this is possible in DX without blending. // do this. (I don't think this is possible in DX without blending.)
// if (dx_decal_type == GDT_blend) if (dx_decal_type == GDT_blend) {
// {
// Expensive. // Expensive.
enable_blend(true); enable_blend(true);
call_dxBlendFunc(D3DBLEND_ZERO, D3DBLEND_ONE); call_dxBlendFunc(D3DBLEND_ZERO, D3DBLEND_ONE);
// } }
// else glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); else {
// note: not saving current planemask val, assumes this is always all 1's. should be ok
_d3dDevice->SetRenderState(D3DRENDERSTATE_PLANEMASK,0x0); // note PLANEMASK is supposedly obsolete for DX7
}
// No need to have texturing on for this. // No need to have texturing on for this.
enable_texturing(false); enable_texturing(false);
@ -3607,28 +3629,34 @@ end_decal(GeomNode *base_geom) {
// Finally, restore the depth write and color mask states to the // Finally, restore the depth write and color mask states to the
// way they're supposed to be. // way they're supposed to be.
/*
DepthWriteAttribute *depth_write; DepthWriteAttribute *depth_write;
if (get_attribute_into(depth_write, _state, if (get_attribute_into(depth_write, _state,
DepthWriteTransition::get_class_type())) DepthWriteTransition::get_class_type()))
issue_depth_write(depth_write); issue_depth_write(depth_write);
// if (dx_decal_type == GDT_blend) { ColorMaskAttribute *color_mask;
enable_blend(was_blend);
if (was_blend)
call_dxBlendFunc(old_blend_source_func, old_blend_dest_func);
enable_texturing(was_textured);
}
}
/* } else {
ColorMaskAttribute *color_mask;
if (get_attribute_into(color_mask, _state, if (get_attribute_into(color_mask, _state,
ColorMaskTransition::get_class_type())) { ColorMaskTransition::get_class_type())) {
issue_color_mask(color_mask); issue_color_mask(color_mask);
} else { } else {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
} }
} */
*/
if (dx_decal_type == GDT_blend) {
enable_blend(was_blend);
if (was_blend)
call_dxBlendFunc(old_blend_source_func, old_blend_dest_func);
} else {
_d3dDevice->SetRenderState(D3DRENDERSTATE_PLANEMASK,0xFFFFFFFF);
}
enable_texturing(was_textured);
_d3dDevice->SetRenderState(D3DRENDERSTATE_ZWRITEENABLE, _depth_write_enabled);
}
}
} }
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////

View File

@ -378,6 +378,8 @@ protected:
bool _multisample_alpha_mask_enabled; bool _multisample_alpha_mask_enabled;
bool _blend_enabled; bool _blend_enabled;
bool _depth_test_enabled; bool _depth_test_enabled;
bool _depth_write_enabled;
DWORD _old_colormaskval;
bool _fog_enabled; bool _fog_enabled;
bool _alpha_test_enabled; bool _alpha_test_enabled;
int _decal_level; int _decal_level;

View File

@ -168,7 +168,7 @@ CreateTexture( HDC hdc, LPDIRECT3DDEVICE7 pd3dDevice, int cNumTexPixFmts, LPDDPI
DWORD cNumColorChannels = pbuf->get_num_components(); DWORD cNumColorChannels = pbuf->get_num_components();
if((cNumColorChannels != 3) && (cNumColorChannels != 4)) { if((cNumColorChannels != 3) && (cNumColorChannels != 4)) {
dxgsg_cat.error() << "CreateTexture failed, havent handled pixbufs with < 3 channels yet! \n"; dxgsg_cat.error() << "CreateTexture failed for "<< _tex->get_name()<<", havent handled pixbufs with < 3 channels yet! \n";
return NULL; return NULL;
} }