Opengl es OpenGL ES 2.0绘制多个纹理

Opengl es OpenGL ES 2.0绘制多个纹理,opengl-es,textures,opengl-es-2.0,sprite,Opengl Es,Textures,Opengl Es 2.0,Sprite,我想我的问题很简单,我正在使用OpenGL ES 2.0绘制一个简单的2D场景。 我有一个延伸整个屏幕的背景纹理和另一个在屏幕上特定位置绘制的花(或雪碧?)纹理 因此,我可以考虑这样做的一个简单原因是调用glDrawArrays两次,一次调用背景纹理的顶点,另一次调用花卉纹理的顶点 这样对吗?如果是这样,这是否意味着对于10朵鲜花,我需要调用glDrawArrays10次 那么混合呢?如果我想将花与背景混合,我需要背景和花像素的颜色,这可能是两张画的问题没有 还是可以一次平局?如果是,我如何创建

我想我的问题很简单,我正在使用OpenGL ES 2.0绘制一个简单的2D场景。
我有一个延伸整个屏幕的背景纹理和另一个在屏幕上特定位置绘制的花(或雪碧?)纹理

因此,我可以考虑这样做的一个简单原因是调用
glDrawArrays
两次,一次调用背景纹理的顶点,另一次调用花卉纹理的顶点

这样对吗?如果是这样,这是否意味着对于10朵鲜花,我需要调用
glDrawArrays
10次

那么混合呢?如果我想将花与背景混合,我需要背景和花像素的颜色,这可能是两张画的问题没有

还是可以一次平局?如果是,我如何创建一个着色器,知道它现在是在处理背景纹理顶点还是花纹理顶点

还是可以一次抽签?

一次绘制的问题是着色器需要知道当前顶点是背景顶点(而不是使用背景纹理颜色)还是花朵顶点(而不是使用花朵纹理颜色),我不知道如何操作。

下面是我如何使用一个draw调用来绘制背景图像,该图像拉伸整个屏幕,并且花朵以一半大小为中心

- (void)renderOnce {
    //... set program, clear color..

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_2D, backgroundTexture);
    glUniform1i(backgroundTextureUniform, 2);

    glActiveTexture(GL_TEXTURE3);
    glBindTexture(GL_TEXTURE_2D, flowerTexture);
    glUniform1i(flowerTextureUniform, 3);

    static const GLfloat allVertices[] = {
        -1.0f, -1.0f, // background texture coordinates
        1.0f, -1.0f,  // to draw in whole screen
        -1.0f,  1.0f, //
        1.0f,  1.0f,

        -0.5f, -0.5f, // flower texture coordinates
        0.5f, -0.5f,  // to draw half screen size
        -0.5f,  0.5f, // and centered
        0.5f,  0.5f,  //
    };

    // both background and flower texture coords use the whole texture
    static const GLfloat backgroundTextureCoordinates[] = {
        0.0f, 0.0f,
        1.0f, 0.0f,
        0.0f, 1.0f,
        1.0f, 1.0f,
    };

    static const GLfloat flowerTextureCoordinates[] = {
        0.0f, 0.0f,
        1.0f, 0.0f,
        0.0f, 1.0f,
        1.0f, 1.0f,
    };

    glVertexAttribPointer(positionAttribute, 2, GL_FLOAT, 0, 0, allVertices);
    glVertexAttribPointer(backgroundTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, backgroundTextureCoordinates);
    glVertexAttribPointer(flowerTextureCoordinateAttribute, 2, GL_FLOAT, 0, 0, flowerTextureCoordinates);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
你有两个选择:

  • 为要绘制的每个纹理调用glDrawArrays,如果纹理超过10-20个,则速度会很慢,因为可以使用硬件vbo来加快速度
  • 批处理要在一个数组中绘制的所有精灵的顶点(顶点、纹理坐标、颜色),并使用纹理图集(包含要在其中绘制的所有图片的纹理)并使用一个glDrawArrays绘制所有这些

  • 第二种方法显然是更好和正确的。要了解如何做,请查看我的awnser

    谢谢你的回复,我更新了我的答案,并举例说明了如何使用一次抽签通话进行抽签。我的问题是如何构建一个着色器,该着色器将知道如何读取背景/花顶点的正确颜色。你能检查一下吗?这在opengl es中是不可能的。在调用glDrawArrays时,只有一个着色器可以激活,并且它的属性将是在glDrawArrays之前传递给它的最后一个值。唯一的方法是调用glDrawArrays两次,一次用于背景(使用背景着色器)对于所有的花(使用花的着色器)我很困惑,那么我该怎么做你建议的(选项2)?如果你真的想在一个绘制调用中完成,你可以在你的VBO中存储一个使用哪个纹理的ID(为每个顶点复制相同的ID)。这是完全可能的,但并不实际。假设您有一个动画精灵,您可以通过绑定10个纹理并选择要在着色器中采样的纹理来实现它。更好的方法是将帧打包到一个纹理中。类似地,正如SteveL所说,你可以用背景和你的花创建一个纹理图谱。然后使用纹理坐标来决定纹理,而不是ID。@Eyal,如果要使用不同的着色器,唯一的选项是为每个不同的着色器调用GLDrawArray。因此,方法是:1)绘制背景(如果只有一个背景,则使用背景着色器而不进行批处理)2)批处理并绘制所有的花(使用花卉着色器)。