具有不同uv坐标的OpenGL

具有不同uv坐标的OpenGL

本文介绍了具有不同uv坐标的OpenGL ES 1多纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用多重纹理渲染对象,但是两个纹理对于同一对象具有不同的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.

推荐答案

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

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

当然,您需要为这个新属性提供数据(使用glVertexAttribPointer).但是,如果这一切听起来很陌生,那么您应该更深入地研究GLSL着色器,或者您实际使用OpenGL ES1.在这种情况下,您应该重新标记问题,我将更新答案.

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.

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

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.

使用glActiveTexture(GL_TEXTUREi),您可以激活第i个纹理单元.以下所有与纹理状态有关的操作都仅引用第i个纹理单位(例如glBindTexture,还包括glTexEnvgl(En/Dis)able(GL_TEXTURE_2D)).

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)).

对于指定纹理坐标,您仍然可以使用glTexCoordPointer函数,就像使用单一纹理一样,但是使用glCientActiveTexture(GL_TEXTUREi)时,您可以选择随后对glTexCoordPointerglEnableClientAttrib(GL_TEXTURE_COORD_ARRAY)的调用所引用的纹理单位.

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.

所以会是这样:

//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)处于活动状态,否则不关心多纹理的代码可能会出现问题.

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.

编辑:如果您使用即时模式(glBegin/glEnd)而不是顶点数组,那么您当然不会使用glTexCoordPointer.当然,在这种情况下,您也不需要glClientAttribTexture.您只需要将glMultiTexCoord(GL_TEXTUREi, ...)与相应的纹理单位(GL_TEXTURE0GL_TEXTURE1,...)一起使用,而不要使用glTexCoord(...).但是,如果我被正确告知,无论如何,OpenGL ES都不具有即时模式.

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.

这篇关于具有不同uv坐标的OpenGL ES 1多纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-23 12:47