我有一个顶点着色器,我正在尝试使用顶点着色器渲染内容。当我使用普通的vec3“in”属性时,我有它工作,但现在我需要传递某些信息。我制作了一个结构,我将用于顶点着色器,几何着色器和计算着色器。
struct StellarEntity
{
vec3 position;
vec3 velocity;
double mass;
double radius;
};
这是我的顶点着色器(当然结构在那里):
#version 430
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
layout(location = 0) in StellarEntity in_entity;
void main()
{
gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(in_entity.position, 1.0);
}
我认为问题可能是我绑定顶点属性的方式。
vao = new VAO();
//"entities" is a StellarEntity[256] with all data initialized
vao.BufferData(BufferTarget.ArrayBuffer, entities, BufferUsageHint.StaticDraw);
vao.VertexAttribPointer(0, 3, VertexAttribPointerType.Double, false, 0, 0);
vao.VertexAttribPointer(0, 3, VertexAttribPointerType.Double, false, 0, 0);
vao.VertexAttribPointer(0, 1, VertexAttribPointerType.Double, false, 0, 0);
vao.VertexAttribPointer(0, 1, VertexAttribPointerType.Double, false, 0, 0);
我真的不明白步幅和偏移(VertexAttribPointer的最后两个参数),所以我把它们放在0 ......
编辑:忘了把我的BindAttributeLocation调用,所以这里是:
//"program" being my shaderprogram, after the linking (worked fine for simple shaders)
program.BindAttribLocation(0, "in_entity");
答案 0 :(得分:1)
首先,您不能使用结构作为顶点着色器的输入。您应该只使用四个单独的顶点属性:
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 velocity;
layout(location = 2) in double mass;
layout(location = 3) in double radius;
(我认为你应该在这里考虑使用double
。在GPU上,它们的表现不如浮点数。)
其次,步幅是一个顶点的属性与下一个顶点的属性之间的字节偏移。在您的情况下,它应该是您的StellarEntity
结构的大小(以字节为单位)。偏移量是从绑定缓冲区的开头到第一个顶点的属性的字节偏移量。如果您将mass
和radius
更改为float
s,则可以是:0,12,24& 28.然后你的'VertexAttribPointer'调用成为:
vao.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 32, 0);
vao.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, 32, 12);
vao.VertexAttribPointer(2, 1, VertexAttribPointerType.Float, false, 32, 24);
vao.VertexAttribPointer(3, 1, VertexAttribPointerType.Float, false, 32, 28);
(免责声明:我不使用C#,所以我假设OpenGl绑定是直接的,vec3
类型使用float
而不是double
s)
最后,如果您在着色器中明确设置顶点输入的位置,program.BindAttribLocation(0, "in_entity");
将不会执行任何操作。
答案 1 :(得分:0)
解决了这个问题,这是一个跨步和抵消的问题。对于那些寻找答案的人:步幅是数组中一个元素的总大小(以字节为单位),偏移量是字段前的字节数。所以严格来说:
struct A {
Vector4f pos;
Vector4f norm;
}
两次调用的步幅均为32.第一次偏移为0,第二次为16次。