您的位置:首页 > 其它

Direct3D成长日记(05):简单几何模型绘制

2009-05-15 16:24 260 查看
Direct3D成长日记(05):简单几何模型绘制

源程序:

//////////////////////////////////////////////////////////////////////////
//说明 :Direct3D成长日记(05):简单几何模型绘制。
//作者 :shenzi
//完成时间 :2009.05.07
//描述 :绘制简单的立体图形-正方体。可以通过鼠标进行控制几何体,鼠标按
// 下拖动鼠标,旋转几何体,松开鼠标停止。F1控制是否用索引顶点。
//////////////////////////////////////////////////////////////////////////

//包含头文件,相应库:
#include <windows.h>
#include <d3d9.h>
#include <d3dx9.h>

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

//全局变量声明:
LPDIRECT3D9 g_pD3D = NULL; //Direct3D接口指针
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;//Direct3D设备指针
LPDIRECT3DVERTEXBUFFER9 g_pVBuffer = NULL; //顶点缓存
LPDIRECT3DVERTEXBUFFER9 g_pVBuffer_Indexed = NULL;
LPDIRECT3DINDEXBUFFER9 g_pIndexBuffer = NULL;

#define WINDOW_CLASS_NAME L"Direct3D"
#define WINDOW_NAME L"Direct3DBasics Tutorial"

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

bool g_bUseIndexedGeometry = true;

//鼠标移动控制的旋转
float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;

//顶点结构
struct CUSTOMVERTEX
{
FLOAT X, Y ,Z;
DWORD COLOR;
};

#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)

//函数声明:
HRESULT InitD3D( HWND); //初始化Direct3D
void RenderFrame( void); //场景渲染
void CleanD3D( void); //释放资源
HRESULT InitGraphics(void); //初始化图形
void SetupMatrices(void); //模型视图投影矩阵设置

//WINDOWS 消息处理函数:
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM);

//WinMain函数:
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hprevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
//变量声明:
HWND hwnd;
MSG msg;
WNDCLASSEX wc;

ZeroMemory(&wc, sizeof(WNDCLASSEX));

//创建窗口类
wc.cbClsExtra = 0;
wc.cbSize = sizeof(WNDCLASSEX);
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.hCursor = LoadCursor( NULL, IDC_ARROW);
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = WINDOW_CLASS_NAME;
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;

//注册窗口类
RegisterClassEx(&wc);

//初始化窗口
hwnd = CreateWindowEx( NULL,
WINDOW_CLASS_NAME,
WINDOW_NAME,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
SCREEN_WIDTH,
SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);

//显示,更新窗口:
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);

if (SUCCEEDED(InitD3D(hwnd)))
{
if (SUCCEEDED(InitGraphics()))
{
ZeroMemory(&msg, sizeof(MSG));

//消息循环:
while( msg.message != WM_QUIT )
{
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
RenderFrame();
}
}

}

UnregisterClass( WINDOW_CLASS_NAME, wc.hInstance );
return 0;

}

LRESULT WINAPI WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
static POINT ptLastMousePosit;
static POINT ptCurrentMousePosit;
static bool bMousing;
switch( msg )
{
case WM_DESTROY:
CleanD3D();
PostQuitMessage( 0 );
return 0;
case WM_LBUTTONDOWN:
{
ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
bMousing = true;
}
break;

case WM_LBUTTONUP:
{
bMousing = false;
}
break;

case WM_MOUSEMOVE:
{
ptCurrentMousePosit.x = LOWORD (lParam);
ptCurrentMousePosit.y = HIWORD (lParam);

if( bMousing )
{
g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
}

ptLastMousePosit.x = ptCurrentMousePosit.x;
ptLastMousePosit.y = ptCurrentMousePosit.y;
}
break;
case WM_KEYDOWN:
switch (wParam)
{
case VK_F1:
g_bUseIndexedGeometry = !g_bUseIndexedGeometry;
break;
}
break;
}

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

HRESULT InitD3D(HWND hwnd)
{
//创建D3D对象:
if (NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)))
{
return E_FAIL;
}

//定义窗口的显示信息:
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp));

d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hwnd;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.EnableAutoDepthStencil = TRUE;

//创建D3D设备:
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&g_pD3DDevice)))
{
return E_FAIL;
}

g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

g_pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);

return S_OK;
}
void RenderFrame(void)
{
if(NULL == g_pD3DDevice)
return;
//清空背景缓冲区:
g_pD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

if(SUCCEEDED(g_pD3DDevice->BeginScene()))
{
//渲染场景:
//设置顶点结构:
g_pD3DDevice->SetFVF(CUSTOMFVF);

SetupMatrices();

D3DXMATRIX matTrans;
D3DXMATRIX matRot;
D3DXMATRIX matWorld;

D3DXMatrixTranslation( &matTrans, 0.0f, 0.0f, 5.0f );

D3DXMatrixRotationYawPitchRoll( &matRot,
D3DXToRadian(g_fSpinX),
D3DXToRadian(g_fSpinY),
0.0f );
matWorld = matRot * matTrans;
g_pD3DDevice->SetTransform( D3DTS_WORLD, &matWorld );

if( g_bUseIndexedGeometry == true )
{
g_pD3DDevice->SetStreamSource( 0, g_pVBuffer_Indexed, 0, sizeof(CUSTOMVERTEX) );
g_pD3DDevice->SetIndices( g_pIndexBuffer );
g_pD3DDevice->SetFVF( CUSTOMFVF );

g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, 8, 0, 2 );
g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, 8, 4, 2 );
g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, 8, 8, 2 );
g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, 8, 12, 2 );
g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, 8, 16, 2 );
g_pD3DDevice->DrawIndexedPrimitive( D3DPT_TRIANGLESTRIP, 0, 0, 8, 20, 2 );
}
else
{
g_pD3DDevice->SetStreamSource( 0, g_pVBuffer, 0, sizeof(CUSTOMVERTEX) );
g_pD3DDevice->SetFVF( CUSTOMFVF );

g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 4, 2 );
g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 8, 2 );
g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 12, 2 );

//利于观察按F1后,区别用索引顶点绘图。
//g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 16, 2 );
//g_pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 20, 2 );
}

g_pD3DDevice->EndScene();
}
//把渲染的场景显示在窗口:
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);

}
void CleanD3D(void)
{
//释放资源
if (NULL != g_pVBuffer)
{
g_pVBuffer->Release();
}
if (NULL != g_pVBuffer_Indexed)
{
g_pVBuffer_Indexed->Release();
}
if (NULL !+ g_pIndexBuffer)
{
g_pIndexBuffer->Release();
}
if(NULL != g_pD3DDevice)
g_pD3DDevice->Release();
if(NULL != g_pD3D)
g_pD3D->Release();

g_pVBuffer = NULL;
g_pVBuffer_Indexed = NULL;
g_pIndexBuffer = NULL;
g_pD3DDevice = NULL;
g_pD3D = NULL;
}

HRESULT InitGraphics(void)
{
//定义顶点数组
CUSTOMVERTEX vertices[] =
{
// Quad 0
{-1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // 0 (unique)
{ 1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, // 1 (unique)
{-1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, // 2 (unique)
{ 1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ) }, // 3 (unique)

// Quad 1
{-1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 1.0, 1.0 ) }, // 4 (unique)
{-1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ) }, // 5 (unique)
{ 1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 1.0, 1.0 ) }, // 6 (unique)
{ 1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // 7 (unique)

// Quad 2
{-1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 1.0, 1.0 ) }, // 4 (start repeating here)
{ 1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 1.0, 1.0 ) }, // 6 (repeat of vertex 6)
{-1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // 0 (repeat of vertex 0... etc.)
{ 1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, // 1

// Quad 3
{-1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ) }, // 5
{-1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, // 2
{ 1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // 7
{ 1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ) }, // 3

// Quad 4
{ 1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, // 1
{ 1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 1.0, 1.0 ) }, // 6
{ 1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ) }, // 3
{ 1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // 7

// Quad 5
{-1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // 0
{-1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, // 2
{-1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 1.0, 1.0 ) }, // 4
{-1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ) } // 5

};
//索引顶点数组只需用到以上八个顶点
CUSTOMVERTEX Vertices_indexed[] =
{
{-1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) }, // 0
{ 1.0f, 1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 0.0, 1.0 ) }, // 1
{-1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 0.0, 0.0, 1.0, 1.0 ) }, // 2
{ 1.0f,-1.0f,-1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 0.0, 1.0 ) }, // 3
{-1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 1.0, 1.0 ) }, // 4
{-1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 0.0, 1.0, 1.0, 1.0 ) }, // 5
{ 1.0f, 1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 1.0, 1.0, 1.0 ) }, // 6
{ 1.0f,-1.0f, 1.0f, D3DCOLOR_COLORVALUE( 1.0, 0.0, 0.0, 1.0 ) } // 7
};
//索引数组
WORD Indices[] =
{
0, 1, 2, 3, // Quad 0
4, 5, 6, 7, // Quad 1
4, 6, 0, 1, // Quad 2
5, 2, 7, 3, // Quad 3
1, 6, 3, 7, // Quad 4
0, 2, 4, 5 // Quad 5
};

//建立顶点缓存
if (FAILED(g_pD3DDevice->CreateVertexBuffer(sizeof(vertices),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&g_pVBuffer,
NULL)))
{
return E_FAIL;
}

//通过Lock,Unlock 为顶点缓存填充数据(顶点信息):
VOID * pV;

if(FAILED(g_pVBuffer->Lock(0,
sizeof(vertices),
(void**)&pV,
0)))
{
return E_FAIL;
}

memcpy(pV, vertices, sizeof(vertices));

g_pVBuffer->Unlock();

//同样方法建立顶点缓存

if(FAILED(g_pD3DDevice->CreateVertexBuffer( 8*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&g_pVBuffer_Indexed,
NULL )))
{
return E_FAIL;
}
pV = NULL;

g_pVBuffer_Indexed->Lock( 0, sizeof(Vertices_indexed), (void**)&pV, 0 );
memcpy( pV, Vertices_indexed, sizeof(Vertices_indexed) );
g_pVBuffer_Indexed->Unlock();

if(FAILED(g_pD3DDevice->CreateIndexBuffer( 24*sizeof(WORD),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&g_pIndexBuffer,
NULL )))
{
return E_FAIL;
}
WORD *pIndices = NULL;

g_pIndexBuffer->Lock( 0, sizeof(Indices), (void**)&pIndices, 0 );
memcpy( pIndices, Indices, sizeof(Indices) );
g_pIndexBuffer->Unlock();

}

void SetupMatrices(void)
{
//投影变换
D3DXMATRIX matProjection;

D3DXMatrixPerspectiveFovLH(&matProjection,
D3DX_PI/4,
(FLOAT)SCREEN_WIDTH/(FLOAT)SCREEN_HEIGHT,
0.1f,
100.0f);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProjection);

}

结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: