0001: // ----------------------------------------------------------------------------
0002: //
0003: // draw.cpp - Rendering
0004: // 
0005: // Copyright (c) 2002 IMAGIRE Takashi (imagire@gmail.com)
0006: // All Rights Reserved.
0007: //
0008: // ----------------------------------------------------------------------------
0009: #define STRICT
0010: 
0011: #include <windows.h>
0012: #include "main.h"
0013: #include "draw.h"
0014: #include "load.h"
0015: 
0016: #include "Cg/cgD3D.h"
0017: 
0018: // Cg Env
0019: cgDirect3D cg;
0020: cgContextContainer * pContextContainer = 0;
0021: 
0022: // Ordinal shader
0023: cgProgramContainer *pVertexProgramContainer = 0;
0024: cgBindIter * vertex_mat_iter = 0;
0025: cgProgramContainer  *pPixelProgramContainer = 0;
0026: cgBindIter * tex0_iter = 0;
0027: cgBindIter * tex1_iter = 0;
0028: 
0029: // Burn
0030: cgProgramContainer *pBurnVC = 0;
0031: cgProgramContainer *pBurnPC = 0;
0032: cgBindIter * BurnTex0_iter = 0;
0033: cgBindIter * BurnTex1_iter = 0;
0034: cgBindIter * BurnTex2_iter = 0;
0035: 
0036: // Black spot
0037: cgProgramContainer *pBlackVC = 0;
0038: 
0039: CMyMesh mesh;                       // ground
0040: CMyView view;                       // camera
0041: 
0042: D3DXMATRIX gProj;                   // Projectio matrix
0043: 
0044: LPDIRECT3DSURFACE8      pBackbuffer = NULL;
0045: 
0046: // catmap
0047: LPDIRECT3DTEXTURE8      pCatTexture[2]={NULL,NULL};
0048: LPDIRECT3DSURFACE8      pCatTextureSurface[2]={NULL,NULL};
0049: LPDIRECT3DTEXTURE8      pCatSeedTexture=NULL;
0050: 
0051: // envmap
0052: LPDIRECT3DTEXTURE8      pEnvTexture=NULL;
0053: LPDIRECT3DSURFACE8      pEnvTextureSurface=NULL;
0054: 
0055: // Result of the Fire
0056: LPDIRECT3DTEXTURE8      pFireTexture[2]={NULL,NULL};
0057: LPDIRECT3DSURFACE8      pFireTextureSurface[2]={NULL,NULL};
0058: LPDIRECT3DTEXTURE8      pBurnTexture=NULL;
0059: 
0060: // Black spot
0061: LPDIRECT3DTEXTURE8      pBlackTexture=NULL;
0062: LPDIRECT3DSURFACE8      pBlackTextureSurface=NULL;
0063: 
0064: 
0065: // ----------------------------------------------------------------------------
0066: // Vertex format
0067: // ----------------------------------------------------------------------------
0068: struct TLVERTEX
0069: {
0070:     float x,y,z,rhw;
0071:     float tu,tv;
0072: };
0073: #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)
0074: 
0075: // ----------------------------------------------------------------------------
0076: void InitBg(LPDIRECT3DDEVICE8 lpD3DDev);
0077: void DrawBg(LPDIRECT3DDEVICE8 lpD3DDev, D3DXMATRIX &mVP, bool texture);
0078: void CleanBg(LPDIRECT3DDEVICE8 lpD3DDev);
0079: 
0080: 
0081: //-----------------------------------------------------------------------------
0082: // Name: InitRender()
0083: //-----------------------------------------------------------------------------
0084: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0085: {
0086:     HRESULT hr;
0087:     DWORD i;
0088: 
0089:     cgVertexDefinition vertex_attributes[] = {
0090:         {D3DVSDT_FLOAT4, "position",  0},
0091:         {D3DVSDT_FLOAT2, "texcoord0", 0},
0092:         CGVERTEXDEFINITIONEND
0093:     };
0094: 
0095:     // ==================================================
0096:     // Initialization of the sky
0097:     // ==================================================
0098:     InitBg(lpD3DDev);
0099:     
0100:     // ==================================================
0101:     // read the ground mesh
0102:     // ==================================================
0103:     mesh.Load(lpD3DDev, "map.x");
0104: 
0105:     // ==================================================
0106:     // Initializatioon of the Cg
0107:     // ==================================================
0108:     cg.AddFilePath("..");
0109:     pContextContainer = cg.CreateContextContainer(lpD3DDev);
0110: 
0111:     // ==================================================
0112:     // Almost fixed function
0113:     // ==================================================
0114:     pVertexProgramContainer = pContextContainer->LoadCGProgramFromFile(
0115:         "vs.cg", "Vertex Shader", cgDX8VertexProfile, vertex_attributes);
0116: 
0117:     if (pVertexProgramContainer == NULL) {// error
0118:         const char * listing = pContextContainer->GetLastListing();
0119:         if (listing == 0) listing = "Could not find cgc.exe.";
0120:         cg.NotePad("頂点シェーダープログラムの生成に失敗しました\n\n", listing);
0121:         exit(1);    // end
0122:     }
0123:     vertex_mat_iter = pVertexProgramContainer->GetParameterBindByName("worldviewproj_matrix");
0124: 
0125:     pPixelProgramContainer = pContextContainer->LoadCGProgramFromFile(
0126:                                 "ps.cg", "test", cgDX8PixelProfile);
0127:     if (NULL == pPixelProgramContainer) { // error
0128:         const char * error_text = pContextContainer->GetLastListing();
0129:         cg.NotePad("ピクセルシェーダープログラムの生成に失敗しました\n\n\n", error_text);
0130:         exit(1);    // end
0131:     }
0132:     tex0_iter = pPixelProgramContainer->GetTextureBindByName("tex0");
0133:     tex1_iter = pPixelProgramContainer->GetTextureBindByName("tex1");
0134:     
0135:     // ==================================================
0136:     // This program creates the fire effect
0137:     // ==================================================
0138:     pBurnVC = pContextContainer->LoadCGProgramFromFile(
0139:         "BurnV.cg", "Vertex Shader", cgDX8VertexProfile, vertex_attributes);
0140:     if (NULL == pBurnVC) {
0141:         const char * listing = pContextContainer->GetLastListing();
0142:         if (listing == 0) listing = "Could not find cgc.exe.";
0143:         cg.NotePad("頂点シェーダープログラムの生成に失敗しました\n\n", listing);
0144:         exit(1);
0145:     }
0146: 
0147:     pBurnPC = pContextContainer->LoadCGProgramFromFile(
0148:         "BurnP.cg", "test", cgDX8PixelProfile);
0149:     if (NULL == pBurnPC) {
0150:         const char * error_text = pContextContainer->GetLastListing();
0151:         cg.NotePad("ピクセルシェーダープログラムの生成に失敗しました\n\n\n", error_text);
0152:         exit(1);
0153:     }
0154:     BurnTex0_iter = pBurnPC->GetTextureBindByName("tex0");
0155:     BurnTex1_iter = pBurnPC->GetTextureBindByName("tex1");
0156:     BurnTex2_iter = pBurnPC->GetTextureBindByName("tex2");
0157: 
0158:     // ==================================================
0159:     // This program creates the black spots
0160:     // ==================================================
0161:     pBlackVC = pContextContainer->LoadCGProgramFromFile(
0162:         "BlackV.cg", "Vertex Shader", cgDX8VertexProfile, vertex_attributes);
0163:     if (NULL == pBlackVC) {
0164:         const char * listing = pContextContainer->GetLastListing();
0165:         if (listing == 0) listing = "Could not find cgc.exe.";
0166:         cg.NotePad("頂点シェーダープログラムの生成に失敗しました\n\n", listing);
0167:         exit(1);
0168:     }
0169:     // ==================================================
0170:     // Texture for the seed of the fire (CatMap)
0171:     // ==================================================
0172:     D3DXCreateTextureFromFileEx(lpD3DDev, "fire.bmp",0,0,0,0,D3DFMT_A8R8G8B8,
0173:                                 D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0174:                                 0, NULL, NULL, &pCatSeedTexture);
0175:     
0176:     D3DXCreateTextureFromFileEx(lpD3DDev, "t-pot.bmp",0,0,0,0,D3DFMT_A8R8G8B8,
0177:                                 D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0178:                                 0, NULL, NULL, &pBurnTexture);
0179:     
0180: 
0181:     // ==================================================
0182:     // Create Rendering Texture
0183:     // ==================================================
0184:     // Backup back buffers
0185:     D3DSURFACE_DESC Desc;
0186:     LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0187:     if( FAILED(hr = lpD3DDev->GetRenderTarget(&pBackbuffer))) return hr;
0188:     if( FAILED(hr = pBackbuffer->GetDesc( &Desc ))) return hr;
0189:     if( FAILED(hr = lpD3DDev->GetDepthStencilSurface( &lpZbuffer ))) return hr;
0190: 
0191:     if( FAILED(hr = lpD3DDev->CreateTexture(Desc.Width, Desc.Height, 1
0192:                             , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pBlackTexture))) return hr;
0193:     if( FAILED(hr = pBlackTexture->GetSurfaceLevel(0,&pBlackTextureSurface))) return hr;
0194:     if( FAILED(hr = lpD3DDev->SetRenderTarget(pBlackTextureSurface, NULL ))) return hr;
0195: 
0196:     // Total Fire result
0197:     if( FAILED(hr = lpD3DDev->CreateTexture(Desc.Width, Desc.Height, 1
0198:                             , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pEnvTexture))) return hr;
0199:     if( FAILED(hr = pEnvTexture->GetSurfaceLevel(0,&pEnvTextureSurface))) return hr;
0200:     if( FAILED(hr = lpD3DDev->SetRenderTarget(pEnvTextureSurface, lpZbuffer ))) return hr;
0201: 
0202:     for(i=0;i<2;i++){
0203:         // CatMap
0204:         if( FAILED(hr = lpD3DDev->CreateTexture(128, 128, 1
0205:                                 , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pCatTexture[i]))) return hr;
0206:         if( FAILED(hr = pCatTexture[i]->GetSurfaceLevel(0,&pCatTextureSurface[i]))) return hr;
0207:         // Fire map
0208:         if( FAILED(hr = lpD3DDev->CreateTexture(Desc.Width, Desc.Height, 1
0209:                                 , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pFireTexture[i]))) return hr;
0210:         if( FAILED(hr = pFireTexture[i]->GetSurfaceLevel(0,&pFireTextureSurface[i]))) return hr;
0211:     }
0212: 
0213:     // Set rendering target to back buffer
0214:     lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0215: 
0216:     // ==================================================
0217:     // Initialize render states
0218:     // ==================================================
0219:     lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE );
0220:     lpD3DDev->SetRenderState( D3DRS_LIGHTING,  FALSE );
0221:     lpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
0222:     lpD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
0223:     lpD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR);
0224: 
0225:     D3DXMatrixPerspectiveFovLH(&gProj
0226:         ,60.0f*D3DX_PI/180.0f
0227:         ,(float)WIDTH/(float)HEIGHT
0228:         ,0.01f,100.0f
0229:         );
0230: 
0231:     return S_OK;
0232: }
0233: 
0234: //-----------------------------------------------------------------------------
0235: // Name: Render()
0236: // Desc: Draws the scene
0237: //    type 0 normal
0238: //    type 1 burn envmap
0239: //-----------------------------------------------------------------------------
0240: VOID DrawModel(LPDIRECT3DDEVICE8 lpD3DDev, D3DXMATRIX &mVP, DWORD type)
0241: {
0242:     DrawBg(lpD3DDev, mVP, 0==type);
0243: 
0244:     D3DXMATRIX m;
0245:     D3DXMatrixTranspose( &m, &mVP );
0246:     pVertexProgramContainer->SetShaderConstant( vertex_mat_iter, &m  );
0247:     
0248:     lpD3DDev->SetStreamSource(0, mesh.pVB, sizeof(D3D_CUSTOMVERTEX));
0249:     lpD3DDev->SetIndices(mesh.pIndex,0);
0250: 
0251:     switch(type){
0252:     case 1:
0253:         pPixelProgramContainer->SetTexture(tex0_iter, pBurnTexture);
0254:         pPixelProgramContainer->SetTexture(tex1_iter, NULL);
0255:         break;
0256:     default:
0257:         pPixelProgramContainer->SetTexture(tex0_iter, mesh.pTextures[0]);
0258:         pPixelProgramContainer->SetTexture(tex1_iter, pBlackTexture);
0259:         break;
0260:     }
0261: 
0262:     lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0263:                                     mesh.pSubsetTable[0].VertexStart,
0264:                                     mesh.pSubsetTable[0].VertexCount,
0265:                                     mesh.pSubsetTable[0].FaceStart * 3,
0266:                                     mesh.pSubsetTable[0].FaceCount);
0267: }
0268: //-----------------------------------------------------------------------------
0269: // Name: Render()
0270: //-----------------------------------------------------------------------------
0271: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev)
0272: {
0273:     D3DXMATRIX      mWorld, mView, mProj, m, mat;
0274:     static DWORD    id=0;
0275:     static BOOL     init = TRUE;
0276:     LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0277:     lpD3DDev->GetDepthStencilSurface( &lpZbuffer );
0278: 
0279:     //-----------------------------------------------------------------------------
0280:     // CatMap
0281:     //-----------------------------------------------------------------------------
0282:     {
0283:         lpD3DDev->SetRenderTarget(pCatTextureSurface[id], NULL);
0284: 
0285:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0286:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0287:         lpD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
0288:         lpD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT );
0289:         float size = 128.0f;
0290:         TLVERTEX Vertex[] = {
0291:             //   x          y     z rhw  tu    tv
0292:             {0.0f*size, 0.0f*size,0, 1, 0.0f, 0.0f,},
0293:             {0.5f*size, 0.0f*size,0, 1, 1.0f, 0.5f,},
0294:             {0.0f*size, 1.0f*size,0, 1, 1.0f, 1.0f,},
0295: 
0296:             {0.5f*size, 0.0f*size,0, 1, 0.0f, 0.5f,},
0297:             {1.0f*size, 0.0f*size,0, 1, 1.0f, 1.0f,},
0298:             {0.0f*size, 1.0f*size,0, 1, 0.0f, 1.0f,},
0299: 
0300:             {0.0f*size, 1.0f*size,0, 1, 0.0f, 0.0f,},
0301:             {1.0f*size, 0.0f*size,0, 1, 1.0f, 0.0f,},
0302:             {0.5f*size, 1.0f*size,0, 1, 1.0f, 0.5f,},
0303: 
0304:             {0.5f*size, 1.0f*size,0, 1, 0.0f, 0.5f,},
0305:             {1.0f*size, 0.0f*size,0, 1, 0.0f, 0.0f,},
0306:             {1.0f*size, 1.0f*size,0, 1, 1.0f, 1.0f,},
0307:         };
0308: 
0309:         if(init){
0310:             lpD3DDev->SetTexture( 0, pCatSeedTexture);      // initialize
0311:         }else{
0312:             lpD3DDev->SetTexture( 0, pCatTexture[1-id] );   // ordinary
0313:         }
0314:         lpD3DDev->SetVertexShader( FVF_TLVERTEX );
0315:         lpD3DDev->SetPixelShader(0);
0316:         lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLELIST, 4, Vertex, sizeof( TLVERTEX ) );
0317:     }
0318: 
0319:     //-----------------------------------------------------------------------------
0320:     // Create 16 box sampling of the pBurnTexture
0321:     //-----------------------------------------------------------------------------
0322:     lpD3DDev->SetRenderTarget(pBlackTextureSurface, NULL );
0323:     lpD3DDev->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0),1.0f,0);
0324:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0325:     lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_ADD);
0326:     lpD3DDev->SetTextureStageState(2,D3DTSS_COLOROP,    D3DTOP_ADD);
0327:     lpD3DDev->SetTextureStageState(3,D3DTSS_COLOROP,    D3DTOP_ADD);
0328:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0329:     lpD3DDev->SetTextureStageState(1,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0330:     lpD3DDev->SetTextureStageState(2,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0331:     lpD3DDev->SetTextureStageState(3,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0332:     lpD3DDev->SetTextureStageState(1,D3DTSS_COLORARG2,  D3DTA_CURRENT);
0333:     lpD3DDev->SetTextureStageState(2,D3DTSS_COLORARG2,  D3DTA_CURRENT);
0334:     lpD3DDev->SetTextureStageState(3,D3DTSS_COLORARG2,  D3DTA_CURRENT);
0335:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP);
0336:     lpD3DDev->SetTextureStageState(1,D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP);
0337:     lpD3DDev->SetTextureStageState(2,D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP);
0338:     lpD3DDev->SetTextureStageState(3,D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP);
0339:     lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0340:     lpD3DDev->SetTextureStageState(1,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0341:     lpD3DDev->SetTextureStageState(2,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0342:     lpD3DDev->SetTextureStageState(3,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0343: 
0344:     TLVERTEX BlackVertex[] = {
0345:         // x    y   z   rhw tu tv
0346:         { -1,  1, 0.1f, 1.f, 0, 0,},
0347:         {  1,  1, 0.1f, 1.f, 1, 0,},
0348:         {  1, -1, 0.1f, 1.f, 1, 1,},
0349:         { -1, -1, 0.1f, 1.f, 0, 1,},
0350:     };
0351: 
0352:     pBlackVC->SetShaderActive();
0353:     lpD3DDev->SetTexture(0, pBurnTexture);
0354:     lpD3DDev->SetTexture(1, pBurnTexture);
0355:     lpD3DDev->SetTexture(2, pBurnTexture);
0356:     lpD3DDev->SetTexture(3, pBurnTexture);
0357:     lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, BlackVertex, sizeof( TLVERTEX ) );
0358:     lpD3DDev->SetTexture(0, NULL);
0359:     lpD3DDev->SetTexture(1, NULL);
0360:     lpD3DDev->SetTexture(2, NULL);
0361:     lpD3DDev->SetTexture(3, NULL);
0362: 
0363:     //-----------------------------------------------------------------------------
0364:     // Create 3D Burn map
0365:     //-----------------------------------------------------------------------------
0366:     D3DXVECTOR3 eye    = D3DXVECTOR3(0.0f,  2.0f,  4.0f);
0367:     D3DXVECTOR3 lookAt = D3DXVECTOR3(0.0f,  1.0f,  0.0f);
0368:     D3DXVECTOR3 up     = D3DXVECTOR3(0.0f,  1.0f,  0.0f);
0369:     D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0370:     mat = view.Get() * gProj;
0371: 
0372:     lpD3DDev->SetRenderTarget(pEnvTextureSurface, lpZbuffer );
0373:     lpD3DDev->Clear(0,NULL,D3DCLEAR_ZBUFFER, 0,1.0f,0);
0374:     pVertexProgramContainer->SetShaderActive();
0375:     pPixelProgramContainer->SetShaderActive();
0376:     DrawModel(lpD3DDev, mat, 1);
0377:         
0378:     //-----------------------------------------------------------------------------
0379:     // Create fire effect
0380:     //-----------------------------------------------------------------------------
0381:     lpD3DDev->SetRenderTarget(pFireTextureSurface[id], NULL);
0382:     lpD3DDev->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0),1.0f,0);
0383:         
0384:     if(!init){
0385:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0386:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0387:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0388:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0389:         lpD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_POINT );
0390:         lpD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_POINT );
0391:         lpD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_POINT );
0392:         lpD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_POINT );
0393:         lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP);
0394:         lpD3DDev->SetTextureStageState(0,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0395:         lpD3DDev->SetTextureStageState(1,D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP);
0396:         lpD3DDev->SetTextureStageState(1,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0397:         TLVERTEX Vertex[] = {
0398:             // x    y   z   rhw tu tv
0399:             { -1,  1, 0.1f, 1.f, 0+0.5f/512.0f, 1+0.5f/512.0f,},
0400:             {  1,  1, 0.1f, 1.f, 1+0.5f/512.0f, 1+0.5f/512.0f,},
0401:             {  1, -1, 0.1f, 1.f, 1+0.5f/512.0f, 0+0.5f/512.0f,},
0402:             { -1, -1, 0.1f, 1.f, 0+0.5f/512.0f, 0+0.5f/512.0f,},
0403:         };
0404: 
0405:         pBurnVC->SetShaderActive();
0406:         pBurnPC->SetShaderActive();
0407:         pBurnPC->SetTexture(BurnTex0_iter, pFireTexture[1-id]);
0408:         pBurnPC->SetTexture(BurnTex1_iter, pEnvTexture);
0409:         pBurnPC->SetTexture(BurnTex2_iter, pCatTexture[id]);
0410:         lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) );
0411:     }
0412: 
0413:     //-----------------------------------------------------------------------------
0414:     // Make final result
0415:     //-----------------------------------------------------------------------------
0416:     lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0417:     lpD3DDev->Clear(0,NULL,D3DCLEAR_ZBUFFER, 0,1.0f,0);
0418: 
0419:     pVertexProgramContainer->SetShaderActive();
0420:     pPixelProgramContainer->SetShaderActive();
0421:     lpD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
0422:     lpD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
0423:     DrawModel(lpD3DDev, mat, 0);
0424: 
0425:     // Add burned result
0426:     {
0427:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0428:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0429:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0430:         lpD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
0431:         float size = 512.0f;
0432:         TLVERTEX Vertex[4] = {
0433:             // x    y   z rhw tu tv
0434:             {   0,    0,0, 1, 0, 0,},
0435:             {size,    0,0, 1, 1, 0,},
0436:             {size, size,0, 1, 1, 1,},
0437:             {   0, size,0, 1, 0, 1,},
0438:         };
0439:         lpD3DDev->SetTexture( 0, pFireTexture[id] );
0440:         lpD3DDev->SetVertexShader( FVF_TLVERTEX );
0441:         lpD3DDev->SetPixelShader(0);
0442:         lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) );
0443:         lpD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
0444:     }
0445: 
0446: #if 1
0447:     //-----------------------------------------------------------------------------
0448:     // For debugging, this part shows rendered texture.
0449:     //-----------------------------------------------------------------------------
0450:     DWORD i;
0451:     for(i=0;i<4;i++){
0452:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0453:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0454:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0455:         float scale = 128.0f;
0456:         TLVERTEX Vertex[4] = {
0457:             // x  y  z rhw tu tv
0458:             {    0,    0,0, 1, 0, 0,},
0459:             {scale,    0,0, 1, 1, 0,},
0460:             {scale,scale,0, 1, 1, 1,},
0461:             {    0,scale,0, 1, 0, 1,},
0462:         };
0463:         for(DWORD j=0;j<4;j++){
0464:             Vertex[j].x += i*scale;
0465:         }
0466:         switch(i){
0467:         case 0:
0468:             lpD3DDev->SetTexture( 0, pCatTexture[id] );
0469:             break;
0470:         case 1:
0471:             lpD3DDev->SetTexture( 0, pEnvTexture );
0472:             break;
0473:         case 2:
0474:             lpD3DDev->SetTexture( 0, pFireTexture[id] );
0475:             break;
0476:         case 3:
0477:             lpD3DDev->SetTexture( 0, pBlackTexture );
0478:             break;
0479:         }
0480:     
0481: //      lpD3DDev->SetTexture( 0, pBurnTexture );
0482:         lpD3DDev->SetVertexShader( FVF_TLVERTEX );
0483:         lpD3DDev->SetPixelShader(0);
0484:         lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) );
0485:     }
0486: #endif
0487:     init=FALSE;
0488:     id=1-id;
0489: }
0490: //-----------------------------------------------------------------------------
0491: // Name: CleanRender()
0492: //-----------------------------------------------------------------------------
0493: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev)
0494: {
0495:     RELEASE(pCatSeedTexture);
0496:     RELEASE(pCatTextureSurface[1]);
0497:     RELEASE(pCatTextureSurface[0]);
0498:     RELEASE(pCatTexture[1]);
0499:     RELEASE(pCatTexture[0]);
0500: 
0501:     RELEASE(pFireTextureSurface[1]);
0502:     RELEASE(pFireTextureSurface[0]);
0503:     RELEASE(pFireTexture[1]);
0504:     RELEASE(pFireTexture[0]);
0505: 
0506:     RELEASE(pEnvTextureSurface);
0507:     RELEASE(pEnvTexture);
0508: 
0509:     RELEASE(pBurnTexture);
0510: 
0511:     RELEASE(pBlackTextureSurface);
0512:     RELEASE(pBlackTexture);
0513: 
0514:     RELEASE(pBackbuffer);
0515: 
0516:     CleanBg(lpD3DDev);
0517: }
0518: //-----------------------------------------------------------------------------
0519: // eazy camera setting
0520: //-----------------------------------------------------------------------------
0521: static void set_camera(float cam_r, float cam_theta, float cam_phi, const D3DXVECTOR4 &cam_tr)
0522: {
0523:     D3DXVECTOR4 v = cam_tr;
0524:     view.SetLookAt(v);
0525:     v.z += cam_r * (float)cos(cam_phi) * (float)cos(cam_theta);
0526:     v.x += cam_r * (float)cos(cam_phi) * (float)sin(cam_theta);
0527:     v.y += cam_r * (float)sin(cam_phi);
0528:     view.SetEye(v);
0529: }
0530: //-----------------------------------------------------------------------------
0531: // Name: MyMsgProc()
0532: //-----------------------------------------------------------------------------
0533: LRESULT CALLBACK MyMsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
0534: {
0535:     static int  type = 0;
0536:     // mouse position
0537:     static long prevX = 0;
0538:     static long prevY = 0;
0539:     long x,y,dx,dy;
0540:     // camera
0541:     static D3DXVECTOR4 cam_tr = D3DXVECTOR4(0.0f, 0.5f, 0.0f, 0.0f);
0542:     static float cam_r      = 5.0f;
0543:     static float cam_theta  = D3DX_PI;
0544:     static float cam_phi    = 0.3f*D3DX_PI;
0545: 
0546:     switch(msg){
0547:     case WM_CREATE:
0548:         set_camera(cam_r, cam_theta, cam_phi, cam_tr);
0549:         break;
0550:     case WM_RBUTTONDOWN:
0551:         type=1;
0552:         prevX = (lParam << 16) >> 16;
0553:         prevY = lParam >> 16;
0554:         SetCapture(hWnd);
0555:         break;
0556:     case WM_RBUTTONUP:
0557:         type=0;
0558:         ReleaseCapture();
0559:         break;
0560:     case WM_MOUSEMOVE:
0561:         x = (lParam << 16) >> 16;
0562:         y = lParam >> 16;
0563:         dx = x - prevX;
0564:         dy = y - prevY;
0565:         switch(type){
0566:         case 1:// camera
0567:             if(wParam & MK_RBUTTON){
0568:                 if(dy != 0){
0569:                     cam_phi += 0.005f*dy;
0570:                     if( 0.499f*D3DX_PI<cam_phi)cam_phi = 0.499f*D3DX_PI;
0571:                     if(cam_phi<-0.000f*D3DX_PI)cam_phi =-0.000f*D3DX_PI;
0572:                     set_camera(cam_r, cam_theta, cam_phi, cam_tr);
0573:                 }
0574:                 if(dx != 0){
0575:                     cam_theta += 0.005f*dx;
0576:                     set_camera(cam_r, cam_theta, cam_phi, cam_tr);
0577:                 }
0578:             }
0579:             break;
0580:         }
0581:         prevX = x;
0582:         prevY = y;
0583:         break;
0584:     case 0x020A:// WM_MOUSEWHEEL
0585:         cam_r += 0.001f*(float)(short)HIWORD(wParam);
0586:         if(cam_r<=0.1f)cam_r = 0.1f;
0587:         if(7.0f<cam_r)cam_r = 7.0f;
0588: 
0589:         set_camera(cam_r, cam_theta, cam_phi, cam_tr);
0590:         break;
0591:     }
0592: 
0593:     return 0L;
0594: }