Thread: Making sprites opengl

  1. #1
    Registered User
    Join Date
    Aug 2012
    Posts
    9

    Making sprites opengl

    Hello C programming board

    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.
    Code:
    
    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.
    Code:
    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:
    1. http://www.youtube.com/watch?v=TECYZN2udSA&feature=plcp
    translated, rotated, and scaled based on the camera view matrix

    2.http://www.youtube.com/watch?v=0aYOIWyDiCk&feature=plcp
    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);
    Last edited by blubee; 09-02-2012 at 02:28 PM. Reason: added video for demo purposes

  2. #2
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    You know this is a C programming board:
    Hello C programming board
    and yet you've still posted Java:
    import java.nio.ByteBuffer;
    import java.nio.ByteOrder;
    import java.nio.FloatBuffer;
    import java.nio.ShortBuffer;

  3. #3
    Registered User
    Join Date
    Aug 2012
    Posts
    9
    Quote Originally Posted by memcpy View Post
    You know this is a C programming board:


    and yet you've still posted Java:

    What does that have to do with the question I asked? Is designing a sprite class only a C thing?

    I hope someone with something constructive can offer some advice.

  4. #4
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    What does that have to do with the question I asked?
    C, C++, and Java have different core features, certain design characteristics, and idiomatic constructs.

    So, asking your question "how do I create a sprite class" of a C or C++ programmer is not likely going to result in something you will want or even be able to use.

    Soma

  5. #5
    Registered User
    Join Date
    Aug 2012
    Posts
    9
    OK, let me rephrase the question.

    Creating a class to represent a sprite. I would figure the sprite needs a image, a position, a bounding box represented by its x,y, width and height, some way to rotate the sprite and things like that.

    My question was does a sprite class that will support batching need to have its own set of vertices and indices, as you see from the video in my original post, I can draw a textured cube which accurately represents what would sorta be a sprite but right now it has many limitations that I am not sure how to solve.

    For example the texture rotation, translations, scaling in the video above is achieved by rotating the camera's view matrix but I dont think this is the proper way to do it.
    I should be able to translate, rotate, scale the sprite by its internal variables and not using the camera as this will cause all my sprites to do the same thing which I don't want.
    Does a sprite class have its own model matrix?

    I hope with those restated questions someone has something that will help me move towards my goal of fixing the issues i raised in this post.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    @others : This is Java code but it seems to be more of an OpenGL question than a Java or C++ question, and OpenGL is perfectly reasonable in this forum. I will, of course, use C++ function names in my answer however!

    I think you're on the right track. It makes perfect sense to me to have a separate model transform matrix associated with each sprite. The usual OpenGL idiom is something like this:
    Code:
    cameraTransformations();
    glPushMatrix();  // push the matrix onto the stack, save for later
        object1Transform();
        paintObject2();
    glPopMatrix();  // pop (restore) the matrix that was saved on the stack
    glPushMatrix();
        object2Transform();
        paintObject2();
    glPopMatrix();
    // and so on
    Basically you save the current matrix so that you can do a sprite's model transform, and then undo this in time for the next sprite. This takes advantage of the way matrices associate: suppose I had push/object1Transform/paintObject1/pop inside a function. Then this could be called right after I did the camera transform, and it could also be called after I do another transform to (e.g.) paint a really small mini-map in the corner. You keep refining the area that's being painted by successive glMultMatrix() calls, and whenever you do something you'll need to undo, you push/pop the matrix.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User
    Join Date
    Aug 2012
    Posts
    9
    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.
    Last edited by blubee; 09-04-2012 at 12:22 AM. Reason: part of my message got chopped off because of the boards timeout...

  8. #8
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Perhaps part of the reason it's a bit slow is that you reconstruct the entire modelview matrix for every sprite. In onDrawFrame(), you restore the identity matrix and then multiply in all the matrices. This works for now but it will be slower, and with a more complex scene it would be difficult to manage. Look into matrix pushing/popping, you'll probably find it nice and easy to use.

    By the way, Java has array-initialization syntax that might make setRegion simpler:
    Code:
    vertices = new float[] {
        -width*0.5f, -height*0.5f, 0.0f, 0, 0, 0,
        // ...
    };
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #9
    Registered User
    Join Date
    Aug 2012
    Posts
    9
    Quote Originally Posted by dwks View Post
    Perhaps part of the reason it's a bit slow is that you reconstruct the entire modelview matrix for every sprite. In onDrawFrame(), you restore the identity matrix and then multiply in all the matrices. This works for now but it will be slower, and with a more complex scene it would be difficult to manage. Look into matrix pushing/popping, you'll probably find it nice and easy to use.

    opengl es 2.0 and above doesn't really use the push/ pop idea anymore, its basically reset to set identity then do your transformations again. Although I might be wrong here I am not 100% certain.


    By the way, Java has array-initialization syntax that might make setRegion simpler:
    Code:
    vertices = new float[] {
        -width*0.5f, -height*0.5f, 0.0f, 0, 0, 0,
        // ...
    };
    I don't use that method because I will need to apply scale/ rotation/ translation to my models when I want to draw with a sprite batcher, so I will have a function to return a set of vertices to add to the sprite batcher's current mesh. With that setup I cannot rotate the model's matrix as I'm doing now because the mesh will have many different sprites on one mesh, so I will have to manually calculate the rotations and store them in the vertices.

    Ex. Now drawing single sprites I can just mess with their model matrix, but doing batching I will have to do somethings like
    Code:
    public float[] getverts(){
    float[] verts = this.vertices;
    now to handle rotations, i will need to do something like this
    
    final float cos = cosDegrees(rotation);
    final float sin = sinDegrees(rotation);
    final float locXCos = localX * cos;
    final float locXSin = localX * sin;
    final float x1 = locXCos - locYSin + OriginX;
    vertices[X1] = x1;
    and basically do manual rotations around each vertex; If I use the
    Code:
    float[] verts = {....}
    constructor things get hairy in my calculations because I have to make sure that im operating on the correct array index, but constant X1, Y1, etc is a bit easier to deal with.

    That was my frame of thought for using this setup but I am always open to suggestions to improve my code.

  10. #10
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You can still do the batching and then set vertices[X1] directly if you want too... My suggestion is basically to avoid listing the vertices references, when you can combine it into one initialization. You can still keep around the X1, Y1, etc if you want. It's up to you.

    Also, you could replace the X1 Y1 ... variables with an enum. That would ensure that the integers got assigned correctly, without you having to count yourself, although Java being Java you'd then have to specify a scope for the enum values. For example,
    Code:
    enum Foo { X1 = 1, Y1, Z1, ... };
    and then Foo.X1.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  11. #11
    Registered User
    Join Date
    Aug 2012
    Posts
    9
    oh wow thanks for that, I had no idea, sorry I am still kinda a noob. Implemented!

    I already implemented something like that in my texture loader class;
    Code:
    public enum TextureFilter{
            GL_NEAREST(GLES20.GL_NEAREST), GL_LINEAR(GLES20.GL_LINEAR), 
            GL_LINEAR_MIPMAP_LINEAR(GLES20.GL_LINEAR_MIPMAP_LINEAR), 
            GL_LINEAR_MIPMAP_NEAREST(GLES20.GL_LINEAR_MIPMAP_NEAREST),
            GL_NEAREST_MIPMAP_NEAREST(GLES20.GL_NEAREST_MIPMAP_NEAREST), 
            GL_NEAREST_MIPMAP_LINEAR(GLES20.GL_NEAREST_MIPMAP_LINEAR);
            final int filter;
                TextureFilter(int id){
                    this.filter = id;
                }
            };
    Last edited by blubee; 09-06-2012 at 12:39 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. making sprites
    By DavidP in forum Game Programming
    Replies: 9
    Last Post: 02-20-2010, 07:00 AM
  2. Making a resizable window in openGL??
    By neil_w_84 in forum C++ Programming
    Replies: 2
    Last Post: 02-23-2005, 11:42 AM
  3. Sprites
    By Paninaro in forum Game Programming
    Replies: 4
    Last Post: 07-07-2002, 11:37 PM
  4. Where to get sprites?
    By compjinx in forum A Brief History of Cprogramming.com
    Replies: 8
    Last Post: 03-16-2002, 06:27 PM

Tags for this Thread