📄 shadow.cpp
字号:
//-----------------------------------------------------------------------------
// File: Shadow.cpp
//
// Desc: DirectX window application created by the DirectX AppWizard
//-----------------------------------------------------------------------------
#define STRICT
#include <windows.h>
#include <commctrl.h>
#include <commdlg.h>
#include <basetsd.h>
#include <math.h>
#include <stdio.h>
#include <d3dx9.h>
#include <dxerr9.h>
#include <tchar.h>
#include "DXUtil.h"
#include "D3DEnumeration.h"
#include "D3DSettings.h"
#include "D3DApp.h"
#include "D3DFont.h"
#include "D3DFile.h"
#include "D3DUtil.h"
#include "resource.h"
#include "Shadow.h"
#define FNAME_OCC "data\\tiger.x"
#define MESH_SCL 1.0f
//-----------------------------------------------------------------------------
// Global access to the app (needed for the global WndProc())
//-----------------------------------------------------------------------------
CMyD3DApplication* g_pApp = NULL;
HINSTANCE g_hInst = NULL;
struct MYVERTEX
{
enum { FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 };
D3DXVECTOR3 v;
D3DXVECTOR3 n;
D3DXVECTOR2 t;
};
//-----------------------------------------------------------------------------
// 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;
g_pApp = &d3dApp;
g_hInst = hInst;
InitCommonControls();
if( FAILED( d3dApp.Create( hInst ) ) )
return 0;
return d3dApp.Run();
}
//-----------------------------------------------------------------------------
// Name: CMyD3DApplication()
// Desc: Application constructor. Paired with ~CMyD3DApplication()
// Member variables should be initialized to a known state here.
// The application window has not yet been created and no Direct3D device
// has been created, so any initialization that depends on a window or
// Direct3D should be deferred to a later stage.
//-----------------------------------------------------------------------------
CMyD3DApplication::CMyD3DApplication()
{
m_dwCreationWidth = 500;
m_dwCreationHeight = 375;
m_strWindowTitle = TEXT( "Planar Shadow" );
m_d3dEnumeration.AppUsesDepthBuffer = TRUE;
m_d3dEnumeration.AppMinDepthBits = 16;
m_d3dEnumeration.AppMinStencilBits = 4; // 创建stencil缓冲
m_d3dSettings.SetVertexProcessingType( SOFTWARE_VP );
m_bShowCursorWhenFullscreen = TRUE;
m_bStartFullscreen = false;
m_bShowCursorWhenFullscreen = false;
// Create a D3D font using d3dfont.cpp
m_pFont = new CD3DFont( _T("Arial"), 12, D3DFONT_BOLD );
m_bLoadingApp = TRUE;
m_pMeshOcc = NULL;
m_pMeshFloor = NULL;
ZeroMemory( &m_UserInput, sizeof(m_UserInput) );
m_fWorldRotX = 0.0f;
m_fWorldRotY = 0.0f;
m_bWireframe = FALSE;
m_bShadow = TRUE;
m_bVolume = FALSE;
m_pMeshFloor = new CD3DMesh();
m_pMeshOcc = new CD3DMesh();
}
//-----------------------------------------------------------------------------
// Name: ~CMyD3DApplication()
// Desc: Application destructor. Paired with CMyD3DApplication()
//-----------------------------------------------------------------------------
CMyD3DApplication::~CMyD3DApplication()
{
}
//-----------------------------------------------------------------------------
// Name: OneTimeSceneInit()
// Desc: Paired with FinalCleanup().
// The window has been created and the IDirect3D9 interface has been
// created, but the device has not been created yet. Here you can
// perform application-related initialization and cleanup that does
// not depend on a device.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::OneTimeSceneInit()
{
// TODO: perform one time initialization
// Drawing loading status message until app finishes loading
SendMessage( m_hWnd, WM_PAINT, 0, 0 );
m_bLoadingApp = FALSE;
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: ConfirmDevice()
// Desc: Called during device initialization, this code checks the display device
// for some minimum set of capabilities
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::ConfirmDevice( D3DCAPS9* pCaps, DWORD dwBehavior,
D3DFORMAT Format )
{
UNREFERENCED_PARAMETER( Format );
UNREFERENCED_PARAMETER( dwBehavior );
UNREFERENCED_PARAMETER( pCaps );
BOOL bCapsAcceptable;
// TODO: Perform checks to see if these display caps are acceptable.
bCapsAcceptable = TRUE;
if( bCapsAcceptable )
return S_OK;
else
return E_FAIL;
}
// 顶点着色器初始化
HRESULT CMyD3DApplication::InitVS()
{
D3DVERTEXELEMENT9 decl[MAX_FVF_DECL_SIZE];
// 使用FVF自动填写顶点声明值
D3DXDeclaratorFromFVF( MYVERTEX::FVF, decl );
// 通过顶点声明值生成 g_pDecl.
m_pd3dDevice->CreateVertexDeclaration( decl, &m_pDecl );
LPD3DXBUFFER pCode;
// 读取simple.vs 文件,生成顶点着色器界面.
if( FAILED( D3DXAssembleShaderFromFile( "shadow.vs", NULL, NULL, 0, &pCode, NULL ) ) )
return E_FAIL;
m_pd3dDevice->CreateVertexShader( (DWORD*)pCode->GetBufferPointer(), &m_pVS);
SAFE_RELEASE( pCode );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: InitDeviceObjects()
// Desc: Paired with DeleteDeviceObjects()
// The device has been created. Resources that are not lost on
// Reset() can be created here -- resources in D3DPOOL_MANAGED,
// D3DPOOL_SCRATCH, or D3DPOOL_SYSTEMMEM. Image surfaces created via
// CreateImageSurface are never lost and can be created here. Vertex
// shaders and pixel shaders can also be created here as they are not
// lost on Reset().
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::InitDeviceObjects()
{
m_pFont->InitDeviceObjects( m_pd3dDevice );
// 绘制底网格
m_pMeshFloor->Create( m_pd3dDevice, "data\\plane.x" );
m_pMeshFloor->SetFVF( m_pd3dDevice, MYVERTEX::FVF );
// 绘制物体网格
m_pMeshOcc->Create( m_pd3dDevice, FNAME_OCC );
m_pMeshOcc->SetFVF( m_pd3dDevice, MYVERTEX::FVF );
return InitVS();
}
//-----------------------------------------------------------------------------
// Name: RestoreDeviceObjects()
// Desc: Paired with InvalidateDeviceObjects()
// The device exists, but may have just been Reset(). Resources in
// D3DPOOL_DEFAULT and any other device state that persists during
// rendering should be set here. Render states, matrices, textures,
// etc., that don't change during rendering can be set once here to
// avoid redundant state setting during Render() or FrameMove().
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::RestoreDeviceObjects()
{
// TODO: setup render states
// Setup a material
D3DMATERIAL9 mtrl;
D3DUtil_InitMaterial( mtrl, 1.0f, 0.0f, 0.0f );
m_pd3dDevice->SetMaterial( &mtrl );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
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_MODULATE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
// Set miscellaneous render states
m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE, FALSE );
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x000F0F0F );
// Set the world matrix
D3DXMATRIX matIdentity;
D3DXMatrixIdentity( &matIdentity );
m_pd3dDevice->SetTransform( D3DTS_WORLD, &matIdentity );
// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
D3DXVECTOR3 vFromPt = D3DXVECTOR3( 0.0f, 2.0f, -4.0f );
D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
D3DXMatrixLookAtLH( &m_matView, &vFromPt, &vLookatPt, &vUpVec );
m_pd3dDevice->SetTransform( D3DTS_VIEW, &m_matView );
// Set the projection matrix
FLOAT fAspect = ((FLOAT)m_d3dsdBackBuffer.Width) / m_d3dsdBackBuffer.Height;
D3DXMatrixPerspectiveFovLH( &m_matProj, D3DX_PI/4, fAspect, 1.0f, 100.0f );
m_pd3dDevice->SetTransform( D3DTS_PROJECTION, &m_matProj );
// Set up lighting states
D3DLIGHT9 light;
D3DUtil_InitLight( light, D3DLIGHT_DIRECTIONAL, 0.0f, -1.0f, 0.0f );
m_pd3dDevice->SetLight( 0, &light );
m_pd3dDevice->LightEnable( 0, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
// Restore the font
m_pFont->RestoreDeviceObjects();
m_pMeshFloor->RestoreDeviceObjects( m_pd3dDevice );
m_pMeshOcc->RestoreDeviceObjects( m_pd3dDevice );
// 阴影运算参数初始化
m_vLightPos = D3DXVECTOR4( 50, 50, 0, 1 );
m_planeFloor = D3DXPLANE( 0, 1, 0, 0.1f );
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: FrameMove()
// Desc: Called once per frame, the call is the entry point for animating
// the scene.
//-----------------------------------------------------------------------------
HRESULT CMyD3DApplication::FrameMove()
{
// TODO: update world
// Update user input state
UpdateInput( &m_UserInput );
// Update the world state according to user input
D3DXMATRIX matWorld;
D3DXMATRIX matRotY;
D3DXMATRIX matRotX;
D3DXMATRIX matPos;
D3DXMATRIX matScl;
if( m_UserInput.bRotateLeft && !m_UserInput.bRotateRight )
m_fWorldRotY += m_fElapsedTime;
else if( m_UserInput.bRotateRight && !m_UserInput.bRotateLeft )
m_fWorldRotY -= m_fElapsedTime;
if( m_UserInput.bRotateUp && !m_UserInput.bRotateDown )
m_fWorldRotX += m_fElapsedTime;
else if( m_UserInput.bRotateDown && !m_UserInput.bRotateUp )
m_fWorldRotX -= m_fElapsedTime;
D3DXMatrixRotationX( &matRotX, m_fWorldRotX );
D3DXMatrixRotationY( &matRotY, m_fWorldRotY );
// 物体的变换矩阵
D3DXMatrixMultiply( &matWorld, &matRotY, &matRotX );
D3DXMatrixTranslation( &matPos, 1, 1, 0 );
D3DXMatrixScaling( &matScl, MESH_SCL, MESH_SCL, MESH_SCL );
m_matWorld = matScl * matWorld * matPos;
SetupVSConst();
return S_OK;
}
void CMyD3DApplication::SetupVSConst()
{
D3DXMATRIXA16 m;
/// 在顶点着色器常数table设置矩阵值(c0 ~ c7)
m = m_matWorld;
D3DXMatrixInverse( &m, NULL, &m );
D3DXMatrixTranspose( &m, &m );
m_pd3dDevice->SetVertexShaderConstantF( 0, (float*)&m, 4 ); // matIW
m = m_matProj;
D3DXMatrixTranspose( &m, &m );
m_pd3dDevice->SetVertexShaderConstantF( 4, (float*)&m, 4 ); // matP
m = m_matWorld * m_matView;
D3DXMatrixTranspose( &m, &m );
m_pd3dDevice->SetVertexShaderConstantF( 8, (float*)&m, 3 ); // matWV
/// 在顶点着色器常数table设置光源的位置值(c7)
D3DXMATRIXA16 matRot;
D3DXVECTOR4 v;
D3DXMatrixRotationY( &matRot, GetTickCount()/1000.0f );
D3DXVec4Transform( &v, &m_vLightPos, &matRot );
m_pd3dDevice->SetVertexShaderConstantF( 11, (float*)&m_vLightPos, 1 );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -