2013-06-17 2 views
28

glVertexAttribPointer을 호출해야하는 것은 설명서에서 분명하지 않습니다. VBO 초기화의 일부인 것처럼 보이지만 렌더링하는 동안 호출하는 예제 코드에 주목합니다.언제 glVertexAttribPointer를 호출해야합니까?

glVertexAttribPointer(vertexAttributeId, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex2D), reinterpret_cast<const GLvoid*>(offsetof(Vertex2D, m_x)));

glVertexAttribPointer (glBindBuffer를 호출 후) 렌더링 동안 GL_ARRAY_BUFFER 또는 호출되어야한다 초기화 중에 호출해야 하는가? 의 말을하자 - - 접착제 사이

+2

어쩌면 질문해야 할 질문은 * 호출해야 할 때가 아니라 * 무엇을 할 것인가입니다. 그것이 무엇을하는지 안다면, 언제 부를지의 여부는 명백합니다. 그리고 "VBO 초기화의 일부"라고 생각하면이 함수가하는 일에 대한 아이디어는 매우 잘못되었습니다. –

+1

@NicolBolas (현재 바인드 된 버퍼의) 속성 데이터의 오프셋을 저장합니까? 그리고 attributeId는 셰이더에있는 속성의 위치입니다 ('glGetAttribLocation'에서 가져 오거나'glBindAttribLocation'을 통해 설정)? –

+2

"* (현재 바인딩 된 버퍼의) 속성 데이터의 오프셋을 저장합니다. * * [[* Dangerously * incomplete.] (http://www.opengl.org/wiki/Vertex_Specification#Vertex_Buffer_Object) ([format information] (http://www.opengl.org/wiki/Vertex_Specification#Vertex_format) 및 [stride data] (http://www.opengl.org/wiki/) 속성뿐만 아니라 그 속성에 사용될 객체 Vertex_Specification # Vertex_buffer_offset_and_stride)를 사용합니다. –

답변

41

(즉, 다음 glDraw... 통화).

이제 두 가지 시나리오가 있습니다.버텍스 배열 객체 (VAO)를 사용하거나 사용하지 마십시오 (VAO를 사용하지 않는 것이 현재 OpenGL에서는 더 이상 사용되지 않으며 권장되지 않습니다). 이 아니고 VAO를 사용하는이 아닌 경우 올바르게 렌더링하기 전에 glVertexAttribPointer (및 그에 상응하는 glEnableVertexAttribArray)이라고 부릅니다. VAO를 사용하는 경우 VAO 생성 코드 (일반적으로 초기화 또는 객체 생성의 일부 임) 내부에서 설정을 호출하기 때문에 실제로 설정을 VAO 내부에 저장하고 렌더링 할 때 필요한 작업 만 수행하면됩니다 VAO를 바인딩하고 그리기 기능을 호출하십시오. 당신이 glVertexAttribPointer를 호출 할 때

하지만 상관없이, 당신은 (즉, 실제로 생성 및 작성 때에 상관없이)에 glVertexAttribPointer 기능은 현재이 속성에 대해 소스 버퍼로 GL_ARRAY_BUFFER 바인딩을 설정하기 때문에, 바로 전에 해당 버퍼를 바인딩 (저장한다 이 설정은 나중에 다른 VBO를 자유롭게 바인딩 할 수 있음).

//initialization 
glGenBuffers 
glBindBuffer 
glBufferData 

... 

//rendering 
glBindBuffer 
glVertexAttribPointer 
glEnableVertexAttribArray 
glDrawWhatever 
+0

버퍼 삭제에주의하십시오. 현재 바인드 된 버퍼 오브젝트가 삭제되면 바인딩은 0 (클라이언트 메모리 사용으로 되돌아가는 버퍼 오브젝트 없음)으로 되돌아갑니다. " –

+0

따라서 버퍼를 삭제하는 동안 버퍼를 삭제합니다 아직도 묶여 있니? 삭제하기 전에'glBindBuffer (GL_ARRAY_BUFFER, 0);'를 호출해야합니까? –

+0

@ t.niese 언제 VBO를 바인딩 해제 할 수 있습니까/VBO를 삭제합니까? –

4

glVertexAttribPointer 정말 버퍼에 않으며입니다프로그램에 속하지 않는 무언가이다.

