在某些 Windows 系统上使用 OpenGL 和 DevIL 的白色纹理

Posted

技术标签:

【中文标题】在某些 Windows 系统上使用 OpenGL 和 DevIL 的白色纹理【英文标题】:White textures with OpenGL and DevIL on some Windows systems 【发布时间】:2010-12-21 00:10:00 【问题描述】:

我在尝试使用 DevIL 加载图像并在 OpenGL 中创建纹理时遇到了一些问题。当我的一个朋友在他的 Windows 上测试我的程序时,所有应该包含纹理的矩形都是白色的,没有任何图像(纹理)。这个问题似乎只出现在 Window XP、Windows Vista 和 Windows 7 上,而不是在每台 Windows PC 上:我的 Windows XP 运行程序没有问题。

可能是缺少一些 DLL 或文件(不太可能),或者某些东西不能让图像被加载或用作纹理。另一方面,该程序在 *UNIX 系统上运行良好。

这是我用来加载图像并生成纹理的代码:

void Image::load(const char* filename)

    ILuint ilimg;

    ilGenImages(1, &ilimg);
    ilBindImage(ilimg);

    if (!ilLoadImage(filename))
        throw ImageLoadError;

    glGenTextures(1, &image);
    glBindTexture(GL_TEXTURE_2D, image);

    bpp = ilGetInteger(IL_IMAGE_BPP);
    width = ilGetInteger(IL_IMAGE_WIDTH);
    height = ilGetInteger(IL_IMAGE_HEIGHT);
    format = ilGetInteger(IL_IMAGE_FORMAT);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, bpp, width, height, 0, format,
        GL_UNSIGNED_BYTE, ilGetData());

    ilDeleteImages(1, &ilimg);

这是使用纹理绘制矩形的代码:

void Rect::show()

    glPushAttrib(GL_CURRENT_BIT);

    glEnable(GL_TEXTURE_2D);
    glColor4f(1.0, 1.0, 1.0, opacity);
    glBindTexture(GL_TEXTURE_2D, texture->get_image());

    glBegin(GL_POLYGON);
        glTexCoord2i(0, 0); glVertex2f(x, y);
        glTexCoord2i(1, 0); glVertex2f(x+width, y);
        glTexCoord2i(1, 1); glVertex2f(x+width, y+height);
        glTexCoord2i(0, 1); glVertex2f(x, y+height);
    glEnd();

    glDisable(GL_TEXTURE_2D);

    glPopAttrib();

如果您需要我未提及的其他代码,请询问我,我会发布。

【问题讨论】:

我猜,路径有问题 - 尝试打印 getcwd 并检查是否真的存在图像。 如果缺少 DLL,则会出现运行时错误,并且它会抱怨找不到“ATIOGLX.dll”或类似的东西,具体取决于您的视频卡和驱动程序。 windows系统自带的默认opengl驱动只是一个封装了GDI的软件驱动。此驱动程序不支持很多功能,因此如果无法正确加载它们,经常会生成白色纹理。您确定这些系统安装了第 3 方视频驱动程序(这是安装卡的硬件 OpenGL 驱动程序的唯一方法) 嗯,我不确定。我去看看,谢谢解答。 【参考方案1】:
glTexImage2D(target, level, internal format, width, height, border, format, type, data);

glTexImage 的内部格式 参数不是每像素位数。实际上它的数值与格式完全无关。 OpenGL只定义了特定的值是有效的,其中也有四个数字关系,但只是作为助记符:1(GL_LUMINANCE的简写)、2(GL_LUMINANCE_ALPHA)、3(GL_RGB)、4(GL_RGBA)。还有许多其他格式标记,但它们的数值是任意选择的。

图像数据的 bpp 也用于查找 formattype 参数。您需要为此实现 LUT 或 switch-case 结构。

【讨论】:

【参考方案2】:

您遇到的问题听起来像是实施版本问题。可能一个“正确”但不太“好”的实现不会让你摆脱一些不正确的事情。或者另一方面,实现可能有一个微妙的错误并且不接受您的有效代码。

我可能会尝试交换

glColor4f(1.0, 1.0, 1.0, opacity);
glBindTexture(GL_TEXTURE_2D, texture->get_image());

glBindTexture(GL_TEXTURE_2D, texture->get_image());
glColor4f(1.0, 1.0, 1.0, opacity);

并在 texcoord 之前声明顶点。

glVertex2f(x, y);
glTexCoord2i(0, 0);

如果您还没有“红皮书”,请咨询http://glprogramming.com/red/chapter09.html

【讨论】:

这些建议都没有用或正确。 glVertex 函数总是在设置所有其他属性之后出现。 glColor 根本不与纹理绑定交互 - 从 glColor 可以在每个顶点调用并且在评估纹理环境时在管道中影响纹理很远的事实中应该很明显。是的,某些实现存在问题,例如 ATI/AMD 的实现,但不是这样的。

以上是关于在某些 Windows 系统上使用 OpenGL 和 DevIL 的白色纹理的主要内容,如果未能解决你的问题,请参考以下文章

Qt+Windows,Windows 底层默认使用d3d还是opengl?

生锈的Win32 OpenGL窗口:无法加载某些函数指针

关于 Windows 上 OpenGL 中的多重缓冲的几个问题

在某些平台上损坏的 OpenGL 渲染

如何在 Windows 7 中使用 OpenGL、Glut 和 Visual Studio 2008 准备 C++ 项目

SDL+OpenGL 程序没有出现在 linux 上