OpenGL:将图像加载到纹理数组中

Posted

技术标签:

【中文标题】OpenGL:将图像加载到纹理数组中【英文标题】:OpenGL: Loading images into texture array 【发布时间】:2011-06-24 07:23:18 【问题描述】:

我正在尝试通过以下 sn-p 将多个纹理(来自 8x8 *.bmp 图像)加载到多个 FBO:

glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8I_EXT, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_NUM, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

for( int i = 0; i < TEXTURE_NUM; i++ )

    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBO_ID[i]);
    glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, TEXTURE_WIDTH, TEXTURE_HEIGHT);
    glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO_ID[i]);
    glFramebufferTextureLayerEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, TexArray_ID, 0, i);
    glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, RBO_ID[i]);
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


checkGLErrors("begin check");
for ( int i = 0; i < TEXTURE_NUM; i++ )

    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO_ID[i]);
    char fileName[32];
    sprintf(fileName, "./img/%02d.bmp", i);
    unsigned char* imgData;
    imgData = loadBMP(fileName);
    if (imgData)
        printf("imgData %s is successfully loaded\n",fileName);
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, imgData);
    checkGLErrors("end check");
    free(imgData);      
    glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, NULL);

但是,我无法使用 glTexSubImage3D 函数附加这些纹理。 CheckGLErrors() 指示错误在以下行,说明“无效值”错误。

glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, imgData);

阅读manual后,我认为错误与以下语句有关:

如果 xoffset w - b , yoffset h - b , or zoffset d - b ,则生成

GL_INVALID_VALUE,其中w 是 GL_TEXTURE_WIDTH,h 是 GL_TEXTURE_HEIGHT,d 是 GL_TEXTURE_DEPTH,b 是正在修改的纹理图像的边框宽度。请注意,w、h 和 d 包含两倍的边框宽度。

这让我不知道如何让这些纹理发挥作用。有任何想法吗?提前致谢。

【问题讨论】:

【参考方案1】:

仅当您想将新图像渲染到纹理中时,将纹理附加到 FBO 才有意义。但是,您已经拥有图像文件形式的图像,因此绝对没有理由将纹理附加到 FBO(除非您想在加载将“牺牲给 FBO”的图像时浪费内存和 CPU 周期)。

摆脱对 FBO 的滥用,你应该会没事的。

也许您将 FBO(Frame 缓冲区对象)与 PBO(像素 缓冲区对象)混淆了,它们是不同类型的东西,实际上使用起来很有意义如果你想加速纹理生成。

因评论而编辑

你真正需要的是一个纹理对象

GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_3D, textureID);

glTexImage3D(GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGB8I_EXT, TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_NUM, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

checkGLErrors("begin check");
for ( int i = 0; i < TEXTURE_NUM; i++ )

    char fileName[32];
    sprintf(fileName, "./img/%02d.bmp", i);
    unsigned char* imgData;
    imgData = loadBMP(fileName);
    if (imgData)
        printf("imgData %s is successfully loaded\n",fileName);
    glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, 8, 8, 1, GL_RGB, GL_UNSIGNED_BYTE, imgData);
    checkGLErrors("end check");
    free(imgData);

【讨论】:

我想我看到了有关性能的问题。谢谢!无论如何,有没有办法加载图像? @snowball147:您不需要 FBO,只需使用 glTexImage3D 加载图像即可。 @snowball47:你的系统真的支持二维纹理数组吗?您必须通过测试您的 OpenGL 版本是否至少为 3.0(要求使用纹理数组)或glGetString(GL_EXTENSIONS); 返回的字符串包含GL_EXT_texture_array 来测试这一点。如果没有,那么您根本无法使用该系统使用它。

以上是关于OpenGL:将图像加载到纹理数组中的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES之如何传输一个超大数组给着色器程序

将纹理快速加载到 OpenGL 2.0

使用OpenGL显示图像?

如何从 OpenGL 中的帧缓冲区纹理中采样像素?

将位图数据加载到 OpenGL 纹理中时出现问题

OpenGL渲染纹理全白