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:
0015: LPDIRECT3DVERTEXBUFFER8 pMeshVB = NULL;
0016: LPDIRECT3DINDEXBUFFER8 pMeshIndex = NULL;
0017: D3DXATTRIBUTERANGE *pSubsetTable = NULL;
0018: DWORD nMeshFaces = 0;
0019: DWORD nMeshVertices = 0;
0020: D3DMATERIAL8 *pMeshMaterials = NULL;
0021: LPDIRECT3DTEXTURE8 *pMeshTextures = NULL;
0022: DWORD dwNumMaterials = 0L;
0023:
0024: DWORD hVertexShader=~0;
0025: FLOAT MeshRadius;
0026:
0027:
0028:
0029:
0030: typedef struct {
0031: float x,y,z;
0032: float nx,ny,nz;
0033: float tu0,tv0;
0034: }D3DVERTEX;
0035: #define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0036:
0037: typedef struct {
0038: float x,y,z;
0039: float nx,ny,nz;
0040: float tu0,tv0;
0041: }D3D_CUSTOMVERTEX;
0042: #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0043:
0044: DWORD dwDecl[] = {
0045: D3DVSD_STREAM(0),
0046: D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
0047: D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3 ),
0048: D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ),
0049: D3DVSD_END()
0050: };
0051:
0054: HRESULT LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDEV)
0055: {
0056: LPD3DXMESH pMesh, pMeshOpt;
0057: LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
0058: DWORD i;
0059: HRESULT hr;
0060:
0061: hr = D3DXLoadMeshFromX(filename, D3DXMESH_MANAGED,
0062: lpD3DDEV, NULL,
0063: &pD3DXMtrlBuffer, &dwNumMaterials,
0064: &pMesh);
0065: if(FAILED(hr)) return E_FAIL;
0066:
0067:
0068: pMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshOpt);
0069: RELEASE(pMesh);
0070:
0071:
0072: pMeshOpt->GetAttributeTable(NULL,&dwNumMaterials);
0073: pSubsetTable = new D3DXATTRIBUTERANGE[dwNumMaterials];
0074: pMeshOpt->GetAttributeTable(pSubsetTable, &dwNumMaterials);
0075:
0076:
0077: hr = pMeshOpt->CloneMeshFVF(pMeshOpt->GetOptions(), D3DFVF_VERTEX, lpD3DDEV, &pMesh);
0078: if(FAILED(hr)) return E_FAIL;
0079: RELEASE(pMeshOpt);
0080: D3DXComputeNormals(pMesh);
0081:
0082:
0083: D3DVERTEX* pSrc;
0084: D3D_CUSTOMVERTEX* pDest;
0085: LPDIRECT3DINDEXBUFFER8 pSrcIndex;
0086: WORD* pISrc;
0087: WORD* pIDest;
0088:
0089: DWORD nMeshVertices = pMesh->GetNumVertices();
0090: DWORD nMeshFaces = pMesh->GetNumFaces();
0091: lpD3DDEV->CreateVertexBuffer(nMeshVertices * sizeof(D3D_CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pMeshVB);
0092: lpD3DDEV->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&pMeshIndex);
0093:
0094: LPDIRECT3DVERTEXBUFFER8 pVB;
0095: pMesh->GetVertexBuffer(&pVB);
0096: pVB->Lock(0,0,(BYTE**)&pSrc,0);
0097: pMeshVB->Lock(0,0,(BYTE**)&pDest,0);
0098: MeshRadius = 0.0f;
0099: for(i=0;i<nMeshVertices;i++){
0100:
0101: FLOAT radius = sqrtf( pSrc->x*pSrc->x + pSrc->y*pSrc->y + pSrc->z*pSrc->z );
0102: if (MeshRadius < radius) MeshRadius = radius;
0103:
0104: pDest->x = pSrc->x;
0105: pDest->y = pSrc->y;
0106: pDest->z = pSrc->z;
0107: pDest->nx = pSrc->nx;
0108: pDest->ny = pSrc->ny;
0109: pDest->nz = pSrc->nz;
0110: pDest->tu0 = pSrc->tu0;
0111: pDest->tv0 = pSrc->tv0;
0112: pSrc += 1;
0113: pDest += 1;
0114: }
0115: pVB->Unlock();
0116: pVB->Release();
0117: pMeshVB->Unlock();
0118:
0119:
0120: pMesh->GetIndexBuffer(&pSrcIndex);
0121: pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0122: pMeshIndex->Lock(0,0,(BYTE**)&pIDest,0);
0123: CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0124: pSrcIndex->Unlock();
0125: pMeshIndex->Unlock();
0126: pSrcIndex->Release();
0127:
0128:
0129: D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0130: pMeshTextures = new LPDIRECT3DTEXTURE8[dwNumMaterials];
0131: pMeshMaterials = new D3DMATERIAL8[dwNumMaterials];
0132:
0133: for(i = 0; i < dwNumMaterials; i++){
0134: pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
0135: pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
0136: hr = D3DXCreateTextureFromFile( lpD3DDEV,
0137: d3dxMaterials[i].pTextureFilename,
0138: &pMeshTextures[i] );
0139: if(FAILED(hr)) pMeshTextures[i] = NULL;
0140: }
0141: RELEASE(pD3DXMtrlBuffer);
0142:
0143: RELEASE(pMesh);
0144:
0145: return S_OK;
0146: }
0147:
0148:
0149:
0150:
0151:
0152:
0153: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0154: {
0155: HRESULT hr;
0156:
0157:
0158: hr = LoadXFile("nsx.x", lpD3DDev);
0159: if ( FAILED(hr) ) return hr;
0160:
0161:
0162: ID3DXBuffer* pshader;
0163: hr = D3DXAssembleShaderFromFile("vs.vsh", 0,NULL,&pshader,NULL);
0164: if ( FAILED(hr) ) return hr;
0165: hr = lpD3DDev->CreateVertexShader( dwDecl, (DWORD*)pshader->GetBufferPointer(), &hVertexShader, 0 );
0166: RELEASE(pshader);
0167: if ( FAILED(hr) ) return hr;
0168:
0169:
0170: lpD3DDev->SetRenderState( D3DRS_LIGHTING, FALSE );
0171: lpD3DDev->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
0172: lpD3DDev->SetRenderState( D3DRS_FOGENABLE, FALSE);
0173:
0174: lpD3DDev->SetRenderState( D3DRS_DITHERENABLE, FALSE );
0175: lpD3DDev->SetRenderState( D3DRS_SPECULARENABLE, FALSE );
0176: lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE );
0177:
0178: lpD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
0179: lpD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
0180: lpD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
0181:
0182: lpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
0183: lpD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
0184: lpD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
0185:
0186: lpD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0187: lpD3DDev->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
0188: lpD3DDev->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
0189: lpD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
0190: lpD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
0191:
0192:
0193: lpD3DDev->SetVertexShaderConstant(0, D3DXVECTOR4(0.0f,0.5f,1.0f,2.0f), 1);
0194:
0195: return S_OK;
0196: }
0197:
0198: static set_transform(bool bWithBlur, LPDIRECT3DDEVICE8 lpD3DDev, D3DXMATRIX mWorld, D3DXMATRIX mView, D3DXMATRIX mProj)
0199: {
0200: D3DXMATRIX m, mWV, mWV_IT;
0201: static D3DXMATRIX mLastWV;
0202:
0203: D3DXMatrixMultiply(&mWV, &mWorld, &mView);
0204: D3DXMatrixInverse( &mWV_IT, NULL, &mWV);
0205:
0206:
0207: D3DXMatrixTranspose(&m, &mProj);
0208: lpD3DDev->SetVertexShaderConstant(4, &m, 4);
0209:
0210:
0211: D3DXMatrixTranspose(&mWV, &mWV);
0212: lpD3DDev->SetVertexShaderConstant(8, &mWV, 3);
0213: if (bWithBlur){
0214: lpD3DDev->SetVertexShaderConstant(12, &mLastWV, 3);
0215: mLastWV = mWV;
0216: }else{
0217:
0218: lpD3DDev->SetVertexShaderConstant(12, &mWV, 3);
0219: }
0220:
0221:
0222: lpD3DDev->SetVertexShaderConstant(16, &mWV_IT, 3);
0223:
0224: return S_OK;
0225: }
0226:
0227:
0228:
0229:
0230: void Render(LPDIRECT3DDEVICE8 lpD3DDev)
0231: {
0232: if(NULL == pMeshVB) return;
0233:
0234: D3DXMATRIX m, mWorld, mView, mProj;
0235: DWORD i;
0236:
0237:
0238: D3DXMatrixTranslation(&m, MeshRadius, 0,0);
0239: D3DXMatrixRotationY( &mWorld, timeGetTime()/1000.0f );
0240: mWorld = m * mWorld;
0241:
0242:
0243: D3DXVECTOR3 eye (0.0f,MeshRadius,2.5f*MeshRadius);
0244: D3DXVECTOR3 lookAt(0.0f, 0.0f, 0.0f);
0245: D3DXVECTOR3 up (0.0f, 1.0f, 0.0f);
0246: D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0247:
0248: D3DXMatrixPerspectiveFovLH(&mProj, PI/3.0f, (float)WIDTH/(float)HEIGHT, 0.01f, 100.0f);
0249:
0250:
0251: lpD3DDev->SetVertexShaderConstant( 3, D3DXVECTOR4(
0252: 2.0f/MeshRadius,
0253: 3.0f,
0254: 1.0f,0.0f), 1 );
0255:
0256: lpD3DDev->SetVertexShader(hVertexShader);
0257: lpD3DDev->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0258: lpD3DDev->SetIndices(pMeshIndex,0);
0259:
0260:
0261:
0262: set_transform(1,lpD3DDev, mWorld, mView, mProj);
0263: lpD3DDev->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
0264: for(i=0;i<dwNumMaterials;i++){
0265:
0266: D3DXVECTOR4 c(pMeshMaterials[i].Diffuse.r,
0267: pMeshMaterials[i].Diffuse.g,
0268: pMeshMaterials[i].Diffuse.b,
0269: 1.0f);
0270: FLOAT const kBlurAlpha = 0.0f;
0271:
0272: lpD3DDev->SetVertexShaderConstant( 1, &c, 1 );
0273: c[3] = kBlurAlpha;
0274: lpD3DDev->SetVertexShaderConstant( 2, &c, 1 );
0275:
0276: lpD3DDev->SetTexture(0, pMeshTextures[i]);
0277: lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0278: pSubsetTable[i].VertexStart,
0279: pSubsetTable[i].VertexCount,
0280: pSubsetTable[i].FaceStart * 3,
0281: pSubsetTable[i].FaceCount);
0282: }
0283:
0284:
0285: set_transform(0,lpD3DDev, mWorld, mView, mProj);
0286: lpD3DDev->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
0287: for(i=0;i<dwNumMaterials;i++){
0288:
0289: D3DXVECTOR4 c(pMeshMaterials[i].Diffuse.r,
0290: pMeshMaterials[i].Diffuse.g,
0291: pMeshMaterials[i].Diffuse.b,
0292: 1.0f);
0293: lpD3DDev->SetVertexShaderConstant( 1, &c, 1 );
0294: lpD3DDev->SetVertexShaderConstant( 2, &c, 1 );
0295:
0296: lpD3DDev->SetTexture(0, pMeshTextures[i]);
0297: lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0298: pSubsetTable[i].VertexStart,
0299: pSubsetTable[i].VertexCount,
0300: pSubsetTable[i].FaceStart * 3,
0301: pSubsetTable[i].FaceCount);
0302: }
0303:
0304: Sleep(100);
0305: }
0306:
0307:
0308:
0309: void DeleteMeshObject(void)
0310: {
0311: DWORD i;
0312:
0313: if(pMeshVB == NULL) return;
0314:
0315: for(i=0; i<dwNumMaterials; i++){
0316: RELEASE(pMeshTextures[i]);
0317: }
0318: delete[] pMeshTextures;
0319: delete[] pMeshMaterials;
0320: delete[] pSubsetTable;
0321:
0322: RELEASE(pMeshVB);
0323: RELEASE(pMeshIndex);
0324: }
0325:
0326:
0327:
0328:
0329: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDEV)
0330: {
0331: DeleteMeshObject();
0332:
0333: if ( hVertexShader != ~0 ){
0334: lpD3DDEV->DeleteVertexShader( hVertexShader );
0335: hVertexShader = ~0;
0336: }
0337: }
0338: