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