简体   繁体   English

通过PBO将纹理上传到GPU不起作用(OpenGL版本4.1)

[英]Uploading texture to GPU by PBO not working (OpenGL version 4.1)

I have read the famous tutorial OpenGL Pixel Buffer Object (PBO) . 我已经阅读了著名的OpenGL像素缓冲区对象(PBO)教程。 I tested the sample code on my computer and it works (although with PBO on, its performance didn't improve but at least it's rendering correctly). 我在计算机上测试了示例代码,并且该代码可以正常工作(尽管启用了PBO,其性能并没有提高,但至少可以正确呈现)。

The problem is in the sample code the OpenGL context version is quite old ( Version: 2.1 INTEL-10.22.29 ), and the OpenGL context version for my project is version: 4.1 INTEL-10.22.29 which doesn't support extension GL_ARB_pixel_buffer_object any more. 问题在于示例代码中的OpenGL上下文版本很旧( Version: 2.1 INTEL-10.22.29 ),而我项目的OpenGL上下文版本是version: 4.1 INTEL-10.22.29 ,它不支持扩展名GL_ARB_pixel_buffer_object any更多。

I have read this Map and fill texture using PBO (OpenGL 3.3) , so I change my code to: 我已经阅读了此Map并使用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);

and render loop: 并渲染循环:

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

My code is simply rendering a single color texture, if I comment the block from ======== start process PBO ========= to ========= end process PBO ========== then everything goes well, but with this block, it just failed and all I get is a black screen. 如果我从======== start process PBO =========注释该块,则我的代码只是呈现单一的颜色纹理======== start process PBO ================== end process PBO ==========然后一切都会顺利进行,但是有了这个方块,它只是失败了,我得到的只是一个黑屏。 I already checked that the glMapBuffer works correctly and I successfully write the texture data to memory pointed by ptr ( checking by print out its value ), but I can't figure out why I didn't get my expected result. 我已经检查了glMapBuffer是否可以正常工作,并且成功将纹理数据写入了ptr指向的内存中(通过打印出其值进行检查),但是我不知道为什么我没有得到预期的结果。

Thanks in advance. 提前致谢。

My Environment: 我的环境:

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

EDIT 编辑

This answer has been accepted, but it requires modifications. 该答案已被接受,但需要进行修改。 Here they are: 他们来了:

First my eye pointed out a cast from (void*) . 首先,我的眼睛指出了(void*)的演员表。 No, this can't be, memcpy() will cast it again. 不,这不可能,memcpy()将再次对其进行转换。
Then I arrived to glTextImage2D . 然后我到达了glTextImage2D And erroneously thought it can not be used with PBO (dam, I make too mistakes due to rush. I must relax...). 并错误地认为它不能与PBO一起使用(大坝,由于匆忙我犯了太多错误。我必须放松一下...)。 Thanks Nico Bolas corrected me. 谢谢尼科·波拉斯纠正了我。

Then, slowly reading again, it was just a matter of not using a pointer to client data in glTextImage2D, change data to 0 然后,再次慢慢读取,这只是不使用glTextImage2D中的指向客户端数据的指针,而是将data更改为0

Docs say clearly about this last parameter: 文档清楚地说明了最后一个参数:

If a non-zero named buffer object is bound to the GL_PIXEL_UNPACK_BUFFER target (see glBindBuffer) while a texture image is specified, data is treated as a byte offset into the buffer object's data store. 如果在指定纹理图像时将非零命名的缓冲区对象绑定到GL_PIXEL_UNPACK_BUFFER目标(请参阅glBindBuffer),则将数据视为缓冲区对象的数据存储区中的字节偏移。

OLD: 旧:

GLubyte *ptr = (GLubyte*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
You are degenerating the returned pointer. 您正在退化返回的指针。 Let it be (void*) if you only use it in a memcpy() command: 如果仅在memcpy()命令中使用它,则将其设为(void*)
void* ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);

EDIT: (after I read again that you want to copy from PBO to a texture) 编辑:(在我再次阅读您要从PBO复制到纹理后)

glTextImage2D() reads from a pointer data while glTexSubImage2D() can be used to read from a bound PBO. glTextImage2D()从指针数据中读取,而glTexSubImage2D()可用于从绑定的PBO中读取。 In this last case the last parameter to glTexSubImage2D() is an offset to that PBO (0 if no offset is needed). 在后一种情况下, glTexSubImage2D()的最后一个参数是该PBO的偏移量(如果不需要偏移量,则为0)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM