GLSL и FBO - glActiveTexture не работает?

Я пытаюсь написать простой шейдер, который добавлял бы текстуры, прикрепленные к FBO. Проблем с инициализацией FBO и прочим нет (тестировал). Я считаю, что проблема в glActiveTexture (GL_TEXTURE0). Кажется, он ничего не делает - вот мой фрагмент-шейдер: (но обычно шейдер вызывается - я проверил это, поместив gl_FragColor = vec4 (0,1,0,1);

 uniform sampler2D Texture0;
 uniform sampler2D Texture1;
 varying vec2 vTexCoord;
 void main()
 {
     vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st);
     vec4 vec = texel0; 
     gl_FragColor = texel0;     
 }

И в коде C ++ у меня есть:

 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, iFrameBufferAccumulation); 

 glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
 ( Render something - it works fine to iTextureImgAccumulation texture attached to     GL_COLOR_ATTACHMENT0_EXT )
 glClear (GL_COLOR_BUFFER_BIT );
 glEnable(GL_TEXTURE_RECTANGLE_NV);


 glActiveTexture(GL_TEXTURE0); 

 glBindTexture( GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation ); // Bind our frame buffer texture 
 xShader.setUniform1i("Texture0", 0);

 glLoadIdentity(); // Load the Identity Matrix to reset our drawing locations 
 glTranslatef(0.0f, 0.0f, -2.0f); 
 xShader.bind();        
 glBegin(GL_QUADS);

     glTexCoord2f(0,OPT.m_nHeight);
     glVertex3f(-1,-1,0);

 glTexCoord2f(OPT.m_nWidth,OPT.m_nHeight);
 glVertex3f(1,-1,0);

 glTexCoord2f(OPT.m_nWidth,0);
 glVertex3f(1,1,0);

 glTexCoord2f(0,0);
 glVertex3f(-1,1,0);

 glEnd();

 glBindTexture( GL_TEXTURE_RECTANGLE_NV, NULL ); 

 xShader.unbind();

