|
|

楼主 |
发表于 2007-6-18 08:52:00
|
显示全部楼层
Re:为什么我做的灵活的摄象机一动不动?
谢谢justgame持续的关注.
好.我把程序其余部分的代码发上来,camera.cpp,camera.h在顶楼有,就不再占用篇幅了.
//game.cpp
#include <Windows.h>
#include <mmsystem.h>
#include <d3dx9.h>
#pragma warning( disable : 4996 ) // disable deprecated warning
#include <strsafe.h>
#pragma warning( default : 4996 )
#include "Terrain10.h"
#include "camera.h"
//-----------------------------------------------------------------------------
// Global variables
//-----------------------------------------------------------------------------
LPDIRECT3D9 g_pD3D = NULL; // Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
ID3DXMesh* mesh = 0;
const int Width = 800;
const int Height = 600;
POINT m_ptLastMouse; // position of last mouse point
float Z=0.0f;
D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f);
float X=0.0f;
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 g_matWorld;
Terrain* g_pTerrain;
const DWORD Terrain::Vertex::FVF = D3DFVF_XYZ|D3DFVF_TEX1;
Camera* g_pCamera = new Camera(vEyePt,vLookatPt,vUpVec);
D3DXMATRIXA16 matView;
//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
// Create the D3D object.
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;
// Set up the structure used to create the D3DDevice. Since we are now
// using more complex geometry, we will create a device with a zbuffer.
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
// Create the D3DDevice
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}
// Turn on the zbuffer
g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, true );
//g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Turn on ambient lighting
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0xffffffff );
// g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_WIREFRAME);
// Turn off D3D lighting
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
//g_pd3dDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID );
g_pTerrain = new Terrain(g_pd3dDevice,9, 9, 10);
D3DXCreateTeapot(g_pd3dDevice,&mesh,0);
return S_OK;
}
//-----------------------------------------------------------------------------
// Name: Cleanup()
// Desc: Releases all previously initialized objects
//-----------------------------------------------------------------------------
VOID Cleanup()
{
mesh->Release();
mesh = 0;
delete(g_pTerrain);
delete(g_pCamera);
if( g_pd3dDevice != NULL )
g_pd3dDevice->Release();
if( g_pD3D != NULL )
g_pD3D->Release();
}
void OnBegin( int nX, int nY)
{
m_ptLastMouse.x =nX;
m_ptLastMouse.y =nY;
}
//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
D3DXMatrixIdentity(&g_matWorld);
g_pd3dDevice->SetTransform( D3DTS_WORLD,&g_matWorld );
D3DXMatrixLookAtLH( &matView,&vEyePt, &vLookatPt , &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj,D3DX_PI/4, 1.0f, 1.0f, 1000.0f);
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}
//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
// Clear the backbuffer and the zbuffer
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(250,250,250), 1.0f, 0 );
// Begin the scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
// Setup the world, view, and projection matrices
SetupMatrices();
// Meshes are divided into subsets, one for each material. Render them in
mesh->DrawSubset(0);
g_pTerrain->Render();
// End the scene
g_pd3dDevice->EndScene();
}
// Present the backbuffer contents to the display
g_pd3dDevice-> resent( NULL, NULL, NULL, NULL );
}
//-----------------------------------------------------------------------------
// Name: MsgProc()
// Desc: The window's message handler
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
// Current mouse position
int iMouseX = (short)LOWORD(lParam);
int iMouseY = (short)HIWORD(lParam);
switch( msg )
{
case WM_DESTROY:
Cleanup();
PostQuitMessage( 0 );
return 0;
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN:
SetCapture( hWnd );
OnBegin( iMouseX, iMouseY);//
return TRUE;
case WM_MOUSEMOVE:
//ADD 摄象机的代码
if( MK_RBUTTON&wParam )
{
// Compute the drag rectangle in screen coord.
// POINT ptCursor = { (short)LOWORD(lParam), (short)HIWORD(lParam) };
// Update member var state
// if( ( msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK ))
// Capture the mouse, so if the mouse button is
// released outside the window, we'll get the WM_LBUTTONUP message
SetCapture(hWnd);
Z = (iMouseY-m_ptLastMouse.x)/10.0f;
X = (iMouseX-m_ptLastMouse.x)/10.0f;
g_pCamera->walk(Z);
g_pCamera->yaw(X);
g_pCamera->getViewMatrix(&matView);//update the view matrix representing the cameras new position/orientation
D3DXMatrixLookAtLH( &matView,&vEyePt, &vLookatPt , &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
}
return TRUE;
case WM_RBUTTONUP:
{
ReleaseCapture();
break;
}
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: The application's entry point
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
// Register the window class
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
"Terrain8", NULL };
RegisterClassEx( &wc );
// Create the application's window
HWND hWnd = CreateWindow( "Terrain8", "Terrain8",
WS_OVERLAPPEDWINDOW, 0, 0, 800, 800,
NULL, NULL, wc.hInstance, NULL );
// Initialize Direct3D
if( SUCCEEDED( InitD3D( hWnd ) ) )
{
// Show the window
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
// Enter the message loop
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
Render();
}
}
UnregisterClass( "Terrain8", wc.hInstance );
return 0;
}
//Terrain10.cpp
#include "Terrain10.h"
Terrain::Terrain(IDirect3DDevice9* device,int numVertsPerRow,int numVertsPerCol,int cellSpacing)
{
m_pDevice = device;//quote globle variable
m_pVB = 0;//pionter to vertex buffer
m_pIB = 0; //pionter to index buffer
pTex = 0;
_numVertsPerRow = numVertsPerRow ;//number of vertices per row
_numVertsPerCol = numVertsPerCol ;//number of vertices per column
_cellSpacing = cellSpacing;//space between neighbor vertexs
_numCellsPerRow = _numVertsPerRow-1;//number of cells per row
_numCellsPerCol = _numVertsPerCol-1;//number of cells per column
_width = _numCellsPerRow*_cellSpacing;//terrain width
_depth = _numCellsPerCol*_cellSpacing;//terrain depth
_numVertices = _numVertsPerRow*_numVertsPerCol;//total nummber of vertexes
_numTriangles = _numCellsPerRow*_numCellsPerCol*2;//total triangles of the terrain
computeVertices();//deal with vertices
computeIndices();//deal with indices
createTexture();
};
Terrain::~Terrain()
{
m_pVB->Release();
m_pIB->Release();
pTex->Release();
};
bool Terrain::computeVertices()
{
HRESULT hr = 0;
hr = m_pDevice->CreateVertexBuffer(_numVertices*sizeof(Vertex),D3DUSAGE_WRITEONLY,Vertex::FVF,D3DPOOL_MANAGED,&m_pVB,0);
if(FAILED(hr))
return false;
int startX = -_width/2;//set piont (0,0) the center of the terrain
int startZ = _depth/2;
int endX = _width/2;
int endZ = -_depth/2;
float uCoordIncrementSize = 1.0f/(float)_numCellsPerRow;//compute the increment size of texture coordinates
float vCoordIncrementSize = 1.0f/(float)_numCellsPerCol;//from one vertex to the next
Vertex* v = 0;
m_pVB->Lock(0,0,(void**)&v,0);
int i = 0;
for(int z = startZ;z>=endZ;z-=_cellSpacing)//
{
int j = 0;
for(int x = startX;x<=endX;x+=_cellSpacing)
{
int index = i*_numVertsPerRow+j;//give every vertex its coordinate
v[index] = Vertex((float)x,(float)0,(float)z,(float)j*uCoordIncrementSize,(float)i*vCoordIncrementSize);
j++;
}
i++;
}
m_pVB->Unlock();
return true;
}
bool Terrain::computeIndices()
{
HRESULT hr = 1;
hr = m_pDevice->CreateIndexBuffer(3*_numTriangles*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,D3DPOOL_MANAGED,&m_pIB,0);//
if(FAILED(hr))
return false;
WORD* indices =0;
m_pIB->Lock(0,0,(void**)&indices,0);
int baseIndex = 0;
for(int i = 0;i<_numCellsPerCol;i++)
{
for(int j = 0;j<_numCellsPerRow;j++)//assign every vertex a number,weave tiangles
{
indices[baseIndex] = i*_numVertsPerRow+j;
indices[baseIndex+1] = i*_numVertsPerRow+j+1;
indices[baseIndex+2] = (i+1)*_numVertsPerRow+j;
indices[baseIndex+3] = (i+1)*_numVertsPerRow+j;
indices[baseIndex+4] = i*_numVertsPerRow+j+1;
indices[baseIndex+5] = (i+1)*_numVertsPerRow+j+1;
baseIndex +=6;
}
}
m_pIB->Unlock();
return true;
}
bool Terrain::Render()
{
m_pDevice->SetRenderState(D3DRS_FILLMODE,D3DFILL_SOLID );
m_pDevice->SetStreamSource( 0,m_pVB,0,sizeof(Vertex) );
m_pDevice->SetIndices( m_pIB );
m_pDevice->SetFVF(Vertex::FVF);
m_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,_numVertices,0,_numTriangles);//
return true;
}
bool Terrain::createTexture()
{
HRESULT hr = 0;
hr = D3DXCreateTextureFromFile(m_pDevice,"Grass.bmp",&pTex);
if(FAILED(hr))
return false;
m_pDevice->SetTexture(0,pTex);
m_pDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_LINEAR);
m_pDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_LINEAR);
m_pDevice->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_POINT);
return true;
}
float Terrain::getHeight(float x,float z)//not completed
{
x = ((float)_width/2.0f)+x;
z = ((float)_depth/2.0f)+z;
x /= (float)_cellSpacing;
z /= (float)_cellSpacing;
float col = ::floorf(x);
float row = ::floorf(z);
return 1;
}
//Terrain10.h
#include <d3dx9.h>
class Terrain
{
public:
Terrain(IDirect3DDevice9* device,int numVertsPerRow,int numVertsPerCol,int cellSpacing);
Terrain(IDirect3DDevice9* device);
~Terrain();
bool Render();
float getHeight(float x,float z);
struct Vertex
{
Vertex(){}
Vertex(float x,float y,float z,float u,float v)
{
_x=x,_y=y,_z=z,_u=u,_v=v;
}
float _x,_y,_z;
float _u,_v;
static const DWORD FVF;
};
private:
IDirect3DVertexBuffer9* m_pVB ;
IDirect3DIndexBuffer9* m_pIB ;
IDirect3DDevice9* m_pDevice;
IDirect3DTexture9* pTex;
bool computeVertices();
bool computeIndices();
bool createTexture();
int _numVertsPerRow;
int _numVertsPerCol;
int _cellSpacing;
int _numCellsPerRow;
int _numCellsPerCol;
int _width;
int _depth;
int _numVertices;
int _numTriangles;
};
|
|