PBO无法正常将纹理上传到GPU(OpenGL 4.1版)

时间:2017-03-23 09:16:38

标签: macos opengl graphics textures pbo

我已经阅读了着名的教程OpenGL Pixel Buffer Object (PBO)。我在我的计算机上测试了示例代码并且它可以工作(尽管在PBO上,它的性能没有改善,但至少它正确地渲染)。

问题出在示例代码中,OpenGL上下文版本已经过时(Version: 2.1 INTEL-10.22.29),而我项目的OpenGL上下文版本为version: 4.1 INTEL-10.22.29,不支持扩展GL_ARB_pixel_buffer_object更多。

我已阅读此Map and fill texture using PBO (OpenGL 3.3),因此我将代码更改为:

// generating buffers and textures
glGenVertexArrays(1, &_vertex_array);
glBindVertexArray(_vertex_array);

glGenBuffers(1, &_vertex_buffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs_data), vertexs_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

glGenBuffers(1, &_uv_buffer);
glBindBuffer(GL_ARRAY_BUFFER, _uv_buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(uvs_data), uvs_data, GL_STATIC_DRAW);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

glGenBuffers(1, &_pixel_buffer);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pixel_buffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);

glGenTextures(1, &_texture);
glBindTexture(GL_TEXTURE_2D, _texture);

并渲染循环:

glBindTexture(GL_TEXTURE_2D, _texture);
// ======== start process PBO =========
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _pixel_buffer);
glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0, GL_STREAM_DRAW);
GLubyte *ptr = (GLubyte*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
if( ptr != nullptr )
{
    cout<<"map pixel buffer success"<<endl;
    memcpy(ptr, DATA_SIZE, data );
    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);   
}
// ========= end process PBO ==========

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
             _window_width, _window_height,
             0, GL_RGB,
             GL_UNSIGNED_BYTE, data
);
glGenerateMipmap(GL_TEXTURE_2D);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
// draw commands goes here

我的代码只是呈现单一颜色纹理,如果我将块从======== start process PBO =========注释到========= end process PBO ==========,那么一切顺利,但是对于这个块,它只是失败了,我得到的只是一个黑色屏幕。我已经检查过glMapBuffer是否正常工作,并且我成功地将纹理数据写入ptr指向的内存(通过打印输出其值来检查),但我无法弄清楚为什么我没有得到我的预期结果。

提前致谢。

我的环境:

OS: macOS sierra 10.12.3 (16D32)
Graphics: Intel Iris Graphics 6100 1536 MB

1 个答案:

答案 0 :(得分:1)

修改

此答案已被接受,但需要修改。他们来了:

首先,我的眼睛指出了来自(void*)的演员。不,这不可能,memcpy()会再次施放它。
然后我到了glTextImage2D。并错误地认为它不能与PBO一起使用(大坝,我因为匆忙而犯错误。我必须放松......)。谢谢 Nico Bolas 纠正了我。

然后,再次慢慢阅读,只是在glTextImage2D中不使用指向客户端数据的指针,将data更改为0

文档清楚地说明了最后一个参数:

  

如果绑定了非零命名缓冲区对象   GL_PIXEL_UNPACK_BUFFER目标(参见glBindBuffer)同时是纹理图像   如果指定,则将数据视为缓冲区中的字节偏移量   对象的数据存储。

OLD:

GLubyte *ptr = (GLubyte*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
您正在退化返回的指针。如果你只在memcpy()命令中使用它,那就让它为(void*)
void* ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

编辑:(在我再次阅读您想要从PBO复制到纹理之后)

glTextImage2D()从指针 data 读取,而glTexSubImage2D()可用于从绑定的PBO读取。在最后一种情况下,glTexSubImage2D()的最后一个参数是该PBO的偏移量(如果不需要偏移则为0)。