QT OpenGL unable to draw rectangle
-
wrote on 7 Feb 2018, 05:36 last edited by
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); }
-
wrote on 7 Feb 2018, 20:00 last edited by Mapku3 2 Jul 2018, 20:15
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(); }
-
wrote on 7 Feb 2018, 21:00 last edited by
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.
-
Lifetime Qt Championwrote on 7 Feb 2018, 21:06 last edited by mrjj 2 Jul 2018, 21:06
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.
1/4