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