Невозможно получить доступ к ранее обработанной текстуре из шейдера в OpenGL - PullRequest
1 голос
/ 24 августа 2011

У меня есть программа OpenGL, в которой я выполняю работу с дополненной реальностью. Работает в 2 прохода.

Во-первых, он рендерит кадр с использованием стандартных вызовов OpenGL. Затем он сравнивает кадр из камеры с визуализированным кадром с помощью шейдера.

На первом этапе я рендеринг текстуры, привязанной к моим объектам кадрового буфера, и также загружаю кадры камеры в другие текстуры, связанные с этим объектом.

Во время второго прохода у моего шейдера нет проблем с доступом к загруженным текстурам (то есть кадрам камеры), однако не может получить доступ к текстуре , отображаемой при первом проходе.

Если я создаю отладочный шейдер, который просто устанавливает цвета вершин в цвет текстуры в этой точке, то при использовании текстуры, загруженной с камеры, я вижу это:

Successfully accessing texture

Однако, если я изменю шейдер вместо использования текстуры, отображаемой на первом проходе, я вижу это:

Not accessing texture successfully

Я постараюсь дать достаточно фона, чтобы прояснить это, но любая помощь очень ценится!


Фон

Я знаю, что он правильно рендерился на первом проходе, так как у меня есть окно отладки, показывающее мне результаты рендеринга, и, кроме того, я использую OpenGL Profiler от Apple и могу видеть все текстуры.

Я в основном делаю рендеринг для текстур, как этот сайт

http://www.songho.ca/opengl/gl_fbo.html#example

Разница в том, что я никогда не переключаю объекты кадрового буфера. То есть я никогда не звоню

// switch back to window-system-provided framebuffer
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

Нужно ли использовать разные FBO, когда я делаю свой первоначальный рендеринг, и когда я использую свой шейдер для их сравнения?


Еще один намек на то, что может происходить, заключается в том, что если в профилировщике OpenGL я смотрю на свое состояние, оно только утверждает, что GL_TEXTURE0 и GL_TEXTURE4 изменились по сравнению со своим состоянием по умолчанию. Это обе текстуры, в которые я явно загружаю данные пикселей. Остальные 3 текстуры отображаются в моем первом проходе. Screenshot of OpenGL state


Соответствующий код

// First I create the textures
glGenTextures(1, &renderTexture);
glGenTextures(1, &cameraTexture);
glGenTextures(1, &correlationTexture);

gllActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, cameraTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, img->width, img->height, 0,GL_BGR, GL_UNSIGNED_BYTE, img->imageData); 

glActiveTexture(GL_TEXTURE0+1);
glBindTexture(GL_TEXTURE_2D, renderTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture, 0);

glActiveTexture(GL_TEXTURE0+2);
glBindTexture(GL_TEXTURE_2D, correlationTexture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width, size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, correlationTexture, 0);

// Now I render to the renderTexture. This works fine, I can verify
// it using glReadPixels.

// However, later on when I'm ready to do the shader, I do this
// First I switch the bound texture
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,      GL_TEXTURE_2D,correlationTexture, 0); // (this has been set up earlier)
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(theProgram);
glUniform1i(renderTexLoc, 1); // This should tell it to look at the rendered texture from earlier, it does not.

Ответы [ 2 ]

2 голосов
/ 27 августа 2011

Ах, похоже, я решил это. Мне пришлось привязать визуализированную текстуру первого прохода, прежде чем рендерить с помощью шейдера:

  glActiveTexture(GL_TEXTURE0+1);
  glBindTexture(GL_TEXTURE_2D,renderTexture);

Полагаю, я все еще не совсем понимаю, в чем именно разница между связанными текстурами и активными текстурами, но пока это работает.

0 голосов
/ 24 августа 2011

Вы не можете одновременно читать и записывать одно и то же изображение.Это приводит к неопределенному поведению.

Вы можете записывать разные изображения в одну и ту же текстуру (разные мип-карты или слои массива / куба / 3D-текстуры).Но вы не можете писать и читать с одного и того же изображения в текстуре.

Я предполагаю, что вы звонили glClear(GL_COLOR_BUFFER_BIT) перед тем, как пытаться выполнить рендеринг на втором проходе, который переписал текстуру, с которой вы ожидали прочитать.

В общем, если текстура прикреплена к FBO, она должна , а не быть привязанной к контексту.И наоборот.Возможно, вам следует пинг-понг между двумя текстурами.Один является текущим пунктом назначения, а другой - предыдущим пунктом назначения.После того, как вы закончите второй проход, вы переключаетесь.Это довольно распространенная техника.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...