📄 ch22p2_inscenelensflare.cpp
字号:
/*
#############################################################################
Ch22p2_InSceneLensFlare.cpp: a program that demonstrates how to create an
in-scene lens flare effect.
#############################################################################
*/
// 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 "Ch22p2_resource.h"
#include "Camera.h"
#include "InputManager.h"
#include "AnimSequence.h"
#include "Sprite.h"
#include "SkyBox.h"
#include "Ch22p1_LensFlare.h"
const int NUMSPRITES = 5;
//-----------------------------------------------------------------------------
// 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;
// object mesh
CD3DMesh* m_pObject;
// skybox
CSkyBox m_SkyBox;
// lens flare
CLensFlare m_LensFlare;
D3DXVECTOR3 m_vSunPos;
float m_fPlanetRotation;
int m_iNumObjectsAtPoint;
int m_iSunScreenPosX;
int m_iSunScreenPosY;
D3DXMATRIX m_matProj;
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 );
bool IsLensFlareObscured();
int NumObjectsAtPoint(int iX, int iY);
void ProcessInput();
public:
CMyD3DApplication();
};
//-----------------------------------------------------------------------------
// 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("Ch22p2_InSceneLensFlare");
m_bUseDepthBuffer = TRUE;
m_pObject = new CD3DMesh;
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
m_pFontSmall = new CD3DFont( _T("Arial"), 9, D3DFONT_BOLD );
}
//-----------------------------------------------------------------------------
// 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()
{
if (m_fElapsedTime < 0.0001f) {
m_fElapsedTime = 0.0001f;
}
if (m_fElapsedTime > 0.5f) m_fElapsedTime = 0.5f;
char buf[256]; sprintf(buf, "\nElapsed Time: %f", m_fElapsedTime);
OutputDebugString(buf);
CTimer::UpdateAll(m_fElapsedTime);
m_fPlanetRotation += m_fElapsedTime;
if (m_fPlanetRotation > (float)(32.0f*PI)) m_fPlanetRotation -= (float)(32.0f*PI);
return S_OK;
}
void CMyD3DApplication::ProcessInput()
{
const float fSpeed = 0.5f;
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);
}
bool CMyD3DApplication::IsLensFlareObscured()
{
// get screen coordinates of the light source.
int iLightW;
m_LensFlare.CalcLightSourceScreenCoords(m_Camera, m_matProj, m_vSunPos,
m_d3dsdBackBuffer.Width,m_d3dsdBackBuffer.Height, m_iSunScreenPosX,
m_iSunScreenPosY, iLightW);
m_iNumObjectsAtPoint = NumObjectsAtPoint(m_iSunScreenPosX, m_iSunScreenPosY);
return(m_iNumObjectsAtPoint > 0);
}
int CMyD3DApplication::NumObjectsAtPoint(int iX, int iY)
{
D3DXVECTOR3 vRayDir;
D3DXVECTOR3 vRayOrig;
int iNumObjectsAtPoint = 0;
// Get the pick ray from given coordinates
{
D3DXVECTOR3 v;
v.x = ( ( ( 2.0f * iX ) / m_d3dsdBackBuffer.Width ) - 1 ) / m_matProj._11;
v.y = -( ( ( 2.0f * iY ) / m_d3dsdBackBuffer.Height ) - 1 ) / m_matProj._22;
v.z = 1.0f;
// Get the inverse view matrix
D3DXMATRIX matView, m;
matView = m_Camera.GetViewMatrix();
D3DXMatrixInverse( &m, NULL, &matView );
// Transform the screen space pick ray into 3D space
vRayDir.x = v.x*m._11 + v.y*m._21 + v.z*m._31;
vRayDir.y = v.x*m._12 + v.y*m._22 + v.z*m._32;
vRayDir.z = v.x*m._13 + v.y*m._23 + v.z*m._33;
vRayOrig.x = m._41;
vRayOrig.y = m._42;
vRayOrig.z = m._43;
}
// Get the picked triangle
LPDIRECT3DVERTEXBUFFER8 pVB;
LPDIRECT3DINDEXBUFFER8 pIB;
m_pObject->GetLocalMesh()->GetVertexBuffer( &pVB );
m_pObject->GetLocalMesh()->GetIndexBuffer( &pIB );
struct VERTEX { D3DXVECTOR3 p, n; FLOAT tu; FLOAT tv; };
DWORD dwFVF = m_pObject->GetLocalMesh()->GetFVF();
WORD* pIndices;
VERTEX* pVertices;
DWORD dwNumFaces = m_pObject->GetLocalMesh()->GetNumFaces();
pIB->Lock( 0,0,(BYTE**)&pIndices, 0 );
pVB->Lock( 0,0,(BYTE**)&pVertices, 0 );
for( DWORD i=0; i<dwNumFaces; i++ )
{
D3DXVECTOR3 v0 = pVertices[pIndices[3*i+0]].p;
D3DXVECTOR3 v1 = pVertices[pIndices[3*i+1]].p;
D3DXVECTOR3 v2 = pVertices[pIndices[3*i+2]].p;
float fPickT, fPickU, fPickV;
// Check if the pick ray passes through this point
if( DoesRayIntersectTriangle( vRayOrig, vRayDir, v0, v1, v2,
&fPickT, &fPickU, &fPickV ) )
{
iNumObjectsAtPoint++;
}
}
pVB->Unlock();
pIB->Unlock();
pVB->Release();
pIB->Release();
return(iNumObjectsAtPoint);
}
//-----------------------------------------------------------------------------
// 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()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -