2016-03-06 110 views
0

我試圖實現2D等距遊戲的深度測試。爲了得到一些工作,我開始使用這個示例,但是我無法使它正常工作。Opengl沒有任何東西正在寫入深度緩衝區

我想按特定順序繪製2張圖像。

first.png

enter image description here

second.png

enter image description here

first.png首先被吸入,並second.png繪製在頂部。使用片段着色器,我計算出紅色深度比綠色深,因此在紅色碎片上繪製綠色碎片時應丟棄。最終的結果是,當second.png直接在first.png的頂部繪製時,所產生的方形僅着色爲紅色。

在渲染函數結束時,我得到深度緩衝區的像素,並在它們上循環檢查值是否已從默認值更改。似乎不管我做什麼,深度緩衝區中的值都不會改變。

深度測試本身正在工作,如果我將綠色片段設置爲depth = 1.0,將紅色片段設置爲depth = 0.0,並且我的深度函數爲GL_LESS,則只繪製紅色片段,但深度緩衝區不會更改。

代碼是用Java編寫的,但是OpenGL的功能是一樣的。

private SpriteBatch mBatch; 

private Texture mTexture1; 
private Texture mTexture2; 

@Override 
public void create() { 

    mBatch = new SpriteBatch(); 
    mBatch.setShader(new ShaderProgram(Gdx.files.internal("test.vsh"), Gdx.files.internal("test.fsh"))); 

    mTexture1 = new Texture("first.png"); 
    mTexture2 = new Texture("second.png"); 

    Gdx.gl20.glEnable(GL20.GL_DEPTH_TEST); 
    Gdx.gl20.glDepthFunc(GL20.GL_LESS); 
    Gdx.gl20.glDepthMask(true); 

} 

@Override 
public void render() { 

    Gdx.gl20.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); 

    mBatch.begin(); 

    float scale = 4.0f; 

    float x = Gdx.graphics.getWidth()/2; 
    float y = Gdx.graphics.getHeight()/2; 

    mBatch.draw(mTexture1, x - mTexture1.getWidth()/2 * scale, y - mTexture1.getHeight()/2 * scale, 
      mTexture1.getWidth() * scale, mTexture1.getHeight() * scale); 

    mBatch.flush(); 

    mBatch.draw(mTexture2, x - mTexture2.getWidth()/2 * scale, y - mTexture2.getHeight()/2 * scale, 
      mTexture2.getWidth() * scale, mTexture2.getHeight() * scale); 

    mBatch.end(); 

    int width = Gdx.graphics.getWidth(); 
    int height = Gdx.graphics.getHeight(); 
    FloatBuffer buffer = BufferUtils.newFloatBuffer(width * height); 
    Gdx.gl20.glReadPixels(0, 0, width, height, GL20.GL_DEPTH_COMPONENT, GL20.GL_FLOAT, 
      buffer); 

    for (int i = 0; i < width * height; i++) { 
     float pixel = buffer.get(i); 
     if (pixel != 1.0f && pixel != 0.0f) { 
      // why is this never thrown?? 
      // it means depth buffer wasn't changed. 
      throw new IllegalStateException("OMG IT WORKS!! " + pixel); 
     } 
    } 

    if (Gdx.gl20.glGetError()!=0) { 
     throw new Error("OPENGL ERROR: " + Gdx.gl20.glGetError()); 
    } 
} 

頂點着色器

#ifdef GL_ES 
precision mediump float; 
#endif 

attribute vec3 a_position; 
attribute vec4 a_color; 
attribute vec2 a_texCoord0; 

uniform mat4 u_projTrans; 
varying vec4 v_color; 
varying vec2 v_texCoord; 

void main() 
{ 
    gl_Position = u_projTrans * vec4(a_position, 1); 
    v_color = a_color * 2.0; 
    v_texCoord = a_texCoord0; 
} 

片段着色器

#ifdef GL_ES 
precision mediump float; 
#endif 

uniform sampler2D u_texture; 

varying vec4 v_color; 
varying vec2 v_texCoord; 

void main() 
{ 

    vec4 texel = v_color * texture2D(u_texture, v_texCoord); 

    if (texel.r > texel.g) 
    { 
     gl_FragDepth = 0.0; 
    } 
    else 
    { 
     gl_FragDepth = 0.5; 
    } 


    gl_FragColor = texel; 
} 

回答

0

好吧,我發現這個問題。

SpriteBatch.begin()不

glDepthMask(假)

從寫入深度緩衝器設置glDepthMask爲False可防止OpenGL的。

解決方法是在SpriteBatch.begin()後調用glDepthMask(true)