惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园_首页
Security Archives - TechRepublic
Security Archives - TechRepublic
Application and Cybersecurity Blog
Application and Cybersecurity Blog
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
S
Security @ Cisco Blogs
S
Security Affairs
D
Darknet – Hacking Tools, Hacker News & Cyber Security
L
Lohrmann on Cybersecurity
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Hacker News: Ask HN
Hacker News: Ask HN
Forbes - Security
Forbes - Security
H
Heimdal Security Blog
A
Arctic Wolf
NISL@THU
NISL@THU
P
Proofpoint News Feed
W
WeLiveSecurity
S
Schneier on Security
AI
AI
Schneier on Security
Schneier on Security
N
News and Events Feed by Topic
L
LINUX DO - 最新话题
Cisco Talos Blog
Cisco Talos Blog
AWS News Blog
AWS News Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
Know Your Adversary
Know Your Adversary
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
Cyberwarzone
Cyberwarzone
I
Intezer
S
Securelist
Help Net Security
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
小众软件
小众软件
Last Week in AI
Last Week in AI
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
WordPress大学
WordPress大学
罗磊的独立博客
月光博客
月光博客
雷峰网
雷峰网
A
About on SuperTechFans
The GitHub Blog
The GitHub Blog
T
The Blog of Author Tim Ferriss
MongoDB | Blog
MongoDB | Blog
大猫的无限游戏
大猫的无限游戏
博客园 - 司徒正美
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events

博客园 - 邗影

关于音频PA结构腔体 球面渲染 关于linux和shi脚本常用的通配符 关于fread读不满一块和读不满count的返回值 如何去掉merge UBI的覆盖写和擦除 DTSI 多个模块共用同一个 GPIO 引脚冲突 问题汇总 debug比release程序启动的快 关于CPU占用优先级的调整 关于蜂鸣器发声 麦序与声源定位 关于squashfs压缩挂载 软连接生成 线程退出未定义行为 linux文件查找 C语言弱函数 数据传输报错port unreachable 关于延迟测试 v4l2检测 关于数据库的性能 流媒体小记包含一些面试问题 v4l2视频采集 流媒体ZLM配置vscode远程开发 关于SPS中的帧率问题 Linux编译问题 SSl冲突问题 D3D初始化窗口显示 关于线程池
D3D11绘制三角形
邗影 · 2025-08-20 · via 博客园 - 邗影
// D3Dtest.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//代码来自基于 DirectX11 的 3D 图形程序设计案例教程 重庆大学

#include "d3dinit.h"
#include <d3dCompiler.h>
#define D3DCOMPILE_STANDARD_FILE_INCLUDE ((ID3DInclude*)(UINT_PTR)1)
#define D3DCOMPILE_ENABLE_STRICTNESS 0x1



ID3D11Device* device = NULL;                    //D3D11设备指针
IDXGISwapChain* swapChain = NULL;               //交换链指针
ID3D11DeviceContext* immediateContext = NULL;   //设备上下文指针
ID3D11RenderTargetView* renderTargetView = NULL;//渲染目标视图指针  
//定点和像素(片源着色)器
ID3D11VertexShader* v_shader;
ID3D11PixelShader*  p_shader;

struct st_Vertex {
	XMFLOAT3 Pos;//顶点结构体
};
//着色器处理
bool SetUp()
{
	// 第一步, 创建顶点着色器
   // 定义一个着色器编译标识符
   // D3DCOMPILE_ENABLE_STRICTINESS 表示强制严格编译
	const D3D_SHADER_MACRO defines[] = { NULL };
	ID3DBlob* pVSBlob = nullptr;
	ID3DBlob* errorBlob = nullptr;

	if (FAILED(D3DCompileFromFile(
		L"VertexShader.hlsl",      // 着色器文件路径
		defines,               // 宏定义数组(原D3DX11版本未使用)
		D3DCOMPILE_STANDARD_FILE_INCLUDE,  // 自动处理include文件
		"VSMain",             // 着色器入口函数
		"vs_5_0",             // 着色器目标版本
		D3DCOMPILE_ENABLE_STRICTNESS,         // 编译标志(保留原有逻辑)
		0,                    // 次级标志(Effect编译相关)
		&pVSBlob,             // 输出字节码
		&errorBlob))          // 错误信息
		)
	{
		// 如果编译失败, 弹出一个消息框
		MessageBox(NULL, L"Fail to compile vertex shader", L"ERROR", MB_OK);

		return S_FALSE;
	}
	// 用 CreateVertexShader 创建顶点着色器
	device->CreateVertexShader(
		pVSBlob->GetBufferPointer(),  // 指向 pVSBlob 所在内存块的起始地址
		pVSBlob->GetBufferSize(),     // 取得 pVSBlob 的大小
		NULL,                         // 指向 ID3D11ClassLinkage 的指针, 一般为空
		&v_shader);               // 将创建好的顶点着色器存放到 vertexShader 中

	// 第二步, 创建像素着色器
	// 声明一个 ID3DBlob 对象来存放编译后的像素着色器
	ID3DBlob* pPSBlob = NULL;
	if (FAILED(D3DCompileFromFile(
		L"VertexShader.hlsl",      // 着色器文件路径
		defines,               // 宏定义数组(原D3DX11版本未使用)
		D3DCOMPILE_STANDARD_FILE_INCLUDE,  // 自动处理include文件
		"PSMain",             // 着色器入口函数
		"ps_5_0",             // 着色器目标版本
		D3DCOMPILE_ENABLE_STRICTNESS,         // 编译标志(保留原有逻辑)
		0,                    // 次级标志(Effect编译相关)
		&pPSBlob,             // 输出字节码
		&errorBlob))          // 错误信息
		)
	{
		// 如果编译失败, 弹出一个消息框
		MessageBox(NULL, L"Fail to compile vertex shader", L"ERROR", MB_OK);

		return S_FALSE;
	}
	// 用 CreatePixelShader 创建像素着色器
	device->CreatePixelShader(
		pPSBlob->GetBufferPointer(),  // 指向 pPSBlob 所在内存块的起始地址
		pPSBlob->GetBufferSize(),     // 取得 pPSBlob 的大小
		NULL,                         // 指向 ID3D11ClassLinkage 的指针, 一般为空
		&p_shader);                  // 将创建好的像素着色器存放到 pixelShader 中

	

	// 第三步, 创建并设置输入布局
	// 所谓输入布局, 就是制定顶点结构所包含信息的实际意义
	// D3D11_INPUT_ELEMENT_DESC 用于描述顶点结构的意义
	// 以便让显卡识别所定义的顶点结构
	// 这里定义一个 D3D11_INPUT_ELEMENT_DESC 数组,
	// 由于定义的顶点结构只有位置坐标, 所有这个数组里也只有一个元素
	D3D11_INPUT_ELEMENT_DESC layout[] =
	{
		{
			"POSITION",  // 语义标识符, 必须和 hlsl 文件中 VSMain 所用的标识符一致
			0,           // 表示第 1 个元素, 注意和数组一样都是从 0 开始计数,
			DXGI_FORMAT_R32G32B32_FLOAT,  // 96 位浮点像素, 红绿蓝各 32 位
			0,           // 可以取值 0 - 15, 0 表示绑定顶点缓存到第一个输入槽
			0,           // 可选项, 定义了缓存的对齐方式,
			D3D11_INPUT_PER_VERTEX_DATA,     // 定义输入数据类型为顶点数据
			0            // 本例没有使用实例技术, 所以这里为 0
		}
	};

	// 获取输入布局中元素个数
	UINT numElements = ARRAYSIZE(layout);

	// 声明一个输入布局对象 pVertexLayout 用于存放创建好的布局
	ID3D11InputLayout* pVertexLayout;

	// 调用 CreateInputLayout 创建输入布局
	device->CreateInputLayout(
		layout,                     // 上面定义的 D3D11_INPUT_ELEMENT_DESC 数组
		numElements,                // D3D11_INPUT_ElEMENT_DESC 数组的元素个数
		pVSBlob->GetBufferPointer(),  // 指向顶点着色器起始位置的指针
		pVSBlob->GetBufferSize(),     // 指向顶点着色器的所在内存大小
		&pVertexLayout);            // 返回生成的输入布局对象

	// 设置生成的输入布局
	immediateContext->IASetInputLayout(pVertexLayout);

	// 第四步, 创建顶点缓存
	// 用我们自己定义的 Vertex 结构创建三角形的三个顶点坐标
	st_Vertex  vertices[] =
	{
	  XMFLOAT3(0.0f, 0.5f, 0.0f),
	  XMFLOAT3(0.5f, 0.0f, 0.0f),
	  XMFLOAT3(-0.5f, -0.5f, 0.0f),
	  XMFLOAT3(0.5f, 0.5f, 0.0f)
	};

	// 填充 D3D11_BUFFER_DESC 结构, 这个结构是用来描述顶点缓存的属性
	// 首先声明一个 D3D11_BUFFER_DESC 的对象 bd
	D3D11_BUFFER_DESC bd;
	ZeroMemory(&bd, sizeof(bd));                   // 进行清零操作
	bd.Usage = D3D11_USAGE_DEFAULT;       // 设置缓存的读写方式, 一般用默认方式
	bd.ByteWidth = sizeof(st_Vertex) * 3;        // 设置缓存区域的大小,
	// 由于有三个顶点所以要乘以 3
	bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;  // 将这个缓存区域绑定到顶点缓存
	bd.CPUAccessFlags = 0;                         // CPU 访问标识符, 0 表示没有 CPU 访问
	bd.MiscFlags = 0;                         // 其他项标识符, 0 表示不使用该项

	// 声明一个数据用于初始化子资源
	D3D11_SUBRESOURCE_DATA initData;
	ZeroMemory(&initData, sizeof(initData));       // 进行清零操作
	initData.pSysMem = vertices;                  // 设置需要初始化的数据, 即顶点数组

	// 声明一个 ID3D11Buffer 对象作为顶点缓存
	ID3D11Buffer* vertexBuffer;

	// 调用 CreateBuffer 创建顶点
	device->CreateBuffer(&bd, &initData, &vertexBuffer);
	UINT stride = sizeof(st_Vertex);     // 获取 Vertex 的大小作为跨度
	UINT offset = 0;                  // 设置偏移量为 0

	// 设置顶点缓存
	immediateContext->IASetVertexBuffers(
		0,              // 绑定到第一个输入槽
		1,              // 顶点缓存的个数, 这里为一个
		&vertexBuffer,  // 创建好的顶点缓存
		&stride,        // 跨度, 即顶点结构的大小
		&offset);       // 缓存第一个元素到所用元素的偏移量

	// 指定图元类型, D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST 表示图元为三角形
	immediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	return true;
}

void Cleanup()
{
	//释放指针
	if (renderTargetView) renderTargetView->Release();
	if (immediateContext) immediateContext->Release();
	if (swapChain)        swapChain->Release();
	if (device)           device->Release();
	if (v_shader)    v_shader->Release();
	if (p_shader)     p_shader->Release();
}
LRESULT CALLBACK d3d::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    //处理窗口消息
	switch (msg)
	{
	case WM_DESTROY:
		::PostQuitMessage(0);
		break;

	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)
			::DestroyWindow(hwnd);
		break;
	}
	return ::DefWindowProc(hwnd, msg, wParam, lParam);

}

bool Display(float timeDelta)
{
	if (device)
	{
		// 声明一个数组存放颜色信息, 4 个元素分别表示红, 绿, 蓝以及 alpha
		float ClearColor[4] = { 0.0f, 0.125f, 0.3f, 1.0f };

		// 清除渲染目标视图
		immediateContext->ClearRenderTargetView(renderTargetView,
			ClearColor);

		// 把创建好的顶点着色器和像素着色器绑定到 immediateContext
		immediateContext->VSSetShader(v_shader, NULL, 0);
		immediateContext->PSSetShader(p_shader, NULL, 0);

		// 绘制三角形, 第一个参数表示绘制 3 个点
		// 第二个参数表示从第 0 个点开始绘制
		immediateContext->Draw(3, 0);

		swapChain->Present(0, 0);
	}

	return true;

}
int WINAPI WinMain(HINSTANCE hinstance,
	HINSTANCE prevInstance,
	PSTR cmdLine,
	int showCmd)
{
	//初始化
	//**注意**:最上面声明的4个指针,在这里作为参数传给InitD3D函数
	if (!d3d::initD3D(hinstance,
		800,
		600,
		&renderTargetView,
		&immediateContext,
		&swapChain,
		&device))
	{
		::MessageBox(0, L"InitD3D() - FAILED", 0, 0);
		return 0;
	}

	if (!SetUp())
	{
		::MessageBox(0, L"Setup() - FAILED", 0, 0);

		return 0;
	}

	//执行消息循环,将函数Display的指针作为参数传递
	d3d::EnterMsgLoop(Display);

	Cleanup();

	return 0;

}
代码来源
/*
************************************************************************ > File Name: Triangle.hlsl > Author: YLD10 《基于 DirectX11 的 3D 图形程序设计案例教程》 5.2 节程序例子 绘制一个三角形 ************************************************************************/ /* * 顶点着色器 (Vertex Shader) * float4 为 HLSL 提供的关键字, 表示一个 4 维向量, 每个分量是一个浮点数 * VSMain 为顶点着色器的主函数名, 名字可以任意取 * POSITION 为语义表示符, 在创建输入布局时会用到 * SV_POSITION 为 HLSL 标识符, 表示该函数返回的是一个坐标 * 注意这种函数的声明方法有别于 C/C++, 具体意义如下 * 返回类型 参数类型 参数语义 返回值语义 * ↓ ↓ ↓ ↓ * float4 VSMain(float4 Pos : POSITION) : SV_POSITION */ float4 VSMain(float4 Pos : POSITION) : SV_POSITION { return Pos; } /* * 像素着色器(Pixel Shader) * PSMain 为像素着色器的主函数名, 名字可以任意取 * SV_TARGET 为 HLSL 标识符, 表示该函数返回的是一个颜色 */ float4 PSMain(float4 Pos : POSITION) : SV_TARGET { // 返回一个 4 维向量, 分别表示红绿蓝和 alpha, 这里表示三角形是红色的 return float4(1.0f, 1.0f, 0.0f, 1.0f); }