2013-09-29 3 views
3

OpenGL 4.2를 사용하고 있는데 왜이 프로그램에서 GL_INVALID_VALUE 오류가 발생하는지 알 수 없습니다. glBindAttribLocation을 호출하면 오류가 발생합니다. OpenGL 4 reference page에 따르면 glBindAttribLocation에서 GL_INVALID_VALUE를 생성해야하는 이유는 두 가지뿐입니다. 인덱스가 동일하거나 MAX_VERTEX_ATTRIBS보다 크면OpenGL 4.2 glBindAttribLocation 값이 잘못 되었습니까?

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

  1. INVALID_VALUE 생성된다.
  2. 프로그램이 OpenGL에서 생성 된 값이 아니면 INVALID_VALUE가 생성됩니다. 아래의 프로그램에서 볼 수 있듯이 index20GL_MAX_VERTEX_ATTRIBS34921입니다 때문에

, 조건 1이 설정되어 있지 않습니다. 조건 2는 program이 OpenGL에 의해 glCreateProgram()을 사용하여 생성되기 때문에 충족되지 않습니다. 그렇다면 어떻게하면 GL_INVALID_VALUE 오류가 발생할 수 있습니까? reference page에 따르면

// 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 존재하지 않는다는 사실은 문제가 아닙니다.

+0

은 드라이버 버그 일 수 있지만 왜이 작업을 수행하고 있습니까? 나는 어떤 점도 보지 못했다 ... 4.2 또한 명시 적 속성 위치를 갖는다. – yngccc

+0

이것은 훨씬 더 큰 프로그램에서 버그를 복제하는 단지 거짓 프로그램입니다. 4.2에서 셰이더에서 속성 위치를 정의 할 수 있지만 위치를 바인딩하는 것이 최적이라는 방식으로 프로그램을 구조화했음을 알고 있습니다. 또한 이것은 Nvidia 560 GTX가있는 OpenGL 4.2를 실행하는 다른 컴퓨터에서도 반복 가능합니다. 나는 운전사를 새롭게하려고 노력할 것이다 – jodag

답변

9

두 달 후에이 질문을 회상 할 수 있습니다. 이 질문이 마지막으로 나올 때, 바로 이것이 동일한 질문이라는 것이 명백하지 않지만 here입니다.

컴파일러가 런타임에 구현 정의 한계를 OpenGL 드라이버에 요청하는 데 사용할 수있는 ID를 정의하는 프리 프로세서 토큰임을보고 컴파일러가 확인하므로 GL_MAX_VERTEX_ATTRIBS입니다. 이 값을 직접 인쇄하려고하면 모든 OpenGL 구현에서이 특정 제한을 쿼리하는 데 사용하는 범용 ID가 인쇄됩니다.

은 실제 구현에 의존하는 한계를 얻으려면, 당신은 런타임에서이 작업을 수행 할 필요가 :

int max_attribs; 
glGetIntegerv (GL_MAX_VERTEX_ATTRIBS, &max_attribs); 

덧붙여, OpenGL을 구현 전용 정점 당 속성 (16)의 최소를 제공해야합니다; 대부분은 최소값을 제공하기 때문에 20이 범위를 벗어난 이유가 설명됩니다.

+0

Wonderful! GL_MAX_VERTEX_ATTRIBS는 실제로 16입니다. – jodag

+1

이제 어려운 부분이 있습니다. 실제로 정점마다 20 개의 속성을 사용하고 있습니까?:) 그렇다면 정점 데이터 구조를 대폭 단순화하는 방법을 찾아야합니다. 'mat4 '와 같은 것은 4 개의 버텍스 속성 슬롯을 차지한다는 것을주의하십시오. –

+0

하하, 버텍스 당 20 개의 애트리뷰트가 필요하지 않을 것입니다. 그 이유 중 하나는 다른 버텍스 쉐이더가있는 여러 프로그램에서 하나의 VBO를 사용하고 있기 때문입니다. 하나의 버텍스 쉐이더는 4 가지 이상의 버텍스 속성을 가지고 있지 않습니다. – jodag