我使用的是Qt-5.4。现在我想在QOpenGLWidget上绘制几个3D形状。我尝试通过创建2个VBO来设置顶点位置,但只渲染了一个形状。并且有一个" QOpenGLVertexArrayObject :: create()已经创建了VAO"在调试信息中显示。 有没有人可以告诉我该怎么做? 我的QOpenGLWidget实现如下:
static const char *vertexShaderSourceCore =
"#version 150\n"
"in vec4 vertex;\n"
"in vec3 normal;\n"
"in vec3 color;\n"
"out vec3 vert;\n"
"out vec3 vertNormal;\n"
"out vec3 vertColor;\n"
"uniform mat4 projMatrix;\n"
"uniform mat4 mvMatrix;\n"
"uniform mat3 normalMatrix;\n"
"void main() {\n"
" vert = vertex.xyz;\n"
" vertNormal = normalMatrix * normal;\n"
" vertColor = color;\n"
" gl_Position = projMatrix * mvMatrix * vertex;\n"
"}\n";
static const char *fragmentShaderSourceCore =
"#version 150\n"
"in highp vec3 vert;\n"
"in highp vec3 vertNormal;\n"
"in highp vec3 vertColor;\n"
"out highp vec4 fragColor;\n"
"uniform highp vec3 lightPos;\n"
"void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(0.5, 0.5, 0);\n"
" highp vec3 col = clamp(vertColor * 0.2 + vertColor * 0.8 * NL, 0.0, 1.0);\n"
" fragColor = vec4(col, 1.0);\n"
"}\n";
static const char *vertexShaderSource =
"attribute vec4 vertex;\n"
"attribute vec3 normal;\n"
"attribute vec3 color;\n"
"varying vec3 vert;\n"
"varying vec3 vertNormal;\n"
"varying vec3 vertColor;\n"
"uniform mat4 projMatrix;\n"
"uniform mat4 mvMatrix;\n"
"uniform mat3 normalMatrix;\n"
"void main() {\n"
" vert = vertex.xyz;\n"
" vertColor = color;\n"
" vertNormal = normalMatrix * normal;\n"
" gl_Position = projMatrix * mvMatrix * vertex;\n"
"}\n";
static const char *fragmentShaderSource =
"varying highp vec3 vert;\n"
"varying highp vec3 vertNormal;\n"
"varying highp vec3 vertColor;\n"
"uniform highp vec3 lightPos;\n"
"void main() {\n"
" highp vec3 L = normalize(lightPos - vert);\n"
" highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n"
" highp vec3 color = vec3(0.39, 1.0, 0.0);\n"
" highp vec3 col = clamp(vertColor * 0.2 + vertColor * 0.8 * NL, 0.0, 1.0);\n"
" gl_FragColor = vec4(col, 1.0);\n"
"}\n";
void DisplayGLWidget::initializeGL()
{
// In this example the widget's corresponding top-level window can change
// several times during the widget's lifetime. Whenever this happens, the
// QOpenGLWidget's associated context is destroyed and a new one is created.
// Therefore we have to be prepared to clean up the resources on the
// aboutToBeDestroyed() signal, instead of the destructor. The emission of
// the signal will be followed by an invocation of initializeGL() where we
// can recreate all resources.
initializeOpenGLFunctions();
glClearColor(255, 255, 255, m_transparent ? 0 : 1);
m_program = new QOpenGLShaderProgram;
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource);
m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("normal", 1);
m_program->bindAttributeLocation("color", 2);
m_program->link();
m_program->bind();
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
m_mvMatrixLoc = m_program->uniformLocation("mvMatrix");
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
m_lightPosLoc = m_program->uniformLocation("lightPos");
m_camera.setToIdentity();
QVector3D eye(0, 0, 8.0);
QVector3D up(0, 1.0, 0);
QVector3D center(0, 0, 0.0);
m_camera.lookAt(eye, center, up);
// Store the vertex attribute bindings for the program.
setupVertexAttribs();
// Light position is fixed.
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));
m_program->release();
}
void DisplayGLWidget::setupVertexAttribs()
{
// Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x
// implementations this is optional and support may not be present
// at all. Nonetheless the below code works in all cases and makes
// sure there is a VAO when one is needed.
m_vao.create();
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
// Setup our vertex buffer object.
m_meshModelVbo.create();
m_meshModelVbo.bind();
m_meshModelVbo.allocate(m_model->constData(), m_model->count() * sizeof(GLfloat));
m_meshModelVbo.bind();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glEnableVertexAttribArray(2);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
m_meshModelVbo.release();
m_pcModelVbo.create();
m_pcModelVbo.bind();
m_pcModelVbo.allocate(m_model2->constData(), m_model2->count() * sizeof(GLfloat));
m_pcModelVbo.bind();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glEnableVertexAttribArray(2);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(GLfloat), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
m_pcModelVbo.release();
m_vao.release();
}
void DisplayGLWidget::paintGL()
{
/* paint 1st object */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_vao.bind();
m_meshModelVbo.bind();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
m_world.setToIdentity();
m_world.translate(m_model->getCenter().x(), m_model->getCenter().y(), m_model->getCenter().z());
m_world.rotate(m_xRot / 16.0f, 1, 0, 0);
m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
m_world.translate(-m_model->getCenter().x(), -m_model->getCenter().y(), -m_model->getCenter().z());
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
m_program->bind();
m_program->setUniformValue(m_projMatrixLoc, m_proj);
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
QMatrix3x3 normalMatrix = m_world.normalMatrix();
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
glPointSize(2.0);
glDrawArrays(GL_POINTS, 0, m_model->vertexCount());
glFinish();
m_program->release();
/* paint 2nd object */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
m_pcModelVbo.bind();
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
m_world.setToIdentity();
m_world.translate(m_model2->getCenter().x(), m_model2->getCenter().y(), m_model2->getCenter().z());
m_world.rotate(m_xRot / 16.0f, 1, 0, 0);
m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
m_world.translate(-m_model2->getCenter().x(), -m_model2->getCenter().y(), -m_model2->getCenter().z());
m_program->bind();
m_program->setUniformValue(m_projMatrixLoc, m_proj);
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
glPointSize(2.0);
glDrawArrays(GL_POINTS, 0, m_model2->vertexCount());
glFinish();
m_program->release();
m_vao.release();
}
void DisplayGLWidget::resizeGL(int w, int h)
{
if (width != w)
width = w;
if (height != h)
height = h;
m_proj.setToIdentity();
m_proj.perspective(30.0f, GLfloat(w) / h, 2.0f, 20.0f);
}
答案 0 :(得分:0)
你不应该打电话给&#34; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);&#34;在绘制第二个形状之前:它会清除当前帧缓冲区(可能是屏幕)
关于你的&#34; QOpenGLVertexArrayObject :: create()已经创建了VAO&#34;警告,我不知道,也许你的方法&#34; setupVertexAttribs&#34;被叫两次?