I made a Qt Application to preview 3D model. I use QOpenGLWidget to draw the triangles, with the core profile OpenGL v3.3. The shader compiler does not output any errors, and application run successfully, and everything seems like work.
Here are the general steps:
- Before application creating, set the default format to version 3.3 with Core profile:
auto format = QSurfaceFormat::defaultFormat();
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(3, 3);
QSurfaceFormat::setDefaultFormat(format);
- For previewing multiple models simultaneously, use shared context attribute:
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
- To simplify the description and code, I put a simple shader (called 'Skybox' in my application, to draw a gradient sky) as follows, although still does not work normally yet:
//////////////////
// Vertex Shader
//////////////////
#version 330 core
layout (location = 0) in vec3 aPos;
out vec3 fragPos;
void main()
{
fragPos = aPos;
gl_Position = vec4(aPos, 1.0);
}
////////////////////
// Fragment Shader
////////////////////
#version 330 core
in vec3 fragPos;
out vec4 fragCol;
uniform float _fov_rad;
uniform float _pitch;
uniform vec3 _sky;
uniform vec3 _ground;
void main()
{
vec3 down = (_pitch - _fov_rad * 0.5) * (_sky - _ground) + _ground;
vec3 up = (_pitch + _fov_rad * 0.5) * (_sky - _ground) + _ground;
float pitch = (fragPos.y + 1.0) * 0.5;
fragCol = vec4( pitch * (up - down) + down, 1.0) ;
}
- The rendering code:
///////////////////////////
//// in 'initializeGL' ////
///////////////////////////
//... some other initializations
makeCurrent();
// prepare data
QVector4 vertices = {
{-1.f, -1.f, .0f},
{ 1.f, -1.f, .0f},
{-1.f, 1.f, .0f},
{ 1.f, 1.f, .0f},
};
unsigned int indices[6] = {
0, 1, 2,
2, 1, 3
};
// creating buffers
auto vbo_v = std::make_shared<QOpenGLBuffer>(QOpenGLBuffer::Type::VertexBuffer);
if (!vbo_v->create()) {
qDebug() << "TriangleData::TriangleData>> vbo_v create failed";
}
vbo_v->bind();
vbo_v->setUsagePattern(QOpenGLBuffer::UsagePattern::StaticDraw);
vbo_v->allocate(mesh->vertices.data(), mesh->verticesNum() * sizeof(QVector3D));
auto vbo_n = std::make_shared<QOpenGLBuffer>(QOpenGLBuffer::Type::VertexBuffer);
if (!vbo_n->create()) {
qDebug() << "TriangleData::TriangleData>> vbo_n create failed";
}
vbo_n->bind();
vbo_n->setUsagePattern(QOpenGLBuffer::UsagePattern::StaticDraw);
vbo_n->allocate(mesh->normals.data(), mesh->verticesNum() * sizeof(QVector3D));
auto ibo = std::make_shared<QOpenGLBuffer>(QOpenGLBuffer::Type::IndexBuffer);
if (!ibo->create()) {
qDebug() << "TriangleData::TriangleData>> ibo create failed";
}
ibo->bind();
ibo->setUsagePattern(QOpenGLBuffer::UsagePattern::StaticDraw);
ibo->allocate(mesh->indices.data(), mesh->facesNum() * 3 * sizeof(unsigned int));
...
doneCurrent();
//////////////////////
//// in 'paintGL' ////
//////////////////////
QOpenGLFunctions f(QOpenGLContext::currentContext());
f.glClearColor(178.f/255.f, 168.f/255.f, 70.f/255.f, 1.0f);
f.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
QOpenGLShaderProgram* sprog = m_skyShader->sprog;
sprog->bind();
sprog->setUniformValue("_fov_rad", 70.f * 3.1415926f / 180.f);
sprog->setUniformValue("_sky", {.7f,.8f,.9f});
sprog->setUniformValue("_ground", {.1f,.2f,.3f});
sprog->setUniformValue("_pitch", .0f);
// binding attribute
vbo_v->bind();
sprog->enableAttributeArray(0);
sprog->setAttributeBuffer(0, GL_FLOAT, 0, 3, 0);
vbo_n->bind();
sprog->enableAttributeArray(1);
sprog->setAttributeBuffer(1, GL_FLOAT, 0, 3, 0);
ibo->bind();
// drawing
f.glDrawElements(GL_TRIANGLES, 2 * 3, GL_UNSIGNED_INT, 0);
If it worked, the result should look like this (the nice gradient background):
But it looks like this (only the clear color):
The same cpp code, and the similar shader (but in compatible profile) worked well.
For some reason it should run in core profile. Anyway, I still want to figure out why this weird problem occurred.
So I compiled RenderDoc from source to get Mac RenderDoc, and capture this application to point out the problem.
When I used RenderDoc (MAC) to launch this and capture the frames, it did render normally as below:
Here is the capture, saved as an .rdc file:
Environment:
HD: MacBook Air M1 2020
OS: MacOS 12.6.3
Qt: 6.5.0
Compiler: Clang arm 64bit



Possible Reason
In
RenderDoc, I found that after all render pass, aVAO(Vertex Array Object) calleddefaultVAOwas bound inCGLFLushDrawable().But in my render pass, there was no
VAObound, because I follow along the old code with Compatible Profile OpenGL.This might cause no actual buffers being flushed to draw in real application environment; but in
renderDocenvironment, it might be rendered byrenderDoc's flushed normally.Solution
I use
QOpenGLFunctions_3_3_Coreto create a vao when initialized for every render pass:And bind the specific
VAObefore setting vertex attribute: