📄 ch24p3_imgmanip.cpp
字号:
/*
#############################################################################
Ch24p3_ImgManip.cpp: a program that demonstrates the fire algorithm,
without any annoying bells and/or whistles.
#############################################################################
*/
// include files ////////////////////////////////////////////////////////////
#define STRICT
#include <stdio.h>
#include <math.h>
#include <D3DX8.h>
#include "D3DApp.h"
#include "D3DFile.h"
#include "D3DFont.h"
#include "D3DUtil.h"
#include "DXUtil.h"
#include "D3DHelperFuncs.h"
#include "Ch24p3_resource.h"
#include "Camera.h"
#include "InputManager.h"
#include "Timer.h"
#include "d3dx8mesh.h"
typedef struct
{
D3DXVECTOR3 position; // The position
D3DCOLOR color; // The color
float tu0, tv0; // texcoords 0
float tu1, tv1; // texcoords 1
float tu2, tv2; // texcoords 2
float tu3, tv3; // texcoords 3
} VERTEX_IMGMANIP;
#define D3DFVF_IMGMANIP (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX4)
typedef struct
{
D3DXVECTOR3 position; // The position
D3DXVECTOR3 normal; // normal
D3DCOLOR color; // diffuse color
float tu, tv; // texture coordinates
} VERTEX_TEAPOT;
#define D3DFVF_TEAPOT (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX1)
class CPixelShaderEntry
{
public:
CPixelShaderEntry() { m_dwID = 0; m_pd3dDevice = NULL; }
virtual ~CPixelShaderEntry() { }
CPixelShaderEntry(LPDIRECT3DDEVICE8 pDev, std::string strName,
std::string strFilename)
{
m_strName = strName;
m_strFilename = strFilename;
m_pd3dDevice = pDev;
if (FAILED(CreateShader(pDev, strFilename.c_str(), NULL, m_dwID))) {
throw("Cannot Create Pixel Shader!");
}
}
LPDIRECT3DDEVICE8 m_pd3dDevice;
std::string m_strName;
std::string m_strFilename;
DWORD m_dwID;
};
//-----------------------------------------------------------------------------
// Name: class CMyD3DApplication
// Desc: Application class. The base class (CD3DApplication) provides the
// generic functionality needed in all Direct3D samples. CMyD3DApplication
// adds functionality specific to this sample program.
//-----------------------------------------------------------------------------
class CMyD3DApplication : public CD3DApplication
{
// Font for drawing text
CD3DFont* m_pFont;
CD3DFont* m_pFontSmall;
// Scene
CUserControlledCamera m_Camera;
// Mouse Input
CInputManager m_InputManager;
// teapot
CD3DMesh *m_pTeapot;
LPDIRECT3DTEXTURE8 m_texRender;
LPDIRECT3DSURFACE8 m_surfRenderDepth;
DWORD m_dwTeapotVertexShader;
DWORD m_dwImageVertexShader;
std::vector<CPixelShaderEntry> m_PixelShaders;
int m_iCurPixelShader;
static const int m_iTextureSize;
float m_fTotalTime;
protected:
HRESULT OneTimeSceneInit();
HRESULT InitDeviceObjects();
HRESULT RestoreDeviceObjects();
HRESULT InvalidateDeviceObjects();
HRESULT DeleteDeviceObjects();
HRESULT FinalCleanup();
HRESULT Render();
HRESULT FrameMove();
HRESULT ConfirmDevice( D3DCAPS8* pCaps, DWORD dwBehavior, D3DFORMAT Format );
LRESULT MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
void ProcessInput();
HRESULT RenderSceneOntoTexture(D3DXMATRIX matView);
public:
CMyD3DApplication();
};
const int CMyD3DApplication::m_iTextureSize = 256;
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Entry point to the program. Initializes everything, and goes into a
// message-processing loop. Idle time is used to render the scene.
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
CMyD3DApplication d3dApp;
if( FAILED( d3dApp.Create( hInst ) ) )
return 0;
return d3dApp.Run();
}
//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application constructor. Sets attributes for the app.
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
m_strWindowTitle = _T("Ch24p3_ImgManip");
m_bUseDepthBuffer = TRUE;
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
m_pFontSmall = new CD3DFont( _T("Arial"), 9, D3DFONT_BOLD );
m_texRender = NULL;
m_surfRenderDepth = NULL;
m_iCurPixelShader = 0;
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Called during initial app startup, this function performs all the
// permanent initialization.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
m_fElapsedTime = 0.001f;
if (m_fElapsedTime < 0.0001f) {
m_fElapsedTime = 0.0001f;
}
if (m_fElapsedTime > 0.005f) {
m_fElapsedTime = 0.005f;
m_fTime -= m_fElapsedTime - 0.005f;
}
m_fTotalTime += m_fElapsedTime;
CTimer::UpdateAll(m_fElapsedTime);
return S_OK;
}
void CMyD3DApplication::ProcessInput()
{
float fSpeed = 600.0f * m_fElapsedTime;
unsigned char m_bKey[256];
ZeroMemory( m_bKey, 256 );
GetKeyboardState(m_bKey);
// Process keyboard input
if(m_bKey['D'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(fSpeed, 0.0f, 0.0f)); // Slide Right
if(m_bKey['A'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(-fSpeed, 0.0f, 0.0f));// Slide Left
if(m_bKey['Q'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, fSpeed, 0.0f)); // Slide Up
if(m_bKey['Z'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, -fSpeed, 0.0f));// Slide Down
if(m_bKey['W'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, 0.0f, fSpeed)); // Slide Foward
if(m_bKey['S'] & 128) m_Camera.AddToVelocity(D3DXVECTOR3(0.0f, 0.0f, -fSpeed));// Slide Back
if(m_bKey['L'] & 128) m_Camera.AddToYawPitchRoll(fSpeed, 0.0f, 0.0f); // Turn Right
if(m_bKey['J'] & 128) m_Camera.AddToYawPitchRoll(-fSpeed, 0.0f, 0.0f); // Turn Left
if(m_bKey['K'] & 128) m_Camera.AddToYawPitchRoll(0.0f, fSpeed, 0.0f); // Turn Down
if(m_bKey['I'] & 128) m_Camera.AddToYawPitchRoll(0.0f, -fSpeed, 0.0f);// Turn Up
// mouse look
DIMOUSESTATE2 dims2;
m_InputManager.ReadMouse(dims2);
// play with the divisor constants to change the mouselook sensitivity.
// I've found that these values most accurately simulate my beloved Q3A setup. :)
m_Camera.AddToYawPitchRoll((float)dims2.lX/0.8f, (float)dims2.lY/0.8f, 0.0f);
}
HRESULT CMyD3DApplication::RenderSceneOntoTexture(D3DXMATRIX matView)
{
m_pd3dDevice->Clear( 0L, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DXCOLOR(0,0,0.5,1), 1.0f, 0L );
if( SUCCEEDED( m_pd3dDevice->BeginScene() ) )
{
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/2, 1.0f, 0.5f, 100.0f);
m_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
m_pd3dDevice->SetTexture(0, NULL);
m_pd3dDevice->SetVertexShader(m_dwTeapotVertexShader);
m_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
m_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_DIFFUSE);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
m_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
m_pd3dDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
LPDIRECT3DVERTEXBUFFER8 pVB; m_pTeapot->m_pLocalMesh->GetVertexBuffer(&pVB);
LPDIRECT3DINDEXBUFFER8 pIB; m_pTeapot->m_pLocalMesh->GetIndexBuffer(&pIB);
for (int q=0; q < 3; q++) {
D3DXCOLOR colorDiffuse;
D3DXMATRIX matWorld;
D3DXMATRIX matInternalRot, matOrbitRot, matTranslate;
switch(q) {
case 0:
colorDiffuse = D3DXCOLOR(1.0f,0.0f,0.0f,1.0f);
D3DXMatrixRotationYawPitchRoll(&matInternalRot, m_fTotalTime*4.0f, m_fTotalTime, 0.0f);
D3DXMatrixRotationYawPitchRoll(&matOrbitRot, m_fTotalTime*3.0f, 0.0f, m_fTotalTime*3.0f);
D3DXMatrixIdentity(&matTranslate);
D3DXMatrixTranslation(&matTranslate, 0.0f, 2.0f, 2.0f);
break;
case 1:
colorDiffuse = D3DXCOLOR(0.0f,1.0f,0.0f,1.0f);
D3DXMatrixRotationYawPitchRoll(&matInternalRot, m_fTotalTime*10.0f, m_fTotalTime, 0.0f);
D3DXMatrixRotationYawPitchRoll(&matOrbitRot, m_fTotalTime*4.8f, m_fTotalTime, m_fTotalTime*4.8f);
D3DXMatrixIdentity(&matTranslate);
D3DXMatrixTranslation(&matTranslate, 0.0f, 1.0f, 1.0f);
break;
case 2:
colorDiffuse = D3DXCOLOR(0.0f,0.0f,1.0f,1.0f);
D3DXMatrixRotationYawPitchRoll(&matInternalRot, m_fTotalTime*6.0f, m_fTotalTime, 0.0f);
D3DXMatrixRotationYawPitchRoll(&matOrbitRot, m_fTotalTime, 0.0f, m_fTotalTime);
D3DXMatrixIdentity(&matTranslate);
D3DXMatrixTranslation(&matTranslate, 0.0f, 3.5f, 3.5f);
break;
}
matWorld = matInternalRot * matTranslate * matOrbitRot;
m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
m_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
// Set up the vertex shader constants
{
D3DXMATRIX matWorldViewProj;
D3DXMATRIX matWorldView;
matWorldViewProj = matWorld * m_Camera.GetViewMatrix() * matProj;
matWorldView = matWorld * m_Camera.GetViewMatrix();
D3DXMatrixTranspose(&matWorldViewProj, &matWorldViewProj);
D3DXVECTOR3 vLightDir(0.0, 0.0, 1.0);
m_pd3dDevice->SetVertexShaderConstant(10, vLightDir, 1);
m_pd3dDevice->SetVertexShaderConstant(0, &matWorldViewProj, 4);
m_pd3dDevice->SetVertexShaderConstant(11, &matWorldView, 4);
}
m_pd3dDevice->SetVertexShaderConstant(5, &colorDiffuse, 1);
m_pd3dDevice->SetStreamSource( 0, pVB, sizeof(VERTEX_TEAPOT));
m_pd3dDevice->SetIndices(pIB, 0);
m_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0,
m_pTeapot->m_pLocalMesh->GetNumVertices(), 0, m_pTeapot->m_pLocalMesh->GetNumFaces());
}
pVB->Release();
pIB->Release();
m_pd3dDevice->EndScene();
}
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()
{
// these are done here so that you can move the camera around during a freeze
// frame, ala The Matrix
ProcessInput();
m_Camera.Update(m_fElapsedTime);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -