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: // 座標変換テーブル 0017: LPDIRECT3DTEXTURE8 pTransTexture=NULL; 0018: 0019: // テクスチャーレンダリングのためのオブジェクト 0020: LPDIRECT3DSURFACE8 pBackbuffer = NULL; 0021: DWORD hVertexShader=~0; 0022: DWORD hPixelShader=~0; 0023: LPDIRECT3DVERTEXBUFFER8 pVB = NULL; 0024: LPDIRECT3DINDEXBUFFER8 pIB = NULL; 0025: 0026: const int nTempTex = 2; 0027: LPDIRECT3DTEXTURE8 pTmpTexture[nTempTex]; 0028: LPDIRECT3DSURFACE8 pTmpSurface[nTempTex]; 0029: 0030: LPDIRECT3DTEXTURE8 pInitTexture=NULL; // 初期化テクスチャー 0031: 0032: // ---------------------------------------------------------------------------- 0033: // 頂点の定義 0034: typedef struct { 0035: float x,y,z; 0036: float tu,tv; 0037: }D3D_MY_VERTEX; 0038: #define D3DFVF_MY_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1) 0039: 0040: DWORD dwMyDecl[] = { 0041: D3DVSD_STREAM(0), 0042: D3DVSD_REG(D3DVSDE_POSITION, D3DVSDT_FLOAT3 ), //D3DVSDE_POSITION, 0 0043: D3DVSD_REG(D3DVSDE_TEXCOORD0,D3DVSDT_FLOAT2 ), //D3DVSDE_TEXCOORD0, 7 0044: D3DVSD_END() 0045: }; 0046: 0047: //----------------------------------------------------------------------------- 0048: // Name: InitRenderingTexture() 0049: // Desc: テクスチャー描画用の下準備 0050: //----------------------------------------------------------------------------- 0051: HRESULT InitRenderingTexture(LPDIRECT3DDEVICE8 lpD3DDev) 0052: { 0053: HRESULT hr; 0054: DWORD i; 0055: 0056: // 頂点バッファの作成 0057: D3D_MY_VERTEX *pBlurDest; 0058: WORD *pIndex; 0059: lpD3DDev->CreateVertexBuffer( 4 * sizeof(D3D_MY_VERTEX), 0060: D3DUSAGE_WRITEONLY, D3DFVF_MY_VERTEX, D3DPOOL_MANAGED, 0061: &pVB ); 0062: // 頂点をセットアップ 0063: pVB->Lock ( 0, 0, (BYTE**)&pBlurDest, 0 ); 0064: for (i = 0; i < 4; i++) { 0065: pBlurDest->x = (i == 0 || i == 1)?-1:(float)1; 0066: pBlurDest->y = (i == 0 || i == 2)?-1:(float)1; 0067: pBlurDest->z = 0.5f; 0068: pBlurDest->tu = (i == 2 || i == 3)?1:(float)0; 0069: pBlurDest->tv = (i == 0 || i == 2)?1:(float)0; 0070: pBlurDest++; 0071: } 0072: pVB->Unlock (); 0073: // インデックスをセットアップ 0074: lpD3DDev->CreateIndexBuffer( 6 * sizeof(WORD), 0075: 0, 0076: D3DFMT_INDEX16, D3DPOOL_MANAGED, 0077: &pIB ); 0078: pIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 ); 0079: pIndex[0] = 0; pIndex[1] = 1; pIndex[2] = 2; 0080: pIndex[3] = 1; pIndex[4] = 3; pIndex[5] = 2; 0081: pIB->Unlock (); 0082: 0083: // 描画用テクスチャーを用意する 0084: D3DSURFACE_DESC Desc; 0085: LPDIRECT3DSURFACE8 lpZbuffer = NULL; 0086: if( FAILED(hr = lpD3DDev->GetRenderTarget(&pBackbuffer))) return hr; 0087: if( FAILED(hr = pBackbuffer->GetDesc( &Desc ))) return hr; 0088: 0089: // 深度バッファのサーフェスを確保する 0090: if( FAILED(hr = lpD3DDev->GetDepthStencilSurface( &lpZbuffer ))) return hr; 0091: 0092: // テクスチャー作成用のリソースを確保する 0093: for (i = 0; i < nTempTex; ++i) { 0094: // テクスチャーの生成 0095: if( FAILED(hr = lpD3DDev->CreateTexture(Desc.Width, Desc.Height, 1 0096: , D3DUSAGE_RENDERTARGET, Desc.Format, D3DPOOL_DEFAULT, &pTmpTexture[i]))) return hr; 0097: // テクスチャーとサーフェスを関連づける 0098: if( FAILED(hr = pTmpTexture[i]->GetSurfaceLevel(0,&pTmpSurface[i]))) return hr; 0099: // テクスチャー用の描画と深度バッファを関連付ける 0100: if( FAILED(hr = lpD3DDev->SetRenderTarget(pTmpSurface[i], NULL ))) return hr; 0101: } 0102: 0103: // 描画を元の画面に戻す 0104: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer ); 0105: 0106: // シェ-ダーのロード 0107: if ( FAILED(CVertexShaderMgr::Load(lpD3DDev, "vs.vsh", &hVertexShader, dwMyDecl)) ) return hr; 0108: if ( FAILED( CPixelShaderMgr::Load(lpD3DDev, "ps.psh", &hPixelShader)) ) return hr; 0109: 0110: return S_OK; 0111: } 0112: //----------------------------------------------------------------------------- 0113: // Name: MakeInitTexture() 0114: // Desc: 座標変換マップ 0115: //----------------------------------------------------------------------------- 0116: VOID MakeInitTexture(D3DXVECTOR4* pOut, D3DXVECTOR2 *pTexCoord, D3DXVECTOR2 *pTexelSize, LPVOID pData) 0117: { 0118: float x = 2*pTexCoord->x-1; 0119: float y = 2*pTexCoord->y-1; 0120: 0121: float dx = 5.0f*((0<x)?x:-x); 0122: float dy = 5.0f*((0<y)?y:-y); 0123: 0124: while(1.0f<=dx)dx -= 1.0f; 0125: while(1.0f<=dy)dy -= 1.0f; 0126: float f = max(dx,dy); 0127: 0128: pOut->x = (0<x )?f:0; 0129: pOut->y = (0<y )?f:0; 0130: pOut->z = (0<x*y)?f:0; 0131: pOut->w = 1.0f; 0132: } 0133: 0134: //----------------------------------------------------------------------------- 0135: // Name: MakeTexture() 0136: // Desc: 座標変換マップ 0137: //----------------------------------------------------------------------------- 0138: VOID MakeTexture(D3DXVECTOR4* pOut, D3DXVECTOR2 *pTexCoord, D3DXVECTOR2 *pTexelSize, LPVOID pData) 0139: { 0140: float x = 2*pTexCoord->x-1; 0141: float y = 2*pTexCoord->y-1; 0142: float Ar = 0.378f; 0143: float Ai = 0.183f; 0144: 0145: float x1 = x*x-y*y+Ar; 0146: float y1 = 2*x*y+Ai; 0147: 0148: min(1,max(x1,0)); 0149: min(1,max(y1,0)); 0150: 0151: pOut->x = 0.0f; 0152: pOut->y = 0.5f*x1+0.5f; 0153: pOut->z = 0.5f*y1+0.5; 0154: pOut->w = 1.0f; 0155: } 0156: 0157: //----------------------------------------------------------------------------- 0158: // Name: InitRender() 0159: // Desc: Load the mesh and build the material and texture arrays 0160: //----------------------------------------------------------------------------- 0161: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev) 0162: { 0163: DWORD i; 0164: HRESULT hr; 0165: 0166: // 変換テクスチャー 0167: if( FAILED(hr = lpD3DDev->CreateTexture(512, 512, 1 0168: , D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8 0169: , D3DPOOL_DEFAULT, &pTransTexture))) return hr; 0170: if( FAILED(hr = D3DXFillTexture(pTransTexture, MakeTexture, NULL))) return hr; 0171: 0172: // 初期化テクスチャー 0173: if( FAILED(hr = lpD3DDev->CreateTexture(512, 512, 1 0174: , D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8 0175: , D3DPOOL_DEFAULT, &pInitTexture))) return hr; 0176: if( FAILED(hr = D3DXFillTexture(pInitTexture, MakeInitTexture, NULL))) return hr; 0177: 0178: // ぼけテクスチャー用の初期化 0179: InitRenderingTexture(lpD3DDev); 0180: 0181: // 不変なレジスタの設定 0182: lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE ); 0183: lpD3DDev->SetRenderState( D3DRS_LIGHTING, FALSE ); 0184: lpD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); 0185: lpD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); 0186: for (i = 0; i < 1; ++i) { 0187: lpD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); 0188: lpD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR); 0189: lpD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_NONE); 0190: lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP); 0191: lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP); 0192: } 0193: 0194: 0195: return S_OK; 0196: } 0197: 0198: //----------------------------------------------------------------------------- 0199: // Name: Render() 0200: // Desc: Draws the scene 0201: //----------------------------------------------------------------------------- 0202: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev) 0203: { 0204: Sleep(50); 0205: D3DXMATRIX mWorld, mView, mProj, m; 0206: 0207: static int idx = 0; 0208: idx=1-idx; 0209: 0210: LPDIRECT3DSURFACE8 lpZbuffer = NULL; 0211: lpD3DDev->GetDepthStencilSurface( &lpZbuffer ); 0212: lpD3DDev->SetRenderTarget(pTmpSurface[idx], lpZbuffer); 0213: lpD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0),1.0f,0); 0214: 0215: lpD3DDev->SetTexture(0, pTransTexture); 0216: lpD3DDev->SetTexture(1, pTmpTexture[1-idx]); 0217: lpD3DDev->SetVertexShader(hVertexShader); 0218: lpD3DDev->SetPixelShader(hPixelShader); 0219: lpD3DDev->SetStreamSource(0, pVB, sizeof(D3D_MY_VERTEX)); 0220: lpD3DDev->SetIndices(pIB,0); 0221: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 ); 0222: 0223: static int init=1; 0224: if(init){// 初期化として、変換テクスチャーを最初の模様に設定する 0225: init--; 0226: struct TLVERTEX 0227: { 0228: float x,y,z,rhw; 0229: float tu,tv; 0230: }; 0231: #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) 0232: float scale = 512; 0233: TLVERTEX Vertex[4] = { 0234: // x y z rhw tu tv 0235: { 0, 0, 0, 1, 0, 0,}, 0236: {scale, 0, 0, 1, 1, 0,}, 0237: {scale,scale, 0, 1, 1, 1,}, 0238: { 0,scale, 0, 1, 0, 1,}, 0239: }; 0240: lpD3DDev->SetTexture( 0, pTransTexture ); 0241: // lpD3DDev->SetTexture( 0, pInitTexture ); 0242: lpD3DDev->SetVertexShader( FVF_TLVERTEX ); 0243: lpD3DDev->SetPixelShader(0); 0244: lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) ); 0245: } 0246: 0247: // 0248: // 完成した一枚絵を描画する 0249: // 0250: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer ); // 描画をバックバッファに戻す 0251: lpD3DDev->SetVertexShader(hVertexShader); 0252: lpD3DDev->SetPixelShader(NULL); 0253: lpD3DDev->SetTexture( 0, pTmpTexture[idx] ); 0254: lpD3DDev->SetStreamSource(0, pVB, sizeof(D3D_MY_VERTEX)); 0255: lpD3DDev->SetIndices(pIB,0); 0256: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 ); 0257: 0258: #if 1 0259: // 変換テクスチャーを描く 0260: { 0261: struct TLVERTEX 0262: { 0263: float x,y,z,rhw; 0264: float tu,tv; 0265: }; 0266: #define FVF_TLVERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) 0267: float scale = 128; 0268: TLVERTEX Vertex[4] = { 0269: // x y z rhw tu tv 0270: { 0, 0, 0, 1, 0, 0,}, 0271: {scale, 0, 0, 1, 1, 0,}, 0272: {scale,scale, 0, 1, 1, 1,}, 0273: { 0,scale, 0, 1, 0, 1,}, 0274: }; 0275: lpD3DDev->SetTexture( 0, pTransTexture ); 0276: lpD3DDev->SetVertexShader( FVF_TLVERTEX ); 0277: lpD3DDev->SetPixelShader(0); 0278: lpD3DDev->DrawPrimitiveUP( D3DPT_TRIANGLEFAN, 2, Vertex, sizeof( TLVERTEX ) ); 0279: } 0280: #endif 0281: } 0282: //----------------------------------------------------------------------------- 0283: // Name: CleanRender() 0284: // Desc: 後始末 0285: //----------------------------------------------------------------------------- 0286: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev) 0287: { 0288: DWORD i; 0289: 0290: for (i = 0; i < nTempTex; ++i) { 0291: RELEASE(pTmpSurface[i]); 0292: RELEASE(pTmpTexture [i]); 0293: } 0294: 0295: RELEASE(pTransTexture); 0296: RELEASE(pInitTexture); 0297: 0298: RELEASE(pBackbuffer); 0299: 0300: CPixelShaderMgr::Release(lpD3DDev, &hPixelShader); 0301: CVertexShaderMgr::Release(lpD3DDev, &hVertexShader); 0302: } 0303: