简体   繁体   中英

How to setup a depth range in a 2D game in opengl es 2.0?

So I'm currently working on a 2D game project for android and I'm using Opengl ES 2.0. I have a depth buffer ranging by default from 0.0 to 1.0 I guess but I would like to extend it to 0.0 - 100.0. I tried to use the GLES20.glDepthRangef, but it doesn't seem to work for me. Images that have Z value beyond the scope: 0.0 - 1.0 just don't show up on the screen. Do I miss anything? I would be grateful for help!

private final float[] mtrxProjection = new float[16];
private final float[] mtrxView = new float[16];
private final float[] mtrxProjectionAndView = new float[16];

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

        //current width and height.
        swp = width;
        shp = height;

        // Redo the Viewport, making it fullscreen.
        GLES20.glViewport(0, 0, (int)swp, (int)shp);

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

        // Setup our screen width and height for normal sprite translation.
        Matrix.orthoM(mtrxProjection, 0, 0f, swp, 0.0f, shp, 0, 100);

        // Depth testing
        GLES20.glEnable( GLES20.GL_DEPTH_TEST );
        GLES20.glDepthFunc( GLES20.GL_LEQUAL );
        GLES20.glDepthMask( true ); 
        GLES20.glDepthRangef(0,  100);

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

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

And here's my vertex shader:

public static final String vs_Image =
        "uniform mat4 u_MVPMatrix;" + // u_MVPMatrix is the mtrxProjectionAndView calculated above
        "attribute vec4 a_position;" +
        "attribute vec2 a_texCoord;" +
        "varying vec2 v_texCoord;" +
        "void main() {" +
        "  gl_Position = u_MVPMatrix * a_position;" +
        "  v_texCoord = a_texCoord;" +
        "}";

The parameters to glDepthRange() need to be in the range 0.0 to 1.0. The way this works is that 0.0 to 1.0 represents the whole available range of the depth buffer. glDepthRange() can be used to map your depth values to only a sub-range of the full available range, but it cannot extend the available range.

The way you control the range of coordinates that gets mapped to the depth buffer range is with the transformations applied in the vertex shader. The output coordinates of the vertex shader that are produced in gl_Position are in clip coordinates, which are turned into normalized device coordinates (NDC) by dividing x, y and z of the position by the w coordinate, which is often called perspective division. The range of z-values in NDC that is then mapped to the depth buffer range is [-1.0, 1.0].

In your specific vertex shader, you obtain gl_Position by multiplying the input position with u_MVPMatrix . To solve your problem, you need to make sure that this matrix is properly set up. Using glDepthRange() is not the solution you're looking for.

With your projection matrix, you're already setting up a range of 100 units in z-direction, which looks consistent with your goal:

Matrix.orthoM(mtrxProjection, 0, 0f, swp, 0.0f, shp, 0, 100);

The problem appears to be with your view matrix:

Matrix.setLookAtM(mtrxView, 0, 0f, 0f, 1f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

The 3rd to 5th arguments are the eye point, which is (0.0, 0.0, 1.0) in your call. The 6th to 8th arguments are the point you're looking at, which is (0.0, 0.0, 0.0) in your call. So you're looking from a point on the z-axis one unit away from the origin towards the origin. Since the total z-range given by the projection matrix is 100 units, the range of z values in the view volume is therefore [-99.0, 1.0].

If you want the visible z-range to be [0.0, 100.0] instead, you need to adjust the eye point in the view matrix to be 100 units away from the origin. The call would then look like this:

Matrix.setLookAtM(mtrxView, 0, 0f, 0f, 100f, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

Now you're looking from point (0.0, 0.0, 100.0) towards the origin, with a range of 100 units given by the projection matrix. This gives you the [0.0, 100.0] visible range for the z-coordinates.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM