[英]OpenGL mix fix pipeline and shader program (Qt)
我正在处理使用固定 function 管道的旧代码,场景有点复杂但工作正常。 为简单起见,我将其替换为一个蓝色三角形:
void RenduOpenGL::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glViewport(0, 0, this->width(), this->height());
glBegin(GL_TRIANGLES);
glColor3d(0,0,1);
glVertex3d(0.7, 0.7, 0.0);
glVertex3d(-0.5, 0.7, 0.0);
glVertex3d(0.1, -0.7, 0.0);
glEnd();
}
现在我想为场景中的新元素添加着色器,但保留场景中的旧元素,就像这个蓝色三角形一样。
我在这里读过,我可以将两者混合以产生一个包含第一个然后是第二个的场景。
因此,我想在蓝色三角形之后添加此代码:
float vertices[] = {
0.6, 0.6, 0.0,
-0.6, 0.6, 0.0,
0.0, -0.6, 0.0,
};
vbo.create(); // glGenBuffers(...);
vbo.bind(); // glBindBuffer(GL_ARRAY_BUFFER, vbo);
vbo.allocate(vertices, sizeof(vertices)); // glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), vertices, GL_STATIC_DRAW);
vbo.release(); // glBindBuffer(GL_ARRAY_BUFFER, 0);
prog.addShaderFromSourceFile(QOpenGLShader::Vertex, "shaders/base.vert");
prog.addShaderFromSourceFile(QOpenGLShader::Fragment, "shaders/base.frag");
vao.create(); // glGenVertexArrays(...)
vao.bind(); // glBindVertexArray(vao);
prog.enableAttributeArray("position"); // glEnableVertexAttribArray(VAO_position);
prog.setAttributeBuffer("position", GL_FLOAT, 0, 3); // (offset, size, stride=0); // glVertexAttribPointer(VAO_position, 4, GL_FLOAT, False, 0, reinterpret_cast<const void *>(offset)(0)); (False,
vao.release(); // glBindVertexArray(0);
// draw the triangle
prog.bind(); // glUseProgram(shader_program);
vao.bind(); // glBindVertexArray(vertex_array_object);
glDrawArrays(GL_TRIANGLES, 0, 3);
vao.release(); // glBindVertexArray(0);
prog.release(); // glUseProgram(0);
我使用Qt调用openGL函数,对应的opengl函数在注释中。
我的着色器非常基础:
// base.vert
#version 330
// vertex shader
in vec3 position;
void main() {
gl_Position = vec4(position.xyz, 1);
}
// base.frag
#version 330
// fragment shader
out vec4 pixel;
void main() {
pixel = vec4(1, 0.5, 0, 1);
}
那应该绘制一个橙色三角形,但是当我将代码放在蓝色三角形代码之后时,我看不到由着色器创建的橙色三角形。
简短(带代码)答案:VBO 和 prog.enableAttributeArray 和 prog.setAttributeBuffer 应该在 VAO 中。
类似的东西:
float vertices[] = {
0.6, 0.6, 0.0,
-0.6, 0.6, 0.0,
0.0, -0.6, 0.0,
};
prog.bind(); // glUseProgram(shader_program);
vao.create(); // glGenVertexArrays(...)
vao.bind(); // glBindVertexArray(vao);
vbo.create(); // glGenBuffers(...);
vbo.bind(); // glBindBuffer(GL_ARRAY_BUFFER, vbo);
vbo.allocate(vertices, sizeof(vertices)); // glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), vertices, GL_STATIC_DRAW);
//vbo.release(); // glBindBuffer(GL_ARRAY_BUFFER, 0);
prog.addShaderFromSourceFile(QOpenGLShader::Vertex, "shaders/base.vert");
prog.addShaderFromSourceFile(QOpenGLShader::Fragment, "shaders/base.frag");
prog.enableAttributeArray("position"); // glEnableVertexAttribArray(VAO_position);
prog.setAttributeBuffer("position", GL_FLOAT, 0, 3); // (offset, size, stride=0); // glVertexAttribPointer(VAO_position, 4, GL_FLOAT, False, 0, reinterpret_cast<const void *>(offset)(0)); (False,
vao.release(); // glBindVertexArray(0);
// draw the triangle
prog.bind(); // glUseProgram(shader_program);
vao.bind(); // glBindVertexArray(vertex_array_object);
glDrawArrays(GL_TRIANGLES, 0, 3);
vao.release(); // glBindVertexArray(0);
prog.release(); // glUseProgram(0);
不是那么长,而是文字答案:OpenGL 是一台 state 机器,您需要链接在一起:VBO 以及如何在 VAO 中读取其数据。 然而,恕我直言,Qt 人们遗憾地选择了他们的抽象很糟糕: enableAttributeArray 和 setAttributeBuffer 作为 VAO 类的成员而不是 prog class 会更清晰。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.