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: