0

我在 SFML 中创建渲染纹理(sf::RenderTexture用于离屏渲染),绘制到它并尝试使用 PBO 异步读取像素。这是我正在做的一个最小的例子:

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#define GL_SILENCE_DEPRECATION
#include <SFML/OpenGL.hpp>

#include <iostream>

int main()
{
    // create texture and circle to draw on texture
    int texSize = 200;
    sf::RenderTexture tex;
    tex.create(texSize, texSize);
    sf::CircleShape circle(50);
    circle.setPosition(0, 0);
    circle.setFillColor(sf::Color::Blue);
 
    // initialize PBOs
    int nPbos = 2;
    GLuint* pbos = new GLuint[nPbos];
    glGenBuffers(nPbos, pbos);
    for (int i = 0; i < nPbos; ++i) { 
        glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[i]);
        glBufferData(GL_PIXEL_PACK_BUFFER, texSize * texSize * 4, NULL, GL_STREAM_READ);
    }
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);

    int pboIdx = 0;
    for (int frame = 0; frame < 100; ++frame) {
        // draw stuff
        tex.clear(sf::Color::White);
        tex.draw(circle);
        tex.display();

        glReadBuffer(GL_COLOR_ATTACHMENT0);
        if (frame < nPbos) {
            glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[pboIdx]);
            glReadPixels(0, 0, texSize, texSize, GL_BGRA, GL_UNSIGNED_BYTE, 0);
        }
        else {
            glBindBuffer(GL_PIXEL_PACK_BUFFER, pbos[pboIdx]);

            unsigned char* ptr = (unsigned char*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);
            if (ptr != nullptr) {
                std::cout << "OK" << std::endl;
                glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
            }

            glReadPixels(0, 0, texSize, texSize, GL_BGRA, GL_UNSIGNED_BYTE, 0);
        }

        pboIdx = (pboIdx + 1) % nPbos;

        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
    }

    return 0;
}

我没有从glGetError(). 但是我从来没有进入条件,即。像素数组始终为空。我无法弄清楚代码有什么问题以及为什么我没有从纹理中获取像素,我是否在某处错过了绑定?

4

1 回答 1

0

这是从颜色缓冲区读取数据的示例。

本示例使用 glfw 和 glew。

#include <gl\glew.h>
#include <glfw3.h>

int w_readIndex = 0;
int w_writeIndex = 1;

int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
    glewInit();

    glGenBuffers(2, w_pbo);
    glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[0]);
    glBufferData(GL_PIXEL_PACK_BUFFER, SCR_WIDTH * SCR_HEIGHT * 4, 0, GL_STREAM_READ);
    glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[1]);
    glBufferData(GL_PIXEL_PACK_BUFFER, SCR_WIDTH * SCR_HEIGHT * 4, 0, GL_STREAM_READ);
    // unbind buffers for now
    glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);


while (!glfwWindowShouldClose(window))
    {
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

      // Draw your objects here

        w_writeIndex = (w_writeIndex + 1) % 2;
        w_readIndex = (w_readIndex + 1) % 2;
        glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[w_writeIndex]);
        // copy from framebuffer to PBO asynchronously. it will be ready in the NEXT frame
        glReadPixels(0, 0, SCR_WIDTH, SCR_HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
       
        // now read other PBO which should be already in CPU memory
        glBindBuffer(GL_PIXEL_PACK_BUFFER, w_pbo[w_readIndex]);
        unsigned char* downsampleData = (unsigned char*)glMapBuffer(GL_PIXEL_PACK_BUFFER, GL_READ_ONLY);

        if (downsampleData) {    
            std::cout << "Pointer is not NULL" << static_cast<unsigned>(downsampleData[2]) << std::endl;
        }
        glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
        glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
        
        glfwSwapBuffers(window);
        glfwPollEvents();
    }   
}
于 2022-02-01T13:26:57.033 回答