PDA

View Full Version : Qt OpenGL (QOpenGLWidget) - Simple Triangle



saket
31st July 2016, 17:13
As a newbee to QT+OpenGL using QOpenGLWidget, I am unable to color my triangle. Please find my code here, using QMainWindow for 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();
}


Here the GUI - window


// 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

Here implementation - file ...


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

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

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


Here is the widget rendering 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

Here is the implementation file ...


#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);
}

Here the rendered triangle is just white. I am unable to understand whether the shader is compiled and attributes are linked but still, I am unable to color the triangle.

If I can get any guidance... ?

12049

d_stranz
1st August 2016, 17:28
In line 43 of the "implementation file", you release() the shader program. Why? And you've commented out the call the bind(). Why? In line 83, you again release() the shader program (although that call does nothing since you never bind the shader to the rendering pipeline in the first place.

I think you should study the Cube example program (http://doc.qt.io/qt-5/qtopengl-cube-example.html).