📄 ch14p1_simplewarp.cpp
字号:
D3DXMatrixOrthoLH(&mat, (float)texwidth, (float)texheight,
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)texwidth/2.0f, (float)texheight/2.0f, 1.0);
// move the quad left and up 0.5 units, so that th e 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, &matScale );
// 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() ) )
{
// no alpha blending
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
// set our texture active...
m_pd3dDevice->SetTexture( 0, m_pActiveTex );
// 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 );
// draw our quad
m_pd3dDevice->SetStreamSource( 0, m_pVB, sizeof(CUSTOMVERTEX) );
m_pd3dDevice->SetVertexShader( D3DFVF_CUSTOMVERTEX );
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
// End the scene.
m_pd3dDevice->EndScene();
}
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
// seed our random number generator
srand(time(NULL));
// set up a default view matrix. since we're using an orthogonal projection,
// we don't really care about the z-distance between the camera and the
// object(s) we're viewing. What's more important is the x and y alignment -
// in this case, making sure that our camera is exactly perpendicular to our
// quad, and positioned (and aimed at) the quad's exact center.
D3DXMATRIX matView;
D3DXVECTOR3 vEye = D3DXVECTOR3( 0.0f, 0.0f, -10.0f );
D3DXVECTOR3 vAt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUp = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &matView, &vEye, &vAt, &vUp );
m_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
// bilinear filtering makes the image fade out (might be cool in some
// situations!)
//m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR);
//m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR);
//m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR);
// normal filtering looks OK
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_POINT);
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_POINT);
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_POINT);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Initialize scene objects.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
HRESULT hr;
// Setup render states
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
D3DXIMAGE_INFO imageinfo;
// create texture image.
//if (FAILED(hr = D3DXCreateTextureFromFileEx(m_pd3dDevice, "..\\..\\Ch13 - Image FeedBack\\Ch13p2_OrthoProj\\Ch13p2_TestImage.png",
if (FAILED(hr = D3DXCreateTextureFromFileEx(m_pd3dDevice, "Ch14p1_WarpImage.bmp",
D3DX_DEFAULT,
D3DX_DEFAULT,
1, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE,
0, &imageinfo, NULL, &m_pImageTex))) {
return(hr);
}
// store texture width/height
m_iImageWidth = imageinfo.Width;
m_iImageHeight = imageinfo.Height;
// create the two texture buffers that we'll use for the effect
// these must be created as render targets.
if (FAILED(hr = D3DXCreateTexture(m_pd3dDevice,
GetLowestPowerOf2(m_iImageWidth), GetLowestPowerOf2(m_iImageHeight),
1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pTex1))) {
return(hr);
}
if (FAILED(hr = D3DXCreateTexture(m_pd3dDevice,
GetLowestPowerOf2(m_iImageWidth), GetLowestPowerOf2(m_iImageHeight),
1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &m_pTex2))) {
return(hr);
}
// set up the pointers
m_pActiveTex = m_pTex1;
m_pScratchTex = m_pTex2;
// 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, 6*sizeof(CUSTOMVERTEX), (BYTE**)&pVertices, 0 ) ) )
return hr;
float tex1horz = (float)(m_iImageWidth)/GetLowestPowerOf2(m_iImageWidth);
float tex1vert = (float)(m_iImageHeight)/GetLowestPowerOf2(m_iImageHeight);
// first triangle
pVertices[0].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
pVertices[0].color = D3DCOLOR_ARGB(255,0,0,0);
pVertices[0].tu = 0.0f;
pVertices[0].tv = 0.0f;
pVertices[1].position = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
pVertices[1].color = D3DCOLOR_ARGB(255,0,0,0);
pVertices[1].tu = tex1horz;
pVertices[1].tv = 0.0f;
pVertices[2].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
pVertices[2].color = D3DCOLOR_ARGB(255,0,0,0);
pVertices[2].tu = tex1horz;
pVertices[2].tv = tex1vert;
// second triangle
pVertices[3].position = D3DXVECTOR3(-1.0f, 1.0f, 0.0f);
pVertices[3].color = D3DCOLOR_ARGB(255,0,0,0);
pVertices[3].tu = 0.0f;
pVertices[3].tv = 0.0f;
pVertices[4].position = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
pVertices[4].color = D3DCOLOR_ARGB(255,0,0,0);
pVertices[4].tu = tex1horz;
pVertices[4].tv = tex1vert;
pVertices[5].position = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
pVertices[5].color = D3DCOLOR_ARGB(255,0,0,0);
pVertices[5].tu = 0.0f;
pVertices[5].tv = tex1vert;
if( FAILED( hr = m_pVB->Unlock() ) )
return hr;
}
// create grid vertex buffer
if(FAILED(hr = m_pd3dDevice->CreateVertexBuffer(
VERTEX_GRID_DENSITY*VERTEX_GRID_DENSITY*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED, &m_pVBGrid)))
return hr;
// create index buffer
if(FAILED(hr = m_pd3dDevice->CreateIndexBuffer(
VERTEX_GRID_DENSITY*VERTEX_GRID_DENSITY*2*3*2,
D3DUSAGE_WRITEONLY, D3DFMT_INDEX16,
D3DPOOL_MANAGED, &m_pIBGrid)))
return hr;
// lock and fill index buffer - we can do this here because we only need to
// do it once.
WORD *pIndices;
if(FAILED(hr = m_pIBGrid->Lock(0, VERTEX_GRID_DENSITY*VERTEX_GRID_DENSITY*2*3*2, (unsigned char **)&pIndices,
0)))
return hr;
WORD *pIndex = pIndices;
for (int x=0; x < VERTEX_GRID_DENSITY-1; x++) {
for (int y=0; y < VERTEX_GRID_DENSITY-1; y++) {
// first triangle
*(pIndex++) = ((y)*VERTEX_GRID_DENSITY)+x;
*(pIndex++) = ((y)*VERTEX_GRID_DENSITY)+x+1;
*(pIndex++) = ((y+1)*VERTEX_GRID_DENSITY)+x+1;
// second triangle
*(pIndex++) = ((y)*VERTEX_GRID_DENSITY)+x;
*(pIndex++) = ((y+1)*VERTEX_GRID_DENSITY)+x+1;
*(pIndex++) = ((y+1)*VERTEX_GRID_DENSITY)+x;
}
}
if(FAILED(hr = m_pIBGrid->Unlock()))
return hr;
try {
RenderCopy(m_pImageTex, m_pActiveTex,
GetLowestPowerOf2(m_iImageWidth), GetLowestPowerOf2(m_iImageHeight),
m_pd3dDevice, m_pVB);
} catch(...) { }
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InvalidateDeviceObjects()
// Desc:
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InvalidateDeviceObjects()
{
SAFE_RELEASE( m_pVB );
SAFE_RELEASE( m_pVBGrid );
SAFE_RELEASE( m_pIBGrid );
SAFE_RELEASE( m_pImageTex );
SAFE_RELEASE( m_pTex1 );
SAFE_RELEASE( m_pTex2 );
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()
{
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()
{
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:
try {
RenderCopy(m_pImageTex, m_pActiveTex,
GetLowestPowerOf2(m_iImageWidth), GetLowestPowerOf2(m_iImageHeight),
m_pd3dDevice, m_pVB);
} catch(...) { }
break;
}
// Pass remaining messages to default handler
return CD3DApplication::MsgProc( hWnd, uMsg, wParam, lParam );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -