📄 clfragmentvector.cpp
字号:
int iDepth = reduceAddInternal();
combineLastPointsGeneral(iDepth,pSurface,0);
float result = evalLastPoint(pSurface);
ms_memoryMananger->releaseTextureTarget(m_ID[0]);
ms_memoryMananger->releaseTextureTarget(m_ID[1]);
ms_memoryMananger->releaseTextureTarget(iMiniTexID);
return result;
}
/*******************************************************************************************
Name: reduceAdd
Purpose: return sum(this*clvSecond)
********************************************************************************************/
float clFragmentVector::reduceAdd(clFragmentVector* clvSecond) {
LPDIRECT3DSURFACE9 pSurface;
PDIRECT3DTEXTURE9 pTexture;
int iMiniTexID = ms_memoryMananger->getTextureTarget(clMemDescr(1,1,m_memDesc.m_d3dFormat,D3DUSAGE_RENDERTARGET),pTexture,pSurface);
m_ID[0] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[0],m_pTempTextureSurface[0]);
m_ID[1] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[1],m_pTempTextureSurface[1]);
ms_pShaderClVector->SetTexture(ms_tVector, m_pVectorTexture);
ms_pShaderClVector->SetTexture(ms_tVector2, clvSecond->m_pVectorTexture);
ms_pShaderClVector->SetTechnique(ms_tReduceAddFirst);
int iDepth = reduceAddInternal();
combineLastPointsGeneral(iDepth,pSurface,0);
float result = evalLastPoint(pSurface);
ms_memoryMananger->releaseTextureTarget(m_ID[0]);
ms_memoryMananger->releaseTextureTarget(m_ID[1]);
ms_memoryMananger->releaseTextureTarget(iMiniTexID);
return result;
}
/*******************************************************************************************
Name: splitQuadX
Purpose: reduce a quad to half of it's size in x-dimension
********************************************************************************************/
void clFragmentVector::splitQuadX(CL_TEX2D_VERTEX *hQuad) {
hQuad[1].x = (hQuad[1].x+1.0f)/2.0f-1.0f;
hQuad[3].x = (hQuad[3].x+1.0f)/2.0f-1.0f;
hQuad[1].tu /= 2.0;
hQuad[3].tu /= 2.0;
}
/*******************************************************************************************
Name: splitQuadY
Purpose: reduce a quad to half of it's size in y-dimension
********************************************************************************************/
void clFragmentVector::splitQuadY(CL_TEX2D_VERTEX *hQuad) {
hQuad[2].y = (hQuad[2].y-1.0f)/2.0f+1.0f;
hQuad[3].y = (hQuad[3].y-1.0f)/2.0f+1.0f;
hQuad[2].tv /= 2.0;
hQuad[3].tv /= 2.0;
}
/*******************************************************************************************
Name: splitQuad
Purpose: reduce a quad to half of it's size in both dimensions
********************************************************************************************/
void clFragmentVector::splitQuad(CL_TEX2D_VERTEX *hQuad) {
splitQuadX(hQuad);
splitQuadY(hQuad);
}
/*******************************************************************************************
Name: reduceAddInternal
Purpose: called by the reduceAdd methods
********************************************************************************************/
int clFragmentVector::reduceAddInternal() {
int iDepth = 1;
// a quad covering the entire viewport
CL_TEX2D_VERTEX hQuad[4]; memcpy(hQuad,ms_hCoverQuad,sizeof(CL_TEX2D_VERTEX)*4);
m_pd3dDevice->SetFVF( CL_TEX2D_VERTEX_FVF );
while (iDepth*2 < m_memDesc.m_iWidth && iDepth*2 < m_memDesc.m_iHeight) {
splitQuad(hQuad);
m_pd3dDevice->SetRenderTarget(0, m_pTempTextureSurface[m_iTempActive]);
ms_pShaderClVector->SetFloat(ms_fReduceStep, 1.0f/(iDepth*2.0f));
UINT cPasses;
ms_pShaderClVector->Begin(&cPasses, 0);
ms_pShaderClVector->BeginPass(0);
m_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, hQuad, sizeof( CL_TEX2D_VERTEX ) );
ms_pShaderClVector->EndPass();
ms_pShaderClVector->End();
iDepth *= 2;
ms_pShaderClVector->SetTexture(ms_tLastPass, m_pTempTexture[m_iTempActive]);
m_iTempActive = 1-m_iTempActive; // swap temp-surface
if (iDepth == 2) ms_pShaderClVector->SetTechnique(ms_tReduceAddRest);
}
// further reduce non-quadratic vectors
if (m_memDesc.m_iWidth != m_memDesc.m_iHeight) {
reduceInXDirection(iDepth,hQuad); // try to reduce in x-direction
reduceInYDirection(iDepth,hQuad); // try to reduce in y-direction
}
m_pd3dDevice->SetRenderTarget(0,m_lpBackBuffer);
return iDepth;
}
/*******************************************************************************************
Name: multiplyScalar
Purpose: multiply this vector with a scalar (this = this*fScalar)
********************************************************************************************/
void clFragmentVector::multiplyScalar(float fScalar){
BeginScene();
ms_pShaderClVector->SetFloat(ms_fMultiply,fScalar);
ms_pShaderClVector->SetTexture(ms_tVector, m_pVectorTexture);
ms_pShaderClVector->SetTechnique(ms_tMultiplyScal);
RenderViewPortCover(ms_pShaderClVector);
EndScene();
}
LPDIRECT3DSURFACE9 clFragmentVector::getWriteSurface() {
m_ID[0] = ms_memoryMananger->getTextureTarget(m_memDesc,m_pTempTexture[0],m_pTempTextureSurface[0]);
return m_pTempTextureSurface[0];
}
LPDIRECT3DSURFACE9 clFragmentVector::getReadSurface() {
return m_pVectorTextureSurface;
}
void clFragmentVector::swapSurfaces() {
// swap temp and vector surface and texture
PDIRECT3DTEXTURE9 swapTex = m_pVectorTexture;
LPDIRECT3DSURFACE9 swapSurface = m_pVectorTextureSurface;
m_pVectorTexture = m_pTempTexture[0];
m_pVectorTextureSurface = m_pTempTextureSurface[0];
ms_memoryMananger->releaseTextureTarget(m_ID[0],swapTex,swapSurface);
m_ID[0] = -1;
}
/*******************************************************************************************
Name: addVector
Purpose: adds this vector to another vector storing the result in target
vTarget = (this*fScal1)+(vSource*fScal2)
********************************************************************************************/
void clFragmentVector::addVector(clFragmentVector* vSource, clFragmentVector* vTarget, float fScal1, float fScal2) {
vTarget->BeginScene();
ms_pShaderClVector->SetTechnique(ms_tVectorAdd);
ms_pShaderClVector->SetFloat(ms_fMultiply,fScal1);
ms_pShaderClVector->SetFloat(ms_fMultiply2,fScal2);
ms_pShaderClVector->SetTexture(ms_tVector, this->m_pVectorTexture);
ms_pShaderClVector->SetTexture(ms_tLastPass, vSource->m_pVectorTexture);
RenderViewPortCover(ms_pShaderClVector);
vTarget->EndScene();
}
/*******************************************************************************************
Name: vectorOp
Purpose: executes different vector-vector ops depending on eOpType
********************************************************************************************/
void clFragmentVector::vectorOp(CL_enum eOpType, clFragmentVector *clvSource, clFragmentVector *clvTarget, float fScal1, float fScal2) {
switch (eOpType) {
case CL_ADD: addVector(clvSource, clvTarget, fScal1, fScal2);
break;
case CL_SUB: addVector(clvSource, clvTarget, fScal1, -fScal2);
break;
}
}
void clFragmentVector::addVector(clFragmentVector* vSource, clFragmentVector* vTarget, float fScal, clFloat *clfScal) {
vTarget->BeginScene();
ms_pShaderClVector->SetTechnique(ms_tVectorAdd);
ms_pShaderClVector->SetFloat(ms_fMultiply,fScal);
ms_pShaderClVector->SetTexture(ms_tMultiply, clfScal->readTexture());
ms_pShaderClVector->SetTexture(ms_tVector, this->m_pVectorTexture);
ms_pShaderClVector->SetTexture(ms_tLastPass, vSource->m_pVectorTexture);
RenderViewPortCover(ms_pShaderClVector,1);
vTarget->EndScene();
}
void clFragmentVector::subtractVector(clFragmentVector* vSource, clFragmentVector* vTarget, float fScal, clFloat *clfScal) {
vTarget->BeginScene();
ms_pShaderClVector->SetTechnique(ms_tVectorAdd);
ms_pShaderClVector->SetFloat(ms_fMultiply,fScal);
ms_pShaderClVector->SetTexture(ms_tMultiply, clfScal->readTexture());
ms_pShaderClVector->SetTexture(ms_tVector, this->m_pVectorTexture);
ms_pShaderClVector->SetTexture(ms_tLastPass, vSource->m_pVectorTexture);
RenderViewPortCover(ms_pShaderClVector,2);
vTarget->EndScene();
}
/*******************************************************************************************
Name: copyVector
Purpose: dublicate a vector (this.data = clvSource.data)
********************************************************************************************/
void clFragmentVector::copyVector(clFragmentVector *clvSource) {
BeginScene();
ms_pShaderClVector->SetFloat(ms_fMultiply,1);
ms_pShaderClVector->SetTexture(ms_tVector, clvSource->m_pVectorTexture);
ms_pShaderClVector->SetTechnique(ms_tMultiplyScal);
RenderViewPortCover(ms_pShaderClVector);
EndScene();
}
/*******************************************************************************************
Name: setData
Purpose: copy vector to a texture on the GPU
********************************************************************************************/
void clFragmentVector::setData(float* fVectorData) {
D3DLOCKED_RECT rfTextureLock;
LPDIRECT3DSURFACE9 pSurf;
PDIRECT3DTEXTURE9 pTex;
int id = ms_memoryMananger->getSysmemTexture(m_memDesc,pTex,pSurf);
pTex->LockRect(0, &rfTextureLock, NULL, 0); // lock whole region in the vector texture
#ifdef use16BitPrecOnly
D3DXFLOAT16* temp = new D3DXFLOAT16[getSize()]; // convert float32 to float16
for (int i=0;i<getSize();i++) temp[i] = fVectorData[i];
D3DXFLOAT16* pfTexture = (D3DXFLOAT16*)rfTextureLock.pBits;
memcpy(pfTexture,temp,getSize()*sizeof(D3DXFLOAT16));
delete [] temp;
#else
float* pfTexture = (float*)rfTextureLock.pBits;
memcpy(pfTexture,fVectorData,getSize()*sizeof(float));
#endif
pTex->UnlockRect(0);
setData(pSurf);
ms_memoryMananger->releaseSysmemTexture(id);
}
/*******************************************************************************************
Name: getData
Purpose: read vector data back into main mem
********************************************************************************************/
void clFragmentVector::getData(float* fVectorData) {
D3DLOCKED_RECT rfTextureLock;
LPDIRECT3DSURFACE9 pSurf;
PDIRECT3DTEXTURE9 pTex;
int id = ms_memoryMananger->getSysmemTexture(m_memDesc,pTex,pSurf);
// transfer data from GPU to CPU
getData(pSurf);
// copy data into user pointer
pTex->LockRect(0, &rfTextureLock, NULL, D3DLOCK_READONLY); // lock whole region in the vector texture
#ifdef use16BitPrecOnly
D3DXFLOAT16* temp = new D3DXFLOAT16[getSize()]; // convert float32 to float16
D3DXFLOAT16* pfTexture = (D3DXFLOAT16*)rfTextureLock.pBits;
memcpy(temp,pfTexture,getSize()*sizeof(D3DXFLOAT16));
for (int i=0;i<getSize();i++) fVectorData[i] = temp[i];
delete [] temp;
#else
float* pfTexture = (float*)rfTextureLock.pBits;
memcpy(fVectorData,pfTexture,getSize()*sizeof(float));
#endif
pTex->UnlockRect(0);
ms_memoryMananger->releaseSysmemTexture(id);
}
HRESULT clFragmentVector::setData(LPDIRECT3DSURFACE9 m_pSurfSystem) {
HRESULT hr;
CHECK_HR(m_pd3dDevice->UpdateSurface(m_pSurfSystem, NULL, m_pVectorTextureSurface, NULL));
return S_OK;
}
HRESULT clFragmentVector::getData(LPDIRECT3DSURFACE9 m_pSurfSystem) {
HRESULT hr;
CHECK_HR(m_pd3dDevice->GetRenderTargetData(m_pVectorTextureSurface, m_pSurfSystem));
return S_OK;
}
/*******************************************************************************************
Name: toString
Purpose: convert the vector to a string, outputting only the first iOutputCount values
iOutputCount==0 (default) outputs all values
********************************************************************************************/
TCHAR* clFragmentVector::toString(int iOutputCount) {
TCHAR* cpResult = new TCHAR[20*getSize()]; // TODO: check if 20 makes sense here
TCHAR* cpTemp = new TCHAR[20];
float* pfData = new float[getSize()];
getData(pfData);
cpResult[0] = 0;
for (int i = 0;i<getSize();i++) {
if (iOutputCount > 0 && iOutputCount <= i) return cpResult;
if ((i+1)%m_memDesc.m_iWidth)
_stprintf(cpTemp,_T("%7.5f\t "),pfData[i]);
else
_stprintf(cpTemp,_T("%7.5f\n"),pfData[i]);
_tcscat(cpResult,cpTemp);
}
return cpResult;
}
/*******************************************************************************************
Name: toShortString
Purpose: convert the vector to a string, but display only non zero entries
********************************************************************************************/
TCHAR* clFragmentVector::toShortString(int iOutputCount) {
TCHAR* cpResult = new TCHAR[20*getSize()]; // TODO: check if 20 makes sense here
TCHAR* cpTemp = new TCHAR[20];
float* pfData = new float[getSize()];
int iOutCounter = 0;
getData(pfData);
cpResult[0] = 0;
for (int i = 0;i<getSize();i++) {
if (fabs(pfData[i]) > 0.00001) {
_stprintf(cpTemp,_T("%i:%7.5f\t "),i, pfData[i]);
_tcscat(cpResult,cpTemp);
iOutCounter++;
if (iOutputCount > 0 && iOutputCount < iOutCounter) return cpResult;
}
}
return cpResult;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -