2013-11-02 60 views
2

从VBO/VAO的正常绘图切换到VBO/VAO的实例化阵列后,我有麻烦从我的OpenGL应用程序获取正确的输出。输出应该是一堆球体,但它是疯狂定位的顶点形成奇怪的三角形。我已经检查了调试器控制台中的顶点位置,但似乎没有任何可疑的东西。他们都在从-10到10的范围内,而在现场他们可能会+/- 30。OpenGL实例化阵列奇怪的顶点位置

以下是我的代码的重要部分。请告诉我,如果我没有看到什么。我将不胜感激!

char const *attribInSphereModelMatrix = "inSphereModelMatrix"; 
std::vector<glm::mat4> dNodesModelMatrices; 

... 

attributes[ATTRIB_SPHERE_MODEL_COLUMN0] = shader->getAttribLocation(attribInSphereModelMatrix); 
attributes[ATTRIB_SPHERE_MODEL_COLUMN1] = attributes[ATTRIB_SPHERE_MODEL_COLUMN0] + 1; 
attributes[ATTRIB_SPHERE_MODEL_COLUMN2] = attributes[ATTRIB_SPHERE_MODEL_COLUMN0] + 2; 
attributes[ATTRIB_SPHERE_MODEL_COLUMN3] = attributes[ATTRIB_SPHERE_MODEL_COLUMN0] + 3; 

... 

// Create the vertex array object 
glGenVertexArrays(1, &sphereVertexArray); 
glBindVertexArray(sphereVertexArray); 

// Create the buffer object to hold the sphere view matrix 
glGenBuffers(1, &sphereModelMatrixBuffer); 
glBindBuffer(GL_ARRAY_BUFFER, sphereModelMatrixBuffer); 
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::mat4) * dNodes.size(), &dNodesModelMatrices[0], GL_STATIC_DRAW); 

// All matrix data is in one VBO, set the appropriate offsets 
glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN0]); 
glVertexAttribPointer(attributes[ATTRIB_SPHERE_MODEL_COLUMN0], 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), NULL); 
glVertexAttribDivisorARB(attributes[ATTRIB_SPHERE_MODEL_COLUMN0], 1); 

glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN1]); 
glVertexAttribPointer(attributes[ATTRIB_SPHERE_MODEL_COLUMN1], 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const GLvoid *)(sizeof(glm::vec4))); 
glVertexAttribDivisorARB(attributes[ATTRIB_SPHERE_MODEL_COLUMN1], 1); 

glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN2]); 
glVertexAttribPointer(attributes[ATTRIB_SPHERE_MODEL_COLUMN2], 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const GLvoid *)(2 * sizeof(glm::vec4))); 
glVertexAttribDivisorARB(attributes[ATTRIB_SPHERE_MODEL_COLUMN2], 1); 

glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN3]); 
glVertexAttribPointer(attributes[ATTRIB_SPHERE_MODEL_COLUMN3], 4, GL_FLOAT, GL_FALSE, sizeof(glm::mat4), (const GLvoid *)(3 * sizeof(glm::vec4))); 
glVertexAttribDivisorARB(attributes[ATTRIB_SPHERE_MODEL_COLUMN3], 1); 

一旦我准备好了设置,我就去绘图了。

glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN0]); 
glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN1]); 
glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN2]); 
glEnableVertexAttribArray(attributes[ATTRIB_SPHERE_MODEL_COLUMN3]); 

... 

glDrawElementsInstanced(GL_TRIANGLES, numSphereTris, GL_UNSIGNED_INT, NULL, (int)dNodes.size()); 

这里是顶点着色器的重要组成部分:

in mat4 inSphereModelMatrix; 

... 

void main() 
{ 
    vec4 v = vec4(inPosition, 1.0); 
    mat4 modelViewMatrix = viewMatrix * inSphereModelMatrix; 

    ... 

    gl_Position = projectionMatrix * modelViewMatrix * v; 
} 

结果看起来是这样的:

end result

请帮我弄好了。过去3天我一直在为此而苦苦挣扎。谢谢你们!

编辑:我一直在想,如果它与列/行主要顺序有关,

回答

2

我懂了!我曾尝试在着色器中使用纹理缓冲区对象和gl_InstanceID来实际获取矩阵列,并且它工作正常!我无法相信与我以前做过的工作相当的东西不应该如何工作,并且使用纹理缓冲区对象(TBOs)的作品......但是,我将发布代码的重要部分以备将来参考。

/// A texture buffer object to pass to the shaders 
GLuint sphereModelMatrixTBO; 

/// A texture holding the matrices data 
GLuint sphereModelMatrixTex; 
. 
. 
. 
/// Vector containing the model matrices of the spheres 
std::vector<glm::mat4> dNodesModelMatrices; 
. 
. 
. 
glGenBuffers(1, &sphereModelMatrixTBO); 
glBindBuffer(GL_TEXTURE_BUFFER, sphereModelMatrixTBO); 
glBufferData(GL_TEXTURE_BUFFER, sizeof(glm::mat4) * dNodes.size(), &dNodesModelMatrices[0], GL_STATIC_DRAW); 

而在抽签程序我做了以下内容:现在

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_BUFFER, sphereModelMatrixTex); 
glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, sphereModelMatrixTBO); 

glUniform1i(uniforms[UNIFORM_MODEL_MATRIX_BUFFER], 0); 
. 
. 
. 
glDrawElementsInstanced(GL_TRIANGLES, numSphereTris, GL_UNSIGNED_INT, NULL, (int)dNodes.size()); 

顶点着色器看起来如下:

uniform samplerBuffer sphereModelMatrixBuffer; 
. 
. 
. 
vec4 col1 = texelFetch(sphereModelMatrixBuffer, gl_InstanceID * 4); 
vec4 col2 = texelFetch(sphereModelMatrixBuffer, gl_InstanceID * 4 + 1); 
vec4 col3 = texelFetch(sphereModelMatrixBuffer, gl_InstanceID * 4 + 2); 
vec4 col4 = texelFetch(sphereModelMatrixBuffer, gl_InstanceID * 4 + 3); 
mat4 modelMatrix = mat4(col1, col2, col3, col4); 

而这一切,你需要做的,有一个完全功能快速的OpenGL应用程序!这是怎么看起来像现在:

+0

这工作,但绝对不是最有效的方法。你确定混合和匹配ARB实例渲染扩展与核心不是责备? 'glVertexAttribDivisor(...)'是适合与'glDrawElementsInstanced(...)'匹配的调用。 –

+0

就效率而言,我在2013版红皮书中看到,两种方法在速度上都是相同的。我仍然不确定第一个结果的确切原因是什么。这可能是你的建议。而在性能方面,你还会建议如何加速这个过程?谢谢! –