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);
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: LPDIRECT3DSURFACE8 pBackbuffer = NULL;
0032:
0033: LPDIRECT3DTEXTURE8 pTexture;
0034: LPDIRECT3DSURFACE8 pTextureSurface;
0035:
0036: FLOAT MeshRadius;
0037:
0038:
0039:
0040:
0041:
0042:
0043:
0044:
0045: typedef struct {
0046: float x,y,z;
0047: float nx,ny,nz;
0048: float tu0,tv0;
0049: }D3DVERTEX;
0050: #define D3DFVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0051:
0052: typedef struct {
0053: float x,y,z;
0054: float nx,ny,nz;
0055: float tu0,tv0;
0056: }D3D_CUSTOMVERTEX;
0057: #define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
0058:
0059: static DWORD dwDecl[] = {
0060: D3DVSD_STREAM(0),
0061: D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),
0062: D3DVSD_REG(D3DVSDE_NORMAL, D3DVSDT_FLOAT3 ),
0063: D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ),
0064: D3DVSD_END()
0065: };
0066:
0067:
0068:
0069:
0070:
0071:
0072:
0073: VOID MakeCookTorranceTexture(D3DXVECTOR4* pOut, D3DXVECTOR2 *pTexCoord, D3DXVECTOR2 *pTexelSize, LPVOID pData)
0074: {
0075: float NH = pTexCoord->x;
0076: float NL = pTexCoord->y;
0077:
0078:
0079: float n = 1.5f;
0080: float c = NL;
0081: float g = (float)sqrt(n*n+c*c-1.0f);
0082: float F = 0.5*((g-c)*(g-c)/(g+c)*(g+c))*(1.0f+((c*(g+c)-1)*(c*(g+c)-1))/((c*(g-c)+1)*(c*(g-c)+1)));
0083:
0084:
0085: float m = 0.3f;
0086: float D = (float)(exp(-(1.0f-NH*NH)/(m*m*NH*NH))/(4*m*m*NH*NH*NH*NH));
0087:
0088:
0089: float G = min(1.0f, 2.0f*NH);
0090:
0091: float rho = 1.0f*F*D*G/((NL));
0092: rho = min(1.0f, rho);
0093: rho = max(rho, 0.0f);
0094:
0095: pOut->x = rho;
0096: pOut->y = rho;
0097: pOut->z = rho;
0098: pOut->w = 1.0f;
0099: }
0100:
0101:
0102:
0103:
0104: HRESULT LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDev)
0105: {
0106: LPD3DXMESH pMesh, pMeshOpt;
0107: LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
0108: DWORD i;
0109: HRESULT hr;
0110:
0111: hr = D3DXLoadMeshFromX(filename, D3DXMESH_MANAGED,
0112: lpD3DDev, NULL,
0113: &pD3DXMtrlBuffer, &dwNumMaterials,
0114: &pMesh);
0115: if(FAILED(hr)) return E_FAIL;
0116:
0117:
0118: pMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshOpt);
0119: RELEASE(pMesh);
0120:
0121:
0122: pMeshOpt->GetAttributeTable(NULL,&dwNumMaterials);
0123: pSubsetTable = new D3DXATTRIBUTERANGE[dwNumMaterials];
0124: pMeshOpt->GetAttributeTable(pSubsetTable, &dwNumMaterials);
0125:
0126:
0127: hr = pMeshOpt->CloneMeshFVF(pMeshOpt->GetOptions(), D3DFVF_VERTEX, lpD3DDev, &pMesh);
0128: if(FAILED(hr)) return E_FAIL;
0129: RELEASE(pMeshOpt);
0130: D3DXComputeNormals(pMesh, NULL);
0131:
0132:
0133: D3DVERTEX* pSrc;
0134: D3D_CUSTOMVERTEX* pDest;
0135: LPDIRECT3DINDEXBUFFER8 pSrcIndex;
0136: WORD* pISrc;
0137: WORD* pIDest;
0138:
0139: DWORD nMeshVertices = pMesh->GetNumVertices();
0140: DWORD nMeshFaces = pMesh->GetNumFaces();
0141: lpD3DDev->CreateVertexBuffer(nMeshVertices * sizeof(D3D_CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pMeshVB);
0142: lpD3DDev->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&pMeshIndex);
0143:
0144: LPDIRECT3DVERTEXBUFFER8 pVB;
0145: pMesh->GetVertexBuffer(&pVB);
0146: pVB->Lock(0,0,(BYTE**)&pSrc,0);
0147: pMeshVB->Lock(0,0,(BYTE**)&pDest,0);
0148: MeshRadius = 0.0f;
0149: for(i=0;i<nMeshVertices;i++){
0150: pDest->x = pSrc->x;
0151: pDest->y = pSrc->y;
0152: pDest->z = pSrc->z;
0153: pDest->nx = pSrc->nx;
0154: pDest->ny = pSrc->ny;
0155: pDest->nz = pSrc->nz;
0156: pDest->tu0 = pSrc->tu0;
0157: pDest->tu0 = pSrc->tu0;
0158:
0159: FLOAT radius = sqrtf( pSrc->x*pSrc->x + pSrc->y*pSrc->y + pSrc->z*pSrc->z );
0160: if (MeshRadius < radius) MeshRadius = radius;
0161:
0162: pSrc += 1;
0163: pDest += 1;
0164: }
0165: pVB->Unlock();
0166: pVB->Release();
0167: pMeshVB->Unlock();
0168:
0169:
0170: pMesh->GetIndexBuffer(&pSrcIndex);
0171: pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0172: pMeshIndex->Lock(0,0,(BYTE**)&pIDest,0);
0173: CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0174: pSrcIndex->Unlock();
0175: pMeshIndex->Unlock();
0176: pSrcIndex->Release();
0177:
0178:
0179: D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0180: pMeshTextures = new LPDIRECT3DTEXTURE8[dwNumMaterials];
0181: pMeshMaterials = new D3DMATERIAL8[dwNumMaterials];
0182:
0183: for(i = 0; i < dwNumMaterials; i++){
0184: pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
0185: pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
0186: hr = D3DXCreateTextureFromFile( lpD3DDev,
0187: d3dxMaterials[i].pTextureFilename,
0188: &pMeshTextures[i] );
0189: if(FAILED(hr)) pMeshTextures[i] = NULL;
0190: }
0191: RELEASE(pD3DXMtrlBuffer);
0192:
0193: RELEASE(pMesh);
0194:
0195: return S_OK;
0196: }
0197:
0198:
0199:
0200:
0201: HRESULT LoadVertexShader(char* filename, LPDIRECT3DDEVICE8 lpD3DDev, DWORD *phVertexShader, const DWORD *dwDecl)
0202: {
0203: HRESULT hr;
0204: ID3DXBuffer *pshader;
0205:
0206: if ( FAILED(hr = D3DXAssembleShaderFromFile(filename, 0,NULL,&pshader,NULL)) ) return hr;
0207:
0208: hr = lpD3DDev->CreateVertexShader( dwDecl, (DWORD*)pshader->GetBufferPointer(), phVertexShader, 0 );
0209: RELEASE(pshader);
0210: if ( FAILED(hr) ) return hr;
0211:
0212: return S_OK;
0213: }
0214:
0215:
0216:
0217:
0218: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0219: {
0220: HRESULT hr;
0221:
0222:
0223:
0224: if ( FAILED(hr = LoadXFile("nsx.x", lpD3DDev)) ) return hr;
0225:
0226:
0227: if ( FAILED(hr = LoadVertexShader("vs.vsh", lpD3DDev, &hVertexShader, dwDecl)) ) return hr;
0228:
0229:
0230: if ( FAILED(hr = lpD3DDev->GetRenderTarget(&pBackbuffer))) return hr;
0231: D3DSURFACE_DESC Desc;
0232: if ( FAILED(hr = pBackbuffer->GetDesc( &Desc ))) return hr;
0233:
0234:
0235: if( FAILED(hr = lpD3DDev->CreateTexture(512, 512, 1 ,D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pTexture))) return hr;
0236: if( FAILED(hr = D3DXFillTexture(pTexture, MakeCookTorranceTexture, NULL))) return hr;
0237:
0238: InitBg(lpD3DDev);
0239:
0240: lpD3DDev->SetRenderState(D3DRS_LIGHTING, FALSE);
0241:
0242: return S_OK;
0243: }
0244:
0245: struct TLVERTEX
0246: {
0247: float x,y,z,rhw;
0248: D3DCOLOR color;
0249: float tu,tv;
0250: };
0251: #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1)
0252:
0253:
0254:
0255:
0256:
0257:
0258: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev)
0259: {
0260: static int cnt = 0;
0261: ++cnt;
0262:
0263: D3DXMATRIX mWorld, mView, mProj, m;
0264:
0265: D3DXMatrixTranslation(&m, MeshRadius, 0,0);
0266: D3DXMatrixRotationY( &mWorld, timeGetTime()/300.0f );
0267: mWorld = m * mWorld;
0268:
0269:
0270: D3DXVECTOR3 eye = D3DXVECTOR3(0.0f,MeshRadius,2.5f*MeshRadius);
0271: D3DXVECTOR3 lookAt = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
0272: D3DXVECTOR3 up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
0273:
0274: D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0275: D3DXMatrixPerspectiveFovLH(&mProj
0276: ,60.0f*PI/180.0f
0277: ,(float)WIDTH/(float)HEIGHT
0278: ,0.01f,100.0f
0279: );
0280:
0281:
0282: lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_MODULATE);
0283: lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0284: lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE);
0285: lpD3DDev->SetTransform(D3DTS_VIEW, &mView);
0286: lpD3DDev->SetTransform(D3DTS_PROJECTION, &mProj);
0287: DrawBg(lpD3DDev);
0288:
0289:
0290: m = mWorld * mView * mProj;
0291: D3DXMatrixTranspose( &m , &m);
0292: lpD3DDev->SetVertexShaderConstant(0,&m, 4);
0293:
0294: D3DXMatrixInverse( &m, NULL, &mWorld);
0295:
0296:
0297: D3DXVECTOR4 lightDir(0.5f, 1.0f, -0.5f, 0.0f);
0298: D3DXVec4Normalize(&lightDir, &lightDir);
0299: D3DXVec4Transform(&lightDir, &lightDir, &m);
0300: lightDir[3] = 0.3f;
0301: lpD3DDev->SetVertexShaderConstant(13, &lightDir, 1);
0302:
0303: D3DXVECTOR4 view(0.0f,MeshRadius, 2.5f*MeshRadius, 0.0f);
0304: D3DXVec4Transform(&view, &view, &m);
0305: lpD3DDev->SetVertexShaderConstant(15, &view, 1);
0306:
0307: lpD3DDev->SetVertexShader(hVertexShader);
0308: lpD3DDev->SetTexture( 0, pTexture );
0309: lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0310: lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0311: lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_ADD);
0312: lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0313: lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE);
0314:
0315:
0316: lpD3DDev->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0317: lpD3DDev->SetIndices(pMeshIndex,0);
0318: for(DWORD i=0;i<dwNumMaterials;i++){
0319:
0320: D3DXVECTOR4 vl( pMeshMaterials[i].Diffuse.r,
0321: pMeshMaterials[i].Diffuse.g,
0322: pMeshMaterials[i].Diffuse.b,
0323: 0.0f);
0324: lpD3DDev->SetVertexShaderConstant(14, &vl, 1);
0325: lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
0326: pSubsetTable[i].VertexStart,
0327: pSubsetTable[i].VertexCount,
0328: pSubsetTable[i].FaceStart * 3,
0329: pSubsetTable[i].FaceCount);
0330: }
0331:
0332: #if 1
0333:
0334: {
0335: lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0336: lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
0337: TLVERTEX Vertex[4] = {
0338:
0339: { 0, 0,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0, 0,},
0340: { 64, 0,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 1, 0,},
0341: { 64, 64,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 1, 1,},
0342: { 0, 64,0, 1, D3DCOLOR_ARGB( 255, 255, 255, 255 ), 0, 1,},
0343: };
0344: lpD3DDev->SetTexture( 0, pTexture );
0345: lpD3DDev->SetVertexShader( FVF_TLVERTEX );
0346: lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) );
0347: }
0348: #endif
0349: }
0350:
0351:
0352:
0353: void DeleteMeshObject(void)
0354: {
0355: DWORD i;
0356:
0357: if(pMeshVB == NULL) return;
0358:
0359: for(i=0; i<dwNumMaterials; i++){
0360: RELEASE(pMeshTextures[i]);
0361: }
0362: delete[] pMeshTextures;
0363: delete[] pMeshMaterials;
0364: delete[] pSubsetTable;
0365:
0366: RELEASE(pMeshVB);
0367: RELEASE(pMeshIndex);
0368: }
0369:
0370:
0371:
0372:
0373: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev)
0374: {
0375: CleanBg(lpD3DDev);
0376:
0377: DeleteMeshObject();
0378:
0379: if ( hVertexShader != ~0 ){
0380: lpD3DDev->DeleteVertexShader( hVertexShader );
0381: hVertexShader = ~0;
0382: }
0383:
0384: RELEASE(pTexture);
0385: RELEASE(pTextureSurface);
0386:
0387: RELEASE(pBackbuffer);
0388: }
0389: