Hello, fellow Linux OpenGL coders.
All of a sudden my texture loading code stopped working on my primary workstation, an amd64 system running debian testing (‘etch’) in i386 mode. I’m using Nvidias lastest driver, built as a custom driver package. GLU package seems to be libglu1-xorg (at least that is what is installed).
The code itself has worked without a hitch for a long time (I didn’t even touch it when it broke). It runs fine on my laptop (Thinkpad X41 running Ubuntu Breezy). Other OpenGL applications seems to be running fine, including Blender 3D and Enemy Territory.
Here is the error output:
TextureManager: Request for "../data/ui/background.tga".
TextureManager: Loading new texture from disk.
An TGA image was loaded successfully.
compression: 0, width: 512 height: 512
bpp: 24
size: 786432 bytes, bytesPerPixel: 3
numChannels: 3
New texture ID is: 3214180648.
Building mipmaps.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1222743808 (LWP 13277)]
0xb7bfff16 in strtof_l () from /lib/tls/libc.so.6
(gdb) bt
#0 0xb7bfff16 in strtof_l () from /lib/tls/libc.so.6
#1 0xb7bfd1e8 in __strtod_internal () from /lib/tls/libc.so.6
#2 0xb7ebd6ad in __gluTessErrorString () from /usr/X11R6/lib/libGLU.so.1
#3 0x00000000 in ?? ()
(gdb)
And here is the code itself:
bool GLTexture::load (const Image &img, const TextureParameters &prm)
{
GLuint newid;
glGenTextures(1, &newid);
if (newid == 0) return false;
printf("New texture ID is: %u.
", newid);
glBindTexture(GL_TEXTURE_2D, newid);
GLuint err = glGetError();
if (glGetError() != GL_NO_ERROR)
System::warning("GLTexture: An OpenGL error has been detected.(1)");
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, prm.getGLMinFilter());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, prm.getGLMagFilter());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, prm.getGLWrapS());
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, prm.getGLWrapT());
err = glGetError();
if (err != GL_NO_ERROR)
System::warning("GLTexture: An OpenGL error has been detected.(2): %d", err);
GLenum format = 0;
if (img.getFormat() == Image::RGB) {
format = GL_RGB;
} else {
format = GL_RGBA;
}
glTexImage2D(GL_TEXTURE_2D, 0, format, img.getWidth(), img.getHeight(), 0, format, GL_UNSIGNED_BYTE, img.getData());
err = glGetError();
if (err != GL_NO_ERROR)
System::warning("GLTexture: An OpenGL error has been detected.(3): %d", err);
if (prm.isMipMapped()) {
printf("Building mipmaps.
");
if (gluBuild2DMipmaps(GL_TEXTURE_2D, format, img.getWidth(), img.getHeight(), format, GL_UNSIGNED_BYTE, img.getData()) != 0) {
System::warning("GLTexture: Mipmap creation failed.");
}
}
if (glGetError() != GL_NO_ERROR)
System::warning("GLTexture: An OpenGL error has been detected.(4)");
// We only load the id when everything has worked out ok.
// This way we can give a 'Strong Guarantee'.
id = newid;
return true;
}
Some oddities I’ve noticed include the large OpenGL texture ID, which is also completely random on each iteration. The ID’s usually started on 1 and went on upwards. This MIGHT be a new implementation that assigns the ID’s in a non-linear manner, I suspect.
I also found some people having similar difficulties (also debian):
Armagetron forums discussion
Any help resolving this issue would be greatly appreciated, I’m starting to miss my good, old Slackware again…
Addendum: The problem persists despite an upgrade to the unstable version of debian (still exactly the same package for libglu1-xorg). Full recompile/rebuild performed to no avail.
Second addendum: It would seem the problem is with glGenTextures(). I modified the code to always initialize the variable newid to zero (good practice). And voila, glGenTextures() does not modify it at all…