0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009: #define STRICT
0010:
0011: #include <windows.h>
0012: #include "main.h"
0013: #include "draw.h"
0014: #include "load.h"
0015:
0016: LPDIRECT3DVERTEXBUFFER8 pMeshVB = NULL;
0017: LPDIRECT3DINDEXBUFFER8 pMeshIndex = NULL;
0018: D3DXATTRIBUTERANGE *pSubsetTable = NULL;
0019: DWORD nMeshFaces = 0;
0020: DWORD nMeshVertices = 0;
0021: D3DMATERIAL8 *pMeshMaterials = NULL;
0022: LPDIRECT3DTEXTURE8 *pMeshTextures = NULL;
0023: DWORD dwNumMaterials = 0L;
0024: FLOAT MeshRadius;
0025:
0026: DWORD hVertexShader=~0;
0027:
0028:
0029:
0030: LPDIRECT3DSURFACE8 pBackbuffer = NULL;
0031: LPDIRECT3DTEXTURE8 pMaskTexture = NULL;
0032: DWORD hBlurVertexShader=~0;
0033: DWORD hBlurPixelShader=~0;
0034: DWORD hFocusPixelShader=~0;
0035: LPDIRECT3DVERTEXBUFFER8 pBlurVB = NULL;
0036: LPDIRECT3DINDEXBUFFER8 pBlurIB = NULL;
0037:
0038: const int nBlurTex = 4;
0039: LPDIRECT3DTEXTURE8 pTexture[nBlurTex];
0040: LPDIRECT3DSURFACE8 pTextureSurface[nBlurTex];
0041:
0042: const int nTempTex = 2;
0043: LPDIRECT3DTEXTURE8 pTmpTexture[nTempTex];
0044: LPDIRECT3DSURFACE8 pTmpSurface[nTempTex];
0045:
0046: typedef struct {
0047: float x,y,z;
0048: float tu,tv;
0049: }D3D_BLUR_VERTEX;
0050: #define D3DFVF_BLUR_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
0051:
0052: DWORD dwBlurDecl[] = {
0053: D3DVSD_STREAM(0),
0054: D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
0055: D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ),
0056: D3DVSD_END()
0057: };
0058:
0059:
0060:
0061:
0062: void InitBg(LPDIRECT3DDEVICE8 lpD3DDev);
0063: void DrawBg(LPDIRECT3DDEVICE8 lpD3DDev);
0064: void CleanBg(LPDIRECT3DDEVICE8 lpD3DDev);
0065:
0066:
0067:
0068:
0069:
0070:
0071: typedef struct {
0072: float x,y,z;
0073: float nx,ny,nz;
0074: float tu0,tv0;
0075: }D3DVERTEX;
0076: #define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0077:
0078:
0079:
0080:
0081:
0082: HRESULT LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDev)
0083: {
0084: LPD3DXMESH pMesh, pMeshOpt;
0085: LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
0086: DWORD i;
0087: HRESULT hr;
0088:
0089: hr = D3DXLoadMeshFromX(filename, D3DXMESH_MANAGED,
0090: lpD3DDev, NULL,
0091: &pD3DXMtrlBuffer, &dwNumMaterials,
0092: &pMesh);
0093: if(FAILED(hr)) return E_FAIL;
0094:
0095:
0096: pMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshOpt);
0097: RELEASE(pMesh);
0098:
0099:
0100: pMeshOpt->GetAttributeTable(NULL,&dwNumMaterials);
0101: pSubsetTable = new D3DXATTRIBUTERANGE[dwNumMaterials];
0102: pMeshOpt->GetAttributeTable(pSubsetTable, &dwNumMaterials);
0103:
0104:
0105: hr = pMeshOpt->CloneMeshFVF(pMeshOpt->GetOptions(), D3DFVF_VERTEX, lpD3DDev, &pMesh);
0106: if(FAILED(hr)) return E_FAIL;
0107: RELEASE(pMeshOpt);
0108: D3DXComputeNormals(pMesh, NULL);
0109:
0110:
0111: D3DVERTEX* pSrc;
0112: D3D_CUSTOMVERTEX* pDest;
0113: LPDIRECT3DINDEXBUFFER8 pSrcIndex;
0114: WORD* pISrc;
0115: WORD* pIDest;
0116:
0117: DWORD nMeshVertices = pMesh->GetNumVertices();
0118: DWORD nMeshFaces = pMesh->GetNumFaces();
0119: lpD3DDev->CreateVertexBuffer(nMeshVertices * sizeof(D3D_CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pMeshVB);
0120: lpD3DDev->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&pMeshIndex);
0121:
0122: LPDIRECT3DVERTEXBUFFER8 pVB;
0123: pMesh->GetVertexBuffer(&pVB);
0124: pVB->Lock(0,0,(BYTE**)&pSrc,0);
0125: pMeshVB->Lock(0,0,(BYTE**)&pDest,0);
0126: MeshRadius = 0.0f;
0127: for(i=0;i<nMeshVertices;i++){
0128: pDest->x = pSrc->x;
0129: pDest->y = pSrc->y;
0130: pDest->z = pSrc->z;
0131: pDest->nx = pSrc->nx;
0132: pDest->ny = pSrc->ny;
0133: pDest->nz = pSrc->nz;
0134: pDest->tu0 = pSrc->tu0;
0135: pDest->tu0 = pSrc->tu0;
0136:
0137: FLOAT radius = sqrtf( pSrc->x*pSrc->x + pSrc->y*pSrc->y + pSrc->z*pSrc->z );
0138: if (MeshRadius < radius) MeshRadius = radius;
0139:
0140: pSrc += 1;
0141: pDest += 1;
0142: }
0143: pVB->Unlock();
0144: pVB->Release();
0145: pMeshVB->Unlock();
0146:
0147:
0148: pMesh->GetIndexBuffer(&pSrcIndex);
0149: pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0150: pMeshIndex->Lock(0,0,(BYTE**)&pIDest,0);
0151: CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0152: pSrcIndex->Unlock();
0153: pMeshIndex->Unlock();
0154: pSrcIndex->Release();
0155:
0156:
0157: D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0158: pMeshTextures = new LPDIRECT3DTEXTURE8[dwNumMaterials];
0159: pMeshMaterials = new D3DMATERIAL8[dwNumMaterials];
0160:
0161: for(i = 0; i < dwNumMaterials; i++){
0162: pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
0163: pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
0164: hr = D3DXCreateTextureFromFile( lpD3DDev,
0165: d3dxMaterials[i].pTextureFilename,
0166: &pMeshTextures[i] );
0167: if(FAILED(hr)) pMeshTextures[i] = NULL;
0168: }
0169: RELEASE(pD3DXMtrlBuffer);
0170:
0171: RELEASE(pMesh);
0172:
0173: return S_OK;
0174: }
0175:
0176:
0177:
0178:
0179: HRESULT InitBlurTexture(LPDIRECT3DDEVICE8 lpD3DDev)
0180: {
0181: HRESULT hr;
0182: DWORD i;
0183:
0184:
0185: D3D_BLUR_VERTEX *pBlurDest;
0186: WORD *pIndex;
0187: lpD3DDev->CreateVertexBuffer( 4 * sizeof(D3D_BLUR_VERTEX),
0188: D3DUSAGE_WRITEONLY, D3DFVF_BLUR_VERTEX, D3DPOOL_MANAGED,
0189: &pBlurVB );
0190:
0191: pBlurVB->Lock ( 0, 0, (BYTE**)&pBlurDest, 0 );
0192: for (i = 0; i < 4; i++) {
0193: pBlurDest->x = (i == 0 || i == 1)?-1:(float)1;
0194: pBlurDest->y = (i == 0 || i == 2)?-1:(float)1;
0195: pBlurDest->z = 0.0f;
0196: pBlurDest->tu = (i == 2 || i == 3)?1:(float)0;
0197: pBlurDest->tv = (i == 0 || i == 2)?1:(float)0;
0198: pBlurDest++;
0199: }
0200: pBlurVB->Unlock ();
0201:
0202: lpD3DDev->CreateIndexBuffer( 6 * sizeof(WORD),
0203: 0,
0204: D3DFMT_INDEX16, D3DPOOL_MANAGED,
0205: &pBlurIB );
0206: pBlurIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0207: pIndex[0] = 0; pIndex[1] = 1; pIndex[2] = 2;
0208: pIndex[3] = 1; pIndex[4] = 3; pIndex[5] = 2;
0209: pBlurIB->Unlock ();
0210:
0211:
0212: D3DSURFACE_DESC Desc;
0213: LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0214: if( FAILED(hr = lpD3DDev->GetRenderTarget(&pBackbuffer))) return hr;
0215: if( FAILED(hr = pBackbuffer->GetDesc( &Desc ))) return hr;
0216:
0217:
0218: if( FAILED(hr = lpD3DDev->GetDepthStencilSurface( &lpZbuffer ))) return hr;
0219:
0220: for(i = 0; i < nBlurTex; i ++){
0221:
0222: if( FAILED(hr = lpD3DDev->CreateTexture(Desc.Width, Desc.Height, 1
0223: , D3DUSAGE_RENDERTARGET, Desc.Format, D3DPOOL_DEFAULT, &pTexture[i]))) return hr;
0224:
0225: if( FAILED(hr = pTexture[i]->GetSurfaceLevel(0,&pTextureSurface[i]))) return hr;
0226:
0227: if( FAILED(hr = lpD3DDev->SetRenderTarget(pTextureSurface[i], (i==0)?lpZbuffer:NULL ))) return hr;
0228: }
0229:
0230: for (i = 0; i < nTempTex; ++i) {
0231:
0232: if( FAILED(hr = lpD3DDev->CreateTexture(Desc.Width, Desc.Height, 1
0233: , D3DUSAGE_RENDERTARGET, Desc.Format, D3DPOOL_DEFAULT, &pTmpTexture[i]))) return hr;
0234:
0235: if( FAILED(hr = pTmpTexture[i]->GetSurfaceLevel(0,&pTmpSurface[i]))) return hr;
0236:
0237: if( FAILED(hr = lpD3DDev->SetRenderTarget(pTmpSurface[i], NULL ))) return hr;
0238: }
0239:
0240:
0241: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0242:
0243:
0244: if ( FAILED(CVertexShaderMgr::Load(lpD3DDev, "blur.vsh", &hBlurVertexShader, dwBlurDecl)) ) return hr;
0245: if ( FAILED( CPixelShaderMgr::Load(lpD3DDev, "blur.psh", &hBlurPixelShader)) ) return hr;
0246: if ( FAILED( CPixelShaderMgr::Load(lpD3DDev, "focus.psh", &hFocusPixelShader)) ) return hr;
0247:
0248:
0249: float const s = 4.0f/3.0f;
0250: float const inv_w = s / (float)WIDTH;
0251: float const inv_h = s / (float)HEIGHT;
0252: float const box9OffsetX[4] = { 0.0f, 0.0f, inv_w, inv_w };
0253: float const box9OffsetY[4] = { 0.0f, inv_h, inv_h, 0.0f };
0254: lpD3DDev->SetVertexShaderConstant(20, &D3DXVECTOR4 ( 0.0f, 0.0f, 0.0f, 0.0f), 1);
0255: lpD3DDev->SetVertexShaderConstant(21, &D3DXVECTOR4 ( 0.0f, inv_h, 0.0f, 0.0f), 1);
0256: lpD3DDev->SetVertexShaderConstant(22, &D3DXVECTOR4 (inv_w, inv_h, 0.0f, 0.0f), 1);
0257: lpD3DDev->SetVertexShaderConstant(23, &D3DXVECTOR4 (inv_w, 0.0f, 0.0f, 0.0f), 1);
0258:
0259: return S_OK;
0260: }
0261:
0262:
0263:
0264:
0265: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0266: {
0267: HRESULT hr;
0268:
0269:
0270: if ( FAILED(hr = LoadXFile("nsx.x", lpD3DDev)) ) return hr;
0271:
0272:
0273: if ( FAILED(CTextureMgr::Load(lpD3DDev, "mask.bmp", &pMaskTexture)) ) return hr;
0274:
0275:
0276: if ( FAILED(CVertexShaderMgr::Load(lpD3DDev, "vs.vsh", &hVertexShader, dwDecl)) ) return hr;
0277:
0278:
0279: InitBlurTexture(lpD3DDev);
0280:
0281:
0282: InitBg(lpD3DDev);
0283:
0284:
0285: lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE );
0286: lpD3DDev->SetRenderState( D3DRS_LIGHTING, FALSE );
0287: lpD3DDev->SetVertexShaderConstant(12, &D3DXVECTOR4(0.0f, 0.5f, 1.0f, 2.0f), 1);
0288:
0289: return S_OK;
0290: }
0291:
0292:
0293:
0294:
0295:
0296: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev)
0297: {
0298: DWORD i, j, k;
0299: D3DXMATRIX mWorld, mView, mProj, m;
0300:
0301: LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0302: lpD3DDev->GetDepthStencilSurface( &lpZbuffer );
0303: lpD3DDev->SetRenderTarget(pTextureSurface[0], lpZbuffer);
0304: lpD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0),1.0f,0);
0305:
0306: D3DXMatrixRotationY( &mWorld, -2.5f );
0307:
0308:
0309:
0310: D3DXVECTOR3 eye = D3DXVECTOR3(0.0f,MeshRadius,2.5f*MeshRadius);
0311: D3DXVECTOR3 lookAt = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
0312: D3DXVECTOR3 up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
0313:
0314: D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0315: D3DXMatrixPerspectiveFovLH(&mProj
0316: ,60.0f*PI/180.0f
0317: ,(float)WIDTH/(float)HEIGHT
0318: ,0.01f,100.0f
0319: );
0320:
0321:
0322:
0323: lpD3DDev->SetTransform( D3DTS_VIEW, &mView );
0324: lpD3DDev->SetTransform( D3DTS_PROJECTION, &mProj );
0325: DrawBg(lpD3DDev);
0326:
0327:
0328: m = mWorld * mView * mProj;
0329: D3DXMatrixTranspose( &m , &m);
0330: lpD3DDev->SetVertexShaderConstant(0,&m, 4);
0331:
0332: D3DXVECTOR4 lightDir(1.0f, 1.0f, 0.5f, 0.0f);
0333: D3DXVec4Normalize(&lightDir, &lightDir);
0334: D3DXMatrixInverse( &m, NULL, &mWorld);
0335: D3DXVec4Transform(&lightDir, &lightDir, &m);
0336: lightDir[3] = 0.3f;
0337: lpD3DDev->SetVertexShaderConstant(13, &lightDir, 1);
0338:
0339: lpD3DDev->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0340: lpD3DDev->SetIndices(pMeshIndex,0);
0341:
0342:
0343:
0344:
0345: lpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
0346: lpD3DDev->SetVertexShader(hVertexShader);
0347: for(i=0;i<dwNumMaterials;i++){
0348:
0349: D3DXVECTOR4 vl;
0350: vl.x = pMeshMaterials[i].Diffuse.r;
0351: vl.y = pMeshMaterials[i].Diffuse.g;
0352: vl.z = pMeshMaterials[i].Diffuse.b;
0353: lpD3DDev->SetVertexShaderConstant(14, &vl, 1);
0354:
0355: lpD3DDev->SetTexture(0,pMeshTextures[i]);
0356: lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0357: pSubsetTable[i].VertexStart,
0358: pSubsetTable[i].VertexCount,
0359: pSubsetTable[i].FaceStart * 3,
0360: pSubsetTable[i].FaceCount);
0361: }
0362:
0363:
0364:
0365: lpD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0366: lpD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
0367: lpD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
0368:
0369: for (i = 0; i < 4; ++i) {
0370: lpD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0371: lpD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0372: lpD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_NONE);
0373: lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0374: lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0375: }
0376:
0377: lpD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
0378: lpD3DDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
0379: lpD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
0380: lpD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
0381:
0382: lpD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE);
0383:
0384: D3DXMatrixLookAtLH(&mView, &D3DXVECTOR3( 0.0f, 0.0f, -5.0f ), &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), &D3DXVECTOR3( 0.0f, 1.0f, 0.0f ));
0385: D3DXMatrixOrthoLH(&mProj, 512, 512, 0.2f, 20.0f);
0386: D3DXMatrixMultiply(&m, &mView, &mProj);
0387: D3DXMatrixScaling(&mWorld, 2.0f, 2.0f, 1.0f);
0388: D3DXMatrixMultiply(&m, &mWorld, &m);
0389: D3DXMatrixTranspose(&m, &m);
0390: lpD3DDev->SetVertexShaderConstant(0, &m, 4);
0391:
0392: lpD3DDev->SetVertexShader(hBlurVertexShader);
0393: lpD3DDev->SetPixelShader(hBlurPixelShader);
0394: lpD3DDev->SetStreamSource(0, pBlurVB, sizeof(D3D_BLUR_VERTEX));
0395: lpD3DDev->SetIndices(pBlurIB,0);
0396:
0397: for (i = 1; i < nBlurTex; ++i){
0398: for (j = 0; j < nTempTex; ++j){
0399: LPDIRECT3DTEXTURE8 pSource = (j == 0)? pTexture[i-1]:pTmpTexture[ j &1];
0400: LPDIRECT3DSURFACE8 pDestination = (j == nTempTex-1)?pTextureSurface[i ]:pTmpSurface[(j+1)&1];
0401: lpD3DDev->SetRenderTarget(pDestination, NULL);
0402: for (k = 0; k < 4; ++k) lpD3DDev->SetTexture(k, pSource);
0403: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0404: }
0405: }
0406:
0407:
0408:
0409: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0410: lpD3DDev->SetPixelShader(hFocusPixelShader);
0411: lpD3DDev->SetTexture( 0, pMaskTexture );
0412: lpD3DDev->SetTexture( 1, pTexture[0] );
0413: lpD3DDev->SetTexture( 2, pTexture[nBlurTex-1] );
0414: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0415:
0416:
0417:
0418: lpD3DDev->SetPixelShader(NULL);
0419: lpD3DDev->SetRenderState(D3DRS_ZENABLE, TRUE);
0420: }
0421:
0422:
0423:
0424: void DeleteMeshObject(void)
0425: {
0426: DWORD i;
0427:
0428: if(pMeshVB == NULL) return;
0429:
0430: for(i=0; i<dwNumMaterials; i++){
0431: RELEASE(pMeshTextures[i]);
0432: }
0433: delete[] pMeshTextures;
0434: delete[] pMeshMaterials;
0435: delete[] pSubsetTable;
0436:
0437: RELEASE(pMeshVB);
0438: RELEASE(pMeshIndex);
0439: }
0440:
0441:
0442:
0443:
0444: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev)
0445: {
0446: DWORD i;
0447:
0448: CleanBg(lpD3DDev);
0449:
0450: for (i = 0; i < nTempTex; ++i) {
0451: RELEASE(pTmpSurface[i]);
0452: RELEASE(pTmpTexture [i]);
0453: }
0454: for(i = 0; i < nBlurTex; i++){
0455: RELEASE(pTextureSurface[i]);
0456: RELEASE(pTexture[i]);
0457: }
0458:
0459: RELEASE(pBackbuffer);
0460:
0461: CPixelShaderMgr::Release(lpD3DDev, &hFocusPixelShader);
0462: CPixelShaderMgr::Release(lpD3DDev, &hBlurPixelShader);
0463: CVertexShaderMgr::Release(lpD3DDev, &hBlurVertexShader);
0464: CVertexShaderMgr::Release(lpD3DDev, &hVertexShader);
0465:
0466: RELEASE(pMaskTexture);
0467: DeleteMeshObject();
0468: }
0469: