📄 zfxd3d_misc.cpp
字号:
/*----------------------------------------------------------------*/
// enable / disable use of color buffer
void ZFXD3D::UseColorBuffer(bool b) {
// clear out buffers prior to state changes
m_pVertexMan->ForcedFlushAll();
m_pVertexMan->InvalidateStates();
m_bColorBuffer = b;
if (!b) {
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}
else {
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
}
} // UseColorBuffer
/*----------------------------------------------------------------*/
// SET VARIOUS RENDERSTATES AND STUFF LIKE THAT
void ZFXD3D::SetBackfaceCulling(ZFXRENDERSTATE rs) {
// clear out buffers prior to state changes
m_pVertexMan->ForcedFlushAll();
if (rs == RS_CULL_CW)
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
else if (rs == RS_CULL_CCW)
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
else if (rs == RS_CULL_NONE)
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
} // SetBackfaceCulling
/*----------------------------------------------------------------*/
void ZFXD3D::SetStencilBufferMode(ZFXRENDERSTATE rs, DWORD dw) {
// clear out buffers prior to state changes
m_pVertexMan->ForcedFlushAll();
switch (rs) {
// switch on and off
case RS_STENCIL_DISABLE:
m_pDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
break;
case RS_STENCIL_ENABLE:
m_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
break;
case RS_DEPTHBIAS:
m_pDevice->SetRenderState(D3DRS_DEPTHBIAS, dw);
// function modes and values
case RS_STENCIL_FUNC_ALWAYS:
m_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
break;
case RS_STENCIL_FUNC_LESSEQUAL:
m_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL);
break;
case RS_STENCIL_MASK:
m_pDevice->SetRenderState(D3DRS_STENCILMASK, dw);
break;
case RS_STENCIL_WRITEMASK:
m_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, dw);
break;
case RS_STENCIL_REF:
m_pDevice->SetRenderState(D3DRS_STENCILREF, dw);
break;
// stencil test fails modes
case RS_STENCIL_FAIL_DECR:
m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_DECR);
break;
case RS_STENCIL_FAIL_INCR:
m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_INCR);
break;
case RS_STENCIL_FAIL_KEEP:
m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
break;
// stencil test passes but z test fails modes
case RS_STENCIL_ZFAIL_DECR:
m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR);
break;
case RS_STENCIL_ZFAIL_INCR:
m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR);
break;
case RS_STENCIL_ZFAIL_KEEP:
m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
break;
// stencil test passes modes
case RS_STENCIL_PASS_DECR:
m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_DECR);
break;
case RS_STENCIL_PASS_INCR:
m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_INCR);
break;
case RS_STENCIL_PASS_KEEP:
m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
break;
} // switch
} // SetStencilBufferMode
/*----------------------------------------------------------------*/
void ZFXD3D::UseStencilShadowSettings(bool b) {
ZFXMatrix matProj;
m_pVertexMan->InvalidateStates();
if (b) {
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
m_pDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
m_pDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
m_pDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
m_pDevice->SetRenderState(D3DRS_STENCILREF, 0x1);
m_pDevice->SetRenderState(D3DRS_STENCILMASK, 0xffffffff);
m_pDevice->SetRenderState(D3DRS_STENCILWRITEMASK, 0xffffffff);
m_pDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_INCR);
UseColorBuffer(false);
}
else {
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
UseColorBuffer(true);
SetMode(m_Mode, m_nStage);
}
} // UseStencilShadowSettings
/*----------------------------------------------------------------*/
void ZFXD3D::SetDepthBufferMode(ZFXRENDERSTATE rs) {
// clear out buffers prior to state changes
m_pVertexMan->ForcedFlushAll();
if (rs == RS_DEPTH_READWRITE) {
m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
}
else if (rs == RS_DEPTH_READONLY) {
m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
}
else if (rs == RS_DEPTH_NONE){
m_pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
}
} // SetDepthBufferMode
/*----------------------------------------------------------------*/
inline DWORD FtoDW( FLOAT f ) { return *((DWORD*)&f); }
void ZFXD3D::SetShadeMode(ZFXRENDERSTATE smd, float f, const ZFXCOLOR *pClr) {
// copy color if it was given
if ( pClr && !m_pSkinMan->ColorEqual( pClr, &m_clrWire) ) {
m_pVertexMan->ForcedFlushAll();
m_pVertexMan->InvalidateStates();
memcpy(&m_clrWire, pClr, sizeof(ZFXCOLOR));
}
// no change in current mode
if (smd == m_ShadeMode) {
// but maybe change in size
if (smd==RS_SHADE_POINTS) {
m_pVertexMan->ForcedFlushAll();
m_pDevice->SetRenderState(D3DRS_POINTSIZE, FtoDW(f));
}
return;
}
else {
m_pVertexMan->ForcedFlushAll();
}
if (smd == RS_SHADE_TRIWIRE) {
// only triangle wireframe ist set via d3d shade mode
m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
m_ShadeMode = smd;
}
else {
if (smd != RS_SHADE_SOLID) {
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);
}
m_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);
m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
m_ShadeMode = smd;
}
if (smd == RS_SHADE_POINTS) {
if (f > 0.0f) {
m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_POINTSIZE, FtoDW( f ));
m_pDevice->SetRenderState(D3DRS_POINTSIZE_MIN, FtoDW(0.00f));
m_pDevice->SetRenderState(D3DRS_POINTSCALE_A, FtoDW(0.00f));
m_pDevice->SetRenderState(D3DRS_POINTSCALE_B, FtoDW(0.00f));
m_pDevice->SetRenderState(D3DRS_POINTSCALE_C, FtoDW(1.00f));
}
else {
m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
}
}
else {
m_pDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_POINTSCALEENABLE, FALSE);
}
// update depending states
m_pVertexMan->InvalidateStates();
} // SetShadeMode
/*----------------------------------------------------------------*/
HRESULT ZFXD3D::SetTextureStage(UCHAR n, ZFXRENDERSTATE rs) {
D3DCAPS9 caps;
m_pDevice->GetDeviceCaps(&caps);
if (caps.MaxSimultaneousTextures < (n+1))
return ZFX_FAIL;
switch (rs) {
case RS_NONE:
m_TOP[n] = D3DTOP_DISABLE;
break;
case RS_TEX_ADDSIGNED:
m_TOP[n] = D3DTOP_ADDSIGNED;
break;
case RS_TEX_MODULATE:
m_TOP[n] = D3DTOP_MODULATE;
break;
default: break;
} // switch
return ZFX_OK;
} // SetTextureStage
/*----------------------------------------------------------------*/
HRESULT ZFXD3D::SetLight(const ZFXLIGHT *pLight, UCHAR nStage) {
D3DLIGHT9 d3dLight;
// switch it off
if (!pLight) {
m_pDevice->LightEnable(nStage, FALSE);
return ZFX_OK;
}
memset(&d3dLight, 0, sizeof(D3DLIGHT9));
switch (pLight->Type) {
case LGT_DIRECTIONAL:
// set light values
d3dLight.Type = D3DLIGHT_DIRECTIONAL;
// copy light direction
memcpy(&d3dLight.Direction,
&pLight->vcDirection,
sizeof(float)*3);
break;
case LGT_POINT:
// set light values
d3dLight.Type = D3DLIGHT_POINT;
d3dLight.Range = pLight->fRange;
d3dLight.Attenuation1 = 1.0f;
// copy light position
memcpy(&d3dLight.Position,
&pLight->vcPosition,
sizeof(float)*3);
break;
case LGT_SPOT:
// set light values
d3dLight.Type = D3DLIGHT_SPOT;
d3dLight.Range = pLight->fRange;
d3dLight.Falloff = 1.0f;
d3dLight.Theta = pLight->fTheta;
d3dLight.Phi = pLight->fPhi;
d3dLight.Attenuation0 = pLight->fAttenuation0;
d3dLight.Attenuation1 = pLight->fAttenuation1;
d3dLight.Attenuation2 = 1.0f;
// copy light position
memcpy(&d3dLight.Position,
&pLight->vcPosition,
sizeof(float)*3);
// copy light direction
memcpy(&d3dLight.Direction,
&pLight->vcDirection,
sizeof(float)*3);
break;
}
memcpy(&d3dLight.Ambient, &pLight->cAmbient,
sizeof(float)*4);
memcpy(&d3dLight.Diffuse, &pLight->cDiffuse,
sizeof(float)*4);
memcpy(&d3dLight.Specular, &pLight->cSpecular,
sizeof(float)*4);
m_pDevice->SetLight(nStage, &d3dLight);
m_pDevice->LightEnable(nStage, TRUE);
return ZFX_OK;
} // SetLight
/*----------------------------------------------------------------*/
// the user wants to render additive
void ZFXD3D::UseAdditiveBlending(bool b) {
if (m_bAdditive == b) return;
// clear all vertex caches
m_pVertexMan->ForcedFlushAll();
m_pVertexMan->InvalidateStates();
m_bAdditive = b;
if (!m_bAdditive) {
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
}
} // UseAdditiveBlending
/*----------------------------------------------------------------*/
// the user wants to render without textures
void ZFXD3D::UseTextures(bool b) {
if (m_bTextures == b) return;
// clear all vertex caches
m_pVertexMan->ForcedFlushAll();
m_pVertexMan->InvalidateStates();
m_bTextures = b;
} // UseAdditiveBlending
/*----------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -