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: DWORD hVertexShader=~0;
0025:
0026: LPDIRECT3DSURFACE8 pBackbuffer = NULL;
0027:
0028: LPDIRECT3DTEXTURE8 pTexture[2];
0029: LPDIRECT3DSURFACE8 pTextureSurface[2];
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 | D3DFVF_TEX1)
0053:
0054: 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: pDest->tu0 = pSrc->tu0;
0119: pDest->tu0 = pSrc->tu0;
0120:
0121: FLOAT radius = sqrtf( pSrc->x*pSrc->x + pSrc->y*pSrc->y + pSrc->z*pSrc->z );
0122: if (MeshRadius < radius) MeshRadius = radius;
0123:
0124: pSrc += 1;
0125: pDest += 1;
0126: }
0127: pVB->Unlock();
0128: pVB->Release();
0129: pMeshVB->Unlock();
0130:
0131:
0132: pMesh->GetIndexBuffer(&pSrcIndex);
0133: pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0134: pMeshIndex->Lock(0,0,(BYTE**)&pIDest,0);
0135: CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0136: pSrcIndex->Unlock();
0137: pMeshIndex->Unlock();
0138: pSrcIndex->Release();
0139:
0140:
0141: D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0142: pMeshTextures = new LPDIRECT3DTEXTURE8[dwNumMaterials];
0143: pMeshMaterials = new D3DMATERIAL8[dwNumMaterials];
0144:
0145: for(i = 0; i < dwNumMaterials; i++){
0146: pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
0147: pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
0148: hr = D3DXCreateTextureFromFile( lpD3DDev,
0149: d3dxMaterials[i].pTextureFilename,
0150: &pMeshTextures[i] );
0151: if(FAILED(hr)) pMeshTextures[i] = NULL;
0152: }
0153: RELEASE(pD3DXMtrlBuffer);
0154:
0155: RELEASE(pMesh);
0156:
0157: return S_OK;
0158: }
0159:
0160:
0161:
0162:
0163: HRESULT LoadVertexShader(char* filename, LPDIRECT3DDEVICE8 lpD3DDev, DWORD *phVertexShader, const DWORD *dwDecl)
0164: {
0165: HRESULT hr;
0166: ID3DXBuffer *pshader;
0167:
0168: if ( FAILED(hr = D3DXAssembleShaderFromFile(filename, 0,NULL,&pshader,NULL)) ) return hr;
0169:
0170: hr = lpD3DDev->CreateVertexShader( dwDecl, (DWORD*)pshader->GetBufferPointer(), phVertexShader, 0 );
0171: RELEASE(pshader);
0172: if ( FAILED(hr) ) return hr;
0173:
0174: return S_OK;
0175: }
0176:
0177:
0178:
0179:
0180: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0181: {
0182: HRESULT hr;
0183:
0184:
0185: if ( FAILED(hr = LoadXFile("nsx.x", lpD3DDev)) ) return hr;
0186:
0187:
0188: if ( FAILED(hr = LoadVertexShader("vs.vsh", lpD3DDev, &hVertexShader, dwDecl)) ) return hr;
0189:
0190:
0191: if ( FAILED(hr = lpD3DDev->GetRenderTarget(&pBackbuffer))) return hr;
0192: D3DSURFACE_DESC Desc;
0193: if ( FAILED(hr = pBackbuffer->GetDesc( &Desc ))) return hr;
0194:
0195: LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0196: for( int i = 0; i < 2; i++ ){
0197: if( FAILED(hr = lpD3DDev->CreateTexture(WIDTH,HEIGHT, 1 ,D3DUSAGE_RENDERTARGET, Desc.Format, D3DPOOL_DEFAULT, &pTexture[i]))) return hr;
0198: if( FAILED(hr = pTexture[i]->GetSurfaceLevel(0,&pTextureSurface[i]))) return hr;
0199: if( FAILED(hr = lpD3DDev->GetDepthStencilSurface( &lpZbuffer ))) return hr;
0200: if( FAILED(hr = lpD3DDev->SetRenderTarget(pTextureSurface[i], lpZbuffer ))) return hr;
0201:
0202:
0203: lpD3DDev->BeginScene();
0204: lpD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0205: D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
0206: lpD3DDev->EndScene();
0207: }
0208:
0209: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0210:
0211: return S_OK;
0212: }
0213:
0214: struct TLVERTEX
0215: {
0216: float x,y,z,rhw;
0217: D3DCOLOR color;
0218: float tu,tv;
0219: };
0220: #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
0221:
0222:
0223:
0224:
0225:
0226:
0227: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev)
0228: {
0229: LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0230: static int cnt = 0;
0231: ++cnt;
0232:
0233: lpD3DDev->GetDepthStencilSurface( &lpZbuffer );
0234: lpD3DDev->SetRenderTarget(pTextureSurface[cnt & 1], lpZbuffer );
0235:
0236: lpD3DDev->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,32,32), 1.0f, 0 );
0237:
0238: D3DXMATRIX mWorld, mView, mProj, m;
0239:
0240: D3DXMatrixTranslation(&m, MeshRadius, 0,0);
0241: D3DXMatrixRotationY( &mWorld, timeGetTime()/300.0f );
0242: mWorld = m * mWorld;
0243:
0244:
0245: D3DXVECTOR3 eye = D3DXVECTOR3(0.0f,MeshRadius,2.5f*MeshRadius);
0246: D3DXVECTOR3 lookAt = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
0247: D3DXVECTOR3 up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
0248:
0249: D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0250: D3DXMatrixPerspectiveFovLH(&mProj
0251: ,60.0f*PI/180.0f
0252: ,(float)WIDTH/(float)HEIGHT
0253: ,0.01f,100.0f
0254: );
0255:
0256: m = mWorld * mView * mProj;
0257: D3DXMatrixTranspose( &m , &m);
0258: lpD3DDev->SetVertexShaderConstant(0,&m, 4);
0259:
0260: D3DXVECTOR4 lightDir(1.0f, 1.0f, 0.5f, 0.0f);
0261: D3DXVec4Normalize(&lightDir, &lightDir);
0262: D3DXMatrixInverse( &m, NULL, &mWorld);
0263: D3DXVec4Transform(&lightDir, &lightDir, &m);
0264: lightDir[3] = 0.3f;
0265: lpD3DDev->SetVertexShaderConstant(13, &lightDir, 1);
0266:
0267:
0268: lpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
0269: lpD3DDev->SetVertexShader(hVertexShader);
0270: lpD3DDev->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0271: lpD3DDev->SetIndices(pMeshIndex,0);
0272: for(DWORD i=0;i<dwNumMaterials;i++){
0273:
0274: D3DXVECTOR4 vl;
0275: vl.x = pMeshMaterials[i].Diffuse.r;
0276: vl.y = pMeshMaterials[i].Diffuse.g;
0277: vl.z = pMeshMaterials[i].Diffuse.b;
0278: lpD3DDev->SetVertexShaderConstant(14, &vl, 1);
0279:
0280: lpD3DDev->SetTexture(0,pMeshTextures[i]);
0281: lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0282: pSubsetTable[i].VertexStart,
0283: pSubsetTable[i].VertexCount,
0284: pSubsetTable[i].FaceStart * 3,
0285: pSubsetTable[i].FaceCount);
0286: }
0287:
0288:
0289: lpD3DDev->SetRenderState( D3DRS_ZENABLE, FALSE );
0290: lpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
0291: lpD3DDev->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
0292: lpD3DDev->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
0293: lpD3DDev->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
0294:
0295: lpD3DDev->SetTransform( D3DTS_VIEW, &mView );
0296: lpD3DDev->SetTransform( D3DTS_PROJECTION, &mProj );
0297:
0298: TLVERTEX Vertex[4] = {
0299:
0300: { 0, 0,0,1,D3DCOLOR_ARGB( 200, 255, 255, 255 ),0,0,},
0301: {512, 0,0,1,D3DCOLOR_ARGB( 200, 255, 255, 255 ),1,0,},
0302: { 0,512,0,1,D3DCOLOR_ARGB( 200, 255, 255, 255 ),0,1,},
0303: {512,512,0,1,D3DCOLOR_ARGB( 200, 255, 255, 255 ),1,1,},
0304: };
0305: lpD3DDev->SetTexture( 0, pTexture[(cnt + 1)&1] );
0306: lpD3DDev->SetVertexShader( FVF_TLVERTEX );
0307: lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, Vertex, sizeof( TLVERTEX ) );
0308:
0309:
0310: lpD3DDev->GetDepthStencilSurface( &lpZbuffer );
0311: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0312: lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE );
0313: lpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
0314:
0315:
0316: {
0317: TLVERTEX Vertex[4] = {
0318:
0319: { 0, 0,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0, 0,},
0320: {512, 0,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 1, 0,},
0321: {512,512,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 1, 1,},
0322: { 0,512,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0, 1,},
0323: };
0324: lpD3DDev->SetTexture( 0, pTexture[cnt&1] );
0325: lpD3DDev->SetVertexShader( FVF_TLVERTEX );
0326: lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) );
0327: }
0328: }
0329:
0330:
0331:
0332: void DeleteMeshObject(void)
0333: {
0334: DWORD i;
0335:
0336: if(pMeshVB == NULL) return;
0337:
0338: for(i=0; i<dwNumMaterials; i++){
0339: RELEASE(pMeshTextures[i]);
0340: }
0341: delete[] pMeshTextures;
0342: delete[] pMeshMaterials;
0343: delete[] pSubsetTable;
0344:
0345: RELEASE(pMeshVB);
0346: RELEASE(pMeshIndex);
0347: }
0348:
0349:
0350:
0351:
0352: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev)
0353: {
0354: DeleteMeshObject();
0355:
0356: if ( hVertexShader != ~0 ){
0357: lpD3DDev->DeleteVertexShader( hVertexShader );
0358: hVertexShader = ~0;
0359: }
0360:
0361: for(int i = 0; i < 2; i++){
0362: RELEASE(pTexture[i]);
0363: RELEASE(pTextureSurface[i]);
0364: }
0365: RELEASE(pBackbuffer);
0366: }
0367: