您的位置:首页 > 电脑网络 > 电脑配件 > 2011年01月29日

2011年01月29日

luyued 发布于 2011-02-06 03:06   浏览 N 次  

#include
#include
#include
#include
#pragma comment( lib, "d3d9.lib" )
#pragma comment( lib, "d3dx9.lib" )

HWND g_hWnd = NULL;
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVBL = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pPick = NULL;
LPD3DXFONT g_pFont = NULL;
LPDIRECT3DTEXTURE9 g_Texture = NULL; //用于粒子的纹理
float g_camalAngle = D3DX_PI*3/2;

POINT g_MousePos = {0,0};

float r = 50.0f; // 相机球体半径
float len = 20.0f; // 坐标系长度

#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 600

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
BOOL InitWnd( HINSTANCE hInstance );
BOOL InitD3D( HWND hWnd );
BOOL InitD3DData();
void RenderScene();
void SetCamcal();
void OnSize();

struct VERTEXUV
{
D3DXVECTOR3 posation;
D3DXVECTOR2 UV;
};
#define D3DFVF_VERTEXUV D3DFVF_XYZ|D3DFVF_TEX0

struct CUSTOMVERTEX
{
D3DXVECTOR3 posation;
D3DCOLOR color;
};
#define D3DFVF_CUSTOMVERTEX D3DFVF_XYZ|D3DFVF_DIFFUSE

int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd)
{

if ( !InitWnd( hInstance ) )
{
return 0;
}
if ( !InitD3D( g_hWnd ) )
{
return 0;
}
if ( !InitD3DData() )
{
return 0;
}
ShowWindow(g_hWnd, nShowCmd);
UpdateWindow(g_hWnd);

MSG msg = {0};

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
RenderScene();
}

return 0;
}

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
break;

case WM_KEYUP:
if(wParam == VK_ESCAPE)
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if ( wParam == VK_LEFT )
{
g_camalAngle -= 0.05;
SetCamcal();
}
if ( wParam == VK_RIGHT )
{
g_camalAngle += 0.05;
SetCamcal();
}
if ( wParam == VK_UP )
{

}
if ( wParam == VK_DOWN )
{
}
break;
case WM_MOUSEMOVE:
g_MousePos.x = LOWORD(lParam);
g_MousePos.y = HIWORD(lParam);
break;
case WM_SIZE:
OnSize();
break;
}

return DefWindowProc(hWnd, msg, wParam, lParam);
}

BOOL InitWnd( HINSTANCE hInstance )
{
WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW, MsgProc, 0L, 0L,
hInstance, NULL, LoadCursor(NULL, IDC_ARROW), NULL, NULL,
"MyBillBorand", NULL };
if( RegisterClassEx(&wc) == 0 )
{
return FALSE;
}

g_hWnd = CreateWindow("MyBillBorand", "BillBorand", WS_OVERLAPPEDWINDOW,
100, 100, WINDOW_WIDTH, WINDOW_HEIGHT,
NULL, NULL, hInstance, NULL);
if ( !g_hWnd )
{
return FALSE;
}
return TRUE;
}

BOOL InitD3D( HWND hWnd )
{
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_pD3D == NULL)
return FALSE;

D3DDISPLAYMODE displayMode;
if(FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
return FALSE;

RECT rect;
GetClientRect( hWnd, &rect );

D3DPRESENT_PARAMETERS d3dpp = {0};
d3dpp.Windowed = TRUE;
d3dpp.BackBufferWidth = rect.right;
d3dpp.BackBufferHeight = rect.bottom;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;

if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pD3DDevice)))
{
int i = GetLastError();
return false;
}

//设置投影矩阵
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, rect.right/rect.bottom, 1.0f, 1500.0f );
g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );

g_pD3DDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
g_pD3DDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB(200,200,200) );
g_pD3DDevice->SetRenderState( D3DRS_ZENABLE, TRUE );

SetCamcal();

D3DXFONT_DESC lf;
ZeroMemory(&lf, sizeof(D3DXFONT_DESC));
lf.Height = 20; // in logical units
lf.Width = 10; // in logical units
lf.Weight = 500; // boldness, range 0(light) - 1000(bold)
lf.Italic = FALSE;
lf.CharSet = DEFAULT_CHARSET;
lf.OutputPrecision = 0;
lf.MipLevels = D3DX_DEFAULT;
lf.Quality = 0;
lf.PitchAndFamily = 0;
strcpy(lf.FaceName, "宋体"); // font style

if( FAILED( D3DXCreateFontIndirect( g_pD3DDevice, &lf, &g_pFont ) ) )
{
return FALSE;
}

return TRUE;
}

BOOL InitD3DData()
{
if ( FAILED( g_pD3DDevice->CreateVertexBuffer( 6*sizeof(VERTEXUV), 0, D3DFVF_VERTEXUV, D3DPOOL_SYSTEMMEM, &g_pVB, NULL ) ) )
{
MessageBox( g_hWnd, "wrong", "g_pD3DDevice->CreateVertexBuffer()", MB_OK );
return FALSE;
}
VERTEXUV *pVerticesUV;
if ( FAILED( g_pVB->Lock( 0, 0, (void**)&pVerticesUV, 0 ) ) )
{
MessageBox( g_hWnd, "wrong", "g_pVB->Lock()", MB_OK );
return FALSE;
}
pVerticesUV[0].posation = D3DXVECTOR3( -5.0f, -5.0f, 0.0f );
pVerticesUV[1].posation = D3DXVECTOR3( -5.0f, 5.0f, 0.0f );
pVerticesUV[2].posation = D3DXVECTOR3( 5.0f, 5.0f, 0.0f );
pVerticesUV[3].posation = D3DXVECTOR3( -5.0f, -5.0f, 0.0f );
pVerticesUV[4].posation = D3DXVECTOR3( 5.0f, 5.0f, 0.0f );
pVerticesUV[5].posation = D3DXVECTOR3( 5.0f, -5.0f, 0.0f );
pVerticesUV[0].UV = D3DXVECTOR2( 0.0f, 1.0f );
pVerticesUV[1].UV = D3DXVECTOR2( 0.0f, 0.0f );
pVerticesUV[2].UV = D3DXVECTOR2( 1.0f, 0.0f );
pVerticesUV[3].UV = D3DXVECTOR2( 0.0f, 1.0f );
pVerticesUV[4].UV = D3DXVECTOR2( 1.0f, 0.0f );
pVerticesUV[5].UV = D3DXVECTOR2( 1.0f, 1.0f );
g_pVB->Unlock();

// 坐标系
if ( FAILED( g_pD3DDevice->CreateVertexBuffer( 6*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_SYSTEMMEM, &g_pVBL, NULL ) ) )
{
MessageBox( g_hWnd, "wrong", "g_pD3DDevice->CreateVertexBuffer()", MB_OK );
return FALSE;
}
CUSTOMVERTEX* pVertices;
if ( FAILED( g_pVBL->Lock( 0, 0, (void**)&pVertices, 0 ) ) )
{
MessageBox( g_hWnd, "wrong", "g_pVBL->Lock()", MB_OK );
return FALSE;
}
pVertices[0].posation = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
pVertices[1].posation = D3DXVECTOR3( len, 0.0f, 0.0f );
pVertices[2].posation = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
pVertices[3].posation = D3DXVECTOR3( 0.0f, len, 0.0f );
pVertices[4].posation = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
pVertices[5].posation = D3DXVECTOR3( 0.0f, 0.0f, len );
pVertices[0].color = D3DCOLOR_ARGB( 255, 0, 255, 255 );
pVertices[1].color = D3DCOLOR_ARGB( 255, 0, 255, 255 );
pVertices[2].color = D3DCOLOR_ARGB( 255, 255, 0, 255 );
pVertices[3].color = D3DCOLOR_ARGB( 255, 255, 0, 255 );
pVertices[4].color = D3DCOLOR_ARGB( 255, 255, 255, 0 );
pVertices[5].color = D3DCOLOR_ARGB( 255, 255, 255, 0 );

g_pVBL->Unlock();

if ( FAILED( g_pD3DDevice->CreateVertexBuffer( 6*sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_SYSTEMMEM, &g_pPick, NULL ) ) )
{
MessageBox( g_hWnd, "wrong", "g_pD3DDevice->CreateVertexBuffer()", MB_OK );
return FALSE;
}

//加载纹理
//if(D3DXCreateTextureFromFile(g_pD3DDevice, "snow.tga", &g_Texture) != D3D_OK)
//return FALSE;

return TRUE;
}

