OpenGL混合修复管道和着色器程序(Qt)

OpenGL mix fix pipeline and shader program (Qt)

我正在编写一个旧的代码,它使用固定功能管道,场景有点复杂但工作正常。为了简单起见,我用一个蓝色三角形代替了它:

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();
}

现在我想为场景中的新元素添加着色器,但保留场景中的旧元素,例如这个蓝色三角形。

我读过 here 我可以将两者混合以产生包含第一个 然后 第二个的场景。

因此我想在蓝色三角形后面添加这段代码:

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是一个状态机,你需要link在一起:VBO和如何读取它的数据,在VAO里面。然而,恕我直言,Qt 人遗憾地选择了他们的抽象:enableAttributeArray 和 setAttributeBuffer 作为 VAOclass 的成员而不是 prog class.

的成员会更清楚