Hello everyone,
My main program is a VBO based fixed function OpenGL application.
When I use glCompressedTexImage2D, everything works perfectly.
However, I was working on a tool which uses immediate mode and the texture loader uses identical code, including the glCompressedTexImage2D.
-And this code segfaults when it runs the glCompressedTexImage2D line.
I am totally stumped. There is no difference except one is using VBO/FBO and this one is a fairly plain immediate mode program.
To help you, help me, I have provided a complete code example. This code sample crashes for me and I don’t know why.
To compile you will need:
[ul]
[li]GLI headers for the compressed texture loader from g-truc. [/li][li]GLFW 2.7~ for windowing. [/li][/ul]
In Mac:
usr/bin/g++ crash.cpp -o crash -lglfw -framework Cocoa -framework OpenGL -L/usr/lib/libglfw.a -lGLU -lGL -lGLEW -pthread -lboost_thread -lm -L/usr/local/lib -L/usr/lib/ -I/usr/include -g
In Linux:
/usr/bin/g++ crash.cpp -o crash -lglfw -lGL -lX11 -L/usr/lib/libglfw.a -lGLU -lGL -lGLEW -pthread -lboost_thread -lm -L/usr/local/lib -L/usr/lib/ -g
// Example where glCompressedTexImage2D causes a segfault.
#include <iostream>
#include <string>
#include <GL/glew.h>
#include <GL/glfw.h>
#include <gli/gli.hpp>
#include <gli/gtx/loader.hpp>
using namespace std;
int xres = 0;
int yres = 0;
GLuint ta = 0;
void refresh()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio = 1.0 * xres / yres;
gluPerspective(45,ratio,0.1,4000);
gluLookAt( 0, 0, -5, // camera location
0.0, 0.0, 0.0, // looking at
1.0, -1.0, 0.0 );
glMatrixMode(GL_MODELVIEW);
glViewport( 0, 0, xres, yres );
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glClearDepth( 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, ta);
glBegin(GL_QUADS);
glColor3f ( 0.0, 1.0, 0.0 );
glVertex3f( 0, 0, 0 ); glTexCoord2f( 0, 0 );
glVertex3f( 2, 0, 0 ); glTexCoord2f( 1, 0 );
glVertex3f( 2, 2, 0 ); glTexCoord2f( 1, 1 );
glVertex3f( 0, 2, 0 ); glTexCoord2f( 0, 1 );
glEnd();
glfwSwapBuffers();
}
void window ( string name, int xsize, int ysize )
{
xres = xsize;
yres = ysize;
glfwInit();
glfwOpenWindowHint( GLFW_WINDOW_NO_RESIZE, 1 );
int ok = glfwOpenWindow(
xres, yres, // Width and height of window
8, 8, 8, // Number of red, green, and blue bits for color buffer
8, // Number of bits for alpha buffer
24, // Number of bits for depth buffer (Z-buffer)
0, // Number of bits for stencil buffer
GLFW_WINDOW // We want a desktop window (could be GLFW_FULLSCREEN)
);
glfwSwapInterval( 1 );
glfwSetWindowTitle( name.c_str() );
glClearColor( 1.0f, 1.0f, 1.0f, 1.0f );
glClearDepth( 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
glDisable(GL_DITHER);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);
glClear(GL_ACCUM_BUFFER_BIT);
glEnable(GL_LINE_SMOOTH); // Enable Antialiased lines
glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void loadtexture ( string filename )
{
glGenTextures(1, &ta);
glBindTexture(GL_TEXTURE_2D, ta);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
cout<<"loading filename: "<<filename<<"
";
gli::texture2D T = gli::load(filename);
cout<<"image dimensions = "<<T[0].dimensions().x<<" "<<T[0].dimensions().y<<"
";
// glCompressedTexImage2D crashes for some reason..
cout<<"about to submit compressed texture
";
glCompressedTexImage2D( GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GLsizei(T[0].dimensions().x), GLsizei(T[0].dimensions().y), 0, GLsizei(T[0].capacity()), T[0].data());
cout<<"Submitted ok.
";
glEnable(GL_TEXTURE_2D);
}
int main ( )
{
window ( "crash example", 1024, 768 );
loadtexture ( "image.dds" );
refresh();
sleep (5);
cout<<"This did not crash.
";
glDeleteTextures( 1, &ta );
glfwTerminate();
exit( EXIT_SUCCESS );
}