【问题标题】:Contiguous memory, OpenGL, and how are you wrapping your vertices?连续内存,OpenGL,以及如何包装顶点?
【发布时间】:2013-04-04 09:33:52
【问题描述】:

因此,OpenGL 编程的一个关键要求是您以保证连续内存的方式存储顶点。我最近读了几本专业图形程序员写的不错的书,他们都使用了相同想法的变体:将顶点打包成floats的struct,x,y,z,然后打包多个顶点放入 c 样式数组或 std::vector 中的 structs。它有效。

但我在这个网站上一次又一次地看到struct 不能保证内存连续性。据说如果您的结构包含所有floats,那么它们可能是连续的,但不能保证。array 和std::vector 可以保证它,但如果您放入数组或向量中的内容不连续,则无关紧要。

对于生产代码,我希望“可能”不会削减它。因此,尽管这两本书中的建议显然更适合学习,但我想知道还有哪些其他好的技术可以以保证连续记忆的方式轻松组织顶点数据,或者,我会接受我不应该担心这个的建议,可能应该足够好。

图形领域还有哪些常用的好方法?

【问题讨论】:

  • 除了您可能采取的任何其他预防措施之外,请将其放入您的代码中:static_assert(sizeof(vertex) == sizeof(float) * 3, "vertex not properly aligned"); -- 如果在对您的工具链进行任何修改时,您的假设失败了,您将在编译时收到通知.
  • C++ 标准可能无法保证,但可能由特定平台上的 ABI“标准”指定。这意味着一旦你确定它可以在一个平台上运行,它就不会发生不可预测的变化,或者它会破坏所有已编译的库。基本上,C++ 标准并不是唯一适用的标准,每个平台都有这些东西的标准。即使它不是书面的、已发布的标准,它仍然不会轻易被破坏。当然,您必须确保在移植到平台时您的假设是正确的,但之后我看不到它会崩溃。

标签: c++ opengl graphics opengl-es 3d


【解决方案1】:

因此,OpenGL 编程的一个关键要求是您以保证连续内存的方式存储顶点。

不,不是。连续内存可以节省空间,但只要属性之间的步幅(字节距离)在所有元素之间相同,这个东西就可以工作。

图形领域还有哪些常用的好方法?

原始数据类型的简单、普通、平面数组,如std::vector<float> 或std::vector<char>,如果您只想要一块内存,您可以在其中手动连续地分散数据。您可以使用 getter 和 setter 方法以及抽象偏移量和步幅计算的迭代器接口将其封装在一个类中。

如果您可以使用编译器扩展来指定其内存布局,您也可以使用结构。例如 GCC 的 __attribute__((packed)) 将组成一个紧密的元素结构,之间没有间隙。

【讨论】:

  • 很有趣,谢谢。您是否碰巧知道任何可能具有您提到的包装类的好示例或示例代码?
【解决方案2】:

OpenGL Mathematics Library,glm,保证它的向量在内存中是连续且简单的,我个人用它来存储顶点:

std::vector<glm::vec3> positions;
std::vector<glm::vec2> texCoords;

它还有一个实用程序可以在 OpenGL glXXXv 函数中安全地转换其结构的地址。

如果你想把所有东西都放在一个 VBO 中,你就必须创建某种复合结构,因为我担心 std::tuple&lt;glm::vec3, glm::vec2&gt; is not up for the challenge,这有点令人难过。


看起来,the glm behaviour is not backed by the standard,但 C++11 和 alignas() 可能已经改变了。但是,我猜你在对齐结构方面几乎没有做得更好,建议的static_assert 应该可以防止你在脚下开枪。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    • 2013-10-22
    • 1970-01-01
    • 1970-01-01
    • 2014-03-28
    相关资源
    最近更新 更多