Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to implement QOpenGLBuffer ::PixelPackBuffer
QtWS25 Last Chance

How to implement QOpenGLBuffer ::PixelPackBuffer

Scheduled Pinned Locked Moved Unsolved General and Desktop
openglpixel bufferpbo
2 Posts 2 Posters 789 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.
  • Carlos RobertoC Offline
    Carlos RobertoC Offline
    Carlos Roberto
    wrote on last edited by
    #1

    Hello,
    I'm just started learning Qt/C++ and now I'm trying to learn how to use PBO using Qt's OpenGL wrapper.

    A quick overview of my idea: I'm using GLSL shaders to process images OffScreen, and showing the results with a QOpenGLBlitter Quad. My current objective is to 'stack' multiple shaders passes to the same image.
    Right now I'm using fbo.toImage to save the offscreen render, and then using it as the texture for the following passes. Now I wanted to use PBO's to retain the fbo render and pass it as the texture for subsequent shader calls.

    Here most of my code.

    QImage imageShader::proImg(const QImage& image,
                             const QImage& tip,
                             const QString& vertexPosVar,
                             const QString& textureCoordVar){
    
        QOpenGLContext context;
    
        QOffscreenSurface offSurface;
        offSurface.setFormat(context.format());
        offSurface.create();
    
        // I'm sharing the context to show the offscreen Render into a
        // QOpenGLTextureBlitter under PaintGL()
        context.setShareContext(imageShader::context()); 
        context.create();
        context.makeCurrent(&offSurface);
    
        m_fbo = new QOpenGLFramebufferObject(image.size());
        m_fbo->bind();
    
        context.functions()->glViewport(0, 0, image.width(), image.height());
    
        QOpenGLShaderProgram program(&context);
        program.addShaderFromSourceFile(QOpenGLShader::Vertex, "path to vertex shader");
        program.addShaderFromSourceFile(QOpenGLShader::Fragment, "path to fragment shader");
        program.link();
        program.bind();
    
        // The next block is basically what I understood how to setup a PBO using
        // Qt's OpenGL wrapper.
        QOpenGLBuffer *pubo = new QOpenGLBuffer(QOpenGLBuffer::PixelUnpackBuffer);
        pubo->setUsagePattern(QOpenGLBuffer::DynamicCopy);
        pubo->create();
        pubo->bind();
        pubo->map(QOpenGLBuffer::ReadWrite);
        pubo->allocate(image.bits(),image.sizeInBytes());
        pubo->write(0,image.bits(),image.sizeInBytes());
        pubo->unmap();
        pubo->release();
    
        // Testing how to use texture::setData() using straight bytes instead of the
        // baked method of setData(QImage).
        // I believe this is how to use the PBO's content to set the texture using QOpenGL?
        QOpenGLTexture textu(QOpenGLTexture::Target2D);
        textu.setSize(image.width(),image.height());
        textu.setFormat(QOpenGLTexture::RGBA8_UNorm);
        textu.allocateStorage();
        textu.setData(QOpenGLTexture::BGRA,QOpenGLTexture::UInt8,image.bits(),nullptr);
    
        // The texture bellow is a test to see if I was able to set up two textures and
        // change which one the shader should use.
        QOpenGLTexture brush(QOpenGLTexture::Target2D);
        brush.setData(tip);
    
    
        // Using native OpenGL snippets never work. The texture remain black.
    //    GLuint tex;
    //    glGenTextures(1, &tex);
    //    glBindTexture(GL_TEXTURE_2D, tex);
    
    //        glTexImage2D(GL_TEXTURE_2D, 0, 3, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.bits());
    //        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    //        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    //    glBindTexture( GL_TEXTURE_2D, 0);
    
        GLint brTip = 1;
        brush.bind(brTip);
        GLint oriTxt = 0;
        textu.bind(oriTxt);
    
    //Rest of the code. Following Amin Ahmadi tutorial.
    
    

    I can summarize my questions as follow:

    1. Is this possible to keep a Offscreen render in memory and pass it as texture on a future shader call?
    2. What is the proper setup before writing into a PBO?
    3. QOpenGLBuffer::write will not work using with a simple QImage.bits(). How one write to a Pixel Buffer?
    4. How do you use a written PBO with Texture::setData()?

    I really hope to a least learn how to use QOpenGL::PixelBuffer, because every time I tried implement native OpenGL code in my project it broke it.

    Thanks.

    1 Reply Last reply
    0
    • W Offline
      W Offline
      wrosecrans
      wrote on last edited by
      #2

      I don't have an exact answer, but do you need any of that PBO stuff? You have a QImage and you want a QOpenGLTexture, so you can just do that directly: https://doc.qt.io/qt-5/qopengltexture.html#QOpenGLTexture-1 The texture object can be made directly from a QImage, with no extra steps.

      @Carlos-Roberto said in How to implement QOpenGLBuffer ::PixelPackBuffer:

      Is this possible to keep a Offscreen render in memory and pass it as texture on a future shader call?

      Sure. Render to your QOpenGLFramebufferObject, release it, and it has a texture() method so you can use it as a texture in a render somewhere else.

      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