Как найти правильную конфигурацию / документацию кадрового буфера OpenGL

Я использую MacBook Pro начала 2011 года с macOS Sierra 10.12.4 и Intel HD Graphics 3000 512 МБ, и я использую JOGL. Согласно информации OS X 10.9 Core Profile OpenGL (к сожалению, у них пока нет информации о более новых версиях), моя система поддерживает буферы глубины 0, 16 или 24 бит / с и буферы трафарета 0 или 8 бит / с. Тем не менее кажется, что на самом деле работает, когда я создаю пользовательский кадровый буфер, можно только догадываться:

  • Я могу заставить его работать с GL_DEPTH_COMPONENT_32 буфер рендеринга.
  • Я не могу заставить его работать с GL_STENCIL_INDEX8 буфер рендеринга - я всегда получаю GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT или же GL_FRAMEBUFFER_UNSUPPORTED ошибки, независимо от того, использую ли я 16-, 24- или 32-битный буфер глубины.
  • Но я могу заставить его работать с GL_DEPTH24_STENCIL8 буфер рендеринга.

Я не смог найти конкретное упоминание о GL_DEPTH24_STENCIL8 для 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!");
    ...

1 ответ

Решение

Спецификация OpenGL не требует, чтобы вы могли прикреплять отдельные изображения глубины и трафарета к кадровому буферу. API позволяет вам попробовать его, но отдельные реализации могут запретить его, предоставив вам неподдерживаемое состояние завершения.

В спецификации 3.0 добавлена ​​концепция требуемых форматов изображений, которые реализации должны принять для своих конфигураций кадрового буфера. Среди них есть GL_DEPTH24_STENCIL8, Таким образом, любая совместимая реализация OpenGL требуется для поддержки комбинированных буферов глубины / трафарета.

Другие вопросы по тегам