DirectX11 顶点和顶点布局

2023-11-02

顶点和顶点布局
1. 如何描述顶点?
5.5.1节已经讲过,在Direct3D中,顶点由空间位置和各种附加属性组成,Direct3D可以让我们灵活地建立属于我们自己的顶点格式;换句话说,它允许我们定义顶点的分量。要创建一个自定义的顶点格式,我们必须先创建一个包含顶点数据的结构体。例如,下面是两种不同类型的顶点格式;一个由位置和颜色组成,另一个由位置、法线和纹理坐标组成。

struct Vertex1
{
    XMFLOAT3 Pos;
    XMFLOAT4 Color;
};
struct Vertex2
{
    XMFLOAT3 Pos;
    XMFLOAT3 Normal;
    XMFLOAT2 Tex0;
    XMFLOAT2 Tex1;
};

2. 顶点布局的作用是什么?
在定义了顶点结构体之后,我们必须设法描述该顶点结构体的分量结构,使Direct3D知道该如何使用每个分量。这一描述信息是以输入布局(ID3D11InputLayout)的形式提供给Direct3D的。

2. 顶点布局如何创建?
输入布局是一个D3D11_INPUT_ELEMENT_DESC数组。D3D11_INPUT_ELEMENT_DESC数组中的每个元素描述了顶点结构体的一个分量。比如,当顶点结构体包含两个分量时,对应的D3D11_INPUT_ELEMENT_DESC数组会包含两个元素。我们将D3D11_INPUT_ELEMENT_DESC称为输入布局描述(input layout description)。D3D11_INPUT_ELEMENT_DESC结构体定义如下:

typedef struct D3D11_INPUT_ELEMENT_DESC {
    LPCSTR SemanticName;
    UINT SemanticIndex;
    DXGI_FORMAT Format;
    UINT InputSlot;
    UINT AlignedByteOffset
    D3D11_INPUT_CLASSIFICATION InputSlotClass;
    UINT InstanceDataStepRate;
} D3D11_INPUT_ELEMENT_DESC;

1.SemanticName:一个与元素相关的字符串。它可以是任何有效的语义名。语义(semantic)用于将顶点结构体中的元素映射为顶点着色器参数(参见图6.1)。
这里写图片描述
(图6.1 顶点结构体中的每个元素分别由D3D11_INPUT_ELEMENT_DESC数组中的对应元素描述。语义名和语义索引提供了一种将顶点元素映射为顶点着色器参数的方法。)

2.SemanticIndex:附加在语义上的索引值。图6.1说明了使用该索引的原因;举例来说,当顶点结构体包含多组纹理坐标时,我们不是添加一个新的语义名,而是在语义名的后面加上一个索引值。在着色器代码中没有指定索引的语义默认索引为0,例如,在图6.1中的POSITION相当于POSITION0。

3.Format:一个用于指定元素格式的DXGI_FORMAT枚举类型成员;下面是一些常用的格式:

DXGI_FORMAT_R32_FLOAT // 1D 32-bit float scalar
DXGI_FORMAT_R32G32_FLOAT // 2D 32-bit float vector
DXGI_FORMAT_R32G32B32_FLOAT // 3D 32-bit float vector
DXGI_FORMAT_R32G32B32A32_FLOAT // 4D 32-bit float vector
DXGI_FORMAT_R8_UINT // 1D 8-bit unsigned integer scalar
DXGI_FORMAT_R16G16_SINT // 2D 16-bit signed integer vector
DXGI_FORMAT_R32G32B32_UINT // 3D 32-bit unsigned integer vector
DXGI_FORMAT_R8G8B8A8_SINT // 4D 8-bit signed integer vector
DXGI_FORMAT_R8G8B8A8_UINT // 4D 8-bit unsigned integer vector

4.InputSlot:指定当前元素来自于哪个输入槽(input slot)。Direct3D支持16个输入槽(索引依次为 0到15),通过这些输入槽我们可以向着色器传入顶点数据。例如,当一个顶点由位置元素和颜色元素组成时,我们既可以使用一个输入槽传送两种元素,也可以将两种元素分开,使用第一个输入槽传送顶点元素,使用第二个输入槽传送颜色元素。Direct3D可以将来自于不同输入槽的元素重新组合为顶点。在本书中,我们只使用一个输入槽,但是在本章结尾的练习2中我们会引导读者做一个使用两个输入槽的练习。

5.AlignedByteOffset:对于单个输入槽来说,该参数表示从顶点结构体的起始位置到顶点元素的起始位置之间的字节偏移量。例如在下面的顶点结构体中,元素Pos的字节偏移量为0,因为它的起始位置与顶点结构体的起始位置相同;元素Normal的字节偏移量为12,因为必须跳过由Pos占用的字节才能到达Normal的起始位置;元素Tex0的字节偏移量为24,因为必须跳过由Pos和Normal占用的字节才能到达Tex0的起始位置;元素Tex1的字节偏移量为32,因为必须跳过由Pos,Normal和Tex0占用的字节才能到达Tex1的起始位置。

struct Vertex2
{
    XMFLOAT3 Pos;       // 0-byte offset
    XMFLOAT3 Normal;   // 12-byte offset
    XMFLOAT2 Tex0;      // 24-byte offset
    XMFLOAT2 Tex1;      // 32-byte offset
};

6.InputSlotClass:目前指定为D3D11_INPUT_PER_VERTEX_DATA;其他选项用于高级实例技术。

7.InstanceDataStepRate:目前指定为0;其他值只用于高级实例技术。

对于前面的两个示例顶点结构体Vertex1和Vertex2来说,对应的输入布局描述为:

D3D11_INPUT_ELEMENT_DESC desc1[]=
{
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
        D3D11_INPUT_PER_VERTEX_DATA, 0},
    {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12,
        D3D11_INPUT_PER_VERTEX_DATA, 0}
};

D3D11_INPUT_ELEMENT_DESC desc2[]=
{
    {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0,
        D3D11_INPUT_PER_VERTEX_DATA, 0},
    {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT,0, 12,
        D3D11_INPUT_PER_VERTEX_DATA, 0},
    {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 24,
        D3D11_INPUT_PER_VERTEX_DATA, 0}
    {"TEXCOORD", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 32,
        D3D11_INPUT_PER_VERTEX_DATA, 0}
};

指定了输入布局描述之后,我们就可以使用ID3D11Device::CreateInputLayout方法获取一个表示输入布局的ID3D11InputLayout接口的指针:

HRESULT ID3D11Device::CreateInputLayout(
    const D3D11_INPUT_ELEMENT_DESC *pInputElementDescs,
    UINT NumElements,
    const void *pShaderBytecodeWithInputSignature,
    SIZE_T BytecodeLength,
    ID3D11InputLayout **ppInputLayout);

1.pInputElementDescs:一个用于描述顶点结构体的D3D11_INPUT_ELEMENT_DESC数组。

2.NumElements:D3D11_INPUT_ELEMENT_DESC数组的元素数量。

3.pShaderBytecodeWithInputSignature:指向顶点着色器参数的字节码的指针。

4.BytecodeLength:顶点着色器参数的字节码长度,单位为字节。

5.ppInputLayout:返回创建后的ID3D11InputLayout指针。

我们需要进一步解释一下第3个参数的含义。本质上,顶点着色器以一组顶点元素作为它的输入参数——也就是所谓的输入签名(input signature)。自定义顶点结构体中的元素必须被映射为与它们对应的顶点着色器参数,图6.1解释了这一问题。通过在创建输入布局时传入顶点着色器签名,Direct3D在创建时就可以验证输入布局是否与输入签名匹配,并建立从顶点结构体到着色器参数之间的映射关系。一个ID3D11InputLayout对象可以在多个参数完全相同的着色器中重复使用。

假设有下列输入参数和顶点结构:

VertexOut VS(float3 Pos:POSITION, float4 Color:COLOR,
    float3 Normal: NORMAL){ }
struct Vertex
{
    XMFLOAT3  Pos ;
    XMFLOAT4  Color;
};

这样会产生错误,VC++的调试输出窗口会显示以下信息:

D3D11:ERROR:ID3D11Device::CreateInputLayout:The provided input
signature expects to read an element with SemanticName/Index:
‘NORMAL’/0, but the declaration doesn’t provide a matching name.

假如顶点结构和输入参数与输入元素匹配,但类型不同:

VertexOut VS(int3 Pos:POSITION, float4 Color:COLOR) { }
struct Vertex
{
XMFLOAT3 Pos;
XMFLOAT4 Color;
} ;

这样做是可行的,因为Direct3D允许输入寄存器中的字节被重新解释。但是,VC ++调试输出窗口会显示以下信息:

D3D11:WARNING:ID3D11Device::CreateInputLayout:The provided input
signature expects to read an element with SemanticName/Index:
‘POSITION’/0 and component(s) of the type ‘int32’. However,the
matching entry in the InputLayout declaration, element[0],
specifies mismatched format:’R32G32B32_FLOAT’.This is not an error,
since behavior is well defined :The element format determines what
data conversion algorithm gets applied before it shows up in a
shader register.Independently,the shader input signature defines
how the shader will interpret the data that has been placed in its
input registers,with no change in the bits stored.It is valid for
the application to reinterpret data as a different type once it is
in the vertex shader,so this warning is issued just in case reinte rpretation was not intended by the author.

下面的代码说明了该如何调用ID3D11Device::CreateInputLayout方法。注意,这些代码涉及了一些我们还未讨论的内容(比如ID3D11Effect)。本质上,一个effect可以封装一个或多个pass,而每个pass都会与一个顶点着色器相连。所以,我们可以从effect中得到有关pass的描述信息(D3D11_PASS_DESC),然后再从中得到顶点着色器的输入签名。

ID3D11Effect* mFX;
ID3D11EffectTechnique* mTech;
ID3D11InputLayout* mVertexLayout;
/* ...create the effect... */
mTech = mFX->GetTechniqueByName("Tech");
D3D11_PASS_DESC PassDesc;
mTech->GetPassByIndex(0)->GetDesc(&PassDesc);
HR(md3dDevice->CreateInputLayout(vertexDesc, 4,
    PassDesc.pIAInputSignature, PassDesc.IAInputSignatureSize,
    &mVertexLayout));

创建了输入布局对象之后,它不会自动绑定到设备上。我们必须调用下面的语句来实现绑定:

ID3D11InputLayout* mVertexLayout;
/* ...create the input layout... */
md3dImmediateContext->IASetInputLayout(mVertexLayout);

如果你打算用一个输入布局来绘制一些物体,然后再使用另一个的布局来绘制另一些物体,那你必须按照下面的形式来组织代码:

md3dImmediateContext->IASetInputLayout(mVertexLayout1);
/* ...draw objects using input layout 1... */
md3dImmediateContext->IASetInputLayout(mVertexLayout2);
/* ...draw objects using input layout 2... */

换句话说,当一个ID3D11InputLayout对象被绑定到设备上时,如果不去改变它,那么它会始终驻留在那里。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DirectX11 顶点和顶点布局 的相关文章

  • 基于FBX SDK的FBX模型解析与加载 -(一)

    1 简介 FBX是Autodesk的一个用于跨平台的免费三维数据交换的格式 最早不是由Autodesk开发 但后来被其收购 目前被 众多的标准建模软件所支持 在游戏开发领域也常用来作为各种建模工具的标准导出格式 Autodesk提供了基于C
  • 【DirectX11】第八篇 光照模型——漫反射

    本系列文章主要翻译和参考自 Real Time 3D Rendering with DirectX and HLSL 一书 感谢原书作者 同时会加上一点个人理解和拓展 文章中如有错误 欢迎指正 这里是书中的代码和资源 本文所有的环境和工具使
  • DirectX11 顶点和顶点布局

    顶点和顶点布局 1 如何描述顶点 5 5 1节已经讲过 在Direct3D中 顶点由空间位置和各种附加属性组成 Direct3D可以让我们灵活地建立属于我们自己的顶点格式 换句话说 它允许我们定义顶点的分量 要创建一个自定义的顶点格式 我们
  • ‘fxc‘ 不是内部或外部命令,也不是可运行的程序

    编译龙书的Demo出现这个问题 d3d11CodeSet Chapter 6 Drawing in Direct3D Box 1 添加到环境变量 fxc exe在C Program Files x86 Microsoft DirectX S
  • 摸爬滚打DirectX11_day01——VS2015与DirectX11的配置

    什么是DirectX11 DirectX 微软提供的应用程序接口集 APIs 被设计为在运行 windows 操作系统平台上用来提供给开发人员控制硬件的底层接口 它的各个组件提供了访问不同硬件的能力 包括图形 显卡 声音 声卡 GPU 输入
  • 深入探索透视投影变换(续)

    潘宏 2009 4 14 本人水平有限 疏忽错误在所难免 还请各位数学高手 编程高手不吝赐教 email popyy netease com B站专栏 https b23 tv oWsl6PD 在上一篇文章中我们讨论了透视投影变换的原理 分
  • DirectX 11 像素着色器 什么是 SV_POSITION?

    我正在学习 DirectX 11 的 HLSL 我想知道 SV POSITION 究竟是什么 它是顶点着色器的输出和像素着色器的输入 1 这是屏幕上每个像素的 x y z 还是物体的 x y z 2 为什么是4个32位浮点数 3 顶点输出需
  • Direct3D11:翻转 ID3D11Texture2D

    我执行 Direct3D 后台缓冲区的捕获 当我下载像素时 图像帧沿其垂直轴翻转 复制资源或创建目标时是否可以 告诉 D3D 翻转帧ID3D11Texture2D 我是这样做的 我将帧缓冲区复制到其中的纹理是这样创建的 D3D11 TEXT
  • Directx 11 前缓冲器

    我希望这是对一个我找不到答案的简单问题的简单答案 如何访问 Directx 11 DXGI 中的前端缓冲区 我发现在 Directx 9 中可以使用 GetFrontBufferData 在 Directx 11 中可以使用 GetBuff
  • 如何提高 Direct3D 流纹理性能?

    我正在尝试加速全屏纹理的绘制 该纹理会改变每一帧 在我的系统上 使用 GDI 和 BitBlt 可以获得大约 1000 FPS 但我认为可以通过使用 Direct3D 和动态纹理来提高性能 相反 我只能获得 250 FPS 左右 我在配备
  • 用 GDI 绘制 opengl/D3D 吗?

    我想知道是否可以使用 GDI 在 opengl direct3D 表面上进行绘制 如果是的话 该怎么做 我问的原因是因为我正在编写一个简单的应用程序来在游戏中绘制一些东西 这些东西都是 2D 或文本 例如帧速率信息 自定义十字准线 时钟等
  • 如何找出真实屏幕刷新率(不是四舍五入的数字)

    根据微软的这篇文章 http support microsoft com kb 2006076 en us用户设置的屏幕刷新率可以 并且大部分是 小数 用户设置为 59Hz 但屏幕按照屏幕显示 60Hz 运行 但实际上是 59 94Hz 我
  • 在 directx 11 中一次渲染到多个纹理

    我正在尝试使用 C directx 11 SDK 一次渲染到两个纹理 我希望一个纹理包含结果图像的每个像素的颜色 渲染 3D 场景时我通常在屏幕上看到的颜色 另一个纹理包含每个像素的法线和深度 3 个浮点表示法线 1 个浮点表示法线 为深度
  • 从计算着色器中的 RWTexture2D 加载

    据我所知 HLSL 着色器模型 5 0 存在一个限制 即无法从非标量类型的 RWTexture2D 资源加载数据 也就是说 以下行为是非法的 RWTexture2D
  • DirectX 11 叠加

    我正在为游戏编写 DirectX 11 覆盖 创建纹理非常简单 而且我对 C C 有很好的了解 我遇到的问题是在我的测试窗口中我可以打印纹理 但是一旦我改变相机角度 纹理就会随之移动 这就是大多数人想要的 我想知道的是如何以 2D 打印某些
  • Direct3D 10 是否有 COM 暴露

    先生们 尊敬的女士们 我在 Code Project 的 COM 论坛上发布了这个问题 并得到了一个傲慢的回复 希望对您有所帮助 我看到 Microsoft 有一个用于 Direct3D 9 的 COM 库 其 GUID 为 81BDCBC
  • WARP 驱动程序、参考驱动程序和软件驱动程序之间有什么区别?

    在 DirectX 11 中 有四种类型的驱动程序 D3D DRIVER TYPE HARDWARE D3D DRIVER TYPE REFERENCE D3D DRIVER TYPE SOFTWARE D3D DRIVER TYPE WA
  • 双倍的 Pow 实现

    我正在开发一个用于运动控制的代码 但我遇到了 pow 函数的问题 我使用VS2010作为IDE 这是我的问题 我有 double p 100 0000 double d 1000 0000 t1 pow p 8 0000 d 1 00 4
  • 如何使用 SharpDX Toolkit 绘制透明 3D 对象?

    我正在开发一个使用 SharpDX 和 SharpDX Toolkit 来绘制简单 3D 形状的应用程序 Geometrics Desktop 示例对于入门非常有帮助 现在我正在尝试使某些形状透明 并且为了简单起见 我只是尝试使该示例中的茶
  • 如何在使用 Cmake 构建期间编译 HLSL 着色器?

    我正在开发 d3d 应用程序 我想在使用 cmake 构建期间编译我的 hlsl 着色器 我不知道从哪里开始 这是我当前的 CMakeLists txt cmake minimum required VERSION 3 20 project