Результат: черный экран (при отображении второй текстуры и использовании шейдера (без использования шейдера все в порядке). Я знаю, что этот шейдер не должен делать много, но он даже не отображает первую текстуру. Я нахожусь в середине Тестирование вещей, но идея состоит в том, что после рендеринга первой текстуры я бы добавил первую текстуру ко второй.Для этого я полагаю, что этот шейдер фрагмента будет работать:

 uniform sampler2D Texture0;
 uniform sampler2D Texture1;
 varying vec2 vTexCoord;
 void main()
 {
     vec4 texel0 = texture2D(Texture0, gl_TexCoord[0].st);
     vec4 texel1 = texture2D(Texture1, gl_TexCoord[0].st);
     vec4 vec = texel0 + texel1;
     vec.w = 1.0;
     gl_FragColor = vec;    
 }

И вся идея состоит в том, что в цикле tex2 = tex2 + tex1 (возможно ли, чтобы я использовал tex2 в этом шейдере для рендеринга в GL_COLOR_ATTACHMENT1_EXT, который прикреплен к tex2?) Я тестировал как xShader.bind (); перед инициализацией универсальных переменных и после. В обоих случаях - черный экран.

В любом случае, на мгновение я почти уверен, что есть какая-то проблема с инициализацией сэмплера для текстур (может быть, потому что они привязаны к FBO)?

Остальное проверил, все работает нормально.

Еще одна глупая проблема:

Как визуализировать текстуру на весь экран?

Я пробовал что-то подобное, но не работает (надо немного перевести этот квад)

glViewport(0,0 , OPT.m_nWidth, OPT.m_nHeight);

glBindTexture( GL_TEXTURE_RECTANGLE_NV, iTextureImg/*iTextureImgAccumulation*/ ); // Bind our frame buffer texture 

glBegin(GL_QUADS);
glTexCoord2f(0,OPT.m_nHeight);
glVertex3f(-1,-1,0);

glTexCoord2f(OPT.m_nWidth,OPT.m_nHeight);
glVertex3f(1,-1,0);

glTexCoord2f(OPT.m_nWidth,0);
glVertex3f(1,1,0);

glTexCoord2f(0,0);
glVertex3f(-1,1,0);

glEnd();

Также не работает с glVertex2f ..

Изменить: я проверил, и я могу инициализировать некоторые однородные переменные, только текстуры проблематичны.

Я изменил порядок, но он все еще не работает. :( Между прочим, другие значения униформы работают хорошо. Я отобразил текстуру, которую тоже хочу передать шейдеру. Она работает нормально. Но по неизвестной причине сэмплер текстуры не инициализирован во фрагментном шейдере. Может быть, это имеет какое-то отношение, что эта текстура - glTexImage2D (GL_TEXTURE_RECTANGLE_NV, 0, GL_RGB16F / GL_FLOAT_R32_NV /, OPT.m_nWidth, OPT.m_nHeight, 0, GL_RED, GL_FLOAT); (, NULL_RED, GL_FLOAT); это не GL_TEXTURE_2D)?


person mathew    schedule 10.05.2012    source источник
comment
почему вы используете текстурные прямоугольники? это могло бы работать, если бы вы использовали нормальные текстуры. В OpenGL 2.0 и выше полностью поддерживаются текстуры npot.   -  person fen    schedule 10.05.2012
comment
Я не понимаю, что вы имеете в виду. Я использую GL_TEXTURE_RECTANGLE_NV с GL_RGB16F, я считаю, что это текстура NPOT. Кстати, я пытался использовать GL_FLOAT_R32_NV, но это не сработало (мне нужен шейдер для этого, если да, то какой именно?)   -  person mathew    schedule 10.05.2012
comment
Еще одна глупая проблема: вы не задаете два вопроса. Вы задаете по одному вопросу за раз. Если у вас возникла очередная дурацкая проблема, задайте другой вопрос кнопкой Ask Question.   -  person Nicol Bolas    schedule 10.05.2012
comment
извините за то, что не очень точен ... нормальные текстуры для меня означают GL_TEXTURE_2D, а не GL_TEXTURE_RECTANGLE_NV   -  person fen    schedule 11.05.2012


Ответы (2)


Непонятно, что делает ваш xShader.bind(), я догадываюсь, что вы там делаете glUseProgram(...). Но универсальные переменные (индекс сэмплера в вашем случае) должны быть установлены после вызова glUseProgram(...). В этом порядке:

glUseProgram(your_shaders); //probably your xShader.bind() does it.

GLuint sampler_idx = 0; 
GLint location = glGetUniformLocation(your_shaders, "Texture0");
if(location != -1) glUniform1i(location, sampler_idx);
else error("cant, get uniform location");

glActiveTexture(GL_TEXTURE0 + sampler_idx);
glBindTexture(GL_TEXTURE_2D, iTextureImg);

и "да" вы можете визуализировать текстуру FBO и использовать ее в шейдере в другом контексте.

glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, your_fbo_id);
// render to FBO there
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

затем используйте текстуру FBO так же, как и обычные текстуры.

person ChatCloud    schedule 10.05.2012
comment
Большое спасибо. Я протестировал его, изменил порядок, но он все еще не работает. - person mathew; 10.05.2012

glActiveTexture(GL_TEXTURE0); 

glBindTexture( GL_TEXTURE_RECTANGLE_NV, iTextureImgAccumulation ); // Bind our frame buffer texture 
xShader.setUniform1i("Texture0", 0);

Это прямоугольная текстура.

uniform sampler2D Texture0;

Это двухмерная текстура. Это не одно и то же. тип сэмплера должен соответствовать тип текстуры. Вам нужно использовать samplerRect, если ваша версия GLSL это поддерживает.

person Nicol Bolas    schedule 10.05.2012
comment
Большое спасибо. Я считаю, что сейчас я на правильном пути :)) Осталось только обновить свои шейдеры до версии 140 .. Можете порекомендовать какой-нибудь хороший туториал? - person mathew; 11.05.2012