创建异构顶点数据数组的可移植方法
Portable way to create heterogenous vertex data array
在图形编程中,使用顶点格式是很常见的。 例如,此处对此进行了描述。
但是,我正在寻找一种方法来完成不调用未定义行为的方法 (我主要寻找C++信息,但 C 也可以(。
常见的方法是这样的:首先,将顶点格式声明为结构。
struct Vertex {
float x;
float y;
uint16_t someData;
float etc;
};
然后,您创建一个数组,填写它们,并将它们发送到您的图形 API(例如:OpenGL(。
Vertex myVerts[100];
myVerts[0].x = 42.0;
// etc.
// when done, send the data along:
graphicsApi_CreateVertexBuffer(&myVerts[0], ...);
(旁白:我跳过了你告诉 API 格式是什么的部分;我们只是假设它知道(。
但是,图形 API 不了解您的结构。它只需要内存中的一系列值,如下所示:
|<--- first vertex -->||<--- second vertex -->| ...
[float][float][u16][float][float][float][u16][float] ...
由于打包和对齐的问题,无法保证myVerts
将在内存中以这种方式布局。
当然,大量的代码都是以这种方式编写的,尽管它不是可移植的,但它可以工作。
但是有没有任何便携式方法可以做到这一点,也不是
1. Inefficient
2. Awkward to write
?
这基本上是一个序列化问题。另请参阅:将缓冲区解释为结构的正确、可移植的方法
我知道的主要符合标准的方式是将您的内存分配为char[]
. 然后,您只需完全按照您希望的布局方式填写所有字节。
但是要从上面的struct Vertex
表示转换为char[]
表示,需要一个额外的副本(以及一个缓慢的逐字节副本(。所以这是低效的。
或者,您可以直接将数据写入char[]
表示形式,但这非常尴尬。说verts[5].x = 3.0f
比寻址到字节数组、将浮点数写入 4 个字节等要好得多。
有没有一种好的便携式方法来做到这一点?
但是,图形 API 不了解您的结构。它只需要内存中的一系列值,如下所示:
|<--- first vertex -->||<--- second vertex -->| ... [float][float][u16][float][float][float][u16][float] ...
这不是真的。图形 API 具有有关结构的知识,因为您告诉它有关结构的信息。你甚至已经知道这一点:
(旁白:我跳过了你告诉 API 格式是什么的部分;我们只是假设它知道(。
当您告诉图形 API 每个字段在结构中的位置时,应使用sizeof
和offsetof
,而不是猜测结构的布局。然后,即使编译器插入填充,您的代码也将正常工作。例如(在OpenGL中(:
struct Vertex {
float position[2];
uint16_t someData;
float etc;
};
glVertexAttribPointer(position_index, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), (void*)offsetof(struct Vertex, position));
glVertexAttribIPointer(someData_index, 1, GL_SHORT, sizeof(struct Vertex), (void*)offsetof(struct Vertex, someData));
glVertexAttribPointer(etc_index, 1, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), (void*)offsetof(struct Vertex, etc));
不
glVertexAttribPointer(position_index, 2, GL_FLOAT, GL_FALSE, 14, (void*)0);
glVertexAttribIPointer(someData_index, 1, GL_SHORT, 14, (void*)8);
glVertexAttribPointer(etc_index, 1, GL_FLOAT, GL_FALSE, 14, (void*)10);
当然,如果您将磁盘中的顶点读取为已知格式的字节 blob(可能与编译器的结构布局不同(,则可以使用硬编码布局来解释这些字节。如果要将顶点视为结构数组,请使用编译器为您决定的布局。
- C++Union/Struct位域的实现和可移植性
- 具有Qt事件循环的可移植通用共享库设置
- 没有执行策略的 std::transform_reduce 是可移植的吗?
- 如何在 c++ 中正确指定 #include 路径以使程序可移植
- 创建异构顶点数据数组的可移植方法
- FlatBuffers/Protobuf 中是否有支持任意 24 位有符号整数定义的可移植二进制序列化架构?
- 静态库可移植性
- 从非类型模板参数声明 constexpr 数组的可移植方法
- C++:Unicode 字符串文字的可移植性
- 如何使Visual Studio 2017 C++项目在计算机之间更具可移植性
- 将参数推送到调用堆栈 (C++) 的可移植方法
- 一种在编译时用C++根据printf格式检查参数的可移植方法
- 在C++中设置文件修改时间的可移植方法
- 试图找出一种可移植的数据保存方法
- 有没有一种可移植的方法可以知道uintptr_t是否在stdint.h中定义
- 确定使用dlopen打开的动态库的路径的可移植方法
- c++中是否有一种可移植的方法将stdin重定向为string ?
- Boost::serialization——是否有一种可移植的方法来对std::wstring进行二进制序列化?
- 可移植的c++ 11方法,同时等待套接字和bool变量
- 检查表达式是否编译的可移植方法