?? ch12p1_simplewater.cpp
字號:
}
else {
if (ydiff < 0) {
if (y-ydisp < 0 || y-ydisp >= TEXTURESIZE || x+xdisp < 0 || x+xdisp >= TEXTURESIZE)
pDest[dest_index++] = pSrc[0];
else
pDest[dest_index++] = pSrc[((y-ydisp)*src_pitch)+x+xdisp];
}
else {
if (y+ydisp < 0 || y+ydisp >= TEXTURESIZE || x+xdisp < 0 || x+xdisp >= TEXTURESIZE)
pDest[dest_index++] = pSrc[0];
else
pDest[dest_index++] = pSrc[((y+ydisp)*src_pitch)+x+xdisp];
}
}
}
// next line
dest_index += (rect_dest.Pitch - (TEXTURESIZE*4))/4;
}
// unlock texture surface
if (FAILED(hr = pSrcTex->UnlockRect(0))) return(hr);
if (FAILED(hr = pDestTex->UnlockRect(0))) return(hr);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
// permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
MakeDisplacementLookupTable(m_lutDisplacement, sizeof(m_lutDisplacement), 1.333f, 0.5f);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
FLOAT fSecsPerFrame = m_fElapsedTime;
// process the water
ProcessWater(m_pWaterActive, m_pWaterScratch, TEXTURESIZE, TEXTURESIZE, 4);
// use it to displace our image texture onto our dest texture
PutWaterOntoTexture(m_pWaterActive, TEXTURESIZE, TEXTURESIZE, m_lutDisplacement,
m_pd3dDevice, m_pImageTex, m_pWaterTex);
// flip-flop the water buffers.
int *temp = m_pWaterActive;
m_pWaterActive = m_pWaterScratch;
m_pWaterScratch = temp;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Called once per frame, the call is the entry point for 3d
// rendering. This function sets up render states, clears the
// viewport, and renders the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::Render()
{
// Clear the backbuffer
m_pd3dDevice->Clear(0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
0x000000, 1.0f, 0L);
// Begin rendering the scene
if( SUCCEEDED(m_pd3dDevice->BeginScene()))
{
// set our water texture active...
m_pd3dDevice->SetTexture(0, m_pWaterTex);
// draw our quad
m_pd3dDevice->SetStreamSource(0, m_pVB, sizeof(CUSTOMVERTEX));
m_pd3dDevice->SetVertexShader(D3DFVF_CUSTOMVERTEX);
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
// Output statistics
m_pFont->DrawText(2, 0, D3DCOLOR_ARGB(255,255,255,0), m_strFrameStats);
m_pFont->DrawText(2, 20, D3DCOLOR_ARGB(255,255,255,0), m_strDeviceStats);
m_pFont->DrawText(2, 40, D3DCOLOR_ARGB(255,255,255,0), m_strTextureSurfFormat);
// End the scene.
m_pd3dDevice->EndScene();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
m_pFont->InitDeviceObjects( m_pd3dDevice );
m_pFontSmall->InitDeviceObjects( m_pd3dDevice );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
HRESULT hr;
m_pFont->RestoreDeviceObjects();
m_pFontSmall->RestoreDeviceObjects();
// Setup render states
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
// Create vertex buffer
{
CUSTOMVERTEX* pVertices;
if( FAILED( hr = m_pd3dDevice->CreateVertexBuffer( 6*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED, &m_pVB ) ) )
return hr;
if( FAILED( hr = m_pVB->Lock( 0, m_dwNumVertices*sizeof(CUSTOMVERTEX), (BYTE**)&pVertices, 0 ) ) )
return hr;
// first triangle
pVertices[0].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
pVertices[0].color = 0xffffffff;
pVertices[0].tu = 0.0f;
pVertices[0].tv = 0.0f;
pVertices[1].position = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
pVertices[1].color = 0xffffffff;
pVertices[1].tu = 1.0f;
pVertices[1].tv = 0.0f;
pVertices[2].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
pVertices[2].color = 0xffffffff;
pVertices[2].tu = 1.0f;
pVertices[2].tv = 1.0f;
// second triangle
pVertices[3].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
pVertices[3].color = 0xffffffff;
pVertices[3].tu = 0.0f;
pVertices[3].tv = 0.0f;
pVertices[4].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
pVertices[4].color = 0xffffffff;
pVertices[4].tu = 1.0f;
pVertices[4].tv = 1.0f;
pVertices[5].position = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
pVertices[5].color = 0xffffffff;
pVertices[5].tu = 0.0f;
pVertices[5].tv = 1.0f;
if( FAILED( hr = m_pVB->Unlock() ) )
return hr;
}
// clear water memory
memset(m_iWaterField, 0, TEXTURESIZE*TEXTURESIZE*4);
memset(m_iWaterField2, 0, TEXTURESIZE*TEXTURESIZE*4);
// setup water buffers
m_pWaterActive = m_iWaterField;
m_pWaterScratch = m_iWaterField2;
// create image texture
{
if (FAILED(hr = D3DXCreateTextureFromFile(m_pd3dDevice, "Ch12p1_WaterImage.png", &m_pImageTex))) return(hr);
LPDIRECT3DSURFACE8 pSurf;
if (FAILED(hr = m_pImageTex->GetSurfaceLevel(0, &pSurf))) return(hr);
// get the texture's surface format, and store that in our variable for later display.
D3DSURFACE_DESC surfdesc;
pSurf->GetDesc(&surfdesc);
strcpy(m_strTextureSurfFormat, SurfFormatToString(surfdesc.Format));
SAFE_RELEASE(pSurf);
}
// create destination water texture - same size as image
if (FAILED(hr = D3DXCreateTexture(m_pd3dDevice, TEXTURESIZE, TEXTURESIZE,
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &m_pWaterTex))) return(hr);
// Set up an orthagonal projection matrix, so we can render the entire
// texture.
D3DXMATRIX mat;
D3DXMatrixOrthoLH(&mat, (float)TEXTURESIZE, (float)TEXTURESIZE,
0.0, 100.0);
m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &mat );
// this world matrix, combined with orthogonal projection, causes the
// texture to completely and exactly fill the rendering surface.
D3DXMATRIX matWorld,matTrans,matScale;
D3DXMatrixScaling(&matScale, (float)TEXTURESIZE/2.0f, (float)TEXTURESIZE/2.0f, 1.0);
// move the quad left and up 0.5 units, so that the texels are perfectly
// centered on the screen pixels.
D3DXMatrixMultiply(&matWorld, &matScale, D3DXMatrixTranslation(&matTrans, -0.5f, -0.5f, 0));
// our matrix is now finished. Tell D3D to use it!
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
// set up our texture stages for a simple texture copy...
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1 );
// turning on linear filtering for our fire texture really helps out with
// the image quality.
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
m_pFont->InvalidateDeviceObjects();
m_pFontSmall->InvalidateDeviceObjects();
SAFE_RELEASE(m_pVB);
SAFE_RELEASE(m_pImageTex);
SAFE_RELEASE(m_pWaterTex);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: DeleteDeviceObjects()
// Desc: Called when the app is exiting, or the device is being changed,
// this function deletes any device dependent objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::DeleteDeviceObjects()
{
m_pFont->DeleteDeviceObjects();
m_pFontSmall->DeleteDeviceObjects();
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FinalCleanup()
// Desc: Called before the app exits, this function gives the app the chance
// to cleanup after itself.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FinalCleanup()
{
SAFE_DELETE( m_pFont );
SAFE_DELETE( m_pFontSmall );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ConfirmDevice()
// Desc: Called during device intialization, this code checks the device
// for some minimum set of capabilities
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior,
D3DFORMAT Format )
{
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: Message proc function to handle key and menu input
//-----------------------------------------------------------------------------
LRESULT CMyD3DApplication::MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam,
LPARAM lParam )
{
switch(uMsg) {
case WM_KEYDOWN:
for (int q=0; q < 5; q++) {
CreateWaterDroplet(RandomNumber(0,TEXTURESIZE),
RandomNumber(0,TEXTURESIZE), RandomNumber(5,15), RandomNumber(10,25),
m_pWaterActive, TEXTURESIZE, TEXTURESIZE);
}
break;
}
// Pass remaining messages to default handler
return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -