使用glTexSubimage3D从不可变的PBO上传数据时结果错误

时间:2019-01-07 07:33:55

标签: opengl rendering immutability pbo

我正在实现一种用于渲染体积数据的核外算法。在每个渲染过程中,应使用PBO中的glTexSubImage3D将工作集(许多丢失的数据块,例如64 ^ 3)上传到GPU。为每个块应用glMapBuffer非常昂贵,因此我使用了一个不变的PBO,因此映射操作仅需要执行一次。为了提高效率,我采用了乒乓更新策略。

这是我的代码

// Generating immutable PBO
GLbitfield flgs = GL_MAP_PERSISTENT_BIT |GL_MAP_COHERENT_BIT | 
GL_MAP_WRITE_BIT | GL_MAP_READ_BIT;
glGenBuffers(1, &g_pingPBO);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, g_pingPBO);
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, blockBytes, nullptr,flgs);
g_pboPtr[0] = 
(char*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER,0,blockBytes,flgs);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

glGenBuffers(1, &g_pongPBO);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, g_pongPBO);
glBufferStorage(GL_PIXEL_UNPACK_BUFFER, blockBytes, nullptr,flgs);
g_pboPtr[1] = (char*)glMapBufferRange(GL_PIXEL_UNPACK_BUFFER, 0, blockBytes, 
flgs);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);

// Upload
g_texCache->Bind();
unsigned int pbo[2] = { g_pingPBO,g_pongPBO };
auto curPBO = 0;
auto i = 0;

// pointer dd is the block data on cpu
memcpy(g_pboPtr[1-curPBO], dd, blockBytes);
for (; i < missedBlocks - 1;)
{
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo[1 - curPBO]);

    // glTexSubImage3D here 
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);


    i++;
    const auto & index = g_hits[i];
    // pointer d is the block data on cpu
    memcpy(g_pboPtr[curPBO], d, blockBytes);
    curPBO = 1 - curPBO;

}

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo[1 - curPBO]);

glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
g_texCache->Unbind();

根本没有OpenGL运行时错误。只是块的位置不应该在该位置。

但是以下代码获得了正确的结果:

std::shared_ptr<OpenGLBuffer> pbo[2] = { g_blockPingBuf,g_blockPongBuf };
auto curPBO = 0;
auto i = 0;
const auto & idx = g_hits[i];
const auto dd = g_largeVolumeData->ReadBlockDataFromCache(idx);

pbo[1 - curPBO]->Bind();
auto pp = pbo[1 - curPBO]->Map(OpenGLBuffer::WriteOnly);
memcpy(pp, dd, blockBytes);
pbo[1 - curPBO]->Unmap();       // copy data to pbo
pbo[1 - curPBO]->Bind();

g_texCache->Bind();
for (;i < missedBlocks-1;)
{
    pbo[1 - curPBO]->Bind();
    // glTexSubImage3D here
    pbo[1 - curPBO]->Unbind();
    i++;

    pbo[curPBO]->Bind();
    auto p = pbo[curPBO]->Map(OpenGLBuffer::WriteOnly);

    memcpy(p, d, blockBytes);

    pbo[curPBO]->Unmap();       // copy data to pbo
    curPBO = 1 - curPBO;
}
pbo[1 - curPBO]->Bind();
// glTexSubImage3D here
pbo[1 - curPBO]->Unbind();

0 个答案:

没有答案