【问题标题】:OpenGL mipmap issuesOpenGL mipmap 问题
【发布时间】:2011-12-01 21:39:43
【问题描述】:

我的 mipmapping 工作正常。但是由于某种原因,在我应用纹理之后,我的应用程序中的所有其他对象都呈现出似乎是纹理的平均颜色。甚至是HUD。有什么我需要解释的吗?代码如下:

GLuint LoadTexture( const char * filename, int width, int height )
{
    GLuint texture;
    unsigned char * data;
    FILE * file;

    file = fopen( filename, "rb" );
    if ( file == NULL ) return 0;
    data = (unsigned char *)malloc( width * height * 3 );
    fread( data, width * height * 3, 1, file );
    fclose( file );

    glGenTextures( 1, &texture );
    glBindTexture( GL_TEXTURE_2D, texture );
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR );

    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

    gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height, GL_RGB, GL_UNSIGNED_BYTE, data ); 
    free( data );
    return texture;
}

在循环之前调用它并释放后记。下一部分代码发生在我的 while 循环中。它在场景中的所有其他对象之前调用。

void makeGround() {

    glBindTexture( GL_TEXTURE_2D, texture );

    GLfloat mat_specular[]      = { 0.5, 0.5, 0.5, 1.0 };
    GLfloat mat_diffuse[]       = { 0.8, 0.8, 0.8, 1.0 };
    GLfloat mat_shininess[]     = { 100.0 };

    glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);

    //glColor3f(1.0, 1.0, 1.0);

    glPushMatrix();
        glTranslatef(-(size/2), 0.0f, -(size/2));
        glCallList(LIST1);
    glPopMatrix();
}

在绘制不同的元素之间我应该怎么做才能避免这种情况发生?

【问题讨论】:

  • 两个cmets:1)语言标签不应该是c吗?这段代码中没有多少 c++。 2)我真的希望固定的管道和从opengl中删除的所有其他东西现在都已经死了并被掩埋了。至少我不会再指望这些东西在更新的硬件和驱动程序上得到非常优化了。
  • 您不能将LINEAR_MIPMAP_LINEARTEXTURE_MAG_FILTER 一起使用。无论如何,这没有任何意义。 TEXTURE_MAG_FILTER 用于放大:使纹理比基础层(mipmap 链中最大的层)更大。不能使用大于基础层的 mipmap,因此不能使用TEXTURE_MAG_FILTER 在 mipmap 之间进行过滤。这可能不是你的问题,但无论如何你都应该知道。
  • @Grizzly:“死了?”你在开玩笑吗?使用 OpenGL 的人这样做只是因为 1)他们正在从在线资源中学习,这几乎可以肯定不是基于着色器的,2)他们使用的是旧的基于 OpenGL 的代码库,它也不是基于着色器的, 或 3) 他们正在进行跨平台开发。既然这么多 GL 学习资源是固定功能的,那么它的跨平台用户也是如此。
  • @Nicol Bolas:哈,实际上都是三个。在 GLSL 上找不到任何好的资源。但我真正的目标是实现粗劣的平台兼容性。
  • @Nicol Bolas:在我看来,您的第一点是导致使用 opengl 已弃用部分的最常见情况,这就是为什么我想至少提到这些部分有点过时的原因我谈论的是opengl(希望有人学习它将切换到更现代的功能)。根据我的经验,在尝试更复杂的事情时使用固定管道学习它通常会导致问题,在这种情况下使用着色器会更容易。头晕:真的吗?我会认为那些存在。不幸的是,我从一些德国方面学习,所以我无法提供英文资源。

标签: c++ opengl texture-mapping mipmaps


【解决方案1】:

我猜你应该在完成渲染应该纹理化的部分后取消绑定纹理或禁用纹理化。当您尝试渲染无纹理的对象时,它们仍然会获得纹理,但由于缺少纹理坐标,它们都使用相同的 texcoord,因此只会从纹理中获得一种颜色。

【讨论】:

  • 如果我绘制地面,然后在绘制其他任何内容之前禁用 2d 纹理,它只会阻止地板被纹理化。
  • 所以如果你在绘制地面之后禁用纹理(并在下次绘制地面之前重新启用它,地面就没有纹理了?这看起来有点奇怪,请注意多说一下你到底在做什么(显示您在哪里启用/禁用纹理等)
  • 啊,你知道吗,在某些时候我注释掉了重新启用。谢谢!这解决了我的问题。
  • 我猜到了类似的事情(这就是我特意提到它的原因)。所以你很受欢迎。如果您使用 C++ 编写,我建议为此利用 RAII,因此编写一个在构造函数上启用它并在析构函数上禁用它的类(我知道的人为示例,实际上可能更灵活一些)。
  • 在我的循环开始时,我调用了一个重置​​函数,它清除颜色和深度缓冲区、加载标识等。所以我添加了纹理启用,并在结束时禁用它绘制地板的函数。最终我希望做一些更健壮的东西,比如可以为我处理它的显示列表类。感谢您的建议!
猜你喜欢
  • 2011-06-30
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 2022-11-04
  • 2011-12-25
  • 2011-01-17
  • 1970-01-01
相关资源
最近更新 更多