<commit_before>package com.badlogic.gdx.graphics;

import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.graphics.Font.Glyph;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.math.Matrix;

/**
 * A SpriteBatch is used to draw 2D rectangles that reference a 
 * texture. The class will batch the drawing commands and optimize
 * them for processing by the GPU.
 * 
 * To draw something with a SpriteBatch one has to first call the
 * {@link SpriteBatch.begin()} method which will setup apropriate
 * render states. When you are done with drawing you have to call
 * {@link SpriteBatch.end()} which will actually draw the things you
 * specified.
 * 
 * All drawing commands of the SpriteBatch operate in screen coordinates.
 * The screen coordinate system has an x-axis pointing to the right, an
 * y-axis pointing upwards and the origin is in the lower left corner of
 * the screen.
 * 
 * A sprite rendered via this batch has an origin relative to it's
 * top left corner and a position in screen coordinates for that origin.
 * 
 * A sprite has a width and height in screen coordinates
 * 
 * A sprite can be scaled on the x and y axis.
 * 
 * A sprite can be rotated around the origin by some angle.
 * 
 * A sprite references a portion of a texture where the portion is specified in texels.
 * 
 * @author mzechner
 *
 */
public final class SpriteBatch 
{	
	private static final int MAX_VERTICES = 6 * 5000;
	
	/** the mesh used to transfer the data to the GPU **/
	private final Mesh mesh;
	
	/** the graphics instance **/
	private final Graphics graphics;			
	
	/** the transform to be applied to all sprites **/
	private final Matrix transform = new Matrix();
	
	/** the view matrix holding the orthogonal projection **/
	private final Matrix viewMatrix = new Matrix();
	
	/** the vertex storage **/
	private final float[] vertices = new float[MAX_VERTICES * (2 + 4 + 2)];
	
	/** last texture **/
	private Texture lastTexture = null;
	
	/** current index into vertices **/
	private int idx = 0;
	
	/** drawing flag **/
	private boolean drawing = false;
	
	/** inverse texture width and height **/
	private float invTexWidth = 0;
	private float invTexHeight = 0;
	
	/** whether to use the blend mode for text or for sprites **/
	private boolean useTextBlend = false;
	
	/** the shader for opengl 2.0 **/
	private ShaderProgram shader;
	
	/** number of render calls **/
	public int renderCalls = 0;

	/** whether blending is enabled or not **/
	private boolean blendingDisabled;
	
	/**
	 * Consturctor, sets the {@link Graphics} instance
	 * to use.
	 * 
	 * @param graphics the Graphics instance
	 */
	public SpriteBatch( Graphics graphics )
	{
		this.graphics = graphics;		
		this.mesh = new Mesh( graphics, true, false, false, MAX_VERTICES, 0, 
							  new VertexAttribute( Usage.Position, 2, "a_position" ),
							  new VertexAttribute( Usage.Color, 4, "a_color" ),
							  new VertexAttribute( Usage.TextureCoordinates, 2, "a_texCoords" ) );
		viewMatrix.setToOrtho2D( 0, 0, graphics.getWidth(), graphics.getHeight() );
		
		if( graphics.isGL20Available() )
			createShader( );
	}
	
	private void createShader( )
	{
		String vertexShader = "attribute vec4 a_position; \n" +
							  "attribute vec4 a_color; \n" + 
							  "attribute vec2 a_texCoords; \n" +
							  "uniform mat4 u_projectionViewMatrix; \n" +
							  "varying vec4 v_color; \n" +
							  "varying vec2 v_texCoords; \n" +
							  " \n" + 
							  "void main()                  \n" +
							  "{                            \n" +
							  "   v_color = a_color; \n" +
							  "   v_texCoords = a_texCoords; \n" +
							  "   gl_Position =  u_projectionViewMatrix * a_position;  \n" +
							  "}  \n";
		String fragmentShader = "precision mediump float;\n" +
								"varying vec4 v_color;\n" +
								"varying vec2 v_texCoords;\n" +								
								"uniform sampler2D u_texture;\n" +
								"void main()                                  \n" +
							    "{                                            \n" +							    							   
							    "  gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n" +
							    "}"; 
		
		shader = new ShaderProgram( graphics.getGL20(), vertexShader, fragmentShader, true);
		if( shader.isCompiled() == false )
			throw new IllegalArgumentException( "couldn't compile shader: " + shader.getLog()  );
	}
	
	/**
	 * Sets up the SpriteBatch for drawing. This will disable
	 * depth buffer testing and writting, culling and lighting.
	 * It enables blending and alpha testing. It sets the projection
	 * matrix to an orthographic matrix and the modelview and texture
	 * matrix to identity. If you have more texture units enabled than
	 * the first one you have to disable them before calling this.  
	 */
	public void begin( )
	{
		renderCalls = 0;
		transform.idt();		
		begin( transform );
	}
	
	/**
	 * Sets up the SpriteBatch for drawing. This will disable
	 * depth buffer testing and writting, culling and lighting.
	 * It enables blending and alpha testing. It sets the projection
	 * matrix to an orthographic matrix and the modelview and texture
	 * matrix to identity. If you have more texture units enabled than
	 * the first one you have to disable them before calling this. Applies
	 * the given transformation {@link Matrix} to all subsequently specified sprites.
	 * 
	 * @param transform the transformation matrix.
	 */
	public void begin( Matrix transform )
	{
		if( graphics.isGL20Available() == false )
		{
			transform.set( transform );
			viewMatrix.setToOrtho2D( 0, 0, graphics.getWidth(), graphics.getHeight() );
					
			GL10 gl = graphics.getGL10();
			gl.glViewport( 0, 0, graphics.getWidth(), graphics.getHeight() );
			gl.glDisable( GL10.GL_LIGHTING );
			gl.glDisable( GL10.GL_DEPTH_TEST );
			gl.glDisable( GL10.GL_CULL_FACE );
			gl.glDepthMask ( false );
			
			gl.glEnable( GL10.GL_TEXTURE_2D );
			gl.glActiveTexture( GL10.GL_TEXTURE0 );
			
			if( !blendingDisabled )
			{
				gl.glEnable( GL10.GL_BLEND );						;				
				gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );							
			}			
			else
			{
				gl.glDisable( GL10.GL_BLEND );				
			}
			
			gl.glMatrixMode( GL10.GL_PROJECTION );
			gl.glLoadMatrixf( viewMatrix.val, 0 );
			gl.glMatrixMode( GL10.GL_MODELVIEW );
			gl.glLoadMatrixf( transform.val, 0 );
		}		
		else
		{
			transform.set( transform );
			viewMatrix.setToOrtho2D( 0, 0, graphics.getWidth(), graphics.getHeight() ).mul(transform);
					
			GL20 gl = graphics.getGL20();		
			gl.glViewport( 0, 0, graphics.getWidth(), graphics.getHeight() );
			gl.glDisable( GL20.GL_DEPTH_TEST );
			gl.glDisable( GL20.GL_CULL_FACE );
			gl.glDepthMask ( false );
			
			gl.glEnable( GL20.GL_TEXTURE_2D );
			gl.glActiveTexture( GL20.GL_TEXTURE0 );
			
			if( !blendingDisabled )
			{
				gl.glEnable( GL20.GL_BLEND );						;				
				gl.glBlendFunc( GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA );							
			}			
			else
			{
				gl.glDisable( GL20.GL_BLEND );				
			}
			
			shader.begin();
			shader.setUniformMatrix( "u_projectionViewMatrix", viewMatrix );<commit_msg>[fixed] issue 11, you can now pass a projection matrix to spritebatch.<commit_after>package com.badlogic.gdx.graphics;

import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.graphics.Font.Glyph;
import com.badlogic.gdx.graphics.VertexAttributes.Usage;
import com.badlogic.gdx.math.Matrix;

/**
 * A SpriteBatch is used to draw 2D rectangles that reference a 
 * texture. The class will batch the drawing commands and optimize
 * them for processing by the GPU.
 * 
 * To draw something with a SpriteBatch one has to first call the
 * {@link SpriteBatch.begin()} method which will setup apropriate
 * render states. When you are done with drawing you have to call
 * {@link SpriteBatch.end()} which will actually draw the things you
 * specified.
 * 
 * All drawing commands of the SpriteBatch operate in screen coordinates.
 * The screen coordinate system has an x-axis pointing to the right, an
 * y-axis pointing upwards and the origin is in the lower left corner of
 * the screen.
 * 
 * A sprite rendered via this batch has an origin relative to it's
 * top left corner and a position in screen coordinates for that origin.
 * 
 * A sprite has a width and height in screen coordinates
 * 
 * A sprite can be scaled on the x and y axis.
 * 
 * A sprite can be rotated around the origin by some angle.
 * 
 * A sprite references a portion of a texture where the portion is specified in texels.
 * 
 * @author mzechner
 *
 */
public final class SpriteBatch 
{	
	private static final int MAX_VERTICES = 6 * 5000;
	
	/** the mesh used to transfer the data to the GPU **/
	private final Mesh mesh;
	
	/** the graphics instance **/
	private final Graphics graphics;			
	
	/** the transform to be applied to all sprites **/
	private final Matrix transform = new Matrix();
	
	/** the view matrix holding the orthogonal projection **/
	private final Matrix viewMatrix = new Matrix();
	
	/** the vertex storage **/
	private final float[] vertices = new float[MAX_VERTICES * (2 + 4 + 2)];
	
	/** last texture **/
	private Texture lastTexture = null;
	
	/** current index into vertices **/
	private int idx = 0;
	
	/** drawing flag **/
	private boolean drawing = false;
	
	/** inverse texture width and height **/
	private float invTexWidth = 0;
	private float invTexHeight = 0;
	
	/** whether to use the blend mode for text or for sprites **/
	private boolean useTextBlend = false;
	
	/** the shader for opengl 2.0 **/
	private ShaderProgram shader;
	
	/** number of render calls **/
	public int renderCalls = 0;

	/** whether blending is enabled or not **/
	private boolean blendingDisabled;
	
	/**
	 * Consturctor, sets the {@link Graphics} instance
	 * to use.
	 * 
	 * @param graphics the Graphics instance
	 */
	public SpriteBatch( Graphics graphics )
	{
		this.graphics = graphics;		
		this.mesh = new Mesh( graphics, true, false, false, MAX_VERTICES, 0, 
							  new VertexAttribute( Usage.Position, 2, "a_position" ),
							  new VertexAttribute( Usage.Color, 4, "a_color" ),
							  new VertexAttribute( Usage.TextureCoordinates, 2, "a_texCoords" ) );
		viewMatrix.setToOrtho2D( 0, 0, graphics.getWidth(), graphics.getHeight() );
		
		if( graphics.isGL20Available() )
			createShader( );
	}
	
	private void createShader( )
	{
		String vertexShader = "attribute vec4 a_position; \n" +
							  "attribute vec4 a_color; \n" + 
							  "attribute vec2 a_texCoords; \n" +
							  "uniform mat4 u_projectionViewMatrix; \n" +
							  "varying vec4 v_color; \n" +
							  "varying vec2 v_texCoords; \n" +
							  " \n" + 
							  "void main()                  \n" +
							  "{                            \n" +
							  "   v_color = a_color; \n" +
							  "   v_texCoords = a_texCoords; \n" +
							  "   gl_Position =  u_projectionViewMatrix * a_position;  \n" +
							  "}  \n";
		String fragmentShader = "precision mediump float;\n" +
								"varying vec4 v_color;\n" +
								"varying vec2 v_texCoords;\n" +								
								"uniform sampler2D u_texture;\n" +
								"void main()                                  \n" +
							    "{                                            \n" +							    							   
							    "  gl_FragColor = v_color * texture2D(u_texture, v_texCoords);\n" +
							    "}"; 
		
		shader = new ShaderProgram( graphics.getGL20(), vertexShader, fragmentShader, true);
		if( shader.isCompiled() == false )
			throw new IllegalArgumentException( "couldn't compile shader: " + shader.getLog()  );
	}
	
	/**
	 * Sets up the SpriteBatch for drawing. This will disable
	 * depth buffer testing and writting, culling and lighting.
	 * It enables blending and alpha testing. It sets the projection
	 * matrix to an orthographic matrix and the modelview and texture
	 * matrix to identity. If you have more texture units enabled than
	 * the first one you have to disable them before calling this.  
	 */
	public void begin( )
	{		
		transform.idt();		
		begin( transform );
	}
	
	/**
	 * Sets up the SpriteBatch for drawing. This will disable
	 * depth buffer testing and writting, culling and lighting.
	 * It enables blending and alpha testing. If you have more texture units enabled than
	 * the first one you have to disable them before calling this. Applies
	 * the given transformation {@link Matrix} to all subsequently specified sprites. Loads
	 * an orthographic projection matrix with the full screen as the viewport.
	 * 
	 * @param transform the transformation matrix.
	 */
	public void begin( Matrix transform )
	{		
		viewMatrix.setToOrtho2D( 0, 0, graphics.getWidth(), graphics.getHeight() );
		begin( viewMatrix, transform );
	}
	
	/**
	 * Sets up the SpriteBatch for drawing. This will disable
	 * depth buffer testing and writting, culling and lighting.
	 * It enables blending and alpha testing. If you have more texture units enabled than
	 * the first one you have to disable them before calling this. Applies
	 * the given transformation {@link Matrix} to all subsequently specified sprites. Uses
	 * the provided projection matrix.
	 * 
	 * @param projection the projection matrix;
	 * @param transform the transformation matrix.
	 */
	public void begin( Matrix projection, Matrix transform )
	{
		renderCalls = 0;
		if( graphics.isGL20Available() == false )
		{										
			GL10 gl = graphics.getGL10();
			gl.glViewport( 0, 0, graphics.getWidth(), graphics.getHeight() );
			gl.glDisable( GL10.GL_LIGHTING );
			gl.glDisable( GL10.GL_DEPTH_TEST );
			gl.glDisable( GL10.GL_CULL_FACE );
			gl.glDepthMask ( false );
			
			gl.glEnable( GL10.GL_TEXTURE_2D );
			gl.glActiveTexture( GL10.GL_TEXTURE0 );
			
			if( !blendingDisabled )
			{
				gl.glEnable( GL10.GL_BLEND );						;				
				gl.glBlendFunc( GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA );							
			}			
			else
			{
				gl.glDisable( GL10.GL_BLEND );				
			}
			
			gl.glMatrixMode( GL10.GL_PROJECTION );
			gl.glLoadMatrixf( projection.val, 0 );
			gl.glMatrixMode( GL10.GL_MODELVIEW );
			gl.glLoadMatrixf( transform.val, 0 );
		}		
		else
		{
			viewMatrix.set(projection).mul(transform);			
					
			GL20 gl = graphics.getGL20();		
			gl.glViewport( 0, 0, graphics.getWidth(), graphics.getHeight() );
			gl.glDisable( GL20.GL_DEPTH_TEST );
			gl.glDisable( GL20.GL_CULL_FACE );
			gl.glDepthMask ( false );
			
			gl.glEnable( GL20.GL_TEXTURE_2D );
			gl.glActiveTexture( GL20.GL_TEXTURE0 );
			
			if( !blendingDisabled )
			{
				gl.glEnable( GL20.GL_BLEND );						;				
				gl.glBlendFunc( GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA );							
			}			
			else
			{
				gl.glDisable( GL20.GL_BLEND );				
			}
			
			shader.begin();
			shader.setUniformMatrix( "u_projectionViewMatrix", viewMatrix );
{'fraction_non_alphanumeric': 0.09815242494226328, 'fraction_numerical': 0.013653036272245619, 'mean_word_length': 2.768364474020988, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6534710', 'n_tokens_mistral': 5492, 'n_tokens_neox': 4410, 'n_words': 1485}