2016-05-19 14 views
0

私はQt-5.4を使用しています。 QOpenGLWidgetでいくつかの3Dシェイプを描画したいと思います。 2つのVBOを作成して頂点の位置を設定しようとしましたが、1つの図形だけがレンダリングされます。また、「QOpenGLVertexArrayObject :: create()VAOが既に作成されています」というデバッグ情報が表示されます。 何をすべきか教えてくれる人はいますか? QOpenGLWidgetの私の実装は以下の通りです:Qt- 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

あなたが呼び出すべきではありません "にglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);"あなたの "QOpenGLVertexArrayObject :: create()VAOは既に作成されています"という警告については、わからないかもしれません。おそらく、あなたのメソッド "setupVertexAttribs"は次のようになっています。二度呼ばれる?

+0

2番目の描画の前にglClear関数を削除しましたが、レンダリングされるオブジェクトは1つのみです。バッファバインドに問題がありますか? –

+0

私はついにそれを作る。すべて同じようにありがとう。 –

関連する問題