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