OpenGL ES 1 мульти-текстурирование с различными координатами уф - PullRequest
5 голосов
/ 13 октября 2011

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

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

1 Ответ

6 голосов
/ 13 октября 2011

В 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 не имеет немедленного режима, в любом случае.

...