dwks Thanks I was rendering my sprites before doing my matrix math stuff so they were all rendering on top of each other. It didn't become clear until you pointed it out with your example.
updated sprite class
Code:
public class Sprite {
private static final String TAG = "Sprite Class";
final public float[] vertices = new float[32];
final public short[] indices = new short[6];
public FloatBuffer vertBuffer;
public ShortBuffer indxBuffer;
SpriteSheetRegion region;
private float halfWidth, halfHeight;
public float width;
public float height;
public float sMin, sMax, tMin, tMax;
public float angle;
public vec3 pos;
public vec2 vel;
public vec2 origin;
public Color color;
public Sprite(SpriteSheetRegion region){
color = new Color();
pos = new vec3();
vel = new vec2();
setRegion(region);
}
public Sprite(SpriteSheetRegion region, float angle){
color = new Color();
pos = new vec3();
vel = new vec2();
this.angle = angle;
setRegion(region);
}
public Sprite(SpriteSheetRegion region, float width, float height){
color = new Color();
pos = new vec3();
vel = new vec2();
region.width = width;
region.height = height;
setRegion(region);
}
public Sprite(SpriteSheetRegion region, float xPos, float yPos, float zPos){
color = new Color();
pos = new vec3(xPos, yPos, zPos);
setRegion(region);
}
private void setRegion(SpriteSheetRegion region){
vel = new vec2();
if(region.isRoatated)
this.angle = 90.0f;
else
this.angle = 0.0f;
this.region = region;
this.width = region.width;
this.height = region.height;
this.sMax = region.sMax;
this.sMin = region.sMin;
this.tMax = region.tMax;
this.tMin = region.tMin;
halfWidth = this.width * 0.5f;
halfHeight = this.height * 0.5f;
/*pad vertex array w/ 0 to align the data on 32 byte marks
ex R1, G1, B1, etc... maybe I can implement sprite tinting later */
vertices[X1] = -width*0.5f;
vertices[Y1] = -height*0.5f;
vertices[Z1] = 0.0f;
vertices[R1] = 0;
vertices[G1] = 0;
vertices[B1] = 0;
vertices[U1] = sMin;
vertices[V1] = tMax;
vertices[X2] = width*0.5f;
vertices[Y2] = -height*0.5f;
vertices[Z2] = 0.0f;
vertices[R2] = 0;
vertices[G2] = 0;
vertices[B2] = 0;
vertices[U2] = sMax;
vertices[V2] = tMax;
vertices[X3] = -width*0.5f;
vertices[Y3] = height*0.5f;
vertices[Z3] = 0.0f;
vertices[R3] = 0;
vertices[G3] = 0;
vertices[B3] = 0;
vertices[U3] = sMin;
vertices[V3] = tMin;
vertices[X4] = width*0.5f;
vertices[Y4] = height*0.5f;
vertices[Z4] = 0.0f;
vertices[R4] = 0;
vertices[G4] = 0;
vertices[B4] = 0;
vertices[U4] = sMax;
vertices[V4] = tMin;
indices[0] = 0;
indices[1] = 1;
indices[2] = 2;
indices[3] = 2;
indices[4] = 1;
indices[5] = 3;
vertBuffer = ByteBuffer.allocateDirect(vertices.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertBuffer.put(vertices).position(0);
indxBuffer = ByteBuffer.allocateDirect(indices.length*2).order(ByteOrder.nativeOrder()).asShortBuffer();
indxBuffer.put(indices).position(0);
Log.d(TAG, "Sprite W&H scaled "+(width*0.5f)+" "+(height*0.5f)+" unscaled "+(width)+" "+(height));
//test
vel.set(10, 10);
}
public void draw(int program){
//test update
pos.x += vel.x;
pos.y += vel.y;
if(pos.x-halfWidth >= 240)
vel.x = vel.x*-1;
if(pos.x-halfWidth <= -480)
vel.x = vel.x*-1;
if(pos.y+halfHeight >= 800)
vel.y = vel.y*-1;
if(pos.y-halfHeight <= -800)
vel.y = vel.y*-1;
//draw
GLES20.glUseProgram(program);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, region.texture.id);
GLES20.glEnable(GLES20.GL_CULL_FACE);
GLES20.glCullFace(GLES20.GL_BACK);
//i think these really slow rendering down
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
vertBuffer.position(0);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aPos"), 3, GLES20.GL_FLOAT, false, 32, vertBuffer);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aPos"));
vertBuffer.position(3);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aTintCol"), 3, GLES20.GL_FLOAT, false, 32, vertBuffer);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aTintCol"));
vertBuffer.position(6);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aTexPos"), 2, GLES20.GL_FLOAT, false, 32, vertBuffer);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aTexPos"));
GLES20.glUniform1i(GLES20.glGetUniformLocation(program, "texture"), 0);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, indxBuffer);
GLES20.glDisable(GLES20.GL_CULL_FACE);
GLES20.glDisable(GLES20.GL_BLEND);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
}
//Not too sure what to do about this here...
static private final int X1 = 0;
static private final int Y1 = 1;
static private final int Z1 = 2;
static private final int R1 = 3;
static private final int G1 = 4;
static private final int B1 = 5;
static private final int U1 = 6;
static private final int V1 = 7;
static private final int X2 = 8;
static private final int Y2 = 9;
static private final int Z2 = 10;
static private final int R2 = 11;
static private final int G2 = 12;
static private final int B2 = 13;
static private final int U2 = 14;
static private final int V2 = 15;
static private final int X3 = 16;
static private final int Y3 = 17;
static private final int Z3 = 18;
static private final int R3 = 19;
static private final int G3 = 20;
static private final int B3 = 21;
static private final int U3 = 22;
static private final int V3 = 23;
static private final int X4 = 24;
static private final int Y4 = 25;
static private final int Z4 = 26;
static private final int R4 = 27;
static private final int G4 = 28;
static private final int B4 = 29;
static private final int U4 = 30;
static private final int V4 = 31;
}
fixed rendering code, before I had my matrix multiplications AFTER my sprite.draw() call....
Code:
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
vShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vShader, vCode);
GLES20.glCompileShader(vShader);
fShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fShader, fCode);
GLES20.glCompileShader(fShader);
sProgram = GLES20.glCreateProgram();
GLES20.glAttachShader(sProgram, vShader);
GLES20.glAttachShader(sProgram, fShader);
GLES20.glLinkProgram(sProgram);
tex = tLoader.loadTexture(R.raw.hmm, TextureFilter.GL_LINEAR_MIPMAP_LINEAR, TextureFilter.GL_LINEAR, true);
SpriteSheet s = new SpriteSheet(this.context, tex, R.raw.hmma);
Sprite = new ArrayList<Sprite>();
for(int i = 0; i < 100; i++){
(0+Math.random()*300), (float)(0+Math.random()*700), (float)0));
}
len = Sprite.size();
GLES20.glClearColor(1.0f, 1.0f, 0.0f, 0.0f);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
cam = new Camera(width, height);
}
public void onDrawFrame(GL10 gl) {
GLES20.glUseProgram(sProgram);
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
for(int i = 0; i < len; i++){
Matrix.setIdentityM(modelMatrix, 0);
/*move the sprite around the world */
Matrix.translateM(modelMatrix, 0, Sprite.get(i).pos.x, Sprite.get(i).pos.y, 0);
/*rotate around its new world space position*/
//Matrix.rotateM(modelMatrix, 0, Sprite.get(i).angle+angleInDegrees, 0.0f, 0.0f, 1.0f);
/*translate away from camera so you can see the sprite*/
Matrix.translateM(modelMatrix, 0, 0.0f, 0.0f, -1.0f);
/*if texture is rotated in the atlas rotated texture fix*/
Matrix.rotateM(modelMatrix, 0, Sprite.get(i).angle, 0.0f, 0.0f, 1.0f);
Matrix.multiplyMM(cam.combMatrix, 0, cam.viewMatrix, 0, modelMatrix, 0);
Matrix.multiplyMM(cam.combMatrix, 0, cam.projMatrix, 0, cam.combMatrix, 0);
GLES20.glUniformMatrix4fv(GLES20.glGetUniformLocation(sProgram, "MVPMat"), 1, false, cam.combMatrix, 0);
Sprite.get(i).draw(sProgram);
}
}
Camera cam;
Texture tex;
Sprite sprite;
TextureLoader tLoader;
private int vShader, fShader, sProgram;
private float[] modelMatrix = new float[16];
private final String vCode =
"uniform mat4 MVPMat; \n"
+"attribute vec2 aTexPos; \n"
+"attribute vec3 aTintCol; \n"
+"attribute vec3 aPos; \n"
+"varying vec3 vTintCol; \n"
+"varying vec2 vTexPos; \n"
+"void main(){ \n"
+" vTexPos = aTexPos; \n"
+" vTintCol = aTintCol; \n"
+" gl_Position = MVPMat * vec4(aPos, 1.0); \n"
+"} \n";
private final String fCode =
"precision mediump float; \n"
+"uniform sampler2D texture; \n"
+"varying vec3 vTintCol; \n"
+"varying vec2 vTexPos; \n"
+"void main(){ \n"
+"gl_FragColor = texture2D(texture, vTexPos); \n"
+"} \n";
}
sprite render test - YouTube
Thanks, I finally got some "Sprites" up and moving about my scene. Right now I can render about 100 sprites somewhat choppily but I have nothing going on to cull or anything like that.
Right now all my screen resolutions and bouncing sprites are hard coded also theres no sprite batching going on.
Until your reply I was kinda stuck, i had an array of sprites but they were drawing on top of each other, then i found out that i had my camera transformations after my draw calls :/
fixed now : sprite render test - YouTube
but still many things I need to fix, basically figuring out a bounding box based on the sprites dimensions, being able to set a local origin to rotate about. I think I need to develop a mesh class to hold the vertex/ index data for batching. Since Im targeting gles 2.0 and above I dont have to worry about vertex arrays and can just use vbos.