Reputation: 21
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:
auto format = QSurfaceFormat::defaultFormat();
format.setRenderableType(QSurfaceFormat::OpenGL);
format.setProfile(QSurfaceFormat::CoreProfile);
format.setVersion(3, 3);
QSurfaceFormat::setDefaultFormat(format);
QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
//////////////////
// 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) ;
}
///////////////////////////
//// 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
Upvotes: 1
Views: 217
Reputation: 21
In RenderDoc
, I found that after all render pass, a VAO
(Vertex Array Object) called defaultVAO
was bound in CGLFLushDrawable()
.
But in my render pass, there was no VAO
bound, 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 renderDoc
environment, it might be rendered by renderDoc
's flushed normally.
I use QOpenGLFunctions_3_3_Core
to create a vao when initialized for every render pass:
// 'RenderAPI' is my own redundant API
...
struct RenderAPI {
...
QOpenGLFunctions_3_3_Core f_330C;
...
};
...
// in initialization QOpenGLWidget
auto &f = RenderAPI::getInstance()->f_330C;
f.glGenVertexArrays(1, &vao);
And bind the specific VAO
before setting vertex attribute:
auto &f = RenderAPI::getInstance()->f_330C;
f.glBindVertexArray(vao);
Upvotes: 1