0001: // ----------------------------------------------------------------------------
0002: //
0003: // draw.cpp : Render scene
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 "Cg/cgD3D.h"
0013: #include "main.h"
0014: #include "draw.h"
0015:
0016: // ----------------------------------------------------------------------------
0017: // ----------------------------------------------------------------------------
0018: // Objects
0019: // ----------------------------------------------------------------------------
0020: // ----------------------------------------------------------------------------
0021:
0022: // ----------------------------------------------------------------------------
0023: // Cg object
0024: cgDirect3D cg;
0025: cgContextContainer * pCg = 0;
0026:
0027: // ----------------------------------------------------------------------------
0028: // vertex shader
0029: cgProgramContainer *pVs = 0; // vertex container
0030: cgBindIter *const_texcoord0= 0;// texture coord
0031: cgBindIter *const_texcoord1= 0;// texture coord
0032: cgBindIter *const_texcoord2= 0;// texture coord
0033: cgBindIter *const_texcoord3= 0;// texture coord
0034:
0035: cgVertexAttribute vertex_attributes[] = { // input
0036: {4, "Position", 0},
0037: {2, "Texcoord", 0},
0038: {0, 0, 0},
0039: };
0040:
0041: // ----------------------------------------------------------------------------
0042: // pixel shader
0043: cgProgramContainer *pPs = 0; // pixel shader
0044: cgBindIter * tex0_iter = 0; // texture
0045: cgBindIter * tex1_iter = 0; // texture
0046: cgBindIter * tex2_iter = 0; // texture
0047: cgBindIter * tex3_iter = 0; // texture
0048:
0049:
0050: // ----------------------------------------------------------------------------
0051: // vertex & index buffer
0052:
0053: #define D3DFVF_SUMIE_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1)
0054: #define D3DFVF_DROP_VERTEX (D3DFVF_XYZRHW | D3DFVF_TEX1) // for Drop texture
0055: typedef struct {
0056: float x, y, z, w;
0057: float tu,tv;
0058: }D3D_SUMIE_VERTEX;
0059:
0060: LPDIRECT3DVERTEXBUFFER8 pFinalVB = NULL;
0061: LPDIRECT3DVERTEXBUFFER8 pDropVB = NULL;
0062: LPDIRECT3DVERTEXBUFFER8 pSumieVB = NULL;
0063: LPDIRECT3DINDEXBUFFER8 pSumieIB = NULL;
0064:
0065: // ----------------------------------------------------------------------------
0066: // Surface & texture
0067: LPDIRECT3DTEXTURE8 pDropTexture = NULL; // dot texture
0068: LPDIRECT3DTEXTURE8 pRenderTexture[2] = {NULL,NULL};
0069: LPDIRECT3DSURFACE8 pRenderSurface[2] = {NULL,NULL};
0070: LPDIRECT3DSURFACE8 pBackbuffer = NULL;
0071:
0072:
0073:
0074: // ----------------------------------------------------------------------------
0075: // ----------------------------------------------------------------------------
0076: // Drop dot
0077: // ----------------------------------------------------------------------------
0078: // ----------------------------------------------------------------------------
0079:
0080: // ----------------------------------------------------------------------------
0081: // Initialize
0082: HRESULT InitDrop(LPDIRECT3DDEVICE8 lpD3DDev)
0083: {
0084: HRESULT hr = S_OK;
0085:
0086: // Create vertex buffers
0087: D3D_SUMIE_VERTEX vertices[] = {
0088: // x, y, z, rhw, tu tv
0089: { 100.0f, 100.0f, 0.5f, 1.0f, 0.0f,0.0f,},
0090: { 420.0f, 100.0f, 0.5f, 1.0f, 1.0f,0.0f,},
0091: { 100.0f, 340.0f, 0.5f, 1.0f, 0.0f,1.0f,},
0092: { 420.0f, 340.0f, 0.5f, 1.0f, 1.0f,1.0f,},
0093: };
0094:
0095: hr = lpD3DDev->CreateVertexBuffer( 4*sizeof(D3D_SUMIE_VERTEX),0,
0096: D3DFVF_DROP_VERTEX, D3DPOOL_DEFAULT, &pDropVB);
0097: if(FAILED(hr)) return E_FAIL;
0098:
0099: VOID* pVertices;
0100: hr = pDropVB->Lock( 0, sizeof(vertices), (BYTE**)&pVertices, 0);
0101: if(FAILED(hr)) return E_FAIL;
0102: memcpy( pVertices, vertices, sizeof(vertices) );
0103: pDropVB->Unlock();
0104:
0105: // Load texture
0106: D3DXCreateTextureFromFileEx(lpD3DDev, "mask.bmp",0,0,0,0,D3DFMT_A8R8G8B8,
0107: D3DPOOL_MANAGED, D3DX_FILTER_LINEAR, D3DX_FILTER_LINEAR,
0108: 0, NULL, NULL, &pDropTexture);
0109:
0110: return hr;
0111: }
0112: // ----------------------------------------------------------------------------
0113: // Request
0114: static float drop_x=0;
0115: static float drop_y=0;
0116: static int drop = 0;
0117: // ----------------------------------------------------------------------------
0118: void SetDrop(float x , float y)
0119: {
0120: drop = 100;
0121: drop_x = x;
0122: drop_y = y;
0123: }
0124: // ----------------------------------------------------------------------------
0125: void ResetDrop()
0126: {
0127: drop = 0;
0128: }
0129: // ----------------------------------------------------------------------------
0130: int IsDrop()
0131: {
0132: return drop;
0133: }
0134: // ----------------------------------------------------------------------------
0135: // Rendering
0136: void RenderDrop(LPDIRECT3DDEVICE8 lpD3DDev)
0137: {
0138: if(drop){
0139: D3D_SUMIE_VERTEX *p;
0140: pDropVB->Lock( 0, 4*sizeof(D3D_SUMIE_VERTEX), (BYTE**)&p, 0);
0141: const float r = 8.0f;// radius of dot
0142: p[0].x = p[2].x = drop_x-r;
0143: p[1].x = p[3].x = drop_x+r;
0144: p[0].y = p[1].y = drop_y-r;
0145: p[2].y = p[3].y = drop_y+r;
0146: pDropVB->Unlock();
0147:
0148: lpD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
0149: lpD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR);
0150: lpD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO);
0151:
0152: lpD3DDev->SetTexture( 0, pDropTexture);
0153: lpD3DDev->SetTexture( 1, 0);
0154: lpD3DDev->SetTexture( 2, 0);
0155: lpD3DDev->SetTexture( 3, 0);
0156: lpD3DDev->SetStreamSource( 0, pDropVB, sizeof(D3D_SUMIE_VERTEX) );
0157: lpD3DDev->SetVertexShader( D3DFVF_DROP_VERTEX );
0158: lpD3DDev->SetPixelShader ( 0 );
0159: lpD3DDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
0160:
0161: lpD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
0162: }
0163: }
0164:
0165: // ----------------------------------------------------------------------------
0166: // ----------------------------------------------------------------------------
0167: // Render Target
0168: // ----------------------------------------------------------------------------
0169: // ----------------------------------------------------------------------------
0170:
0171:
0172: //-----------------------------------------------------------------------------
0173: // Initialize Rendering Texture
0174: //-----------------------------------------------------------------------------
0175: HRESULT InitRenderTexture(LPDIRECT3DDEVICE8 lpD3DDev)
0176: {
0177: HRESULT hr;
0178: DWORD i;
0179:
0180: // ==================================================
0181: // Vertex & Index buffer
0182: // ==================================================
0183: // Create Vertex buffer
0184: D3D_SUMIE_VERTEX *pDest;
0185: WORD *pIndex;
0186: hr = lpD3DDev->CreateVertexBuffer( 4 * sizeof(D3D_SUMIE_VERTEX),
0187: D3DUSAGE_WRITEONLY, D3DFVF_SUMIE_VERTEX, D3DPOOL_MANAGED,
0188: &pSumieVB );
0189: pSumieVB->Lock ( 0, 0, (BYTE**)&pDest, 0 );
0190: for (i = 0; i < 4; i++) {
0191: pDest->x = (i == 0 || i == 1)?-1:(float)1;
0192: pDest->y = (i == 0 || i == 2)?-1:(float)1;
0193: pDest->z = 0.5f;
0194: pDest->w = 1.0f;
0195: pDest->tu = (i == 2 || i == 3)?1:(float)0;
0196: pDest->tv = (i == 0 || i == 2)?1:(float)0;
0197: pDest++;
0198: }
0199: pSumieVB->Unlock ();
0200: // Create Index Buffer
0201: hr = lpD3DDev->CreateIndexBuffer( 6 * sizeof(WORD),
0202: 0,
0203: D3DFMT_INDEX16, D3DPOOL_MANAGED,
0204: &pSumieIB );
0205: pSumieIB->Lock ( 0, 0, (BYTE**)&pIndex, 0 );
0206: pIndex[0] = 0; pIndex[1] = 1; pIndex[2] = 2;
0207: pIndex[3] = 1; pIndex[4] = 3; pIndex[5] = 2;
0208: pSumieIB->Unlock ();
0209:
0210: // ==================================================
0211: // Programmable shader
0212: // ==================================================
0213: cg.AddFilePath("..");
0214: pCg = cg.CreateContextContainer(lpD3DDev);
0215:
0216: // ==================================================
0217: // Vertex Shader
0218: pVs = pCg->LoadCGProgramFromFile(
0219: "sumie.vsh", "Sumie Vertex Shader", cgDX8VertexProfile, vertex_attributes);
0220:
0221: if (NULL == pVs) {
0222: // ERROR
0223: const char * listing = pCg->GetLastListing();
0224: if (listing == 0) listing = "Could not find cgc.exe.";
0225: cg.NotePad("Failed to Create Vertex Program\n\n", listing); // Output error
0226: exit(1); // END
0227: }
0228:
0229: const_texcoord0 = pVs->GetParameterBindByName("const_texcoord0");
0230: const_texcoord1 = pVs->GetParameterBindByName("const_texcoord1");
0231: const_texcoord2 = pVs->GetParameterBindByName("const_texcoord2");
0232: const_texcoord3 = pVs->GetParameterBindByName("const_texcoord3");
0233:
0234: float const inv_w = 1.0f / (float)WIDTH;
0235: float const inv_h = 1.0f / (float)HEIGHT;
0236: pVs->SetShaderConstant( const_texcoord0, &D3DXVECTOR2 (( 0.0f +0.5f)*inv_w, ( 0.0f+0.5f)*inv_h) );
0237: pVs->SetShaderConstant( const_texcoord1, &D3DXVECTOR2 (( 0.0f +0.5f)*inv_w, (-1.0f+0.5f)*inv_h) );
0238: pVs->SetShaderConstant( const_texcoord2, &D3DXVECTOR2 ((-0.57735f+0.5f)*inv_w, ( 0.5f+0.5f)*inv_h) );
0239: pVs->SetShaderConstant( const_texcoord3, &D3DXVECTOR2 ((+0.57735f+0.5f)*inv_w, ( 0.5f+0.5f)*inv_h) );
0240:
0241: // ==================================================
0242: // Pixel Shader
0243: pPs = pCg->LoadCGProgramFromFile( "sumie.psh", "Sumie Pixel Shader", cgDX8PixelProfile);
0244:
0245: if (NULL == pPs) {
0246: // ERROR
0247: const char * error_text = pCg->GetLastListing();
0248: cg.NotePad("Failed to Create Pixel Program\n\n", error_text); // Output error
0249:
0250: exit(1); // END
0251: }
0252:
0253: tex0_iter = pPs->GetTextureBindByName("tex0");
0254: tex1_iter = pPs->GetTextureBindByName("tex1");
0255: tex2_iter = pPs->GetTextureBindByName("tex2");
0256: tex3_iter = pPs->GetTextureBindByName("tex3");
0257:
0258: // ==================================================
0259: // Surface
0260: // ==================================================
0261: D3DSURFACE_DESC Desc;
0262: LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0263: if( FAILED(hr = lpD3DDev->GetRenderTarget(&pBackbuffer))) return hr;
0264: if( FAILED(hr = pBackbuffer->GetDesc( &Desc ))) return hr;
0265:
0266: if( FAILED(hr = lpD3DDev->GetDepthStencilSurface( &lpZbuffer ))) return hr;
0267:
0268: for( i=0 ; i<2 ; i++ ){
0269: if( FAILED(hr = lpD3DDev->CreateTexture(Desc.Width, Desc.Height, 1
0270: , D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pRenderTexture[i]))) return hr;
0271: if( FAILED(hr = pRenderTexture[i]->GetSurfaceLevel(0,&pRenderSurface[i]))) return hr;
0272: if( FAILED(hr = lpD3DDev->SetRenderTarget(pRenderSurface[i], lpZbuffer ))) return hr;
0273: }
0274:
0275: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0276:
0277: return S_OK;
0278: }
0279: // ----------------------------------------------------------------------------
0280: // Rendering
0281: // ----------------------------------------------------------------------------
0282: void RenderSumie(LPDIRECT3DDEVICE8 lpD3DDev, int id)
0283: {
0284: pVs->SetShaderActive();
0285: pPs->SetShaderActive();
0286: pPs->SetTexture(tex0_iter, pRenderTexture[id]);
0287: pPs->SetTexture(tex1_iter, pRenderTexture[id]);
0288: pPs->SetTexture(tex2_iter, pRenderTexture[id]);
0289: pPs->SetTexture(tex3_iter, pRenderTexture[id]);
0290: lpD3DDev->SetStreamSource( 0, pSumieVB, sizeof(D3D_SUMIE_VERTEX) );
0291: lpD3DDev->SetIndices(pSumieIB,0);
0292: lpD3DDev->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 4, 0, 2 );
0293: }
0294:
0295: // ----------------------------------------------------------------------------
0296: // ----------------------------------------------------------------------------
0297: // Final rendering
0298: // ----------------------------------------------------------------------------
0299: // ----------------------------------------------------------------------------
0300:
0301: // ----------------------------------------------------------------------------
0302: // Initialize
0303: HRESULT InitFinal(LPDIRECT3DDEVICE8 lpD3DDev)
0304: {
0305: HRESULT hr = S_OK;
0306:
0307: // Create vertex buffer
0308: D3D_SUMIE_VERTEX vertices[] = {
0309: // x, y, z, rhw, tu tv
0310: { 0.0f, 0.0f, 0.5f, 1.0f, 0.0f,0.0f,},
0311: { WIDTH, 0.0f, 0.5f, 1.0f, 1.0f,0.0f,},
0312: { 0.0f, HEIGHT, 0.5f, 1.0f, 0.0f,1.0f,},
0313: { WIDTH, HEIGHT, 0.5f, 1.0f, 1.0f,1.0f,},
0314: };
0315:
0316: hr = lpD3DDev->CreateVertexBuffer( 4*sizeof(D3D_SUMIE_VERTEX),0,
0317: D3DFVF_DROP_VERTEX, D3DPOOL_DEFAULT, &pFinalVB);
0318: if(FAILED(hr)) return hr;
0319:
0320: VOID* pVertices;
0321: hr = pFinalVB->Lock( 0, sizeof(vertices), (BYTE**)&pVertices, 0);
0322: if(FAILED(hr)) return hr;
0323: memcpy( pVertices, vertices, sizeof(vertices) );
0324: pFinalVB->Unlock();
0325:
0326: return hr;
0327: }
0328: // ----------------------------------------------------------------------------
0329: // Rendering
0330: void RenderFinal(LPDIRECT3DDEVICE8 lpD3DDev)
0331: {
0332: lpD3DDev->SetStreamSource( 0, pFinalVB, sizeof(D3D_SUMIE_VERTEX) );
0333: lpD3DDev->SetVertexShader( D3DFVF_DROP_VERTEX );
0334: lpD3DDev->SetPixelShader(NULL);
0335: lpD3DDev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
0336: }
0337:
0338:
0339:
0340: //-----------------------------------------------------------------------------
0341: // Name: Initialize and setup some rendering states
0342: //-----------------------------------------------------------------------------
0343: HRESULT InitRender(LPDIRECT3DDEVICE8 lpD3DDev)
0344: {
0345: HRESULT hr = S_OK;
0346: int i;
0347:
0348: if ( FAILED(hr = InitDrop(lpD3DDev)))return hr;
0349:
0350: // レンダリングテクスチャー用の初期化
0351: if ( FAILED(hr = InitRenderTexture(lpD3DDev)))return hr;
0352:
0353: // 最終描画頂点バッファの初期化
0354: if ( FAILED(hr = InitFinal(lpD3DDev)))return hr;
0355:
0356: // 不変なレジスタの設定
0357: lpD3DDev->SetRenderState( D3DRS_ZENABLE, TRUE );
0358: lpD3DDev->SetRenderState( D3DRS_LIGHTING, FALSE );
0359: for (i = 0; i < 4; ++i) {
0360: lpD3DDev->SetTextureStageState(i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
0361: lpD3DDev->SetTextureStageState(i, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
0362: lpD3DDev->SetTextureStageState(i, D3DTSS_MIPFILTER, D3DTEXF_NONE);
0363: lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP);
0364: lpD3DDev->SetTextureStageState(i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP);
0365: lpD3DDev->SetTextureStageState(i, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
0366: lpD3DDev->SetTextureStageState(i, D3DTSS_COLORARG1, D3DTA_TEXTURE);
0367: }
0368:
0369: return hr;
0370: }
0371:
0372: //-----------------------------------------------------------------------------
0373: // Name: Render()
0374: // Desc: Draws the scene
0375: //-----------------------------------------------------------------------------
0376: VOID Render(LPDIRECT3DDEVICE8 lpD3DDev)
0377: {
0378: static DWORD id = 0;
0379: id = 1-id;
0380:
0381: LPDIRECT3DSURFACE8 lpZbuffer = NULL;
0382: lpD3DDev->GetDepthStencilSurface( &lpZbuffer );
0383: lpD3DDev->SetRenderTarget(pRenderSurface[id], lpZbuffer);
0384:
0385: RenderSumie(lpD3DDev, 1-id);
0386: RenderDrop(lpD3DDev);
0387:
0388: static int first = 2;
0389: if(0<first){
0390: first--;
0391: lpD3DDev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(255,255,255,255),1.0f,0);
0392: }
0393:
0394: lpD3DDev->SetRenderTarget(pBackbuffer, lpZbuffer );
0395: lpD3DDev->SetTexture( 0, pRenderTexture[id]);
0396: lpD3DDev->SetTexture( 1, NULL);
0397: lpD3DDev->SetTexture( 2, NULL);
0398: lpD3DDev->SetTexture( 3, NULL);
0399: RenderFinal(lpD3DDev);
0400: }
0401: //-----------------------------------------------------------------------------
0402: // Name: CleanRender()
0403: //-----------------------------------------------------------------------------
0404: void CleanRender(LPDIRECT3DDEVICE8 lpD3DDev)
0405: {
0406: DWORD i;
0407:
0408: for( i=0 ; i<2 ; i++ ){
0409: RELEASE(pRenderSurface[i]);
0410: RELEASE(pRenderTexture[i]);
0411: }
0412: RELEASE(pBackbuffer);
0413:
0414: RELEASE(pFinalVB);
0415: RELEASE(pDropVB);
0416: RELEASE(pDropTexture);
0417: }
0418: