Re-rendering the object doesn't work



  • Hello everyone!

    I have the problem when try to re-render the object in GLWidget: the object does not appear when I press the button second time. Probably the answer is very simple, but I'm new in Qt development and would be very appreciate for any help.

    In my application I have two objects with different properties so I make them through two different QOpenGL shader programs. To render the objects I make two VBOs. For the first one the vertices and colours are known from the start so I initialise the correspondent VBO in initializeGL() function:

    void GLWidget::initializeGL()
    {
    initializeOpenGLFunctions();
    glClearColor(1, 1, 1, 1.0);

    ... defining vertex and fragment shaders....

        m_program1 = new QOpenGLShaderProgram;
    m_program1->addShader(m_vshader1);
    m_program1->addShader(m_fshader1);
    m_program1->link();
    
    m_program2 = new QOpenGLShaderProgram;
    m_program2->addShader(m_vshader2);
    m_program2->addShader(m_fshader2);
    m_program2->link();
    

    ...adding vertices, normals, colours, matrices, light to the shader programs....

    createGeometry();  // create the vertices for the first object
    
    m_vbo1.create();
    m_vbo1.bind();
    
    const int vertexCount = m_vertices.count();
    QVector<GLfloat> buf;
    buf.resize(vertexCount * 3 * 2);
    GLfloat *p = buf.data();
    for (int i = 0; i < vertexCount; ++i) {
    	*p++ = m_vertices[i].x();
    	*p++ = m_vertices[i].y();
    	*p++ = m_vertices[i].z();
    	*p++ = m_normals[i].x();
    	*p++ = m_normals[i].y();
    	*p++ = m_normals[i].z();
    }
    m_vbo1.allocate(buf.constData(), buf.count() * sizeof(GLfloat));
    m_vbo1.release();
    
    m_program1->release();
    

    }

    The second object vertices, normals and colours are calculated later in the program so I make the special function to initialise and upload the VBO2:

    ...calculation of the vertices, normals and colours for the second object....

    if (m_vbo2.isCreated() == false){
    	m_vbo2.create();
    	m_vbo2.bind();
    }
    else
    {
    	m_vbo2.destroy();
    	m_vbo2.create();
    	m_vbo2.bind();
    }
    
    const int dataCount = m_vertices_video.count();
    buf2.clear();
    buf2.resize(dataCount * 3 * 3);
    GLfloat *ptr = buf2.data();
    
    for (int j = 0; j < dataCount; j++){
    	*ptr++ = m_vertices_video[j].x();
    	*ptr++ = m_vertices_video[j].y();
    	*ptr++ = m_vertices_video[j].z();
    
    	*ptr++ = m_normals_video[j].x();
    	*ptr++ = m_normals_video[j].y();
    	*ptr++ = m_normals_video[j].z();
    
    	*ptr++ = m_color_video[j].x();
    	*ptr++ = m_color_video[j].y();
    	*ptr++ = m_color_video[j].z();
    }
    m_vbo2.allocate(buf2.constData(), buf2.count() * sizeof(GLfloat));
    m_vbo2.release();
    
    m_program2->release();
    

    The idea is to call this function each time I press the correspondent button.

    Then in the paintGL() function depending on the booling variable I render either first object or the second one:

    1. For the first object:

    m_camera.setToIdentity();
    m_camera.translate(-0.5, -0.5, -4.0);
    m_camera.rotate(30.0, 0.0, 1.0, 0.0);

    timer.start(12, this);
    
    m_world.setToIdentity();
    
    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);
    
    //draw cube
    m_program1->bind();
    m_program1->setUniformValue(m_projMatrixLoc, m_proj);
    m_program1->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
    QMatrix3x3 normalMatrix = m_world.normalMatrix();
    m_program1->setUniformValue(m_normalMatrixLoc, normalMatrix);
    
    QVector3D light3(100.0, 1.0, 0.0);
    m_program1->setUniformValue(m_lightPosLoc, light3);
    

    QVector3D color(0.7f, 0.7f, 0.7f);

    m_program1->setUniformValue(m_colorAttr1, color);
    
    m_program1->enableAttributeArray(m_vertexAttr1);
    m_program1->enableAttributeArray(m_normalAttr1);
    
    m_vbo1.bind();
    m_program1->setAttributeBuffer(m_vertexAttr1, GL_FLOAT, 0, 3, 6 * sizeof(GLfloat));
    m_program1->setAttributeBuffer(m_normalAttr1, GL_FLOAT, 3 * sizeof(GLfloat), 3, 6 * sizeof(GLfloat));
    m_vbo1.release();
    
    glDrawArrays(GL_QUADS, 0, m_vertices.size());
    
    
    m_program1->disableAttributeArray(m_normalAttr1);
    m_program1->disableAttributeArray(m_vertexAttr1);
    
    m_program1->release();
    
    1. for the second object:
      m_camera.setToIdentity();
      m_camera.translate(-0.5, -0.5, -4);
      m_camera.rotate(40.0, 0.0, 1.0, 0.0);

      m_world.setToIdentity();

      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_program2->bind();
      

      m_program2->setUniformValue(m_projMatrixLoc, m_proj);
      m_program2->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
      QMatrix3x3 normalMatrix = m_world.normalMatrix();
      m_program2->setUniformValue(m_normalMatrixLoc, normalMatrix);

       QVector3D light3(2.0, 2.0, 3.0);
      

      m_program2->setUniformValue(m_lightPosLoc, light3);

      m_vbo2.bind();
      m_program2->enableAttributeArray(m_vertexAttr2);
      m_program2->setAttributeBuffer(m_vertexAttr2, GL_FLOAT, 0, 3, 9 * sizeof(GLfloat));

      m_program2->enableAttributeArray(m_normalAttr2);
      m_program2->setAttributeBuffer(m_normalAttr2, GL_FLOAT, 3 * sizeof(GLfloat), 3, 9 * sizeof(GLfloat));

      m_program2->enableAttributeArray(m_colorAttr2);
      m_program2->setAttributeBuffer(m_colorAttr2, GL_FLOAT, 6 * sizeof(GLfloat), 3, 9 * sizeof(GLfloat));
      m_vbo2.release();

       int ii;
      

      int dataCount2 = m_vertices_video.count() / (aD->tStep*aD->isections);

      ii = aD->frameLoc;

      for (int i = 0; i < aD->isections; i++){
      glDrawArrays(GL_QUADS, idataCount2 + iiaD->isections*dataCount2, dataCount2);
      }

      m_program2->disableAttributeArray(m_normalAttr2);
      

      m_program2->disableAttributeArray(m_vertexAttr2);
      m_program2->disableAttributeArray(m_colorAttr2);

    m_program2->release();
    

    The idea is torender the correspondent object when I press the correspondent button. The first object renders all the times no problem. However, the second one renders only once, with the first time button pressed.

    It looks to me I upload the object data in VBOs OK, so the problem probably lays in the rendering itself. Unfortunately, I can't see it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.