具有不同uv坐标的OpenGL ES 1多纹理

roc*_*ick 5 opengl-es multitexturing ios

我需要使用多纹理渲染对象,但两个纹理对同一个对象都有不同的uv坐标.一个是法线贴图,另一个是光贴图.

请提供有关此的任何有用的材料.

Chr*_*ica 6

在OpenGL ES 2中,无论如何都要使用着色器.因此,您可以完全自由地使用您喜欢的任何纹理坐标.只需为第二个纹理cooridnate对引入一个附加属性,并像往常一样将其委托给片段着色器:

...
attribute vec2 texCoord0;
attribute vec2 texCoord1;

varying vec2 vTexCoord0;
varying vec2 vTexCoord1;

void main()
{
    ...
    vTexCoord0 = texCoord0;
    vTexCoord1 = texCoord1;
}
Run Code Online (Sandbox Code Playgroud)

在片段着色器中使用相应的坐标来访问纹理:

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

void main()
{
    ... = texture2D(tex0, vTexCoord0);
    ... = texture2D(tex1, vTexCoord1);
}
Run Code Online (Sandbox Code Playgroud)

当然,您需要为此新属性提供数据(使用glVertexAttribPointer).但如果所有这些听起来对你来说都很陌生,那么你应该深入研究一下GLSL着色器,或者你实际上使用OpenGL ES 1.在这种情况下你应该重新提出你的问题,我会更新我的答案.

编辑:根据您对OpenGL ES 1的更新,情况有点不同.我假设您已经知道如何使用单个纹理并为此指定纹理坐标,否则您应该在深入研究多纹理之前从那里开始.

随着glActiveTexture(GL_TEXTUREi)您可以激活第i个纹理单元.与纹理状态相关的所有后续操作仅涉及第i个纹理单元(如glBindTexture,但也glTexEnvgl(En/Dis)able(GL_TEXTURE_2D)).

对于指定纹理坐标,您仍然使用该glTexCoordPointer函数,与单个纹理一样,但glCientActiveTexture(GL_TEXTUREi)您可以选择以下调用glTexCoordPointerglEnableClientAttrib(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);
Run Code Online (Sandbox Code Playgroud)

我在第一个纹理之前设置第二个纹理的参数的原因只是为了在设置它们之后我们最终得到纹理单元0活动.我想我已经看到司机在绘图时遇到问题而另一个单位比单位0有效.最后在最后保留一个或多或少的干净状态总是一个好主意,这意味着默认纹理单元(GL_TEXTURE0)处于活动状态,否则不关心多纹理的代码可能会出现问题.

编辑:如果你使用立即模式(glBegin/glEnd)而不是顶点数组,那么你glTexCoordPointer当然不使用.在这种情况下,您glClientAttribTexture当然也不需要.你只需要使用glMultiTexCoord(GL_TEXTUREi, ...)与适当的纹理单元(GL_TEXTURE0,GL_TEXTURE1,...)代替glTexCoord(...).但是,如果我得到正确的通知,无论如何,OpenGL ES都没有立即模式.