(이것의 기능은 다른 기능 VertexAttrib*Format, VertexAttribBindingARB_vertex_attrib_binding을 통해 aviable BindVertexBuffer에서 OpenGL을 4.3 splitten있다) 그러나 당신이 무언가의 일부라고 말하고 싶은 경우에 나는 그것이 VAO 상점의 일부입니다 말할 것 Buffer 객체가 바인드 된 상태, 사용 가능한 속성 및 버퍼 데이터가 프로그램으로 전달되어야하는 방식.

그래서 부분 설정은 VAO입니다.

  • VAO 인 경우 버퍼를 바인딩해야하는 활성화 된 attribs 정의 VAO을 만들

    1. Buffer의의/설정을 생성하고 생성 프로그램 : 순서를 보여

      편집 간단한 설치 사용한 데이터와 그 데이터를 프로그램에 전달하는 방법 (glVertexAttribPointer)

  • 1

    해당되는 경우 (예 :)는 (대부분의 경우) 호출되어야합니다. 당신이 사용하고자하는 하나) VBO가 바인딩됩니다. 그런 다음 마지막 매개 변수가 버퍼에서 오프셋됩니다.

    마지막 파라미터 the reference manual 특히 좋은 정의된다

    현재 GL_ARRAY_BUFFER에 바인딩 버퍼의 데이터 저장 장치의 어레이로 상기 제 1 일반 정점의 첫번째 성분의 오프셋 속성을 지정 목표. 초기 값은 0입니다.

    적절한 정점 포인터 VBO 소스와의 바인딩은 VAO 내에 저장되므로 가능한 경우이를 사용해야합니다.

    짧은 예 (내 의사 변명) : 기능 glVertexAttribPointer의 형식과 소스 버퍼 뭔가를 렌더링 할 때 사용되는 정점 속성 (클라이언트 배열의 사용되지 않는 사용을 무시)을 지정

    // Setup 
    CreateVAO(); BindVAO(); 
    CreateVBO(); BindVBO(); 
    VertexAttribPointer(/*id*/ 0, 3, GL_FLOAT, /*starting at offset*/ 0); 
    
    // We have specified Vertex attribute bound to location 0, 
    // with size of 3 floats, starting at offset 0 of VBO we've just created.   
    
    //Draw 
    BindVAO(); 
    Draw(); 
    
    +0

    * "glVertexAttribPointer는 적절한 (즉, 사용하고 싶은) VBO가 바인딩되어있을 때 (대부분의 경우) 호출되어야합니다."* - Meh. VBO의 바인딩은'glVertexAttribPointer'가 호출 될 때 (그리고 VAO 셋업 시간이나 VAO를 사용하지 않을 때의 렌더링 시간으로 안내 됨)에 의해 유도되어야합니다. –

    +1

    글쎄,'glVertexAttribBuffer' 함수는 어쨌든 훨씬 더 직관적이지만 OpenGL입니다. –

    +0

    @ChristianRau IMHO 거의 비슷하지만 의미론에 대해서는 논쟁하지 않을 것입니다. 또한 커뮤니티가 귀하의 답변에 더 동의하는 것으로 보입니다. –

    1
    : VAOs를 사용하지 않을 경우

    //initialization 
    glGenVertexArrays 
    glBindVertexArray 
    
    glGenBuffers 
    glBindBuffer 
    glBufferData 
    
    glVertexAttribPointer 
    glEnableVertexAttribArray 
    
    glBindVertexArray(0) 
    
    glDeleteBuffers //you can already delete it after the VAO is unbound, since the 
           //VAO still references it, keeping it alive (see comments below). 
    
    ... 
    
    //rendering 
    glBindVertexArray 
    glDrawWhatever 
    

    그것이 그런 일이 될 것입니다 :

    그래서 (권장) VAOs을 사용하여 현대는 OpenGL에서,이 흐름에 일반적으로 유사

    버퍼, 일반 버텍스 속성 및 셰이더 속성 변수의 연결은 아주 미묘합니다. glVertexAttribPointer이이 연결을 설정합니다. 자세한 설명은 OpenGL-Terminology을 참조하십시오.

    또한 링크 OpenGL-VBO,shader,VAO은 필요한 API 호출 순서를 보여주는 작업 예제를 보여줍니다.

    관련 문제