Problem with glvertexPointer()

Hi, I’m having problems with vertex arrays in Java


import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import org.lwjgl.opengl.GL11;

public class Triangle 
{
	
	private FloatBuffer vertexBuffer;	
	
	private float vertices[] = 
	{
			-0.5f, -0.5f,  0.0f,		// (x,y,z)
			 0.5f, -0.5f,  0.0f,		
			 0.0f,  0.5f,  0.0f			
	};
	
	public Triangle() 
	{
		ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect( vertices.length * 4 );
		vertexByteBuffer.order( ByteOrder.nativeOrder() );
		
		vertexBuffer = vertexByteBuffer.asFloatBuffer();
		
		vertexBuffer.put( vertices );
		
		vertexBuffer.rewind();

	}

	
	public void render() 
	{
		
		GL11.glEnableClientState( GL11.GL_VERTEX_ARRAY );
		GL11.glVertexPointer( 3, GL11.GL_FLOAT, vertexBuffer );
		GL11.glDrawArrays( GL11.GL_TRIANGLE_STRIP, 0, vertices.length / 3 );
		GL11.glDisableClientState( GL11.GL_VERTEX_ARRAY );
		
		/*
		vertexBuffer.rewind();
		GL11.glBegin( GL11.GL_TRIANGLE_STRIP );
			GL11.glVertex3f( vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get() );
			GL11.glVertex3f( vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get() );
			GL11.glVertex3f( vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get() );
		GL11.glEnd();
		*/
		
		
	}
}


The above code produces some nasty display (sometimes a quad or a "bleeding’ triangle ). I thought that the problem lies in my use of NIO but changing the render code to this produces the correct result:


public void render() 
	{
		
		vertexBuffer.rewind();
		GL11.glBegin( GL11.GL_TRIANGLE_STRIP );
			GL11.glVertex3f( vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get() );
			GL11.glVertex3f( vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get() );
			GL11.glVertex3f( vertexBuffer.get(), vertexBuffer.get(), vertexBuffer.get() );
		GL11.glEnd();
		
	}

So I think that the problem lies with the call to:


GL11.glVertexPointer( 3, GL11.GL_FLOAT, vertexBuffer );

Somehow, the pointer seems to be incorrect. Also there’s this thing that the C and LWJGL version of the prototype is different.

Any thoughts?

Thanks!

GL11.glVertexPointer( 3, GL11.GL_FLOAT, vertexBuffer );

The second argument is the stride, in this case: zero or 3*4, whatever you prefer.

The idea behind the LWJGL version of this function is that if your provide a FloatBuffer, it passes GL_FLOAT to the native function, behind the scenes.

Thanks bud!

I was wondering where to put “stride”. I thought it was “type” instead of stride since eclipse just tells me int,int as there is no GLuint in Java.

Now, I can recode my old spritebatcher to java. ;*)

Add the sourcecode of lwjgl to Eclipse and it will show the javadoc and parameter names in the popups.

That’s cool! How do I do that? (Eclipse is a beast of an IDE to figure out).

Thanks!

Downloading the source for LWJGL…

Yay! Basic spriteBatcher!


// ************************************************************************
// 
// Fixed - function Sprite Batcher
// Non-interleaved vertex arrays
// Richard Eric M. Lope (relminator)
// http://rel.phatcode.net
//
//	Todo:
//  1. Use interleaved arrays
//  2. Index the triangle and use glDrawElements()
//
// ************************************************************************
	
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ByteBuffer;

import org.lwjgl.opengl.GL11;

// CCW
// 6 verts per quad
// Top First
// TOP LEFT first
//6
//1       5
//|
//|       4
//2-------3
public class SpriteBatcher
{
	private FloatBuffer vertexBuffer;	
	private FloatBuffer colorBuffer;	
	private FloatBuffer uvBuffer;	
	private int numSprites;
	private int maxSize;
	private int index;
	private int cindex;
	
	private float[] vertices; 
	private float[] uvs; 
	private float[] colors; 
			
	
	public SpriteBatcher()
	{
		this( 1024 );
	}

	public SpriteBatcher( int maxSprites )
	{
		this.index = 0;
		this.cindex = 0;
		this.numSprites = 0;
		this.maxSize = maxSprites * 6 * 2;  // 3 verts per triangle * 2 triangles per quad * 2 floats per vertex
		
		this.vertices = new float[this.maxSize];
		this.uvs = new float[this.maxSize];
		this.colors = new float[maxSprites * 6 * 4];   // 4(rgba) * 6 verts per quad
		
		for( int i = 0; i < colors.length; i++ )
		{
			this.colors[i] = 1.0f;
		}
			
	}
	
	
	public void sprite( float x, float y, int flipmode, SpriteGL sprite )
	{
			
		float x1 = x;
		float y1 = y;
		float x2 = x + sprite.width;
		float y2 = y + sprite.height;
		
		float u1 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u1 : sprite.u2;
		float v1 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v1 : sprite.v2;
		float u2 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u2 : sprite.u1;
		float v2 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v2 : sprite.v1;
		
		vertices[index +  0] = x1; uvs[index +  0] = u1;
		vertices[index +  1] = y1; uvs[index +  1] = v1;
		vertices[index +  2] = x1; uvs[index +  2] = u1;
		vertices[index +  3] = y2; uvs[index +  3] = v2;
		vertices[index +  4] = x2; uvs[index +  4] = u2;
		vertices[index +  5] = y2; uvs[index +  5] = v2;
		
		vertices[index +  6] = x2; uvs[index +  6] = u2;
		vertices[index +  7] = y2; uvs[index +  7] = v2;
		vertices[index +  8] = x2; uvs[index +  8] = u2;
		vertices[index +  9] = y1; uvs[index +  9] = v1;
		vertices[index + 10] = x1; uvs[index + 10] = u1;
		vertices[index + 11] = y1; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		
		index += 12;

        numSprites++; 
	
	}

	public void sprite( float x, float y, float r, float g, float b, float a, int flipmode, SpriteGL sprite )
	{
			
		float x1 = x;
		float y1 = y;
		float x2 = x + sprite.width;
		float y2 = y + sprite.height;
		
		float u1 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u1 : sprite.u2;
		float v1 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v1 : sprite.v2;
		float u2 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u2 : sprite.u1;
		float v2 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v2 : sprite.v1;
		
		vertices[index +  0] = x1; uvs[index +  0] = u1;
		vertices[index +  1] = y1; uvs[index +  1] = v1;
		vertices[index +  2] = x1; uvs[index +  2] = u1;
		vertices[index +  3] = y2; uvs[index +  3] = v2;
		vertices[index +  4] = x2; uvs[index +  4] = u2;
		vertices[index +  5] = y2; uvs[index +  5] = v2;
		
		vertices[index +  6] = x2; uvs[index +  6] = u2;
		vertices[index +  7] = y2; uvs[index +  7] = v2;
		vertices[index +  8] = x2; uvs[index +  8] = u2;
		vertices[index +  9] = y1; uvs[index +  9] = v1;
		vertices[index + 10] = x1; uvs[index + 10] = u1;
		vertices[index + 11] = y1; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		
		index += 12;

        numSprites++; 
	
	}

	public void spriteRotateScale( float x, 
								   float y, 
								   float degrees,
								   float scalex,
								   float scaley, 
								   int flipmode, 
								   SpriteGL sprite )
	{
		
		float hx = (sprite.width/2) * scalex;
		float hy = (sprite.height/2) * scaley;
		
		float hx1 = -hx;   // top left
		float hy1 = -hy;
		float hx2 = -hx;	// bottom left
		float hy2 =  hy;
		float hx3 =  hx;	// bottom right
		float hy3 =  hy;
		float hx4 =  hx;	// top right
		float hy4 = -hy;
		
		float rotation = (float)Math.toRadians(degrees);
		float cz = (float) Math.cos(rotation);
	    float sz = (float) Math.sin(rotation);
		
	    float x1 = cz * hx1 - sz * hy1;
	    float y1 = sz * hx1 + cz * hy1;
	    float x2 = cz * hx2 - sz * hy2;
	    float y2 = sz * hx2 + cz * hy2;
	    float x3 = cz * hx3 - sz * hy3;
	    float y3 = sz * hx3 + cz * hy3;
	    float x4 = cz * hx4 - sz * hy4;
	    float y4 = sz * hx4 + cz * hy4;
 
		float u1 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u1 : sprite.u2;
		float v1 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v1 : sprite.v2;
		float u2 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u2 : sprite.u1;
		float v2 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v2 : sprite.v1;
		
		vertices[index +  0] = x1 + x; uvs[index +  0] = u1;
		vertices[index +  1] = y1 + y; uvs[index +  1] = v1;
		vertices[index +  2] = x2 + x; uvs[index +  2] = u1;
		vertices[index +  3] = y2 + y; uvs[index +  3] = v2;
		vertices[index +  4] = x3 + x; uvs[index +  4] = u2;
		vertices[index +  5] = y3 + y; uvs[index +  5] = v2;
		
		vertices[index +  6] = x3 + x; uvs[index +  6] = u2;
		vertices[index +  7] = y3 + y; uvs[index +  7] = v2;
		vertices[index +  8] = x4 + x; uvs[index +  8] = u2;
		vertices[index +  9] = y4 + y; uvs[index +  9] = v1;
		vertices[index + 10] = x1 + x; uvs[index + 10] = u1;
		vertices[index + 11] = y1 + y; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1; colors[ cindex++ ] = 1;
		
		index += 12;

        numSprites++; 
	
	}

	public void spriteRotateScale( float x, 
								   float y, 
								   float degrees,
								   float scalex,
								   float scaley,
								   float r, 
								   float g, 
								   float b, 
								   float a,  
								   int flipmode, 
								   SpriteGL sprite )
	{
	
		float hx = (sprite.width/2) * scalex;
		float hy = (sprite.height/2) * scaley;
		
		float hx1 = -hx;    // top left
		float hy1 = -hy;
		float hx2 = -hx;	// bottom left
		float hy2 =  hy;
		float hx3 =  hx;	// bottom right
		float hy3 =  hy;
		float hx4 =  hx;	// top right
		float hy4 = -hy;
		
		float rotation = (float)Math.toRadians(degrees);
		float cz = (float) Math.cos(rotation);
		float sz = (float) Math.sin(rotation);
		
		float x1 = cz * hx1 - sz * hy1;
		float y1 = sz * hx1 + cz * hy1;
		float x2 = cz * hx2 - sz * hy2;
		float y2 = sz * hx2 + cz * hy2;
		float x3 = cz * hx3 - sz * hy3;
		float y3 = sz * hx3 + cz * hy3;
		float x4 = cz * hx4 - sz * hy4;
		float y4 = sz * hx4 + cz * hy4;
		
		float u1 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u1 : sprite.u2;
		float v1 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v1 : sprite.v2;
		float u2 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u2 : sprite.u1;
		float v2 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v2 : sprite.v1;
		
		vertices[index +  0] = x1 + x; uvs[index +  0] = u1;
		vertices[index +  1] = y1 + y; uvs[index +  1] = v1;
		vertices[index +  2] = x2 + x; uvs[index +  2] = u1;
		vertices[index +  3] = y2 + y; uvs[index +  3] = v2;
		vertices[index +  4] = x3 + x; uvs[index +  4] = u2;
		vertices[index +  5] = y3 + y; uvs[index +  5] = v2;
		
		vertices[index +  6] = x3 + x; uvs[index +  6] = u2;
		vertices[index +  7] = y3 + y; uvs[index +  7] = v2;
		vertices[index +  8] = x4 + x; uvs[index +  8] = u2;
		vertices[index +  9] = y4 + y; uvs[index +  9] = v1;
		vertices[index + 10] = x1 + x; uvs[index + 10] = u1;
		vertices[index + 11] = y1 + y; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		index += 12;
		
		numSprites++; 
	
	}

	
	public void spriteStretch( float x, 
							   float y, 
							   float width, 
							   float height, 
							   float r, 
							   float g, 
							   float b, 
							   float a,
							   SpriteGL sprite )
	{
		
		float hw = sprite.width/2;
		float hh = sprite.height/2;
		
		float uoff = sprite.u1;
		float voff = sprite.v1;
		float uwidth = sprite.u2 - sprite.u1;
		float vheight = sprite.v2 - sprite.v1;
		
		float su = uwidth/2;
		float tv = vheight/2;
						
		float x1 = x;
		float y1 = y;
		float x2 = x + width;
		float y2 = y + height;
		
		float xh1 = x1 + hw;
		float yh1 = y1 + hh;
		float xh2 = x2 - hw;
		float yh2 = y2 - hh;
		
		// top left
		spriteOnBox( x1, 
				  	 y1, 
				  	 xh1, 
				  	 yh1, 
				  	 uoff, 
				  	 voff, 
				  	 uoff + su, 
				  	 voff + tv, 
				  	 r,g,b,a );
		// top right
		spriteOnBox( xh2, 
				  	 y1, 
				  	 x2, 
				  	 yh1, 
				  	 uoff + su, 
				  	 voff, 
				  	 uoff + uwidth, 
				  	 voff + tv, 
				  	 r,g,b,a );
	
		// bottom left
		spriteOnBox( x1, 
				  	 yh2, 
				  	 xh1, 
				  	 y2, 
				  	 uoff, 
				  	 voff + tv, 
				  	 uoff + su, 
				  	 voff + vheight, 
				  	 r,g,b,a );
		
		// bottom right
		spriteOnBox( xh2, 
				  	 yh2, 
				  	 x2, 
				  	 y2, 
				  	 uoff + su, 
				  	 voff + tv, 
				  	 uoff + uwidth, 
				  	 voff + vheight, 
				  	 r,g,b,a );
		
		// top border
		spriteOnBox( xh1, 
				  	 y1, 
				  	 xh2, 
				  	 yh1, 
				  	 uoff + su, 
				  	 voff, 
				  	 uoff + su, 
				  	 voff + tv, 
				  	 r,g,b,a );

		// bottom border
		spriteOnBox( xh1, 
				  	 yh2, 
				  	 xh2, 
				  	 y2, 
				  	 uoff + su, 
				  	 voff + tv, 
				  	 uoff + su, 
				  	 voff + vheight, 
				  	 r,g,b,a );
		
		// left border
		spriteOnBox( x1, 
				  	 yh1, 
				  	 xh1, 
				  	 yh2, 
				  	 uoff, 
				  	 voff + tv, 
				  	 uoff + su, 
				  	 voff + tv, 
				  	 r,g,b,a );
		
		// right border
		spriteOnBox( xh2, 
				  	 yh1, 
				  	 x2, 
				  	 yh2, 
				  	 uoff + su, 
				  	 voff + tv, 
				  	 uoff + uwidth, 
				  	 voff + tv, 
				  	 r,g,b,a );
		
		// center
		spriteOnBox( xh1, 
			  	 	 yh1, 
			  	  	 xh2, 
			  	  	 yh2, 
			  	  	 uoff + su, 
			  	  	 voff + tv, 
			  	  	 uoff + su, 
			  	  	 voff + tv, 
			  	  	 r,g,b,a );
	
	}

	
	public void spriteOnLine( float x1,
							  float y1,
							  float x2,
							  float y2,
							  float thickness,
							  float r,
							  float g,
							  float b,
							  float a,
							  SpriteGL sprite )
	{
		
		float nx = -(y2 - y1);
		float ny =  (x2 - x1);
		
		float invLength = 1 / (float)( Math.sqrt(nx * nx + ny * ny ) );
		
		nx *= invLength;
		ny *= invLength;
		
		nx *= thickness / 2;
		ny *= thickness / 2;
		
		float vx = (x2 - x1);
		float vy = (y2 - y1);
		invLength = 1 / (float)( Math.sqrt(vx * vx + vy * vy ) );
		vx *= invLength;
		vy *= invLength;
		
		vx *= thickness / 2;
		vy *= thickness / 2;
		
		
		float lx1 = x2 + nx;
		float ly1 = y2 + ny;
		float lx2 = x2 - nx;
		float ly2 = y2 - ny;                      
		float lx3 = x1 - nx;
		float ly3 = y1 - ny;
		float lx4 = x1 + nx;
		float ly4 = y1 + ny;
		float lx5 = lx1 + vx;
		float ly5 = ly1 + vy;
		float lx6 = lx2 + vx;
		float ly6 = ly2 + vy;
		float lx7 = lx4 - vx;
		float ly7 = ly4 - vy;
		float lx8 = lx3 - vx;
		float ly8 = ly3 - vy;
	    		
		float u1 = sprite.u1;
		float v1 = sprite.v1;
		float u2 = sprite.u2;
		float v2 = sprite.v2;
		float su = (u1 + u2) / 2;
				
		// center
		spriteOnQuad( lx1, ly1, 
					  lx2, ly2, 
					  lx3, ly3, 
					  lx4, ly4, 
					  su, v2, 
					  su, v1, 
					  r, g, b, a  );
		
		// right
		spriteOnQuad( lx5, ly5, 
					  lx6, ly6, 
					  lx2, ly2, 
					  lx1, ly1, 
					  u2, v2, 
					  su, v1, 
					  r, g, b, a  );
		
		// left
		spriteOnQuad( lx8, ly8, 
					  lx7, ly7, 
					  lx4, ly4, 
					  lx3, ly3,
					  u1, v1, 
					  su, v2, 
					  r, g, b, a  );
		
	}
	
	
	public void spriteOnBox( float x, 
			  				 float y, 
			  				 float width, 
			  				 float height, 
			  				 float r, 
			  				 float g, 
			  				 float b, 
			  				 float a,
			  				 int flipmode, 
			  				 SpriteGL sprite )
	{
	
		float x1 = x;
		float y1 = y;
		float x2 = x + width;
		float y2 = y + height;
		
		float u1 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u1 : sprite.u2;
		float v1 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v1 : sprite.v2;
		float u2 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u2 : sprite.u1;
		float v2 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v2 : sprite.v1;
		
		vertices[index +  0] = x1; uvs[index +  0] = u1;
		vertices[index +  1] = y1; uvs[index +  1] = v1;
		vertices[index +  2] = x1; uvs[index +  2] = u1;
		vertices[index +  3] = y2; uvs[index +  3] = v2;
		vertices[index +  4] = x2; uvs[index +  4] = u2;
		vertices[index +  5] = y2; uvs[index +  5] = v2;
		
		vertices[index +  6] = x2; uvs[index +  6] = u2;
		vertices[index +  7] = y2; uvs[index +  7] = v2;
		vertices[index +  8] = x2; uvs[index +  8] = u2;
		vertices[index +  9] = y1; uvs[index +  9] = v1;
		vertices[index + 10] = x1; uvs[index + 10] = u1;
		vertices[index + 11] = y1; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		index += 12;
		
		numSprites++; 
	
	}

	public void spriteOnQuad( float x1, 
			   			   	  float y1, 
			   				  float x2, 
			   				  float y2,
			   				  float x3, 
			   				  float y3,
			   				  float x4, 
			   				  float y4,
			   				  float r, 
			   				  float g, 
			   				  float b, 
			   				  float a,
			   				  int flipmode, 
			   				  SpriteGL sprite )
	{
	
		float u1 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u1 : sprite.u2;
		float v1 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v1 : sprite.v2;
		float u2 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u2 : sprite.u1;
		float v2 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v2 : sprite.v1;
		
		vertices[index +  0] = x1; uvs[index +  0] = u1;
		vertices[index +  1] = y1; uvs[index +  1] = v1;
		vertices[index +  2] = x2; uvs[index +  2] = u1;
		vertices[index +  3] = y2; uvs[index +  3] = v2;
		vertices[index +  4] = x3; uvs[index +  4] = u2;
		vertices[index +  5] = y3; uvs[index +  5] = v2;
		
		vertices[index +  6] = x3; uvs[index +  6] = u2;
		vertices[index +  7] = y3; uvs[index +  7] = v2;
		vertices[index +  8] = x4; uvs[index +  8] = u2;
		vertices[index +  9] = y4; uvs[index +  9] = v1;
		vertices[index + 10] = x1; uvs[index + 10] = u1;
		vertices[index + 11] = y1; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		index += 12;
		
		numSprites++; 
	
	}

	public void spriteOnQuadClipped( float x1, 
							  		 float y1, 
							  		 float x2, 
							  		 float y2,
							  		 float x3, 
							  		 float y3,
							  		 float x4, 
							  		 float y4,
							  		 float cu1,
							  		 float cv1,
							  		 float cu2,
							  		 float cv2,
							  		 float r, 
							  		 float g, 
							  		 float b, 
							  		 float a,
							  		 int flipmode, 
									 SpriteGL sprite )
	{
	
		float u1 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u1 : sprite.u2;
		float v1 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v1 : sprite.v2;
		float u2 = ( (flipmode & SpriteGL.FLIP_H) == 0 ) ? sprite.u2 : sprite.u1;
		float v2 = ( (flipmode & SpriteGL.FLIP_V) == 0 ) ? sprite.v2 : sprite.v1;
		
		u1 += cu1;
		v1 += cv1;
		
		u2 += cu2;
		v2 += cv2;
		
		vertices[index +  0] = x1; uvs[index +  0] = u1;
		vertices[index +  1] = y1; uvs[index +  1] = v1;
		vertices[index +  2] = x2; uvs[index +  2] = u1;
		vertices[index +  3] = y2; uvs[index +  3] = v2;
		vertices[index +  4] = x3; uvs[index +  4] = u2;
		vertices[index +  5] = y3; uvs[index +  5] = v2;
		
		vertices[index +  6] = x3; uvs[index +  6] = u2;
		vertices[index +  7] = y3; uvs[index +  7] = v2;
		vertices[index +  8] = x4; uvs[index +  8] = u2;
		vertices[index +  9] = y4; uvs[index +  9] = v1;
		vertices[index + 10] = x1; uvs[index + 10] = u1;
		vertices[index + 11] = y1; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		index += 12;
		
		numSprites++; 
	
	}


	public void render( int textureID )
	{
		
		GL11.glBindTexture( GL11.GL_TEXTURE_2D, textureID );
		
	
		fillBuffers();
		
		
		GL11.glEnableClientState( GL11.GL_VERTEX_ARRAY );
		GL11.glEnableClientState( GL11.GL_TEXTURE_COORD_ARRAY );
	    GL11.glEnableClientState( GL11.GL_COLOR_ARRAY );
		GL11.glColorPointer(4, 4 << 2, colorBuffer );
		GL11.glTexCoordPointer( 2, 2 << 2, uvBuffer );
		GL11.glVertexPointer( 2, 2 << 2, vertexBuffer );   // stride == 8 bytes per vertex (x and y) at 4 bytes each
		GL11.glDrawArrays( GL11.GL_TRIANGLES, 0, numSprites * 6);   // 6 floats = 3 verts per triangle
		GL11.glDisableClientState( GL11.GL_COLOR_ARRAY );
		GL11.glDisableClientState( GL11.GL_TEXTURE_COORD_ARRAY );
	    GL11.glDisableClientState( GL11.GL_VERTEX_ARRAY );
		
	    this.index = 0;
	    this.cindex = 0;
		this.numSprites = 0;
		
		vertexBuffer.clear();
		uvBuffer.clear();
		colorBuffer.clear();
		
	}

	// ************************************************************************
	// Privates
	// ************************************************************************
	private void spriteOnBox( float x1, 
			 				  float y1, 
			 				  float x2, 
			 				  float y2,
			 				  float u1,
			 				  float v1,
			 				  float u2,
			 				  float v2,
			 				  float r, 
			 				  float g, 
			 				  float b, 
			 				  float a )
	{
	
		vertices[index +  0] = x1; uvs[index +  0] = u1;
		vertices[index +  1] = y1; uvs[index +  1] = v1;
		vertices[index +  2] = x1; uvs[index +  2] = u1;
		vertices[index +  3] = y2; uvs[index +  3] = v2;
		vertices[index +  4] = x2; uvs[index +  4] = u2;
		vertices[index +  5] = y2; uvs[index +  5] = v2;
		
		vertices[index +  6] = x2; uvs[index +  6] = u2;
		vertices[index +  7] = y2; uvs[index +  7] = v2;
		vertices[index +  8] = x2; uvs[index +  8] = u2;
		vertices[index +  9] = y1; uvs[index +  9] = v1;
		vertices[index + 10] = x1; uvs[index + 10] = u1;
		vertices[index + 11] = y1; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		index += 12;
		
		numSprites++; 
	
	}

	private void spriteOnQuad( float x1, 
			 				   float y1, 
			  				   float x2, 
			  				   float y2,
			  				   float x3, 
			  				   float y3,
			  				   float x4, 
			  				   float y4,
			  				   float u1,
			  				   float v1,
			  				   float u2,
			  				   float v2,
			  				   float r, 
			  				   float g, 
			  				   float b, 
			  				   float a )
	{
	
		vertices[index +  0] = x1; uvs[index +  0] = u1;
		vertices[index +  1] = y1; uvs[index +  1] = v1;
		vertices[index +  2] = x2; uvs[index +  2] = u1;
		vertices[index +  3] = y2; uvs[index +  3] = v2;
		vertices[index +  4] = x3; uvs[index +  4] = u2;
		vertices[index +  5] = y3; uvs[index +  5] = v2;
		
		vertices[index +  6] = x3; uvs[index +  6] = u2;
		vertices[index +  7] = y3; uvs[index +  7] = v2;
		vertices[index +  8] = x4; uvs[index +  8] = u2;
		vertices[index +  9] = y4; uvs[index +  9] = v1;
		vertices[index + 10] = x1; uvs[index + 10] = u1;
		vertices[index + 11] = y1; uvs[index + 11] = v1;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		colors[ cindex++ ] = r; colors[ cindex++ ] = g; colors[ cindex++ ] = b; colors[ cindex++ ] = a;
		
		index += 12;
		
		numSprites++; 
	
	}

	private void fillBuffers()
	{
		// 4 bytes per float
		// 12 vertices per quad (two triangles)
		ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(numSprites * 12 * 4);
		vertexByteBuffer.order(ByteOrder.nativeOrder());
		
		vertexBuffer = vertexByteBuffer.asFloatBuffer();
		vertexBuffer.put( vertices, 0, numSprites * 12 );
		vertexBuffer.position(0);
		
		ByteBuffer uvByteBuffer = ByteBuffer.allocateDirect(numSprites * 12 * 4);
		uvByteBuffer.order(ByteOrder.nativeOrder());
		
		uvBuffer = uvByteBuffer.asFloatBuffer();
		uvBuffer.put( uvs, 0, numSprites * 12 );
		uvBuffer.position(0);
		
		ByteBuffer colorByteBuffer = ByteBuffer.allocateDirect(numSprites * 24 * 4);
		colorByteBuffer.order(ByteOrder.nativeOrder());
		
		colorBuffer = colorByteBuffer.asFloatBuffer();
		colorBuffer.put( colors, 0, numSprites * 24 );
		colorBuffer.position(0);
		
	}
		
		

}   // end class