Qt OpenGL(QOpenGLWidget) - 简单三角形

时间:2016-07-31 14:37:01

标签: c++ qt opengl opengl-es

作为使用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);
}

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

如果我能得到任何指导...... ??? Output

2 个答案:

答案 0 :(得分:0)

让我们看一下着色器的功能。片段着色器:

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

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

现在你的顶点着色器:

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

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

<强>更新

如果你得到一个白色三角形,这表明你的着色器根本就没用过。您的mprogram->release()方法中有一个paintGL来电,但您实际上从未启用该程序,因此不会被使用。

答案 1 :(得分:0)

也许你可以使用

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

而不是

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

如果你用着色器写

gl_FragColor = col;

col = col,colAttr!= col

更改属性名称,如果这无助于在initializeGL中更改此调用

program->release(); 

program->bind();