顶点缓存

#include <windows.h>
#include <tchar.h>
#include <d3dx9.h>

#pragma comment(lib,"D3D9.lib")

//函数声明
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);//窗口过程
bool InitD3D(HINSTANCE hInstance);
bool Setup();
void Cleanup();
void Render();		//绘制


//窗口相关全局变量
const TCHAR g_szWindowTitleName[] = _T("顶点缓存");	//窗口标题
const TCHAR g_szWindowClassName[] = _T("WindowClass");	//窗口类名
int g_cxWindow = 640;				//窗口宽
int g_cyWindow = 480;				//窗口高


//Direct3D全局变量
IDirect3D9 * g_pD3d = nullptr;				//Direct3D对象指针
IDirect3DDevice9 * g_pDevice = nullptr;		//Direct3D设备对象指针
IDirect3DVertexBuffer9 * g_pVertexBuffer = nullptr;	//顶点缓存

struct Vertex					//定义顶点结构
{
	Vertex(float x, float y, float z, float rhw, DWORD color)
	{
		_x = x;
		_y = y;
		_z = z;
		_rhw = rhw;
		_color = color;
	}
	float _x, _y, _z, _rhw;
	DWORD _color;
	static const DWORD FVF;
};

const DWORD Vertex::FVF = D3DFVF_DIFFUSE | D3DFVF_XYZRHW;	//使用了D3DFVF_XYZRHW标记,表示不对顶点进行变换


int WINAPI _tWinMain(HINSTANCE hInstance,
					 HINSTANCE hPreInstance,
					 LPTSTR lpCmdLine,
					 int nShowCmd)
{
	if (!InitD3D(hInstance))
	{
		MessageBox(NULL, _T("初始化D3D失败"), NULL, MB_OK);
		return 0;
	}
	if (!Setup())
	{
		MessageBox(NULL, _T("启动失败!"), NULL, MB_OK);
		return 0;
	}

	MSG msg;
	memset(&msg, 0, sizeof(msg));
	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
				break;
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			Render();											//5 绘制
		}
	}
	Cleanup();													//6 清理资源
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch (uMsg)
	{
	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)
			DestroyWindow(hWnd);
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

bool InitD3D(HINSTANCE hInstance)
{
	WNDCLASS wndClass;						//初始化窗口类结构体
	wndClass.cbClsExtra = 0;
	wndClass.cbWndExtra = 0;
	wndClass.style = CS_HREDRAW | CS_VREDRAW;
	wndClass.hInstance = hInstance;
	wndClass.hbrBackground = static_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
	wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
	wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wndClass.lpfnWndProc = WndProc;
	wndClass.lpszClassName = g_szWindowClassName;
	wndClass.lpszMenuName = NULL;

	BOOL bRet;
	bRet = RegisterClass(&wndClass);		//注册窗口类
	if (!bRet)
	{
		MessageBox(NULL, _T("Register window class fail"), NULL, MB_OK);
		return FALSE;
	}

	HWND  hWnd;
	hWnd = CreateWindow(g_szWindowClassName,//创建窗口
						g_szWindowTitleName,
						WS_OVERLAPPEDWINDOW,
						CW_USEDEFAULT,
						CW_USEDEFAULT,
						g_cxWindow,
						g_cyWindow,
						NULL,
						NULL,
						hInstance,
						NULL);
	if (!hWnd)
	{
		MessageBox(NULL, _T("Create Window FAil"), NULL, MB_OK);
		return FALSE;
	}

	ShowWindow(hWnd, SW_SHOW);
	UpdateWindow(hWnd);

	//init Direct3D
	g_pD3d = Direct3DCreate9(D3D_SDK_VERSION);		//1、创建D3D对象
	if (!g_pD3d)
	{
		MessageBox(NULL, _T("创建D3D对象失败!"), NULL, MB_OK);
		return false;
	}
	D3DCAPS9 caps;									//2、检查设备能力,硬件是否支持顶点运算
	g_pD3d->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &caps);
	int cap;
	if (caps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT)
		cap = D3DCREATE_HARDWARE_VERTEXPROCESSING;	//用硬件方式处理顶点运算
	else
		cap = D3DCREATE_SOFTWARE_VERTEXPROCESSING;	//用软件方式处理顶点运算

	HRESULT hr;
	D3DPRESENT_PARAMETERS d3dpp;					//3、初始化D3DPRESENT_PARAMETERS结构体
	memset(&d3dpp, 0, sizeof(D3DPRESENT_PARAMETERS));
	d3dpp.BackBufferWidth = 640;
	d3dpp.BackBufferHeight = 480;
	d3dpp.EnableAutoDepthStencil = true;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
	d3dpp.Windowed = true;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
	d3dpp.hDeviceWindow = hWnd;
	d3dpp.BackBufferCount = 1;
	d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

	hr = g_pD3d->CreateDevice(D3DADAPTER_DEFAULT,	//4、创建D3D设备对象
							  D3DDEVTYPE_HAL,
							  hWnd,
							  cap,
							  &d3dpp,
							  &g_pDevice);
	if (FAILED(hr))
	{
		MessageBox(NULL, _T("创建D3D设备对象失败!"), NULL, MB_OK);
		return false;
	}
	return true;
}

