Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OpenGL ES 1и2.docx
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
4.8 Mб
Скачать

Доступ к текстурам из шейдера.

Теперь поговорим о том, как получить доступ к текстуре из шейдера. Для этого в GLSL существует специальный тип униформы и называется он sampler2D. Сэмплеры можно объявлять только во фрагментном шейдере, например так:

uniform sampler2D u_texture;

Здесь u_texture-это имя униформы.

Теперь нам нужно связать униформу текстуры u_texture с текстурным объектом mTexture. Последовательность действий при этом следующая. Сначала нужно выбрать текущую активную программу:

GLES20.glUseProgram(program_Handle); 

Затем нужно получить ссылку на униформу u_texture:

int u_texture_Handle = GLES20.glGetUniformLocation(program_Handle, "u_texture");

В OpenGL ES 2.0 одновременно может быть загружено до 32 текстур в разные текстурные блоки. Каждый текстурный блок может содержать только одну текстуру. Текстурные блоки обозначают именами GL_TEXTURE0, GL_TEXTURE1, GL_TEXTURE2 и.т.д. Поэтому мы должны с начала выбрать текущий текстурный блок (например блок 0) :

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

Затем в этом блоке сделать активным наш текстурный объект mTexture:

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTexture.getName());

Здесь первый аргумент это тип текстуры GL_TEXTURE_2D, который говорит о том, что текстура является двумерной. Второй аргумент - это имя текстуры.

Окончательно связь текстурного объекта mTexture и униформы u_texture выполняется командой:

GLES20.glUniform1i(u_texture_Handle, 0);

Здесь первый аргумент - это ссылка на униформу u_texture. Второй аргумент - номер текстурного блока (в нашем случае 0). Связь текстурного объекта с униформой установлена.

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

uniform sampler2D u_texture0;

uniform sampler2D u_texture1;

и.т.д.

Далее нужно установить связь между объектом mTexture0 и униформой u_texture0, а также между объектом  mTexture1 и униформой u_texture1 и.т.д. 

Для примера рассмотрим случай двух текстур. 

Дополним наш класс Shader, описанный в первом уроке, методом linkTexture, который выполняет связь двух текстур с соответствующими сэмплерами:

public void linkTexture(Texture texture0,Texture texture1){

        // texture0, texture1 - текстурные объекты устанавливаем текущую активную программу         GLES20.glUseProgram(program_Handle);

        if (texture0 != null){

                //получаем ссылку на униформу u_texture0

                int u_texture0_Handle = GLES20.glGetUniformLocation(program_Handle, "u_texture0");

                //выбираем текущий текстурный блок GL_TEXTURE0          

                GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

                //в текстурном блоке GL_TEXTURE0 делаем активной текстуру с именем texture0.getName()  

                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture0.getName());

                //выполняем связь между объектом  texture0 и униформой u_texture0 в нулевом текстурном блоке

                GLES20.glUniform1i(u_texture0_Handle, 0);

        }

        if (texture1 != null){

                //получаем ссылку на униформу u_texture1

                int u_texture1_Handle = GLES20.glGetUniformLocation(program_Handle, "u_texture1");

                //выбираем текущий текстурный блок GL_TEXTURE1          

                GLES20.glActiveTexture(GLES20.GL_TEXTURE1);

                //в текстурном блоке GL_TEXTURE1 делаем активной текстуру с именем texture1.getName()  

                GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture1.getName());

                //выполняем связь между объектом  texture1 и униформой u_texture1 в первом текстурном блоке

                GLES20.glUniform1i(u_texture1_Handle, 1);

        }

}//конец метода Создавать текстурные объекты и связывать их с сэмплерами нужно в методе onSurfaceCreated класса рендерера, потому что при создании экрана они разрушаются.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]