2016-11-29 2 views
0

Я ищу использование бесконтактных текстур, чтобы быстро отображать серию изображений. Моя рекомендация - это Redbook OpenGL 4.5. Книга говорит, что я могу попробовать bindless текстуру в шейдере с этим пиксельным шейдером:OpenGL Bindless Textures: привязка к единому массиву sampler2D

#version 450 core 
#extension GL_ARB_bindless_texture : require 

in FS_INPUTS { 
    vec2 i_texcoord; 
    flat int i_texindex; 
}; 

layout (binding = 0) uniform ALL_TEXTURES { 
    sampler2D fs_textures[200]; 
}; 

out vec4 color; 

void main(void) { 
    color = texture(fs_textures[i_texindex], i_texcoord); 
}; 

Я создал вершинный шейдер, выглядит следующим образом:

#version 450 core 

in vec2 vert; 
in vec2 texcoord; 
uniform int texindex; 

out FS_INPUTS { 
    vec2 i_texcoord; 
    flat int i_texindex; 
} tex_data; 

void main(void) { 
    tex_data.i_texcoord = texcoord; 
    tex_data.i_texindex = texindex; 
    gl_Position = vec4(vert.x, vert.y, 0.0, 1.0); 
}; 

Как вы можете заметить, мое понимание того, что происходит он немного слаб.

В моем коде OpenGL я создаю кучу текстур, получаю их ручки и делаю их резидентными. Функция, которую я использую для получения обработчиков текстур, - «glGetTextureHandleARB». Существует другая функция, которая может быть использована вместо: 'glGetTextureSamplerHandleARB', где я могу проходить в месте сэмплера. Вот что я сделал:

Texture* textures = new Texture[load_limit]; 
GLuint64* tex_handles = new GLuint64[load_limit]; 

for (int i=0; i<load_limit; ++i) 
{ 
    textures[i].bind(); 
    textures[i].data(new CvImageFile(image_names[i])); 
    tex_handles[i] = glGetTextureHandleARB(textures[i].id()); 
    glMakeTextureHandleResidentARB(tex_handles[i]); 
    textures[i].unbind(); 
} 

Моим вопрос, как я могу связать мою текстуру ручку к ALL_TEXTURES равномерному атрибуту пиксельного шейдера? Кроме того, что я должен использовать для обновления атрибута vertex «texindex» - фактического индекса в моем массиве дескриптора текстуры или обработчике текстуры?

ответ

5

Это связующее текстурирование. Вы не привязываете такие текстуры ко всему.

В bindless texturing значением данных пробоотборника является число. В частности, номер возвращается glGetTextureHandleARB. Обработчики текстур - это 64-разрядное целое число без знака.

В шейдере значения sampler типов в buffer-backed interface blocks (UBOs и SSBOs) являются 64-разрядными целыми без знака. Таким образом, массив пробников эквивалентен по структуре массиву из 64-разрядных целых чисел без знака.

Таким образом, в С ++ структура эквивалентно вашему ALL_TEXTURES блока будет:

struct AllTextures 
{ 
    GLuint64 textures[200]; 
}; 

Ну, если вы правильно использовать std140 макет, конечно. В противном случае вам придется запросить компоновку структуры.

На данный момент вы обрабатываете буфер как отличный от любого другого использования UBO. Создайте данные для шейдера, вставив AllTextures в объект-буфер, затем привяжите этот буфер как привязку UBO к привязке 0. Вам просто нужно заполнить массив с помощью фактических ручек текстуры.

Кроме того, что я должен использовать для обновления атрибута vertex 'texindex' - фактического индекса в моем массиве дескриптора текстуры или дескриптора текстуры?

Хорошо, никто не будет работать. Не так, как вы его написали.

См., ARB_bindless_texture. Вы не можете получить доступ к какой-либо текстуре в любом случае в любом случае из любого вызова шейдера. Если вы не используете NV_gpu_shader5, код, ведущий к доступу к текстуре, должен быть основан на dynamically uniform expressions.

Так что, если каждая вершина в вашей команде рендеринга не получает тот же указатель или дескриптор, вы можете использовать их, чтобы выбрать, какую текстуру использовать.Даже instancing не спасет вас, так как динамически однородные выражения не заботятся о том, чтобы инстанцировать.

Если вы хотите сделать кучу квадроциклов без необходимости менять форму между ними (и, не полагаясь на расширение NVIDIA), у вас есть несколько вариантов. Большинство аппаратных средств, поддерживающих текстуру без привязки, также поддерживают ARB_shader_draw_parameters. Это дает вам доступ к gl_DrawID, который представляет текущий индекс команды рендеринга within a glMultiDraw-style command. И это расширение явно заявляет, что gl_DrawID является динамически однородным.

Итак, вы можете использовать это, чтобы выбрать текстуру для рендеринга. Вам просто нужно выпустить команду multi-draw, в которой вы повторяете одни и те же данные сетки снова и снова, но в каждом случае он получает другой код gl_DrawID.

+0

Спасибо, это было очень полезно! OpenGL сложно! – vincent

+0

Я смог получить код, который я опубликовал. Мне просто нужно было использовать UBO для прикрепления к ALL_TEXTURES, как вы упомянули. Я все еще использую целое число i_texindex для индексации в fs_textures. Если я повторяю fs_textures, независимо от того, сколько текстур загружается, работает только первая половина текстур (из 50 текстур всего 25). Другая половина, похоже, покрывается тем, что говорит отладчик Linux Graphics Debugger, называется drawable, называемым «Front Left Color» или «Back Left Color». Я подтвердил, что полный массив текстур загружен правильно. Я в тупике от этого! Вы видели это раньше? – vincent

+0

Понял! В очередной раз благодарим за помощь! – vincent

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