void SetCamcal()
{
float x = r*cos(g_camalAngle);
float y = r;
float z = r*sin(g_camalAngle);

D3DXVECTOR3 vEyePt( x, y, z );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0 );
D3DXMATRIX matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pD3DDevice->SetTransform( D3DTS_VIEW, &matView );
}

void RenderCoord()
{
// 坐标系
D3DXMATRIX mat;
D3DXMatrixIdentity( &mat );
g_pD3DDevice->SetTransform( D3DTS_WORLD, &mat );
g_pD3DDevice->SetTexture( 0, NULL );
g_pD3DDevice->SetStreamSource( 0, g_pVBL, 0, sizeof(CUSTOMVERTEX) );
g_pD3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pD3DDevice->DrawPrimitive( D3DPT_LINELIST, 0, 3 );

// x y z 位置
D3DXMATRIX matWorld, matView, matProj;
g_pD3DDevice->GetTransform( D3DTS_WORLD, &matWorld );
g_pD3DDevice->GetTransform( D3DTS_VIEW, &matView );
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &matProj );
D3DXVECTOR3 x( len, 0.0f, 0.0f );
D3DXVECTOR3 y( 0.0f, len, 0.0f );
D3DXVECTOR3 z( 0.0f, 0.0f, len );
D3DXVec3TransformCoord( &x, &x, &matWorld );
D3DXVec3TransformCoord( &y, &y, &matWorld );
D3DXVec3TransformCoord( &z, &z, &matWorld );

D3DXVec3TransformCoord( &x, &x, &matView );
D3DXVec3TransformCoord( &y, &y, &matView );
D3DXVec3TransformCoord( &z, &z, &matView );

D3DXVec3TransformCoord( &x, &x, &matProj );
D3DXVec3TransformCoord( &y, &y, &matProj );
D3DXVec3TransformCoord( &z, &z, &matProj );

RECT rect = {0};
GetClientRect( g_hWnd, &rect );

int sx = (x.x+1)*rect.right/2;
int sy = (-x.y+1)*rect.bottom/2;
RECT rectX = { sx, sy, sx+50, sy+50 };
sx = (y.x+1)*rect.right/2;
sy = (-y.y+1)*rect.bottom/2;
RECT rectY = { sx, sy, sx+25, sy+25 };
sx = (z.x+1)*rect.right/2;
sy = (-z.y+1)*rect.bottom/2;
RECT rectZ = { sx, sy, sx+25, sy+25 };
g_pFont->DrawText( NULL, "x", -1, &rectX, DT_LEFT, D3DCOLOR_XRGB( 255,0,0 ) );
g_pFont->DrawText( NULL, "y", -1, &rectY, DT_LEFT, D3DCOLOR_XRGB( 255,0,0 ) );
g_pFont->DrawText( NULL, "z", -1, &rectZ, DT_LEFT, D3DCOLOR_XRGB( 255,0,0 ) );
}

void OnSize()
{
RECT rect;
GetClientRect( g_hWnd, &rect );

D3DDISPLAYMODE displayMode;
g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode);

D3DPRESENT_PARAMETERS d3dpp = {0};
d3dpp.Windowed = TRUE;
d3dpp.BackBufferWidth = rect.right;
d3dpp.BackBufferHeight = rect.bottom;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = displayMode.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;

// 这个函数还不是很会调用
//g_pD3DDevice->Reset( &d3dpp );

//设置投影矩阵
D3DXMATRIX matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, rect.right/rect.bottom, 1.0f, 1500.0f );
g_pD3DDevice->SetTransform( D3DTS_PROJECTION, &matProj );

D3DVIEWPORT9 port;

port.X = rect.left;
port.Y = rect.top;
port.Width = rect.right;
port.Height = rect.bottom;
port.MaxZ = 1.0f;
port.MinZ = 0.0f;