bool Setup()
{
	HRESULT hr;
	//顶点缓存的使用1:创建顶点缓存
	hr = g_pDevice->CreateVertexBuffer(sizeof(Vertex)* 3,
									   D3DUSAGE_DYNAMIC,
									   Vertex::FVF,
									   D3DPOOL_DEFAULT,
									   &g_pVertexBuffer,
									   NULL);
	if (FAILED(hr))
	{
		MessageBox(NULL, _T("创建顶点缓存失败!"), NULL, MB_OK);
		return false;
	}

	//顶点缓存的使用2:写入顶点数据(在此之前需要定义顶点结构)		
	/*画一个三角形
	    v1
	    /\
	   /  \
	  /    \
	v3------v2
	注意三角形的顶点顺序(v1、v2、v3)为顺时针(即正面)
	这样才能将效果给渲染出来,因为默认情况下D3D只渲染正面三角形
	*/
	Vertex * pVertexs = nullptr;
	g_pVertexBuffer->Lock(0, 0, (void**)&pVertexs, 0);
	pVertexs[0] = Vertex(g_cxWindow / 2, g_cyWindow / 2 - 100, 1.f, 1.f, D3DCOLOR_XRGB(255, 0, 0));
	pVertexs[1] = Vertex(g_cxWindow / 2 + 100, g_cyWindow / 2 + 100, 1.f, 1.f, D3DCOLOR_XRGB(0, 255, 0));
	pVertexs[2] = Vertex(g_cxWindow / 2 - 100, g_cyWindow / 2 + 100, 1.f, 1.f, D3DCOLOR_XRGB(0, 0, 255));
	g_pVertexBuffer->Unlock();
	return true;
}

void Cleanup()
{
	if (g_pDevice){ g_pDevice->Release(); g_pDevice = nullptr; }
	if (g_pD3d){ g_pD3d->Release(); g_pD3d = nullptr; }
	if (g_pVertexBuffer){ g_pVertexBuffer->Release(), g_pVertexBuffer = nullptr; }	//顶点缓存的使用7:释放顶点数据
}

void Render()
{
	HRESULT hr;
	hr = g_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB(255, 255, 255, 255), 1.f, 0);
	hr = g_pDevice->BeginScene();
	if (SUCCEEDED(hr))
	{
		g_pDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(Vertex));		//顶点缓存的使用3:将顶点缓存绑定到一个设备数据流
		g_pDevice->SetFVF(Vertex::FVF);											//顶点缓存的使用4:定制灵活顶点格式
		g_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_FLAT);				//顶点缓存的使用5:设置着色模式
		g_pDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD);//D3D默认设置为该值
		g_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);						//顶点缓存的使用6:
		g_pDevice->EndScene();
	}
	hr = g_pDevice->Present(nullptr, nullptr, NULL, nullptr);
}


运行结果:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值