用DX11绘画底面为五角星的棱锥以及鼠标键盘对该棱锥控制的实现过程

用DX11绘画底面为五角星的棱锥以及鼠标键盘对该棱锥控制的实现过程

一.五角星棱锥的实现:

1.原理实现:通过LINELIST的图元类型将五角星的十个顶点连接起来,再取五角星的五个点与上方的顶点连接起来

图元类型: D3D11_PRIMITIVE_TOPOLOGY_LINELIST

  • 1618406390463.png

2.代码改动:

1)设置好顶点的位置,十个顶点的在二维直角坐标系下的坐标如下

  • 1618406459939.png

用代码设置好顶点的位置

	VertexPosColor vertices[] =
	{
	{ XMFLOAT3(0.0f, 1.0f, 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(0.0f,-(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)), -0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(cos(18.0 / 180.0 * XM_PI), sin(18.0 / 180.0 * XM_PI), 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(-(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * cos(18.0 / 180.0 * XM_PI), -(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * sin(18.0 / 180.0 * XM_PI), 0.0f),XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(cos(54.0 / 180.0 * XM_PI), -sin(54.0 / 180.0 * XM_PI), 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{XMFLOAT3(-(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * cos(54.0 / 180.0 * XM_PI),-(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * -sin(54.0 / 180.0 * XM_PI), 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(-cos(54.0 / 180.0 * XM_PI), -sin(54.0 / 180.0 * XM_PI), 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(-(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * -cos(54.0 / 180.0 * XM_PI),-(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * -sin(54.0 / 180.0 * XM_PI), 0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(-cos(18.0 / 180.0 * XM_PI), sin(18.0 / 180.0 * XM_PI), 0.0f),XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(-(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * -cos(18.0 / 180.0 * XM_PI), -(1 + tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) / (3 - tan(18.0 / 180.0 * XM_PI) * tan(18.0 / 180.0 * XM_PI)) * sin(18.0 / 180.0 * XM_PI),0.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
	{ XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },	
	};

2)设置好顶点的连接顺序,通过索引数组指定连接顺序

	DWORD indices[] = {
	//画出五角星的底面
	0,7,7,
	2,2,9,
	9,4,4,
	1,1,6,
	6,3,3,
	8,8,5,
	5,0,
	//连接顶点
	0,10,10,8,
	8,10,10,6,
	6,10,10,4,
	4,10,10,2,
	2,10,10,0,	
	};

3)修改打印顶点的个数

// 绘制立方体
	m_pd3dImmediateContext->DrawIndexed(40, 0, 0);//修改为40个

4)效果图

  • 1618407307537.png

1618407290255.png

二.实现鼠标和键盘对该锥体的控制

1)代码改动如下:

d3dApp.h

#include "Mouse.h"   //加入两行头文件
#include "Keyboard.h"

//在protected中加入对鼠标键盘以及鼠标键盘状态追踪器
protected:

	HINSTANCE m_hAppInst;        // 应用实例句柄
	HWND      m_hMainWnd;        // 主窗口句柄
	bool      m_AppPaused;       // 应用是否暂停
	bool      m_Minimized;       // 应用是否最小化
	bool      m_Maximized;       // 应用是否最大化
	bool      m_Resizing;        // 窗口大小是否变化
	bool	  m_Enable4xMsaa;	 // 是否开启4倍多重采样
	UINT      m_4xMsaaQuality;   // MSAA支持的质量等级


	GameTimer m_Timer;           // 计时器

	// 使用模板别名(C++11)简化类型名
	template <class T>
	using ComPtr = Microsoft::WRL::ComPtr<T>;
	// Direct3D 11
	ComPtr<ID3D11Device>           m_pd3dDevice;                         // D3D11设备
	ComPtr<ID3D11DeviceContext>    m_pd3dImmediateContext;               // D3D11设备上下文
	ComPtr<IDXGISwapChain>         m_pSwapChain;                         // D3D11交换链
	// Direct3D 11.1
	ComPtr<ID3D11Device1>          m_pd3dDevice1;                        // D3D11.1设备
	ComPtr<ID3D11DeviceContext1>   m_pd3dImmediateContext1;              // D3D11.1设备上下文
	ComPtr<IDXGISwapChain1>        m_pSwapChain1;                        // D3D11.1交换链
	// 常用资源
	ComPtr<ID3D11Texture2D>        m_pDepthStencilBuffer;                // 深度模板缓冲区
	ComPtr<ID3D11RenderTargetView> m_pRenderTargetView;                  // 渲染目标视图
	ComPtr<ID3D11DepthStencilView> m_pDepthStencilView;                  // 深度模板视图
	D3D11_VIEWPORT                 m_ScreenViewport;                     // 视口

	std::unique_ptr<DirectX::Mouse> m_pMouse;						// 鼠标
	DirectX::Mouse::ButtonStateTracker m_MouseTracker;				// 鼠标状态追踪器
	std::unique_ptr<DirectX::Keyboard> m_pKeyboard;					// 键盘
	DirectX::Keyboard::KeyboardStateTracker m_KeyboardTracker;
	// 派生类应该在构造函数设置好这些自定义的初始参数
	std::wstring m_MainWndCaption;                       // 主窗口标题
	int m_ClientWidth;                                   // 视口宽度
	int m_ClientHeight;                                  // 视口高度
};








GameApp.cpp

bool GameApp::Init()
{
	

	if (!D3DApp::Init())
		return false;

	if (!InitEffect())
		return false;

	if (!InitResource())
		return false;
	// 初始化鼠标,键盘不需要
	
	m_pMouse->SetWindow(m_hMainWnd);
	m_pMouse->SetMode(DirectX::Mouse::MODE_ABSOLUTE);
	return true;
}
void GameApp::UpdateScene(float dt)
{
	static float cubePhi = 0.0f, cubeTheta = 0.0f;

	// 获取鼠标状态
	Mouse::State mouseState = m_pMouse->GetState();
	Mouse::State lastMouseState = m_MouseTracker.GetLastState();
	// 获取键盘状态
	Keyboard::State keyState = m_pKeyboard->GetState();
	Keyboard::State lastKeyState = m_KeyboardTracker.GetLastState();

	// 更新鼠标按钮状态跟踪器,仅当鼠标按住的情况下才进行移动
	m_MouseTracker.Update(mouseState);
	m_KeyboardTracker.Update(keyState);
	if (mouseState.leftButton == true && m_MouseTracker.leftButton == m_MouseTracker.HELD)
	{
		cubeTheta -= (mouseState.x - lastMouseState.x) * 0.01f;
		cubePhi -= (mouseState.y - lastMouseState.y) * 0.01f;
	}
	if (keyState.IsKeyDown(Keyboard::W))
		cubePhi += dt * 2;
	if (keyState.IsKeyDown(Keyboard::S))
		cubePhi -= dt * 2;
	if (keyState.IsKeyDown(Keyboard::A))
		cubeTheta += dt * 2;
	if (keyState.IsKeyDown(Keyboard::D))
		cubeTheta -= dt * 2;


	m_CBuffer.world = XMMatrixTranspose(XMMatrixRotationY(cubeTheta) * XMMatrixRotationX(cubePhi));
	// 更新常量缓冲区,让立方体转起来
	D3D11_MAPPED_SUBRESOURCE mappedData;
	HR(m_pd3dImmediateContext->Map(m_pConstantBuffer.Get(), 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedData));
	memcpy_s(mappedData.pData, sizeof(m_CBuffer), &m_CBuffer, sizeof(m_CBuffer));
	m_pd3dImmediateContext->Unmap(m_pConstantBuffer.Get(), 0);
}

void GameApp::DrawScene()
{
	assert(m_pd3dImmediateContext);
	assert(m_pSwapChain);

	static float black[4] = { 0.0f, 0.0f, 0.0f, 1.0f };	// RGBA = (0,0,0,255)
	m_pd3dImmediateContext->ClearRenderTargetView(m_pRenderTargetView.Get(), reinterpret_cast<const float*>(&black));
	m_pd3dImmediateContext->ClearDepthStencilView(m_pDepthStencilView.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

	// 绘制立方体
	m_pd3dImmediateContext->DrawIndexed40, 0, 0);
	HR(m_pSwapChain->Present(0, 0));
}

d3dApp.h

LRESULT D3DApp::MsgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	
	switch (msg)
	{
		// 省略原有的部分...

		// 监测这些键盘/鼠标事件
	case WM_INPUT:

	case WM_LBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_RBUTTONDOWN:
	case WM_XBUTTONDOWN:

	case WM_LBUTTONUP:
	case WM_MBUTTONUP:
	case WM_RBUTTONUP:
	case WM_XBUTTONUP:

	case WM_MOUSEWHEEL:
	case WM_MOUSEHOVER:
	case WM_MOUSEMOVE:
		m_pMouse->ProcessMessage(msg, wParam, lParam);
		return 0;

	case WM_KEYDOWN:
	case WM_SYSKEYDOWN:
	case WM_KEYUP:
	case WM_SYSKEYUP:
		m_pKeyboard->ProcessMessage(msg, wParam, lParam);
		return 0;

	case WM_ACTIVATEAPP:
		m_pMouse->ProcessMessage(msg, wParam, lParam);
		m_pKeyboard->ProcessMessage(msg, wParam, lParam);
		return 0;
	}

	return DefWindowProc(hwnd, msg, wParam, lParam);
}
  1. 效果图如下
  • Video_20210414_100005_456.gif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值