Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Game Development
  4. Bare minimal QOpenGLFramebufferObject render to texture: Rendered triangle contains "noise"
Forum Updated to NodeBB v4.3 + New Features

Bare minimal QOpenGLFramebufferObject render to texture: Rendered triangle contains "noise"

Scheduled Pinned Locked Moved Unsolved Game Development
4 Posts 3 Posters 2.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    axeljaeger17
    wrote on last edited by
    #1

    Hello,
    I am trying to make a minimal example that renders the famous red triangle to a texture. I tried this using the following code:

    void GLWidget::initializeGL()
    {
        initializeOpenGLFunctions();
        glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
        m_vao = new QOpenGLVertexArrayObject(this);
        m_vao->create();
        m_vao->bind();
        static const GLfloat g_vertex_buffer_data[] = {
           -1.0f, -1.0f, 0.0f,
           1.0f, -1.0f, 0.0f,
           0.0f,  1.0f, 0.0f,
        };
        m_vertexBuffer.create();
        m_vertexBuffer.bind();
        m_vertexBuffer.allocate(g_vertex_buffer_data, sizeof(g_vertex_buffer_data));
        m_program = new QOpenGLShaderProgram(this);
        m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertexshader.glsl");
        m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragmentshader.glsl");
        m_program->link();
        m_program->enableAttributeArray(0);
        m_program->setAttributeBuffer(0, GL_FLOAT,0,3,0);
        m_framebuffer = new QOpenGLFramebufferObject(QSize(512,512), GL_TEXTURE_2D);
        m_filename = "C:/Users/Axel/Desktop/phased-array/trunk/testcases/build-rendertotexture-Desktop_Qt_5_8_0_MinGW_32bit2-Debug/test.png";
        glDisable(GL_DEPTH_TEST);
    }
    
    void GLWidget::paintGL()
    {
        m_framebuffer->bind(); // <= uncomment this one to draw on screen, which works perfectly
        glViewport(0,0,512,512);
    
        m_vao->bind();
        m_program->bind();
    
        glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
        glFinish();
    
        QImage fbo_img(m_framebuffer->toImage());
    
        fbo_img.save(m_filename);
    }
    

    When I uncomment the first two lines of my drawing routine, e.g. m_framebuffer->bind(); and glViewport(0,0,512,512); I get my red triangle as expected on the screen. When I render to the FBO and look into the resulting file, only about maybe half of the pixels are red, the others stay black. The black and red pixel follow a noise-like pattern and on each drawing calls, different pixels belonging to the triangle are red or black.

    I see two possible explainations:

    1. There is some kind of uninitialized buffer involved. Do you have any idea which one?
    2. The graphics card is still busy drawing all the fragments while I save the image. I tried fixing this by calling glFinish, but was not successfull.

    Do you have any idea what might went wrong in my case?

    Best regards

    Axel

    1 Reply Last reply
    0
    • johngodJ Offline
      johngodJ Offline
      johngod
      wrote on last edited by
      #2

      Just a shot in the dark, in case the problem is number 2) maybe you should try to save to the file outside the paintGL()

      1 Reply Last reply
      0
      • L Offline
        L Offline
        Lassson
        wrote on last edited by
        #3

        Just to be clear, are you using QGLWidget?

        I might be wrong, but I have a feeling that the FBO isn't fully updated at the time of m_framebuffer->toImage().
        If that's the case, you need to find a way to execute that at a point where the rendering (paintGL) is done. Maybe updateGL()?

        Ps. I just saw johngod pointing in the same direction. Maybe this answer give some more value. Ds.

        1 Reply Last reply
        0
        • johngodJ Offline
          johngodJ Offline
          johngod
          wrote on last edited by
          #4

          Any way, if all you want to do is create a image file from the window and if you using QOpenGLWidget I just remember I have done it before, check the following snipet that you can adatp to your needs:

          void XXXXX::SaveImageAs()
          {
              QString filename;
              filename = QFileDialog::getSaveFileName( this,
                                                      tr("Save File"),
                                                      getenv( "HOME" ), tr(" Image (*.png)") );
                                                      //getenv( "HOME" ), fileformat );
          
              if( !filename.endsWith( ".png" ) )
              {
                  filename.append( ".png" );
              }
          
              QPixmap pixmap( size() );
              render( &pixmap );
              QImage image = grabFramebuffer();
              QImageWriter imageWriter( filename, "png" );
          
              //imageWriter.setQuality(100);
          
              if( imageWriter.canWrite() )
              {
                  imageWriter.write(image);
              }
              else
              {
                  QMessageBox::warning( this, tr("Save Image"), tr("Error saving image.") );
              }
          }
          
          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved