如何找到有效的 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_DEPTH_COMPONENT_32
渲染缓冲区一起工作。
- 我无法让它与
GL_STENCIL_INDEX8
渲染缓冲区一起工作——无论我是否使用 16-、24,我总是得到 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
或 GL_FRAMEBUFFER_UNSUPPORTED
错误- 或 32 位深度缓冲区。
- 但我可以让它与
GL_DEPTH24_STENCIL8
渲染缓冲区一起工作。
我无法在任何地方找到 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 缓冲区。
我使用的是 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_DEPTH_COMPONENT_32
渲染缓冲区一起工作。 - 我无法让它与
GL_STENCIL_INDEX8
渲染缓冲区一起工作——无论我是否使用 16-、24,我总是得到GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
或GL_FRAMEBUFFER_UNSUPPORTED
错误- 或 32 位深度缓冲区。 - 但我可以让它与
GL_DEPTH24_STENCIL8
渲染缓冲区一起工作。
我无法在任何地方找到 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 缓冲区。