Can't render triangle with opengl



  • I'm trying to make a simple intro opengl application that renders a triangle to the screen. Currently I have nothing drawing to the screen and no errors are being thrown with glGetError(). I've been working on this for several hours and I am not sure what the issue is. The window and background are created but no triangle. Here is my code.

    Header File:

    #ifndef OGLWIDGET_H
    #define OGLWIDGET_H

    #include <QWidget>
    #include <QOpenGLWidget>
    #include <QtGui/QOpenGLShaderProgram>
    #include <QtGui/QOpenGLBuffer>
    #include <QtGui/QOpenGLFunctions>
    #include <QtGui/QOpenGLContext>
    #include <QtGui/QOpenGLVertexArrayObject>
    #include <QtGui/QGuiApplication>
    #include <QtGui/QOpenGLExtraFunctions>
    class OGLWidget: public QOpenGLWidget, protected QOpenGLExtraFunctions
    {
    public:
    OGLWidget(QWidget* parent = 0);
    ~OGLWidget();
    void paintGL() override;
    void initializeGL() override;
    void resizeGL(int width, int height) override;

    protected:
    QOpenGLVertexArrayObject* m_vao;
    QOpenGLBuffer* m_vbo;
    QOpenGLShaderProgram* shader;

    GLint m_posAttr;
    GLint m_colAttr;
    GLint m_matrixUni;
    

    };

    #endif // OGLWIDGET_H

    Implementation file:

    #include "oglwidget.h"

    static const char* vertexSource =
    "#version 150\n"
    "in vec2 posAttr;\n"
    "in vec3 colAttr;\n"
    "out vec3 Color;\n"
    "void main() {\n"
    " Color = colAttr;\n"
    " gl_Position = vec4(posAttr, 0.0, 1.0);\n"
    "}\n";

    static const char* fragSource =
    "#version 150\n"
    "in vec3 Color;\n"
    "out vec4 outColor;\n"
    "void main() {\n"
    " outColor = vec4(Color, 1.0);\n"
    "}\n";

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

    }
    OGLWidget::~OGLWidget()
    {

    }

    void OGLWidget::initializeGL()
    {
    makeCurrent();
    initializeOpenGLFunctions();
    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    f->glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    shader = new QOpenGLShaderProgram(this);
    shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexSource);
    shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragSource);
    shader->link();
    m_posAttr = shader->attributeLocation("posAttr");
    m_colAttr = shader->attributeLocation("colAttr");
    //m_matrixUni = shader->attributeLocation("matrix");
    shader->release();
    

    }
    void OGLWidget::paintGL()
    {
    initializeOpenGLFunctions();

    QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
    f->glClear(GL_COLOR_BUFFER_BIT);
    makeCurrent();
    
    shader->bind();
    
    GLfloat colors[] = {
            1.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 1.0f
        };
    
    
    GLfloat vertices[] = {
            0.0f, 0.707f,
            -0.5f, -0.5f,
            0.5f, -0.5f
        };
    
    
    m_vao = new QOpenGLVertexArrayObject();
    m_vao->create();
    
    if(m_vao->isCreated())
    {
        m_vao->bind();
    }
    
    m_vbo = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
    m_vbo->create();
    m_vbo->bind();
    m_vbo->allocate(vertices, sizeof(vertices));
    m_vbo->setUsagePattern(QOpenGLBuffer::StaticDraw);
    
    glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 0, vertices);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 0, colors);
    glEnableVertexAttribArray(m_posAttr);
    glEnableVertexAttribArray(m_colAttr);
    
    glDrawArrays(GL_TRIANGLES, 0, 3);
    
    
    shader->disableAttributeArray(m_colAttr);
    shader->disableAttributeArray(m_posAttr);
    shader->release();
    

    }

    void OGLWidget::resizeGL(int width, int height)
    {
    glViewport(0, 0, width, height);
    }


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Did you first took a look at the OpenGL Window example ?

    It will be easier to get you started and and modifying it to use QOpenGLWidget is pretty straightforward.



  • @SGaist That was one of the first resources I looked at. A lot of my project is modeled off of that one. I've been attempting to do it with QOpenGLWidget rather than QOpenGLWindow.


  • Lifetime Qt Champion

    Can you provide a complete minimal example that can be tested ? This will ensure that we are looking at the same stuff.



  • The issue ended up being with my opengl code. I'll go into detail for people who might be having the same issue. I combined the vertices and color arrays into one and changed some of the values like so :

    GLfloat vertices[] = {
            0.0f, 0.5f, 1.0f, 0.0f, 0.0f,
            0.5f, -0.5f, 0.0f, 1.0f, 0.0f,
            -0.5f, -0.5f, 0.0f, 0.0f, 1.0f
        };
    

    I removed the vao as it is unnecessary for this example. I moved the attributeLocation() calls and I then updated my attribute information to represent the single array containing the vertex and color attributes. I think one of the main issues was improper input values for the glVertexAttribPointer() calls. More specifically the last two for stride and pointer. I had my stride set to "0" for both when it should have been the number of attribute values per vertex. The pointer for the vertex attribute should have been "0" for the index it will begin in the array. For the color attribute I changed it so it tells it to skip the first two attribute values and start where the color attributes values begin for each vertex. The Below is what changed:

    m_posAttr = shader->attributeLocation("posAttr");
    glEnableVertexAttribArray(m_posAttr);
    glVertexAttribPointer(m_posAttr, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), 0);
    
    m_colAttr = shader->attributeLocation("colAttr");
    glEnableVertexAttribArray(m_colAttr);
    glVertexAttribPointer(m_colAttr, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(2*sizeof(float)));
    
    glDrawArrays(GL_TRIANGLES, 0, 3);
    
    shader->disableAttributeArray(m_colAttr);
    shader->disableAttributeArray(m_posAttr);
    

    There was also a coloring problem after I got it to render. It turns out that I was using an inappropriate version of qt's equivalent of glUseProgram. I was using shader->release() in initializeGL() when I should have been using shader->bind(). I had a
    shader->bind() call in paintGL() so I moved it into initializeGL() in its place.

    shader = new QOpenGLShaderProgram(this);
    shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexSource);
    shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragSource;
    shader->link();
    shader->bind();

  • Lifetime Qt Champion

    Thanks for the detailed feedback !


Log in to reply
 

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