Qt OpenGL (QOpenGLWidget) - Simple Triangle



  • 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... ???

    Output





  • here I updated the code as per your suggestion ...

    #include "openglwidget.h"
    
    
    OpenglWidget::OpenglWidget(QWidget *parent) :
        QOpenGLWidget(parent)
    {
        setFormat(QSurfaceFormat::defaultFormat());
    }
    
    OpenglWidget::~OpenglWidget()
    {
    }
    
    static const char *vertexShaderSource =
        "attribute highp vec3 posAttr;\n"
        "attribute lowp vec3 colAttr;\n"
        "varying lowp vec4 col;\n"
        "uniform highp mat4 matrix;\n"
        "void main() {\n"
        "   gl_Position = matrix * vec4(posAttr, 1.0);\n"
        "   col = vec4(colAttr, 1.0);\n"
        "}\n";
    
    static const char *fragmentShaderSource =
        "varying lowp vec4 col;\n"
        "out vec4 fragcol;\n"
        "void main() {\n"
        "   //gl_FragColor = col;\n"
        "   fragcol = 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.5f, 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();
    }
    

    still having the same problem of white Triangle. Here In the above code, I had commented the

    //m_program->bind();
    

    If I un-comment it, then triangle doesn't even render.
    Is there any way to upload the screen-shot.



  • @saket

    whats the openGL version ? You can get with this
    glGetString(GL_VERSION) &also glGetString(GL_SHADING_LANGUAGE_VERSION)

    Qt needs OpenGL version 3.1 or newer. check here.

    Edit:
    Did you try OpenGL window example from the Qt examples. If you are using the Qt Creator, click on the "Welcome" button and check for "openGL window example". Test the example, still you get the triangle in white color?



  • GL Version:  3.1.0 - Build 9.17.10.3223
    GLSL Version:  1.40 - Intel Build 9.17.10.3223
    

    Yeah I tried inheriting QOpenGLFunction with QWindow and it's working fine with colors assigned to vertices (R,G,B).


  • Moderators

    @saket said:

    Is there any way to upload the screen-shot

    You can upload it to https://postimage.org and then embed it here with ![alternate text](image url).



  • Thanks Wieland!

    Any one, can help me on this???



  • @saket
    I think the driver of your graphics card isn't able to understand the GLSL command. As i see you're using an Intel Graphics Card, i had a lot of problems with my GLSL code on several machines with Intel Graphics.

    Try to change the attributes and varying qualifiers:

    static const char *vertexShaderSource =
        "#version 140\n"
        "in vec4 posAttr;\n"
        "in vec4 colAttr;\n"
        "out vec4 col;\n"
        "uniform mat4 matrix;\n"
        "void main() {\n"
        "   col = vec4(1, 0, 0, 1);\n"
        "   gl_Position = matrix * posAttr;\n"
        "}\n";
    
    static const char *fragmentShaderSource =
        "#version 140\n"
        "in vec4 col;\n"
        "out vec4 fragcol;\n"
        "void main() {\n"
        "   //gl_FragColor = col;\n"
        "   fragcol = col;\n"
        "}\n";
    

    And try to get the Info from the shader after compilation (https://www.opengl.org/wiki/Shader_Compilation#Shader_error_handling)

    GLuint shader = glCreateShader(...);
    
    // Get strings for glShaderSource.
    glShaderSource(shader, ...);
    
    glCompileShader(shader);
    
    GLint isCompiled = 0;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &isCompiled);
    if(isCompiled == GL_FALSE)
    {
    	GLint maxLength = 0;
    	glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &maxLength);
    
    	// The maxLength includes the NULL character
    	std::vector<GLchar> errorLog(maxLength);
    	glGetShaderInfoLog(shader, maxLength, &maxLength, &errorLog[0]);
    
    	// Provide the infolog in whatever manor you deem best.
    	// Exit with failure.
    	glDeleteShader(shader); // Don't leak the shader.
    	return;
    }
    
    // Shader compilation is successful.
    


Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.