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

发布于 2024-12-09 08:39:28 字数 86 浏览 1 评论 0原文

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

请提供与此相关的任何有用材料。

I need to render an object using multi-texturing but both the textures have different uv coordinates for same object. One is normal map and other one is light map.

Please provide any useful material regarding this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半衬遮猫 2024-12-16 08:39:28

在 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,还有 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);

我在第一个纹理之前设置第二个纹理的参数的原因只是为了在设置它们之后我们最终会激活纹理单元 0。我想我已经看到驱动程序在绘图时出现问题,并且除单元 0 之外的另一个单元处于活动状态。最后留下或多或少干净的状态总是一个好主意,这意味着默认纹理单元(GL_TEXTURE0)处于活动状态,否则不关心多重纹理的代码可能会问题。

编辑:如果您使用立即模式 (glBegin/glEnd) 而不是顶点数组,那么您当然不会使用 glTexCoordPointer。当然,在这种情况下,您也不需要 glClientAttribTexture。您只需将 glMultiTexCoord(GL_TEXTUREi, ...) 与适当的纹理单元 (GL_TEXTURE0, GL_TEXTURE1, ...) 结合使用,而不是glTexCoord(...)。但如果我没被告知的话,OpenGL ES 无论如何都没有即时模式。

In OpenGL ES 2 you use shaders anyway. So you're completely free to use whatever texture coordinates you like. Just introduce an additional attribute for the second texture cooridnate pair and delegate this to the fragment shader, as usual:

...
attribute vec2 texCoord0;
attribute vec2 texCoord1;

varying vec2 vTexCoord0;
varying vec2 vTexCoord1;

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

And in the fragment shader use the respective coordinates to access the textures:

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

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

And of course you need to provide data to this new attribute (using glVertexAttribPointer). But if all this sounds very alien to you, then you should either delve a little deeper into GLSL shaders or you actually use OpenGL ES 1. In this case you should retag your question and I will update my answer.

EDIT: According to your update for OpenGL ES 1 the situation is a bit different. I assume you already know how to use a single texture and specify texture coordinates for this, otherwise you should start there before delving into multi-texturing.

With glActiveTexture(GL_TEXTUREi) you can activate the ith texture unit. All following operations related to texture state only refer to the ith texture unit (like glBindTexture, but also glTexEnv and gl(En/Dis)able(GL_TEXTURE_2D)).

For specifying the texture coordinates you still use the glTexCoordPointer function, as with single texturing, but with glCientActiveTexture(GL_TEXTUREi) you can select the texture unit to which following calls to glTexCoordPointer and glEnableClientAttrib(GL_TEXTURE_COORD_ARRAY) refer.

So it would be something like:

//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);

The reason I set the parameters for the second texture before the first texture is only so that after setting them we end up with texture unit 0 active. I think I have already seen drivers making problems when drawing and another unit than unit 0 was active. And it's always a good idea to leave a more or less clean state at the end, which means the default texture unit (GL_TEXTURE0) active, as otherwise code that doesn't care about multi-texturing could get problems.

EDIT: If you use immediate mode (glBegin/glEnd) instead of vertex arrays, then you don't use glTexCoordPointer, of course. In this case you also don't need glClientAttribTexture, of course. You just need to use glMultiTexCoord(GL_TEXTUREi, ...) with the appropriate texture unit (GL_TEXTURE0, GL_TEXTURE1, ...) instead of glTexCoord(...). But if I'm informed correctly, OpenGL ES doesn't have immediate mode, anyway.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文