Why my triangle is centered (Using QOpenGLWidget, basic stuff)

  • I was learning OpenGL, made some basics triangles on visual studio with GLFW and everything worked nice.
    Now I want to try out Qt with OpenGL and encountered strange thing with vertices coordinates.

    I made a simple working example of my VS & GLFW code in Qt with QOpenGLWidget, but result is other. It looks like my Y coordinate gets normalized to 0.0f instead of 1.0f.

    I dont understand why this is happens. Coordinates on X axis works as they should.

    My code:

    int main(int argc, char *argv[])
        QApplication a(argc, argv);
        QSurfaceFormat format;
        SimpleRender render(format);
        return a.exec();
    SimpleRender::SimpleRender(const QSurfaceFormat& format, QWidget* parent) : QOpenGLWidget(parent),
    void SimpleRender::initializeGL()
        qDebug() << "OpenGL format major version =" <<context()->format().majorVersion() << "\n";
        glFun = context()->versionFunctions<QOpenGLFunctions_3_3_Core>();
        QVector<GLfloat> vertices = {
            -1.0f, -1.0f, 0.0f,
            1.0f, -1.0f, 0.0f,
            0.0f, 1.0f, 0.0f
        QOpenGLShader vertexShader(QOpenGLShader::Vertex, this);
        QOpenGLShader fragmentShader(QOpenGLShader::Fragment, this);
        QFile vertexShaderFile(":/shaders/vertexshader.vsh");
        if (!vertexShaderFile.exists())
            qDebug() << "Vertex shader file not found\n";
        if (!vertexShader.compileSourceFile(vertexShaderFile.fileName()))
            qDebug() << "Vertex shader compile error\n" << vertexShader.log() << "\n";
        QFile fragmentShaderFile(":/shaders/fragmentshader.fsh");
        if (!fragmentShaderFile.exists())
            qDebug() << "Fragmenth shader file not found\n";
        if (!fragmentShader.compileSourceFile(fragmentShaderFile.fileName()))
            qDebug() << "Fragment shader compile error\n" << fragmentShader.log() << "\n";
        if (!shaderProgram.link())
            qDebug() << "Shader program link error\n" << shaderProgram.log() << "\n";
        VBO.allocate(&vertices, vertices.count() * sizeof(vertices));
        // normalization is off, so we using plain opengl functions
        glFun->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (GLvoid*)0);
        qDebug() << "size of vertices = " << sizeof(vertices) << "\n";
        qDebug() << "size of GL_FLOAT = " << sizeof(GL_FLOAT) << "\n";
    void SimpleRender::resizeGL(int w, int h)
        glFun->glViewport(0,0, w, h);
        qDebug() << "new width =" << w << "\n";
        qDebug() << "new height =" << h << "\n";
    void SimpleRender::paintGL()
        glFun->glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glFun->glDrawArrays(GL_TRIANGLES, 0, 3);

    I dont get any info from qDebug(), so everything compiles without errors.

  • Hi

    You didnt post your shaders, but from your resizeGL() and paintGL() functions I can see that you didnt define any view or projection matrix.

  • Vertex shaders just fill gl_Position with vertices position without any modifications, and fragment shader just fill out vec4 color.

    I suppose basic triangle should work without any matrix stuff? It worked with GLFW or this is some stuff that depens on platform, not on opengl?

  • I just notice that in this line of code

    glFun->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (GLvoid*)0);

    you are defining a stride, but your vertices are compact, so please try:

    glFun->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);

    Regarding mapping the y coordinate, not sure if it is platform dependent but I just tested it and it works good on QOpenGLWidget, it maps the window corners to (-1, 1). If you need to map to other range you will need to use matrices, check this example: https://bitbucket.org/joaodeusmorgado/opengltutorials/src/314b981b60d64dd59498b4c6b96ab2aa61bc9be2/T10_MatrixTransforms_ortho/mygl.cpp?at=master&fileviewer=file-view-default

  • Hi,

    I'm not saying this is the problem but this code looks a bit weird.

    EDIT: It looks to me that you're passing the address of QVector<GLfloat> and not the actual address of the GLfloats. Convert this to a standard C array GLfloat data[9] = { immediates }; and see what happens. I assume VBO is a QOpenGLBuffer and there's no special overload for QVector<GLfloat>. It just takes a void *.

    VBO.allocate(&vertices, vertices.count() * sizeof(vertices));

    Looks like you're uploading X vertices but the sizeof is sizeof(QVector<GLfloat>). That's unlikely to be what you mean and could assplode on some paranoid machines (likely you'd walk off the end of the vertex array of sizeof(QVector<GLfloat>) is > sizeof(GLfloat)).

    I'd take the advice of @johngod on the stride (although, IIRC that setting is OK. It's the size of each attribute element not the gap between them).

    Also, if you have one, try this on another device/machine. You'd be amazed how many times my GL code works differently across desktop and Android platforms. Not even consistent between Android machines.

    @johngod One doesn't have to use matrices! I don't use matrices in GL all the time!

Log in to reply