2015-08-18 5 views
0

Я использую 2D текстурный массив для хранения некоторых данных. Как я часто хочу связать отдельные слои этого 2D массива текстуры, я создаю отдельные GL_TEXTURE_2D взгляды текстуры для каждого слоя:Копирование одного слоя массива 2D-текстур из графического процессора в CPU

for(int l(0); l < m_layers; l++) 
{ 
    QOpenGLTexture * view_texture = m_texture.createTextureView(QOpenGLTexture::Target::Target2D, 
                   m_texture_format, 
                   0,0, 
                   l,l); 
    view_texture->setMinMagFilters(QOpenGLTexture::Filter::Linear, QOpenGLTexture::Filter::Linear); 
    view_texture->setWrapMode(QOpenGLTexture::WrapMode::MirroredRepeat); 
    assert(view_texture != 0); 

    m_texture_views.push_back(view_texture); 
} 

Этих 2D TextureViews работают отлично. Однако, если я хочу получить данные 2D-текстуры со стороны графического процессора, используя этот просмотр текстуры, это не сработает.

Другими словами, следующие копии нет данных (но не приводит к возникновению ошибок GL):

glGetTexImage(GL_TEXTURE_2D, 0, m_pixel_format, m_pixel_type, (GLvoid*) m_raw_data[layer]) 

Однако, извлекая весь GL_TEXTURE_2D_ARRAY делает работу:

glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, m_pixel_format, m_pixel_type, (GLvoid*) data); 

Там, очевидно, будет потеря производительности, если мне нужно скопировать все слои массива 2D текстуры, когда были изменены только данные для одного слоя.

Есть ли способ скопировать GPU-> CPU только один слой GL_TEXTURE_2D_ARRAY? Я знаю, что существует противоположное (например, CPU-> GPU), поэтому я был бы удивлен, если бы не было.

ответ

3

В какой версии GL вы работаете?

Возможно, вам это не понравится, но ... GL 4.5 представляет glGetTextureSubImage (...), чтобы сделать именно то, что вы хотите. Это довольно внушительная версия для чего-то такого простого; он также доступен в extension form, но это расширение относительно новое.

Для этой функции не требуется специальное аппаратное обеспечение, но для этого требуется очень недавний драйвер.


Я бы не стал отчаиваться, пока.

Можно скопировать весь массив текстуры в ПБО, а затем прочитать вложенный прямоугольник этого ПБО обратно с помощью объекта буфера API (например, glGetBufferSubData (...)). Это требует дополнительной памяти на стороне GPU, но позволит вам перенести один фрагмент этого 2D-массива.

+0

К счастью, я работаю с GL 4.5 и последней версии драйвера Nvidia, так что новость не плохо. Он отлично работает! Не знаю, как я пропустил эту функцию во время просмотра документации openGL. Большое спасибо Андон. – Harry

+0

Ах, отлично. Возможности OpenGL с высокими требованиями к версии не позволяют мне спать ночью;) Я всегда обременен поиском решения, которое работает на старых системах. Для чего-то, что простое, отсутствующее в более старых версиях API, сложно расстраивать. –

4

Похоже, вы нашли решение с использованием glGetTexSubImage() из OpenGL 4.5. Существует также простое решение, которое работает с OpenGL версии 3.2 или выше.

Вы можете установить слой текстуры в качестве вложения FBO, а затем использовать glReadPixels():

GLuint fboId = 0; 
glGenFramebuffers(1, &fboId); 
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboId); 

glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 
          textureId, 0, layer); 

glReadPixels(...); 

glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); 

 Смежные вопросы

  • Нет связанных вопросов^_^