2011-06-01 115 views
4

我正在嘗試使用Java和JOGL創建發光效果的幀緩衝區,但我遇到了問題。目前,我的目標是將具有紋理紋理的太空船模型渲染爲幀緩衝紋理,然後將幀緩衝紋理繪製爲三角形風扇四邊形。我用OpenGL 2.1和/或2.0以下運行是我產生幀緩衝,質地代碼:OpenGL Framebuffer呈現紋理不工作

private int createFrameBuffer(GL2GL3 gl) { 
    _frameBufferTextureId = GLHelper.makeTextureBuffer(gl, GL2GL3.GL_RGBA, _width/2, _height/2, 0, GL2GL3.GL_RGBA, 
      GL2GL3.GL_UNSIGNED_BYTE, GL2GL3.GL_TEXTURE_MIN_FILTER, GL2GL3.GL_TEXTURE_MIN_FILTER, GL2GL3.GL_REPEAT, null); 
    int frameBufferId = GLHelper.makeFrameBuffer(gl, _frameBufferTextureId, _width/2, _height/2); 
    return frameBufferId; 
} 

public static int makeTextureBuffer(GL2GL3 gl, int glEnumInternalFormat, int width, int height, int border, 
     int glEnumPixelFormat, int glEnumPixelType, int glEnumMinFilter, int glEnumMagFilter, int glEnumWrapMode, 
     File textureFile) { 
    ByteBuffer textureDataBuffer = null; 
    if (textureFile != null) { 
     String filePath = textureFile.getPath(); 
     String extension = filePath.substring(filePath.lastIndexOf('.') + 1, filePath.length()); 
     TextureData textureData = null; 
     try { 
      textureData = TextureIO.newTextureData(gl.getGLProfile(), textureFile, false, extension); 
     } catch (IOException e) { 
      throw new RuntimeException("Error reading texture"); 
     } 
     textureDataBuffer = getProperlyFormattedBuffer(textureData); 
    } 
    IntBuffer texture = IntBuffer.allocate(1); 
    gl.glGenTextures(1, texture); 
    gl.glBindTexture(GL2GL3.GL_TEXTURE_2D, texture.get(0)); 
    gl.glTexParameteri(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_MIN_FILTER, glEnumMinFilter); 
    gl.glTexParameteri(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_MAG_FILTER, glEnumMagFilter); 
    gl.glTexParameteri(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_WRAP_S, glEnumWrapMode); 
    gl.glTexParameteri(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_WRAP_T, glEnumWrapMode); 
    gl.glTexImage2D(GL2GL3.GL_TEXTURE_2D, 0, glEnumInternalFormat, width, height, border, glEnumPixelFormat, glEnumPixelType, 
      textureDataBuffer); 
    gl.glBindTexture(GL2GL3.GL_TEXTURE_2D, 0); 
    return texture.get(0); 
} 

public static int makeFrameBuffer(GL2GL3 gl, int textureBufferId, int width, int height) { 
    IntBuffer frameBuffer = IntBuffer.allocate(1); 
    gl.glGenFramebuffers(1, frameBuffer); 
    gl.glBindFramebuffer(GL2GL3.GL_FRAMEBUFFER, frameBuffer.get(0)); 
    gl.glFramebufferTexture2D(GL2GL3.GL_FRAMEBUFFER, GL2GL3.GL_COLOR_ATTACHMENT0, GL2GL3.GL_TEXTURE_2D, textureBufferId, 0); 
    verifyFrameBuffer(gl); 
    gl.glBindFramebuffer(GL2GL3.GL_FRAMEBUFFER, 0); 
    return frameBuffer.get(0); 
} 

private void drawTextureQuad(GL2GL3 gl) { 
    _glowShader.bind(gl); 
    int textureLocation = _glowShader.getUniformFields().getIlluminationTextureLocation(); 
    gl.glUniform1i(textureLocation, 0); 
    gl.glActiveTexture(GL2GL3.GL_TEXTURE0); 
    gl.glBindTexture(GL2GL3.GL_TEXTURE_2D, _frameBufferTextureId); 

    int vertexLocation = _glowShader.getAttributeFields().getVertexLocation(); 
    gl.glBindBuffer(GL2GL3.GL_ARRAY_BUFFER, _textureQuadId); 
    gl.glVertexAttribPointer(vertexLocation, 3, GL2GL3.GL_FLOAT, false, 0, 0); 
    gl.glEnableVertexAttribArray(vertexLocation); 

    int textureCoordLocation = _glowShader.getAttributeFields().getVertexTextureCoordinateLocation(); 
    gl.glBindBuffer(GL2GL3.GL_ARRAY_BUFFER, _textureQuadCoordsId); 
    gl.glVertexAttribPointer(textureCoordLocation, 2, GL2GL3.GL_FLOAT, false, 0, 0); 
    gl.glEnableVertexAttribArray(textureCoordLocation); 

    gl.glDrawArrays(GL2GL3.GL_TRIANGLE_FAN, 0, 4); 
    _glowShader.unbind(gl); 
} 

在我的渲染循環,我做了以下內容:

_glowShader.bind(gl);// bind my Shader object. 
gl.glUniformMatrix4fv(_glowShader.getUniformFields().getProjectionMatrixLocation(), 1, true, _projectionMatrix.getBuffer()); 
gl.glUniformMatrix4fv(_glowShader.getUniformFields().getModelViewMatrixLocation(), 1, true, _modelViewMat.getBuffer()); 
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, _framebufferId); 
gl.glDrawBuffers(1, _frameBufferAttachmentss); //contains GL_COLOR_ATTACHMENT0 
gl.glViewport(0, 0, _width/2, _height/2); // same size as texture 
_spaceship.draw(gl, _glowShader);// draw method in my ModelObject class 
gl.glBindFramebuffer(GL.GL_FRAMEBUFFER, 0); 
_glowShader.unbind(gl); 

drawTextureQuad(gl); 

當我運行這個,我的四邊形是應該繪製的,但紋理全是黑色的。當我在渲染循環中註釋掉任何framebuffer綁定時,模型會按照它的原樣渲染,所以我知道我的着色器代碼沒有任何問題。當我用從文件加載的另一個紋理替換_frameBufferTextureId時,該紋理被正確繪製,所以我知道我的紋理座標正在工作,並且我的着色器代碼也是正確的。每當我綁定我的幀緩衝區,但我沒有得到任何我期望的。我也在驗證我的幀緩衝區,它是GL_FRAMEBUFFER_COMPLETE。

我讀過無數的教程和帖子在這裏stackoverflow,但我不能爲我的生活弄清楚我做錯了什麼。任何幫助將是偉大的!謝謝。

+0

這可能沒關係,但是在createFrameBuffer中,看起來你會通過縮放過濾器兩次而不是放大過濾器。 – 2011-06-02 07:45:48

+0

我愛你!對不起,如果這讓你不舒服,但這是我的問題的來源!我實際上應該從未傳過GL_TEXTURE_MIN_FILTER,因爲它們是glTexParameteri()方法中的目標,而不是參數。我將其更改爲GL_LINEAR作爲GL_TEXTURE_MIN_FILTER和GL_TEXTURE_MAX_FILTER目標,並且它非常完美! :D – Wagan8r 2011-06-02 17:22:04

+0

啊,我不知道喬吉爾,所以我無法弄清楚過濾器是如何工作的,我想也許他們是全局設置的,並分配給GL_TEXTURE_MIN_FILTER。使你的修復更有意義;) – 2011-06-02 19:36:00

回答

2

正如Bethor指出的那樣,我將GL_TEXTURE_MIN_FILTER傳遞給了我的makeTextureBuffer方法。這是解決glTexParameteri()的呼籲:

gl.glTexParameteri(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_MIN_FILTER, GL2GL2.GL_TEXTURE_MIN_FILTER); 
gl.glTexParameteri(GL2GL3.GL_TEXTURE_2D, GL2GL3.GL_TEXTURE_MAG_FILTER, GL2GL2.GL_TEXTURE_MIN_FILTER); 

這當然,是沒有任何意義。更改我的呼叫以通過GL_LINEAR修復了一切。