Загрузка текстуры в GPU с помощью PBO не работает (OpenGL версия 4.1)
Я прочитал известный учебник 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
больше
Я прочитал эту Карту и залил текстуру, используя 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 ответ
РЕДАКТИРОВАТЬ
Этот ответ принят, но требует изменений. Вот они:
Сначала мой глаз указал на бросок из (void*)
, Нет, этого не может быть, memcpy() приведёт его снова.
Затем я прибыл в glTextImage2D
, И ошибочно подумал, что его нельзя использовать с PBO (черт, я слишком ошибаюсь из-за ажиотажа. Я должен расслабиться...). Спасибо Нико Болас поправил меня.
Затем, медленно читая снова, это был просто вопрос не использования указателя на данные клиента в glTextImage2D, изменить data
в 0
Документы ясно говорят об этом последнем параметре:
Если ненулевой именованный объект буфера привязан к цели GL_PIXEL_UNPACK_BUFFER (см. GlBindBuffer), пока задано изображение текстуры, данные обрабатываются как байтовое смещение в хранилище данных объекта буфера.
OLD:
GLubyte *ptr = (GLubyte*) glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
Вы вырождаете возвращенный указатель. Будь как будет (void*)
если вы используете его только в команде memcpy (): void* ptr = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_READ_WRITE);
РЕДАКТИРОВАТЬ: (после того, как я снова прочитал, что вы хотите скопировать из PBO в текстуру)
glTextImage2D()
читает из данных указателя в то время как glTexSubImage2D()
может быть использован для чтения из связанной ПБО. В этом последнем случае последний параметр glTexSubImage2D()
смещение к этому PBO (0, если смещение не требуется).