【问题标题】:Opengl Vertex attribute strideOpengl顶点属性步幅
【发布时间】:2015-01-03 00:58:42
【问题描述】:

嘿。 我是 OpenGL ES 的新手,但我对普通的 OpenGL 有一些经验。 有人告诉我,由于避免缓存未命中的优化,对顶点缓冲区使用交错数组要快得多。
我开发了一种我将使用的顶点格式,如下所示

结构 SVertex { 浮动 x,y,z; 浮动 nx,ny,nz; 浮动 tx,ty,tz; 浮动 bx,by,bz; 浮动 tu1,tv1; 浮动 tu2,tv2; };

然后我使用“glVertexAttribPointer(index,3,GL_FLOAT,GL_FALSE,stride,v);”指向顶点数组。索引是我要使用的属性之一,除步幅外,其他一切都可以。在我决定将其添加到等式之前它起作用了。我以 sizeof(SVertex) 和 13*4 的形式通过了跨步,但它们似乎都不起作用。
如果它有任何重要性,我会像这样绘制原语

glDrawElements(GL_TRIANGLES,surface->GetIndexCount()/3,GL_UNSIGNED_INT,surface->IndPtr());
在 OpenGL 规范中写到,步幅应该是从属性末尾(在本例中为 z)到下一个同类属性(在本例中为 x)的大小(以字节为单位)。所以根据我的计算,这应该是 13(nx,ny,nz,tx,ty....tuv2,tv2) 乘以 4(浮点数的大小)。
哦,还有一件事是显示器只是空的。
谁能帮我解决这个问题?
非常感谢。

【问题讨论】:

  • 我说了 13 个值,认为我必须减去前 3 个值(如果你只有 x,y,z 则步幅为 0);

标签: c++ pointers opengl-es rendering


【解决方案1】:

如果你有这样的结构,那么stride 就是sizeof SVertex 并且每个属性都是一样的。这里没有什么复杂的。

如果这不起作用,请在其他地方查找您的错误。

例如这里:

surface->GetIndexCount()/3

这个参数应该是要发送的顶点数,而不是基元数 - 因此我会说这个除以三是错误的。保留为:

surface->GetIndexCount()

【讨论】:

  • 谢谢。这是索引计数。虽然如果你看一下 Ogl 规范“count-指定要渲染的元素的数量。”
  • 我相信规范意味着在这种情况下“元素”与“顶点”相同。线、三角形、四边形、多边形等统称为“基元”。
  • 实际上第二个参数是索引的数量,而不是顶点。关于规范“元素”意味着更多根据拓扑模式使用索引构建的基元。但归根结底,这只是指数的数量。
  • 1 个索引通常对应于 1 个顶点,所以这并不是一个很大的区别恕我直言 :) 但是是的,有些情况下这不成立(原始重启,实例化......)。跨度>
  • 您可以拥有一个具有 1024 个顶点的 VBO,并使用索引绘制调用从中仅绘制 10 个索引。那就是我的意思。但是是的,我理解你的意思,一个索引总是对应一个顶点,希望 ;)
【解决方案2】:

然后我用 “glVertexAttribPointer(索引,3,GL_FLOAT,GL_FALSE,步幅,v);” 指向顶点数组。这 索引是我的属性之一 想用其他都ok 除了步幅

这不适用于 texcoord(您有 2x 2 个浮点数或 1x 4 个浮点数)。

关于步幅,就像科斯说的,我认为你应该通过16 * sizeof(float) 的步幅(你的SVertex 的大小)。

还有一件事值得一提。你说你想优化性能。为什么不将顶点压缩到最大值,并抑制冗余值?这将节省大量带宽。

x, y, z 可以,但如果您的法线已标准化(可能是这种情况),nxny 就足够了。您可以在顶点着色器nz 中提取(假设您有着色器功能)。 txty 也是如此。你根本不需要bx, by, bz,因为你知道它是normaltangent 的叉积。

struct SPackedVertex
{
    float x,y,z,w;       //pack all on vector4
    float nx,ny,tx,ty;
    float tu1,tv1;tu2,tv2;
};

【讨论】:

  • 这里有一些关于冗余的好评论,但是这种正常的打包真的能提高性能吗?听起来很可能(在大多数情况下,GPU 内存延迟可能是比顶点处理能力更严重的瓶颈),但基准测试真的证实了这一点吗?
  • 我不知道,只是在这里猜测。像往常一样,基准,基准,基准! :) 如果 OP 使用的是 OGL ES,他的代码可能在手持设备上运行,这些设备在内存带宽方面与桌面 GPU 相差甚远(我认为),所以它可能值得尝试..
  • 另外我不知道这是否可以在这里应用,但顶点的大小似乎对于预 VS 缓存也很重要(也许 32 或 64 字节优于 48 ..)在这种情况下我会尝试进一步压缩到 32 个字节。这可以通过对法线、切线和 texcoords 使用半浮点 (GL_OES_vertex_half_float) 来完成:developer.amd.com/gpu_assets/…
  • 感谢您的建议。我会尽量考虑到它们。
  • 不错。半浮动似乎已经是 OpenGL 3.1 的一部分,顺便说一句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多