// 这个也不会调用
//g_pD3DDevice->SetViewport( &port );
}

void RenderBill()
{
// y住公告板
/*float dir = g_camalAngle - D3DX_PI*3/2;
D3DXMatrixRotationY( &mat, -dir );
*/

// 标准公告板
// 求摄像机的转置矩阵 就是公告板的变换矩阵
D3DXMATRIX matView;
g_pD3DDevice->GetTransform( D3DTS_VIEW, &matView );
D3DXMatrixInverse( &matView, NULL, &matView );
matView._41 = 0.0f; // 将公告板位置放倒远点出
matView._42 = 0.0f;
matView._43 = 0.0f;

//g_pD3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
//g_pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
//g_pD3DDevice->SetTexture( 0, g_Texture );

g_pD3DDevice->SetTransform( D3DTS_WORLD, &matView );
g_pD3DDevice->SetStreamSource( 0, g_pVB, 0, sizeof(VERTEXUV) );
g_pD3DDevice->SetFVF( D3DFVF_VERTEXUV );
g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
}

void RenderMousePos()
{
RECT rect = {0};
GetClientRect( g_hWnd, &rect );
D3DXVECTOR3 vec( g_MousePos.x*1.0f/rect.right, g_MousePos.y*1.0f/rect.bottom, 0.0f );
D3DXVECTOR3 vecProj, vecView, vecWorld;
D3DXMATRIX matWorld, matView, matProj;

g_pD3DDevice->GetTransform( D3DTS_WORLD, &matWorld );
g_pD3DDevice->GetTransform( D3DTS_VIEW, &matView );
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &matProj );

D3DXMatrixInverse( &matWorld, NULL, &matWorld );
D3DXMatrixInverse( &matView, NULL, &matView );
D3DXMatrixInverse( &matProj, NULL, &matProj );

D3DXVec3TransformCoord( &vecProj, &vec, &matProj );
D3DXVec3TransformCoord( &vecView, &vecProj, &matView );
D3DXVec3TransformCoord( &vecWorld, &vecView, &matWorld );

char buf[1024] = {0};
sprintf( buf, "屏幕:%d, %d\n%f,%f", g_MousePos.x, g_MousePos.y, vecView.x, vecView.y );
g_pFont->DrawText( NULL, buf, -1, &rect, DT_RIGHT, D3DCOLOR_XRGB( 255,255,0 ) );
}

void RenderPick()
{
RECT rect;
GetClientRect( g_hWnd, &rect );
D3DXVECTOR3 vecProj1( 1.0f*g_MousePos.x/rect.right*2 -1.0f, -(1.0f*g_MousePos.y/rect.bottom*2-1.0f), 0.0f ); // 鼠标点对应投影坐标上的点
D3DXVECTOR3 vecProj2( 1.0f*g_MousePos.x/rect.right*2 -1.0f, -(1.0f*g_MousePos.y/rect.bottom*2-1.0f), 1.0f );

D3DXMATRIX matView, matProj;
g_pD3DDevice->GetTransform( D3DTS_VIEW, &matView );
g_pD3DDevice->GetTransform( D3DTS_PROJECTION, &matProj );
D3DXMatrixInverse( &matView, NULL, &matView );
D3DXMatrixInverse( &matProj, NULL, &matProj );

D3DXVECTOR3 vecView1, vecView2;
D3DXVec3TransformCoord( &vecView1, &vecProj1, &matProj ); // 在相机坐标系下的坐标
D3DXVec3TransformCoord( &vecView2, &vecProj2, &matProj );
D3DXVECTOR3 vecWorld1, vecWorld2;
D3DXVec3TransformCoord( &vecWorld1, &vecView1, &matView ); // 在世界中的坐标系
D3DXVec3TransformCoord( &vecWorld2, &vecView2, &matView ); // 这个是延长的

CUSTOMVERTEX* pVertices;
if ( FAILED( g_pPick->Lock( 0, 0, (void**)&pVertices, 0 ) ) )
{
MessageBox( g_hWnd, "wrong", "g_pVBL->Lock()", MB_OK );
return;
}
pVertices[0].posation = vecWorld1;
pVertices[1].posation = D3DXVECTOR3(0.0f,0.0f,0.0f);
pVertices[2].posation = vecWorld2;
pVertices[3].posation = D3DXVECTOR3(0.0f,0.0f,0.0f);
pVertices[0].color = D3DCOLOR_ARGB( 255, 0, 255, 0 );
pVertices[1].color = D3DCOLOR_ARGB( 255, 0, 255, 0 );
pVertices[2].color = D3DCOLOR_ARGB( 255, 0, 255, 0 );
pVertices[3].color = D3DCOLOR_ARGB( 255, 0, 255, 0 );
g_pPick->Unlock();

D3DXMATRIX mat;
D3DXMatrixIdentity( &mat );
g_pD3DDevice->SetTransform( D3DTS_WORLD, &mat );
g_pD3DDevice->SetTexture( 0, NULL );
g_pD3DDevice->SetStreamSource( 0, g_pPick, 0, sizeof(CUSTOMVERTEX) );
g_pD3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
//g_pD3DDevice->DrawPrimitive( D3DPT_LINELIST, 2, 1 );

D3DXVECTOR3 pVerticesUV[6];
pVerticesUV[0] = D3DXVECTOR3( -5.0f, -5.0f, 0.0f );
pVerticesUV[1] = D3DXVECTOR3( -5.0f, 5.0f, 0.0f );
pVerticesUV[2] = D3DXVECTOR3( 5.0f, 5.0f, 0.0f );
pVerticesUV[3] = D3DXVECTOR3( -5.0f, -5.0f, 0.0f );
pVerticesUV[4] = D3DXVECTOR3( 5.0f, 5.0f, 0.0f );
pVerticesUV[5] = D3DXVECTOR3( 5.0f, -5.0f, 0.0f );

D3DXMATRIX matBill; // 公告板的矩阵
g_pD3DDevice->GetTransform( D3DTS_VIEW, &matBill );
D3DXMatrixInverse( &matBill, NULL, &matBill );
matBill._41 = 0.0f; // 将公告板位置放倒远点出
matBill._42 = 0.0f;
matBill._43 = 0.0f;
UINT outs;
D3DXVec3TransformCoordArray( pVerticesUV, sizeof(D3DXVECTOR3), pVerticesUV, sizeof(D3DXVECTOR3), &matBill, 6 );

float fU, fV, fD;
RECT rectt = { g_MousePos.x, g_MousePos.y, g_MousePos.x+500, g_MousePos.y+50 };
char buf[1024] = {0};
if( D3DXIntersectTri( &pVerticesUV[0], &pVerticesUV[1], &pVerticesUV[2], &vecWorld1, &(vecWorld2-vecWorld1), &fU, &fV, &fD ) )
{
D3DXVECTOR3 vecPickPos = pVerticesUV[0] + fU * (pVerticesUV[1] - pVerticesUV[0]) + fV * (pVerticesUV[2] - pVerticesUV[0]);
sprintf( buf, " %f,%f,%f", vecPickPos.x, vecPickPos.y, vecPickPos.z );
g_pFont->DrawText( NULL, buf, -1, &rectt, DT_LEFT, D3DCOLOR_XRGB( 255,0,0 ) );
}
else if ( D3DXIntersectTri( &pVerticesUV[3], &pVerticesUV[4], &pVerticesUV[5], &vecWorld1, &(vecWorld2-vecWorld1), &fU, &fV, &fD ) )
{
D3DXVECTOR3 vecPickPos = pVerticesUV[3] + fU * (pVerticesUV[4] - pVerticesUV[3]) + fV * (pVerticesUV[5] - pVerticesUV[3]);
sprintf( buf, " %f,%f,%f", vecPickPos.x, vecPickPos.y, vecPickPos.z );
g_pFont->DrawText( NULL, buf, -1, &rectt, DT_LEFT, D3DCOLOR_XRGB( 255,0,0 ) );
}
}

void RenderScene()
{
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
g_pD3DDevice->BeginScene();

RenderCoord();
RenderBill();
RenderMousePos();
RenderPick();

g_pD3DDevice->EndScene();
HRESULT rst = g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
if ( FAILED( rst ) )
{
// 设备丢失
}
}

图文资讯
广告赞助商