3

OpenGL 4.2 を使用していますが、このプログラムで GL_INVALID_VALUE エラーが発生する理由がわかりません。glBindAttribLocation を呼び出すとエラーが発生します。OpenGL 4 リファレンス ページによると、GL_INVALID_VALUE を glBindAttribLocation から生成する必要がある理由は 2 つしかありません。

void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name);

  1. インデックスが MAX_VERTEX_ATTRIBS 以上の場合、INVALID_VALUE が生成されます。
  2. program が OpenGL によって生成された値でない場合、INVALID_VALUE が生成されます。

以下のプログラムからわかるように、indexis20GL_MAX_VERTEX_ATTRIBSisであるため、条件 1 は設定されません34921programは を使用して OpenGL によって生成されるため、条件 2 は満たされていませんglCreateProgram()。では、どうすればエラーが発生する可能性がありGL_INVALID_VALUEますか?

// test.cpp
#include <GL/glew.h>
#include <GL/glut.h>
#include <iostream>

int main(int argc, char* argv[])
{
    glutInit(&argc, argv);
    glutCreateWindow("Test");
    glewInit();

    std::cout << "Max Vertex Attributes : " << GL_MAX_VERTEX_ATTRIBS << std::endl;
    // create program
    GLuint program = glCreateProgram();
    if ( program == 0 )
        std::cout << "Program error" << std::endl;

    // clear existing errors        
    if ( glGetError() != GL_NO_ERROR )
        std::cout << "Pre-existing error" << std::endl;

    // bind attribute location to index 20
    glBindAttribLocation(program, 20U, "DoesNotExist");

    // why is this generating an INVALID_VALUE error?
    if ( glGetError() == GL_INVALID_VALUE )
        std::cout << "Invalid value error" << std::endl;

    glDeleteProgram(program);
    return 0;
}

端末出力

$ g++ test.cpp -lGLEW -lglut
$ ./a.out 
Max Vertex Attributes : 34921
Invalid value error

また、OpenGL 4.2 を確認するには

$ glxinfo | grep OpenGL
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: GeForce GT 540M/PCIe/SSE2
OpenGL version string: 4.2.0 NVIDIA 304.64
OpenGL shading language version string: 4.20 NVIDIA via Cg compiler
OpenGL extensions:

参考ページによる。「glBindAttribLocation は、頂点シェーダー オブジェクトが指定されたプログラム オブジェクトにバインドされる前に呼び出すことができます。汎用属性インデックスを、頂点シェーダーで決して使用されない属性変数名にバインドすることも許可されています。」したがって、シェーダーがロードされてDoesNotExistおらず、存在しないという事実は問題ではありません。

4

1 に答える 1

10

この質問が聞かれたのを思い出すことができるのは、ここ数か月で 2 回目です。これが最後に尋ねられたのは、これが同じ質問であることはすぐにはわかりませんが、hereでした。

要約するとGL_MAX_VERTEX_ATTRIBS、コンパイラは、実行時に実装定義の制限を OpenGL ドライバーに問い合わせるために使用できる ID を定義するプリプロセッサ トークンであると見なします。この値を直接出力しようとすると、すべての OpenGL 実装がこの特定の制限を照会するために使用するユニバーサル ID を出力するだけです。

実際の実装依存の制限を取得するには、実行時にこれを行う必要があります。

int max_attribs;
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs);

ちなみに、OpenGL の実装は、頂点ごとに最低 16 の属性を提供することだけが必要です。ほとんどは最小値のみを提供します。これが、20 が範囲外である理由を説明しています。

于 2013-09-29T01:12:49.787 に答える