OpenGL ES 2 sprite batching (Android)

Hello everyone!

Please forgive me for my english. I used Google translator.
I decided to write batching sprites. Looked SpriteBatch source of LibGDX and began to write.

Here’s what happened:

public class SpriteBatcher {
	
	protected Mesh2D mesh;
	protected SpriteShader shader;
	
	private boolean drawing;
	private Scene scene;
	
	private short last = 0;
	private int lastTexture = 0;
	private int count;
	
	public SpriteBatcher(Scene scene, int size, SpriteShader shader) {
		this.scene = scene;
		this.shader = shader;
		
		if (size > 5460) throw new IllegalArgumentException("Превышен лимит(5460 спрайтов) для батчинга! (size = " + size + ")");
		
		mesh = new Mesh2D();
		
		/*
		int t_size = size * 6;
		short[] triangles = new short[t_size];
		short j = 0;
		
		int last = 0;
        for(int i=0;i<30;i++)
        {
        	triangles[(i * 6) + 0] = (short) (last + 0);
        	triangles[(i * 6) + 1] = (short) (last + 1);
        	triangles[(i * 6) + 2] = (short) (last + 2);
        	triangles[(i * 6) + 3] = (short) (last + 0);
        	triangles[(i * 6) + 4] = (short) (last + 2);
        	triangles[(i * 6) + 5] = (short) (last + 3);
            last = last + 4;
        }
        */
	}
	
	public void begin() {
		if (drawing) throw new IllegalStateException("SpriteBatcher.end() должна вызываться перед SpriteBatcher.begin()!");
		
		shader.start();
		
		drawing = true;
	}
	
	public void draw(Sprite sprite) {
		if (!drawing) throw new IllegalStateException("SpriteBatch.begin() не была вызвана перед отрисовкой!");
		
		int texture = sprite.texture;
		
		if(texture != lastTexture) {
			switchTexture(texture);
		} else {
			flush();
		}
		
		
		float[] vertices = sprite.getTransformedVertices();
		
		mesh.addVertex(vertices[0], vertices[1]);
		mesh.addVertex(vertices[3], vertices[4]);
		mesh.addVertex(vertices[6], vertices[7]);
		mesh.addVertex(vertices[9], vertices[10]);
		
		mesh.addTriangle((short)(0 + last), (short)(1 + last), (short)(2 + last));
		mesh.addTriangle((short)(0 + last), (short)(2 + last), (short)(3 + last));
		
		mesh.addUvs(0, 0);
	  	mesh.addUvs(0, 1);
	  	mesh.addUvs(1, 1);
	  	mesh.addUvs(1, 0);
	  	
	  	last += 4;
	  	count++;
	}
	
	public void end() {
		if (!drawing) throw new IllegalStateException("SpriteBatcher.begin() должна вызываться перед SpriteBatcher.end()!");
		if(count > 0) flush();
		
		mesh.clear();
		lastTexture = 0;
		count = 0;
		last = 0;
		drawing = false;
		shader.stop();
	}
	
	private void flush() {
		if(count == 0) return;
		
		GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, lastTexture);
		mesh.setup();
		mesh.render(scene.getCamera(), shader);
		
		//count = 0;
	}
	
	private void switchTexture (int texture) {
		flush();
		lastTexture = texture;
	}
}

Here I load the sprites and drawing:

public class MainMenu extends Scene {
	
	private int logo_texture, bg_texture;
	private SpriteShader shader;

	SpriteBatcher batcher;
	Sprite logo, bg;
	
	public void onLoad() {
		
		logo_texture = getGameClass().getAssetManager().readTexture("interface/logo.png");
		bg_texture = getGameClass().getAssetManager().readTexture("interface/background.png");
		
		shader = new SpriteShader(getGameClass());
		batcher = new SpriteBatcher(this, 100, shader);
		bg = new Sprite(bg_texture, new Vector2D(400, 240), 800, 480);
		logo = new Sprite(logo_texture, new Vector2D(800 - 512, 480 - 96 / 2), 512, 96);
		
	}
	
	public void onUpdate() {
		
	}

	public void onDrawFrame() {
		batcher.begin();
		batcher.draw(bg);
		batcher.draw(logo);
		batcher.end();
	}

	public void onExit() {
		
	}
}

Everything works, but not correctly …

It must be like this:
http://s23.postimg.org/id0o9yw6j/image.png

But in fact, it looks like this:
http://s8.postimg.org/lbkusg0jp/Ijd_LF_5y_DMI.jpg

I do something screwed up. Can you tell what’s wrong here? Please! :slight_smile: