Search code examples
c++qtopengl

QOpenGLWidget Won't Draw Triangle


So I'm trying to implement an editor for my game using Qt, and I can't seem to decipher how the QOpenGLWidget works. Right now, I just want to get a simple triangle to render, then I can worry about moving in all the rest of my stuff.

Right now, it will open the window, and, in the QOpenGLWidget, will clear to the custom color I set in the subclass (so I did promote it), but it won't draw the triangle described in the class below. I've tried following the Qt OpenGLWindow example as well as the examples in QOpenGLWidget and QOpenGLShaderProgram, I also checked every function that returns a bool to make sure they were all being executed properly, and they are, but still no triangle.

Did I miss a vital function call? Am I doing things in the absolute wrong way? Or is it something super subtle and strange with Qt?

Here's the header:

#include<qopenglwidget.h>
#include<QtGui/qopenglfunctions.h>

class EditorViewWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    EditorViewWidget(QWidget *parent);
protected:
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();
    QOpenGLShaderProgram* shaderProgram;
    QOpenGLVertexArrayObject vao;
    QOpenGLBuffer VBO;
    int position_attribute;
    int color_uniform;
    float Vertices[9];
    const char* vert="#version 150          \n"
"                                           \n"
"   in vec3 position;                       \n"
"                                           \n"
"   void main()                             \n"
"   {                                       \n"
"       gl_Position = vec4(position, 1.0);  \n"
"   }";
    const char* frag="#version 150          \n"
"                                           \n"
"   uniform vec3 Color;                     \n"
"   out vec4 outColor;                      \n"
"                                           \n"
"   void main()                             \n"
"   {                                       \n"
"       outColor = vec4(Color, 1.0);        \n"
"   }";
};

and the source:

EditorViewWidget::EditorViewWidget(QWidget* parent)
    :QOpenGLWidget(parent)
{
    float v[] = {
        0.0, 0.5, 0.0,
        0.5, -0.5, 0.0,
        -0.5, -0.5, 0.0
    };
    for (int i = 0; i < 9; i++)
        Vertices[i] = v[i];
}

void EditorViewWidget::initializeGL()
{
    initializeOpenGLFunctions();
    vao.create();
    vao.bind();

    //glGenBuffers(1, &VBO);
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    shaderProgram = new QOpenGLShaderProgram(this);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, vert);
    shaderProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, frag);
    shaderProgram->link();
    shaderProgram->bind();
    position_attribute = shaderProgram->attributeLocation("position");
    color_uniform = shaderProgram->uniformLocation("Color");
    VBO.create();
    VBO.bind();
    VBO.allocate(&Vertices, 9*sizeof(float));
    shaderProgram->enableAttributeArray(position_attribute);
    shaderProgram->setAttributeArray(position_attribute, Vertices, 3);
    shaderProgram->setUniformValue(color_uniform, 1.0f, 1.0f, 1.0f);
    //glVertexAttribPointer(position_attribute, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
}

void EditorViewWidget::resizeGL(int w, int h)
{
}

void EditorViewWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);
    VBO.bind();
    VBO.allocate(&Vertices, 9 * sizeof(float));
    shaderProgram->enableAttributeArray(position_attribute);
    shaderProgram->setAttributeArray(position_attribute, Vertices, 3, 0);
    shaderProgram->setUniformValue(color_uniform, 1.0f, 1.0f, 1.0f);
    glDrawArrays(GL_TRIANGLES, 0, 3);
    shaderProgram->disableAttributeArray(position_attribute);
}

Solution

  • You specified the vertices of your triangle in clockwise order. OpenGL expects them in counterclockwise order by default. Switch the 2nd and 3rd vertex and you should see your triangle