Constant FPS Android OpenGLES

后端 未结 2 816
星月不相逢
星月不相逢 2021-01-01 06:20

Hello android developers,

I am developing a simple game for Android in Eclipse using OpenGLES 1.0. I am using Samsung Galaxy S2 Android(2.3) as a device for developm

相关标签:
2条回答
  • 2021-01-01 06:53
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        GLES20.glClearColor(0.1f, 0.1f, 0.1f, 1);
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        GLES20.glDepthFunc(GLES20.GL_LEQUAL);
        GLES20Renderer.programLight = GLES20.glCreateProgram();
        int vertexShaderLight       = GLES20Renderer.loadShader(GLES20.GL_VERTEX_SHADER, GLES20Renderer.vertexShaderCodeLight);
        int fragmentShaderLight     = GLES20Renderer.loadShader(GLES20.GL_FRAGMENT_SHADER, GLES20Renderer.fragmentShaderCodeLight);
        GLES20.glAttachShader(GLES20Renderer.programLight, vertexShaderLight);
        GLES20.glAttachShader(GLES20Renderer.programLight, fragmentShaderLight);
        GLES20.glLinkProgram(GLES20Renderer.programLight);
        System.gc();
    }
    
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        float ratio = (float) width / height;
        Matrix.setLookAtM(GLES20Renderer.ViewMatrix, 0, 0, 0, 5f, 0, 0, 0, 0, 1, 0);
        Matrix.frustumM(GLES20Renderer.ProjectionMatrix, 0, -ratio, ratio, -1, 1, 2, 8);
        Matrix.setIdentityM(LightModelMatrix, 0);
        Matrix.translateM(LightModelMatrix, 0, -1.0f, 0.0f, 3f);
        Matrix.multiplyMV(LightPosInWorldSpace, 0, LightModelMatrix, 0, LightPosInModelSpace, 0);
        Matrix.multiplyMV(LightPosInEyeSpace, 0, ViewMatrix, 0, LightPosInWorldSpace, 0);
    
        System.gc();
    }
    
    public void onDrawFrame(GL10 gl) {
        long deltaTime,startTime,endTime;
        startTime   = SystemClock.uptimeMillis() % 1000;
        gl.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
        synchronized (this) {
            updateModel(GLES20Renderer._xAngle, GLES20Renderer._yAngle, GLES20Renderer._zAngle);            
        }
        renderModel(gl);
        endTime     = SystemClock.uptimeMillis() % 1000;
        deltaTime   = endTime - startTime;
        if (deltaTime < 30) {
            try {
                Thread.sleep(30 - deltaTime);
            } catch (InterruptedException e) {
                //e.printStackTrace();
            }
        }
    
        System.gc();
    }
    

    ATTENTION:

    1. Never use sleep in the UI thread; it is very very very bad
    2. Use statics: although this is bad OOP practice, it is useful here
    3. Use vertexbuffer objects
    4. Initialize in onsurfacechanged and fetch locations (glget__location) here too
    5. It is not your fault always because Froyo garbage collector is bad and then on Gingerbread the touch drivers fire too many events (Google this) so gradually switch to other input methods for your app/game that does not use touch like Android sensors
    6. Upgrade to Gingerbread
    0 讨论(0)
  • 2021-01-01 06:58

    You should use elapsed time to scale all your movement, so that the movement stays smooth at varying FPS rates. You can get elapsed time like this:

    long currentTime = System.currentTimeMillis();
    float elapsed = (System.currentTimeMillis() - lastFrameTime) * .001f;//convert ms to seconds
    lastFrameTime = currentTime; 
    

    Then express your velocities in units per second, and update position like this:

    sprite.x += (sprite.xspeed * elapsed);
    
    0 讨论(0)
提交回复
热议问题