OpenGL:多种渲染方法.何时使用哪个



我是OpenGL的新手,我正在学习多个教程,我注意到有多种方法用于渲染对象,但我仍然不明白它们之间的区别以及何时使用它们中的每一个?

例如。。我遵循这个使用着色器渲染立方体的示例,当我尝试使用"正常"方式渲染它时 - 如果这是一个正确的表达式。没有渲染任何内容。我总是需要打电话给shaderProgram.setAttributeArray()shaderProgram.enableAttributeArray()shaderProgram.disableAttributeArray()

但是,如果我尝试使用另一种方式直接渲染它 - 再次,如果这是一个正确的表达式 - 使用 glBegin()glEnd(). 没有任何效果

另外,我

还有另一个问题着色器概念本身,我真的不知道什么时候应该使用它,什么时候不应该使用它

这是我的例子:

#include "glwidget.h"
GlWidget::GlWidget(QWidget *parent)
    : QGLWidget(QGLFormat(/* Additional format options */), parent)
{
    alpha = 25;
    beta = -25;
    distance = 2.5;
}
void GlWidget::initializeGL()
{
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    qglClearColor(QColor(Qt::white));
    shaderProgram.addShaderFromSourceFile(QGLShader::Vertex, ":/vertexShader.vsh");
    shaderProgram.addShaderFromSourceFile(QGLShader::Fragment, ":/fragmentShader.fsh");
    shaderProgram.link();
    vertices << QVector3D(-0.5, -0.5,  0.5) << QVector3D( 0.5, -0.5,  0.5) << QVector3D( 0.5,  0.5,  0.5) // Front
             << QVector3D( 0.5,  0.5,  0.5) << QVector3D(-0.5,  0.5,  0.5) << QVector3D(-0.5, -0.5,  0.5)
             << QVector3D( 0.5, -0.5, -0.5) << QVector3D(-0.5, -0.5, -0.5) << QVector3D(-0.5,  0.5, -0.5) // Back
             << QVector3D(-0.5,  0.5, -0.5) << QVector3D( 0.5,  0.5, -0.5) << QVector3D( 0.5, -0.5, -0.5)
             << QVector3D(-0.5, -0.5, -0.5) << QVector3D(-0.5, -0.5,  0.5) << QVector3D(-0.5,  0.5,  0.5) // Left
             << QVector3D(-0.5,  0.5,  0.5) << QVector3D(-0.5,  0.5, -0.5) << QVector3D(-0.5, -0.5, -0.5)
             << QVector3D( 0.5, -0.5,  0.5) << QVector3D( 0.5, -0.5, -0.5) << QVector3D( 0.5,  0.5, -0.5) // Right
             << QVector3D( 0.5,  0.5, -0.5) << QVector3D( 0.5,  0.5,  0.5) << QVector3D( 0.5, -0.5,  0.5)
             << QVector3D(-0.5,  0.5,  0.5) << QVector3D( 0.5,  0.5,  0.5) << QVector3D( 0.5,  0.5, -0.5) // Top
             << QVector3D( 0.5,  0.5, -0.5) << QVector3D(-0.5,  0.5, -0.5) << QVector3D(-0.5,  0.5,  0.5)
             << QVector3D(-0.5, -0.5, -0.5) << QVector3D( 0.5, -0.5, -0.5) << QVector3D( 0.5, -0.5,  0.5) // Bottom
             << QVector3D( 0.5, -0.5,  0.5) << QVector3D(-0.5, -0.5,  0.5) << QVector3D(-0.5, -0.5, -0.5);
}
void GlWidget::resizeGL(int width, int height)
{
    if (height == 0) {
        height = 1;
    }
    pMatrix.setToIdentity();
    pMatrix.perspective(60.0, (float) width / (float) height, 0.001, 1000);
    glViewport(0, 0, width, height);
}
void GlWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    QMatrix4x4 mMatrix;
    QMatrix4x4 vMatrix;
    QMatrix4x4 cameraTransformation;
    cameraTransformation.rotate(alpha, 0, 1, 0);
    cameraTransformation.rotate(beta, 1, 0, 0);
    QVector3D cameraPosition = cameraTransformation * QVector3D(0, 0, distance);
    QVector3D cameraUpDirection = cameraTransformation * QVector3D(0, 1, 0);
    vMatrix.lookAt(cameraPosition, QVector3D(0, 0, 0), cameraUpDirection);
    shaderProgram.bind();
    shaderProgram.setUniformValue("mvpMatrix", pMatrix * vMatrix * mMatrix);
    // This code is able to draw the cube
    shaderProgram.setAttributeArray("vertex", vertices.constData());
    shaderProgram.enableAttributeArray("vertex");
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());
    shaderProgram.disableAttributeArray("vertex");
    // end
    // This code is never able to draw the cube or anything
    glBegin(GL_TRIANGLES);
    for (int var = 0; var < vertices.size(); ++var) {
        glVertex3f(vertices[var][0],vertices[var][1],vertices[var][2]);
    }
    glEnd();
    // end
    shaderProgram.release();
}

OpenGL曾经有所谓的"即时模式"。在其中,您将使用glBegin()glEnd(),并在它们之间逐点指定数据(点、法线、纹理坐标)。你会在每一帧上都这样做,所以显然这很慢。此功能早已不推荐使用,但大多数显卡驱动程序仍然支持它,以免破坏现有软件。但是,如果你想学习现代OpenGL,我会忽略任何glBegin()的教程。今天,您将一次性将数据传输到GPU(进入称为顶点缓冲区对象的东西),然后使用一个命令(使用顶点数组对象)进行绘制

你的另一个问题是关于着色器的。同样,在过去,OpenGL曾经有一个固定函数的管道。这意味着您只提供顶点(正常,...)数据,显卡继续并完成它的工作。您无法修改它对数据执行的操作。在现代世界中,管道的某些部分是可编程的,这意味着您可以更改管道的某些部分的功能(通过提供自己的程序 - 着色器)。这非常有用,因为有许多效果是无法实现的。同样,如果您不提供自己的着色器,出于兼容性原因,显卡将主要回退到默认实现中。但是你绝对应该编写自己的着色器(基本的着色器只有几行)。

总而言之,如果你开始学习现代OpenGL

(VBO,VAO,着色器),可能需要更长的时间才能完成基础知识,但如果你开始学习遗留的东西,有一天你将不得不离开它,从头开始学习现代OpenGL。

编辑:混合现代和遗留代码通常不是一个好主意。你可能会让它工作,但它不值得痛苦。

最新更新