acmilan作者
10年4个月前修改于 10年2个月前IP:四川
824513
2楼

让三角形旋转起来

除Render调用SetupMatrices设置三个基本变换矩阵外,注意几个细节改变:

  1. CUSTOMVERTEX删除了rhw元素,这样变成了未变换的x,y,z和颜色
  2. D3DFVF_CUSTOMVERTEX中D3DFVF_XYZRHW变为D3DFVF_XYZ
  3. InitVB中三角形的坐标数据作了调整
  4. InitD3D中pD3DDevice->SetRenderState设置剔出模式为NONE,这样可以看到三角形背面
  5. InitD3D中pD3DDevice->SetRenderState关闭光照系统,这样可以显示出本身的颜色

d3d_b.png

///////////////////////////////////////

LPDIRECT3D9 pD3D = NULL;
LPDIRECT3DDEVICE9 pD3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 pVB = NULL; // 顶点缓冲区实例

// 自定义顶点结构体
struct CUSTOMVERTEX
{
	FLOAT x, y, z; // 未变换的x,y,z
	DWORD color; // 颜色
};

// 自定义顶点格式
// 未变换顶点+面反射色
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)

///////////////////////////////////////

// 初始化顶点缓冲区(被InitD3D调用)
HRESULT InitVB()
{
	HRESULT hr = S_OK;

	// 三角形(未变换)
	CUSTOMVERTEX vertices[] = {
		{ -1.0f, -1.0f, 0.0f, 0xffff0000 },
		{ 1.0f, -1.0f, 0.0f, 0xff00ff00 },
		{ 0.0f, 1.0f, 0.0f, 0xff00ffff },
	};

	// 创建顶点缓冲区
	hr = pD3DDevice->CreateVertexBuffer(
		sizeof vertices, // 大小
		0, // 怎样使用缓存的额外信息
		D3DFVF_CUSTOMVERTEX, // 自定义顶点格式
		D3DPOOL_DEFAULT, // 顶点缓冲存储方式
		&pVB, // 返回顶点缓存实例
		NULL); // 保留
	if (FAILED(hr)) goto ret;

	// 锁定并获取缓冲区指针
	void *pVertices = NULL;
	hr = pVB->Lock(0, sizeof vertices, &pVertices, 0);
	if (FAILED(hr)) goto ret;

	// 将顶点数据复制到缓冲区
	memcpy(pVertices, vertices, sizeof vertices);

	// 释放锁定
	hr = pVB->Unlock();
	if (FAILED(hr)) goto ret;

ret:
	return hr;
}

// 初始化Direct3D
HRESULT InitD3D(HWND hwnd)
{
	HRESULT hr = S_OK;

	// 创建Direct3D 9根接口
	pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (pD3D == NULL)
	{
		hr = E_FAIL;
		goto ret;
	}

	// 配置Direct3D 9设备
	D3DPRESENT_PARAMETERS d3dpp;
	RtlZeroMemory(&d3dpp, sizeof d3dpp);
	d3dpp.Windowed = TRUE; // 窗口化
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // 交换缓冲加载后被删除
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; // 显示模式

	// 创建Direct3D 9设备接口
	hr = pD3D->CreateDevice(
		D3DADAPTER_DEFAULT, // 默认适配器
		D3DDEVTYPE_HAL, // 硬件驱动
		hwnd, // 窗体
		D3DCREATE_SOFTWARE_VERTEXPROCESSING, // 顶点像素渲染方式
		&d3dpp, // 参数
		&pD3DDevice); // 返回的设备接口
	if (FAILED(hr)) goto ret;

	// 设置剔除模式为NONE,这样可以看到三角形背面
	pD3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
	// 关闭光照系统,这样可以显示出本身的颜色
	pD3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);

	// 初始化顶点缓冲区
	hr = InitVB();
	if (FAILED(hr)) goto ret;

ret:
	return hr;
}

#include <d3dx9.h>
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "winmm.lib") // timeGetTime

// 设置世界、观察、投影变换矩阵
void SetupMatrices()
{
	HRESULT hr;

	// 设定世界变换矩阵为沿Y轴不停旋转
	D3DXMATRIXA16 matWorld;
	UINT iTime = timeGetTime() % 1000;
	FLOAT fAngle = iTime * (2.0f * D3DX_PI) / 1000.0f;
	D3DXMatrixRotationY(&matWorld, fAngle);
	hr = pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);

	// 设定观察变换矩阵
	D3DXMATRIXA16 matView;
	D3DXVECTOR3 vEyePt(0.0f, 3.0f, -5.0f); // 眼睛的位置
	D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f); //观察的位置
	D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f); //向上的方向
	D3DXMatrixLookAtLH(&matView, &vEyePt, &vLookatPt, &vUpVec);
	hr = pD3DDevice->SetTransform(D3DTS_VIEW, &matView);

	// 设定投影变换矩阵
	D3DXMATRIXA16 matProj;
	// 距离缩小比例、屏幕纵横比、最近剪切平面、最远剪切平面
	D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f);
	hr = pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}

// 绘制图形
void Render()
{
	HRESULT hr = S_OK;

	if (pD3DDevice == NULL)
		goto ret;

	// 清空缓存
	hr = pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET,
		D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);

	// 开始绘制场景
	hr = pD3DDevice->BeginScene();
	if (FAILED(hr)) goto present;

	// 设置变换矩阵
	SetupMatrices();

	// 绘制三角形
	// 设置数据流0为pVB
	hr = pD3DDevice->SetStreamSource(0, pVB, 0, sizeof(CUSTOMVERTEX));
	// 设置顶点格式
	hr = pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
	// 按三角形列表绘制数据流0
	hr = pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);

	// 结束绘制场景
	hr = pD3DDevice->EndScene();

present:
	// 显示缓存内容
	hr = pD3DDevice->Present(NULL, NULL, NULL, NULL);

ret:
	return;
}

// 清理Direct3D
void CleanupD3D()
{
	safe_release(&pVB);
	safe_release(&pD3DDevice);
	safe_release(&pD3D);
}

///////////////////////////////////////
</d3dx9.h>
评论
文号 / 824513

千古风流
名片发私信
学术分 4
总主题 466 帖总回复 2942 楼拥有证书:进士 学者 笔友
注册于 2009/05/30 21:22:42最后登录 2019/01/31 17:16:38
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:0

个人简介

暂未填写
笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的