Как визуализировать несколько текстур с помощью OpenGL?

Это было мое понимание основных шагов к рендерингу нескольких текстур.

1) Привяжите расположение шейдеров для рендеринга в

m_uihDiffuseMap = glGetUniformLocation( m_iShaderProgramHandle, "diffuseMap" );

if( m_uihDiffuseMap != -1 )
    glUniform1i( m_uihDiffuseMap, 0 );

m_uihNormalMap = glGetUniformLocation( m_iShaderProgramHandle, "normalMap" );

if( m_uihNormalMap != -1 )
    glUniform1i( m_uihNormalMap, 1 );

2) Привязать к тому, что вы хотите отобразить

glBindFramebuffer( GL_FRAMEBUFFER, m_uifboHandle );

//diffuse texture binding
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, m_uiTextureHandle1, 0);

//normal texture binding
                                   (or GL_COLOR_ATTACHMENT1)
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0+1, m_uiTextureHandle2, 0);

3) Очистите буфер и укажите, в какие буферы вы хотите рисовать.

glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);

4) Установите шейдерную программу для рендеринга

glUseProgram( m_uiShaderProgramHandle );

5) Передайте переменные в шейдер, как две наши разные текстуры.

glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, uihDiffuseMap );

               //or(GL_TEXTURE1)
glActiveTexture( GL_TEXTURE0+1 );
glBindTexture( GL_TEXTURE_2D, uihNormalMap );

6) Делайте рендер вызов вещей

//Draw stuff

7) верните все по умолчанию, если у вас есть другие процедуры рендеринга, использующие другие вещи

glBindFramebuffer( GL_FRAMEBUFFER, 0 );
glUseProgram( 0 );

--------------------------------------------ФРАГМЕНТНЫЙ ШЕЙДЕР------------------ ------------------

Во фрагментном шейдере вы должны вывести 2 результата, верно?

#version 330

in vec2 vTexCoordVary;

uniform sampler2D diffuseMap;
uniform sampler2D normalMap;

out vec4 fragColor[2];

void main( void )
{
    fragColor[0] = texture( diffuseMap, vTexCoordVary );
    fragColor[1] = texture( normalMap, vTexCoordVary );
};

Я перепроверил
. Моя диффузная текстура и нормальная текстура загружаются нормально. Если я передам свою обычную текстуру в качестве текстуры для использования в качестве TEXTURE0, она появится. -Я получаю fragColor[0] просто отлично. Когда я показываю fragColor[1] на экран, я получаю тот же результат, что и первый. Но я также жестко запрограммировал fragColor[1] для возврата сплошного серого внутри шейдера в качестве тестового примера, и это сработало.

Итак, мое предположение заключается в том, что когда я передаю свои текстуры шейдеру, он предполагает, что «normalMap» - это «diffuseMap»? Это мое единственное понимание того, почему я получу один и тот же результат в fragColor [0] и [1].


person Franky Rivera    schedule 25.08.2014    source источник
comment
Чтобы уточнить, вы рисуете текстуры, отличные от тех, которые вы используете в шейдере?   -  person Alexander Gessler    schedule 25.08.2014
comment
У меня есть 2 текстуры, которые просто используются для рисования на коробке. предполагается, что 2 результата: 1) текстура с блоком, нарисованным с помощью текстуры блока 1 2) текстура — это блок, нарисованный с текстурой 2   -  person Franky Rivera    schedule 25.08.2014
comment
Я не совсем понимаю. Можете ли вы уточнить?   -  person Alexander Gessler    schedule 25.08.2014
comment
2 текстуры для ящика..(diffuse map, normal map) 2 текстуры для заливки(результат1,результат2) на экран вывожу результат1, все хорошо.. на экран вывожу результат2, получаю тот же результат что и из результата1 .   -  person Franky Rivera    schedule 25.08.2014
comment
Желаемый результат должен быть.. Результат 1 должен показывать коробку в диффузных цветах Результат 2 должен показывать коробку в нормальных цветах   -  person Franky Rivera    schedule 25.08.2014
comment
Звук хороший до сих пор. Проверяли ли вы фреймбуфер и проверяли ли вы glError после каждого вызова API?   -  person Alexander Gessler    schedule 25.08.2014
comment
ummmmmmm Я думаю, что мне нужно какое-то объяснение для этого. Я добавил больше проверок glError(), и теперь все работает ...... Что, очевидно, не имеет смысла. Но я отлаживал этот мини-проект почти 2 часа и несколько раз пересобирал его. Ни одну часть не менял. Теперь я добавляю проверки glError() и все хорошо -_-.   -  person Franky Rivera    schedule 25.08.2014


Ответы (2)


Да, на данный момент информация о том, как ваши сэмплеры сопоставляются со слотами текстур, отсутствует, в результате чего оба ссылаются на диффузную карту. Используйте glUniform1i() для привязки индекса правильной текстуры к каждому слоту юниформ.

person Alexander Gessler    schedule 25.08.2014
comment
Извините, я забыл опубликовать это. Я обновил информацию. Теперь это должен быть шаг 1. Спасибо, что заметили =] - person Franky Rivera; 25.08.2014

Похоже, что шаг 1 и шаг 4 находятся в неправильном порядке. Это на шаге 1:

if( m_uihDiffuseMap != -1 )
    glUniform1i( m_uihDiffuseMap, 0 );

if( m_uihNormalMap != -1 )
    glUniform1i( m_uihNormalMap, 1 );

и это на шаге 4:

glUseProgram( m_uiShaderProgramHandle );

glUniform*() вызовы относятся к текущей активной программе. Таким образом, glUseProgram() должен быть вызван до вызова glUniform1i().

Также может быть хорошей идеей специально указать местоположение переменной out:

layout(location = 0) out vec4 fragColor[2];

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

person Reto Koradi    schedule 26.08.2014
comment
Расположение макета — это вещь openGL 4. Я использую 3.3 просто для небольшого ограничения. также я думаю, что это могло быть, когда я предопределил расположение этих текстур в шейдере. У меня был вызов LinkProgram(), но я забыл вызвать glUseProgram сразу после этого. Я понятия не имею, почему я предположил, что LinkProgram все еще связывает мою программу. Так что на самом деле дело было не в том, что 4 было неправильно, а в том, что мне также был нужен этот звонок заранее. - person Franky Rivera; 27.08.2014
comment
Квалификаторы местоположения макета доступны в GLSL версии 330. Решил ли проблему перенос вызова glUseProgram() ранее? - person Reto Koradi; 27.08.2014
comment
Я добавил glUseProgram перед настройкой этих переменных, и все выглядит хорошо. - person Franky Rivera; 27.08.2014