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: