Rendering multiple 2D images in OpenGL-ES 2.0

后端 未结 2 1288
旧巷少年郎
旧巷少年郎 2021-01-15 02:53

I am new to OpenGL, and trying to learn ES 2.0.

To start with, I am working on a card game, where I need to render multiple card images. I followed this http://www.l

相关标签:
2条回答
  • 2021-01-15 03:36

    Your code mixes up two concepts: texture ids (or, as they are called in the official OpenGL documentation, texture names), and texture units:

    • A texture id is a unique id for each texture object, where a texture object owns the actual data, as well as sampling parameters. You can have a virtually unlimited number of texture objects, with the practical limit typically being the amount of memory on your machine.
    • A texture unit is an entry in a table of textures that are currently bound, and available to be sampled by a shader. The maximum size of this table is an implementation dependent limit, which can be queried with glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, ...). The guaranteed minimum for compliant ES 2.0 implementations is 8.

    You're using texture ids correctly while creating your textures, by generating an id with glGenTextures(), binding it with glBindTexture(), and then setting up the texture.

    The problem is where you set up the textures for drawing:

    GLES20.glUniform1i(u_texture, ms.getTextureId());
    

    The value of the sampler uniform is not a texture id, it is the index of a texture unit. You then need to bind the texture you want to use to the texture unit you specify.

    Using texture unit 0, the correct code looks like this:

    GLES20.glUniform1i(u_texture, 0);
    GLES20.glActiveTexture(GL_TEXTURE0);
    GLES20.glBindTexture(ms.getTextureId());
    

    A few remarks on this code sequence:

    • Note that the uniform value is the index of the texture unit (0), while the argument of glActiveTexture() is the corresponding enum (GL_TEXTURE0). That's because... it was defined that way. Unfortunate API design, IMHO, but you just need to be aware of it.
    • glBindTexture() binds the texture to the currently active texture unit, so it needs to come after glActiveTexture().
    • The glActiveTexture() call is not really needed if you only ever use one texture. GL_TEXTURE0 is the default value. I put it there to illustrate how the connection between texture unit and texture id is established.

    Multiple texture units are used if you want to sample multiple textures in the same shader.

    0 讨论(0)
  • 2021-01-15 03:47

    To begin I'll point out some general things about OpenGL:

    Each texture is a large square image. Loading that image into the gpu's memory takes time, as in you can't actively swap images into gpu's texture memory and hope for a fast run time.

    Q1: The reason only the second image is showing is because of this line in your sprite class:

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);
    

    You call that twice, therefore texture0 is replaced by the second image, and only that image is called.

    To combat this, developers load a single image that contains a lot of smaller images in it, aka a texture map. The size of the image that can be loaded largely depends on the gpu. Android devices range roughly from 1024^2 pixels to 4096^2 pixels.

    To use a smaller part of the texture for a sprite, you have to manually define the uvArray that is in your batcher class.

    Let's imagine our texture has 4 images divided as follows:

     (0.0, 0.0) top left   _____ (1.0, 0.0) top right
                          |__|__| middle of the square is (0.5, 0.5) middle
     (0.0, 1.0) bot left  |__|__|(1.0, 1.0) bot right
    

    That means the uv values for the top left image are:

    static float[] uvArray = new float[]{
            0.0f, 0.0f, //top left
            0.0f, 0.5f, //bot left
            0.5f, 0.5f, //bot right
            0.5f, 0.0f  //top right
    };
    

    This way you just quadrupled the amount of sprites you can have on a texture.

    Because of this you will have to pass no only which texture the sprite is on, but also it's custom uvs that the batcher should use.

    0 讨论(0)
提交回复
热议问题