我是OpenGL的新手,在Android上工作。在Web中找到了很好的代码示例,可以记录所有内容。但是我发现了一个大问题:深度测试不起作用,所以在我的模型中,即使它们在另一个面后面,所有与相机相对的面都会被点亮: 我认为在这部分代码中可能会出现一些错误:
/**
* Prepares the off-screen framebuffer.
*/
private void prepareFramebuffer(int width, int height) {
GlUtil.checkGlError("prepareFramebuffer start");
int[] values = new int[1];
// Create a texture object and bind it. This will be the color buffer.
GLES20.glGenTextures(1, values, 0);
GlUtil.checkGlError("glGenTextures");
mOffscreenTexture = values[0]; // expected > 0
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mOffscreenTexture);
GlUtil.checkGlError("glBindTexture " + mOffscreenTexture);
// Create texture storage.
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, width, height, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
// Set parameters. We're probably using non-power-of-two dimensions, so
// some values may not be available for use.
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_NEAREST);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
GlUtil.checkGlError("glTexParameter");
// Create framebuffer object and bind it.
GLES20.glGenFramebuffers(1, values, 0);
GlUtil.checkGlError("glGenFramebuffers");
mFramebuffer = values[0]; // expected > 0
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFramebuffer);
GlUtil.checkGlError("glBindFramebuffer " + mFramebuffer);
// Create a depth buffer and bind it.
GLES20.glGenRenderbuffers(1, values, 0);
GlUtil.checkGlError("glGenRenderbuffers");
mDepthBuffer = values[0]; // expected > 0
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, mDepthBuffer);
GlUtil.checkGlError("glBindRenderbuffer " + mDepthBuffer);
// Allocate storage for the depth buffer.
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16,
width, height);
GlUtil.checkGlError("glRenderbufferStorage");
// Attach the depth buffer and the texture (color buffer) to the framebuffer object.
GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT,
GLES20.GL_RENDERBUFFER, mDepthBuffer);
GlUtil.checkGlError("glFramebufferRenderbuffer");
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, mOffscreenTexture, 0);
GlUtil.checkGlError("glFramebufferTexture2D");
// See if GLES is happy with all this.
int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER);
if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) {
// throw new RuntimeException("Framebuffer not complete, status=" + status);
}
// Switch back to the default framebuffer.
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GlUtil.checkGlError("prepareFramebuffer done");
}
我已经做过的另一件重要事情:
/**
* Prepares window surface and GL state.
*/
private void prepareGl(Surface surface) {
Log.d(TAG, "prepareGl");
EglCore.logCurrent("before creating");
GlUtil.checkGlError("debug");
if (mWindowSurface == null)
mWindowSurface = new WindowSurface(mEglCore, surface, false);
mWindowSurface.makeCurrent();
EglCore.logCurrent("after creation");
glClearColor(0f, 0f, 0f, 1f); //glClearColor(0.15f, 0.15f, 0.15f, 1f);
GlUtil.checkGlError("debug");
glEnable(GL_DEPTH_TEST);
GlUtil.checkGlError("debug");
glEnable(GL_CULL_FACE);
GlUtil.checkGlError("debug");
glCullFace(GL_BACK);
GlUtil.checkGlError("debug");
glShadeModel(GL_SMOOTH);
GlUtil.checkGlError("debug");
glEnable(GL_BLEND);
GlUtil.checkGlError("debug");
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
我做错了什么?哪里可能是错误?
添加onDraw代码:
private void draw() {
GlUtil.checkGlError("draw start");
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthFunc(GL_LESS);
if (leftEye != null) {
resetMatrices();
setModelViewMatrix();
translateMEyes();
eyeTextureProgram.useProgram();
eyeTextureProgram.setViewAndTexture(modelViewProjectionMatrix, textureEye);
setProgramParams(eyeTextureProgram, textureEye);
leftEye.bindData(eyeTextureProgram);
leftEye.draw();
}
if (rightEye != null) {
rightEye.bindData(eyeTextureProgram);
rightEye.draw();
}
glDepthFunc(GL_LEQUAL);
resetMatrices();
setModelViewMatrix();
setProgramParams(faceTextureProgram, textureFace);
headBase.bindData(faceTextureProgram);
headBase.draw();
GlUtil.checkGlError("draw done");
}
答案 0 :(得分:1)
将深度缓冲区的清除值设置为1.0。深度缓冲区的清除值应该是深度范围的最大值,默认值为0.0 - 1.0。
glClearDepth(1.0)
另外,请确保在绘图前清除深度和颜色缓冲区。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)