我需要使用多纹理渲染对象,但两个纹理对同一个对象都有不同的uv坐标。一个是法线贴图,另一个是光贴图。
请提供有关此事的任何有用资料。
答案 0 :(得分:6)
在OpenGL ES 2中,无论如何都要使用着色器。因此,您可以完全自由地使用您喜欢的任何纹理坐标。只需为第二个纹理cooridnate对引入一个额外的属性,并像往常一样将其委托给片段着色器:
...
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
和{{ 1}}参考。
所以它会是这样的:
glEnableClientAttrib(GL_TEXTURE_COORD_ARRAY)
我在第一个纹理之前设置第二个纹理的参数的原因只是为了在设置它们之后我们最终得到纹理单元0活动。我想我已经看到司机在绘图时遇到问题而另一个单位比单位0有效。最后在最后保留一个或多或少的干净状态总是一个好主意,这意味着默认纹理单元(//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);
)处于活动状态,否则不关心多纹理的代码可能会出现问题。 / p>
编辑:如果使用立即模式(GL_TEXTURE0
)而不是顶点数组,那么当然不要使用glBegin/glEnd
。在这种情况下,您当然也不需要glTexCoordPointer
。您只需将glClientAttribTexture
与适当的纹理单元(glMultiTexCoord(GL_TEXTUREi, ...)
,GL_TEXTURE0
,...)一起使用,而不是GL_TEXTURE1
。但是如果我得到正确的通知,无论如何,OpenGL ES都没有立即模式。