📄 zfxd3d_vcache.cpp
字号:
}
else break;
}
// deactivate unused stages at all costs
m_pDevice->SetTextureStageState(iT, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
else {
m_pDevice->SetTexture(0, NULL);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
}
else {
ZFXCOLOR clrWire = m_pZFXD3D->GetWireColor();
// set material
D3DMATERIAL9 matW = {
clrWire.fR, clrWire.fG, clrWire.fB, clrWire.fA,
clrWire.fR, clrWire.fG, clrWire.fB, clrWire.fA,
0.0f, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f,
1.0f };
m_pDevice->SetMaterial(&matW);
// set no texture for device
m_pDevice->SetTexture(0, NULL);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
}
// set alpha states for device
if (pSkin->bAlpha) {
m_pDevice->SetRenderState(D3DRS_ALPHAREF, 50);
m_pDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
}
else {
m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
}
// skin will change now
m_pZFXD3D->SetActiveSkinID(SkinID);
} // [device->skin]
// if using shaders they should be activated by the
// ActivateVShader methods. Else set FVF
if (!m_pZFXD3D->UsesShaders())
m_pDevice->SetFVF(m_pSB[nID].dwFVF);
// this method is for indexed primitives only
if (!m_pSB[nID].bIndis) return ZFX_FAIL;
// should we use additive rendering?
if (m_pZFXD3D->UsesAdditiveBlending()) {
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}
// should we use rendering to color buffer at all?
if (!m_pZFXD3D->UsesColorBuffer()) {
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}
// render content
// STATES OTHER THAT FINAL ELSE NOT EVALUATED /////////////
if ( sm == RS_SHADE_POINTS ) {
hr = m_pDevice->DrawPrimitive(
D3DPT_POINTLIST, 0,
NumVerts);
}
else if ( sm == RS_SHADE_LINES ) {
hr = m_pDevice->DrawIndexedPrimitive(
D3DPT_LINELIST, 0,
0, NumVerts,
StartIndex, NumTris);
}
else if ( sm == RS_SHADE_HULLWIRE ) {
hr = m_pDevice->DrawIndexedPrimitive(
D3DPT_LINESTRIP, 0,
0, NumVerts,
StartIndex, NumTris);
}
else { // RS_SHADE_SOLID || RS_SHADE_TRIWIRE
hr = m_pDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST, 0,
0, NumVerts,
StartIndex, NumTris);
}
return hr;
} // Render
/*----------------------------------------------------------------*/
/**
* Takes the vertex and index lists and sorts them into one fitting
* vertex cache that features the same vertexID. If none of those
* caches is free one will be flushed out. Note that output of pixel
* to any buffers is not immediately. Call ForcedFlush() if needed.
* -> IN: ZFXVERTEXID - vertex type to be processed
* UINT - number of vertices in this call
* UINT - number of indices in this call
* void - array of vertices
* WORD - array of indices
* ZFXSKIN - pointer to the skin used for those vertices
*/
HRESULT ZFXD3DVCManager::Render(ZFXVERTEXID VertexID,
UINT nVerts,
UINT nIndis,
const void *pVerts,
const WORD *pIndis,
UINT SkinID) {
ZFXD3DVCache **pCache=NULL,
*pCacheEmpty=NULL,
*pCacheFullest=NULL;
int nEmptyVC = -1;
int nFullestVC = 0;
bool bShaders = m_pZFXD3D->UsesShaders();
// which vertex type is to be processed?
switch (VertexID) {
case VID_PS: { pCache = m_CachePS; } break;
case VID_UU: { pCache = m_CacheUU; } break;
case VID_UL: { pCache = m_CacheUL; } break;
case VID_CA: { pCache = m_CacheCA; } break;
case VID_3T: { pCache = m_Cache3T; } break;
case VID_TV: { pCache = m_CacheTV; } break;
default: return ZFX_INVALIDID;
} // switch
pCacheFullest = pCache[0];
// active buffer might change now
m_dwActiveSB = MAX_ID;
/*
// for wireframe sorting is not needed
if ( GetShadeMode() != RS_SHADE_SOLID) {
return pCache[0]->Add(nVerts, nIndis, pVerts,
pIndis, bShaders);
}
*/
// SEARCH BEST FITTING CACHE FOR THE VERTICES
// first check if any cache uses same skin. that is the
// easiest option cause we can just add the verts then.
for (int i=0; i<NUM_CACHES; i++) {
if (pCache[i]->UsesSkin(SkinID))
return pCache[i]->Add(nVerts, nIndis, pVerts,
pIndis, bShaders);
if (pCache[i]->IsEmpty())
pCacheEmpty = pCache[i];
if (pCache[i]->NumVerts() > pCacheFullest->NumVerts())
pCacheFullest = pCache[i];
}
// no luck though. second option is to add vertices to
// a flushed empty cache if any one is available.
if (pCacheEmpty) {
pCacheEmpty->SetSkin(SkinID, bShaders);
return pCacheEmpty->Add(nVerts, nIndis, pVerts,
pIndis, bShaders);
}
// still no luck with that one. final option is to force
// one cache to flush itself so we get an empty cache. We
// simply choose the fullest cache here to avoid render
// calls with just a few verts.
pCacheFullest->Flush(bShaders);
pCacheFullest->SetSkin(SkinID, bShaders);
return pCacheFullest->Add(nVerts, nIndis, pVerts,
pIndis, bShaders);
} // Render
/*----------------------------------------------------------------*/
/**
* Render without texture using VID_UU and no shaders
*/
HRESULT ZFXD3DVCManager::RenderNaked(UINT nNumV, const void *pVerts, bool b) {
HRESULT hr=ZFX_OK;
InvalidateStates();
m_pZFXD3D->UseShaders(false);
m_pDevice->SetTexture(0, NULL);
if (b)
m_pDevice->SetTexture(0, (LPDIRECT3DTEXTURE9)
m_pSkinMan->m_pTextures[2].pData);
else
m_pDevice->SetTexture(0, NULL);
m_pDevice->SetFVF(FVF_PVERTEX);
hr = m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST,
nNumV/3,
pVerts,
sizeof(PVERTEX));
return hr;
} // Render
/*----------------------------------------------------------------*/
/**
* Set all states to invalid to force reset at next rendering.
*/
void ZFXD3DVCManager::InvalidateStates(void) {
m_pZFXD3D->SetActiveSkinID(MAX_ID);
m_dwActiveSB = MAX_ID;
m_dwActiveCache = MAX_ID;
} // InvalidateStates
/*----------------------------------------------------------------*/
/**
* Use normal Vertex Type here. Render a list of points.
*/
HRESULT ZFXD3DVCManager::RenderPoints(ZFXVERTEXID VID,
UINT nVerts,
const void *pVerts,
const ZFXCOLOR *pClr) {
D3DMATERIAL9 mtrl;
DWORD dwFVF;
int nStride;
// active skin and static buffer gets invalid
InvalidateStates();
if (pClr) {
memset(&mtrl, 0, sizeof(D3DMATERIAL9));
mtrl.Diffuse.r = mtrl.Ambient.r = pClr->fR;
mtrl.Diffuse.g = mtrl.Ambient.g = pClr->fG;
mtrl.Diffuse.b = mtrl.Ambient.b = pClr->fB;
mtrl.Diffuse.a = mtrl.Ambient.a = pClr->fA;
m_pDevice->SetMaterial(&mtrl);
}
m_pDevice->SetTexture(0,NULL);
// which vertex type is to be processed?
switch (VID) {
case VID_PS: {
nStride = sizeof(PVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
dwFVF = FVF_PVERTEX;
} break;
case VID_UU: {
nStride = sizeof(VERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_VERTEX;
} break;
case VID_3T: {
nStride = sizeof(VERTEX3T);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_T3VERTEX;
} break;
case VID_TV: {
nStride = sizeof(TVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_TVERTEX;
} break;
case VID_CA: {
nStride = sizeof(CVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_CVERTEX;
} break;
case VID_UL: {
nStride = sizeof(LVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
dwFVF = FVF_LVERTEX;
} break;
default: return ZFX_INVALIDID;
} // switch
// shaders or FVF
if ( m_pZFXD3D->UsesShaders() ) {
m_pZFXD3D->ActivateVShader(0, VID);
m_pZFXD3D->ActivatePShader(0);
}
else m_pDevice->SetFVF(dwFVF);
// render list of points
if (FAILED(m_pDevice->DrawPrimitiveUP(D3DPT_POINTLIST, nVerts,
pVerts, nStride))) {
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
return ZFX_FAIL;
}
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
return ZFX_OK;
} // RenderPoints
/*----------------------------------------------------------------*/
/**
* Use normal Vertex Type here. Render a list of lines.
*/
HRESULT ZFXD3DVCManager::RenderLines(ZFXVERTEXID VID,
UINT nVerts,
const void *pVerts,
const ZFXCOLOR *pClr,
bool bStrip) {
D3DMATERIAL9 mtrl;
DWORD dwFVF;
int nStride;
// we will change states
ForcedFlushAll();
// active skin and static buffer gets invalid
InvalidateStates();
if (pClr) {
memset(&mtrl, 0, sizeof(D3DMATERIAL9));
mtrl.Diffuse.r = mtrl.Ambient.r = pClr->fR;
mtrl.Diffuse.g = mtrl.Ambient.g = pClr->fG;
mtrl.Diffuse.b = mtrl.Ambient.b = pClr->fB;
mtrl.Diffuse.a = mtrl.Ambient.a = pClr->fA;
m_pDevice->SetMaterial(&mtrl);
}
m_pDevice->SetTexture(0, NULL);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
// which vertex type is to be processed?
switch (VID) {
case VID_PS: {
nStride = sizeof(PVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
dwFVF = FVF_PVERTEX;
} break;
case VID_UU: {
nStride = sizeof(VERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_VERTEX;
} break;
case VID_3T: {
nStride = sizeof(VERTEX3T);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_T3VERTEX;
} break;
case VID_TV: {
nStride = sizeof(TVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_TVERTEX;
} break;
case VID_CA: {
nStride = sizeof(CVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
dwFVF = FVF_CVERTEX;
} break;
case VID_UL: {
nStride = sizeof(LVERTEX);
m_pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
dwFVF = FVF_LVERTEX;
} break;
default: return ZFX_INVALIDID;
} // switch
// shaders or FVF
if ( m_pZFXD3D->UsesShaders() ) {
m_pZFXD3D->ActivateVShader(0, VID);
m_pZFXD3D->ActivatePShader(0);
}
else m_pDevice->SetFVF(dwFVF);
// render list of lines
if (!bStrip) {
if (FAILED(m_pDevice->DrawPrimitiveUP(D3DPT_LINELIST, nVerts/2,
pVerts, nStride))) {
m_pDevice->SetRenderState(D3DRS_LIGHTING , TRUE);
return ZFX_FAIL;
}
}
else {
if (FAILED(m_pDevice->DrawPrimitiveUP(D3DPT_LINESTRIP, nVerts-1,
pVerts, nStride))) {
m_pDevice->SetRenderState(D3DRS_LIGHTING , TRUE);
return ZFX_FAIL;
}
}
m_pDevice->SetRenderState(D3DRS_LIGHTING , TRUE);
return ZFX_OK;
} // RenderLines
/*----------------------------------------------------------------*/
/**
* Use normal Vertex Type here. Render one line.
*/
HRESULT ZFXD3DVCManager::RenderLine(const float *fStart,
const float *fEnd,
const ZFXCOLOR *pClr) {
D3DMATERIAL9 mtrl;
LVERTEX pVerts[2];
if (!pClr) return ZFX_INVALIDPARAM;
// we will change states
ForcedFlushAll();
// active skin and static buffer gets invalid
InvalidateStates();
// make sure state is switched off
GetZFXD3D()->UseShaders(false);
// set coordinates
pVerts[0].x = fStart[0];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -