QT OpenGL unable to draw rectangle



  • I am learning QT and QT OpenGL. Based on example for drawing triangle it was implemented a following snippet of code. This code is invoked from class inherited from QOpenGLWindow, so all contexts are initialized. Snippet is tested against Qt 5.10 on MacOS X 10.13.3.

    The issue with that code is, that glDrawElements draws nothing, however if replace it to appropriate call of glDrawArrays I see something drawn on the screen (single triangle).

    I would appreciate it if somebody give me a clue what is wrong with that code, because I can't find a bug.

    #include <QOpenGLFunctions>
    
    #include <QtGui/QMatrix4x4>
    #include <QtGui/QScreen>
    
    float sg_vertices[] = {
         0.5f,  0.5f, 0.0f,  // top right
         0.5f, -0.5f, 0.0f,  // bottom right
        -0.5f, -0.5f, 0.0f,  // bottom left
        -0.5f,  0.5f, 0.0f   // top left
    };
    
    unsigned int sg_indices[] = { 
        0, 1, 3,   // first triangle
        1, 2, 3    // second triangle
    };
    
    void SquareRenderer::Initialize(QOpenGLContext* ctx)
    {
        m_program = std::make_unique<QOpenGLShaderProgram>(ctx);
        m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/shader.vert");
        m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/shader.frag");
        m_program->link();
    
        m_program->bind();
    
        // Create Buffer (Do not release until VAO is created)
        m_vertex = std::make_unique<QOpenGLBuffer>(QOpenGLBuffer::VertexBuffer);
        m_vertex->create();
        m_vertex->bind();
        m_vertex->setUsagePattern(QOpenGLBuffer::StaticDraw);
        m_vertex->allocate(sg_vertices, sizeof(sg_vertices));
    
        m_index = std::make_unique<QOpenGLBuffer>(QOpenGLBuffer::IndexBuffer);
        m_index->create();
        m_index->bind();
        m_index->setUsagePattern(QOpenGLBuffer::StaticDraw);
        m_index->allocate(sg_indices, sizeof(sg_indices));
    
        // Create Vertex Array Object
        m_object = std::make_unique<QOpenGLVertexArrayObject>();
        m_object->create();
        m_object->bind();
        m_program->enableAttributeArray(0);
        m_program->setAttributeBuffer(0, GL_FLOAT, 0, 3);
    
        // Release (unbind) all
        m_object->release();
        m_index->release();
        m_vertex->release();
        m_program->release();
    }
    
    void SquareRenderer::Draw(QOpenGLContext* ctx)
    {
        m_program->bind();
    
        {
            QMatrix4x4 matrix;
            matrix.perspective(120.0f, 2.0f, 0.1f, 100.0f);
            matrix.translate(0, 0, -2);
            matrix.rotate(100.0f * m_frame / ctx->screen()->refreshRate(), 0, 1, 0);
    
            m_program->setUniformValue("matrix", matrix);
        }
    
        {
          m_object->bind();
          ctx->functions()->glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
          m_object->release();
        }
    
        m_program->release();
    
        ++m_frame;
    }
    

    Shaders:

    Vertex:
    #version 330
    layout(location = 0) in vec3 position;
    uniform mat4 matrix;
    
    void main()
    {
      gl_Position = matrix * vec4(position, 1.0);
    }
    
    Fragment:
    #version 330
    out highp vec4 fColor;
    
    void main()
    {
        fColor = vec4(0.f, .8f, 0.f, 1.f);
    }
    
    


  • It seems QOpenGLBuffer assumes different sequence of calls, when used as elements buffer, because next modification (replacement QOpenGLBuffer to OpenGL functions) works as expected:

    void SquareRenderer::Initialize(QOpenGLContext* ctx)
    {
        m_program = std::make_unique<QOpenGLShaderProgram>(ctx);
        m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/shader.vert");
        m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/shader.frag");
        m_program->link();
    
        m_program->bind();
    
        ctx->functions()->glGenBuffers(1, &m_vbo);
        ctx->functions()->glGenBuffers(1, &m_ebo);
        m_object = std::make_unique<QOpenGLVertexArrayObject>();
        m_object->create();
    
        m_object->bind();
        ctx->functions()->glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
        ctx->functions()->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ebo);
    
        m_program->enableAttributeArray(0);
        m_program->setAttributeBuffer(0, GL_FLOAT, 0, 3);
    
        ctx->functions()->glBufferData(GL_ARRAY_BUFFER, sizeof(sg_vertices), sg_vertices, GL_STATIC_DRAW);
        ctx->functions()->glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sg_indices), sg_indices, GL_STATIC_DRAW);
    
        m_object->release();
        ctx->functions()->glBindBuffer(GL_ARRAY_BUFFER, 0);
        ctx->functions()->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    
        m_program->release();
    }
    


  • Well, it seems problem solved. Issue in sequence of buffers creation. Reimplementing the same sequence as in previous message, but using QOpenGLBuffer gave me rotating rectangle on the screen.


  • Qt Champions 2016

    Hi and welcome to the forums :)
    Its not often a poster both post and find the answer himself in such time span.
    Not with openGl at least.
    Good work.


Log in to reply
 

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