如何使用android在OGLES2.0中快速绘制图像?

时间:2015-05-29 07:12:43

标签: java android performance opengl-es-2.0

我对android和OGLES2.0有一点了解,但是当我画一张照片大概需要0.4毫秒。因此,我可以在16ms内仅绘制40张图片,以便为我的游戏获得60fps。 这是我的GLRenderer代码: 重要的部分是Render-method和Sprite Class。

 public class GLRenderer implements Renderer {
    // Our matrices
    private final float[]   mtrxProjection          = new float[16];
    private final float[]   mtrxView                = new float[16];
    private final float[]   mtrxProjectionAndView   = new float[16];

    // Geometric variables
    public static int[]     vertices;
    public static short[]   indices;
    public static int[]     uvs;
    public IntBuffer        vertexBuffer;
    public ShortBuffer      drawListBuffer;
    public IntBuffer        uvBuffer;
    public List<Sprite>     sprites;
    public int[]            texturenames;
    public MainActivity     mainActivity;
    // Our screenresolution
    float                   mScreenWidth            = 1280;
    float                   mScreenHeight           = 720;
    float                   ssu                     = 1.0f;
    float                   ssx                     = 1.0f;
    float                   ssy                     = 1.0f;
    float                   swp                     = 1280.0f;
    float                   shp                     = 720.0f;
    Update                  update;
    Images                  images;

    // Misc
    Context                 mContext;
    long                    mLastTime;
    int                     mProgram;

    public GLRenderer (MainActivity mainActivity) {
        this.mContext = mainActivity;
        this.mainActivity = mainActivity;
        this.mLastTime = System.currentTimeMillis() + 100;
        this.sprites = new ArrayList<Sprite>();
    }

    public void onPause () {
        /* Do stuff to pause the renderer */
    }

    public void onResume () {
        /* Do stuff to resume the renderer */
        this.mLastTime = System.currentTimeMillis();
    }

    @Override
    public void onDrawFrame (GL10 unused) {

        // Get the current time
        long now = System.currentTimeMillis();

        // We should make sure we are valid and sane
        if (this.mLastTime > now) return;

        // Get the amount of time the last frame took.
        long elapsed = now - this.mLastTime;
        System.out.println(elapsed);
        // clear Screen and Depth Buffer, we have set the clear color as black.
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        // Drawing all static things like the background
        drawStatics();

        for (Opponent opponent: this.update.opponents) {
            int position = this.sprites.indexOf(opponent.getSprite());

            // Rotate the sprite
            this.sprites.get(position).rotate((float) Math.toRadians(opponent.getAngle()));

            // Create the image information
            SetupImage(opponent.getPicture(), 0);

            // Update our example
            UpdateSprite(position);

            // Render our example
            Render(this.mtrxProjectionAndView, 0);
        }

        for (Tower tower: this.update.towers) {
            long a = System.nanoTime();
            int position = this.sprites.indexOf(tower.getSprite());

            // Rotate the sprite
            this.sprites.get(position).rotate((float) Math.toRadians(tower.getAngle()));

            // Create the image information
            SetupImage(tower.getPicture(), 0);

            // Update our example
            UpdateSprite(position);

            // Render our example
            Render(this.mtrxProjectionAndView, 0);
            System.out.println("time: " + (System.nanoTime() - a));
        }

        for (Bullet bullet: this.update.bullets) {
            int position = this.sprites.indexOf(bullet.getSprite());

            // Rotate the sprite
            this.sprites.get(position).rotate((float) Math.toRadians(bullet.getAngle()));

            // Create the image information
            SetupImage(bullet.getPicture(), 0);

            // Update our example
            UpdateSprite(position);

            // Render our example
            Render(this.mtrxProjectionAndView, 0);
        }

        for (SuperExplosion explosion: this.update.explosions) {
            int position = this.sprites.indexOf(explosion.getSprite());

            // Rotate the sprite
            // sprites.get(position).rotate((float)Math.toRadians(explosion.getAngle()));

            // Create the image information
            SetupImage(explosion.getPicture(), 0);

            // Update our example
            UpdateSprite(position);

            // Render our example
            Render(this.mtrxProjectionAndView, 0);
        }

        drawStatics2();

        // Save the current time to see how long it took :).
        this.mLastTime = now;
        //      System.out.println("höhe "+mScreenHeight+"        breite "+ mScreenWidth);

    }

    private void drawStatics () {
        // Ground
        // Update our example
        long h = System.nanoTime();
        UpdateSprite(0);
        //      for (int i = 0; i < vertices.length; i++) {
        //          System.out.println("vertices [" + i + "]: " + vertices[i]);
        //      }
        // Render our example
        Render(this.mtrxProjectionAndView, 1);
        System.out.println("time: " + (System.nanoTime() - h));
        // Bar
        // Update our example
        UpdateSprite(1);

        // Render our example
        Render(this.mtrxProjectionAndView, 2);

        if (!this.update.upgrade) {
            if (this.update.normalSpeed) {
                // Update our example
                UpdateSprite(2);

                // Render our example
                Render(this.mtrxProjectionAndView, 3);
            } else {
                // Update our example
                UpdateSprite(3);

                // Render our example
                Render(this.mtrxProjectionAndView, 4);
            }
            if (!this.update.start) {
                // Update our example
                UpdateSprite(4);

                // Render our example
                Render(this.mtrxProjectionAndView, 5);
            }
        }

        // UpgradeBar
        if (this.update.upgrade) {
            // Update our example
            UpdateSprite(6);

            // Render our example
            Render(this.mtrxProjectionAndView, 7);
        }
        h = System.nanoTime();
        // Bunny1
        // Update our example
        UpdateSprite(7);

        // Render our example
        Render(this.mtrxProjectionAndView, 8);
        System.out.println("time bunny1 " + (System.nanoTime() - h));
        // CarrotTower
        // Update our example
        UpdateSprite(8);

        // Render our example
        Render(this.mtrxProjectionAndView, 9);

        // MineThrower
        // Update our example
        UpdateSprite(9);

        // Render our example
        Render(this.mtrxProjectionAndView, 10);

        // BunnyKing
        // Update our example
        UpdateSprite(10);

        // Render our example
        Render(this.mtrxProjectionAndView, 11);

    }

    private void drawStatics2 () {
        // Life
        // Update our example
        UpdateSprite(5);

        // Render our example
        Render(this.mtrxProjectionAndView, 6);
    }

    private void Render (float[] m, int index) {

        // get handle to vertex shader's vPosition member
        int mPositionHandle = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "vPosition");

        // Enable generic vertex attribute array
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Prepare the triangle coordinate data
        GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_INT, false, 0, this.vertexBuffer);

        // Get handle to texture coordinates location
        int mTexCoordLoc = GLES20.glGetAttribLocation(riGraphicTools.sp_Image, "a_texCoord");

        // Enable generic vertex attribute array
        GLES20.glEnableVertexAttribArray(mTexCoordLoc);

        // Prepare the texturecoordinates
        GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_INT, false, 0, this.uvBuffer);

        // Get handle to shape's transformation matrix
        int mtrxhandle = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "uMVPMatrix");

        // Apply the projection and view transformation
        GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, m, 0);

        // Get handle to textures locations
        int mSamplerLoc = GLES20.glGetUniformLocation(riGraphicTools.sp_Image, "s_texture");

        // Set the sampler texture unit to 0, where we have saved the texture.
        GLES20.glUniform1i(mSamplerLoc, index);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.texturenames[index]);

        // Set filtering
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        // Draw the triangle
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length, GLES20.GL_UNSIGNED_SHORT, this.drawListBuffer);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
        GLES20.glDisableVertexAttribArray(mTexCoordLoc);

    }

    @Override
    public void onSurfaceChanged (GL10 gl, int width, int height) {

        // We need to know the current width and height.
        this.mScreenWidth = width;
        this.mScreenHeight = height;

        // Redo the Viewport, making it fullscreen.
        GLES20.glViewport(0, 0, (int) this.mScreenWidth, (int) this.mScreenHeight);

        // Clear our matrices
        for (int i = 0; i < 16; i++) {
            this.mtrxProjection[i] = 0.0f;
            this.mtrxView[i] = 0.0f;
            this.mtrxProjectionAndView[i] = 0.0f;
        }

        // Setup our screen width and height for normal sprite translation.
        Matrix.orthoM(this.mtrxProjection, 0, 0f, this.mScreenWidth, 0.0f, this.mScreenHeight, 0, 50);

        // Set the camera position (View matrix)
        Matrix.setLookAtM(this.mtrxView, 0, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

        // Calculate the projection and view transformation
        Matrix.multiplyMM(this.mtrxProjectionAndView, 0, this.mtrxProjection, 0, this.mtrxView, 0);

        // Setup our scaling system
        SetupScaling();

        // Create the GroundSprite
        SetupTriangle(this.images.ground_1.getWidth(), this.images.ground_1.getHeight(), 0, 0);
        SetupTriangle(this.images.bar1.getWidth(), this.images.bar1.getHeight(), 0, 0);
        SetupTriangle(this.images.speed1.getWidth(), this.images.speed1.getHeight(), 0, 0);
        SetupTriangle(this.images.speed2.getWidth(), this.images.speed2.getHeight(), 0, 0);
        SetupTriangle(this.images.start.getWidth(), this.images.start.getHeight(), 0, 0);
        SetupTriangle(this.images.life.getWidth(), this.images.life.getHeight(), 0, 0);
        SetupTriangle(this.images.upgradeBar.getWidth(), this.images.upgradeBar.getHeight(), 0, 0);
        SetupTriangle(this.images.bunny1.getWidth(), this.images.bunny1.getHeight(), 0, 0);
        SetupTriangle(this.images.carrotTower.getWidth(), this.images.carrotTower.getHeight(), 0, 0);
        SetupTriangle(this.images.mineThrower.getWidth(), this.images.mineThrower.getHeight(), 0, 0);
        SetupTriangle(this.images.bunnyKing1.getWidth(), this.images.bunnyKing1.getHeight(), 0, 0);

        this.sprites.get(0).translate(this.ssx * this.images.ground_1.getWidth() / 2, this.ssy * this.images.ground_1.getHeight() / 2);
        this.sprites.get(1).translate(this.ssx * (this.images.bar1.getWidth() / 2) + this.ssx * 1084.0f, this.ssy * this.images.bar1.getHeight() / 2.0f);

        this.sprites.get(2).translate(this.ssx * this.images.speed1.getWidth() / 2 + this.ssx * 20, this.mScreenHeight - (this.ssy * this.images.speed1.getHeight() / 2) - this.ssy * 5);
        this.sprites.get(3).translate(this.ssx * this.images.speed2.getWidth() / 2 + this.ssx * 20, this.mScreenHeight - (this.ssy * this.images.speed2.getHeight() / 2) - this.ssy * 5);
        this.sprites.get(4).translate(this.ssx * this.images.start.getWidth() / 2 + this.ssx * 120, this.mScreenHeight - (this.ssy * this.images.start.getHeight() / 2) - this.ssy * 5);
        this.sprites.get(5).translate(this.ssx * this.images.life.getWidth() / 2 + this.ssx * 5, this.ssy * this.images.life.getHeight() / 2 + this.ssy * (20));
        this.sprites.get(6).translate(this.ssx * this.images.upgradeBar.getWidth() / 2, this.ssy * this.images.upgradeBar.getHeight() / 2);

        this.sprites.get(7).translate(this.ssx * (this.images.bunny1.getWidth()) + this.ssx * (1280 - 143 - (this.images.bunny1.getWidth() / 2)), this.mScreenHeight - (this.ssy * this.images.bunny1.getHeight() / 2) - (this.ssy * (235 + (this.images.bunny1.getHeight() / 2))));
        this.sprites.get(8).translate(this.ssx * (this.images.carrotTower.getWidth()) + this.ssx * (1280 - 53 - (this.images.carrotTower.getWidth() / 2)), this.mScreenHeight - (this.ssy * this.images.carrotTower.getHeight() / 2) - (this.ssy * (235 + (this.images.carrotTower.getHeight() / 2))));
        this.sprites.get(9).translate(this.ssx * (this.images.mineThrower.getWidth()) + this.ssx * (1280 - 143 - (this.images.mineThrower.getWidth() / 2)), this.mScreenHeight - (this.ssy * this.images.mineThrower.getHeight() / 2) - (this.ssy * (325 + (this.images.mineThrower.getHeight() / 2))));
        this.sprites.get(10).translate(this.ssx * (this.images.bunnyKing1.getWidth()) + this.ssx * (1280 - 53 - (this.images.bunnyKing1.getWidth() / 2)), this.mScreenHeight - (this.ssy * this.images.bunnyKing1.getHeight() / 2) - (this.ssy * (325 + (this.images.bunnyKing1.getHeight() / 2))));

    }

    @Override
    public void onSurfaceCreated (GL10 gl, EGLConfig config) {
        // Setup our scaling system
        SetupScaling();

        // Set the clear color to black
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1);

        // Blending
        GLES20.glEnable(GLES20.GL_BLEND);

        // How should opengl blend it
        GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);

        // Create the shaders, solid color
        int vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_SolidColor);
        int fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_SolidColor);

        riGraphicTools.sp_SolidColor = GLES20.glCreateProgram(); // create empty
                                                                    // OpenGL ES
                                                                    // Program
        GLES20.glAttachShader(riGraphicTools.sp_SolidColor, vertexShader); // add
                                                                            // the
                                                                            // vertex
                                                                            // shader
                                                                            // to
                                                                            // program
        GLES20.glAttachShader(riGraphicTools.sp_SolidColor, fragmentShader); // add
                                                                                // the
                                                                                // fragment
                                                                                // shader
                                                                                // to
                                                                                // program
        GLES20.glLinkProgram(riGraphicTools.sp_SolidColor); // creates OpenGL ES
                                                            // program
                                                            // executables

        // Create the shaders, images
        vertexShader = riGraphicTools.loadShader(GLES20.GL_VERTEX_SHADER, riGraphicTools.vs_Image);
        fragmentShader = riGraphicTools.loadShader(GLES20.GL_FRAGMENT_SHADER, riGraphicTools.fs_Image);

        riGraphicTools.sp_Image = GLES20.glCreateProgram(); // create empty
                                                            // OpenGL ES Program
        GLES20.glAttachShader(riGraphicTools.sp_Image, vertexShader); // add the
                                                                        // vertex
                                                                        // shader
                                                                        // to
                                                                        // program
        GLES20.glAttachShader(riGraphicTools.sp_Image, fragmentShader); // add
                                                                        // the
                                                                        // fragment
                                                                        // shader
                                                                        // to
                                                                        // program
        GLES20.glLinkProgram(riGraphicTools.sp_Image); // creates OpenGL ES
                                                        // program executables

        // Set our shader programm
        GLES20.glUseProgram(riGraphicTools.sp_Image);

        // Creating a Images Object
        this.images = new Images(this.mainActivity.getResources());

        // Loading the Bitmaps
        this.images.load();

        Timer t = new Timer();
        t.schedule(this.update = new Update(this.mainActivity, this, this.images), 16);

        // Generate Textures, if more needed, alter these numbers.
        this.texturenames = new int[24];
        GLES20.glGenTextures(24, this.texturenames, 0);
        SetupImageStatics();
    }

    private void SetupImageStatics () {

        SetupImage(this.images.ground_1, 1);
        SetupImage(this.images.bar1, 2);
        SetupImage(this.images.speed1, 3);
        SetupImage(this.images.speed2, 4);
        SetupImage(this.images.start, 5);
        SetupImage(this.images.life, 6);
        SetupImage(this.images.upgradeBar, 7);
        SetupImage(this.images.bunny1, 8);
        SetupImage(this.images.carrotTower, 9);
        SetupImage(this.images.mineThrower, 10);
        SetupImage(this.images.bunnyKing1, 11);
    }

    public void SetupScaling () {
        // The screen resolutions
        this.swp = (this.mContext.getResources().getDisplayMetrics().widthPixels);
        this.shp = (this.mContext.getResources().getDisplayMetrics().heightPixels);

        // Orientation is assumed portrait
        this.ssx = this.swp / 1280.0f;
        this.ssy = this.shp / 720.0f;

        // Get our uniform scaler
        if (this.ssx > this.ssy) this.ssu = this.ssy;
        else this.ssu = this.ssx;
    }

    public void processTouchEvent (MotionEvent me) {
        switch (me.getAction()) {
            case MotionEvent.ACTION_DOWN:
                this.update.x = (int) me.getX();
                this.update.y = (int) me.getY();
                this.update.getItemOrUpgrade(this.update.x, this.update.y);
                this.update.fastForward(this.update.x, this.update.y);
                this.update.start(this.update.x, this.update.y);
                this.update.nextUpgrade(this.update.x, this.update.y);

                break;

            case MotionEvent.ACTION_MOVE:
                if (this.update.tower != 0) {
                    this.update.x = (int) me.getX();
                    this.update.y = (int) me.getY();

                    this.update.pathPlace(this.update.x, this.update.y);
                }

                break;
            case MotionEvent.ACTION_UP:
                this.update.x = (int) me.getX();
                this.update.y = (int) me.getY();

                this.update.placeOrReleaseItem = true;
                break;
        }
    }

    public void UpdateSprite (int location) {
        // Get new transformed vertices
        vertices = this.sprites.get(location).getTransformedVertices();

        // The vertex buffer.
        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        this.vertexBuffer = bb.asIntBuffer();
        this.vertexBuffer.put(vertices);
        this.vertexBuffer.position(0);
    }

    public void SetupImage (Bitmap bmp, int index) {
        // Create our UV coordinates.
        uvs = new int[] { 0, 0, 0, 1, 1, 1, 1, 0 };

        // The texture buffer
        ByteBuffer bb = ByteBuffer.allocateDirect(uvs.length * 4);
        bb.order(ByteOrder.nativeOrder());
        this.uvBuffer = bb.asIntBuffer();
        this.uvBuffer.put(uvs);
        this.uvBuffer.position(0);

        // // Retrieve our image from resources.
        // int id =
        // mContext.getResources().getIdentifier("drawable/ic_launcher", null,
        // mContext.getPackageName());
        //
        // // Temporary create a bitmap
        // Bitmap bmp = BitmapFactory.decodeResource(mContext.getResources(),
        // id);

        // Bind texture to texturename
        GLES20.glActiveTexture(GLES20.GL_TEXTURE0 + index);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, this.texturenames[index]);

        // Set filtering
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);

        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bmp, 0);

        // // We are done using the bitmap so we should recycle it.
        // bmp.recycle();

    }

    public void SetupTriangle (float width, float height, float x, float y) {
        // Get information of sprite.
        this.sprites.add(new Sprite(width, height, x, y));
        vertices = this.sprites.get(this.sprites.size() - 1).getTransformedVertices();

        // The order of vertexrendering for a quad
        indices = new short[] { 0, 1, 2, 0, 2, 3 };

        // The vertex buffer.
        ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
        bb.order(ByteOrder.nativeOrder());
        this.vertexBuffer = bb.asIntBuffer();
        this.vertexBuffer.put(vertices);
        this.vertexBuffer.position(0);

        // initialize byte buffer for the draw list
        ByteBuffer dlb = ByteBuffer.allocateDirect(indices.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        this.drawListBuffer = dlb.asShortBuffer();
        this.drawListBuffer.put(indices);
        this.drawListBuffer.position(0);
    }

    class Sprite {
        float   angle;
        float   scale;
        RectF   base;
        Point   translation;

        public Sprite (float width, float height, float x, float y) {
            // Initialise our intital size around the 0,0 point
            this.base = new RectF(-(width / 2f) * GLRenderer.this.ssu, (height / 2f) * GLRenderer.this.ssu, (width / 2f) * GLRenderer.this.ssu, -(height / 2f) * GLRenderer.this.ssu);

            // Initial translation
            this.translation = new Point(Math.round(x * GLRenderer.this.ssu), Math.round(y * GLRenderer.this.ssu));

            // We start with our inital size
            this.scale = 1f;

            // We start in our inital angle
            this.angle = 0.0f;
        }

        public void translate (float deltax, float deltay) {
            // Update our location.
            this.translation.x += Math.round(deltax);
            this.translation.y += Math.round(deltay);
        }

        public void scale (float deltas) {
            this.scale += deltas;
        }

        public void rotate (float deltaa) {
            this.angle += deltaa;
        }

        public int[] getTransformedVertices () {
            // Start with scaling
            int x1 = Math.round(this.base.left * this.scale);
            int x2 = Math.round(this.base.right * this.scale);
            int y1 = Math.round(this.base.bottom * this.scale);
            int y2 = Math.round(this.base.top * this.scale);

            // We now detach from our Rect because when rotating,
            // we need the seperate points, so we do so in opengl order
            Point one = new Point(x1, y2);
            Point two = new Point(x1, y1);
            Point three = new Point(x2, y1);
            Point four = new Point(x2, y2);

            // We create the sin and cos function once,
            // so we do not have calculate them each time.
            float s = (float) Math.sin(this.angle);
            float c = (float) Math.cos(this.angle);

            // Then we rotate each point
            one.x = Math.round(x1 * c - y2 * s);
            one.y = Math.round(x1 * s + y2 * c);
            two.x = Math.round(x1 * c - y1 * s);
            two.y = Math.round(x1 * s + y1 * c);
            three.x = Math.round(x2 * c - y1 * s);
            three.y = Math.round(x2 * s + y1 * c);
            four.x = Math.round(x2 * c - y2 * s);
            four.y = Math.round(x2 * s + y2 * c);

            // Finally we translate the sprite to its correct position.
            one.x += this.translation.x;
            one.y += this.translation.y;
            two.x += this.translation.x;
            two.y += this.translation.y;
            three.x += this.translation.x;
            three.y += this.translation.y;
            four.x += this.translation.x;
            four.y += this.translation.y;

            // We now return our float array of vertices.
            return new int[] { Math.round(one.x), Math.round(one.y), 0, Math.round(two.x), Math.round(two.y), 0, Math.round(three.x), Math.round(three.y), 0, Math.round(four.x), Math.round(four.y), 0, };
        }
    }

    public class Update extends TimerTask {
        Bitmap                  ball;
        int                     x, y;

        int                     mapStage            = StaticVariables.getMap();
        int                     towerCost           = 200;
        boolean                 start               = false;
        int                     x2                  = 0;
        int                     y2                  = 0;
        public int              points              = 50000;
        public boolean          stageClear          = false;
        boolean                 everythingSpawned   = false;
        public int              life                = 200;
        private int             space               = 40;
        public boolean          stageLose           = false;
        public boolean          upgrade             = false;
        List<Opponent>          opponents           = new ArrayList<Opponent>();
        List<Tower>             towers              = new ArrayList<Tower>();
        List<Bullet>            bullets             = new ArrayList<Bullet>();
        List<SuperExplosion>    explosions          = new ArrayList<SuperExplosion>();
        List<Path>              paths               = new ArrayList<Path>();
        List<int[]>             stages              = new ArrayList<int[]>();
        private List<Integer>   minesPassive        = new ArrayList<Integer>();
        private List<Integer>   removeBulletsIndex  = new ArrayList<Integer>();
        List<Integer>           removeMinesPassive  = new ArrayList<Integer>();

        public int              time                = 16;
        public int              speed               = 1;
        public int              stageLevel          = 1;
        public boolean          placePossible       = true;
        private int             timeTimes           = 0;
        private int             bubble              = 0;
        public boolean          wait                = false;
        public int              mapLength;

        boolean                 change              = false, change1 = false, change2 = false, change3 = false;
        double                  maxX, maxY, minX, minY, abstandX2, abstandX, abstandY2, abstandY, shortestSpacing, shortest, angleMaxX, angleMaxY, angleMinX, angleMinY, angleAbstandX, angleAbstandY;
        int                     shortestIndex, index, spawnCounter = 0;
        private MediaPlayer     bubblePopSound;
        private int             tower               = 0;
        int                     nextImage           = 0;
        private boolean         normalSpeed         = true;
        float                   invisability        = 1;
        private int             upgradeBarDiff      = 0;
        private boolean         hideUpgradeBar      = false;
        public int              iceBallRotation;
        private int             explosionTime;
        private List<MinePlace> minesPlaced         = new ArrayList<MinePlace>();
        private int             gameLocation        = 0;
        Localizer               localizer;
        int                     testCounter;
        boolean                 load                = true;
        private boolean         placeOrReleaseItem  = false;
        double                  viewWidth, viewHeight;
        MergeSort               mergeSort           = new MergeSort();
        GLRenderer              glRenderer2;

        public List<Integer> getMinesPassive () {
            return this.minesPassive;
        }

        public void setMinesPassive (int index2, int minesPassive) {
            this.minesPassive.set(index2, minesPassive);
        }

        public void addMinesPassive (int minesPassive) {
            this.minesPassive.add(minesPassive);
        }

    public void addMinesPassive (int i, Integer minesPassive) {
        this.minesPassive.add(i, minesPassive);

    }   
   }

我希望你知道一种提高绘图速度的方法。 提前谢谢!

1 个答案:

答案 0 :(得分:0)

在您的案例中,如何提高性能有点难。从我的角度来看,代码中的噪音太大了。但一般来说,有一些关于如何在渲染过程中提高性能的基本技巧:   - 避免不必要的OpenGl状态机更改   - 避免不必要的OpenGl状态查询(例如GLES20.glGetAttribLocation())   - 在渲染过程中避免内存分配   - 使用最简单的着色器   - 使用纹理图集以避免必要的纹理绑定   - 尽可能使用VBO

有关主题的更多信息,请尝试阅读https://www.opengl.org/wiki/Performance。或者看一下这个话题https://www.youtube.com/watch?v=YLVbLVtjDDw

您也可以考虑使用libGDX http://libgdx.badlogicgames.com/,它将为您提供有效的绘图精灵。