0001: // ----------------------------------------------------------------------------
0002: //
0003: // draw.cpp - 描画部分
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: // モデル用
0017: LPDIRECT3DVERTEXBUFFER8 pMeshVB = NULL;
0018: LPDIRECT3DINDEXBUFFER8  pMeshIndex = NULL;
0019: D3DXATTRIBUTERANGE      *pSubsetTable = NULL;
0020: DWORD                   nMeshFaces = 0;
0021: DWORD                   nMeshVertices = 0;
0022: D3DMATERIAL8            *pMeshMaterials = NULL;     // メッシュの質感
0023: LPDIRECT3DTEXTURE8      *pMeshTextures  = NULL;     // メッシュのテクスチャー
0024: DWORD                   dwNumMaterials = 0L;        // マテリアルの数
0025: FLOAT                   MeshRadius;                 // メッシュの大きさ
0026: 
0027: // レンダリングテクスチャーの設定
0028: DWORD                   hVertexShader=~0;
0029: DWORD                   hPixelShader=~0;
0030: DWORD                   hVertexShaderEdge=~0;
0031: DWORD                   hPixelShaderEdge=~0;
0032: DWORD                   hVertexShaderBokashi=~0;
0033: DWORD                   hPixelShaderBokashi=~0;
0034: DWORD                   hFinalVertexShader=~0;
0035: DWORD                   hFinalPixelShader=~0;
0036: 
0037: LPDIRECT3DTEXTURE8      pTexture;
0038: LPDIRECT3DSURFACE8      pTextureSurface;
0039: LPDIRECT3DTEXTURE8      pTextureEdge;
0040: LPDIRECT3DSURFACE8      pTextureSurfaceEdge;
0041: LPDIRECT3DTEXTURE8      pTextureBokashi;
0042: LPDIRECT3DSURFACE8      pTextureSurfaceBokashi;
0043: LPDIRECT3DSURFACE8      pBackbuffer = NULL;
0044: 
0045: 
0046: // 最後の一枚絵の描画用
0047: LPDIRECT3DVERTEXBUFFER8 pFinalVB = NULL;
0048: LPDIRECT3DINDEXBUFFER8  pFinalIB = NULL;
0049: 
0050: typedef struct {
0051:     float x,y,z;
0052:     float tu,tv;
0053: }D3D_FINAL_VERTEX;
0054: #define D3DFVF_FINAL_VERTEX         (D3DFVF_XYZ | D3DFVF_TEX1)
0055: 
0056: DWORD dwFinalDecl[] = {
0057:     D3DVSD_STREAM(0),
0058:     D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),          //D3DVSDE_POSITION,  0
0059:     D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ),          //D3DVSDE_TEXCOORD0, 7  
0060:     D3DVSD_END()
0061: };
0062: 
0063: 
0064: // ----------------------------------------------------------------------------
0065: // 外部関数
0066: void InitBg(LPDIRECT3DDEVICE8 lpD3DDev);
0067: void DrawBg(LPDIRECT3DDEVICE8 lpD3DDev);
0068: void CleanBg(LPDIRECT3DDEVICE8 lpD3DDev);
0069: 
0070: 
0071: 
0072: // ----------------------------------------------------------------------------
0073: // Name: LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDev)
0074: // Desc: X-Fileの読み込み
0075: //-----------------------------------------------------------------------------
0076: HRESULT LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDev)
0077: {
0078:     LPD3DXMESH pMesh, pMeshOpt;
0079:     LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
0080:     DWORD i;
0081:     HRESULT hr;
0082: 
0083:     hr = D3DXLoadMeshFromX(filename, D3DXMESH_MANAGED,
0084:                                 lpD3DDev, NULL,
0085:                                 &pD3DXMtrlBuffer, &dwNumMaterials,
0086:                                 &pMesh);
0087:     if(FAILED(hr)) return E_FAIL;
0088: 
0089:     //並び替えておく
0090:     pMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshOpt);
0091:     RELEASE(pMesh);
0092: 
0093:     //アトリビュートテーブル
0094:     pMeshOpt->GetAttributeTable(NULL,&dwNumMaterials);
0095:     pSubsetTable = new D3DXATTRIBUTERANGE[dwNumMaterials];
0096:     pMeshOpt->GetAttributeTable(pSubsetTable, &dwNumMaterials);
0097: 
0098:     // FVF変換
0099:     hr = pMeshOpt->CloneMeshFVF(pMeshOpt->GetOptions(), D3DFVF_VERTEX, lpD3DDev, &pMesh);
0100:     if(FAILED(hr)) return E_FAIL;
0101:     RELEASE(pMeshOpt);
0102:     D3DXComputeNormals(pMesh, NULL);
0103: 
0104:     //Vertex Bufferにコピーする
0105:     D3DVERTEX* pSrc;
0106:     D3D_CUSTOMVERTEX* pDest;
0107:     LPDIRECT3DINDEXBUFFER8 pSrcIndex;
0108:     WORD* pISrc;
0109:     WORD* pIDest;
0110: 
0111:     DWORD nMeshVertices = pMesh->GetNumVertices();
0112:     DWORD nMeshFaces = pMesh->GetNumFaces();
0113:     lpD3DDev->CreateVertexBuffer(nMeshVertices * sizeof(D3D_CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pMeshVB);
0114:     lpD3DDev->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&pMeshIndex);
0115: 
0116:     LPDIRECT3DVERTEXBUFFER8 pVB;
0117:     pMesh->GetVertexBuffer(&pVB);
0118:     pVB->Lock(0,0,(BYTE**)&pSrc,0);
0119:     pMeshVB->Lock(0,0,(BYTE**)&pDest,0);
0120:     MeshRadius = 0.0f;
0121:     for(i=0;i<nMeshVertices;i++){
0122:         pDest->x = pSrc->x;
0123:         pDest->y = pSrc->y;
0124:         pDest->z = pSrc->z;
0125:         pDest->nx = pSrc->nx;
0126:         pDest->ny = pSrc->ny;
0127:         pDest->nz = pSrc->nz;
0128:         pDest->tu0 = pSrc->tu0;
0129:         pDest->tu0 = pSrc->tu0;
0130:         // サイズの計算
0131:         FLOAT radius = sqrtf( pSrc->x*pSrc->x + pSrc->y*pSrc->y + pSrc->z*pSrc->z );
0132:         if (MeshRadius < radius) MeshRadius = radius;
0133:         
0134:         pSrc += 1;
0135:         pDest += 1;
0136:     }
0137:     pVB->Unlock();
0138:     pVB->Release();
0139:     pMeshVB->Unlock();
0140: 
0141:     //インデックスのコピー
0142:     pMesh->GetIndexBuffer(&pSrcIndex);
0143:     pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0144:     pMeshIndex->Lock(0,0,(BYTE**)&pIDest,0);
0145:     CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0146:     pSrcIndex->Unlock();
0147:     pMeshIndex->Unlock();
0148:     pSrcIndex->Release();
0149: 
0150:     // pD3DXMtrlBuffer から、質感やテクスチャーの情報を読み取る
0151:     D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0152:     pMeshTextures = new LPDIRECT3DTEXTURE8[dwNumMaterials];
0153:     pMeshMaterials = new D3DMATERIAL8[dwNumMaterials];
0154: 
0155:     for(i = 0; i < dwNumMaterials; i++){
0156:         pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
0157:         pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
0158:         hr = D3DXCreateTextureFromFile( lpD3DDev, 
0159:                                         d3dxMaterials[i].pTextureFilename, 
0160:                                         &pMeshTextures[i] );
0161:         if(FAILED(hr)) pMeshTextures[i] = NULL;
0162:     }
0163:     RELEASE(pD3DXMtrlBuffer);
0164:     
0165:     RELEASE(pMesh);
0166: 
0167:     return S_OK;
0168: }
0169: //-----------------------------------------------------------------------------
0170: // Name: InitRenderTexture()
0171: // Desc: レンダリングテクスチャー用の下準備
0172: //-----------------------------------------------------------------------------
0173: HRESULT InitRenderTexture(LPDIRECT3DDEVICE8 lpD3DDev)
0174: {
0175:     HRESULT hr;
0176:     DWORD i;
0177:     
0178:     // バーテックスシェーダーを作成する
0179:     hr=CVertexShaderMgr::Load(lpD3DDev, "vs.vsh", &hVertexShader, dwDecl);
0180:     if( FAILED(hr) ) return hr;
0181:     hr=CPixelShaderMgr::Load(lpD3DDev, "ps.psh", &hPixelShader);
0182:     if( FAILED(hr) ) return hr;
0183:     hr=CVertexShaderMgr::Load(lpD3DDev, "edge.vsh", &hVertexShaderEdge, dwFinalDecl);
0184:     if( FAILED(hr) ) return hr;
0185:     hr=CPixelShaderMgr::Load(lpD3DDev, "edge.psh", &hPixelShaderEdge);
0186:     if( FAILED(hr) ) return hr;
0187:     hr=CVertexShaderMgr::Load(lpD3DDev, "bokashi.vsh", &hVertexShaderBokashi, dwFinalDecl);
0188:     if( FAILED(hr) ) return hr;
0189:     hr=CPixelShaderMgr::Load(lpD3DDev, "bokashi.psh", &hPixelShaderBokashi);
0190:     if( FAILED(hr) ) return hr;
0191:     hr=CVertexShaderMgr::Load(lpD3DDev, "final.vsh", &hFinalVertexShader, dwDecl);
0192:     if( FAILED(hr) ) return hr;
0193:     hr=CPixelShaderMgr::Load(lpD3DDev, "final.psh", &hFinalPixelShader);
0194:     if( FAILED(hr) ) return hr;
0195:     
0196:     // 頂点バッファの作成 
0197:     D3D_FINAL_VERTEX *pDest;
0198:     WORD *pIndex;
0199:     hr = lpD3DDev->CreateVertexBuffer( 4 * sizeof(D3D_FINAL_VERTEX),
0200:                                 D3DUSAGE_WRITEONLY, D3DFVF_FINAL_VERTEX, D3DPOOL_MANAGED,
0201:                                 &pFinalVB );
0202:     // 頂点をセットアップ
0203:     pFinalVB->Lock ( 0, 0, (BYTE**)&pDest, 0 );
0204:     for (i = 0; i < 4; i++) {
0205:         pDest->x   = (i == 0 || i == 1)?-1:(float)1;
0206:         pDest->y   = (i == 0 || i == 2)?-1:(float)1;
0207:         pDest->z   = 0.5f;
0208:         pDest->tu = (i == 2 || i == 3)?1:(float)0;
0209:         pDest->tv = (i == 0 || i == 2)?1:(float)0;
0210:         pDest++;
0211:     }       
0212:     pFinalVB->Unlock ();
0213:     // インデックスをセットアップ
0214:     hr = lpD3DDev->CreateIndexBuffer( 6 * sizeof(WORD),
0215:                                0,
0216:                                D3DFMT_INDEX16, D3DPOOL_MANAGED,
0217:                                &pFinalIB );
0218:     pFinalIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0219:     pIndex[0] = 0;  pIndex[1] = 1;  pIndex[2] = 2;
0220:     pIndex[3] = 1;  pIndex[4] = 3;  pIndex[5] = 2;
0221:     pFinalIB->Unlock ();
0222:     
0223:     // -------------------------------------------------------------------------
0224:     // 定数レジスタの設定
0225:     // -------------------------------------------------------------------------
0226:     float const inv_w = 1.0f / (float)WIDTH;
0227:     float const inv_h = 1.0f / (float)HEIGHT;
0228:     lpD3DDev->SetVertexShaderConstant(20, &D3DXVECTOR4  (-0.5f*inv_w, -0.5f*inv_h, 0.0f, 0.0f), 1);
0229:     lpD3DDev->SetVertexShaderConstant(21, &D3DXVECTOR4  (+0.5f*inv_w, -0.5f*inv_h, 0.0f, 0.0f), 1);
0230:     lpD3DDev->SetVertexShaderConstant(22, &D3DXVECTOR4  (-0.5f*inv_w, +0.5f*inv_h, 0.0f, 0.0f), 1);
0231:     lpD3DDev->SetVertexShaderConstant(23, &D3DXVECTOR4  (+0.5f*inv_w, +0.5f*inv_h, 0.0f, 0.0f), 1);
0232:     // ぼかし用
0233:     lpD3DDev->SetVertexShaderConstant(30, &D3DXVECTOR4  (-0.0f*inv_w, -0.0f*inv_h, 0.0f, 0.0f), 1);
0234:     lpD3DDev->SetVertexShaderConstant(31, &D3DXVECTOR4  (+2.0f*inv_w, -0.0f*inv_h, 0.0f, 0.0f), 1);
0235:     lpD3DDev->SetVertexShaderConstant(32, &D3DXVECTOR4  (-0.0f*inv_w, +2.0f*inv_h, 0.0f, 0.0f), 1);
0236:     lpD3DDev->SetVertexShaderConstant(33, &D3DXVECTOR4  (+2.0f*inv_w, +2.0f*inv_h, 0.0f, 0.0f), 1);
0237:     // 便利な定数
0238:     lpD3DDev->SetVertexShaderConstant(12, &D3DXVECTOR4  (0.0f, 0.5f, 1.0f, 2.0f), 1);
0239: 
0240:     // -------------------------------------------------------------------------
0241:     // 描画用テクスチャーを用意する
0242:     // -------------------------------------------------------------------------
0243:     D3DSURFACE_DESC Desc;
0244:     LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0245:     if( FAILED(hr = lpD3DDev->GetRenderTarget(&pBackbuffer))) return hr;
0246:     if( FAILED(hr = pBackbuffer->GetDesc( &Desc ))) return hr;
0247: 
0248:     // 深度バッファのサーフェスを確保する
0249:     if( FAILED(hr = lpD3DDev->GetDepthStencilSurface( &lpZbuffer ))) return hr;
0250:     
0251:     // テクスチャーの生成
0252:     int size = 512;
0253:     if( FAILED(hr = lpD3DDev->CreateTexture(size, size, 1
0254:                             , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8
0255:                             , D3DPOOL_DEFAULT, &pTexture))) return hr;
0256:     // テクスチャーとサーフェスを関連づける
0257:     if( FAILED(hr = pTexture->GetSurfaceLevel(0,&pTextureSurface))) return hr;
0258:     // テクスチャー用の描画と深度バッファを関連付ける
0259:     if( FAILED(hr = lpD3DDev->SetRenderTarget(pTextureSurface, lpZbuffer)))
0260:         return hr;
0261:     // エッジ用-----------------------------------
0262:     if( FAILED(hr = lpD3DDev->CreateTexture(size, size, 1
0263:                             , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8
0264:                             , D3DPOOL_DEFAULT, &pTextureEdge))) return hr;
0265:     if( FAILED(hr = pTextureEdge->GetSurfaceLevel(0,&pTextureSurfaceEdge))) return hr;
0266:     if( FAILED(hr = lpD3DDev->SetRenderTarget(pTextureSurfaceEdge, NULL)))
0267:         return hr;
0268:     // ぼかし用-----------------------------------
0269:     if( FAILED(hr = lpD3DDev->CreateTexture(size, size, 1
0270:                             , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8
0271:                             , D3DPOOL_DEFAULT, &pTextureBokashi))) return hr;
0272:     if( FAILED(hr = pTextureBokashi->GetSurfaceLevel(0,&pTextureSurfaceBokashi))) return hr;
0273:     if( FAILED(hr = lpD3DDev->SetRenderTarget(pTextureSurfaceBokashi, lpZbuffer)))
0274:         return hr;
0275: 
0276:     // 描画を元の画面に戻す
0277:     lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0278:     
0279:     return S_OK;
0280: }
0281: //-----------------------------------------------------------------------------
0282: // Name: InitRender()
0283: // Desc: Load the mesh and build the material and texture arrays
0284: //-----------------------------------------------------------------------------
0285: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0286: {
0287:     HRESULT hr;
0288: 
0289:     // モデルの読み込み
0290:     if ( FAILED(hr = LoadXFile("nsx.x", lpD3DDev)) ) return hr;
0291:     
0292:     // レンダリングテクスチャー用の初期化
0293:     InitRenderTexture(lpD3DDev);
0294:     
0295:     // 背景部分の初期化
0296:     InitBg(lpD3DDev);
0297: 
0298:     // 不変なレジスタの設定
0299:     lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE );
0300:     for (DWORD i = 0; i < 4; ++i) {
0301:         lpD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0302:         lpD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0303:         lpD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_NONE);
0304:         lpD3DDev->SetTextureStageState(i,D3DTSS_ADDRESSU,   D3DTADDRESS_CLAMP);
0305:         lpD3DDev->SetTextureStageState(i,D3DTSS_ADDRESSV,   D3DTADDRESS_CLAMP);
0306:     }
0307: 
0308:     return S_OK;
0309: }
0310: //-----------------------------------------------------------------------------
0311: // Name: DrawModel()
0312: // Desc: Draw Models
0313: //-----------------------------------------------------------------------------
0314: D3DXVECTOR4 lightDir(0.666f, 0.666f, 0.333f, 0.0f);
0315: 
0316: VOID DrawModel(LPDIRECT3DDEVICE8 lpD3DDev, BOOL bShadowMap, BOOL bBg)
0317: {
0318:     D3DXMATRIX mWorld, mView, mProj, mScale, mProjMap, mVPm, mViewI, mSign, mLightView, mProjL, mShift;
0319:     D3DXMATRIX mVP, mVPI, mLP, m;
0320:     D3DXVECTOR4 vl;
0321:     DWORD i;
0322:     float q, qz;
0323: 
0324:     // ビュー行列
0325:     D3DXVECTOR4 eye    = D3DXVECTOR4(0.0f,1.4f*MeshRadius,2.5f*MeshRadius,1);
0326:     D3DXMatrixLookAtLH(&mView, (D3DXVECTOR3*)&eye
0327:                              , &D3DXVECTOR3(0,0,0)
0328:                              , &D3DXVECTOR3(0,1,0));
0329: 
0330:     // 射影行列
0331:     const float z_min =  0.01f;
0332:     const float z_max  = 100.0f;
0333:     D3DXMatrixPerspectiveFovLH(&mProj
0334:         ,60.0f*PI/180.0f                        // 視野角
0335:         ,(float)WIDTH/(float)HEIGHT             // アスペクト比
0336:         ,z_min, z_max                           // 最近接距離,最遠方距離
0337:         );
0338:     mVP = mView * mProj;
0339:     
0340:     // 影マップに関する射影(含む適当なスケーリング)
0341:     D3DXMatrixScaling(&mScale
0342:                 ,mView.m[3][2]/mProj.m[0][0]
0343:                 ,mView.m[3][2]/mProj.m[1][1]
0344:                 ,100.0f*mView.m[3][2]*mView.m[3][2]);
0345:     q = 1.0f/(z_max-z_min);
0346:     float d = D3DXVec3Length((D3DXVECTOR3*)&eye);
0347:     D3DXMatrixScaling(&mScale, d, d, 10000.0f*d*d);
0348:     mProjMap = D3DXMATRIX(1,0,0,0,
0349:                           0,1,0,0,
0350:                           0,0,q,1,
0351:                           0,0,-q*z_min,0) * mScale;
0352:     mVPm = mView * mProjMap;
0353:     
0354:     // 射影空間を(ゆがんだ)ワールド座標に戻すための逆ビュー行列
0355:     D3DXVECTOR4 cent = D3DXVECTOR4(0,0,0,1);
0356:     D3DXVECTOR4 zdir = D3DXVECTOR4(0,0,1,1);
0357:     D3DXVECTOR4 udir = D3DXVECTOR4(0,1,0,1);
0358:     D3DXVec4Transform(&cent, &cent, &mVPm); D3DXVec4Scale(&cent, &cent, 1.0f/cent.w);
0359:     D3DXVec4Transform(&zdir, &zdir, &mVPm); D3DXVec4Scale(&zdir, &zdir, 1.0f/zdir.w);
0360:     D3DXVec4Transform(&udir, &udir, &mVPm); D3DXVec4Scale(&udir, &udir, 1.0f/udir.w);
0361:     D3DXMatrixLookAtLH(&mViewI, (D3DXVECTOR3*)&cent, (D3DXVECTOR3*)&zdir, (D3DXVECTOR3*)&udir);
0362: 
0363:     // 逆ビュー行列による符号の変換を元に戻す
0364:     D3DXMatrixScaling(&mSign,-1, -1,  1);
0365:     mVPI = mView * mProjMap * mViewI * mSign;
0366: 
0367:     // ライト方向からのビュー行列
0368:     const float zoom =30.f;
0369:     D3DXVECTOR4 eyeP;
0370:     D3DXVec3Transform(&eyeP,    &D3DXVECTOR3(zoom*lightDir.x, zoom*lightDir.y, zoom*lightDir.z),    &mVPI);
0371:     D3DXVec4Scale(&eyeP,    &eyeP,    1.0f/eyeP.w);
0372:     D3DXMatrixLookAtLH(&mLightView, (D3DXVECTOR3*)&eyeP, &D3DXVECTOR3(0,0,0), &D3DXVECTOR3(0,1,0));
0373:     
0374:     // ライト方向に関する射影行列
0375:     float lz_min = 20.0f;
0376:     float lz_max =300.0f;
0377:     D3DXMatrixPerspectiveFovLH(&mProjL
0378:         ,80.0f*PI/180.0f                        // 視野角
0379:         ,1.6f                                   // アスペクト比
0380:         ,lz_min, lz_max                         // 最近接距離,最遠方距離
0381:         );
0382: 
0383:     // 中心をずらして、影マップを有効に使う
0384:     D3DXMatrixTranslation(&mShift, -0.7f, 0.65f, 0);
0385:     mLP =mVPI * mLightView * mProjL * mShift;
0386: 
0387:     // z値を0.0fから1.0fに補正する定数
0388:     lz_min =  300.0f;
0389:     lz_max = 5000.0f;
0390:     qz = lz_max*lz_min/(lz_max-lz_min);
0391:     q  = lz_max       /(lz_max-lz_min);
0392:     lpD3DDev->SetVertexShaderConstant(15, &D3DXVECTOR4(-qz, q, 0.0f, 0.0f), 1);
0393: 
0394:     //
0395:     // 逆カリング処理
0396:     //
0397:     if(bShadowMap) lpD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
0398: 
0399:     //
0400:     // 背景描画
0401:     // 
0402:     if(bBg){
0403:         D3DXMatrixScaling(&mWorld, 3.0f, 3.0f, 3.0f);
0404: 
0405:         m = mWorld * mVP;
0406:         D3DXMatrixTranspose( &m ,  &m);
0407:         lpD3DDev->SetVertexShaderConstant(0,&m, 4);
0408:         m = mWorld * mLP;
0409:         D3DXMatrixTranspose( &m ,  &m);
0410:         lpD3DDev->SetVertexShaderConstant(4,&m, 4);
0411:         
0412:         D3DXMatrixInverse( &m,  NULL, &mWorld);
0413:         D3DXVec4Transform(&vl, &lightDir, &m);
0414:         D3DXVec4Normalize(&vl, &vl);
0415:         vl[3] = 0.3f;
0416:         lpD3DDev->SetVertexShaderConstant(13, &vl, 1);
0417:         
0418:         lpD3DDev->SetVertexShaderConstant(14, &D3DXVECTOR4(0.0f, 0.0f, 0.0f, 1.0f), 1);
0419:         DrawBg(lpD3DDev);
0420:     }
0421: 
0422:     //
0423:     // 外側もでる描画
0424:     //
0425:     int t = timeGetTime() & 0xffffff;
0426:     D3DXMatrixTranslation(&m, 1.5f*MeshRadius, 0,0);
0427:     D3DXMatrixRotationY( &mWorld, t/1000.0f );
0428: //D3DXMatrixRotationY( &mWorld, -0.40*PI/2 );   // 撮影アングル
0429:     mWorld = m * mWorld;
0430:     
0431:     m = mWorld * mVP;
0432:     D3DXMatrixTranspose( &m ,  &m);
0433:     lpD3DDev->SetVertexShaderConstant(0,&m, 4);
0434:     m = mWorld * mLP;
0435:     D3DXMatrixTranspose( &m ,  &m);
0436:     lpD3DDev->SetVertexShaderConstant(4,&m, 4);
0437: 
0438:     D3DXMatrixInverse( &m,  NULL, &mWorld);
0439:     D3DXVec4Transform(&vl, &lightDir, &m);
0440:     D3DXVec4Normalize(&vl, &vl);
0441:     vl[3] = 0.3f;
0442:     lpD3DDev->SetVertexShaderConstant(13, &vl, 1);
0443:     
0444:     lpD3DDev->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0445:     lpD3DDev->SetIndices(pMeshIndex,0);
0446:     
0447:     for(i=0;i<dwNumMaterials;i++){
0448:         //色をセット
0449:         D3DXVECTOR4 vl;
0450:         vl.x = pMeshMaterials[i].Diffuse.r;
0451:         vl.y = pMeshMaterials[i].Diffuse.g;
0452:         vl.z = pMeshMaterials[i].Diffuse.b;
0453:         lpD3DDev->SetVertexShaderConstant(14, &vl, 1);
0454: 
0455:         lpD3DDev->SetTexture(0,pMeshTextures[i]);
0456:         lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0457:                                         pSubsetTable[i].VertexStart,
0458:                                         pSubsetTable[i].VertexCount,
0459:                                         pSubsetTable[i].FaceStart * 3,
0460:                                         pSubsetTable[i].FaceCount);
0461:     }
0462:     //
0463:     // モデル2
0464:     //
0465:     D3DXMatrixRotationY( &mWorld, -t/3000.0f );
0466: //D3DXMatrixRotationY( &mWorld, 1.8f*PI/2 );    // 撮影アングル
0467: 
0468:     m = mWorld * mVP;
0469:     D3DXMatrixTranspose( &m ,  &m);
0470:     lpD3DDev->SetVertexShaderConstant(0,&m, 4);
0471:     m = mWorld * mLP;
0472:     D3DXMatrixTranspose( &m ,  &m);
0473:     lpD3DDev->SetVertexShaderConstant(4,&m, 4);
0474: 
0475:     D3DXMatrixInverse( &m,  NULL, &mWorld);
0476:     D3DXVec4Transform(&vl, &lightDir, &m);
0477:     D3DXVec4Normalize(&vl, &vl);
0478:     vl[3] = 0.3f;
0479:     lpD3DDev->SetVertexShaderConstant(13, &vl, 1);
0480:     
0481:     for(i=0;i<dwNumMaterials;i++){
0482:         //色をセット
0483:         D3DXVECTOR4 vl;
0484:         vl.x = pMeshMaterials[i].Diffuse.r;
0485:         vl.y = pMeshMaterials[i].Diffuse.g;
0486:         vl.z = pMeshMaterials[i].Diffuse.b;
0487:         lpD3DDev->SetVertexShaderConstant(14, &vl, 1);
0488: 
0489:         lpD3DDev->SetTexture(0,pMeshTextures[i]);
0490:         lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0491:                                         pSubsetTable[i].VertexStart,
0492:                                         pSubsetTable[i].VertexCount,
0493:                                         pSubsetTable[i].FaceStart * 3,
0494:                                         pSubsetTable[i].FaceCount);
0495:     }
0496:     
0497:     if(bShadowMap) lpD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
0498: }
0499: //-----------------------------------------------------------------------------
0500: // Name: Render()
0501: // Desc: Draw the scene
0502: //-----------------------------------------------------------------------------
0503: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev)
0504: {
0505:     DWORD i;
0506:     BOOL bShadowMap, bBg;
0507: 
0508:     LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0509: 
0510:     lpD3DDev->GetDepthStencilSurface( &lpZbuffer );
0511: 
0512:     // -----------------------------------------------------
0513:     // 深度と色の作成
0514:     // -----------------------------------------------------
0515:     // テクスチャーに描画
0516:     lpD3DDev->SetRenderTarget(pTextureSurface, lpZbuffer);
0517:     lpD3DDev->Clear(0,NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0),1.0f,0);
0518:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_MODULATE);
0519:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0520:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG2,  D3DTA_DIFFUSE);
0521:     lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0522:     lpD3DDev->SetVertexShader(hVertexShader);
0523:     lpD3DDev->SetPixelShader(hPixelShader);
0524:     bShadowMap = TRUE;
0525:     bBg = FALSE;
0526:     DrawModel(lpD3DDev, bShadowMap, bBg);
0527:     // -----------------------------------------------------
0528:     // 深度エッジの作成
0529:     // -----------------------------------------------------
0530:     lpD3DDev->SetRenderTarget(pTextureSurfaceEdge, NULL );
0531:     for (i = 0; i < 4; i++) {
0532:         lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSU,  D3DTADDRESS_CLAMP);
0533:         lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSV,  D3DTADDRESS_CLAMP);
0534:         lpD3DDev->SetTextureStageState(i, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0535:         lpD3DDev->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
0536:         lpD3DDev->SetTexture( i, pTexture );                    // テクスチャー
0537:     }
0538:     lpD3DDev->SetVertexShader(hVertexShaderEdge);
0539:     lpD3DDev->SetPixelShader(hPixelShaderEdge);
0540:     lpD3DDev->SetStreamSource( 0, pFinalVB, sizeof(D3D_FINAL_VERTEX) );
0541:     lpD3DDev->SetIndices(pFinalIB,0);
0542:     lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0543:     // -----------------------------------------------------
0544:     // 深度エッジをぼかす
0545:     // -----------------------------------------------------
0546:     lpD3DDev->SetRenderTarget(pTextureSurfaceBokashi, NULL );
0547:     for (i = 0; i < 4; i++) {
0548:         lpD3DDev->SetTexture( i, pTextureEdge );                    // テクスチャー
0549:     }
0550:     lpD3DDev->SetVertexShader(hVertexShaderBokashi);
0551:     lpD3DDev->SetPixelShader(hPixelShaderBokashi);
0552:     lpD3DDev->SetStreamSource( 0, pFinalVB, sizeof(D3D_FINAL_VERTEX) );
0553:     lpD3DDev->SetIndices(pFinalIB,0);
0554:     lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0555:     // -----------------------------------------------------
0556:     // 影の作成
0557:     // -----------------------------------------------------
0558:     // 描画をバックバッファに戻す
0559:     lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0560:     lpD3DDev->Clear(0,NULL,D3DCLEAR_ZBUFFER, 0,1.0f,0);
0561:     lpD3DDev->SetVertexShader(hFinalVertexShader);
0562:     lpD3DDev->SetPixelShader(hFinalPixelShader);
0563:     lpD3DDev->SetTexture( 1, pTexture );                    // 元テクスチャー   
0564:     lpD3DDev->SetTexture( 2, pTextureBokashi );             // ぼかしたエッジテクスチャー   
0565:     lpD3DDev->SetTexture( 3, NULL);
0566:     bShadowMap = FALSE;
0567:     bBg = TRUE;
0568:     DrawModel(lpD3DDev, bShadowMap, bBg);
0569:     
0570:     // 環境を綺麗にする
0571:     lpD3DDev->SetPixelShader(0);
0572:     lpD3DDev->SetTexture( 0, NULL);
0573:     lpD3DDev->SetTexture( 1, NULL);
0574:     lpD3DDev->SetTexture( 2, NULL);
0575:     lpD3DDev->SetTexture( 3, NULL);
0576: 
0577: #if 0
0578:     // 描画した画面をテクスチャーとして描く
0579:     {
0580:         struct TLVERTEX
0581:         {
0582:             float x,y,z,rhw;
0583:             float tu,tv;
0584:         };
0585:         #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)
0586:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0587:         lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0588:         lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0589:         float scale = 512.0f;
0590:         TLVERTEX Vertex[4] = {
0591:             // x  y  z rhw tu tv
0592:             {    0,    0,0, 1, 0, 0,},
0593:             {scale,    0,0, 1, 1, 0,},
0594:             {scale,scale,0, 1, 1, 1,},
0595:             {    0,scale,0, 1, 0, 1,},
0596:         };
0597:         lpD3DDev->SetTexture( 0, pTexture );            // 深度を見る
0598: //      lpD3DDev->SetTexture( 0, pTextureEdge );        // 深度エッジを見る
0599: //      lpD3DDev->SetTexture( 0, pTextureBokashi );     // ボケた深度エッジを見る
0600:         lpD3DDev->SetVertexShader( FVF_TLVERTEX );
0601:         lpD3DDev->SetPixelShader(0);
0602:         lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) );
0603:     }
0604: #endif
0605: }
0606: //-----------------------------------------------------------------------------
0607: // メッシュオブジェクト削除
0608: //-----------------------------------------------------------------------------
0609: void DeleteMeshObject(void)
0610: {
0611:     DWORD i;
0612: 
0613:     if(pMeshVB == NULL) return;
0614: 
0615:     for(i=0; i<dwNumMaterials; i++){
0616:         RELEASE(pMeshTextures[i]);
0617:     }
0618:     delete[] pMeshTextures;
0619:     delete[] pMeshMaterials;
0620:     delete[] pSubsetTable;
0621: 
0622:     RELEASE(pMeshVB);
0623:     RELEASE(pMeshIndex);
0624: }
0625: //-----------------------------------------------------------------------------
0626: // Name: CleanRender()
0627: // Desc: 後始末
0628: //-----------------------------------------------------------------------------
0629: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev)
0630: {
0631:     CleanBg(lpD3DDev);
0632:     
0633:     RELEASE(pTextureSurfaceBokashi);
0634:     RELEASE(pTextureBokashi);
0635:     RELEASE(pTextureSurfaceEdge);
0636:     RELEASE(pTextureEdge);
0637:     RELEASE(pTextureSurface);
0638:     RELEASE(pTexture);
0639:     RELEASE(pBackbuffer);
0640:     
0641:     RELEASE(pFinalIB);
0642:     RELEASE(pFinalVB);
0643:      CPixelShaderMgr::Release(lpD3DDev, &hFinalPixelShader);
0644:     CVertexShaderMgr::Release(lpD3DDev, &hFinalVertexShader);
0645:      CPixelShaderMgr::Release(lpD3DDev, &hPixelShaderBokashi);
0646:     CVertexShaderMgr::Release(lpD3DDev, &hVertexShaderBokashi);
0647:      CPixelShaderMgr::Release(lpD3DDev, &hPixelShaderEdge);
0648:     CVertexShaderMgr::Release(lpD3DDev, &hVertexShaderEdge);
0649:      CPixelShaderMgr::Release(lpD3DDev, &hPixelShader);
0650:     CVertexShaderMgr::Release(lpD3DDev, &hVertexShader);
0651: 
0652:     
0653:     DeleteMeshObject();
0654: }
0655: