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