【问题标题】:glTexImage2D crashing programglTexImage2D 崩溃程序
【发布时间】:2020-03-14 11:23:08
【问题描述】:

这是我的代码:

int h, w, c;
unsigned char* img = stbi_load("bricks.jpg", &w, &h, &c, 0);
if (img == NULL) {
    printf("Error in loading the image\n");
}
printf("Image loaded with width of %d, height of %d, and %d channels", w, h, c);

GLuint txtr = 0;
glEnable(GL_TEXTURE_2D);
glGenTextures(1, &txtr);
glBindTexture(GL_TEXTURE_2D, txtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);

由于某种原因,当我取消评论 glTexImage2D 时,我的窗口不再打开。 wh 均由 stbi_load 计算,它是 stb_image.h 库的一部分。我的错在哪里?

【问题讨论】:

    标签: c++ visual-studio opengl glut


    【解决方案1】:

    jpg 图像由 3 个颜色通道 (GL_RGB) 组成,stbi_load 返回一个紧凑的图像。图像缓冲区(img)的字节数为w * h * 3

    默认情况下,OpenGL 假定图像的每一行的开头对齐 4 个字节。这是因为GL_UNPACK_ALIGNMENT 参数默认为 4。由于图像有 3 个颜色通道,并且紧密排列,因此行的开头可能未对齐。
    所以图像缓冲区的大小假定为aligne(w*3, 4) * h

    导致崩溃的原因是glTexImage2D。越界访问缓冲区。

    在指定二维纹理图像(glTexImage2D)之前,将GL_UNPACK_ALIGNMENT参数更改为1:

    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, img);
    

    注意,glPixelStorei 设置了一个全局状态,该状态会一直保留到再次更改为止。

    【讨论】:

      【解决方案2】:

      我想您的问题的根源是stbi_load 方法加载的像素图中的通道数与您作为第 7 个参数传递给glTexImage2D 方法的原始图像格式的通道数不匹配。 基本上,glTexImage2D(GL_TEXTURE_2D, 0, INTERNAL_FORMAT, WIDTH, HEIGHT, 0, SOURCE_FORMAT, SOURCE_TYPE, SOURCE_PIXMAP_DATA) 导致 OpenGL 创建一个 2D 纹理,其内部像素表示为 INTERNAL_FORMAT,它具有 WIDTH 像素宽和 HEIGH 像素高来自源像素图 SOURCE_PIXMAP_DATA,它由一系列像素组成编码为SOURCE_FORMATSOURCE_TYPE

      我认为stbi_load 从文件中读取 3 通道、每像素 24 字节(GL_RGBGL_BYTE)图像,但您告诉 OpenGL 将源像素图视为 4 通道、每像素 32 字节(@ 987654333@, GL_BYTE) 图片。这是不正确的。

      您应该在指定源像素图格式之前检查c 变量,或者通过将4 分配给它的第4 个参数来请求stbi_load 加载4 色通道图像(该死,这里有很多4) .

      【讨论】:

        【解决方案3】:

        嗯,问题显然出在GL_RGBA 上。我改成GL_RGB,程序不再崩溃;不过,我确实想知道为什么它首先会崩溃。

        【讨论】:

        • 您正在读取具有 3 个通道的图像,但告诉 OpenGL 您的图像数据具有 4 个通道。 4 > 3,因此 OpenGL 将在图像缓冲区的范围之外读取。要使此代码稳健,您应该根据c 的值确定format 参数(您在代码中将其静态设置为GL_RGB(A))。 1→GL_RED(或 GL_LUMINANCE,如果您使用的是 OpenGL-3 之前的版本),2→GL_RG,3→GL_RGB,4→GL_RGBA
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-30
        • 2011-10-16
        • 2015-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多