Qt OpenGL(QOpenGLWidget)-简单三角形

Qt OpenGL (QOpenGLWidget) - Simple Triangle

本文关键字:简单 三角形 QOpenGLWidget OpenGL Qt      更新时间:2023-10-16

作为使用QOpenGLWidget的QT+OpenGL的新手,我无法为三角形上色。请在这里找到我的代码,使用QMainWindow进行GUI。。。

// main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

这里的GUI窗口

// MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

这里实现-文件。。。

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}
MainWindow::~MainWindow()
{
    delete ui;
}

以下是呈现Opengl Context的小部件。

#ifndef OPENGLWIDGET_H
#define OPENGLWIDGET_H
#include <QWidget>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLContext>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLVertexArrayObject>
#include <QMatrix4x4>
class OpenglWidget : public QOpenGLWidget, public QOpenGLFunctions
{
public:
    OpenglWidget(QWidget *parent = 0);
    ~OpenglWidget();
protected:
    void initializeGL();
    void resizeGL(int width, int height);
    void paintGL();
    GLuint m_posAttr;
    GLuint m_colAttr;
    GLuint m_matrixUniform;
    QOpenGLShaderProgram *m_program;
};
#endif // OPENGLWIDGET_H

这是实现文件。。。

#include "openglwidget.h"

OpenglWidget::OpenglWidget(QWidget *parent) :
    QOpenGLWidget(parent)
{
    setFormat(QSurfaceFormat::defaultFormat());
}
OpenglWidget::~OpenglWidget()
{
}
static const char *vertexShaderSource =
    "attribute highp vec4 posAttr;n"
    "attribute lowp vec4 colAttr;n"
    "varying lowp vec4 col;n"
    "uniform highp mat4 matrix;n"
    "void main() {n"
    "   col = vec4(1, 0, 0, 1);n"
    "   gl_Position = matrix * posAttr;n"
    "}n";
static const char *fragmentShaderSource =
    "varying lowp vec4 col;n"
    "void main() {n"
    "   gl_FragColor = col;n"
    "}n";
void OpenglWidget::initializeGL()
{
    makeCurrent();
    initializeOpenGLFunctions();
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    // Create Shader (Do not release until VAO is created)
    m_program = new QOpenGLShaderProgram(this);
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    m_program->link();
    m_posAttr = m_program->attributeLocation("posAttr");
    m_colAttr = m_program->attributeLocation("colAttr");
    m_matrixUniform = m_program->attributeLocation("matrix");
    m_program->release();
}
void OpenglWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    makeCurrent();
    //m_program->bind();
    QMatrix4x4 matrix;
    matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
    matrix.translate(0, 0, -2);
    m_program->setUniformValue(m_matrixUniform, matrix);
    GLfloat vertices[] = {
        0.0f, 0.707f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    };
    GLfloat colors[] = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f
    };
    glVertexAttribPointer(m_posAttr, 3, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);
    m_program->release();
}
void OpenglWidget::resizeGL(int width, int height)
{
    glViewport(0, 0, width, height);
}

这里渲染的三角形只是白色的。我无法理解着色器是否已编译,属性是否已链接,但仍然无法为三角形着色。

如果我能得到任何指导???输出

让我们看看你的着色器是怎么做的。你的碎片着色器:

varying lowp vec4 col;
[...]
   gl_FragColor = col;

因此,它将获得每个顶点的col输出,为基元中的每个片段进行插值,并将其用作最终颜色。

现在你的顶点着色器:

   col = vec4(1, 0, 0, 1);

这显然是红色。事实上,您添加了一些colAttr输入属性,并为此指定了一些顶点数组,只要您没有实际使用该属性,这是完全无关的——目前,它是一个刚刚优化的非活动属性,因为它从未影响任何输出。

更新

如果得到一个白色三角形,则表示根本没有使用着色器。在paintGL方法中有一个mprogram->release()调用,但您从未真正启用程序,因此不会使用它。

也许你可以使用

m_colAttr = m_program->attributeLocation("col");

而不是

m_colAttr = m_program->attributeLocation("colAttr"); 

如果在着色器中写入

gl_FragColor = col;

col=col,colAttr!=col

更改属性的名称,如果这对更改initializeGL 中的调用没有帮助

program->release(); 

program->bind();