我使用OpenGL渲染16位灰度图像,需要将渲染数据提取到缓冲区而不进行位深度抽取。我的代码完美适用于英特尔(R)HD Graphics 4000 ,但是在nVidia显卡上( NVIDIA Corporation GeForce G 105M / PCIe / SSE2 , NVIDIA Corporation GeForce GT 640M LE / PCIe / SSE2 )当我尝试使用内部格式 GL_R16_SNORM 渲染到纹理时,它以状态 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 失败。它在我使用 GL_R16 格式时有效,但我也松开了渲染纹理的所有负值。使用英特尔高清显卡,它可以同时使用GL_R16_SNORM和GL_16值。
glTexImage2D(GL_TEXTURE_2D, 0, GL_R16_SNORM, width, height, 0, GL_RED, GL_SHORT, null);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId, 0);
glDrawBuffers(1, new int[] {GL_COLOR_ATTACHMENT0}, 0);
int status = gl.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER);
nVidia卡上GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT状态的原因是什么?你能建议如何调试这种情况吗? (不幸的是glGetError()== GL_NO_ERROR)
编辑:经过进一步测试后,我发现它也适用于ATI显卡。正如Reto Koradi所述,OpenGL版本4.4之前的支持是制造商特定的,它似乎适用于ATI和Intel卡但不适用于nVidia卡。答案 0 :(得分:4)
GL_R16_SNORM
仅成为OpenGL 4.4所需的颜色可渲染格式。
如果您查看4.3规范(从第179页开始)中的大纹理格式表,则会为R16_SNORM
检查“颜色可渲染”字段。但是在第178页的“所需纹理格式”下,R16_SNORM
被列为“仅纹理颜色格式”。这意味着虽然实现可以支持渲染到这种格式,但它不是必需的。
在4.4规范中,表格(从第188页开始)基本上表示相同。 R16_SNORM
在“CR”列中有一个复选标记,表示“颜色可渲染”。但规则发生了变化。在4.4及更高版本中,实现必须支持所有颜色可渲染格式。第186页的“必需的纹理格式”部分现在只是引用表,而不是包含列表。这也在规范的更改日志部分中提到。
这意味着除非您至少需要OpenGL 4.4,否则支持渲染此格式确实取决于供应商/硬件。