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