如何找到有效的OpenGL帧缓冲配置/文档

时间:2017-04-10 16:19:12

标签: macos opengl jogl framebuffer stencil-buffer

我使用2011年初的MacBook Pro与macOS Sierra 10.12.4和Intel HD Graphics 3000 512 MB,以及我使用JOGL 。根据{{​​3}}(不幸的是他们还没有新版本的信息),我的系统支持0,16或24 bpp深度缓冲区和0或8 bpp模板缓冲区。然而,当我创建用户帧缓冲区时,似乎实际上有用的是任何人的猜测:

  • 我可以使用GL_DEPTH_COMPONENT_32渲染缓冲区。
  • 我无法使用GL_STENCIL_INDEX8渲染缓冲区 - 无论是否使用16 - 24,我总是会出现GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENTGL_FRAMEBUFFER_UNSUPPORTED错误 - 或32位深度缓冲区。
  • 但我可以使用GL_DEPTH24_STENCIL8渲染缓冲区。

我无法在任何地方为OS X找到GL_DEPTH24_STENCIL8的具体提及。我想确保我的程序可以在各种各样的系统上运行(包括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!");
    ...

1 个答案:

答案 0 :(得分:4)

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

3.0规范增加了required image formats的概念,它们的帧缓冲配置的实现是required to accept。其中包括GL_DEPTH24_STENCIL8。因此,任何兼容的OpenGL实现 required 都支持组合的深度/模板缓冲区。