在OpenGL中,纹理呈白色显示。

4
我无法加载BMP纹理并将其显示在立方体的面上。我正在Windows 7上工作,我的编译器是Visual Studio 2010 Express。我使用FreeImage来加载bmp,我的图像位深度为24,大小为256 * 256。我使用SDL创建窗口和处理事件。当我编译和运行程序时,我的立方体仍然是白色的,它的面上没有显示任何东西。我将纹理加载到GLuint变量中,当我打印该变量时,它只会打印“1”。我的朋友告诉我,我的显卡与此版本的OpenGL不兼容。因此,我在虚拟机上的Ubuntu上编译和运行了该程序,并且它可以成功纹理化立方体。你能帮我正确地在Windows上运行它吗?如果需要,我的显卡是NVIDIA GT240 DDR5。
编辑:
这是我的initgl函数:
//OpenGL initialization.
int initGL(void)
{
    glEnable(GL_TEXTURE_2D); //Enable texture mapping.
    if(!loadGLTextures("bmp_24.bmp"))
        return false;

    glShadeModel(GL_SMOOTH);
    glClearColor(0.0f , 0.0f , 0.0f , 0.5f);
    glClearDepth(1.0f);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    //Nice perspective.
    glHint(GL_PERSPECTIVE_CORRECTION_HINT , GL_NICEST);
    return true;
}

这是加载图像的函数。在此之前已经定义了一个GLuint texture [1]:

//This function will load a bitmap image.
bool loadGLTextures(const char* file)
{
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;

    fif = FreeImage_GetFileType(file , 0);
    if(fif == FIF_UNKNOWN)
        fif = FreeImage_GetFIFFromFilename(file);
    if(fif == FIF_UNKNOWN)
        return false;

    FIBITMAP* dib = FreeImage_Load(fif , file);

    if(!dib)
        return false;
    
    //Create the texture.
    glGenTextures(1 , &texture[0]);

    //Typical texture generation using data from the bitmap.
    glBindTexture(GL_TEXTURE_2D , texture[0]);

    //Generate the texture.
    glTexImage2D(GL_TEXTURE_2D , 0 , GL_RGB , FreeImage_GetWidth(dib) , 
        FreeImage_GetHeight(dib) , 0 , GL_BGR_EXT , GL_UNSIGNED_BYTE , 
        FreeImage_GetBits(dib));



    //Linear filtering.
    glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MIN_FILTER , GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D , GL_TEXTURE_MAG_FILTER , GL_LINEAR);

    printf("%d" , texture[0]);

    FreeImage_Unload(dib);

    return true;

}

这是我的渲染函数:

//All of the drawing goes through this.
int drawGLScene(void)
{
    static float xrot = 0 , yrot = 0 , zrot = 0;
    //Clear screen and depth buffer.
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    glTranslatef(0.0f , 0.0f , -5.0f);
    glRotatef(xrot , 1.0f , 0.0f , 0.0f);
    glRotatef(yrot , 0.0f , 1.0f , 0.0f);
    glRotatef(zrot , 0.0f , 0.0f  ,1.0f);

    //Select the texture.
    glBindTexture(GL_TEXTURE_2D , texture[0]);

    glBegin(GL_QUADS);
    //Front:
    //Bottom left of the texture and quad.
    glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
    //Bottom right fo the texture and quad.
    glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , 1.0f);
    //Top right of the texture and quad.
    glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
    //Top left of the texture and quad.
    glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , 1.0f);

    //Back:
    //Bottom left of the texture and quad.
    glTexCoord2f(0.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
    //Bottom right of the texture and quad.
    glTexCoord2f(1.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
    //Top right of the texture and the quad.
    glTexCoord2f(1.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
    //Top left of the texture and the quad.
    glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);

    //Top:
    //Top right of the texture and quad.
    glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
    //Top left of the texture and quad.
    glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
    //Bottom left of the texture and quad.
    glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
    //Bottom right of the texture and quad.
    glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);

    //Bottom:
    //Top left of the texture and quad.
    glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
    //Bottom left of the texture and quad.
    glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
    //Bottom right of the texture and quad.
    glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
    //Top right of the texture and quad.
    glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , -1.0f , 1.0f);

    //Right:
    //Bottom right of the texture and quad.
    glTexCoord2f(1.0f , 0.0f); glVertex3f(1.0f , -1.0f , -1.0f);
    //Top right of the texture and quad.
    glTexCoord2f(1.0f , 1.0f); glVertex3f(1.0f , 1.0f , -1.0f);
    //Top left of the texture and quad.
    glTexCoord2f(0.0f , 1.0f); glVertex3f(1.0f , 1.0f , 1.0f);
    //Bottom left of the texture and quad.
    glTexCoord2f(0.0f , 0.0f); glVertex3f(1.0f , -1.0f , 1.0f);

    //Left:
    //Bottom left of the texture and quad.
    glTexCoord2f(0.0f , 0.0f); glVertex3f(-1.0f , -1.0f , -1.0f);
    //Bottom right of the texture and quad.
    glTexCoord2f(1.0f , 0.0f); glVertex3f(-1.0f , -1.0f , 1.0f);
    //Top right of the texture and quad.
    glTexCoord2f(1.0f , 1.0f); glVertex3f(-1.0f , 1.0f , 1.0f);
    //Top left of the texture and quad.
    glTexCoord2f(0.0f , 1.0f); glVertex3f(-1.0f , 1.0f , -1.0f);
    glEnd();

    SDL_GL_SwapBuffers();

    xrot += 0.1;
    yrot += 0.1;
    zrot += 0.1;

    return true;

}

