Can't find suitable example for android 2d opengl sprite class which does not use GL11Ext for drawing

后端 未结 1 1917
离开以前
离开以前 2021-01-30 15:18

As SpriteMethodTest says there are many ways for drawing sprites. Firstly, I tried canvas, and had some performance problems. Next, I decided to learn opengl. I made my first ac

相关标签:
1条回答
  • 2021-01-30 15:55

    EVRIKA !!!

    I was allmost killing myself ! after 3 days of leaving Canvas and learning OpenGL methods to implement game engine.

    The web is full of OpenGL tutorials full of trash and many of them are unfinished and many of them lead to wrong way for 2D OpenGL game engine implementation methotds. The big wrong point is using G11Ext for making games. AS THEY DONT ROTATE : D

    Annd annd then i found this tutorial from other tutorial which i found from youtube game sample video link lol:

    not to confuse viewers here is

    Chapter 1: http://obviam.net/index.php/opengl-es-with-android-switching-from-canvas-to-opengl/

    Chapter 2: http://obviam.net/index.php/opengl-es-android-displaying-graphical-elements-primitives/

    Chapter 3: http://obviam.net/index.php/texture-mapping-opengl-android-displaying-images-using-opengl-and-squares/

    Annd just 15 minutes ago I discovered the way I can ROTATE, MOVE AND RESIZE shapes with its sprites ! ! ! hahah

    So as many of readers are asking after reading this GREAT tutorial how to move and resize and rotate sprites. So i worked out some code from this mess of examples and tutorials:

    This class is used for some vertex manipulations

    public class Vertex
    {
        public FloatBuffer buffer; // buffer holding the vertices
        public float vertex[];
        public Vertex (float[] vertex)
        {
            this.vertex = vertex;
            this.prepare ();
        }
        private void prepare ()
        {
            // a float has 4 bytes so we allocate for each coordinate 4 bytes
            ByteBuffer factory = ByteBuffer.allocateDirect (vertex.length * 4);
            factory.order (ByteOrder.nativeOrder ());
            // allocates the memory from the byte buffer
            buffer = factory.asFloatBuffer ();
            // fill the vertexBuffer with the vertices
            buffer.put (vertex);
            // set the cursor position to the beginning of the buffer
            buffer.position (0);        
        }
    }
    

    and this class is used for drawing shape with texture able to move rotate and position

    public class Square
    {
        Vertex shape,texture;
        int corner=0;
        float x=0;
    
        public Square()
        {
            shape = new Vertex (new float[]
                    {
                    1f,1f,0f,
                    0f,1f,0f,
                    1f,0f,0f,
                    0f,0f,0f,
                    });
    
            texture = new Vertex (new float[]
                    {
                    1.0f, 0.0f,
                    0.0f, 0.0f,
                    1.0f, 1.0f,
                    0.0f, 1.0f,
                    });     
        }
    
        /** The draw method for the square with the GL context */
        public void draw (GL10 gl, int image, float x, float y, float width, float height, float corner)
        {
            if (corner>=0)
            {
                corner += 1;    
            }
            if (corner>360)
            {
                corner = -1;
            }
            gl.glPushMatrix();
    
            x += 1f;
            if (x>800)
            {
                x = 0;
            }
    
            position (gl, 0, 0, width, height, corner);
    
            // bind the previously generated texture
            gl.glBindTexture(GL10.GL_TEXTURE_2D, image);
    
            // Point to our buffers
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    
            // set the colour for the square
            gl.glColor4f (0.0f, 1.0f, 0.0f, 0.5f);
    
            // Set the face rotation
            gl.glFrontFace(GL10.GL_CW);     
    
            // Point to our vertex buffer
            gl.glVertexPointer (3, GL10.GL_FLOAT, 0, shape.buffer);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture.buffer);
    
            // Draw the vertices as triangle strip
            gl.glDrawArrays (GL10.GL_TRIANGLE_STRIP, 0, shape.vertex.length / 3);
    
            // Disable the client state before leaving
            gl.glDisableClientState (GL10.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    
            gl.glPopMatrix();       
        }
    
        public void position (GL10 gl, float x, float y, float width, float height, float corner)
        {
            gl.glTranslatef (x, y, 0f); //MOVE !!! 1f is size of figure if called after scaling, 1f is pixel if called before scaling
    
            if (corner>0)
            {
                gl.glTranslatef (width/2, height/2, 0f);
                gl.glRotatef (corner, 0f, 0f, 1f); // ROTATE !!!
                gl.glTranslatef (-width/2, -height/2, 0f);          
    
            }
    
            gl.glScalef (width, height, 0f); // ADJUST SIZE !!!
    
        }
    }
    

    and the main thing how to set camera so that 1 opengl unit == 1 pixel annd how to load textures

    public class Scene implements Renderer
    {
        public Context context;
        public Resources resources;
        public SparseIntArray images = new SparseIntArray ();
        public float width;
        public float height;
    
        public Scene (Context context)
        {
            this.context = context;
            this.resources = context.getResources ();
        }
    
        @Override
        public void onDrawFrame (GL10 gl)
        {
    //      // clear Screen and Depth Buffer
            gl.glClear (GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
            gl.glMatrixMode(GL10.GL_MODELVIEW);
    //      // Reset the Modelview Matrix
            gl.glLoadIdentity ();
            draw (gl);
    
        }
    
        @Override
        public void onSurfaceChanged (GL10 gl, int width, int height)
        {
            this.width = width;
            this.height = height;
    
            gl.glViewport (0, 0, width, height); // Reset The Current Viewport
            gl.glMatrixMode (GL10.GL_PROJECTION); // Select The Projection Matrix
            gl.glLoadIdentity (); // Reset The Projection Matrix
    
            gl.glOrthof (0, width, 0, height, -1f, 1f);
            //gl.glTranslatef (0f, -height/2, 0.0f); // move the camera !!
    
    
            gl.glMatrixMode (GL10.GL_MODELVIEW); // Select The Modelview Matrix
            gl.glLoadIdentity (); // Reset The Modelview Matrix
    
            load (gl);
        }
    
        public void onSurfaceCreated(GL10 gl, EGLConfig config) 
        {
            gl.glEnable(GL10.GL_TEXTURE_2D);            //Enable Texture Mapping ( NEW )
            gl.glShadeModel(GL10.GL_SMOOTH);            //Enable Smooth Shading
            gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    //Black Background
            gl.glClearDepthf(1.0f);                     //Depth Buffer Setup
            gl.glEnable(GL10.GL_DEPTH_TEST);            //Enables Depth Testing
            gl.glDepthFunc(GL10.GL_LEQUAL);             //The Type Of Depth Testing To Do
    
            gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
            gl.glEnable(GL10.GL_BLEND);
    
    
            //Really Nice Perspective Calculations
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
    
            init (gl);
        }
    
    
        public void init (GL10 gl)
        {
    
        }
    
        public void load (GL10 gl)
        {
    
        }
    
        public void draw (GL10 gl)
        {
    
        }
    
        private static int next (GL10 gl)
        {
            int[] temp = new int[1];
            gl.glGenTextures (1, temp, 0);
            return temp[0];
        }   
    
        public int image (GL10 gl, int resource)
        {
            int id = next (gl);
            images.put (resource, id);
    
            gl.glBindTexture (GL10.GL_TEXTURE_2D, id);
    
            gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
            gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
    
            gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
            gl.glTexParameterf (GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
    
            gl.glTexEnvf (GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_REPLACE);
    
            BitmapFactory.Options options = new BitmapFactory.Options ();
            options.inScaled = false;
    
            InputStream input = resources.openRawResource (resource);
            Bitmap bitmap;
            try
            {
                bitmap = BitmapFactory.decodeStream (input, null, options);
            }
            finally
            {
                try
                {
                    input.close ();
                }
                catch (IOException e)
                {
                    // Ignore.
                }
            }
    
    //       Matrix flip = new Matrix ();
    //       flip.postScale (1f, -1f);
    //       bitmap = Bitmap.createBitmap (bitmap, 0, 0, bitmap.getWidth (), bitmap.getHeight (), flip, true);
    
            GLUtils.texImage2D (GL10.GL_TEXTURE_2D, 0, bitmap, 0);      
            return id;
        }
    
    }
    

    and some usage

    public class Scene2 extends Scene
    {
        Square square1, square2;
    
        public Scene2(Context context)
        {
            super (context);
            // TODO Auto-generated constructor stub
        }
    
        public void init (GL10 gl)
        {
            square1 = new Square ();
            square2 = new Square ();
        }
    
        public void load (GL10 gl)
        {
            image (gl, R.drawable.s1_clouds);
            image (gl, R.drawable.s1_ground);
        }
    
        public void draw (GL10 gl)
        {
            square1.draw (gl, images.get(R.drawable.s1_clouds), 0, 0, width, height, 0);
            square1.draw (gl, images.get(R.drawable.s1_ground), 0, 0, width, height, 0);
        }
    
    }
    

    the main thing here i wanted to implement and implemented is that the X and Y axis are like in canvas:

    (0,0)
     --------------------------------- X axis
    |
    |
    |
    |
    |
    |
    |
    |
    Y axis
    

    I ll write some full tutorial after this and I like to announce that i achieved all goals i wanted to achieve i.e: X axis on top, Y axis on left, opengl unit = pixel, set size of object in pixels, rotate object, move object everything in pixels. now i ll handle animating sprites and make them in finer classes and thats the new 2d opengl game framework basis...

    discovering this functions helped me tutorial http://www.morrowland.com/apron/tutorials/gl/gl_matrix.php

    So many thanks to this blog for pointing me out the only true way...

    +1 android simpliest 2d opengl game engine in 1 week...

    happy mind blowing...

    :P

    Edit: After year I have a nice framework https://github.com/hazardland/game.android using concepts described here and sample game with any possible framework usage examples here https://github.com/hazardland/ferry.android (view screens on market https://play.google.com/store/apps/details?id=hazardland.borani)

    0 讨论(0)
提交回复
热议问题