我正在尝试在JOGL 2.0中实现简单的阴影映射技术,并且难以将深度值渲染到纹理中。也许我做的完全错误,但是以彩色渲染场景正常工作是很奇怪的。我还在stackoverflow上找到了一个类似的问题,在这里被问到:Render the depth buffer into a texture using a frame buffer通过调用解决问题gl.glDrawBuffer(GL2.GL_NONE);gl.glReadBuffer(GL2.GL_NONE);但是,这对我来说没有帮助。当我照常用彩色纹理渲染场景时,功能正常工作。结果如下:但是,在尝试渲染深度值之后,它仅渲染白色(有些根本与场景不符)----更新的代码,现在可以正常工作:private void initializeFBO3(GL2 gl) {//Create frame buffergl.glGenFramebuffers(1, frameBufferID, 0);gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferID[0]);// ------------- Depth buffer texture --------------gl.glGenTextures(1,depthBufferID,0);gl.glBindTexture(GL2.GL_TEXTURE_2D, depthBufferID[0]);gl.glTexImage2D(GL2.GL_TEXTURE_2D, // target texture type 0, // mipmap LOD level GL2.GL_DEPTH_COMPONENT, // internal pixel format //GL2.GL_DEPTH_COMPONENT shadowMapWidth, // width of generated image shadowMapHeight, // height of generated image 0, // border of image GL2.GL_DEPTH_COMPONENT, // external pixel format GL2.GL_UNSIGNED_INT, // datatype for each value null); // buffer to store the texture in memory//Some parametersgl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP_TO_EDGE);gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_T, GL2.GL_CLAMP_TO_EDGE);//Attach 2D texture to this FBOgl.glFramebufferTexture2D(GL2.GL_FRAMEBUFFER, GL2.GL_DEPTH_ATTACHMENT, GL2.GL_TEXTURE_2D, depthBufferID[0],0);gl.glBindTexture(GL2.GL_TEXTURE_2D, 0);//Disable color buffer//https://stackoverflow.com/questions/12546368/render-the-depth-buffer-into-a-texture-using-a-frame-buffergl.glDrawBuffer(GL2.GL_NONE);gl.glReadBuffer(GL2.GL_NONE);//Set pixels ((width*2)* (height*2))//It has to have twice the size of shadowmap sizepixels = GLBuffers.newDirectByteBuffer(shadowMapWidth*shadowMapHeight*4);//Set default frame buffer before doing the check//http://www.opengl.org/wiki/FBO#Completeness_Rulesgl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0);int status = gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER);// Always check that our framebuffer is okif(gl.glCheckFramebufferStatus(GL2.GL_FRAMEBUFFER) != GL2.GL_FRAMEBUFFER_COMPLETE){ System.err.println("Can not use FBO! Status error:" + status);}}public void display(GLAutoDrawable drawable) { GL2 gl = drawable.getGL().getGL2(); // get the OpenGL graphics context gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); gl.glLoadIdentity(); // reset the model-view matrix //Render scene into Frame buffer first gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, frameBufferID[0]); renderSmallScene(gl); //Read pixels from buffer gl.glBindFramebuffer(GL2.GL_READ_FRAMEBUFFER, frameBufferID[0]); //Read pixels gl.glReadPixels(0, 0, shadowMapWidth, shadowMapHeight, GL2.GL_DEPTH_COMPONENT , GL2.GL_UNSIGNED_BYTE, pixels); //Switch back to default FBO gl.glBindFramebuffer(GL2.GL_FRAMEBUFFER, 0); drawSceneObjects(gl); //Draw pixels, format has to have only one gl.glDrawPixels(shadowMapWidth, shadowMapHeight, GL2.GL_LUMINANCE , GL2.GL_UNSIGNED_BYTE, pixels); }工作结果: 最佳答案 您必须阅读有关一般使用FBO和OpenGL的内容。在您的代码中,在每个框架中创建FBO及其附件。错了,这是巨大的开销,只能在init上构造一次FBO,其次,必须绑定FBO才能将其绘制(或读取),否则OpenGL将绘制到默认FBO中,请查看here和因此,一旦您的FBO准备就绪,您就可以像这样渲染它:glBindFrameBuffer((GL_DRAW_FRAMEBUFFER, yourFbo); drawSceneObjects(gl);glBindFrameBuffer((GL_READ_FRAMEBUFFER, yourFbo); readPixelsHere() glBindFrameBuffer((GL_FRAMEBUFFER, 0);///switch to default FBO实际上,根据您的情况,当您离开FBO时,只需致电 glBindFrameBuffer((GL_READ_FRAMEBUFFER, yourFbo);绘制几何图形之后。另外,如果您不使用着色器,则没有理由将纹理用作FBO附件,而是创建渲染缓冲区。
08-16 20:14