2016-08-10 5 views
0

로드 VAO 기능에 glDrawArraysInstanced를 사용하려고OpenGL을 충돌 할 때()

glGenVertexArrays(1, &VAO); 
glGenBuffers(1, &modelVertexVBO); 
glGenBuffers(1, &sphereTransformVBO); 

glBindVertexArray(VAO); 
glBindBuffer(GL_ARRAY_BUFFER, modelVertexVBO); 

glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (sphereModel->numVertices * 3), &(sphereModel->vertices[0]), GL_STATIC_DRAW); 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL); 


glBindBuffer(GL_ARRAY_BUFFER, sphereTransformVBO); 

glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * (maxSphereStorage * 4 * 4), NULL, GL_STATIC_DRAW); 
glVertexAttribPointer(1, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL); 

glEnableVertexAttribArray(0); 
glEnableVertexAttribArray(1); 
glVertexAttribDivisor(sphereTransformVBO, 1); 

glBindVertexArray(0); 

도형 그리기 기능 :

glBindVertexArray(VAO); 
glDrawArraysInstanced(sphereModel->mode, 0, sphereModel->numVertices, sphereCount); 

나는 그것이 다음과 같은 충돌 메모와 함께 충돌이 코드를 실행 해보십시오 : 예외 0x0000000068F4EDB4 (nvoglv64.dll) Engine.exe에서 throw됩니다. 0xC0000005 : 0x0000000000000000 위치를 읽는 액세스 위반.

두 번째 VBO를 제거하면 어떤 이유로 작동합니다.

답변

1
glVertexAttribPointer(0, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL); 

귀하의 충돌은 간단한 복사 및 붙여 넣기 버그의 결과입니다. 여기서 속성 0을 사용합니다. 즉, 속성 1에 대해 glVertexAttribPointer을 호출하지 않았습니다. 따라서 기본 속성 상태를 사용하므로 충돌이 발생합니다.

그러나 4x4 매트릭스를 하나의 속성으로 전달하려고하고 있다고 생각합니다. 그것은 작동하지 않습니다; 속성의 크기를 4 이상으로 설정하려고하면 OpenGL이 give you a GL_INVALID_VALUE error이됩니다.

Matrices are treated as arrays of (column) vectors. 그리고 각 벡터는 속성 색인을 따릅니다. 따라서 행렬을 전달하려면 셰이더에서 제공하는 4 개의 특성 인덱스를 사용해야합니다. 그리고 각자는 그것에 대한 제수를 설정해야합니다.

+0

감사합니다. 정말로 빠른 답변에 감사드립니다. –

+0

첫 번째 버그는 실제로 버그가 아니 었습니다. 웹 사이트에 붙여 넣을 때 실수로 1을 0으로 변경했을뿐입니다. 내가 바보라고 생각하지 않을 것입니다. XD –

+0

은'glVertexAttribPointer()'에서'size'가 잘못되었습니다. 위반 읽기 '오류가 발생 했습니까? – Harish

0

왜 Vertex Attribute 포인터를 두 번째 vbo로 다시 매핑합니까?

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL); 
... 
glVertexAttribPointer(0, 4 * 4, GL_FLOAT, GL_FALSE, 4 * 4 * sizeof(GLfloat), NULL); 

내가 초과 드로우 호출

glDrawArraysInstanced(sphereModel->mode, 0, sphereModel->numVertices, sphereCount); 

참고 두 경우 모두

에서 '0'인덱스를 추측하고 glVertexAttribPointer()

에 대한 추가 정보를 원하시면 https://www.opengl.org/sdk/docs/man/html/glVertexAttribPointer.xhtml 참조 두 번째 VBO의 크기와 따라서 너. 이것은 정점 속성 포인터를 두 번째 VBO로 다시 매핑하려는 의도입니까? 이렇게하면 첫 번째 매핑이 덮어 쓰여집니다. 즉, 첫 번째 VBO가 사용되지 않습니다.

색인 및지도를 저장하여 나중에 이러한 문제가 발생하지 않도록하려면 GLuint attribute1;을 사용하는 것이 좋습니다. 0과 같은 속성 색인에 숫자를 사용하면 쉽게 실수를 할 수 있습니다.

+0

실수로 웹 사이트에 붙여 넣을 때 실수로 1을 0으로 변경했습니다. –