【问题标题】:glVertexAttribPointer() working only with the first streamglVertexAttribPointer() 仅适用于第一个流
【发布时间】:2013-01-24 13:52:36
【问题描述】:

我正在尝试使用 glVertexAttribPointer() 向我的顶点着色器提供一些数据。问题是它只适用于 FIRST 属性...

这是我的 OpenGL 代码:

struct Flag_vertex
{
    GLfloat position_1[ 8 ];
    GLfloat position_2[ 8 ];
};

Flag_vertex flag_vertex;

   ... // fill some data to flag_vertex

GLuint vertexbuffer_id;
glGenBuffers( 1, &vertexbuffer_id );
glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer_id );
glBufferData( GL_ARRAY_BUFFER, sizeof(flag_vertex), &flag_vertex, GL_STATIC_DRAW );

glEnableVertexAttribArray( 0 );
glEnableVertexAttribArray( 1 );

glBindBuffer( GL_ARRAY_BUFFER, vertexbuffer_id );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, (void*)offsetof(Flag_vertex, position_1) );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, (void*)offsetof(Flag_vertex, position_2) );

我的着色器是这样的:

#version 420 core

layout(location = 0) in vec2 in_position_1;
layout(location = 1) in vec2 in_position_2;

out vec2 texcoord;

void main()
{
    gl_Position = vec4(in_position_X, 0.0, 1.0);
    texcoord = in_position_X * vec2(0.5) + vec2(0.5);
}

如果我使用“in_position_1”,我的纹理会完美渲染,但如果我使用 in_position_2,则不会发生任何事情......

提示:在链接我正在做的着色器之前:

glBindAttribLocation( programID, 0, "in_position_1");
glBindAttribLocation( programID, 1, "in_position_2");

为什么它只适用于第一个流?我需要更多数据到我的顶点...我需要发送颜色等...有什么提示吗?

【问题讨论】:

  • 您是否启用了两个顶点属性?顺便说一句,如果您在着色器中使用布局限定符,则不需要使用 glBindAttribLocation
  • 哦,是的,当然……我忘了写……我在使用之前做了 glEnableVertexAttribArray( 0 ) 和 glEnableVertexAttribArray( 1 )……我会更新它。
  • 如果你切换布局ID(即,in_position_1 -> 1,in_position_2 -> 0),会有不同的工作方式吗?
  • 有点……如果我在着色器上打开它们,它就会停止工作。如果我在 OpenGL 代码上切换名称,in_position_2 开始工作,而 in_position_1 停止......就像它只识别第一个流:-(
  • 顺便说一句,我尝试了没有“布局(位置= X)”的情况,结果相同。

标签: opengl glsl shader vertex-shader


【解决方案1】:
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, (void*)offsetof(Flag_vertex, position_1) );
glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 0, (void*)offsetof(Flag_vertex, position_2) );

这些行没有意义。至少,与Flag_vertex 的定义方式无关。如果Flag_vertex 真的应该是一个 vertex (而不是一个四边形),那么它有 8 个浮点数是没有意义的。如果每个Flag_vertex 定义了一个完整的四边形,那么您将其命名错误;它根本不是一个顶点,它是Flag_quad

所以很难知道你在这里想要完成什么。

还有:

如果我使用“in_position_1”,我的纹理会完美渲染,但如果我使用 in_position_2,则不会发生任何事情......

当然可以。您的位置数据在属性 0 中。因此,您的位置数据在属性 1 中。如果您假装属性 1 有您的位置数据,而它显然没有,您将不会得到合理的结果。 p>

您的问题是,当您应该使用 这两个属性时,您总是使用属性 0。 您不应该选择其中一个。使用in_position_1 作为位置,使用in_position_2 作为纹理坐标。并尝试根据他们所做的事情合理地命名他们(如positiontexture_coord 或其他东西)。不要为他们使用数字。

提示:在链接我正在做的着色器之前:

这与着色器中的layout(location=#) 设置完全相同。如果你想要它在着色器中,那么把它放在着色器中。如果你想在你的 OpenGL 代码中使用它,那么把它放在你的 OpenGL 代码中。不要放在两个地方。

【讨论】:

  • 实际上,OP 中的glVertexAttribPointer 调用完全没问题;他们只是将两个属性数据流顺序放置在 VBO 中。这是在 VBO 中使用数据的一种非常常见的方式。问题的解决方案位于 OP 代码中的另一个位置,与 OP 无关。请参阅上面的chat 了解分辨率。
  • @radical7: "他们只是将两个属性数据流顺序放置在VBO中" 但是"属性数据"不是a"顶点”。这是我的观点:如果打算在一个结构中包含两个非交错数组,那么该结构的命名不正确。
  • 对不起,我没能理解你的意思。如果您正在评论海报选择的变量名称,那与解决方案无关。帖子中的代码是正确且一致的(并且格式化得很好:)事实上,OP 中的所有代码都是正确的 - 问题出在 OP 应用程序的其他地方。
  • 是的,问题出在其他地方……上面的代码很完美。谢谢大家的贡献。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-07
  • 2015-06-28
  • 2013-01-11
  • 2016-05-26
  • 2011-08-25
相关资源
最近更新 更多