如何找到有效的 OpenGL 帧缓冲区 configuration/documentation

How to find valid OpenGL framebuffer configuration/documentation

我使用的是 2011 年初的 MacBook Pro,配备 macOS Sierra 10.12.4 和 Intel HD Graphics 3000 512 MB,我使用的是 JOGL。根据 OS X 10.9 Core Profile OpenGL Information(不幸的是,他们还没有更新版本的信息),我的系统支持 0、16 或 24 bpp 深度缓冲区和 0 或 8 bpp 模板缓冲区。然而,当我创建用户帧缓冲区时,似乎实际起作用的是任何人的猜测:

我无法在任何地方找到 GL_DEPTH24_STENCIL8 for OS X 的具体提及。我想确保我的程序可以在各种系统上运行(包括 Windows 和 Linux,因为它是一个 JOGL 应用程序),但似乎我所能做的就是猜测和检查各种帧缓冲区配置,直到我找到一个可用的配置。

真的没有更好的方法来决定使用什么帧缓冲区配置吗?是否有我还没有找到的具有更好文档的网站?供应商是否出于某种原因难以记录?

代码示例

配置不成功
    int[] temps = new int[3];
    this.width = width;
    this.height = height;

    gl3.glGenFramebuffers(1, temps, 0);
    framebuffer = temps[0];
    gl3.glBindFramebuffer(GL.GL_FRAMEBUFFER, framebuffer);

    int numBuffers = 2;
    if (desiredUseStencilBuffer) {
        numBuffers++;
    }
    gl3.glGenRenderbuffers(numBuffers, temps, 0);
    colorBuffer = temps[0];
    depthBuffer = temps[1];
    stencilBuffer = temps[2];

    numSamples = targetNumSamples;
    useStencilBuffer = desiredUseStencilBuffer;

    if (numSamples > 1) {
        gl3.glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
        gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL.GL_RGBA8,
                width, height);

        gl3.glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
        gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples,
                GL.GL_DEPTH_COMPONENT24, width, height);
        if (useStencilBuffer) {
            gl3.glBindRenderbuffer(GL_RENDERBUFFER, stencilBuffer);
            gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples,
                    GL3.GL_STENCIL_INDEX8, width, height);
        }
    } else {
        gl3.glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
        gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL.GL_RGBA8, width, height);

        gl3.glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
        gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL.GL_DEPTH_COMPONENT24, width, height);
        if (useStencilBuffer) {
            gl3.glBindRenderbuffer(GL_RENDERBUFFER, stencilBuffer);
            gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL3.GL_STENCIL_INDEX8,
                    width, height);
        }
    }

    gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL2ES3.GL_DEPTH_ATTACHMENT,
            GL_RENDERBUFFER, depthBuffer);
    if (useStencilBuffer) {
        gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL2ES3.GL_STENCIL_ATTACHMENT,
                GL_RENDERBUFFER, stencilBuffer);
    }

    int status = gl3.glCheckFramebufferStatus(GL_FRAMEBUFFER);
    switch (status) {
    case GL.GL_FRAMEBUFFER_COMPLETE:
        break;

    case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
        throw new RuntimeException("An attachment could not be bound to frame buffer object!");
配置成功
    int[] temps = new int[3];
    this.width = width;
    this.height = height;

    gl3.glGenFramebuffers(1, temps, 0);
    framebuffer = temps[0];
    gl3.glBindFramebuffer(GL.GL_FRAMEBUFFER, framebuffer);

    gl3.glGenRenderbuffers(2, temps, 0);
    colorBuffer = temps[0];
    depthBuffer = temps[1];

    numSamples = targetNumSamples;
    useStencilBuffer = desiredUseStencilBuffer;

    if (numSamples > 1) {
        gl3.glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
        gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples, GL.GL_RGBA8,
                width, height);

        gl3.glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
        if (useStencilBuffer) {
            gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples,
                    GL.GL_DEPTH24_STENCIL8, width, height);
        } else {
            gl3.glRenderbufferStorageMultisample(GL_RENDERBUFFER, numSamples,
                    GL.GL_DEPTH_COMPONENT32, width, height);
        }
    } else {
        gl3.glBindRenderbuffer(GL_RENDERBUFFER, colorBuffer);
        gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL.GL_RGBA8, width, height);

        gl3.glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
        if (useStencilBuffer) {
            gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL.GL_DEPTH24_STENCIL8,
                    width, height);
        } else {
            gl3.glRenderbufferStorage(GL_RENDERBUFFER, GL.GL_DEPTH_COMPONENT32,
                    width, height);
        }
    }

    gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorBuffer);
    if (useStencilBuffer) {
        gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL2ES3.GL_DEPTH_STENCIL_ATTACHMENT,
                GL_RENDERBUFFER, depthBuffer);
    } else {
        gl3.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                GL_RENDERBUFFER, depthBuffer);
    }

    int status = gl3.glCheckFramebufferStatus(GL_FRAMEBUFFER);
    switch (status) {
    case GL.GL_FRAMEBUFFER_COMPLETE:
        break;

    case GL.GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
        throw new RuntimeException("An attachment could not be bound to frame buffer object!");
    ...

OpenGL 规范不要求您可以将单独的深度和模板图像附加到帧缓冲区。 API 允许您尝试,但个别实现可以选择通过为您提供不受支持的完成状态来禁止它。

3.0 规范为其帧缓冲区配置添加了 required image formats, which implementations are required to accept 的概念。其中有GL_DEPTH24_STENCIL8。因此,任何兼容的 OpenGL 实现都需要 以支持组合 depth/stencil 缓冲区。