使用 DevIL 在 C++ OpenGL 中加载纹理

Posted

技术标签:

【中文标题】使用 DevIL 在 C++ OpenGL 中加载纹理【英文标题】:loading textures in C++ OpenGL using DevIL 【发布时间】:2012-05-22 17:45:50 【问题描述】:

使用 C++,我正在尝试使用 DevIL 将纹理加载到 OpenGL 中。在四处寻找不同的代码段后,我完成了一些代码(如下所示),但它似乎并不完全有效。

加载纹理(Texture2D 类的一部分):

void Texture2D::LoadTexture(const char *file_name) 
   
    unsigned int image_ID;

    ilInit();
    iluInit();
    ilutInit();

    ilutRenderer(ILUT_OPENGL);

    image_ID = ilutGLLoadImage((char*)file_name);

    sheet.texture_ID = image_ID;
    sheet.width = ilGetInteger(IL_IMAGE_WIDTH);
    sheet.height = ilGetInteger(IL_IMAGE_HEIGHT);

这可以编译并正常工作。我确实意识到我应该只执行一次 ilInit()、iluInit() 和 ilutInit(),但如果我删除这些行,程序会在加载任何图像时立即中断(编译正常,但运行时出错)。

在OpenGL中显示纹理(同一类的一部分):

void Texture2D::Draw() 


    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glPushMatrix();

    u = v = 0;

    // this is the origin point (the position of the button)
    VectorXYZ point_TL; // Top Left 

    VectorXYZ point_BL; // Bottom Left
    VectorXYZ point_BR; // Bottom Right
    VectorXYZ point_TR; // Top Right

    /* For the sake of simplicity, I've removed the code calculating the 4 points of the Quad. Assume that they are found correctly. */

    glColor3f(1,1,1);
    // bind the appropriate texture frame
    glBindTexture(GL_TEXTURE_2D, sheet.texture_ID);

    // draw the image as a quad the size of the first loaded image
        glEnable(GL_TEXTURE_2D);
        glBegin(GL_QUADS);
            glTexCoord2f (0, 0);
            glVertex3f  (point_TL.x, point_TL.y, point_TL.z); // Top Left

            glTexCoord2f (0, 1);
            glVertex3f  (point_BL.x, point_BL.y, point_BL.z); // Bottom Left

            glTexCoord2f (1, 1); 
            glVertex3f  (point_BR.x, point_BR.y, point_BR.z); // Bottom Right

            glTexCoord2f (1, 0);
            glVertex3f  (point_TR.x, point_TR.y, point_TR.z); // Top Right
        glEnd();
        glPopMatrix();
    glDisable(GL_BLEND);
    glDisable(GL_TEXTURE_2D);

目前,四边形显示出来了,但它完全是白色的(给定的背景颜色)。我正在加载的图像存在并且加载正常(使用加载的大小值验证)。

我应该注意的另外几件事: 1)我正在使用深度缓冲区。我听说这不适合 GL_BLEND? 2) 我真的很想使用 ilutGLLoadImage 函数。 3) 我很欣赏示例代码,因为我是 openGL 和 DevIL 整体的新手。

【问题讨论】:

您确定在加载纹理时存在有效的 OpenGL 上下文吗? glGetError() 在您的ilutGLLoadImage() 呼叫返回后会发生什么? @datenwolf:我很确定,但不完全确定。如果您能指导我如何确保存在有效的 OpenGL 上下文,我很乐意检查。 @genpfault:我不确定如何从 glGetError() 获取输出,所以我使用 if 语句检查 glGetError() == GL_NO_ERROR。它 - 不 - 在 ilutGLLoadImage() 语句的任一侧输入 if。 所以您在ilutGLLoadImage() 之前遇到了某种错误。哪一个?我打赌GL_INVALID_OPERATION 【参考方案1】:

是的,你有问题。 ilutGLLoadImage() 可能存在问题。

尝试手动操作:

    使用 ilLoadImage 加载图像 使用 glGenTextures 生成 OpenGL 纹理句柄 将图像上传到 OpenGL glTextImage2D 和 ilGetData()

查看此链接以获得有效的解决方案

http://r3dux.org/tag/ilutglloadimage/

我知道,这个解决方案似乎“有点”复杂,但是没有人知道你会花多少时间来解决这个隐藏在 DevIL 深处的错误。

另一种解决方法:检查 GL 纹理设置代码。过滤中的任何内容都可能是 GL_INVALID_OPERATION 的原因。

在对旧 ATI 卡进行编程时,我们经常遇到“白色纹理”问题。

哦!最大的猜测:非二次幂纹理。你的纹理文件是 2^N x 2^N 还是其他的?

要使用非矩形纹理,您只需使用 GL 扩展。

还有一个:你是在同一个线程中还是在另一个线程中使用纹理?请记住,您应该在同一个线程中使用 glGenTextures() 和 glBindTexture()/glBegin/glEnd。

【讨论】:

好的。编辑了我的函数,以与教程(链接)相同的方式进行。我似乎在 -exact-line ilLoadImage() 处遇到了访问冲突错误(请参阅提供的粘贴中的第 22 行)。我很难过:/。由于代码很长,我把它放在了 paste-bin 上:pastebin.com/TK4yGwHc 好吧,检查 ilBindImage 和 ilGenImages 调用的错误代码 我在两个语句之前和之后都运行了 ilGetError() 调用;他们都返回 IL_NO_ERROR。

以上是关于使用 DevIL 在 C++ OpenGL 中加载纹理的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 中的错误 C2664 和 C2597 以及 C++ 中的 DevIL

在 C++ 中加载 .model 文件

如何在 OpenGL 中加载和渲染可能包含三角形、四边形或 N-Gons 的 OBJ 文件?

OpenGL - 在一个函数中加载多个纹理

在 openGL 纹理中加载图像(使用它们的 RGB(A) 像素数据)

OpenGL-在一个函数中加载多重纹理