0

我正在 Adreno GPU 上的 OpenGL-ES 3.0 应用程序中工作。

使用 FBO 的 Render-to-Texture,我在屏幕外渲染了一个图像数据。

我使用 PBO 更快地读回数据,以便在 CPU 中进行进一步处理。

代码是:

    void pbo_init() {
        unsigned int readPBOId[2];
        unsigned int pbo_buffer_size = view_width * view_height * 3;

        glGenBuffers(2, readPBOId);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, readPBOId[0]);
        glBufferData(GL_PIXEL_PACK_BUFFER, pbo_buffer_size, 0, GL_STREAM_READ);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, readPBOId[1]);
        glBufferData(GL_PIXEL_PACK_BUFFER, pbo_buffer_size, 0, GL_STREAM_READ);
    }
    
    void draw()
    {
        glBindFramebuffer(GL_FRAMEBUFFER, m_FBO);

        glViewport(0, 0, view_width, view_height);
        glBindVertexArray(m_VAO);
        glBindTexture(GL_TEXTURE_2D, texId);
        glDrawElements(GL_TRIANGLE_STRIP, ... );

        unsigned char *readback_data;

        static int index = 0;
        static int nextIndex = 1;
        index = (index + 1) % 2;
        nextIndex = (index + 1) % 2;
    // PBO Read Back 
        glBindBuffer(GL_PIXEL_PACK_BUFFER, readPBOId[index]);
        glReadPixels(0, 0, view_width, view_height, GL_RGB, GL_UNSIGNED_BYTE, 0);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

        // Sync 
        GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        do
        {
            glGetSynciv(sync, GL_SYNC_STATUS, 1, nullptr, &signalled);
        } while (signalled != GL_SIGNALED);
        glDeleteSync(sync);

        glBindBuffer(GL_PIXEL_PACK_BUFFER, readPBOId[nextIndex]);
        unsigned char* mappedBuffer = (unsigned char*)(glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0,
                                                          pbo_buffer_size, GL_MAP_READ_BIT));
        if (NULL != mappedBuffer)
        {
            readback_data = (unsigned char *)malloc( sizeof(unsigned char) * pbo_buffer_size);
            memcpy(readback_data, mappedBuffer, pbo_buffer_size);
            glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
            // Dumping the read data into a bmp file...
            WriteBMPImage("Out.bmp", readback_data, view_width, view_height, sizeof(uint8_t) * 3);
        }
        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
        GLCALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
    }

但是我没有通过使用 PBO 获得任何性能提升,而且 glMapBufferRange() 返回 NULL。

在这里处理 PBO 有什么问题?

4

0 回答 0