📄 d3dhelperfuncs.cpp
字号:
-fSizeDiv2,
0.0f);
pVertices->color = dwColor;
pVertices->tu = (float)x/(float)(iNumVerticesX-1);
pVertices->tv = 1.0f;
pVertices++;
}
// left row
for (y=iNumVerticesY-1; y >= 1; y--) {
pVertices->position = D3DXVECTOR3(
-fSizeDiv2,
(((float)(iNumVerticesY-1-y)/(float)(iNumVerticesY-1))*fTotalSize)-fSizeDiv2,
0.0f);
pVertices->color = dwColor;
pVertices->tu = 0.0f;
pVertices->tv = (float)y/(float)(iNumVerticesY-1);
pVertices++;
}
// last point in exact center
pVertices->position = D3DXVECTOR3(0.0f,0.0f, 0.0f);
pVertices->color = dwColor;
pVertices->tu = 0.5f;
pVertices->tv = 0.5f;
}
// create index buffer
{
if(FAILED(hr = pDev->CreateIndexBuffer(
(((iNumVerticesX-1)*2)+((iNumVerticesY-1)*2))*3*2, // *3 (indicies per tri) * 2 (bytes per index)
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
D3DPOOL_MANAGED, pIB)))
return hr;
// lock and fill index buffer
WORD *pIndices;
if(FAILED(hr = (*pIB)->Lock(0, (((iNumVerticesX-1)*2)+((iNumVerticesY-1)*2))*3*2, (unsigned char **)&pIndices,
0)))
return hr;
// the triangles are arranged in a fan pattern...
// probably could have used tri fans here but GeForce class cards like tri lists better
WORD *pIndex = pIndices;
for (int q=0; q < (((iNumVerticesX-1)*2)+((iNumVerticesY-1)*2)); q++) {
// first triangle
*(pIndex++) = q;
*(pIndex++) = ((iNumVerticesX-1)*2)+((iNumVerticesY-1)*2);
*(pIndex++) = ((q+1 == ((iNumVerticesX-1)*2)+((iNumVerticesY-1)*2)) ? 0 : q+1);
}
if(FAILED(hr = (*pIB)->Unlock())) return hr;
if(FAILED(hr = (*pVB)->Unlock())) return hr;
}
return(S_OK);
}
HRESULT RenderCopy(LPDIRECT3DTEXTURE8 ptexSource, LPDIRECT3DTEXTURE8 ptexDest,
int iDestWidth, int iDestHeight, LPDIRECT3DDEVICE8 pDev,
LPDIRECT3DVERTEXBUFFER8 pvbQuad)
{
HRESULT hr;
// get the current depth buffer (we have to pass this into SetRenderTarget
// so we don't inadvertently drop our depth buffer.)
LPDIRECT3DSURFACE8 pDepthSurf;
pDev->GetDepthStencilSurface(&pDepthSurf);
// get the current rendering target (we'll set it back later)
LPDIRECT3DSURFACE8 pOldRenderTarget;
pDev->GetRenderTarget(&pOldRenderTarget);
// get surface interfaces
LPDIRECT3DSURFACE8 psurfDest;
ptexDest->GetSurfaceLevel(0, &psurfDest);
// set new rendering target & clear
pDev->SetRenderTarget(psurfDest, NULL);
pDev->Clear( 0L, NULL, D3DCLEAR_TARGET, 0x000000, 1.0f, 0L );
// turn off z buffering
pDev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
// set up texture stages for simple texture stage copy
pDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
pDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pDev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
SetupOrthoProjForRenderCopy(pDev, iDestWidth, iDestHeight);
// set the source texture active
pDev->SetTexture(0, ptexSource);
// begin rendering the scene
if (FAILED(hr = pDev->BeginScene())) return hr;
pDev->SetStreamSource( 0, pvbQuad, sizeof(VERTEX_XYZ_DIFFUSE_TEX1));
pDev->SetVertexShader( D3DFVF_XYZ_DIFFUSE_TEX1 );
// this "blits" the texture
pDev->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
// end scene
pDev->EndScene();
// release the dest surface
psurfDest->Release();
// set the rendering target back to the old target.
pDev->SetRenderTarget(pOldRenderTarget, pDepthSurf);
pDev->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
pOldRenderTarget->Release();
// release the depth surface interface.
pDepthSurf->Release();
return S_OK;
}
HRESULT SmoothRenderCopy(LPDIRECT3DTEXTURE8 ptexSource, LPDIRECT3DTEXTURE8 ptexDest,
int iDestWidth, int iDestHeight, LPDIRECT3DDEVICE8 pDev,
LPDIRECT3DVERTEXBUFFER8 pvbQuad)
{
// no alpha blending or lighting
pDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
pDev->SetRenderState(D3DRS_LIGHTING, FALSE);
// turn on bilinear filtering (this is what "smooths the noise")
pDev->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
pDev->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
pDev->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
// render-copy the texture
return(RenderCopy(ptexSource, ptexDest, iDestWidth, iDestHeight, pDev, pvbQuad));
}
HRESULT SetupOrthoProjForRenderCopy(LPDIRECT3DDEVICE8 pDev, int iWidth, int iHeight)
{
// set up orthogonal projection matrix, so that one texel = one pixel in the final
// image, with no perspective correction.
D3DXMATRIX projmat;
D3DXMatrixOrthoLH(&projmat, (float)iWidth, (float)iHeight, 0.0, 100.0);
pDev->SetTransform( D3DTS_PROJECTION, &projmat );
// set up world matrix so that it rotates the quad slightly.
D3DXMATRIX worldmattemp, worldmat, transmat;
D3DXMatrixScaling(&worldmattemp, (float)iWidth/2.0f, (float)iHeight/2.0f, 1.0);
// move the quad left and up 0.5 units, so that the texels are perfectly
// centered on the screen pixels.
D3DXMatrixMultiply(&worldmat, &worldmattemp, D3DXMatrixTranslation(&transmat, -0.5f, -0.5f, 0));
pDev->SetTransform( D3DTS_WORLD, &worldmat );
// set up view matrix
D3DXMATRIX viewmat;
D3DXMatrixIdentity(&viewmat);
pDev->SetTransform( D3DTS_VIEW, &viewmat );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DoesRayIntersectTriangle()
// Desc: Given a ray origin (orig) and direction (dir), and three vertices of
// of a triangle, this function returns TRUE and the interpolated texture
// coordinates if the ray intersects the triangle
//-----------------------------------------------------------------------------
bool DoesRayIntersectTriangle( const D3DXVECTOR3& orig,
const D3DXVECTOR3& dir, D3DXVECTOR3& v0,
D3DXVECTOR3& v1, D3DXVECTOR3& v2,
FLOAT* t, FLOAT* u, FLOAT* v )
{
// Find vectors for two edges sharing vert0
D3DXVECTOR3 edge1 = v1 - v0;
D3DXVECTOR3 edge2 = v2 - v0;
// Begin calculating determinant - also used to calculate U parameter
D3DXVECTOR3 pvec;
D3DXVec3Cross( &pvec, &dir, &edge2 );
// If determinant is near zero, ray lies in plane of triangle
FLOAT det = D3DXVec3Dot( &edge1, &pvec );
if( det < 0.0001f )
return false;
// Calculate distance from vert0 to ray origin
D3DXVECTOR3 tvec = orig - v0;
// Calculate U parameter and test bounds
*u = D3DXVec3Dot( &tvec, &pvec );
if( *u < 0.0f || *u > det )
return false;
// Prepare to test V parameter
D3DXVECTOR3 qvec;
D3DXVec3Cross( &qvec, &tvec, &edge1 );
// Calculate V parameter and test bounds
*v = D3DXVec3Dot( &dir, &qvec );
if( *v < 0.0f || *u + *v > det )
return false;
// Calculate t, scale parameters, ray intersects triangle
*t = D3DXVec3Dot( &edge2, &qvec );
FLOAT fInvDet = 1.0f / det;
*t *= fInvDet;
*u *= fInvDet;
*v *= fInvDet;
return true;
}
HRESULT CreateShader(LPDIRECT3DDEVICE8 pDev, const char *strFilename,
DWORD *pDecl, DWORD &dwID)
{
HRESULT hr;
LPD3DXBUFFER pCode;
// Assemble the shader from the file
if( FAILED( hr = D3DXAssembleShaderFromFile( strFilename,
0, NULL, &pCode, NULL ) ) )
return hr;
// if PDecl is not null, we know this is a vertex shader.
if (pDecl) {
hr = pDev->CreateVertexShader( pDecl,
(DWORD*)pCode->GetBufferPointer(), &dwID, 0 );
}
else {
// it's a pixel shader!
hr = pDev->CreatePixelShader((DWORD *)pCode->GetBufferPointer(), &dwID);
}
pCode->Release();
if( FAILED(hr) ) return hr;
return(S_OK);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -