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: