Я читаю глубину в один пиксель из кадрового буфера для осуществления выбора. Первоначально мой glReadPixels () занимал очень много времени (5 мс или около того), и на nVidia он даже сжигал 100% CPU в течение этого времени. На Intel он тоже был медленным, но с простаивающим процессором.
С тех пор я использовал функциональность PixelBufferObject, PBO , чтобы сделать glReadPixels асинхронными, а также с двойной буферизацией с использованием этого хорошо известного примера .
Этот подход хорошо работает, и давайте я сделаю вызов glReadPixels () асинхронным , но только если я прочитал значения RGBA . Если я использую тот же подход PBO для чтения значений глубины, glReadPixels () снова блокируется.
Чтение RGBA: glReadPixels () занимает 12 мкс.
Чтение DEPTH: glReadPixels () занимает 5 мс.
Я пробовал это на драйверах nVidia и Intel. С различными комбинациями формат / тип. Я попробовал:
glReadPixels( srcx, srcy, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, 0 );
и
glReadPixels( srcx, srcy, 1, 1, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0 );
и
glReadPixels( srcx, srcy, 1, 1, GL_DEPTH_STENCIL, GL_FLOAT_32_UNSIGNED_INT_24_8_REV, 0 );
Ни один из них не приведет к асинхронному вызову glReadPixels (). Но если я читаю значения RGBA с помощью следующего вызова:
glReadPixels( srcx, srcy, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
, затем glReadPixels () немедленно возвращается, поэтому больше не блокируется.
Перед чтением одного пикселя я делаю:
glReadBuffer( GL_FRONT );
glBindBuffer( GL_PIXEL_PACK_BUFFER, pboid );
И я создаю PBO с двойной буферизацией с:
glGenBuffers( NUMPBO, pboids );
for ( int i=0; i<NUMPBO; ++i )
{
const int pboid = pboids[i];
glBindBuffer( GL_PIXEL_PACK_BUFFER, pboid );
glBufferData( GL_PIXEL_PACK_BUFFER, DATA_SIZE, 0, GL_STREAM_READ );
...
Я создаю свой кадровый буфер, используя SDL2 с размером глубины 24, размером трафарета 8 и двойным буфером по умолчанию.
Я использую OpenGL Core Profile 3.3 в Ubuntu LTS.