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