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 нет прямого режима, так или иначе.