How do I render a triangle in QOpenGLWidget?

5nefarious picture 5nefarious · Jul 20, 2015 · Viewed 21.8k times · Source

I'm trying to use OpenGL inside of Qt using QOpenGLWidget, but I am having a hard time finding any relevant examples. I am new to OpenGL, so I am trying to learn how to use it, but the tutorials that I find don't seem to apply particularly well in QOpenGLWidget. Right now, all I want to do is render a triangle to start with.

Here's what I have so far.

Header:

namespace Ui {
class Widget;
}

class Widget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

protected:
    void initializeGL();
    void resizeGL(int, int);
    void paintGL();

private:
    Ui::Widget *ui;
};

Class:

Widget::Widget(QWidget *parent) :
    QOpenGLWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
}

void Widget::initializeGL()
{
    // Set up the rendering context, load shaders and other resources, etc.:
    initializeOpenGLFunctions();
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
}

void Widget::resizeGL(int w, int h)
{
    // Update projection matrix and other size-related settings:
}

void Widget::paintGL()
{
    // Draw the scene:
    glClear(GL_COLOR_BUFFER_BIT);
}

Widget::~Widget()
{
    delete ui;
}

Is there any example I could use to just render a basic triangle? I tried the one from here: https://www.khronos.org/assets/uploads/books/openglr_es_20_programming_guide_sample.pdf, but it threw a lot of errors that I couldn't work out.

I also don't know how OpenGL contexts work in QOpenGLWidget.

*EDIT: So it turns out that the examples were a separate package on my distro (Arch Linux). I was able to install them, and it looks like there is plenty there to get started.

Thanks for your help!

Answer

CroCo picture CroCo · Jul 20, 2015

If you want to use QOpenGLWidget not QGLWidget, then this is the way to do it.

Open Qt Creator and choose Qt Widgets Application. Add Widget and push button as follows

enter image description here

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

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

Now add New Class and name it OGLWidget which should be inherited from QOpenGLWidget

oglwidget.h

#ifndef OGLWIDGET_H
#define OGLWIDGET_H

#include <QWidget>
#include <QOpenGLWidget>
#include <gl/GLU.h>
#include <gl/GL.h>

class OGLWidget : public QOpenGLWidget
{
public:
    OGLWidget(QWidget *parent = 0);
    ~OGLWidget();

protected:
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();
};

#endif // OGLWIDGET_H

oglwidget.cpp

#include "oglwidget.h"

OGLWidget::OGLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{

}

OGLWidget::~OGLWidget()
{

}

void OGLWidget::initializeGL()
{
    glClearColor(0,0,0,1);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHT0);
    glEnable(GL_LIGHTING);
    glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
    glEnable(GL_COLOR_MATERIAL);
}

void OGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBegin(GL_TRIANGLES);
        glColor3f(1.0, 0.0, 0.0);
        glVertex3f(-0.5, -0.5, 0);
        glColor3f(0.0, 1.0, 0.0);
        glVertex3f( 0.5, -0.5, 0);
        glColor3f(0.0, 0.0, 1.0);
        glVertex3f( 0.0,  0.5, 0);
    glEnd();
}

void OGLWidget::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(45, (float)w/h, 0.01, 100.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0,0,5,0,0,0,0,1,0);
}

Now go back to the form and right click on the widget. Select promoted widgets and type in the promoted class name OGLWidget. Hit the add button and then promote. Now click on the background and go to its properties and change windowModality to ApplicationModel.

enter image description here

and this is the result you should get

enter image description here

the .pro file is

#-------------------------------------------------
#
# Project created by QtCreator 2015-07-20T15:15:29
#
#-------------------------------------------------

QT       += core gui opengl

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = test2
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp \
    oglwidget.cpp

HEADERS  += mainwindow.h \
    oglwidget.h

FORMS    += mainwindow.ui