Визуализация кадрового буфера OpenGL в текстуре не работает - PullRequest
4 голосов
/ 01 июня 2011

Я экспериментирую с кадровыми буферами, чтобы создать эффект свечения, используя Java и JOGL, но у меня проблемы. На данный момент моя цель состоит в том, чтобы визуализировать мою модель космического корабля, текстурированную с помощью текстуры подсветки, в текстуру кадрового буфера, а затем нарисовать текстуру кадрового буфера в квадрате веерного треугольника. Я использую OpenGL 2.1 и / или 2.0. Вот мой код для генерации кадрового буфера и его текстуры:

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);

Когда я запускаю это, мой четырехугольник рисуется так, как должен, но вся текстура черная. Когда я закомментирую любые привязки кадрового буфера в цикле рендеринга, модель отображается так, как должна, поэтому я знаю, что с моим шейдерным кодом все в порядке. Когда я заменяю _frameBufferTextureId другой текстурой, загруженной из файла, эта текстура рисуется правильно, поэтому я знаю, что мои текстурные координаты работают, и, опять же, мой код шейдера верен. Всякий раз, когда я связываю свой буфер кадров, я ничего не получаю. Я также проверяю свой кадровый буфер, и это GL_FRAMEBUFFER_COMPLETE.

Я прочитал здесь бесчисленные учебные пособия и посты по stackoverflow, но я не могу на всю жизнь понять, что я делаю неправильно. Любая помощь будет отличной! Спасибо.

1 Ответ

2 голосов
/ 02 июня 2011

Как указал Бетхор, я дважды передавал 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 исправило все.

...