2014-10-07 4 views
0

다른 여러 프로그램을 올바르게 전환하는 방법에 대해 혼란스러워합니다. 문제를 다음과 같이 좁혔습니다 : NO_HDR로 실행하면 정상적으로 작동합니다. 나는 선들과 우주선들, 그리고 몇몇 구체들, 그 순서대로 렌더링 된 것들을 얻는다. HDR로 실행하면 대부분 같은 결과를 얻지 만 구체 대신 2 차원 정사각형을 얻습니다.glVertexAttribPointer 덮어 쓰기

hdr 부분의 쿼드 정점 속성이 forwardRender() 섹션에서 렌더링 할 마지막 항목을 덮어 쓰고 있다고 생각합니다. forwardRender()에서 순서를 변경하면 forwardRender()에서 마지막으로 렌더링되는 것은 무엇이든 엉망이됩니다. 쿼트 버텍스가 다른 객체를 덮어 쓰는 것을 내가 놓치고있다.

#if NO_HDR 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
forwardRender(); 

#else 

//set to render to custom frame buffer 
glBindFramebuffer(GL_FRAMEBUFFER, rt.FramebufferName); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
forwardRender(); 

//now switch to render to screen 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, rt.renderedTexture); 

glUseProgram(hdr.shaderProgram); 
glUniform1i(texID, 0); 

glBindBuffer(GL_ARRAY_BUFFER, hdr.quad_vertexbuffer); 
glEnableVertexAttribArray(hdr.quad_vertexPosition_modelspace); 
glVertexAttribPointer(
         hdr.quad_vertexPosition_modelspace, // attribute 
         3,        // size 
         GL_FLOAT,      // type 
         GL_FALSE,      // normalized? 
         0,        // stride 
         (void*)0      // array buffer offset 
        ); 
// Draw the triangles ! 
glBindVertexArray(hdr.vao); 
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles 

#endif 

또 다른 단서 : 나는 끝에 glDrawArrays 후 vertexAttribArray를 사용하지 않도록 설정하면 내 구/사각형이 사라! 참고로

, 여기에 내가 forwardRender()에 구체를 렌더링하는 방법입니다

glUseProgram(globe.shaderProgram); 
glm::mat4 mvp = camera * world * position * size * orientation; 
GLint uTransform = glGetUniformLocation(shaderProgram, "transform"); 
glUniformMatrix4fv(uTransform, 1, GL_FALSE, glm::value_ptr(mvp)); 
glBindVertexArray(globe.vao); 
glDrawArrays(drawType, 0, globe.drawCount); 

답변

6

게시 된 코드는 어떻게 정점 배열 개체 (VAO) 작업의 가능한 오해를 제안합니다. VAO는 국가의 집합입니다.

  • glVertexAttribPointer(...)
  • glEnableVertexAttribArray(...), 당신이이 통화 중 하나 할 때마다 glDisableVertexAttribArray()
  • glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ...)

는 해당 상태가 현재 바인딩에 저장됩니다에는 다음과 같은 통화 설정 상태를 포함 VAO. 나중에 VAO를 다시 바인딩하면 상태가 복원됩니다. 예를 들어

, 게시 된 코드에서이 순서 :

glEnableVertexAttribArray(hdr.quad_vertexPosition_modelspace); 
glVertexAttribPointer(hdr.quad_vertexPosition_modelspace, ...); 
// Draw the triangles ! 
glBindVertexArray(hdr.vao); 
glDrawArrays(GL_TRIANGLES, 0, 6); // 2*3 indices starting at 0 -> 2 triangles 

glDrawArrays() 호출 은 시퀀스의 첫 번째 두 통화로 설정 상태를 사용하지 것입니다. 그 상태는 당시 VAO가 바인딩 된 모든 것에 적용됩니다. 그런 다음 glBindVertexArray(hdr.vao) 콜은 hdr.vao에 저장된 상태를 복원하는데, 이는 이전에 VAO가 바인드되었을 때 가장 최근의 상태 세트입니다.

또한이 기능은 프로그램 전환과 관련이 없습니다. 버텍스 상태는 프로그램 상태의 일부가 아닙니다.

은 일반적으로 다음과 같이 보일 것이다 VAOs에게 효과적으로 프로그램 구조를 사용하려면

  1. 일단, 설치하는 동안, 각 개체에 대한 VAO을 만들 수 있습니다. 예 : 하나는 지구본, 하나는 쿼드 (quad) 등입니다. 그런 다음 각 VAO를 바인딩하고 위의 목록에서 호출하여 개체의 정점 상태를 설정합니다.
  2. 렌더링하는 동안 각 개체에 대해 필요한 경우 프로그램을 변경하고 개체의 VAO를 바인딩 한 다음 그리기 호출을 만듭니다. 상태는 각 객체의 VAO에 저장되므로 다른 꼭지점 상태 호출은 필요하지 않습니다.

나는 당신이 당신의 코드에서이 문제를 생각하지 않지만, 단지 가끔 혼란을 일으키는 하나 개의 관련 항목을 강조 : 올바른 GL_ARRAY_BUFFER 바인딩 요구 glVertexAttribPointer()가 호출되는 시점에 장소에있을 수 있습니다.그리기 호출에 대해 GL_ARRAY_BUFFER 바인딩을 설정할 필요가 없습니다.

+0

명확하게 말하면 현재 바인딩 된 VAO에 저장된 바인딩은 GL_ELEMENT_ARRAY_BUFFER에 바인딩입니까? – Francis

+1

예. glVertexAttribPointer()가 호출 될 때'GL_ARRAY_BUFFER' 바인딩이 필요하고 버퍼 참조는 그 속성에 대한 상태의 일부가된다. 'GL_ARRAY_BUFFER' 바인딩 자체는 VAO 상태의 일부가 아니며 그리기 호출에 영향을줍니다. –