📄 zfxd3d_vcache.cpp
字号:
pVerts[0].y = fStart[1];
pVerts[0].z = fStart[2];
pVerts[1].x = fEnd[0];
pVerts[1].y = fEnd[1];
pVerts[1].z = fEnd[2];
// set prelit
pVerts[0].Color = pVerts[1].Color = D3DCOLOR_COLORVALUE(
pClr->fR, pClr->fG,
pClr->fB, pClr->fA);
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->SetFVF(FVF_LVERTEX);
m_pDevice->SetVertexShader(NULL);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
// render list of lines
if (FAILED(m_pDevice->DrawPrimitiveUP(D3DPT_LINELIST, 1,
pVerts, sizeof(LVERTEX)))) {
m_pDevice->SetFVF(NULL);
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
return ZFX_FAIL;
}
m_pDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
m_pDevice->SetFVF(NULL);
return ZFX_OK;
} // RenderLine
/*----------------------------------------------------------------*/
/**
* write outputstring to attribut outputstream if exists
* -> IN: bool - flush immediately
* ... - output values
*/
void ZFXD3DVCManager::Log(char *chString, ...) {
char ch[256];
char *pArgs;
pArgs = (char*) &chString + sizeof(chString);
vsprintf(ch, chString, pArgs);
fprintf(m_pLog, "[ZFXD3DVCMngr]: ");
fprintf(m_pLog, ch);
fprintf(m_pLog, "\n");
if (g_bLF)
fflush(m_pLog);
} // Log
/*----------------------------------------------------------------*/
// F U N C T I O N S ///////////////////////////////////////////////
/**
* Constructor: Initialize members, especially vertex- and index-buffer.
* -> IN: UINT - max number of vertices in cache
* UINT - max number of indices in cache
* UINT - size of one vertex element
* SKINMAN - pointer to initialized skin manager
* D3DDEVICE - pointer to initialized d3d device
*/
ZFXD3DVCache::ZFXD3DVCache(UINT nVertsMax, UINT nIndisMax,
UINT nStride, ZFXD3DSkinManager *pSkinMan,
LPDIRECT3DDEVICE9 pDevice, ZFXD3DVCManager *pDad,
DWORD dwID, DWORD dwFVF, FILE *pLog) {
HRESULT hr;
m_pDevice = pDevice;
m_pSkinMan = pSkinMan;
m_pDad = pDad;
m_nNumVertsMax = nVertsMax;
m_nNumIndisMax = nIndisMax;
m_nNumVerts = 0;
m_nNumIndis = 0;
m_dwID = dwID;
m_dwFVF = dwFVF;
m_nStride = nStride;
m_pLog = pLog;
memset(&m_Skin, MAX_ID, sizeof(ZFXSKIN));
m_SkinID = MAX_ID;
// create the buffers
m_pVB = NULL;
m_pIB = NULL;
hr = pDevice->CreateVertexBuffer(nVertsMax * nStride,
D3DUSAGE_DYNAMIC |
D3DUSAGE_WRITEONLY,
0, D3DPOOL_DEFAULT,
&m_pVB, NULL);
if (FAILED(hr)) m_pVB = NULL;
hr = pDevice->CreateIndexBuffer(nIndisMax * sizeof(WORD),
D3DUSAGE_DYNAMIC |
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT, &m_pIB, NULL);
if (FAILED(hr)) m_pIB = NULL;
} // constructor
/*----------------------------------------------------------------*/
/**
* Destructor: Just release all of the stuff.
*/
ZFXD3DVCache::~ZFXD3DVCache(void) {
if (m_pVB) {
m_pVB->Release();
m_pVB = NULL;
}
if (m_pIB) {
m_pIB->Release();
m_pIB = NULL;
}
} // destructor
/*----------------------------------------------------------------*/
/**
* Set the given texture for the given stage.
* -> IN: ZFXSKIN - textures and material used by this polys
*/
void ZFXD3DVCache::SetSkin(UINT SkinID, bool bUseShaders) {
// if a new texture is coming, flush all content of
// the cache because that is using other textures
if (!UsesSkin(SkinID)) {
ZFXSKIN *pSkin = &m_pSkinMan->GetSkin(SkinID);
if (!IsEmpty()) Flush(bUseShaders);
memcpy(&m_Skin, pSkin, sizeof(ZFXSKIN));
m_SkinID = SkinID;
// skin changing so active cache is invalid any case
m_pDad->InvalidateStates();
}
} // SetSkin
/*----------------------------------------------------------------*/
/**
* Send the content of the cache to the renderer and resets the
* cache to accept new content.
*/
HRESULT ZFXD3DVCache::Flush(bool bUseShaders) {
HRESULT hr=ZFX_FAIL;
int iT=0;
// anything to do at all?
if (m_nNumVerts <= 0) return ZFX_OK;
// are the caches buffers still active?
if ( m_pDad->GetActiveCache() != m_dwID) {
// if using shaders they should be activated by the
// ActivateVShader methods. Else set FVF
if (!bUseShaders) m_pDevice->SetFVF(m_dwFVF);
m_pDevice->SetIndices(m_pIB);
m_pDevice->SetStreamSource(0, m_pVB, 0, m_nStride);
m_pDad->SetActiveCache(m_dwID);
} // [device->cache]
// is the device already using this skin?
if (m_pDad->GetZFXD3D()->GetActiveSkinID() != m_SkinID) {
// set material for device
LPDIRECT3DTEXTURE9 pTex=NULL;
ZFXMATERIAL *pMat = &m_pSkinMan->m_pMaterials[m_Skin.nMaterial];
// WIREFRAME MODE NEEDS A SPECIAL CASE
if (m_pDad->GetZFXD3D()->GetShadeMode() == RS_SHADE_SOLID) {
if (!m_pDad->GetZFXD3D()->UsesShaders()) {
D3DMATERIAL9 mat = {
pMat->cDiffuse.fR, pMat->cDiffuse.fG, pMat->cDiffuse.fB, pMat->cDiffuse.fA,
pMat->cAmbient.fR, pMat->cAmbient.fG, pMat->cAmbient.fB, pMat->cAmbient.fA,
pMat->cSpecular.fR, pMat->cSpecular.fG, pMat->cSpecular.fB, pMat->cSpecular.fA,
pMat->cEmissive.fR, pMat->cEmissive.fG, pMat->cEmissive.fB, pMat->cEmissive.fA,
pMat->fPower };
m_pDevice->SetMaterial(&mat);
}
else {
m_pDad->GetZFXD3D()->SetShaderConstant(SHT_PIXEL, DAT_FLOAT, 1, 1, &pMat->cAmbient);
m_pDad->GetZFXD3D()->SetShaderConstant(SHT_PIXEL, DAT_FLOAT, 2, 1, &pMat->cDiffuse);
m_pDad->GetZFXD3D()->SetShaderConstant(SHT_PIXEL, DAT_FLOAT, 3, 1, &pMat->cEmissive);
m_pDad->GetZFXD3D()->SetShaderConstant(SHT_PIXEL, DAT_FLOAT, 4, 1, &pMat->cSpecular);
}
if ( m_pDad->GetZFXD3D()->UsesTextures() ) {
// set texture for device
for (iT=0; iT<8; iT++) {
if (m_Skin.nTexture[iT] != MAX_ID) {
pTex = (LPDIRECT3DTEXTURE9)m_pSkinMan->m_pTextures[
m_Skin.nTexture[iT]].pData;
if (FAILED(m_pDevice->SetTexture(iT, pTex)))
Log("error: SetTexture() in VC::Flush() failed");
// set texture operations
m_pDevice->SetTextureStageState(iT, D3DTSS_TEXCOORDINDEX, 0);
m_pDevice->SetTextureStageState(iT, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(iT, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pDevice->SetTextureStageState(iT, D3DTSS_COLOROP,
m_pDad->GetZFXD3D()->GetTOP(iT));
}
else break;
} // for
// 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_pDad->GetZFXD3D()->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 (m_Skin.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);
}
// now its active
m_pDad->GetZFXD3D()->SetActiveSkinID(m_SkinID);
} // [device->skin]
// should we use additive rendering?
if (m_pDad->GetZFXD3D()->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_pDad->GetZFXD3D()->UsesColorBuffer()) {
m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
}
ZFXRENDERSTATE sm = m_pDad->GetZFXD3D()->GetShadeMode();
// render content
if ( sm == RS_SHADE_POINTS ) {
hr = m_pDevice->DrawPrimitive(
D3DPT_POINTLIST,
0, m_nNumVerts);
}
else if ( sm == RS_SHADE_LINES ) {
hr = m_pDevice->DrawIndexedPrimitive(
D3DPT_LINELIST,
0, 0, m_nNumVerts,
0, m_nNumIndis/2);
}
else if ( sm == RS_SHADE_HULLWIRE ) {
hr = m_pDevice->DrawIndexedPrimitive(
D3DPT_LINESTRIP,
0, 0, m_nNumVerts,
0, m_nNumVerts);
}
else { // RS_SHADE_SOLID || RS_SHADE_TRIWIRE
hr = m_pDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,
0, 0, m_nNumVerts,
0, m_nNumIndis/3);
}
if (FAILED(hr)) {
Log("error: IDirect3DDevice::DrawIndexedPrimitive failed");
return ZFX_FAIL;
}
// reset counters
m_nNumVerts = 0;
m_nNumIndis = 0;
return ZFX_OK;
} // Flush
/*----------------------------------------------------------------*/
/**
* Fill data into the cache. If the cache is full it will be flushed
* prior to accept new data. If no Indexlist is used set indexlist
* parameter to NULL.
* -> IN: UINT - number of vertices in list
* UINT - number of indices in list
* void* - pointer to vertex list
* WORD* - pointer to index list
*/
HRESULT ZFXD3DVCache::Add(UINT nVerts, UINT nIndis,
const void *pVerts,
const WORD *pIndices,
bool bUseShaders) {
BYTE *tmp_pVerts=NULL; // pointer to VB memory
WORD *tmp_pIndis=NULL; // pointer to IB memory
int nSizeV = m_nStride*nVerts;
int nSizeI = sizeof(WORD)*nIndis;
int nPosV;
int nPosI;
DWORD dwFlags;
// lists will never fit into this cache
if (nVerts>m_nNumVertsMax || nIndis>m_nNumIndisMax)
return ZFX_BUFFERSIZE;
// cache is already full, so flush it
if ( (nVerts+m_nNumVerts > m_nNumVertsMax) ||
(nIndis+m_nNumIndis > m_nNumIndisMax) ) {
if ( Flush(bUseShaders) != ZFX_OK) {
Log("error: Flush()");
return ZFX_FAIL;
}
}
// if nothing is in buffer discard content
if (m_nNumVerts == 0) {
nPosV = nPosI = 0;
dwFlags = D3DLOCK_DISCARD;
}
// else just append data without overwrites
else {
nPosV = m_nStride*m_nNumVerts;
nPosI = sizeof(WORD)*m_nNumIndis;
dwFlags = D3DLOCK_NOOVERWRITE;
}
// now lock buffers
if (FAILED(m_pVB->Lock(nPosV, nSizeV, (void**)&tmp_pVerts, dwFlags)))
return ZFX_BUFFERLOCK;
if (FAILED(m_pIB->Lock(nPosI, nSizeI, (void**)&tmp_pIndis, dwFlags))) {
m_pVB->Unlock();
return ZFX_BUFFERLOCK;
}
// copy vertex data into the buffer
memcpy(tmp_pVerts, pVerts, nSizeV);
// copy indices into the buffer
int nBase = m_nNumVerts;
if (!pIndices) nIndis = nVerts;
for (UINT i=0; i<nIndis; i++) {
if (pIndices != NULL)
tmp_pIndis[i] = pIndices[i] + nBase;
else
tmp_pIndis[i] = i + nBase;
m_nNumIndis++;
}
// add to count
m_nNumVerts += nVerts;
// unlock buffers
m_pVB->Unlock();
m_pIB->Unlock();
return ZFX_OK;
} // Add
/*----------------------------------------------------------------*/
/**
* write outputstring to attribut outputstream if exists
* -> IN: bool - flush immediately
* char - format string to output
* ... - output values
*/
void ZFXD3DVCache::Log(char *chString, ...) {
char ch[256];
char *pArgs;
pArgs = (char*) &chString + sizeof(chString);
vsprintf(ch, chString, pArgs);
fprintf(m_pLog, "[ZFXD3DVCache]: ");
fprintf(m_pLog, ch);
fprintf(m_pLog, "\n");
if (g_bLF)
fflush(m_pLog);
} // Log
/*----------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -