Android OpenGL2.0渲染器正确缩放到分辨率

时间:2015-05-04 18:08:59

标签: android opengl-es-2.0

我在Android上绘制的坐标在-1.0和1.0之间,但渲染器将这些坐标映射到错误的位置。在横向中,宽度不会延伸到角落,而在纵向中,宽度会略微延伸到屏幕边框上。我正试着让这个填满屏幕分辨率。这是我的代码:

package com.mycompany.brickbreaker;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.Matrix;
import android.util.Log;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

public class MyGLRenderer implements GLSurfaceView.Renderer {
    private BrickBreaker game;

    public MyGLRenderer(BrickBreaker activity) {
        super();
        game = activity;
    }

    //mMVPMatrix stands for "Model View Projection Matrix"
    private final float[] mMVPMatrix = new float[16];
    private final float[] mProjectionMatrix = new float[16];
    private final float[] mViewMatrix = new float[16];

    public void onSurfaceCreated(GL10 unused, EGLConfig config) {
        //Set the background frame color
        GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    }

    @Override
    public void onDrawFrame(GL10 unused){
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

        //Set the camera position (View Matrix)
        Matrix.setLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0f);

        //Calculate the projection and view transformation
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

        //Draw the rectangle!
        game.draw(mMVPMatrix);
    }

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

        GLES20.glViewport(0, 0, width, height);

        Log.d("Touch", "Surface changed at height/width " + height + "/" + width);
        float ratio = (float) width/(float) height;

        //This projection matrix is applied to object coordinates in
        //the onDrawFrame() method
        Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
    }

    public static int loadShader(int type, String shaderCode){
        //create the shader type
        int shader = GLES20.glCreateShader(type);

        //add the code to the shader, and compile it
        GLES20.glShaderSource(shader, shaderCode);
        GLES20.glCompileShader(shader);

        return shader;
    }
}

2 个答案:

答案 0 :(得分:0)

I'm not an expert at openGL, but I do have a working engine.

In your on SurfaceChanged, you pass in the old projectionMatrix.

You should add the following code:

//Clear the matricies
    for(int i=0;i<16;i++)
    {
        mProjectionMatrix[i] = 0.0f;
        mViewMatrix[i] = 0.0f;
        mMVPMatrix[i] = 0.0f;
    }

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

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

    // Calculate the projection and view transformation
    Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);

Hopefully that fixes your problem.

答案 1 :(得分:0)

所以我解决了这个问题。发生的事情是,当使用Matrix.frustumM(0,0,-ratio,ratio ....)创建投影矩阵时,openGl网格实际上在X和Y中从-1变为1, y中的-1到1网格,x坐标中的比率范围为-ratio。将我使用的任何x坐标乘以传递给frustumM的比率,使得一切都很开心。