2012-03-08 93 views
0

我想设置一个简单的函数,这将使我更容易在OpenGL中纹理贴图几何体,但由于某些原因,当我试图制作天空盒时,我得到的是白色方块而不是纹理映射几何。我认为problemed代码位于以下范围内:OpenGL纹理:为什么命令很重要?

void MapTexture (char *File, int TextNum) { 
    if (!TextureImage[TextNum]){ 
     TextureImage[TextNum]=auxDIBImageLoad(File); 
     glGenTextures(1, &texture[TextNum]); 
     glBindTexture(GL_TEXTURE_2D, texture[TextNum]); 
     glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[TextNum]->sizeX, TextureImage[TextNum]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[TextNum]->data); 
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    } 
glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, texture[TextNum]); 
//glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[TextNum]->sizeX, TextureImage[TextNum]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[TextNum]->data); 
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 

} 

最重要的事情,我不明白的是由于某种原因glBindTexture()一定要来glGenTextures()glTexImage2D之间。如果我把它放在其他地方,它将所有东西都拧紧。什么可能导致这个问题?对不起,如果它很简单,我是全新的OpenGL。

下面是我说的白牌的截图: enter image description here

++++++++++++++++++++++++++++ +++ 编辑 +++++++++++++++++++++++++++++++

在代码中多玩一会儿之后,我意识到如果我在最后的glBindTexture()之后添加glTexImage2D()glTexParameteri(),那么所有纹理都会加载。为什么没有这两行代码就会加载大多数纹理,但是还有一些不会,以及为什么我必须为每一帧调用glTexImage(),但仅限于几个纹理?

+1

“auxDIBImageLoad”请不要使用'GLaux'永远。如果你需要加载图片,那么[很多实际上很好的图书馆](http://www.opengl.org/wiki/Image_Libraries)。 – 2012-03-08 16:25:29

+0

我问这个的原因其实主要是因为我在尝试加载纹理时得到这个白色框,我认为这可能与这些函数的排序有关,但似乎并非如此。还有什么可能导致这个白盒出现? – Sean 2012-03-09 03:00:08

+0

我认为这与订单有关,因为如果我要删除'if(!TextureImage [TextNum])',那么纹理将会出现,但考虑到每当该框架被调用时调用MapTexture呈现,没有'if(!TextureImage [TextNum])'内存泄漏像疯狂,直到程序崩溃。 – Sean 2012-03-09 03:09:41

回答

8

是的,订单绝对重要。

  • glGenTexture创建纹理名称。

  • glBindTexture需要glGenTexture生成的纹理名称,所以它不能在glGenTexture之前运行。

  • glTexImage2D将数据上传到当前绑定的纹理,因此无法在glBindTexture之前运行。

OpenGL的客户端接口是Big Giant Squgly状态机。有很多参数和标志可以改变,你必须小心谨慎才能使OpenGL保持正确的状态。这通常意味着您推送的弹出矩阵,并恢复您修改的标志(至少在OpenGL 1.x中)。

4

OpenGL是一个状态机,这意味着你可以拉动它的手柄,旋转它的旋钮,它将保持这些设置,直到你主动改变它们。

但是它也管理对象中的持久数据。 这样的对象是抽象的,不能与屏幕上看到的对象混淆! 现在OpenGL通过其所谓的标识对象名称,一个数字ID。你创建一个(名单)(名单) - 但不是对象(多个)! - glGenTextures用于纹理对象,这是一种OpenGL对象。

为了消除这样的对象,OpenGL必须首先进入一个状态,以下所有调用操作此类对象的调用都发生在一个特定的对象上。这是通过glBindTexture完成的。在调用glBindTexture之后,以下所有调用纹理的调用都发生在您刚刚绑定的那个纹理对象上。如果该对象先前不存在,则在第一次绑定新分配的对象名称时创建该对象。 现在OpenGL使用那个特定的对象。

glTexImage2D只是用于管理当前绑定纹理的数据的几个函数之一。


否则您的功能指向正确的方向。 OpenGL没有真正的初始化阶段,你只是在做事情。延迟加载数据直到你需要它是有意义的。但在实际绘制框架之前,对对象列表进行多次迭代也是有意义的。其中一个准备应该是,你遍历所有的对象(现在不是OpenGL,但你的)来测试数据是否已经加载。如果仍然缺少大量数据,请改为绘制加载屏幕,以免用户获得程序挂起的印象。甚至可能在单独的线程中执行冗长的加载操作,但对于OpenGL,这需要一些预防措施。