索引缓存

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

#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;
IDirect3DIndexBuffer9 * g_pIndexBuffer = 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_XYZRHW | D3DFVF_DIFFUSE;


//定义圆的相关参数
int g_numTriangle = 8;					//组成圆的三角形个数
int g_numVertex = g_numTriangle + 1;	//顶点个数
int g_radius = 200;						//圆半径
int g_offsetX = g_cxWindow / 2;			//圆心x坐标
int g_offsetY = g_cyWindow / 2;			//圆心y坐标


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;
	//创建顶点缓存
	hr = g_pDevice->CreateVertexBuffer(sizeof(Vertex)* g_numVertex,
									   D3DUSAGE_DYNAMIC,
									   Vertex::FVF,
									   D3DPOOL_DEFAULT,
									   &g_pVertexBuffer,
									   NULL);
	if (FAILED(hr))
	{
		MessageBox(NULL, _T("创建顶点缓存失败!"), NULL, MB_OK);
		return false;
	}
	//初始化顶点数据
	Vertex * pVertexs = nullptr;
	g_pVertexBuffer->Lock(0, 0, (void**)&pVertexs, 0);
	pVertexs[0] = Vertex(g_offsetX, g_offsetY, 1.f, 1.f, D3DCOLOR_XRGB(0, 255, 0));;		//设置圆心
	for (int i = 0; i < g_numVertex - 1; ++i)
	{
		int x, y;
		//注意角度的增大方向为逆时针,屏幕坐标轴的方向、圆的坐标轴方向
		x = g_offsetX + cos(1.f * i / (g_numVertex - 1) * (2 * D3DX_PI)) * g_radius;	//顶点x坐标
		y = g_offsetY + sin(1.f * i / (g_numVertex - 1) * (2 * D3DX_PI)) * g_radius;	//顶点y坐标 ,这里是加上圆的y坐标对其对称变换
		pVertexs[i + 1] = Vertex(x, y, 1.f, 1.f, D3DCOLOR_XRGB(i * 10 + 100, 0, 0));
	}
	g_pVertexBuffer->Unlock();

	//创建索引缓存
	hr = g_pDevice->CreateIndexBuffer(sizeof(WORD)* g_numTriangle * 3,
									  D3DUSAGE_DYNAMIC,
									  D3DFMT_INDEX16,
									  D3DPOOL_DEFAULT,
									  &g_pIndexBuffer,
									  NULL);
	if (FAILED(hr))
	{
		MessageBox(NULL, _T("创建索引缓存失败!"), NULL, MB_OK);
		return false;
	}
	//初始化索引数据
	WORD *pIndex;
	g_pIndexBuffer->Lock(0, 0, (void**)&pIndex, 0);
	*pIndex = 0;					//设置第一个三角形的索引
	*(pIndex + 1) = 1;				//注意设置的顺序
	*(pIndex + 2) = 2;

	int i;
	for (i = 1; i < g_numTriangle; ++i)
	{
		*(pIndex + i * 3) = 0;
		*(pIndex + i * 3 + 1) = *(pIndex + (i - 1) * 3 + 2);
		*(pIndex + i * 3 + 2) = *(pIndex + i * 3 + 1) + 1;
	}
	*(pIndex + --i * 3 + 2) = 1;		//设置最后一个索引
	g_pIndexBuffer->Unlock();
	return true;
}

void Cleanup()
{
	if (g_pDevice){ g_pDevice->Release(); g_pDevice = nullptr; }
	if (g_pD3d){ g_pD3d->Release(); g_pD3d = nullptr; }
}

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))
	{
		//......render
		g_pDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(Vertex));
		g_pDevice->SetFVF(Vertex::FVF);
		g_pDevice->SetIndices(g_pIndexBuffer);					//为顶点缓存设置对应的索引数据
		g_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,g_numVertex, 0,g_numTriangle);	//基于索引去绘制图元
		g_pDevice->EndScene();
	}

	hr = g_pDevice->Present(nullptr, nullptr, NULL, nullptr);
}


运行结果:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值