Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL ES 2.0 drawing more than one texture

My question is quite trivial I believe, I'm using OpenGL ES 2.0 to draw a simple 2D scene.
I have a background texture that stretches the whole screen and another texture of a flower (or shel I say sprite?) that drawn at a specific location on screen.

So the trivial why i can think of doing it is to call glDrawArrays twice, one with the vertices of the background texture, and another one with the vertices of the flower texture.

Is that the right way? if so, is that mean that for 10 flowers i'll need to call glDrawArrays 10 times?

And what about blending? what if i want to blend the flower with the background, i need both the background and flower pixel colors and that may be a problem with two draws no?

Or is it possible to do it in one draw? if so how can I create a shader that knows if it now processing the background texture vertex or the flower texture vertex?

Or is it possible to do it in one draw?     

The problem with one draw is that the shader needs to know if the current vertex is a background vertex (than use the background texture color) or a flower vertex( than use the flower texture color), and I don't know how to do it.  

Here is how I use one draw call to draw the background image stretches the whole screen and the flower is half size centered.

- (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);
}
like image 688
Eyal Avatar asked Sep 30 '13 09:09

Eyal


People also ask

How do textures work in OpenGL?

A texture is an OpenGL Object that contains one or more images that all have the same image format. A texture can be used in two ways: it can be the source of a texture access from a Shader, or it can be used as a render target.

What is OpenGL 3. 0?

The OpenGL ES 3.0 API provides additional features and better performance than the 2.0 API and is also backward compatible. This means that you can potentially write your application targeting OpenGL ES 2.0 and conditionally include OpenGL ES 3.0 graphics features if they are available.

What is Android extension pack?

About the Android Extension Pack AEP is a set of OpenGL ES extensions that bring console-class gaming to Android. AEP features include: ASTC (LDR) texture compression format. Compute shaders. Geometry shaders.

How many textures can you load in OpenGL?

OpenGL 3. x defines the minimum number for the per-stage limit to be 16, so hardware cannot have fewer than 16 textures-per-stage.


1 Answers

You have two choices:

  1. Call glDrawArrays for every texture you want to draw, this will be slow if you have more than 10-20 textures, to speed it up thought you can use hardware vbo
  2. Batch the vertices(vertices,texture coords,color) of all the sprites you want to draw in one array and use a texture atlas(a texture that has all of the pictures you want to draw in it) and draw all this with one glDrawArrays

The second way is obviously the better and the right one.To get an idea of how to do it ,look at my awnser here

like image 117
SteveL Avatar answered Oct 17 '22 12:10

SteveL