【问题标题】:How to setup a depth range in a 2D game in opengl es 2.0?如何在 opengl es 2.0 的 2D 游戏中设置深度范围?
【发布时间】:2014-08-02 21:00:52
【问题描述】:

所以我目前正在为 android 开发一个 2D 游戏项目,并且我正在使用 Opengl ES 2.0。我猜我有一个默认范围从 0.0 到 1.0 的深度缓冲区,但我想将它扩展到 0.0 - 100.0。我尝试使用 GLES20.glDepthRangef,但它似乎对我不起作用。 Z 值超出范围的图像:0.0 - 1.0 不会显示在屏幕上。我想念什么吗?我将不胜感激!

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);
}

这是我的顶点着色器:

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;" +
        "}";

【问题讨论】:

    标签: java android opengl-es


    【解决方案1】:

    glDepthRange() 的参数需要在 0.0 到 1.0 的范围内。它的工作方式是 0.0 到 1.0 代表深度缓冲区的整个可用范围。 glDepthRange() 可用于将您的深度值仅映射到完整可用范围的子范围,但不能扩展可用范围。

    控制映射到深度缓冲区范围的坐标范围的方法是使用顶点着色器中应用的变换。 gl_Position中产生的vertex shader的输出坐标是clip坐标,通过位置的x、y、z除以w坐标,转化为标准化的设备坐标(NDC),也就是常说的透视除法.然后映射到深度缓冲区范围的 NDC 中的 z 值范围是 [-1.0, 1.0]。

    在您的特定顶点着色器中,您可以通过将输入位置乘以u_MVPMatrix 来获得gl_Position。要解决您的问题,您需要确保正确设置此矩阵。使用glDepthRange() 不是您正在寻找的解决方案。

    使用投影矩阵,您已经在 z 方向设置了 100 个单位的范围,这看起来与您的目标一致:

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

    问题似乎出在您的视图矩阵上:

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

    第 3 到第 5 个参数是眼点,即调用中的 (0.0, 0.0, 1.0)。第 6 到第 8 个参数是您正在查看的点,即您调用中的 (0.0, 0.0, 0.0) 。因此,您从 z 轴上的一个点向原点看,距离原点一个单位。由于投影矩阵给出的总 z 范围为 100 个单位,因此视域中 z 值的范围为 [-99.0, 1.0]。

    如果您希望可见 z 范围改为 [0.0, 100.0],则需要将视图矩阵中的视点调整为距原点 100 个单位。调用将如下所示:

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

    现在您从点 (0.0, 0.0, 100.0) 向原点看,投影矩阵给出了 100 个单位的范围。这为您提供了 z 坐标的 [0.0, 100.0] 可见范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-05
      相关资源
      最近更新 更多