OpenGL ES 1 мульти-текстурирование с различными координатами уф

Мне нужно визуализировать объект с использованием мультитекстурирования, но обе текстуры имеют разные UV-координаты для одного и того же объекта. Один - это карта нормалей, а другой - карта света.

Пожалуйста, предоставьте любой полезный материал относительно этого.

1 ответ

Решение

В OpenGL ES 2 вы все равно используете шейдеры. Так что вы можете свободно использовать любые текстурные координаты, которые вам нравятся. Просто добавьте дополнительный атрибут для второй пары координатных текстур и передайте его фрагментному шейдеру, как обычно:

...
attribute vec2 texCoord0;
attribute vec2 texCoord1;

varying vec2 vTexCoord0;
varying vec2 vTexCoord1;

void main()
{
    ...
    vTexCoord0 = texCoord0;
    vTexCoord1 = texCoord1;
}

А в фрагментном шейдере используйте соответствующие координаты для доступа к текстурам:

...
uniform sampler2D tex0;
uniform sampler2D tex1;
...
varying vec2 vTexCoord0;
varying vec2 vTexCoord1;

void main()
{
    ... = texture2D(tex0, vTexCoord0);
    ... = texture2D(tex1, vTexCoord1);
}

И, конечно, вам нужно предоставить данные для этого нового атрибута (используя glVertexAttribPointer). Но если все это звучит для вас очень чуждо, то вам следует либо углубиться в шейдеры GLSL, либо использовать OpenGL ES 1. В этом случае вам следует повторно пометить свой вопрос, и я обновлю свой ответ.

РЕДАКТИРОВАТЬ: Согласно вашему обновлению для OpenGL ES 1 ситуация немного отличается. Я предполагаю, что вы уже знаете, как использовать одну текстуру и указать для нее координаты текстуры, иначе вам следует начать с нее, прежде чем углубляться в мультитекстурирование.

С glActiveTexture(GL_TEXTUREi) Вы можете активировать i-ю текстурную единицу. Все последующие операции, связанные с состоянием текстуры, относятся только к i-му текстурному блоку (например, glBindTexture, но также glTexEnv а также gl(En/Dis)able(GL_TEXTURE_2D)).

Для указания координат текстуры вы все еще используете glTexCoordPointer функция, как с одиночным текстурированием, но с glCientActiveTexture(GL_TEXTUREi) Вы можете выбрать текстурный блок, к которому следующие вызовы glTexCoordPointer а также glEnableClientAttrib(GL_TEXTURE_COORD_ARRAY) см.

Так что это будет что-то вроде:

//bind and enable textures
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, <second texture>);
glTexEnv(<texture environment for second texture>);   //maybe, if needed
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, <first texture>);
glTexEnv(<texture environment for first texture>);   //maybe, if needed
glEnable(GL_TEXTURE_2D);

//set texture coordinates
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(<texCoords for second texture>);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glTexCoordPointer(<texCoords for first texture>);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

//other arrays, like glVertexPointer, ...

glDrawArrays(...)/glDrawElements(...);

//disable arrays
glClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);

//disable textures
glActiveTexture(GL_TEXTURE1);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);

Причина, по которой я установил параметры для второй текстуры перед первой текстурой, заключается лишь в том, что после их установки мы получим активную единицу текстуры 0. Я думаю, что я уже видел проблемы с драйверами при рисовании, и был активен другой блок, кроме блока 0. И всегда полезно оставить в конце более или менее чистое состояние, что означает блок текстуры по умолчанию (GL_TEXTURE0) активен, так как в противном случае код, который не заботится о мультитекстурировании, может получить проблемы.

РЕДАКТИРОВАТЬ: Если вы используете немедленный режим (glBegin/glEnd) вместо массивов вершин, то вы не используете glTexCoordPointer, конечно. В этом случае вам также не нужно glClientAttribTexture, конечно. Вам просто нужно использовать glMultiTexCoord(GL_TEXTUREi, ...) с соответствующим текстурным блоком (GL_TEXTURE0, GL_TEXTURE1,...) вместо glTexCoord(...), Но если я правильно проинформирован, у OpenGL ES нет прямого режима, так или иначе.

Другие вопросы по тегам