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: VOID MakeTexture(D3DXVECTOR4* pOut, D3DXVECTOR2 *pTexCoord, D3DXVECTOR2 *pTexelSize, LPVOID pData)
0153: {
0154: const int num = 16;
0155: const float grid_size = 1.0f/((float)num);
0156:
0157: float shade=1.0f;
0158: float dx, dy, r2;
0159:
0160: dx = pTexCoord->x/(0.5f*grid_size) - 0.0f;
0161: dy = pTexCoord->y/(0.5f*grid_size) - 0.0f;
0162: while( 1.0f<dx) dx -= 2.0f;
0163: while(dx<-1.0f ) dx += 2.0f;
0164: while( 1.0f<dy) dy -= 2.0f;
0165: while(dy<-1.0f ) dy += 2.0f;
0166: r2 = 1.0f-2*(dx*dx+dy*dy);
0167: if(0.0f< r2)shade -= (float)sqrt(r2);
0168:
0169: dx = pTexCoord->x/(0.5f*grid_size) - 1.0f;
0170: dy = pTexCoord->y/(0.5f*grid_size) - 1.0f;
0171: while( 1.0f<dx) dx -= 2.0f;
0172: while(dx<-1.0f ) dx += 2.0f;
0173: while( 1.0f<dy) dy -= 2.0f;
0174: while(dy<-1.0f ) dy += 2.0f;
0175: r2 = 1.0f-2*(dx*dx+dy*dy);
0176: if(0.0f< r2)shade -= (float)sqrt(r2);
0177:
0178: if(shade < 0.0f)shade = 0.0f;
0179: if(1.0f < shade)shade = 1.0f;
0180:
0181: pOut->x = shade;
0182: pOut->y = shade;
0183: pOut->z = shade;
0184: pOut->w = 1.0f;
0185: }
0186:
0187:
0188:
0189:
0190: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDEV)
0191: {
0192: HRESULT hr;
0193:
0194: hr = LoadXFile("nsx.x", lpD3DDEV);
0195: if ( FAILED(hr) ) return hr;
0196:
0197:
0198: D3DXCreateTextureFromFileEx(lpD3DDEV, "toon.bmp",0,0,0,0,D3DFMT_A8R8G8B8,
0199: D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0200: 0, NULL, NULL, &pToonTexture);
0201:
0202: if( FAILED(hr = lpD3DDEV->CreateTexture(256, 256, 1 ,D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pToneTexture))) return hr;
0203: if( FAILED(hr = D3DXFillTexture(pToneTexture, MakeTexture, NULL))) return hr;
0204:
0205:
0206: LPD3DXBUFFER pshader;
0207: hr = D3DXAssembleShaderFromFile("vs.vsh", 0,NULL,&pshader,NULL);
0208: if ( FAILED(hr) ) return hr;
0209: hr = lpD3DDEV->CreateVertexShader( dwDecl, (DWORD*)pshader->GetBufferPointer(), &hVertexShader, 0 );
0210: RELEASE(pshader);
0211: if ( FAILED(hr) ) return hr;
0212:
0213:
0214: hr = D3DXAssembleShaderFromFile("ps.psh", 0,NULL, &pshader, NULL);
0215: if ( FAILED(hr) ) return hr;
0216: hr = lpD3DDEV->CreatePixelShader( (DWORD*)pshader->GetBufferPointer(), &hPixelShader);
0217: RELEASE(pshader);
0218: if ( FAILED(hr) ) return hr;
0219:
0220:
0221:
0222:
0223: lpD3DDEV->SetRenderState( D3DRS_ZENABLE, TRUE);
0224: lpD3DDEV->SetRenderState( D3DRS_AMBIENT, 0xff808080);
0225:
0226: lpD3DDEV->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_MODULATE);
0227: lpD3DDEV->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0228: lpD3DDEV->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE);
0229: lpD3DDEV->SetTextureStageState(0,D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0230: lpD3DDEV->SetTextureStageState(0,D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0231: lpD3DDEV->SetTextureStageState(0,D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0232:
0233: lpD3DDEV->SetRenderState(D3DRS_WRAP1, D3DWRAP_U | D3DWRAP_V);
0234: lpD3DDEV->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_MODULATE);
0235: lpD3DDEV->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_TEXTURE);
0236: lpD3DDEV->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_CURRENT);
0237: lpD3DDEV->SetTextureStageState(1,D3DTSS_MAGFILTER,D3DTEXF_LINEAR);
0238: lpD3DDEV->SetTextureStageState(1,D3DTSS_MINFILTER,D3DTEXF_LINEAR);
0239: lpD3DDEV->SetTextureStageState(1,D3DTSS_ADDRESSU, D3DTADDRESS_WRAP );
0240: lpD3DDEV->SetTextureStageState(1,D3DTSS_ADDRESSV, D3DTADDRESS_WRAP );
0241:
0242: return S_OK;
0243: }
0244:
0245:
0246:
0247:
0248: void Render(LPDIRECT3DDEVICE8 lpD3DDEV)
0249: {
0250: if(NULL == pMeshVB) return;
0251:
0252: D3DXMATRIX mWorld, mView, mProj;
0253:
0254: D3DXMatrixRotationY( &mWorld, timeGetTime()/1000.0f );
0255:
0256:
0257: D3DXVECTOR3 eye, lookAt, up;
0258: eye.x = 0.0f; eye.y = 10.00f; eye.z = 28.0f;
0259: lookAt.x = 0.0f; lookAt.y = 0.0f; lookAt.z = 0.0f;
0260: up.x = 0.0f; up.y = 1.0f; up.z = 0.0f;
0261: D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0262:
0263: D3DXMatrixPerspectiveFovLH(&mProj
0264: ,60.0f*PI/180.0f
0265: ,(float)WIDTH/(float)HEIGHT
0266: ,0.01f
0267: ,100.0f
0268: );
0269: D3DXMATRIX m = mWorld * mView * mProj;
0270: D3DXMatrixTranspose( &m , &m);
0271: lpD3DDEV->SetVertexShaderConstant(0,&m, 4);
0272: D3DXMatrixTranspose( &m , &mWorld);
0273: lpD3DDEV->SetVertexShaderConstant(4, &m, 4);
0274: D3DXMatrixInverse( &m, NULL, &mWorld);
0275: lpD3DDEV->SetVertexShaderConstant(8, &m, 4);
0276:
0277: lpD3DDEV->SetVertexShaderConstant(12, D3DXVECTOR4(0.0f, 0.5f, 1.0f, 3.0f), 1);
0278:
0279: D3DXVECTOR4 lightDir(1.0f, 1.0f, 0.5f, 0.0f);
0280: D3DXVec4Normalize(&lightDir, &lightDir);
0281: D3DXMatrixInverse( &m, NULL, &mWorld);
0282: D3DXVec4Transform(&lightDir, &lightDir, &m);
0283: lightDir[3] = 0.1f;
0284: lpD3DDEV->SetVertexShaderConstant(13, &lightDir, 1);
0285:
0286: lpD3DDEV->SetVertexShader(hVertexShader);
0287: lpD3DDEV->SetPixelShader ( hPixelShader);
0288: lpD3DDEV->SetTexture(0,pToonTexture);
0289: lpD3DDEV->SetTexture(1,pToneTexture);
0290:
0291:
0292: lpD3DDEV->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0293: lpD3DDEV->SetIndices(pMeshIndex,0);
0294:
0295: for(DWORD i=0;i<dwNumMaterials;i++){
0296:
0297: D3DXVECTOR4 vl;
0298: vl.x = pMeshMaterials[i].Diffuse.r;
0299: vl.y = pMeshMaterials[i].Diffuse.g;
0300: vl.z = pMeshMaterials[i].Diffuse.b;
0301: lpD3DDEV->SetVertexShaderConstant(15,&vl,1);
0302:
0303: lpD3DDEV->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0304: pSubsetTable[i].VertexStart,
0305: pSubsetTable[i].VertexCount,
0306: pSubsetTable[i].FaceStart * 3,
0307: pSubsetTable[i].FaceCount);
0308: }
0309:
0310:
0311: {
0312: struct TLVERTEX
0313: {
0314: float x,y,z,rhw;
0315: D3DCOLOR color;
0316: float tu,tv;
0317: };
0318: #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
0319:
0320: lpD3DDEV->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0321: lpD3DDEV->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0322: lpD3DDEV->SetTextureStageState(1,D3DTSS_COLOROP, D3DTOP_DISABLE );
0323: TLVERTEX Vertex[4] = {
0324:
0325: { 0, 0,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0, 0,},
0326: { 64, 0,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0.25f, 0,},
0327: { 64, 64,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0.25f, 0.25f,},
0328: { 0, 64,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0, 0.25f,},
0329: };
0330: lpD3DDEV->SetPixelShader (0);
0331: lpD3DDEV->SetVertexShader( FVF_TLVERTEX );
0332: lpD3DDEV->SetTexture( 0, pToneTexture );
0333: lpD3DDEV->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) );
0334: }
0335: lpD3DDEV->SetTexture(0, NULL);
0336: }
0337:
0338:
0339:
0340: void DeleteMeshObject(void)
0341: {
0342: DWORD i;
0343:
0344: if(pMeshVB == NULL) return;
0345:
0346: for(i=0; i<dwNumMaterials; i++){
0347: RELEASE(pMeshTextures[i]);
0348: }
0349: delete[] pMeshTextures;
0350: delete[] pMeshMaterials;
0351: delete[] pSubsetTable;
0352:
0353: RELEASE(pMeshVB);
0354: RELEASE(pMeshIndex);
0355: }
0356:
0357:
0358:
0359:
0360: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDEV)
0361: {
0362: DeleteMeshObject();
0363:
0364: if ( hPixelShader != ~0 ){
0365: lpD3DDEV->DeleteVertexShader( hPixelShader );
0366: hPixelShader = ~0;
0367: }
0368: if ( hVertexShader != ~0 ){
0369: lpD3DDEV->DeleteVertexShader( hVertexShader );
0370: hVertexShader = ~0;
0371: }
0372:
0373: RELEASE(pToneTexture);
0374: RELEASE(pToonTexture);
0375: }
0376: