2012-12-15 66 views
2

我想用Qt在OpenGL中绘制一个使用顶点缓冲对象的样板。 这里是我的几何形状:如何在Qt中使用OpenGL中的顶点缓冲对象绘制矩形?

numVertices = 4; 
vertices = new float[3*numVertices]; 
int i = 0; 
vertices[i++] = 0.0f; vertices[i++] = 0.0f; vertices[i++] = 0.0f; // (0,0,0) 
vertices[i++] = 1.0f; vertices[i++] = 0.0f; vertices[i++] = 0.0f; // (1,0,0) 
vertices[i++] = 1.0f; vertices[i++] = 1.0f; vertices[i++] = 0.0f; // (1,1,0) 
vertices[i++] = 0.0f; vertices[i++] = 1.0f; vertices[i++] = 0.0f; // (0,1,0) 
i = 0; 
// spilt quad into two triangles: 
numTriangles = 2; 
indices = new unsigned int[numTriangles*3]; 
indices[i++] = 0; indices[i++] = 1; indices[i++] = 2; 
indices[i++] = 0; indices[i++] = 2; indices[i++] = 3; 

接下来在initializeGL方法:

QGLBuffer vertexBuffer; 
vertexBuffer.create(); 
vertexBuffer.bind(); 
vertexBuffer.allocate(vertices, numVertices*sizeof(float)); 

QGLShaderProgram* shaderProgram_ = new QGLShaderProgram; 
shaderProgram_->addShaderFromSourceFile(QGLShader::Vertex,"C:/src/light.vert.glsl")) { 
shaderProgram_->addShaderFromSourceFile(QGLShader::Fragment, "C:/src/light.frag.glsl"); 
bool ok = shaderProgram_->link(); 
ok = shaderProgram_->bind(); 

我认为所有的VBO部分确实是顶点复制到GPU? (为什么这么多行?)

着色器部分适用于旧样式glBegin(GL_QUADS);

下一页我paintGL方法:

shaderProgram_->setAttributeBuffer("vertex", GL_FLOAT, 0, 3, 0); 
shaderProgram_->enableAttributeArray("vertex"); 
glDrawElements(GL_TRIANGLES, numTriangles, GL_UNSIGNED_INT, indices); 

什么是两个第一线做什么?也许告诉着色器,有一个名为GL_FLOAT类型的“顶点”的顶点缓冲区? 但是我在创建VBO时没有指定任何名称!? OpenGL如何知道这是“顶点”?

无论如何,我没有任何东西! 有没有我失踪的步骤? 我的着色器是简单的通槽:

# version 120 
varying vec4 color; 
void main() { 
    vec4 vertex = gl_Vertex; 
    // pass trough: 
    gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vertex; 
    color = gl_Color; 
} 

# version 120 
varying vec4 color; 
void main (void) 
{ 
    // pass-trough:  
gl_FragColor = color; 
} 

回答

2

我猜你在这里失去了3:

vertexBuffer.allocate(vertices, numVertices*sizeof(float)); 

- >

vertexBuffer.allocate(vertices, numVertices*sizeof(float)*3); 

我认为所有的VBO部分确实是将顶点复制到GPU? (为什么这么多 行?)

是的。这就是OpenGL的工作原理。要在VBO中存储一些东西,你必须创建它,绑定它并复制数据。

这两条第一行是干什么的?也许告诉着色器 有一个名为GL_FLOAT类型的“顶点”的顶点缓冲区?但是,我在创建VBO时没有指定任何名称! OpenGL如何知道 这是“顶点”?

第一行:

QGLShaderProgram::setAttributeBuffer()“设置顶点值对这个着色器程序称为名称,起始于一个特定的在当前绑定的顶点缓冲器偏移属性的数组”。 - 从手册。再次,这就是OpenGL的工作原理。这是一台状态机。您将特定缓冲区绑定到GL_ARRAY_BUFFER绑定点,然后告诉OpenGL这是存储“顶点”属性数据的缓冲区。 “顶点”是您在着色器程序中使用的属性名称。 (可能是你应该把它改为“gl_Vertex”)猜测,Qt调用glVertexAttribLocation()找到你的属性的位置,然后调用glVertexAttribPointer()

下联:

的OpenGL必须知道它应该从一些缓冲的数据复制到一些特殊的地方,着色器程序可以找到它。这是通过为特定位置启用属性数组来完成的。猜猜,Qt在这里调用glVertexAttribLocation()glEnableAttribArray()

BTW: 你指定你的代码中的任何模型视图和投影矩阵?我不确定它们是否默认设置。尝试去除这些值形式着色器出于测试目的。

补充:

glDrawElements(GL_TRIANGLES, numTriangles, GL_UNSIGNED_INT, indices); 

第二个参数不是三角形,但指数的数的数量,将从指数阵列读取。这里应该是numTriangles*3

+0

谢谢奥列格!但我仍然没有选择任何矩形。我认为我的模型视图和投影很好。如果我添加一个glutSolidTeapot(2.0f);调用我的paintGL方法,这显示得很好。 – Andy

+0

@Andy我在'glDrawElements()'调用中发现了另一个错误。在主帖中看到它。 –

1

我知道这是一个老问题,但作为opengl初学者,我发现非常有用this QT使用VBO和OpenGL ES绘制立方体的示例。我基本上注释掉了代码行,它们在顶点和索引数组中创建了其他5个面,并在相应的glBufferData调用中修正了顶点和索引的数量,就是这样。

QT有很多有据可查的例子,所以随时检查它们

相关问题