|
|
发表于 2007-3-13 18:56:00
|
显示全部楼层
Re:立体的3d程序
关键是摄象机控制。看看我的方法
//app.cpp
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
#include <d3d9.h>
#include <d3dx9.h>
#include "Mouse.h"
#include "camera.h"
const float PI=3.14159265358f;
void Cleanup();
void Initd3d(HWND hwnd);
void OnKeyDown(WORD KeyCode);
LRESULT WINAPI WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam);
void Render();
void FrameMove();
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR CmdLine,int nShowCmd);
CCamera* g_pMainCamera; //主摄象机,就是鼻梁(定义在世界坐标系中)
CCamera* g_pCamera; //左眼(在主摄象机的坐标系中,所以相对固定不动)
CCamera* g_pCamera2; //右眼(在主摄象机的坐标系中,所以相对固定不动)
//本例中,眼睛不可相对于鼻梁转动,始终注视着鼻梁(主摄象机)前方50.0的位置
CMouse* g_pMouse;
long g_mouseX,g_mouseY;
HWND g_hwnd=0;
//D3DXMATRIXA16 g_matTrans;
LPDIRECT3D9 g_pd3d=0;
LPDIRECT3DDEVICE9 g_pdev=0;
LPDIRECT3DVERTEXBUFFER9 g_pvb=0; //物体1左眼(红)模型
LPDIRECT3DINDEXBUFFER9 g_pib=0;
LPDIRECT3DVERTEXBUFFER9 g_pvb2=0; //物体1右眼(蓝)模型
LPDIRECT3DINDEXBUFFER9 g_pib2=0;
////
LPDIRECT3DVERTEXBUFFER9 g_pvbb=0; //物体2左眼(红)模型
LPDIRECT3DINDEXBUFFER9 g_pibb=0;
LPDIRECT3DVERTEXBUFFER9 g_pvbb2=0; //物体2右眼(蓝)模型
LPDIRECT3DINDEXBUFFER9 g_pibb2=0;
////
LPDIRECT3DVERTEXBUFFER9 g_pvbc=0; //物体3左眼(红)模型
LPDIRECT3DINDEXBUFFER9 g_pibc=0;
LPDIRECT3DVERTEXBUFFER9 g_pvbc2=0; //物体3右眼(蓝)模型
LPDIRECT3DINDEXBUFFER9 g_pibc2=0;
#define ture ((bool)-1)
bool g_bRed=ture;
#define RED(x) D3DCOLOR_XRGB(x,0,0)
#define BLUE(x) D3DCOLOR_XRGB(0,0,x)
typedef struct
{
FLOAT x,y,z;
unsigned long color;
}CUSTOMVERTEX;
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
#define TURE ture;
#define TRY(x) if(FAILED(x))MessageBox(0,"failed!","",0)
void Initd3d(HWND hwnd)
{
if(!(g_pd3d=Direct3DCreate9(D3D_SDK_VERSION))) MessageBox(0,"err","",0);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed=TURE;
d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat=D3DFMT_UNKNOWN;
TRY(g_pd3d->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&g_pdev));
////////////////////////////////////////
g_pMainCamera=new CCamera(0,0,-50.0f);//主摄象机(在世界坐标系中定义)
////
#define teye 3; //两眼距离的一半
D3DXVECTOR3 *pos=new D3DXVECTOR3;
pos->x=-teye; pos->y=0.0f; pos->z=0.0f; //左眼位置(主摄象机坐标系中)
D3DXVECTOR3 *pos2=new D3DXVECTOR3;
pos2->x=teye; pos2->y=0.0f; pos2->z=0.0f; //右眼位置(主摄象机坐标系中)
D3DXVECTOR3 *look=new D3DXVECTOR3;
look->x=teye; look->y=0.0f; look->z=50.0f; //左眼方向(与坐标系无关)
D3DXVECTOR3 *look2=new D3DXVECTOR3;
look2->x=-teye; look2->y=0.0f; look2->z=50.0f; //右眼方向(与坐标系无关)
D3DXVECTOR3 *up=new D3DXVECTOR3;
up->x=0.0f; up->y=1.0f; up->z=0.0f;
g_pCamera=new CCamera(pos,look,up);
g_pCamera2=new CCamera(pos2,look2,up);
///////////////////
}
void InitDraw()
{
TRY(g_pdev->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pvb,0));
TRY(g_pdev->CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
D3DPOOL_MANAGED,&g_pib,0));
const float len=1.0f;
CUSTOMVERTEX source_vertices[]={
{-len,-len,-len,RED(255)},
{-len, len,-len,RED(255)},
{ len, len,-len,RED(255)},
{ len,-len,-len,RED(255)},
{-len,-len, len,RED(255)},
{-len, len, len,RED(255)},
{ len, len, len,RED(255)},
{ len,-len, len,RED(255)},
};
CUSTOMVERTEX* pVertices;
TRY(g_pvb->Lock(0,8*sizeof(CUSTOMVERTEX),(void**)&pVertices,0));
memcpy(pVertices,source_vertices,8*sizeof(CUSTOMVERTEX));
g_pvb->Unlock();
/////////////ib///////////////
WORD* indices=0;
WORD tmpindices[]={0,1,2,0,2,3,4,6,5,4,7,6,4,5,1,4,1,0,3,2,6,3,6,7,1,5,6,1,6,2,4,0,3,4,3,7};
g_pib->Lock(0,0,(void**)&indices,0);
memcpy(indices,tmpindices,36*sizeof(WORD));
g_pib->Unlock();
//**************************************************************************
TRY(g_pdev->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pvb2,0));
TRY(g_pdev->CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
D3DPOOL_MANAGED,&g_pib2,0));
CUSTOMVERTEX source_vertices2[]={
{-len,-len,-len,BLUE(255)},
{-len, len,-len,BLUE(255)},
{ len, len,-len,BLUE(255)},
{ len,-len,-len,BLUE(255)},
{-len,-len, len,BLUE(255)},
{-len, len, len,BLUE(255)},
{ len, len, len,BLUE(255)},
{ len,-len, len,BLUE(255)},
};
CUSTOMVERTEX* pVertices2;
TRY(g_pvb2->Lock(0,8*sizeof(CUSTOMVERTEX),(void**)&pVertices2,0));
memcpy(pVertices2,source_vertices2,8*sizeof(CUSTOMVERTEX));
g_pvb2->Unlock();
/////////////ib///////////////
WORD* indices2=0;
WORD tmpindices2[]={0,1,2,0,2,3,4,6,5,4,7,6,4,5,1,4,1,0,3,2,6,3,6,7,1,5,6,1,6,2,4,0,3,4,3,7};
g_pib2->Lock(0,0,(void**)&indices2,0);
memcpy(indices2,tmpindices2,36*sizeof(WORD));
g_pib2->Unlock();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//////////////////////////
TRY(g_pdev->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pvbb,0));
TRY(g_pdev->CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
D3DPOOL_MANAGED,&g_pibb,0));
#define lenb 7.0f
CUSTOMVERTEX source_verticesb[]={
{-lenb,-lenb,-lenb+15,RED(255)},
{-lenb, lenb,-lenb+15,RED(255)},
{ lenb, lenb,-lenb+15,RED(255)},
{ lenb,-lenb,-lenb+15,RED(255)},
{-lenb,-lenb, lenb+15,RED(255)},
{-lenb, lenb, lenb+15,RED(255)},
{ lenb, lenb, lenb+15,RED(255)},
{ lenb,-lenb, lenb+15,RED(255)},
};
CUSTOMVERTEX* pVerticesb;
TRY(g_pvbb->Lock(0,8*sizeof(CUSTOMVERTEX),(void**)&pVerticesb,0));
memcpy(pVerticesb,source_verticesb,8*sizeof(CUSTOMVERTEX));
g_pvbb->Unlock();
/////////////ib///////////////
WORD* indicesb=0;
WORD tmpindicesb[]={0,1,2,0,2,3,4,6,5,4,7,6,4,5,1,4,1,0,3,2,6,3,6,7,1,5,6,1,6,2,4,0,3,4,3,7};
g_pibb->Lock(0,0,(void**)&indicesb,0);
memcpy(indicesb,tmpindicesb,36*sizeof(WORD));
g_pibb->Unlock();
//**************************************************************************
TRY(g_pdev->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pvbb2,0));
TRY(g_pdev->CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
D3DPOOL_MANAGED,&g_pibb2,0));
CUSTOMVERTEX source_verticesb2[]={
{-lenb,-lenb,-lenb+15,BLUE(255)},
{-lenb, lenb,-lenb+15,BLUE(255)},
{ lenb, lenb,-lenb+15,BLUE(255)},
{ lenb,-lenb,-lenb+15,BLUE(255)},
{-lenb,-lenb, lenb+15,BLUE(255)},
{-lenb, lenb, lenb+15,BLUE(255)},
{ lenb, lenb, lenb+15,BLUE(255)},
{ lenb,-lenb, lenb+15,BLUE(255)},
};
CUSTOMVERTEX* pVerticesb2;
TRY(g_pvbb2->Lock(0,8*sizeof(CUSTOMVERTEX),(void**)&pVerticesb2,0));
memcpy(pVerticesb2,source_verticesb2,8*sizeof(CUSTOMVERTEX));
g_pvbb2->Unlock();
/////////////ib///////////////
WORD* indicesb2=0;
WORD tmpindicesb2[]={0,1,2,0,2,3,4,6,5,4,7,6,4,5,1,4,1,0,3,2,6,3,6,7,1,5,6,1,6,2,4,0,3,4,3,7};
g_pibb2->Lock(0,0,(void**)&indicesb2,0);
memcpy(indicesb2,tmpindicesb2,36*sizeof(WORD));
g_pibb2->Unlock();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//***---------------------------------*******************
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//////////////////////////
TRY(g_pdev->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pvbc,0));
TRY(g_pdev->CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
D3DPOOL_MANAGED,&g_pibc,0));
#define lenc 3.0f
CUSTOMVERTEX source_verticesc[]={
{-lenc+18,-lenc,-lenc+5,RED(255)},
{-lenc+18, lenc,-lenc+5,RED(255)},
{ lenc+18, lenc,-lenc+5,RED(255)},
{ lenc+18,-lenc,-lenc+5,RED(255)},
{-lenc+18,-lenc, lenc+5,RED(255)},
{-lenc+18, lenc, lenc+5,RED(255)},
{ lenc+18, lenc, lenc+5,RED(255)},
{ lenc+18,-lenc, lenc+5,RED(255)},
};
CUSTOMVERTEX* pVerticesc;
TRY(g_pvbc->Lock(0,8*sizeof(CUSTOMVERTEX),(void**)&pVerticesc,0));
memcpy(pVerticesc,source_verticesc,8*sizeof(CUSTOMVERTEX));
g_pvbc->Unlock();
/////////////ib///////////////
WORD* indicesc=0;
WORD tmpindicesc[]={0,1,2,0,2,3,4,6,5,4,7,6,4,5,1,4,1,0,3,2,6,3,6,7,1,5,6,1,6,2,4,0,3,4,3,7};
g_pibc->Lock(0,0,(void**)&indicesc,0);
memcpy(indicesc,tmpindicesc,36*sizeof(WORD));
g_pibc->Unlock();
//**************************************************************************
TRY(g_pdev->CreateVertexBuffer(8*sizeof(CUSTOMVERTEX),D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED,&g_pvbc2,0));
TRY(g_pdev->CreateIndexBuffer(36*sizeof(WORD),D3DUSAGE_WRITEONLY,D3DFMT_INDEX16,
D3DPOOL_MANAGED,&g_pibc2,0));
CUSTOMVERTEX source_verticesc2[]={
{-lenc+18,-lenc,-lenc+5,BLUE(255)},
{-lenc+18, lenc,-lenc+5,BLUE(255)},
{ lenc+18, lenc,-lenc+5,BLUE(255)},
{ lenc+18,-lenc,-lenc+5,BLUE(255)},
{-lenc+18,-lenc, lenc+5,BLUE(255)},
{-lenc+18, lenc, lenc+5,BLUE(255)},
{ lenc+18, lenc, lenc+5,BLUE(255)},
{ lenc+18,-lenc, lenc+5,BLUE(255)},
};
CUSTOMVERTEX* pVerticesc2;
TRY(g_pvbc2->Lock(0,8*sizeof(CUSTOMVERTEX),(void**)&pVerticesc2,0));
memcpy(pVerticesc2,source_verticesc2,8*sizeof(CUSTOMVERTEX));
g_pvbc2->Unlock();
/////////////ib///////////////
WORD* indicesc2=0;
WORD tmpindicesc2[]={0,1,2,0,2,3,4,6,5,4,7,6,4,5,1,4,1,0,3,2,6,3,6,7,1,5,6,1,6,2,4,0,3,4,3,7};
g_pibc2->Lock(0,0,(void**)&indicesc2,0);
memcpy(indicesc2,tmpindicesc2,36*sizeof(WORD));
g_pibc2->Unlock();
/////////////////////////////
g_pdev->SetRenderState(D3DRS_LIGHTING,FALSE);
g_pdev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
void Cleanup()
{
delete g_pMouse;
delete g_pCamera;
delete g_pCamera2;
delete g_pMainCamera;
if(g_pib)g_pib->Release();
if(g_pvb)g_pvb->Release();
if(g_pib2)g_pib2->Release();
if(g_pvb2)g_pvb2->Release();
if(g_pibb)g_pibb->Release();
if(g_pvbb)g_pvbb->Release();
if(g_pibb2)g_pibb2->Release();
if(g_pvbb2)g_pvbb2->Release();
if(g_pibc)g_pibc->Release();
if(g_pvbc)g_pvbc->Release();
if(g_pibc2)g_pibc2->Release();
if(g_pvbc2)g_pvbc2->Release();
if(g_pdev)g_pdev->Release();
if(g_pd3d)g_pd3d->Release();
}
void FrameMove()
{
D3DXMATRIX matMainCamera=g_pMainCamera->GetViewMat(); //从世界坐标系到主摄象机的变换矩阵
D3DXMATRIX matEye; //从主摄象机坐标系变换到眼睛坐标系的矩阵
D3DXMATRIX matFinal; //==matMainCamera*matEye相乘结果,等于从世界坐标系变换到眼睛里
if(g_bRed)
{
matEye=g_pCamera->GetViewMat();
}
else
{
matEye=g_pCamera2->GetViewMat();
}
D3DXMatrixMultiply(&matFinal,&matMainCamera,&matEye);
g_pdev->SetTransform(D3DTS_VIEW,&matFinal);
//////
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI*0.5f,(float)800/(float)600,1.0f,1000.0f);
g_pdev->SetTransform(D3DTS_PROJECTION,&matProj);
}
void Render()
{
g_pdev->Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
g_pdev->BeginScene();
{
if(g_bRed)
{
///////
g_pdev->SetStreamSource(0,g_pvb,0,sizeof(CUSTOMVERTEX));
g_pdev->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pdev->SetIndices(g_pib);
g_pdev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
///////
g_pdev->SetStreamSource(0,g_pvbb,0,sizeof(CUSTOMVERTEX));
g_pdev->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pdev->SetIndices(g_pibb);
g_pdev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
///////
g_pdev->SetStreamSource(0,g_pvbc,0,sizeof(CUSTOMVERTEX));
g_pdev->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pdev->SetIndices(g_pibc);
g_pdev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
}
else
{
///////
g_pdev->SetStreamSource(0,g_pvb2,0,sizeof(CUSTOMVERTEX));
g_pdev->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pdev->SetIndices(g_pib2);
g_pdev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
///////
g_pdev->SetStreamSource(0,g_pvbb2,0,sizeof(CUSTOMVERTEX));
g_pdev->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pdev->SetIndices(g_pibb2);
g_pdev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
///////
g_pdev->SetStreamSource(0,g_pvbc2,0,sizeof(CUSTOMVERTEX));
g_pdev->SetFVF(D3DFVF_CUSTOMVERTEX);
g_pdev->SetIndices(g_pibc2);
g_pdev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,0,0,8,0,12);
}
}
g_pdev->EndScene();
/////////////////////
g_pdev-> resent(0,0,0,0);
}
LRESULT WINAPI WinProc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
switch(msg)
{
case WM_KEYDOWN:
OnKeyDown(wparam);
break;
case WM_MOUSEMOVE:
if(!g_pMouse)g_pMouse=new CMouse((float)g_mouseX,(float)g_mouseY,PI*0.001f,PI*0.001f);
float retx,rety;
g_pMouse->MovePos((float)g_mouseX,(float)g_mouseY,&retx,&rety);
g_pMainCamera->Rotate(rety,0,0);
g_pMainCamera->RotateByWorld(0,retx,0);
break;
case WM_DESTROY:
Cleanup();
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,msg,wparam,lparam);
}
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR CmdLine,int nShowCmd)
{
WNDCLASSEX wc={sizeof(WNDCLASSEX),CS_CLASSDC,WinProc,0L,0L,
GetModuleHandle(0),0,0,0,0,"instemast",0};
RegisterClassEx(&wc);
g_hwnd=CreateWindow("instemast","d3d",WS_OVERLAPPEDWINDOW,100,100,800,600,0,0,wc.hInstance,0);
Initd3d(g_hwnd);
InitDraw();
ShowWindow(g_hwnd,SW_SHOWDEFAULT);
UpdateWindow(g_hwnd);
///////////////////////////////////////
RECT rt;
GetWindowRect(g_hwnd,&rt);
SetCursorPos(g_mouseX=rt.left+400,g_mouseY=rt.top+300);
///////////////////////////////////////
MSG msg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message!=WM_QUIT)
{
if(: eekMessage(&msg,0,0U,0U,PM_REMOVE))
{
g_mouseX=msg.pt.x;g_mouseY=msg.pt.y;
::TranslateMessage(&msg);
: ispatchMessage(&msg);
}else
{
if(g_bRed)
g_bRed=false;
else if(!g_bRed)
g_bRed=ture;
FrameMove();
Render();
};
};
UnregisterClass("instemast",wc.hInstance);
return 0;
}
void OnKeyDown(WORD KeyCode)
{
D3DXMATRIXA16 mat;
// char tmp=(char)KeyCode;
float MoveSpeed=0.75f;
float RotateSpeed=PI*0.005f;
switch(KeyCode)
{
case 'W':
g_pMainCamera->Move(0,0,MoveSpeed);
break;
case 'S':
g_pMainCamera->Move(0,0,-MoveSpeed);
break;
case 'A':
g_pMainCamera->Move(-MoveSpeed,0,0);
break;
case 'D':
g_pMainCamera->Move(MoveSpeed,0,0);
break;
case 'R':
g_pMainCamera->Move(0,MoveSpeed,0);
break;
case 'F':
g_pMainCamera->Move(0,-MoveSpeed,0);
break;
////////////////
case 'L':
g_pMainCamera->Rotate(0,RotateSpeed,0);
break;
case 'J':
g_pMainCamera->Rotate(0,-RotateSpeed,0);
break;
case 'I':
g_pMainCamera->Rotate(-RotateSpeed,0,0);
break;
case 'K':
g_pMainCamera->Rotate(RotateSpeed,0,0);
break;
case 'U':
g_pMainCamera->Rotate(0,0,RotateSpeed);
break;
case 'O':
g_pMainCamera->Rotate(0,0,-RotateSpeed);
break;
};
}
////////////////////////////////////
另外mouse.cpp/h,camera.cpp/h(摄象机类)见这里:
http://bbs.gameres.com/showthread.asp?postid=467279 |
|