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(¢, ¢, &mVPm); D3DXVec4Scale(¢, ¢, 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*)¢, (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: