This question might be a little silly but I don’t know the answer so I’m asking for help.
I have made it to the point where I can load textures even atlas textures and pull out a sub region, and also draw that region on call. I’ll show code below.
My question how is how do I create a sprite class. I want it to eventually be able to support sprite batching but I am coming up a little empty right now. Here is my sprite class.
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import android.opengl.GLES20;
public class Sprite {
final public float[] vertices = new float[20];
final public short[] indices = new short[6];
public FloatBuffer vertBuffer;
public FloatBuffer texBuffer;
public ShortBuffer indxBuffer;
Texture texture;
public float width;
public float height;
public float sMin, sMax, tMin, tMax;
public Sprite(SpriteSheetRegion region){
this.texture = region.texture;
this.width = region.width;
this.height = region.height;
this.sMax = region.sMax;
this.sMin = region.sMin;
this.tMax = region.tMax;
this.tMin = region.tMin;
vertices[0] = -width*0.5f;
vertices[1] = -height*0.5f;
vertices[2] = 0.0f;
vertices[3] = sMin;
vertices[4] = tMax;
vertices[5] = width*0.5f;
vertices[6] = -height*0.5f;
vertices[7] = 0.0f;
vertices[8] = sMax;
vertices[9] = tMax;
vertices[10] = -width*0.5f;
vertices[11] = height*0.5f;
vertices[12] = 0.0f;
vertices[13] = sMin;
vertices[14] = tMin;
vertices[15] = width*0.5f;
vertices[16] = height*0.5f;
vertices[17] = 0.0f;
vertices[18] = sMax;
vertices[19] = tMin;
System.out.println((width*0.5f)+" "+(height*0.5f));
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);
}
public Sprite(SpriteSheetRegion region, float width, float height){
this.texture = region.texture;
this.width = width;
this.height = height;
this.sMax = region.sMax;
this.sMin = region.sMin;
this.tMax = region.tMax;
this.tMin = region.tMin;
vertices[0] = -width*0.5f;
vertices[1] = -height*0.5f;
vertices[2] = 0.0f;
vertices[3] = sMin;
vertices[4] = tMax;
vertices[5] = width*0.5f;
vertices[6] = -height*0.5f;
vertices[7] = 0.0f;
vertices[8] = sMax;
vertices[9] = tMax;
vertices[10] = -width*0.5f;
vertices[11] = height*0.5f;
vertices[12] = 0.0f;
vertices[13] = sMin;
vertices[14] = tMin;
vertices[15] = width*0.5f;
vertices[16] = height*0.5f;
vertices[17] = 0.0f;
vertices[18] = sMax;
vertices[19] = 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);
}
public void draw(int program){
GLES20.glUseProgram(program);
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture.id);
vertBuffer.position(0);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aPos"), 3, GLES20.GL_FLOAT, false, 20, vertBuffer);
GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(program, "aPos"));
vertBuffer.position(3);
GLES20.glVertexAttribPointer(GLES20.glGetAttribLocation(program, "aTexPos"), 2, GLES20.GL_FLOAT, false, 20, 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);
}
@Override
public String toString(){
return texture.toString();
}
}
I basically took all the code I had in my rendering function and put it in the sprite class, from binding the textures and all. For instance, I have no idea how to rotate this sprite. Well Actually I could put a model matrix inside the sprite class but I get the feeling that’s going down the wrong road. I can move the sprite horizontally by adding some uniform value to the x vertices or horizontally by adding some uniform value to the y vertices but again I feel that’s going down the wrong path but honestly I don’t know. Here is my rendering code now.
public void onDrawFrame(GL10 gl) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glUseProgram(sProgram);
Matrix.setIdentityM(modelMatrix, 0);
Matrix.translateM(modelMatrix, 0, 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);
sp.draw(sProgram);
}
I really hope someone with a little more experience can help me out with this.
quick edit!
added videos:
-
2d camera (w.i.p) - YouTube
translated, rotated, and scaled based on the camera view matrix
2.another 2d cam - YouTube
similar but larger image loaded.
the difference in videos show that i can get texture atlas sub regions w/o changing my code, just pass in the name of the texture sub region and do sprite.draw(glprogram);