随机推荐

  • 【区块链介绍】区块链的来龙去脉

    1 了解区块链技术的起源 分布式系统 弱中心化是区块链思想的核心 P2P网络 为区块链提供了网络层基础架构 任何一个节点都能与其他节点进行传输 与其它节点保持一致 共识算法 区块链技术的核心 实现了数据的一致存储 密码学 为区块链数据的传输
  • 高数——彻底搞懂如何判断反常积分收敛和发散

    反常积分收敛和发散 预备知识 复杂的反常积分 真题 预备知识 1 极限 不定积分与定积分的基本计算 2 找等价无穷小 3 无穷小和无穷大速度的比较 趋向无穷大的速度 x x x x xx gt e
  • Celery介绍以及使用

    文章目录 celery 一 什么是celery 1 celery是什么 2 使用场景 3 Celery的优点 4 Celery的安装 二 Celery执行异步任务 1 创建异步任务执行文件 消费者 2 创建生产者文件 3 创建result文
  • InnoDB引擎架构

    逻辑存储结构 表空间 ibd文件 一个mysql实例可以对应多个表空间 用于存储记录 索引等数据 段 分为数据段 索引段 回滚段 InnoDB是索引组织表 数据段就是B 树的叶子节点 索引段即为B 树的非叶子节点 段用来管理多个Extent
  • Vue中vuex的使用(三)

    vuex中getters的使用 1 概念 当state中的数据需要经过加工后再使用时 可以使用getters加工 2 在store js中追加getters配置 准备getter 用于将state中sum加工 const getters b
  • vue如何获取当前页面的url

    如果你使用 vue router 文档在这里 路由信息对象的属性 const routes path portfolio year review component Portfolio 这个样子获取 this route params ye
  • 二十一.数据结构学习笔记.1

    一 抽象数据类型 抽象数据类型 Abstract Data Type ADT 是一些操作的集合 抽象数据类型是数学的抽象 在ADT定义中根本没涉及如何实现这些操作 例如 表 集合 图及它们的操作 它们都可以看作抽象数据类型 就像整数 实数和
  • cmake:if

    有条件地执行一组命令 概要 if
  • java笔记:抽象方法与抽象类

    抽象方法和抽象类 1 规则 抽象方法和抽象类必须用abstract进行修饰 有抽象方法的类只能被定义为抽象类 抽象类中可以没有抽象方法 抽象类不能被实例化 无法使用new调用抽象类的构造器创建抽象类的实例 无法创建实例 抽象类中可以包含成员
  • 网络安全渗透测试实验一

    1 实验目的和要求 理解网络扫描 网络侦察的作用 通过搭建网络渗透测试平台 了解并熟悉常用搜索引擎 扫描工具的应用 通过信息收集为下一步渗透工作打下基础 系统环境 Kali Linux 2 Windows 网络环境 交换网络结构 实验工具
  • pyqt5数据库使用教程

    1 关于连接sqlite数据库时使用QSqlTableModel模型查看具体数据 通过行号 列名称来获取某单元格的数据 注 model中的一行称为一条record 一列称为一条field 方法 1 使用QSqlRecord类 QSqlRec
  • Python中的pass语句详解

    作者 永劫 一 概述 在本文中 我们将详细介绍Python中的pass语句 包括其定义 作用以及使用场景 pass语句在Python编程中是一个实用的占位符 它可以让程序运行在某些特定的情况下 而不引发任何错误 二 pass语句的定义 pa
  • scrapy框架之post请求

    scrapy框架之post请求 1 post请求 2 通过scrapy框架用爬虫发起post请求 3 使用Scrapy框架破解验证码 1 post请求 首先从浏览器打开百度翻译 去抓一下接口 右键检查 一开始是network是什么都没有的
  • 在ubuntu上安装pcl库并配置vscode使用cmake生成可执行文件

    文章目录 在ubuntu上安装pcl库并配置vscode使用cmake生成可执行文件 先列举一下我踩的坑 一 安装vtk7 1 QT5 12 6 VTK7 1 1 二 安装pcl1 9 1 安装依赖库 安装PCL库 三 使用vscode c
  • 根据对象的某一个属性排序

    根据lenval进行排序 思路 使用sort函数 const obj any ID 1 lenval 1 ID 2 lenval 3 ID 3 lenval 2 function compare property return functi
  • Scrapy命令行详解

    官方文档 1 创建项目 scrapy startproject myproject project dir 这将在project dir目录下创建一个Scrapy项目 如果project dir没有指定 project dir将与mypro
  • [运维]python 启用http 文件服务

    要在Python中启用HTTP文件服务 您可以使用内置的http server模块 在Python 3中 或SimpleHTTPServer模块 在Python 2中 在Python 3中 python m http server 在Pyt
  • @CacheEvict 清除多个key

    借用 Caching实现 入参是基本类型的 Caching evict CacheEvict value Cache CONSTANT key CacheKey SINGLE ROLE NAME roleId CacheEvict valu
  • 遗传算法程序 matlab(转)

    遗传算法程序 matlab 一 本程序收集于网络 本人并未运行 如有问题请与作者联系 如有侵权请告之 转载 http hi baidu com hopeasy blog item c82182c302781650b319a802 html
  • DirectX11 顶点和顶点布局

    顶点和顶点布局 1 如何描述顶点 5 5 1节已经讲过 在Direct3D中 顶点由空间位置和各种附加属性组成 Direct3D可以让我们灵活地建立属于我们自己的顶点格式 换句话说 它允许我们定义顶点的分量 要创建一个自定义的顶点格式 我们