21

頂点シェーダーに属性を渡そうとしていますが、何らかの理由で、glGetAttribLocation()を介して取得するようにopenGlに要求している3番目の属性の場所に-1が表示され続けます。現在、texCoord属性に-1が表示され続け、texAttribとcolAttribを切り替える(コード内の行を切り替える)と、テクスチャではなくcolorプロパティに-1が表示されますが、理由がわかりません。-1がglVertexAttribPointerに渡されているため、1281OpenGLエラーGL_INVALID_VALUEが発生します。

私の頂点シェーダー:

#version 150

in vec3 position;
in vec3 color;
in vec2 texcoord;

out vec3 Color;
out vec2 Texcoord;

void main()
{
    Color = color;
    Texcoord = texcoord;
    gl_Position = vec4(position.x, position.y, position.z, 1.0);
}

OpenGLコード:

basicShader.Use();

// Buffers and shaders
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

glGenBuffers(1, &vbo);
// Make it active vbo
glBindBuffer(GL_ARRAY_BUFFER, vbo);

// Build basic triangle
float vertices[] = {
    // position         // color          // textures
    -0.5f,  0.5f, 0.5f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // Top-left
     0.5f,  0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, // Top-right
     0.5f, -0.5f, 0.5f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom-right
    -0.5f, -0.5f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f// Bottom-left
};
GLuint elements[] = {
    0, 1, 2,
    2, 3, 0
};

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

GLint posAttrib = glGetAttribLocation(basicShader.shaderProgram, "position");
glEnableVertexAttribArray(posAttrib); // Enable attribute first before specifiying attributes
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), 0); // 6 float sizes is every new vertex

GLint colAttrib = glGetAttribLocation(basicShader.shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); // same for color + offset

GLint texAttrib = glGetAttribLocation(basicShader.shaderProgram, "texcoord"); // Returns -1
glEnableVertexAttribArray(texAttrib);
glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); // 6 offset from beginning

[..]
4

1 に答える 1

35

の使用をやめる必要がありますglGetAttribLocation。プログラムをリンクする前に、または明示的な属性の場所が利用可能な場合は、各属性に場所を割り当てます。glBindAttribLocation

そうすれば、コンパイラーが属性を最適化する場合(これがここで起こっていることです。フラグメントシェーダーはおそらく補間された値の1つを使用しません)、気にしません。属性インデックスの標準規則を使用して、通常どおり配列を設定します。さらに、別のプログラムでレンダリングするたびに、属性の場所を尋ね続ける必要はありません。あなたはそれを割り当てたのでそれがどんな場所であるかを知っています。

あなたができない/できない場合、あなたができることは何もありません。属性を実際に使用していない場合、コンパイラは属性を最適化します。実行できる唯一のことは、-1を返すことを検出し、その属性の配列を設定しないことです。

于 2013-03-26T14:52:42.623 に答える