繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM