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: #define frand()   rand()/((float)RAND_MAX)
0017: 
0018: static const int SHADOWMAP_HEIGHT = 512;
0019: static const int SHADOWMAP_WIDTH = 512;
0020: 
0021: LPDIRECT3DVERTEXBUFFER8 pMeshVB = NULL;
0022: LPDIRECT3DINDEXBUFFER8  pMeshIndex = NULL;
0023: D3DXATTRIBUTERANGE      *pSubsetTable = NULL;
0024: DWORD                   nMeshFaces = 0;
0025: DWORD                   nMeshVertices = 0;
0026: D3DMATERIAL8            *pMeshMaterials = NULL;     // メッシュの質感
0027: LPDIRECT3DTEXTURE8      *pMeshTextures  = NULL;     // メッシュのテクスチャー
0028: DWORD                   dwNumMaterials = 0L;        // マテリアルの数
0029: FLOAT                   MeshRadius;                 // メッシュの大きさ
0030: 
0031: DWORD                   hVertexShader=~0;           // モデルの描画
0032: DWORD                   hPixelShader=~0;            // モデルの描画
0033: LPDIRECT3DCUBETEXTURE8  pNormalCubeMap=NULL;
0034: LPDIRECT3DCUBETEXTURE8  pCubeMap=NULL;
0035: 
0036: DWORD                   hDiffuseVertexShader=~0;    // モデルの描画
0037: DWORD                   hDiffusePixelShader=~0;     // モデルの描画
0038: LPDIRECT3DCUBETEXTURE8  pDiffuseMap=NULL;
0039: 
0040: LPDIRECT3DVERTEXBUFFER8 pBlurVB = NULL;
0041: LPDIRECT3DINDEXBUFFER8  pBlurIB = NULL;
0042: typedef struct {
0043:     float x,y,z;
0044:     float tu,tv;
0045: }D3D_BLUR_VERTEX;
0046: #define D3DFVF_BLUR_VERTEX      (D3DFVF_XYZ | D3DFVF_TEX1)
0047: 
0048: DWORD dwBlurDecl[] = {
0049:     D3DVSD_STREAM(0),
0050:     D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ),          //D3DVSDE_POSITION,  0
0051:     D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ),          //D3DVSDE_TEXCOORD0, 7  
0052:     D3DVSD_END()
0053: };
0054: 
0055: // ----------------------------------------------------------------------------
0056: // 外部関数
0057: void InitBg ( LPDIRECT3DDEVICE8 lpD3DDev );
0058: void DrawBg ( LPDIRECT3DDEVICE8 lpD3DDev );
0059: void CleanBg( LPDIRECT3DDEVICE8 lpD3DDev );
0060: 
0061: 
0062: 
0063: // ----------------------------------------------------------------------------
0064: // Name: LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDev)
0065: // Desc: X-Fileの読み込み
0066: //-----------------------------------------------------------------------------
0067: HRESULT LoadXFile(char* filename, LPDIRECT3DDEVICE8 lpD3DDev)
0068: {
0069:     LPD3DXMESH pMesh, pMeshOpt;
0070:     LPD3DXBUFFER pD3DXMtrlBuffer = NULL;
0071:     DWORD i;
0072:     HRESULT hr;
0073: 
0074:     hr = D3DXLoadMeshFromX(filename, D3DXMESH_MANAGED,
0075:                                 lpD3DDev, NULL,
0076:                                 &pD3DXMtrlBuffer, &dwNumMaterials,
0077:                                 &pMesh);
0078:     if(FAILED(hr)) return E_FAIL;
0079: 
0080:     //並び替えておく
0081:     pMesh->Optimize(D3DXMESHOPT_ATTRSORT, NULL, NULL, NULL, NULL, &pMeshOpt);
0082:     RELEASE(pMesh);
0083: 
0084:     //アトリビュートテーブル
0085:     pMeshOpt->GetAttributeTable(NULL,&dwNumMaterials);
0086:     pSubsetTable = new D3DXATTRIBUTERANGE[dwNumMaterials];
0087:     pMeshOpt->GetAttributeTable(pSubsetTable, &dwNumMaterials);
0088: 
0089:     // FVF変換
0090:     hr = pMeshOpt->CloneMeshFVF(pMeshOpt->GetOptions(), D3DFVF_VERTEX, lpD3DDev, &pMesh);
0091:     if(FAILED(hr)) return E_FAIL;
0092:     RELEASE(pMeshOpt);
0093:     D3DXComputeNormals(pMesh, NULL);
0094: 
0095:     //Vertex Bufferにコピーする
0096:     D3DVERTEX* pSrc;
0097:     D3D_CUSTOMVERTEX* pDest;
0098:     LPDIRECT3DINDEXBUFFER8 pSrcIndex;
0099:     WORD* pISrc;
0100:     WORD* pIDest;
0101: 
0102:     DWORD nMeshVertices = pMesh->GetNumVertices();
0103:     DWORD nMeshFaces = pMesh->GetNumFaces();
0104:     lpD3DDev->CreateVertexBuffer(nMeshVertices * sizeof(D3D_CUSTOMVERTEX),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED,&pMeshVB);
0105:     lpD3DDev->CreateIndexBuffer(nMeshFaces * 3 * sizeof(WORD),0,D3DFMT_INDEX16,D3DPOOL_MANAGED,&pMeshIndex);
0106: 
0107:     LPDIRECT3DVERTEXBUFFER8 pVB;
0108:     pMesh->GetVertexBuffer(&pVB);
0109:     pVB->Lock(0,0,(BYTE**)&pSrc,0);
0110:     pMeshVB->Lock(0,0,(BYTE**)&pDest,0);
0111:     MeshRadius = 0.0f;
0112:     for(i=0;i<nMeshVertices;i++){
0113:         pDest->x = pSrc->x;
0114:         pDest->y = pSrc->y;
0115:         pDest->z = pSrc->z;
0116:         pDest->nx = pSrc->nx;
0117:         pDest->ny = pSrc->ny;
0118:         pDest->nz = pSrc->nz;
0119:         pDest->tu0 = pSrc->tu0;
0120:         pDest->tu0 = pSrc->tu0;
0121:         // サイズの計算
0122:         FLOAT radius = sqrtf( pSrc->x*pSrc->x + pSrc->y*pSrc->y + pSrc->z*pSrc->z );
0123:         if (MeshRadius < radius) MeshRadius = radius;
0124:         
0125:         pSrc += 1;
0126:         pDest += 1;
0127:     }
0128:     pVB->Unlock();
0129:     pVB->Release();
0130:     pMeshVB->Unlock();
0131: 
0132:     //インデックスのコピー
0133:     pMesh->GetIndexBuffer(&pSrcIndex);
0134:     pSrcIndex->Lock(0,0,(BYTE**)&pISrc,0);
0135:     pMeshIndex->Lock(0,0,(BYTE**)&pIDest,0);
0136:     CopyMemory(pIDest,pISrc,nMeshFaces * 3 * sizeof(WORD));
0137:     pSrcIndex->Unlock();
0138:     pMeshIndex->Unlock();
0139:     pSrcIndex->Release();
0140: 
0141:     // pD3DXMtrlBuffer から、質感やテクスチャーの情報を読み取る
0142:     D3DXMATERIAL* d3dxMaterials = (D3DXMATERIAL*)pD3DXMtrlBuffer->GetBufferPointer();
0143:     pMeshTextures = new LPDIRECT3DTEXTURE8[dwNumMaterials];
0144:     pMeshMaterials = new D3DMATERIAL8[dwNumMaterials];
0145: 
0146:     for(i = 0; i < dwNumMaterials; i++){
0147:         pMeshMaterials[i] = d3dxMaterials[i].MatD3D;
0148:         pMeshMaterials[i].Ambient = pMeshMaterials[i].Diffuse;
0149:         hr = D3DXCreateTextureFromFile( lpD3DDev, 
0150:                                         d3dxMaterials[i].pTextureFilename, 
0151:                                         &pMeshTextures[i] );
0152:         if(FAILED(hr)) pMeshTextures[i] = NULL;
0153:     }
0154:     RELEASE(pD3DXMtrlBuffer);
0155:     
0156:     RELEASE(pMesh);
0157: 
0158:     return S_OK;
0159: }
0160: //-----------------------------------------------------------------------------
0161: // 正規化キューブマップの作成
0162: //-----------------------------------------------------------------------------
0163: void make_normalize_cubemap( D3DXVECTOR4 *pOut, D3DXVECTOR3 *pTexCoord,
0164: D3DXVECTOR3 *pTexelSize, LPVOID pData)
0165: {
0166:     D3DXVECTOR3 n;
0167:     D3DXVec3Normalize( &n, pTexCoord );
0168: 
0169:     pOut->x = 0.5f*(n.x + 1.0f);
0170:     pOut->y = 0.5f*(n.y + 1.0f);
0171:     pOut->z = 0.5f*(n.z + 1.0f);
0172:     pOut->w = 1.0f;
0173: }
0174: static const int BLUR_GRID = 10;
0175: static const float BLURSIZE = 1.0f;
0176: //-----------------------------------------------------------------------------
0177: // Name: InitRender()
0178: // Desc: Load the mesh and build the material and texture arrays
0179: //-----------------------------------------------------------------------------
0180: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0181: {
0182:     HRESULT hr;
0183: 
0184:     // モデルの読み込み
0185:     if ( FAILED(hr = LoadXFile("nsx.x", lpD3DDev)) ) return hr;
0186:     
0187:     // 頂点バッファの作成 
0188:     D3D_BLUR_VERTEX *pBlurDest;
0189:     lpD3DDev->CreateVertexBuffer( (BLUR_GRID+1)*(BLUR_GRID+1)*sizeof(D3DVERTEX),
0190:                                 D3DUSAGE_WRITEONLY, D3DFVF_VERTEX, D3DPOOL_MANAGED,
0191:                                 &pBlurVB );
0192:     // 頂点をセットアップ
0193:     {
0194:     pBlurVB->Lock ( 0, 0, (BYTE**)&pBlurDest, 0 );
0195:     float pos_z = -BLURSIZE;
0196:     for(DWORD z = 0; z <= BLUR_GRID; z++){
0197:         float pos_x = -BLURSIZE;
0198:         for(DWORD x = 0; x <= BLUR_GRID; x++){
0199:             pBlurDest->x  = pos_x;
0200:             pBlurDest->y  = pos_z;
0201:             pBlurDest->z  = 1.0f;
0202:             pBlurDest->tu = (pos_x+BLURSIZE)/(2.0f*BLURSIZE);
0203:             pBlurDest->tv = (pos_z+BLURSIZE)/(2.0f*BLURSIZE);
0204:             pBlurDest++;
0205:             pos_x += 2*BLURSIZE/BLUR_GRID;
0206:         }
0207:         pos_z += 2*BLURSIZE/BLUR_GRID;
0208:     }
0209:     pBlurVB->Unlock ();
0210:     }
0211: 
0212: 
0213:     // インデックスをセットアップ
0214:     WORD *pIndex;
0215:     lpD3DDev->CreateIndexBuffer( 3*2*BLUR_GRID*BLUR_GRID * sizeof(WORD),
0216:                                0,
0217:                                D3DFMT_INDEX16, D3DPOOL_MANAGED,
0218:                                &pBlurIB );
0219:     pBlurIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0220:     {
0221:     for (WORD i = 0; i < BLUR_GRID; i++) {
0222:         for (WORD j = 0; j < BLUR_GRID; j++) {
0223:             *pIndex++ = j + 0 + (i+0) * (BLUR_GRID+1);
0224:             *pIndex++ = j + 0 + (i+1) * (BLUR_GRID+1);
0225:             *pIndex++ = j + 1 + (i+0) * (BLUR_GRID+1);
0226: 
0227:             *pIndex++ = j + 1 + (i+0) * (BLUR_GRID+1);
0228:             *pIndex++ = j + 0 + (i+1) * (BLUR_GRID+1);
0229:             *pIndex++ = j + 1 + (i+1) * (BLUR_GRID+1);
0230:         }
0231:     }
0232:     }
0233: 
0234:     pBlurIB->Unlock ();
0235: 
0236:     
0237:     
0238:     // シェ-ダーのロード
0239:     if ( FAILED(CVertexShaderMgr::Load(lpD3DDev, "vs.vsh",     &hVertexShader, dwDecl)) ) return hr;
0240:     if ( FAILED( CPixelShaderMgr::Load(lpD3DDev, "ps.psh",     &hPixelShader)) ) return hr;
0241:     if ( FAILED(CVertexShaderMgr::Load(lpD3DDev, "diffuse.vsh",&hDiffuseVertexShader, dwBlurDecl)) ) return hr;
0242:     if ( FAILED( CPixelShaderMgr::Load(lpD3DDev, "diffuse.psh", &hDiffusePixelShader)) ) return hr;
0243:     
0244:     // 正規化キューブマップの作成
0245:     hr = lpD3DDev->CreateCubeTexture( 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
0246:                                 D3DPOOL_DEFAULT , &pNormalCubeMap );
0247:     if ( FAILED(hr) ) return hr;
0248:     hr = D3DXFillCubeTexture( pNormalCubeMap, make_normalize_cubemap, NULL );
0249:     if ( FAILED(hr) ) return hr;
0250: 
0251:     // 環境キューブマップの作成
0252:     hr = lpD3DDev->CreateCubeTexture( 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
0253:                                 D3DPOOL_DEFAULT , &pCubeMap );
0254:     if ( FAILED(hr) ) return hr;
0255:     // ディフューズマップの作成
0256:     hr = lpD3DDev->CreateCubeTexture( 512, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
0257:                                 D3DPOOL_DEFAULT , &pDiffuseMap );
0258:     if ( FAILED(hr) ) return hr;
0259: 
0260:     // 背景部分の初期化
0261:     InitBg(lpD3DDev);
0262: 
0263:     // 不変なレジスタの設定
0264:     lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE );
0265:     lpD3DDev->SetRenderState( D3DRS_LIGHTING,  FALSE );
0266:     lpD3DDev->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
0267:     lpD3DDev->SetVertexShaderConstant(12, &D3DXVECTOR4(0.0f, 0.5f, 1.0f, 2.0f), 1);
0268: 
0269:     lpD3DDev->SetTextureStageState(0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0270:     lpD3DDev->SetTextureStageState(1, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0271:     lpD3DDev->SetTextureStageState(2, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0272:     lpD3DDev->SetTextureStageState(3, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0273:     lpD3DDev->SetTextureStageState(0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0274:     lpD3DDev->SetTextureStageState(1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0275:     lpD3DDev->SetTextureStageState(2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0276:     lpD3DDev->SetTextureStageState(3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0277:     lpD3DDev->SetTextureStageState(0, D3DTSS_MIPFILTER, D3DTEXF_NONE);
0278:     lpD3DDev->SetTextureStageState(1, D3DTSS_MIPFILTER, D3DTEXF_NONE);
0279:     lpD3DDev->SetTextureStageState(2, D3DTSS_MIPFILTER, D3DTEXF_NONE);
0280:     lpD3DDev->SetTextureStageState(3, D3DTSS_MIPFILTER, D3DTEXF_NONE);
0281:     lpD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0282:     lpD3DDev->SetTextureStageState(0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0283:     lpD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0284:     lpD3DDev->SetTextureStageState(1, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0285:     lpD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0286:     lpD3DDev->SetTextureStageState(2, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0287:     lpD3DDev->SetTextureStageState(3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0288:     lpD3DDev->SetTextureStageState(3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0289: 
0290:     return S_OK;
0291: }
0292: //-----------------------------------------------------------------------------
0293: // Name: Render()
0294: // Desc: Draws the scene
0295: //-----------------------------------------------------------------------------
0296: const float z_min =   1.0f;
0297: const float z_max  = 80.0f;
0298: D3DXVECTOR4 lightDir(1.0f, 1.0f, 0.0, 0.0f);
0299: 
0300: VOID DrawModel( LPDIRECT3DDEVICE8 lpD3DDev )
0301: {
0302:     D3DXMATRIX mVP,  mWorld, mView,  mProj, mTex;
0303:     D3DXMATRIX mVPL, mLight, mViewL, mProjL;
0304:     D3DXMATRIX  m;
0305:     D3DXVECTOR4 vl;
0306:     DWORD i;
0307:     
0308:     D3DXVec4Normalize(&vl, &lightDir);
0309:     lpD3DDev->SetVertexShaderConstant(11, &vl, 1);
0310: 
0311:     // 
0312:     // 通常レンダリング用の行列を作成
0313:     // 
0314:     // ビュー行列
0315:     D3DXVECTOR3 eye    = D3DXVECTOR3(0.0f,1.4f*MeshRadius, 2.5f*MeshRadius);
0316:     D3DXVECTOR3 lookAt = D3DXVECTOR3(0.0f,  0.0f,  0.0f);
0317:     D3DXVECTOR3 up     = D3DXVECTOR3(0.0f,  1.0f,  0.0f);
0318:     D3DXMatrixLookAtLH(&mView, &eye, &lookAt, &up);
0319:     // 射影行列
0320:     D3DXMatrixPerspectiveFovLH(&mProj
0321:         , D3DXToRadian(60.0f)                       // 視野角
0322:         , (float)WIDTH/(float)HEIGHT                // アスペクト比
0323:         , z_min, z_max                              // 最近接距離,最遠方距離
0324:         );
0325:     
0326:     mVP = mView * mProj;
0327:     lpD3DDev->SetVertexShaderConstant( 15, &eye, 1);
0328: 
0329:     //
0330:     // 外側もでる描画
0331:     //
0332:     float t = 0.0001f*(timeGetTime()%10000);
0333:     D3DXMatrixTranslation(&m, 1.5f*MeshRadius, 0,0);
0334:     D3DXMatrixRotationY( &mWorld, 3.0f*2.0f*D3DX_PI*t );
0335: //D3DXMatrixRotationY( &mWorld, -0.2*PI/2 ); // 撮影角度
0336:     mWorld = m * mWorld;
0337:     
0338:     m = mWorld * mVP;
0339:     lpD3DDev->SetVertexShaderConstant( 0,D3DXMatrixTranspose(&m,&m), 4);
0340:     lpD3DDev->SetVertexShaderConstant( 4,D3DXMatrixTranspose(&m,&mWorld), 4);
0341: 
0342:     D3DXMatrixInverse( &m,  NULL, &mWorld);
0343:     D3DXVec4Transform(&vl, &lightDir, &m);
0344:     D3DXVec4Normalize(&vl, &vl);
0345:     vl.w = 0.3f;
0346:     lpD3DDev->SetVertexShaderConstant(13, &vl, 1);
0347:     
0348:     lpD3DDev->SetStreamSource(0, pMeshVB, sizeof(D3D_CUSTOMVERTEX));
0349:     lpD3DDev->SetIndices(pMeshIndex,0);
0350:     
0351:     for(i=0;i<dwNumMaterials;i++){
0352:         //色をセット
0353:         D3DXVECTOR4 vl;
0354:         vl.x = pMeshMaterials[i].Diffuse.r;
0355:         vl.y = pMeshMaterials[i].Diffuse.g;
0356:         vl.z = pMeshMaterials[i].Diffuse.b;
0357:         lpD3DDev->SetVertexShaderConstant(14, &vl, 1);
0358: 
0359:         lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0360:                                         pSubsetTable[i].VertexStart,
0361:                                         pSubsetTable[i].VertexCount,
0362:                                         pSubsetTable[i].FaceStart * 3,
0363:                                         pSubsetTable[i].FaceCount);
0364:     }
0365:     //
0366:     // 内側モデル
0367:     //
0368:     D3DXMatrixRotationY( &mWorld, -1.0f*2.0f*D3DX_PI*t );
0369: //D3DXMatrixRotationY( &mWorld,-1.10f*PI/2 ); // 撮影角度
0370: 
0371:     m = mWorld * mVP;
0372:     lpD3DDev->SetVertexShaderConstant( 0,D3DXMatrixTranspose(&m,&m), 4);
0373:     lpD3DDev->SetVertexShaderConstant( 4,D3DXMatrixTranspose(&m,&mWorld), 4);
0374: 
0375:     D3DXMatrixInverse( &m,  NULL, &mWorld);
0376:     D3DXVec4Transform(&vl, &lightDir, &m);
0377:     D3DXVec4Normalize(&vl, &vl);
0378:     lpD3DDev->SetVertexShaderConstant(13, &vl, 1);
0379:     
0380:     for(i=0;i<dwNumMaterials;i++){
0381:         //色をセット
0382:         D3DXVECTOR4 vl;
0383:         vl.x = pMeshMaterials[i].Diffuse.r;
0384:         vl.y = pMeshMaterials[i].Diffuse.g;
0385:         vl.z = pMeshMaterials[i].Diffuse.b;
0386:         lpD3DDev->SetVertexShaderConstant(14, &vl, 1);
0387: 
0388:         lpD3DDev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 
0389:                                         pSubsetTable[i].VertexStart,
0390:                                         pSubsetTable[i].VertexCount,
0391:                                         pSubsetTable[i].FaceStart * 3,
0392:                                         pSubsetTable[i].FaceCount);
0393:     }
0394: 
0395:     //
0396:     // 背景描画
0397:     // 
0398:     D3DXMatrixIdentity(&mWorld);
0399:     lpD3DDev->SetTransform(D3DTS_WORLD, &mWorld);
0400:     lpD3DDev->SetTransform(D3DTS_VIEW,  &mView);
0401:     lpD3DDev->SetTransform(D3DTS_PROJECTION, &mProj);
0402:     lpD3DDev->SetTexture( 1, NULL );
0403:     lpD3DDev->SetTexture( 2, NULL );
0404:     lpD3DDev->SetPixelShader (  0 );
0405: 
0406:     DrawBg(lpD3DDev);
0407: }
0408: //-----------------------------------------------------------------------------
0409: // Name: MakeCubeMap()
0410: // Desc: 環境マップを作成する
0411: //-----------------------------------------------------------------------------
0412: VOID MakeCubeMap(LPDIRECT3DDEVICE8 lpD3DDev )
0413: {
0414:     // デバイスのトランスフォーム行列を保存する。
0415:     D3DXMATRIX matProjSave, matViewSave;
0416:     lpD3DDev->GetTransform( D3DTS_VIEW,       &matViewSave );
0417:     lpD3DDev->GetTransform( D3DTS_PROJECTION, &matProjSave );
0418: 
0419:     // 現在のバック バッファと z バッファを格納する。
0420:     LPDIRECT3DSURFACE8 pBackBuffer, pZBuffer;
0421:     lpD3DDev->GetRenderTarget( &pBackBuffer );
0422:     lpD3DDev->GetDepthStencilSurface( &pZBuffer );
0423: 
0424:     // 90°の視野を射影に使用する。
0425:     D3DXMATRIX matProj;
0426:     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 0.5f, 1000.0f );
0427:     lpD3DDev->SetTransform( D3DTS_PROJECTION, &matProj );
0428: 
0429:     // キューブ マップの 6 つのサーフェスに対してループ処理を実行する。
0430:     for( DWORD i=0 ; i<6 ; i++ ) {
0431:         D3DXVECTOR3 vEnvEyePt = D3DXVECTOR3( 0.0f, 10.0f, 0.0f );
0432:         D3DXVECTOR3 vLookatPt, vUpVec;
0433: 
0434:         switch( i ){
0435:         case D3DCUBEMAP_FACE_POSITIVE_X:
0436:             vLookatPt = D3DXVECTOR3( 1.0f, 0.0f, 0.0f )+vEnvEyePt;
0437:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0438:             break;
0439:         case D3DCUBEMAP_FACE_NEGATIVE_X:
0440:             vLookatPt = D3DXVECTOR3(-1.0f, 0.0f, 0.0f )+vEnvEyePt;
0441:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0442:             break;
0443:         case D3DCUBEMAP_FACE_POSITIVE_Y:
0444:             vLookatPt = D3DXVECTOR3( 0.0f, 1.0f, 0.0f )+vEnvEyePt;
0445:             vUpVec    = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
0446:             break;
0447:         case D3DCUBEMAP_FACE_NEGATIVE_Y:
0448:             vLookatPt = D3DXVECTOR3( 0.0f,-1.0f, 0.0f )+vEnvEyePt;
0449:             vUpVec    = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
0450:             break;
0451:         case D3DCUBEMAP_FACE_POSITIVE_Z:
0452:             vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 1.0f )+vEnvEyePt;
0453:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0454:             break;
0455:         case D3DCUBEMAP_FACE_NEGATIVE_Z:
0456:             vLookatPt = D3DXVECTOR3( 0.0f, 0.0f,-1.0f )+vEnvEyePt;
0457:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0458:             break;
0459:         }
0460: 
0461:         D3DXMATRIX matView;
0462:         D3DXMatrixLookAtLH( &matView, &vEnvEyePt, &vLookatPt, &vUpVec );
0463:         lpD3DDev->SetTransform( D3DTS_VIEW, &matView );
0464: 
0465:         //レンダリングするサーフェスへのポインタを取得する。
0466:         LPDIRECT3DSURFACE8 pFace;
0467:         pCubeMap->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pFace );
0468:         lpD3DDev->SetRenderTarget ( pFace , pZBuffer );
0469:         pFace->Release();
0470: 
0471:         lpD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000, 1.0f, 0L);
0472:         lpD3DDev->BeginScene();
0473:         // ここで、シーンをレンダリングする。
0474:         DrawBg(lpD3DDev);
0475:         lpD3DDev->EndScene();
0476:     }
0477: 
0478:     // レンダリング ターゲットをメイン バック バッファに戻す。
0479:     lpD3DDev->SetRenderTarget( pBackBuffer, pZBuffer );
0480:     pBackBuffer->Release();
0481:     pZBuffer->Release();
0482: 
0483:     // 元のトランスフォーム行列をリストアする。
0484:     lpD3DDev->SetTransform( D3DTS_VIEW,       &matViewSave );
0485:     lpD3DDev->SetTransform( D3DTS_PROJECTION, &matProjSave );
0486: }
0487: //-----------------------------------------------------------------------------
0488: // Name: MakeDiffuseMap()
0489: // Desc: 拡散マップを作成する
0490: //-----------------------------------------------------------------------------
0491: VOID MakeDiffuseMap(LPDIRECT3DDEVICE8 lpD3DDev
0492:                     , LPDIRECT3DCUBETEXTURE8 pDiffuseMap
0493:                     , LPDIRECT3DCUBETEXTURE8 pEnvMap )
0494: {
0495:     static int n = 0;
0496:     
0497:     if(256<=n)return;
0498:     n++;
0499: 
0500:     lpD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
0501:     lpD3DDev->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0502:     lpD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0503:     lpD3DDev->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0504:     lpD3DDev->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0505:     lpD3DDev->SetTextureStageState(2, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0506:     lpD3DDev->SetTextureStageState(3, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0507:     lpD3DDev->SetTextureStageState(3, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0508: 
0509:     lpD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
0510:     lpD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
0511:     lpD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
0512:     lpD3DDev->SetVertexShader( hDiffuseVertexShader );
0513:     lpD3DDev->SetPixelShader ( hDiffusePixelShader );
0514:     lpD3DDev->SetTexture( 0, pEnvMap );
0515:     lpD3DDev->SetTexture( 1, pEnvMap );
0516:     lpD3DDev->SetTexture( 2, pEnvMap );
0517:     lpD3DDev->SetTexture( 3, pEnvMap );
0518: 
0519:     // デバイスのトランスフォーム行列を保存する。
0520:     D3DXMATRIX matProjSave, matViewSave;
0521:     lpD3DDev->GetTransform( D3DTS_VIEW,       &matViewSave );
0522:     lpD3DDev->GetTransform( D3DTS_PROJECTION, &matProjSave );
0523: 
0524:     // 現在のバック バッファと z バッファを格納する。
0525:     LPDIRECT3DSURFACE8 pBackBuffer, pZBuffer;
0526:     lpD3DDev->GetRenderTarget( &pBackBuffer );
0527:     lpD3DDev->GetDepthStencilSurface( &pZBuffer );
0528: 
0529:     // 90°の視野を射影に使用する。
0530:     D3DXMATRIX matProj;
0531:     D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/2, 1.0f, 0.5f, 1000.0f );
0532:     lpD3DDev->SetTransform( D3DTS_PROJECTION, &matProj );
0533: 
0534:     // キューブ マップの 6 つのサーフェスに対してループ処理を実行する。
0535:     for( DWORD i=0 ; i<6 ; i++ ) {
0536:         D3DXVECTOR3 vEnvEyePt = D3DXVECTOR3( 0.0f, 10.0f, 0.0f );
0537:         D3DXVECTOR3 vLookatPt, vUpVec;
0538: 
0539:         switch( i ){
0540:         case D3DCUBEMAP_FACE_POSITIVE_X:
0541:             vLookatPt = D3DXVECTOR3( 1.0f, 0.0f, 0.0f )+vEnvEyePt;
0542:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0543:             break;
0544:         case D3DCUBEMAP_FACE_NEGATIVE_X:
0545:             vLookatPt = D3DXVECTOR3(-1.0f, 0.0f, 0.0f )+vEnvEyePt;
0546:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0547:             break;
0548:         case D3DCUBEMAP_FACE_POSITIVE_Y:
0549:             vLookatPt = D3DXVECTOR3( 0.0f, 1.0f, 0.0f )+vEnvEyePt;
0550:             vUpVec    = D3DXVECTOR3( 0.0f, 0.0f,-1.0f );
0551:             break;
0552:         case D3DCUBEMAP_FACE_NEGATIVE_Y:
0553:             vLookatPt = D3DXVECTOR3( 0.0f,-1.0f, 0.0f )+vEnvEyePt;
0554:             vUpVec    = D3DXVECTOR3( 0.0f, 0.0f, 1.0f );
0555:             break;
0556:         case D3DCUBEMAP_FACE_POSITIVE_Z:
0557:             vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 1.0f )+vEnvEyePt;
0558:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0559:             break;
0560:         case D3DCUBEMAP_FACE_NEGATIVE_Z:
0561:             vLookatPt = D3DXVECTOR3( 0.0f, 0.0f,-1.0f )+vEnvEyePt;
0562:             vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
0563:             break;
0564:         }
0565: 
0566:         D3DXMATRIX matView;
0567:         D3DXMatrixLookAtLH( &matView, &vEnvEyePt, &vLookatPt, &vUpVec );
0568:         lpD3DDev->SetTransform( D3DTS_VIEW, &matView );
0569: 
0570:         D3DXMATRIX m = matView * matProj;
0571:         D3DXMatrixInverse( &m,  NULL, &m);
0572:         lpD3DDev->SetVertexShaderConstant( 8, D3DXMatrixTranspose(&m,&m), 4);
0573: 
0574:         //レンダリングするサーフェスへのポインタを取得する。
0575:         LPDIRECT3DSURFACE8 pFace;
0576:         pDiffuseMap->GetCubeMapSurface( (D3DCUBEMAP_FACES)i, 0, &pFace );
0577:         lpD3DDev->SetRenderTarget ( pFace , pZBuffer );
0578:         pFace->Release();
0579: 
0580:         if(1==n){
0581:             lpD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000, 1.0f, 0L);
0582:         }
0583:         lpD3DDev->BeginScene();
0584:         
0585:         // 等方的サンプリング (Thanks Bee さん)
0586:         D3DXVECTOR4 l[4];
0587:         for(int k=0;k<4;k++){
0588:             float d;
0589:             l[k].w = 0;
0590:             do{
0591:                 l[k].x = 2.0f*frand()-1.0f; 
0592:                 l[k].y = 2.0f*frand()-1.0f; 
0593:                 l[k].z = 2.0f*frand()-1.0f;
0594:                 d = D3DXVec4LengthSq(&l[k]);
0595:             }while(1.0f<d);
0596:         }
0597:         D3DXVec4Normalize(&l[0], &l[0]);
0598:         D3DXVec4Normalize(&l[1], &l[1]);
0599:         D3DXVec4Normalize(&l[2], &l[2]);
0600:         D3DXVec4Normalize(&l[3], &l[3]);
0601:         lpD3DDev->SetVertexShaderConstant(32, l, 4);
0602:         lpD3DDev->SetPixelShaderConstant(1, &D3DXVECTOR4(0,0,0,1.0f/n), 1);
0603: 
0604:         lpD3DDev->SetStreamSource( 0, pBlurVB, sizeof(D3D_BLUR_VERTEX) );
0605:         lpD3DDev->SetIndices(pBlurIB,0);
0606:         lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0,
0607:                             (BLUR_GRID+1)*(BLUR_GRID+1), 0, 2*BLUR_GRID*BLUR_GRID );
0608: 
0609:         lpD3DDev->EndScene();
0610:     }
0611:     lpD3DDev->SetTexture( 0, NULL );
0612:     lpD3DDev->SetTexture( 1, NULL );
0613:     lpD3DDev->SetTexture( 2, NULL );
0614:     lpD3DDev->SetTexture( 3, NULL );
0615: 
0616:     // レンダリング ターゲットをメイン バック バッファに戻す。
0617:     lpD3DDev->SetRenderTarget( pBackBuffer, pZBuffer );
0618:     pBackBuffer->Release();
0619:     pZBuffer->Release();
0620: 
0621:     // 元のトランスフォーム行列をリストアする。
0622:     lpD3DDev->SetTransform( D3DTS_VIEW,       &matViewSave );
0623:     lpD3DDev->SetTransform( D3DTS_PROJECTION, &matProjSave );
0624:     lpD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
0625: }
0626: //-----------------------------------------------------------------------------
0627: // Name: Render()
0628: // Desc: Draws the scene
0629: //-----------------------------------------------------------------------------
0630: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev)
0631: {
0632:     static int init=0;
0633:     if(!init){init=1;
0634:         MakeCubeMap(lpD3DDev);
0635:     }
0636:     // ディフューズマップを半リアルタイムに作成する
0637:     MakeDiffuseMap(lpD3DDev, pDiffuseMap, pCubeMap);
0638:     
0639:     // シーン開始
0640:     lpD3DDev->BeginScene();
0641: 
0642:     // ------------------------------------------------------------------------
0643:     // シーンの作成
0644:     // ------------------------------------------------------------------------
0645:     lpD3DDev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x000000, 1.0f, 0L);
0646: 
0647:     lpD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE );
0648:     lpD3DDev->SetTextureStageState(0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0649:     lpD3DDev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0650:     lpD3DDev->SetTextureStageState(1, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0651:     lpD3DDev->SetTextureStageState(2, D3DTSS_COLORARG1, D3DTA_TEXTURE );
0652:     lpD3DDev->SetTextureStageState(2, D3DTSS_COLOROP,   D3DTOP_SELECTARG1);
0653:     lpD3DDev->SetTextureStageState(3, D3DTSS_COLOROP,   D3DTOP_DISABLE);
0654:     lpD3DDev->SetVertexShader( hVertexShader );
0655:     lpD3DDev->SetPixelShader (  hPixelShader );
0656:     lpD3DDev->SetTexture( 0, pDiffuseMap );
0657: //  lpD3DDev->SetTexture( 1, pNormalCubeMap );
0658: //  lpD3DDev->SetTexture( 2, pNormalCubeMap );
0659: 
0660:     DrawModel(lpD3DDev );
0661:     
0662:     // 他でレンダリングしても問題が出ない設定にする
0663:     lpD3DDev->SetTexture( 0, NULL );
0664:     lpD3DDev->SetTexture( 1, NULL );
0665:     lpD3DDev->SetTexture( 2, NULL );
0666:     lpD3DDev->SetPixelShader(0);
0667: #if 1
0668:     //-----------------------------------------------------------------------------
0669:     // デバッグ用、適当にテクスチャーを表示する
0670:     //-----------------------------------------------------------------------------
0671:     struct TLVERTEX {
0672:         float x,y,z,rhw;
0673:         float tu,tv,tr;
0674:     };
0675:     #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1)
0676: 
0677:     float scale = 64.0f;
0678:     TLVERTEX Vertex[6][4] = {
0679:         {
0680:             //   x     y     z rhw tu tv tr
0681:             {0*scale,1*scale,0, 1, -1, 1,-1,},
0682:             {1*scale,1*scale,0, 1, -1, 1, 1,},
0683:             {1*scale,2*scale,0, 1, -1,-1, 1,},
0684:             {0*scale,2*scale,0, 1, -1,-1,-1,},
0685:         },{
0686:             //   x     y     z rhw tu tv tr
0687:             {1*scale,1*scale,0, 1, -1, 1, 1,},
0688:             {2*scale,1*scale,0, 1,  1, 1, 1,},
0689:             {2*scale,2*scale,0, 1,  1,-1, 1,},
0690:             {1*scale,2*scale,0, 1, -1,-1, 1,},
0691:         },{
0692:             //   x     y     z rhw tu tv tr
0693:             {2*scale,1*scale,0, 1,  1, 1, 1,},
0694:             {3*scale,1*scale,0, 1,  1, 1,-1,},
0695:             {3*scale,2*scale,0, 1,  1,-1,-1,},
0696:             {2*scale,2*scale,0, 1,  1,-1, 1,},
0697:         },{
0698:             //   x     y     z rhw tu tv tr
0699:             {3*scale,1*scale,0, 1,  1, 1,-1,},
0700:             {4*scale,1*scale,0, 1, -1, 1,-1,},
0701:             {4*scale,2*scale,0, 1, -1,-1,-1,},
0702:             {3*scale,2*scale,0, 1,  1,-1,-1,},
0703:         },{
0704:             //   x     y     z rhw tu tv tr
0705:             {1*scale,0*scale,0, 1, -1, 1,-1,},
0706:             {2*scale,0*scale,0, 1,  1, 1,-1,},
0707:             {2*scale,1*scale,0, 1,  1, 1, 1,},
0708:             {1*scale,1*scale,0, 1, -1, 1, 1,},
0709:         },{
0710:             //   x     y     z rhw tu tv tr
0711:             {1*scale,2*scale,0, 1, -1,-1, 1,},
0712:             {2*scale,2*scale,0, 1,  1,-1, 1,},
0713:             {2*scale,3*scale,0, 1,  1,-1,-1,},
0714:             {1*scale,3*scale,0, 1, -1,-1,-1,},
0715:         },
0716:     };
0717: 
0718:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLOROP,    D3DTOP_SELECTARG1);
0719:     lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0720:     lpD3DDev->SetTextureStageState(1,D3DTSS_COLOROP,    D3DTOP_DISABLE);
0721:     lpD3DDev->SetVertexShader( FVF_TLVERTEX | D3DFVF_TEXCOORDSIZE3(0) );
0722:     lpD3DDev->SetPixelShader(0);
0723: 
0724:     for( int n=0 ; n<2 ; n++ ){
0725:         if(0==n){
0726:             lpD3DDev->SetTexture( 0, pCubeMap );
0727:         }else{
0728:             lpD3DDev->SetTexture( 0, pDiffuseMap );
0729:         }
0730:         for(int i=0;i<6;i++){
0731:             lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_DIFFUSE);
0732:             lpD3DDev->DrawPrimitiveUP( D3DPT_LINELIST, 2, Vertex[i], sizeof( TLVERTEX ) );
0733:             lpD3DDev->SetTextureStageState(0,D3DTSS_COLORARG1,  D3DTA_TEXTURE);
0734:             lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex[i], sizeof( TLVERTEX ) );
0735:             
0736:             Vertex[i][0].x += 4*scale;
0737:             Vertex[i][1].x += 4*scale;
0738:             Vertex[i][2].x += 4*scale;
0739:             Vertex[i][3].x += 4*scale;
0740:         }
0741:     }
0742: #endif
0743:     // シーン終了
0744:     lpD3DDev->EndScene();
0745: }
0746: //-----------------------------------------------------------------------------
0747: // メッシュオブジェクト削除
0748: //-----------------------------------------------------------------------------
0749: void DeleteMeshObject(void)
0750: {
0751:     DWORD i;
0752: 
0753:     if(pMeshVB == NULL) return;
0754: 
0755:     for(i=0; i<dwNumMaterials; i++){
0756:         RELEASE(pMeshTextures[i]);
0757:     }
0758:     delete[] pMeshTextures;
0759:     delete[] pMeshMaterials;
0760:     delete[] pSubsetTable;
0761: 
0762:     RELEASE(pMeshVB);
0763:     RELEASE(pMeshIndex);
0764: }
0765: //-----------------------------------------------------------------------------
0766: // Name: CleanRender()
0767: // Desc: 後始末
0768: //-----------------------------------------------------------------------------
0769: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev)
0770: {
0771:     CleanBg(lpD3DDev);
0772:     
0773:     CPixelShaderMgr::Release(lpD3DDev, &hDiffusePixelShader);
0774:     CVertexShaderMgr::Release(lpD3DDev, &hDiffuseVertexShader);
0775:     CPixelShaderMgr::Release(lpD3DDev, &hPixelShader);
0776:     CVertexShaderMgr::Release(lpD3DDev, &hVertexShader);
0777: 
0778:     RELEASE(pDiffuseMap);
0779:     RELEASE(pCubeMap);
0780:     RELEASE(pNormalCubeMap);
0781: 
0782:     
0783:     RELEASE(pBlurIB);
0784:     RELEASE(pBlurVB);
0785: 
0786:     DeleteMeshObject();
0787: }
0788: