//////////////////////////////////////////////////////////////////////////
//利用灵活顶点格式 绘制一个三角形
#include <d3d9.h>
#include <d3dx9.h>
#include <Windows.h>
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
//定义全局变量
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_Pd3dDevice = NULL;
//定义顶点缓存
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
//自定义顶点类型
struct CUSTOMVERTEX
{
float x,y,z,rhw; //rhw: RHW表示投影空间中顶点所在的齐次点(x,y,z,w)(homogeneous point)的w坐标的倒数(reciprocal)
DWORD color; //顶点颜色
};
//定义灵活顶点格式的定点结构
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZRHW | D3DFVF_DIFFUSE ) //包含位置属性 和 漫反射颜色属性
//初始化d3d
HRESULT InitD3D( HWND hwnd )
{
//获得d3d接口指针
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if ( !g_pD3D )
{
return E_FAIL;
}
//填充设备参数
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp,sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
//创建d3d设备
if( FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hwnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&g_Pd3dDevice)))
{
return E_FAIL;
}
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
//初始化顶点缓存
HRESULT InitVB()
{
//初始化三角形的三个顶点
CUSTOMVERTEX Vertexs[] =
{
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, }, // x, y, z, rhw, color
{ 250.0f, 250.0f, 0.5f, 1.0f, 0xff00ff00, },
{ 50.0f, 250.0f, 0.5f, 1.0f, 0xff00ffff, }
};
//创建顶点缓存
if( FAILED (g_Pd3dDevice->CreateVertexBuffer(
3* sizeof(CUSTOMVERTEX), //为缓存分配的字节数
0, //指定关于如何使用缓存的附加属性
D3DFVF_CUSTOMVERTEX, //存储在顶点缓存中顶点的灵活定点格式
D3DPOOL_DEFAULT, //容纳缓存的内存池
&g_pVB, //传出参数,接受所创建的顶点缓存指针
NULL
)))
{
return S_FALSE;
}
//填充定点缓存
VOID * pVertices = NULL; //定义指向缓存内部的指针
//通过锁住缓存获得pVertices 指针
if ( g_pVB->Lock(
0, //自缓存起始点到开始锁定位置的偏移量,这里表示锁定整个缓存
sizeof(Vertexs), //要锁定缓存的大小
(VOID **)&pVertices, //指向被锁定缓存起始位置的指针(传出参数)
0 //锁定标记
))
{
return S_FALSE;
}
//顶点信息拷贝到定点缓存中
memcpy(pVertices,Vertexs,sizeof(Vertexs));
g_pVB->Unlock(); //操作结束
return S_OK;
}
//释放资源
void CleanUp()
{
if (g_pVB )
{
g_pVB->Release();
}
if (g_Pd3dDevice )
{
g_Pd3dDevice->Release();
}
if (g_pD3D )
{
g_pD3D->Release();
}
}
//////////////////////////////////////////////////////////////////////////
//渲染函数
void Render(void)
{
//将屏幕清空为蓝色
g_Pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,255),1.0f,0);
if (SUCCEEDED (g_Pd3dDevice->BeginScene()))
{
//指定数据量输入源
g_Pd3dDevice->SetStreamSource(0,g_pVB,0,sizeof( CUSTOMVERTEX )); //最后一个参数是每个顶点的大小
//设置定点格式
g_Pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
//进行绘制
g_Pd3dDevice->DrawPrimitive(
D3DPT_TRIANGLELIST, //绘制图元的类型
0, //顶点数据流中标识顶点数据读取起点的元素的索引
1 //绘制图元的个数
);
g_Pd3dDevice->EndScene();
}
//将后台缓冲输出到屏幕
g_Pd3dDevice->Present(0,0,0,0);
}
//////////////////////////////////////////////////////////////////////////
//消息处理函数
LRESULT WINAPI MgsProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
{
CleanUp();
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
//WinMain
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hInstPre,LPSTR lpcmdLine,INT nShow)
{
WNDCLASSEX wc =
{
sizeof( WNDCLASSEX ), CS_CLASSDC, MgsProc, 0L, 0L,
GetModuleHandle( NULL ), NULL, NULL, NULL, NULL,
"D3D Tutorial", NULL
};
RegisterClassEx( &wc );
// Create the application's window
HWND hWnd = CreateWindow( "D3D Tutorial", "D3D Tutorial 02: Vertices",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
NULL, NULL, wc.hInstance, NULL );
//初始化d3d
if(SUCCEEDED(InitD3D(hWnd)))
{
//创建定点缓存
if(SUCCEEDED(InitVB()))
{
//显示窗口
ShowWindow(hWnd,SW_SHOWDEFAULT);
UpdateWindow(hWnd);
//消息循环
MSG msg;
ZeroMemory(&msg,sizeof(msg));
while(msg.message != WM_QUIT )
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
}
}
UnregisterClass("D3D Tutorial", wc.hInstance );
return 0;
}