Opengl没有任何东西正在写入深度缓冲区
问题描述:
我试图实现2D等距游戏的深度测试。为了得到一些工作,我开始使用这个示例,但是我无法使它正常工作。Opengl没有任何东西正在写入深度缓冲区
我想按特定顺序绘制2张图像。
first.png
second.png
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;
}
答
好吧,我发现这个问题。
SpriteBatch.begin()不
glDepthMask(假)
从写入深度缓冲器设置glDepthMask为False可防止OpenGL的。
解决方法是在SpriteBatch.begin()后调用glDepthMask(true)