2016-03-06 2 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, полученный квадрат окрашен только красным.

В конце функции рендеринга я получаю пиксели буфера глубины и перебираю их, проверяя, были ли значения изменены из значений по умолчанию. Кажется, что независимо от того, что я делаю, значения в буфере глубины никогда не меняются.

Сам тест глубины работает, если я устанавливаю зеленые фрагменты на глубину = 1,0, красные фрагменты на глубину = 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()); 
    } 
} 

Vertex шейдер

#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 ложного предотвращает OpenGL от записи в буфер глубины.

Решение должно вызвать glDepthMask (true) после SpriteBatch.begin()