简体   繁体   English

如何在opengl es 2.0中的2D游戏中设置深度范围?

[英]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. 因此,我目前正在为Android进行2D游戏项目,并且正在使用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. 我的深度缓冲区默认范围是0.0到1.0,但我想将其扩展到0.0-100.0。 I tried to use the GLES20.glDepthRangef, but it doesn't seem to work for me. 我尝试使用GLES20.glDepthRangef,但它似乎对我不起作用。 Images that have Z value beyond the scope: 0.0 - 1.0 just don't show up on the screen. Z值超出范围:0.0-1.0的图像不会显示在屏幕上。 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. glDepthRange()的参数必须在0.0到1.0的范围内。 The way this works is that 0.0 to 1.0 represents the whole available range of the depth buffer. 其工作方式是0.0到1.0代表深度缓冲区的整个可用范围。 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. glDepthRange()可用于将深度值映射到整个可用范围的子范围,但不能扩展可用范围。

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. gl_Position中生成的顶点着色器的输出坐标位于剪辑坐标中,通过将位置的x,y和z除以w坐标可将其转换为归一化设备坐标(NDC),通常将其称为透视划分。 The range of z-values in NDC that is then mapped to the depth buffer range is [-1.0, 1.0]. NDC中的z值范围然后映射到深度缓冲区范围为[-1.0,1.0]。

In your specific vertex shader, you obtain gl_Position by multiplying the input position with u_MVPMatrix . 在特定的顶点着色器中,您gl_Position通过将输入位置乘以gl_Position来获得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. 使用glDepthRange()不是您要的解决方案。

With your projection matrix, you're already setting up a range of 100 units in z-direction, which looks consistent with your goal: 使用投影矩阵,您已经在z方向上设置了100个单位的范围,这看起来与您的目标一致:

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. 第3至第5个自变量是视点,在您的调用中为(0.0,0.0,1.0)。 The 6th to 8th arguments are the point you're looking at, which is (0.0, 0.0, 0.0) in your call. 第6至第8个自变量是您要查看的点,在调用中为(0.0,0.0,0.0)。 So you're looking from a point on the z-axis one unit away from the origin towards the origin. 因此,您正在从z轴上的一个点看,从原点到原点的距离为一个单位。 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]. 由于投影矩阵给出的总z范围为100个单位,因此视图体积中z值的范围为[-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. 如果要将可见z范围改为[0.0,100.0],则需要将视图矩阵中的视点调整为距原点100个单位。 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. 现在,您从点(0.0、0.0、100.0)朝原点看,投影矩阵给出了100个单位的范围。 This gives you the [0.0, 100.0] visible range for the z-coordinates. 这为z坐标提供了[0.0,100.0]可见范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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