Solved 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.
-
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.