Я пытаюсь реализовать глубинное тестирование 2D-изометрической игры. Чтобы получить что-то работающее, я начал с этого образца, но я не могу заставить его работать правильно.Opengl ничего не записывается в буфер глубины
Я пытаюсь нарисовать 2 изображения в определенном порядке.
first.png
second.png
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;
}