尝试打印图像本身的内容,也许 freeimage 读取文件时遇到了问题? - Shahbaz
另外,你使用了哪些光照和材质属性? - Shahbaz
texture[0] 的值是多少?是 0 吗? - UltraInstinct
你能否也发布一下你的渲染函数?如果我的答案不起作用,问题可能就在那里。 - Tom Knapen
3个回答

6

您的代码可能会出现许多问题。

我怀疑您过早地调用了initGL(),即在没有可用上下文的情况下进行调用。由于您没有展示相关代码,因此我只能猜测。

启用纹理单元仅用于绘制。您可以在纹理单元被禁用的情况下上传纹理数据。我强烈建议您将glEnable(GL_TEXTURE_2D);放置到四边形绘制代码之前,而不是其他任何位置(实际上,您应该只在绘制代码中使用glEnable和glDisable调用,有几个原因)。

在加载纹理时,您未能执行几个合理性检查。此外,您忘记正确设置像素存储参数,但这会使您的纹理看起来扭曲。另外,最好从加载函数返回纹理ID,而不是布尔值,并将ID放入全局变量中。纹理ID 0 已保留,因此您可以将其用于指示错误。

您已经设置了滤波模式,因此这并不是未定义mipmap级别的问题。


+1 因为你是对的。我自己刚开始在学校项目中使用OpenGL,我认为我在某个帖子中看到了一些必要的调用,所以我(像我这样天真)只是把它当作真实的事情。 - Tom Knapen
将glEnable移动到渲染四边形之前,会有一些东西出现。我没有白色,但我可以看到一些东西,所以这是朝着正确方向迈出的一步。 - Andrew WC Brown

0

你的纹理尺寸可能不是2的幂,即1、2、4、8、16、32、64等。

这也可能会在某些硬件上引起问题,通常是旧的硬件。

干杯 ;)


我的纹理尺寸不是2的幂次方。所以我会尽快检查问题是否来自于此,并告诉你结果。 - arman_aegit

0

GL_TEXTURES_2D需要在创建纹理之前启用,因此您需要在调用glGenTextures(1 , &texture[0]);之前调用glEnable(GL_TEXTURE_2D);

此外,要启用透明度,您需要调用`glEnable(GL_BLEND);`。

但这仍然无法解释为什么它在Ubuntu上运行正常而在Windows上不行...我建议尝试一下,看看是否有所帮助。

编辑: 现在您已经发布了渲染函数,我注意到您没有设置您的渲染颜色。 尝试调用

glColor4f(r,g,b,a); // r, g, b and a are float between [0,1], specifying your desired color

glLoadIdentity(); 和你的第一个 glVertex3f 调用之间的某个地方


我在initgl函数中启用了GL_TEXTURES_2D - arman_aegit
就像我之前说的,你需要在生成纹理之前启用它,现在你是在之后才启用的。 - Tom Knapen
我把它放在loadGLTextures之前,但结果仍然一样。 - arman_aegit
我已经发布了我的渲染函数。 - arman_aegit
我调用了glColor4f(1, 1, 1, 1),但没有任何反应。这与纹理有关吗? - arman_aegit
3
不需要启用GL_TEXTURE_2D来创建纹理,因此-1。实际上,所有OpenGL的启用/禁用状态都只影响绘制过程,而不会影响其他操作。请注意保持原意,使翻译易于理解,但不要添加解释性内容。 - datenwolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接