📄 zfxd3d_vcache.cpp
字号:
/*******************************************************************
* ZFXEngine! *
* (c)2003 by Stefan Zerbst | www.zfx.info *
*-----------------------------------------------------------------*
* File: ZFXD3D_vcache.cpp *
* part of render dll implementing direct3d rendering *
*******************************************************************/
// I N C L U D E S /////////////////////////////////////////////////
#include "ZFXD3D_vcache.h" // class definition
#include "ZFXD3D.h" // FVF definitions
#include "ZFX.h" // return values and stuff
extern bool g_bLF;
// F U N C T I O N S ///////////////////////////////////////////////
/**
* Constructor: Initializes vertex cache arrays
*/
ZFXD3DVCManager::ZFXD3DVCManager(ZFXD3DSkinManager *pSkinMan,
LPDIRECT3DDEVICE9 pDevice,
ZFXD3D *pZFXD3D, UINT nMaxVerts,
UINT nMaxIndis, FILE *pLog) {
DWORD dwID=1;
int i=0;
m_pSB = NULL;
m_pIB = NULL;
m_nNumSB = 0;
m_nNumIB = 0;
m_pLog = pLog;
m_pDevice = pDevice;
m_pZFXD3D = pZFXD3D;
m_pSkinMan = pSkinMan;
m_dwActiveCache = MAX_ID;
m_dwActiveSB = MAX_ID;
m_dwActiveIB = MAX_ID;
for (i=0; i<NUM_CACHES; i++) {
m_CachePS[i] = new ZFXD3DVCache(nMaxVerts, nMaxIndis,
sizeof(PVERTEX),
pSkinMan, pDevice, this,
dwID++, FVF_PVERTEX, pLog);
m_CacheUU[i] = new ZFXD3DVCache(nMaxVerts, nMaxIndis,
sizeof(VERTEX),
pSkinMan, pDevice, this,
dwID++, FVF_VERTEX, pLog);
m_CacheUL[i] = new ZFXD3DVCache(nMaxVerts, nMaxIndis,
sizeof(LVERTEX),
pSkinMan, pDevice, this,
dwID++, FVF_LVERTEX, pLog);
m_CacheCA[i] = new ZFXD3DVCache(nMaxVerts, nMaxIndis,
sizeof(CVERTEX),
pSkinMan, pDevice, this,
dwID++, FVF_CVERTEX, pLog);
m_Cache3T[i] = new ZFXD3DVCache(nMaxVerts, nMaxIndis,
sizeof(VERTEX3T),
pSkinMan, pDevice, this,
dwID++, FVF_T3VERTEX, pLog);
m_CacheTV[i] = new ZFXD3DVCache(nMaxVerts, nMaxIndis,
sizeof(TVERTEX),
pSkinMan, pDevice, this,
dwID++, FVF_TVERTEX, pLog);
} // for
Log("online");
} // constructor
/*----------------------------------------------------------------*/
/**
* Destructor: Release vertex cache arrays
*/
ZFXD3DVCManager::~ZFXD3DVCManager(void) {
UINT n=0;
int i=0;
// release static buffers
if ( m_pSB ) {
for (n=0; n<m_nNumSB; n++) {
if (m_pSB[n].pVB) {
m_pSB[n].pVB->Release();
m_pSB[n].pVB = NULL;
}
if (m_pSB[n].pIB) {
m_pSB[n].pIB->Release();
m_pSB[n].pIB = NULL;
}
}
free( m_pSB );
m_pSB = NULL;
}
// release index buffers
for (n=0; n<m_nNumIB; n++) {
if (m_pIB[n].pIB) {
m_pIB[n].pIB->Release();
m_pIB[n].pIB = NULL;
}
}
// free memory for buffer lists
if (m_pIB) { free(m_pIB); m_pIB=NULL; }
// free dynamic vertex caches
for (i=0; i<NUM_CACHES; i++) {
if (m_CachePS[i]) {
delete m_CachePS[i];
m_CachePS[i] = NULL;
}
if (m_CacheUU[i]) {
delete m_CacheUU[i];
m_CacheUU[i] = NULL;
}
if (m_CacheCA[i]) {
delete m_CacheCA[i];
m_CacheCA[i] = NULL;
}
if (m_Cache3T[i]) {
delete m_Cache3T[i];
m_Cache3T[i] = NULL;
}
if (m_CacheTV[i]) {
delete m_CacheTV[i];
m_CacheTV[i] = NULL;
}
if (m_CacheUL[i]) {
delete m_CacheUL[i];
m_CacheUL[i] = NULL;
}
} // for
Log("offline (ok)");
} // destructor
/*----------------------------------------------------------------*/
ZFXRENDERSTATE ZFXD3DVCManager::GetShadeMode(void)
{ return m_pZFXD3D->GetShadeMode(); }
/**
* Create a static vertex/index buffer for the given data and returns
* a handle to that buffer for later rendering processes.
* -> IN: ZFXVERTEXID - identify the vertex format used
* UINT - skin that should be used
* UINT - number of vertices to come
* UINT - number of indices to come
* void - pointer to vertex stream
* void - pointer to index stream
* -> OUT: UINT - ID to the created buffer
*/
HRESULT ZFXD3DVCManager::CreateStaticBuffer(ZFXVERTEXID VertexID,
UINT nSkinID, UINT nVerts,
UINT nIndis, const void *pVerts,
const WORD *pIndis, UINT *pnID) {
HRESULT hr;
DWORD dwActualFVF;
void *pData;
if (m_nNumSB >= (MAX_ID-1)) return ZFX_OUTOFMEMORY;
// allocate memory for static buffers if needed
if ( (m_nNumSB % 50) == 0) {
int n = (m_nNumSB+50)*sizeof(ZFXSTATICBUFFER);
m_pSB = (ZFXSTATICBUFFER*)realloc(m_pSB, n);
if (!m_pSB) return ZFX_OUTOFMEMORY;
}
m_pSB[m_nNumSB].nNumVerts = nVerts;
m_pSB[m_nNumSB].nNumIndis = nIndis;
m_pSB[m_nNumSB].nSkinID = nSkinID;
m_pSB[m_nNumSB].pIB = NULL;
m_pSB[m_nNumSB].pVB = NULL;
// get size and format of vertex
switch (VertexID) {
case VID_PS: {
m_pSB[m_nNumSB].nStride = sizeof(PVERTEX);
m_pSB[m_nNumSB].dwFVF = FVF_PVERTEX;
} break;
case VID_UU: {
m_pSB[m_nNumSB].nStride = sizeof(VERTEX);
m_pSB[m_nNumSB].dwFVF = FVF_VERTEX;
} break;
case VID_UL: {
m_pSB[m_nNumSB].nStride = sizeof(LVERTEX);
m_pSB[m_nNumSB].dwFVF = FVF_LVERTEX;
} break;
case VID_CA: {
m_pSB[m_nNumSB].nStride = sizeof(CVERTEX);
m_pSB[m_nNumSB].dwFVF = FVF_CVERTEX;
} break;
case VID_3T: {
m_pSB[m_nNumSB].nStride = sizeof(VERTEX3T);
m_pSB[m_nNumSB].dwFVF = FVF_T3VERTEX;
} break;
case VID_TV: {
m_pSB[m_nNumSB].nStride = sizeof(TVERTEX);
m_pSB[m_nNumSB].dwFVF = FVF_TVERTEX;
} break;
default: return ZFX_INVALIDID;
} // switch
// create indexbuffer if needed
if (nIndis > 0) {
m_pSB[m_nNumSB].bIndis = true;
m_pSB[m_nNumSB].nNumTris = int(nIndis / 3.0f);
hr = m_pDevice->CreateIndexBuffer(
nIndis * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT,
&m_pSB[m_nNumSB].pIB,
NULL);
if (FAILED(hr)) return ZFX_CREATEBUFFER;
// fill the index buffer
if (SUCCEEDED(m_pSB[m_nNumSB].pIB->Lock(
0, 0, (void**)
(&pData), 0))) {
memcpy(pData, pIndis, nIndis*sizeof(WORD));
m_pSB[m_nNumSB].pIB->Unlock();
}
else return ZFX_BUFFERLOCK;
}
else {
m_pSB[m_nNumSB].bIndis = false;
m_pSB[m_nNumSB].nNumTris = int(nVerts / 3.0f);
m_pSB[m_nNumSB].pIB = NULL;
}
// no need for FVF if shaders are used
if (m_pZFXD3D->UsesShaders()) dwActualFVF = 0;
else dwActualFVF = m_pSB[m_nNumSB].dwFVF;
// create vertex buffer
hr = m_pDevice->CreateVertexBuffer(
nVerts*m_pSB[m_nNumSB].nStride,
D3DUSAGE_WRITEONLY,
dwActualFVF,
D3DPOOL_DEFAULT,
&m_pSB[m_nNumSB].pVB,
NULL);
if (FAILED(hr)) return ZFX_CREATEBUFFER;
// fill the vertex buffer
if (SUCCEEDED(m_pSB[m_nNumSB].pVB->Lock(
0, 0, (void**)
(&pData), 0))) {
memcpy(pData, pVerts, nVerts*m_pSB[m_nNumSB].nStride);
m_pSB[m_nNumSB].pVB->Unlock();
}
else return ZFX_BUFFERLOCK;
(*pnID) = m_nNumSB;
m_nNumSB++;
return ZFX_OK;
} // CreateStaticBuffer
/*----------------------------------------------------------------*/
/**
* Create a static index buffer for the given data and returns a
* handle to that buffer for later rendering processes.
* -> IN: UINT - number of indices to come
* WORD - pointer to index stream
* -> OUT: UINT - ID to the created buffer
*/
HRESULT ZFXD3DVCManager::CreateIndexBuffer(UINT nIndis,
const WORD *pIndis,
UINT *pnID) {
HRESULT hr;
void *pData;
if (m_nNumIB >= (MAX_ID-1)) return ZFX_OUTOFMEMORY;
// allocate memory for static buffers if needed
if ( (m_nNumIB % 50) == 0) {
int n = (m_nNumIB+50)*sizeof(ZFXINDEXBUFFER);
m_pIB = (ZFXINDEXBUFFER*)realloc(m_pIB, n);
if (!m_pIB) return ZFX_OUTOFMEMORY;
}
m_pIB[m_nNumIB].nNumIndis = nIndis;
m_pIB[m_nNumIB].nNumTris = int(nIndis / 3.0f);
m_pIB[m_nNumIB].pIB = NULL;
hr = m_pDevice->CreateIndexBuffer(
nIndis * sizeof(WORD),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT,
&m_pIB[m_nNumIB].pIB,
NULL);
if (FAILED(hr)) return ZFX_CREATEBUFFER;
// fill the index buffer
if (SUCCEEDED(m_pIB[m_nNumIB].pIB->Lock(
0, 0, (void**)
(&pData), 0))) {
memcpy(pData, pIndis, nIndis*sizeof(WORD));
m_pIB[m_nNumIB].pIB->Unlock();
}
else return ZFX_BUFFERLOCK;
(*pnID) = m_nNumIB;
m_nNumIB++;
return ZFX_OK;
} // CreateIndexBuffer
/*----------------------------------------------------------------*/
/**
* Flush all vertex caches no matter which vertex format.
*/
HRESULT ZFXD3DVCManager::ForcedFlushAll(void) {
HRESULT hr = ZFX_OK;
bool bShaders = m_pZFXD3D->UsesShaders();
int i;
for (i=0; i<NUM_CACHES; i++)
if (!m_CachePS[i]->IsEmpty() )
if (FAILED( m_CachePS[i]->Flush(bShaders) ))
hr = ZFX_FAIL;
for (i=0; i<NUM_CACHES; i++)
if (!m_CacheUU[i]->IsEmpty() )
if (FAILED( m_CacheUU[i]->Flush(bShaders) ))
hr = ZFX_FAIL;
for (i=0; i<NUM_CACHES; i++)
if (!m_CacheUL[i]->IsEmpty() )
if (FAILED( m_CacheUL[i]->Flush(bShaders) ))
hr = ZFX_FAIL;
for (i=0; i<NUM_CACHES; i++)
if (!m_CacheCA[i]->IsEmpty() )
if (FAILED( m_CacheCA[i]->Flush(bShaders) ))
hr = ZFX_FAIL;
for (i=0; i<NUM_CACHES; i++)
if (!m_Cache3T[i]->IsEmpty() )
if (FAILED( m_Cache3T[i]->Flush(bShaders) ))
hr = ZFX_FAIL;
for (i=0; i<NUM_CACHES; i++)
if (!m_CacheTV[i]->IsEmpty() )
if (FAILED( m_CacheTV[i]->Flush(bShaders) ))
hr = ZFX_FAIL;
return hr;
} // ForcedFlushAll
/*----------------------------------------------------------------*/
/**
* Flush all buffers. Call this function if you want to force all
* contents send to render device to be drawn in backbuffer. This
* will automaticly be done when calling EndScene() for RenderDevice.
* -> IN: ZFXVERTEXID - ID for vertex type
*/
HRESULT ZFXD3DVCManager::ForcedFlush(ZFXVERTEXID VertexID) {
ZFXD3DVCache **pCache=NULL;
HRESULT hr = ZFX_OK;
int i=0;
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;
// unknown vertex type
default: return ZFX_INVALIDID;
} // switch
for (i=0; i<NUM_CACHES; i++)
if (FAILED( pCache[i]->Flush(m_pZFXD3D->UsesShaders()) ))
hr = ZFX_FAIL;
return hr;
} // ForcedFlush
/*----------------------------------------------------------------*/
/**
* Render static buffers with the given skin. Indexbuffer is optional.
* -> IN: UINT - index of static vertexbuffer to use
*/
HRESULT ZFXD3DVCManager::Render(UINT nID) {
HRESULT hr=ZFX_OK;
int iT=0;
ZFXRENDERSTATE sm = m_pZFXD3D->GetShadeMode();
// active cache gets invalid
m_dwActiveCache = MAX_ID;
if (nID >= m_nNumSB) {
Log("error: invalid static buffer ID");
return ZFX_INVALIDPARAM;
}
// activate buffers if not already active
if (m_dwActiveSB != nID) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -