Ios4 如何使用OpenGL ES 2.0显示多个单独的纹理(而不是多纹理)?

Ios4 如何使用OpenGL ES 2.0显示多个单独的纹理(而不是多纹理)?,ios4,opengl-es-2.0,textures,Ios4,Opengl Es 2.0,Textures,我的iOS 4应用程序使用OpenGL ES 2.0,并使用单一纹理渲染元素。我想画元素使用多种不同的纹理和我有问题的东西来工作 我在顶点着色器中添加了一个变量,以指示要应用的纹理: ... attribute float TextureIn; varying float TextureOut; void main(void) { ... TextureOut = TextureIn; } 我在片段着色器中使用该值来选择纹理: ... varying lowp float

我的iOS 4应用程序使用OpenGL ES 2.0,并使用单一纹理渲染元素。我想画元素使用多种不同的纹理和我有问题的东西来工作

我在顶点着色器中添加了一个变量,以指示要应用的纹理:

...
attribute float TextureIn;
varying float TextureOut;

void main(void)
{ 
    ...
    TextureOut = TextureIn;
}
我在片段着色器中使用该值来选择纹理:

...
varying lowp float TextureOut;

uniform sampler2D Texture0;
uniform sampler2D Texture1;

void main(void)
{   
    if (TextureOut == 1.0) 
    {
        gl_FragColor = texture2D(Texture1, TexCoordOut);
    }
    else // 0
    {
        gl_FragColor = texture2D(Texture0, TexCoordOut);
    }
}
编译着色器:

...
_texture = glGetAttribLocation(programHandle, "TextureIn");
glEnableVertexAttribArray(_texture);
_textureUniform0 = glGetUniformLocation(programHandle, "Texture0");
_textureUniform1 = glGetUniformLocation(programHandle, "Texture1");
初始化/设置:

...
GLuint _texture;
GLuint _textureUniform0;
GLuint _textureUniform1;

...
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D); // ?
glBindTexture(GL_TEXTURE_2D, _textureUniform0);
glUniform1i(_textureUniform0, 0);

glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D); // ?
glBindTexture(GL_TEXTURE_2D, _textureUniform1);
glUniform1i(_textureUniform1, 1);

glActiveTexture(GL_TEXTURE0);
呈现:

...
glVertexAttribPointer(_texture, 1, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 13));    

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _textureUniform0);
glUniform1i(_textureUniform0, 0);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, _textureUniform1);
glUniform1i(_textureUniform1, 1);

glActiveTexture(GL_TEXTURE0);

glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0));
glDrawElements(GL_TRIANGLES, indicesCountB, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * indicesCountA));
glDrawElements(GL_TRIANGLES, indicesCountC, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * (indicesCountA + indicesCountB)));
我希望动态应用与顶点关联的纹理,但它似乎只能识别GL_TEXTURE0

我能够更改纹理的唯一方法是将每个纹理与GL_TEXTURE0关联,然后绘制:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _textureUniformX);
glUniform1i(_textureUniformX, 0);
glDrawElements(GL_TRIANGLES, indicesCountA, GL_UNSIGNED_SHORT, (GLvoid*) (sizeof(GLushort) * 0));
...
为了渲染所有的纹理,我需要为每个纹理分别调用一个glDrawerElements(),我已经了解到glDrawerElements()调用对性能有很大的影响,调用的数量应该最小化。这就是为什么我试图动态指定每个顶点使用的纹理

完全有可能我的理解是错误的,或者我遗漏了一些重要的东西。我还是OpenGL新手,我学的越多,我就越觉得我有更多的东西要学

除了GL_TEXTURE0之外,必须可以使用其他纹理,但我还没有弄清楚如何使用


如果您有任何指导或指示,我们将不胜感激。

您是否只是遇到了浮点舍入问题?不应该有任何属性(除非单个privimitve共享具有不同纹理的顶点),但要确保将此
TextureOut==1.0
替换为
TextureOut>0.5
或类似的属性

一般来说,您的建议是正确的,即抽签调用的数量应该尽可能减少,但您的方法非常奇怪。您正在购买使用片段着色器分支的draw call Reduce。您的方法也不能很好地与纹理的总数进行缩放,因为您总是需要将所有纹理放在单独的纹理单元中

减少纹理切换的常用方法是将所有纹理放入一个大纹理中,即所谓的纹理图集,并使用纹理坐标在此纹理中选择适当的子区域。这也有一些陷阱(这是一个完全不同的问题),但没有什么是免费的

编辑:哦,等等,我知道你到底做错了什么

glBindTexture(GL_TEXTURE_2D, _textureUniform0);

您正在将纹理绑定到当前纹理单元,但是您为该函数指定了一个统一的位置,而不是纹理对象,这完全是垃圾(但在某些奇怪的情况下甚至可能工作,因为统一位置和纹理对象本身都只是整数)。当然,您必须绑定实际纹理。

更改为正确绑定纹理并检查浮动范围,但仍然存在问题。只有7种纹理,我想把它作为第一步。最后,我想选择这7种纹理的不同区域,使其具有数十种或数百种不同的纹理。发现了纹理图谱的想法,并将其作为我的下一步。既然我本来希望去查看纹理地图集,也许我现在就走这条路。感谢您的输入。发现如果我在片段着色器中指定一个值来选择纹理,该纹理确实会被渲染:lowp float temp=1.0;//纹理输出;如果((温度>0.5)和(&(温度<1.5))//1。。。动态传递TextureOut值似乎有问题,所以我正在对此进行研究。成功!我找到了一行我忘记输入的代码:vertex.Texture=[(NSNumber*)[vertexBucketAll objectAtIndex:(I+13)]floatValue];如果我不在顶点数组中实际设置纹理数据,就不会有多大进展。那次修正,加上你的指点,让我渡过了难关。现在我们来看看下一个头发拉扯的迪勒玛,我想是纹理图谱。谢谢,仅供参考,一切正常,但在解决一个小细节上却遇到了麻烦,这个小细节给我带来了一个大问题。可变低压浮点数;显然,lowp的精度很低,范围为-2到2。当然,我的纹理范围超出了这一范围,我只是不知道处理6以下的数字可能有多困难。升级到mediump,现在它的工作非常出色(目前)。可变中间泵浮动纹理输出;唷!