0

我在尝试使用 glGetTexLevelParameter 函数获取纹理的宽度和高度时遇到问题。无论我尝试什么,该函数都不会设置宽度或高度变量的值。我检查了错误,但一直没有错误。这是我的代码(如果有帮助,基于 NeHe 教程):

int LoadGLTextures()
{
//load image file directly into opengl as new texture
GLint width = 0;
GLint height = 0;
texture[0] = SOIL_load_OGL_texture("NeHe.bmp", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID,   SOIL_FLAG_INVERT_Y);       //image must be in same place as lib
if(texture[0] == 0)
{
    return false;
}
glEnable(GL_TEXTURE_2D);
glGenTextures(3, &texture[0]);

glBindTexture(GL_TEXTURE_2D, texture[0]);
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  //no filtering bc of GL_NEAREST, looks really bad
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

const GLubyte* test = gluErrorString(glGetError());
cout << test << endl;
return true;
}

如果有帮助,我也在使用 Visual Studio 2010。加载纹理[0] 的调用来自 SOIL 图像库。

4

3 回答 3

2

让我们分解一下:

此调用加载图像,创建新的纹理 ID 并将图像加载到由该 ID 命名的纹理对象中。如果成功,则返回 ID 并将其存储在texture[0].

texture[0] = SOIL_load_OGL_texture(
     "NeHe.bmp",
     SOIL_LOAD_AUTO,
     SOIL_CREATE_NEW_ID,
     SOIL_FLAG_INVERT_Y);

BTW:图像文件与库不在同一目录下,而是在调用此函数时进程的当前工作目录中。如果您没有更改工作目录,那么它就是调用您的进程的任何目录。

检查纹理是否加载成功

if(texture[0] == 0)
{
    return false;
}

在此处启用纹理几乎没有意义。glEnable调用属于渲染代码。

glEnable(GL_TEXTURE_2D);

好的,这里有个问题。glGenTextures 生成新的纹理 ID 并将它们放置在提供给它的数组中。之前存储在该数组中的任何内容都会被覆盖。在您的情况下,由SOIL_load_OGL_texture. 请注意,这只是一些句柄,不会以任何方式收集垃圾。您现在面对一个悬挂在 OpenGL 中的纹理对象并且不再访问它,因为您扔掉了句柄。

glGenTextures(3, &texture[0]);

现在您绑定一个由新创建的 ID 命名的纹理对象。由于这是一个新 ID,因此您实际上是在创建一个没有分配图像数据的新纹理对象。

glBindTexture(GL_TEXTURE_2D, texture[0]);

以下所有调用都在与 SOIL 创建的完全不同的纹理上运行。

如何修复代码:删除glGenTextures. 在您的情况下,它不仅是多余的,而且是您的问题的原因。

于 2012-05-26T20:21:20.073 回答
1

这一行:

texture[0] = SOIL_load_OGL_texture("NeHe.bmp", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID,   SOIL_FLAG_INVERT_Y);

创建一个纹理,将 OpenGL 纹理存储在texture[0].

这一行:

glGenTextures(3, &texture[0]);

创建三个纹理,将它们存储在texture数组中,覆盖那里的任何内容。

看到问题了吗?您从 SOIL 获得纹理,然后立即通过用新创建的纹理覆盖它来丢弃它。

这在概念上与以下内容没有什么不同:

int *pInt = new int(5);
pInt = new int(10);
于 2012-05-26T19:55:15.260 回答
0

嗯,glGenTextures(howmany,where) 不像 glGenBuffers 那样工作吗?为什么要将三个纹理分配给一个指针,它是如何工作的?

我认为应该是

int textures[3];
glGenTextures(3,textures);

这样,三个生成的纹理缓冲区将被放置在纹理数组中。或者

int tex1, tex2, tex3;
glGenTextures(1,&tex1);
glGenTextures(1,&tex2);
glGenTextures(1,&tex3);

所以你有三个单独的纹理缓冲区指针

于 2012-05-26T17:47:44.257 回答