0

I am using OpenGL ES version 3 for my android game and have implemented instancing. It works well IF I use a polygon of the same size/dimension that is identical vertices. I can jump to different UV-coordinates of the texture atlas if I want to create change the sprites state for every frame.

v_TexCoordinate = a_TexCoordinate + uvCoordsOffset[gl_InstanceID];

that is .. I just change the texture coordinates with a uniform-vec which consists of offset coordinates.

BUT - here comes the issue.

What if I want to do the same but with sprites that have different dimensions?

in the drawcall ...

GLES30.glDrawElementsInstanced(GLES30.GL_TRIANGLES, 6,  GLES20.GL_UNSIGNED_SHORT, indexOffset, nFallingObj);

I can only send one polygon, that is the green dinosaur vertices in the screenshot. I have this as base polygon and I want to get to the RED dinosaur of the atlas. I can do this easily with texture offset as described above BUT you see how it becomes? the polygon of the green dinosaur is used but I want to be changed as of the red dinosaurs.

Is there any easy solution to this issue? thanks in advance!!!

some source-code

the draw-method

      public void drawFallingObjects() {

        GLES30.glUseProgram(mProgramHandle);

        GLES30.glEnableVertexAttribArray(mPositionHandle);
        GLES30.glVertexAttribPointer(mPositionHandle, CreateGLContext.POSITION_DATA_SIZE, GLES20.GL_FLOAT, false, CreateGLContext.STRIDE, 0);

        GLES30.glEnableVertexAttribArray(mTextureCoordinateHandle);
        GLES30.glVertexAttribPointer(mTextureCoordinateHandle,  CreateGLContext.TEXTURE_COORDINATE_DATA_SIZE, GLES20.GL_FLOAT, false,
            CreateGLContext.STRIDE, CreateGLContext.POSITION_DATA_SIZE * CreateGLContext.BYTES_PER_FLOAT);


        GLES30.glUniform2fv(uvCoordsOffsetLoc, nFallingObj, uvOffsetVec, 0);
        GLES30.glUniformMatrix4fv(mMVPMatrixHandle, nFallingObj, false, mMVPMatrixMajor, 0);

        GLES30.glDrawElementsInstanced(GLES30.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, indexOffset, nFallingObj);

    }

vertex-shader code

  void main()                                                   
{

   v_Color = a_Color;

   v_TexCoordinate = a_TexCoordinate + uvCoordsOffset[gl_InstanceID];

   gl_Position =  u_MVPMatrix[gl_InstanceID] * a_Position;

}   

enter image description here

BDL
  • 21,052
  • 22
  • 49
  • 55
java
  • 1,165
  • 1
  • 25
  • 50
  • You'll have to bind the correct vertices before drawing. – Androbin Nov 22 '17 at 13:43
  • 1
    The cost of correcting the MVP matrix for each instance every frame is probably more expensive than just animating the batch in software uploading a new vertex buffer. – solidpixel Nov 22 '17 at 14:13
  • 1
    @java beside the texture coordinate offset per instance (`uvCoordsOffset[gl_InstanceID]`) you need a texture scale per instance too. You have to do something like this: `v_TexCoordinate = a_TexCoordinate * uvCoordsScale[gl_InstanceID] + uvCoordsOffset[gl_InstanceID];` or combined in a `vec4`: `v_TexCoordinate = a_TexCoordinate * uvCoords[gl_InstanceID].zw + uvCoords[gl_InstanceID].xy;` – Rabbid76 Nov 22 '17 at 21:03
  • @Rabbid76 ok thanks - will look into this – java Nov 22 '17 at 21:41

1 Answers1

0

What if I want to do the same but with sprites that have different dimensions?

Your MVP matrix can encode scale and skew, which is all you need to adjust the on-screen sprite size.

solidpixel
  • 10,688
  • 1
  • 20
  • 33
  • but if I use glScale the whole sprite is distorted - I just want to adjust the polygon so it can fit the image – java Nov 22 '17 at 17:01
  • I didn't say use glScale, I said encode a scale and a skew in the MVP matrix. You can distort a rectangle arbitrarily using a matrix transform. – solidpixel Nov 23 '17 at 10:12