Как найти правильную конфигурацию / документацию кадрового буфера 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 требуется для поддержки комбинированных буферов глубины / трафарета.