0001:
0002:
0003:
0004:
0005:
0006:
0007:
0008:
0009: #define STRICT
0010:
0011: #include <windows.h>
0012: #include <tchar.h>
0013: #include "main.h"
0014: #include "draw.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:
0025: DWORD hVertexShader=~0;
0026:
0027: LPDIRECT3DCUBETEXTURE8 pEnvTexture = NULL;
0028:
0029:
0030:
0031:
0032:
0033: #define NUM_VERTICES 24
0034: #define NUM_INDICES_PERFACE 6
0035: #define NUM_FACES 6
0036: #define NUM_PRIMS_PERFACE 2
0037: #define NUM_VERTICES_PERFACE 4
0038: LPDIRECT3DVERTEXBUFFER8 pCubeVB = NULL;
0039: LPDIRECT3DINDEXBUFFER8 pFaceIB = NULL;
0040: LPDIRECT3DTEXTURE8 pCubeTex[6] = {NULL,NULL,NULL,NULL,NULL,NULL};
0041: DWORD hCubeVertexShader=~0;
0042:
0043: typedef struct CubeVertex{
0044: D3DXVECTOR3 Position;
0045: D3DXVECTOR2 Texture;
0046: } CubeVertex;
0047:
0048: DWORD dwCubeDecl[] = {
0049: D3DVSD_STREAM(0),
0050: D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
0051: D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ),
0052: D3DVSD_END()
0053: };
0054:
0055:
0056:
0057:
0058:
0059: typedef struct {
0060: float x,y,z;
0061: float nx,ny,nz;
0062: float tu0,tv0;
0063: }D3DVERTEX;
0064: #define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0065:
0066: typedef struct {
0067: float x,y,z;
0068: float nx,ny,nz;
0069: float tu0,tv0;
0070: }D3D_CUSTOMVERTEX;
0071: #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0072:
0073: DWORD dwDecl[] = {
0074: D3DVSD_STREAM(0),
0075: D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
0076: D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3 ),
0077: D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ),
0078: D3DVSD_END()
0079: };
0080:
0081:
0082:
0085: HRESULT LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDEV)
0086: {
0087: LPD3DXMESH pMesh, pMeshOpt;
0088: LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
0089: DWORD i;
0090: HRESULT hr;
0091:
0092: hr = D3DXLoadMeshFromX(filename, D3DXMESH_MANAGED,
0093: lpD3DDEV, NULL,
0094: &pD3DXMtrlBuffer, &dwNumMaterials,
0095: &pMesh);
0096: if(FAILED(hr)) return E_FAIL;
0097:
0098:
0099: pMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshOpt);
0100: RELEASE(pMesh);
0101:
0102:
0103: pMeshOpt->GetAttributeTable(NULL,&dwNumMaterials);
0104: pSubsetTable = new D3DXATTRIBUTERANGE[dwNumMaterials];
0105: pMeshOpt->GetAttributeTable(pSubsetTable, &dwNumMaterials);
0106:
0107:
0108: hr = pMeshOpt->CloneMeshFVF(pMeshOpt->GetOptions(), D3DFVF_VERTEX, lpD3DDEV, &pMesh);
0109: if(FAILED(hr)) return E_FAIL;
0110: RELEASE(pMeshOpt);
0111: D3DXComputeNormals(pMesh);
0112:
0113:
0114: D3DVERTEX* pSrc;
0115: D3D_CUSTOMVERTEX* pDest;
0116: LPDIRECT3DINDEXBUFFER8 pSrcIndex;
0117: WORD* pISrc;
0118: WORD* pIDest;
0119:
0120: DWORD nMeshVertices = pMesh->GetNumVertices();
0121: DWORD nMeshFaces = pMesh->GetNumFaces();
0122: lpD3DDEV->CreateVertexBuffer(nMeshVertices * sizeof(D3D_CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pMeshVB);
0123: lpD3DDEV->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&pMeshIndex);
0124:
0125: LPDIRECT3DVERTEXBUFFER8 pVB;
0126: pMesh->GetVertexBuffer(&pVB);
0127: pVB->Lock(0,0,(BYTE**)&pSrc,0);
0128: pMeshVB->Lock(0,0,(BYTE**)&pDest,0);
0129: for(i=0;i<nMeshVertices;i++){
0130: pDest->x = pSrc->x;
0131: pDest->y = pSrc->y;
0132: pDest->z = pSrc->z;
0133: pDest->nx = pSrc->nx;
0134: pDest->ny = pSrc->ny;
0135: pDest->nz = pSrc->nz;
0136: pSrc += 1;
0137: pDest += 1;
0138: }
0139: pVB->Unlock();
0140: pVB->Release();
0141: pMeshVB->Unlock();
0142:
0143:
0144: pMesh->GetIndexBuffer(&pSrcIndex);
0145: pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0146: pMeshIndex->Lock(0,0,(BYTE**)&pIDest,0);
0147: CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0148: pSrcIndex->Unlock();
0149: pMeshIndex->Unlock();
0150: pSrcIndex->Release();
0151:
0152:
0153: D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0154: pMeshTextures = new LPDIRECT3DTEXTURE8[dwNumMaterials];
0155: pMeshMaterials = new D3DMATERIAL8[dwNumMaterials];
0156:
0157: for(i = 0; i < dwNumMaterials; i++){
0158: pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
0159: pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
0160: hr = D3DXCreateTextureFromFile( lpD3DDEV,
0161: d3dxMaterials[i].pTextureFilename,
0162: &pMeshTextures[i] );
0163: if(FAILED(hr)) pMeshTextures[i] = NULL;
0164: }
0165: RELEASE(pD3DXMtrlBuffer);
0166:
0167: RELEASE(pMesh);
0168:
0169: return S_OK;
0170: }
0171:
0172:
0173:
0174:
0175:
0176:
0177: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDEV)
0178: {
0179: HRESULT hr;
0180:
0181:
0182:
0183:
0184: D3DXCreateCubeTextureFromFileEx(lpD3DDEV,
0185: "earth.dds",
0186: D3DX_DEFAULT,
0187: 0, 0,
0188: D3DFMT_UNKNOWN,
0189: D3DPOOL_MANAGED,
0190: D3DX_FILTER_LINEAR,
0191: D3DX_FILTER_LINEAR,
0192: 0, NULL, NULL,
0193: &pEnvTexture);
0194:
0195:
0196:
0197:
0198: D3DXVECTOR3 CubePosition[] = {
0199: D3DXVECTOR3(-1.0f, -1.0f, -1.0f),
0200: D3DXVECTOR3(-1.0f, 1.0f, -1.0f),
0201: D3DXVECTOR3( 1.0f, 1.0f, -1.0f),
0202: D3DXVECTOR3( 1.0f, -1.0f, -1.0f),
0203: D3DXVECTOR3(-1.0f, -1.0f, 1.0f),
0204: D3DXVECTOR3(-1.0f, 1.0f, 1.0f),
0205: D3DXVECTOR3( 1.0f, 1.0f, 1.0f),
0206: D3DXVECTOR3( 1.0f, -1.0f, 1.0f),
0207: };
0208:
0209: WORD CubeVertList[] = {0,1,2,3, 4,5,1,0, 7,6,5,4, 3,2,6,7, 1,5,6,2, 4,0,3,7};
0210:
0211: D3DXVECTOR2 CubeUV[] = { D3DXVECTOR2(1.0f, 1.0f),
0212: D3DXVECTOR2(1.0f, 0.0f),
0213: D3DXVECTOR2(0.0f, 0.0f),
0214: D3DXVECTOR2(0.0f, 1.0f),
0215: };
0216:
0217:
0218: CubeVertex *pDstCube;
0219: lpD3DDEV->CreateVertexBuffer( NUM_VERTICES * sizeof(CubeVertex),
0220: D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC ,
0221: 0, D3DPOOL_DEFAULT,
0222: &pCubeVB );
0223:
0224:
0225: WORD k=0;
0226: pCubeVB->Lock ( 0, 0, (BYTE**)&pDstCube, D3DLOCK_NOOVERWRITE );
0227: for (DWORD i = 0; i < NUM_FACES; i++) {
0228: for (DWORD j = 0; j < NUM_VERTICES_PERFACE; j++) {
0229: pDstCube->Position = CubePosition[CubeVertList[k++]];
0230: pDstCube->Texture = CubeUV[j];
0231: pDstCube++;
0232: }
0233: }
0234: pCubeVB->Unlock ();
0235:
0236:
0237: WORD *pIndex;
0238: lpD3DDEV->CreateIndexBuffer( NUM_INDICES_PERFACE * NUM_FACES * sizeof(WORD),
0239: D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC ,
0240: D3DFMT_INDEX16, D3DPOOL_DEFAULT,
0241: &pFaceIB );
0242:
0243: pFaceIB->Lock ( 0, 0, (BYTE**)&pIndex, D3DLOCK_NOOVERWRITE );
0244: for ( WORD m = 0; m < NUM_FACES; m++) {
0245: *pIndex++ = 0 + NUM_VERTICES_PERFACE * m;
0246: *pIndex++ = 3 + NUM_VERTICES_PERFACE * m;
0247: *pIndex++ = 2 + NUM_VERTICES_PERFACE * m;
0248: *pIndex++ = 2 + NUM_VERTICES_PERFACE * m;
0249: *pIndex++ = 1 + NUM_VERTICES_PERFACE * m;
0250: *pIndex++ = 0 + NUM_VERTICES_PERFACE * m;
0251: }
0252: pFaceIB->Unlock ();
0253:
0254:
0255: D3DXCreateTextureFromFileEx(lpD3DDEV, "earth_1.bmp",0,0,0,0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,0, NULL, NULL, &pCubeTex[0]);
0256: D3DXCreateTextureFromFileEx(lpD3DDEV, "earth_2.bmp",0,0,0,0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,0, NULL, NULL, &pCubeTex[1]);
0257: D3DXCreateTextureFromFileEx(lpD3DDEV, "earth_3.bmp",0,0,0,0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,0, NULL, NULL, &pCubeTex[2]);
0258: D3DXCreateTextureFromFileEx(lpD3DDEV, "earth_0.bmp",0,0,0,0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,0, NULL, NULL, &pCubeTex[3]);
0259: D3DXCreateTextureFromFileEx(lpD3DDEV, "earth_u.bmp",0,0,0,0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,0, NULL, NULL, &pCubeTex[4]);
0260: D3DXCreateTextureFromFileEx(lpD3DDEV, "earth_d.bmp",0,0,0,0,D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,0, NULL, NULL, &pCubeTex[5]);
0261:
0262:
0263: ID3DXBuffer* pshader;
0264: hr = D3DXAssembleShaderFromFile("cube.vsh", 0,NULL,&pshader,NULL);
0265: if ( FAILED(hr) ) return hr;
0266: hr = lpD3DDEV->CreateVertexShader( dwCubeDecl, (DWORD*)pshader->GetBufferPointer(), &hCubeVertexShader, 0 );
0267: RELEASE(pshader);
0268: if ( FAILED(hr) ) return hr;
0269:
0270:
0271:
0272: if ( FAILED(LoadXFile("kuma.x", lpD3DDEV)) ) return hr;
0273:
0274:
0275: hr = D3DXAssembleShaderFromFile("vs.vsh", 0,NULL,&pshader,NULL);
0276: if ( FAILED(hr) ) return hr;
0277: hr = lpD3DDEV->CreateVertexShader( dwDecl, (DWORD*)pshader->GetBufferPointer(), &hVertexShader, 0 );
0278: RELEASE(pshader);
0279: if ( FAILED(hr) ) return hr;
0280:
0281:
0282: lpD3DDEV->SetRenderState( D3DRS_ZENABLE, TRUE);
0283: lpD3DDEV->SetVertexShaderConstant(12, D3DXVECTOR4(0.0f, 0.5f, 1.0f, -1.0f), 1);
0284:
0285:
0286: lpD3DDEV->SetVertexShaderConstant(13, D3DXVECTOR4(0.5f, 0.5f, 0.5f, 0.0f), 1);
0287: lpD3DDEV->SetVertexShaderConstant(14, D3DXVECTOR4(0.0f, 0.0f,-2.0f, 0.0f), 1);
0288:
0289: return S_OK;
0290: }
0291:
0292:
0293:
0294:
0295: void Render(LPDIRECT3DDEVICE8 lpD3DDEV)
0296: {
0297: D3DXMATRIX mWorld, mView, mProj;
0298:
0299: D3DXVECTOR3 eye, lookAt, up;
0300: eye.x = 0.0f; eye.y = 0.0f; eye.z = -2.0f;
0301: lookAt.x = 0.0f; lookAt.y = 0.0f; lookAt.z = 0.0f;
0302: up.x = 0.0f; up.y = 1.0f; up.z = 0.0f;
0303: D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0304:
0305: D3DXMatrixPerspectiveFovLH(&mProj
0306: ,60.0f*PI/180.0f
0307: ,(float)WIDTH/(float)HEIGHT
0308: ,0.01f
0309: ,100.0f
0310: );
0311:
0312:
0313:
0314:
0315: if(NULL != pCubeVB){
0316:
0317: D3DXMATRIX mat, matT;
0318: mat = mView * mProj;
0319: D3DXMatrixTranspose(&matT, &mat);
0320: lpD3DDEV->SetVertexShaderConstant(0, &matT, 4);
0321:
0322:
0323: lpD3DDEV->SetVertexShader( hCubeVertexShader );
0324:
0325: lpD3DDEV->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
0326: lpD3DDEV->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0327:
0328:
0329: lpD3DDEV->SetStreamSource(0, pCubeVB, sizeof(CubeVertex) );
0330: lpD3DDEV->SetIndices( pFaceIB, 0 );
0331: for (DWORD i= 0; i<NUM_FACES; i++) {
0332: lpD3DDEV->SetTexture(0, pCubeTex[i]);
0333: lpD3DDEV->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,
0334: 0, NUM_VERTICES, NUM_INDICES_PERFACE * i , NUM_PRIMS_PERFACE );
0335: }
0336: }
0337:
0338:
0339:
0340:
0341: if(NULL != pMeshVB){
0342: D3DXMATRIX m, m2;
0343: D3DXMatrixScaling(&mWorld, 0.2f, 0.2f, 0.2f);
0344: D3DXMatrixRotationY( &m, timeGetTime()/1000.0f );
0345: D3DXMatrixTranslation(&m2, 0, -0.7f, 0);
0346: mWorld = mWorld * m * m2;
0347:
0348: m = mWorld * mView * mProj;
0349: D3DXMatrixTranspose( &m , &m);
0350: lpD3DDEV->SetVertexShaderConstant(0,&m, 4);
0351: D3DXMatrixTranspose( &m , &mWorld);
0352: lpD3DDEV->SetVertexShaderConstant(4, &m, 4);
0353: D3DXMatrixInverse( &m, NULL, &mWorld);
0354: lpD3DDEV->SetVertexShaderConstant(8, &m, 4);
0355:
0356: lpD3DDEV->SetVertexShader(hVertexShader);
0357:
0358:
0359: lpD3DDEV->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0360: lpD3DDEV->SetIndices(pMeshIndex,0);
0361: lpD3DDEV->SetTexture(0, pEnvTexture);
0362: for(DWORD i=0;i<dwNumMaterials;i++){
0363:
0364:
0365:
0366:
0367:
0368:
0369:
0370: lpD3DDEV->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0371: pSubsetTable[i].VertexStart,
0372: pSubsetTable[i].VertexCount,
0373: pSubsetTable[i].FaceStart * 3,
0374: pSubsetTable[i].FaceCount);
0375: }
0376: }
0377: }
0378:
0379:
0380:
0381: void DeleteMeshObject(void)
0382: {
0383: DWORD i;
0384:
0385: if(pMeshVB == NULL) return;
0386:
0387: for(i=0; i<dwNumMaterials; i++){
0388: RELEASE(pMeshTextures[i]);
0389: }
0390: delete[] pMeshTextures;
0391: delete[] pMeshMaterials;
0392: delete[] pSubsetTable;
0393:
0394: RELEASE(pMeshVB);
0395: RELEASE(pMeshIndex);
0396: }
0397:
0398:
0399:
0400:
0401: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDEV)
0402: {
0403: DeleteMeshObject();
0404:
0405: if ( hVertexShader != ~0 ){
0406: lpD3DDEV->DeleteVertexShader( hVertexShader );
0407: hVertexShader = ~0;
0408: }
0409:
0410:
0411: RELEASE(pEnvTexture);
0412:
0413:
0414:
0415:
0416: RELEASE(pCubeVB);
0417: RELEASE(pFaceIB);
0418:
0419: if ( hCubeVertexShader != ~0 ){
0420: lpD3DDEV->DeleteVertexShader( hCubeVertexShader );
0421: hCubeVertexShader = ~0;
0422: }
0423: RELEASE(pCubeTex[0]);
0424: RELEASE(pCubeTex[1]);
0425: RELEASE(pCubeTex[2]);
0426: RELEASE(pCubeTex[3]);
0427: RELEASE(pCubeTex[4]);
0428: RELEASE(pCubeTex[5]);
0429: }
0430: