glGenTextures stop working if called after SDL_SetVideoMode

Hello !

I’ve a very strange problem: when I use my functions to load textures before SDL_SetVideoMode and the init of the openGl context, it works fine.
But when I do it later it stops working :doh:

Could you give it a look please ?

(It’s the call to LoadMenu which fails, without error, just black screen)


int SetVideoMode() {
	if( NULL == SDL_SetVideoMode(WINDOW_WIDTH, WINDOW_HEIGHT, 32, SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_RESIZABLE ) ) {
		fprintf(stderr, "Can't open an SDL window
");
		return 0;
	}
	return 1;
}

void InitGlContext() {
	glViewport(0,0,WINDOW_WIDTH,WINDOW_HEIGHT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(-1.,1.,-1.,1.);
}

int main( int argc, char* argv[] ) {	
	/* Init of the commands */
	KeyboardState keyboard;
	int i = 0;
	while( i != SDLK_LAST )
		keyboard.keys[i++] = 0;
	
	/* Init of the SDL library */
	if( -1 == SDL_Init(SDL_INIT_VIDEO) ){
		fprintf(stderr, "Can't initialize the SDL library
");
		return EXIT_FAILURE;
	}

	if( !SetVideoMode() )
		return EXIT_FAILURE;
		
	InitGlContext();

	Menu menu = CreateMenu(8);
	if( !LoadMenu(&menu,THEMES_DIRECTORY[0]) )
		return EXIT_FAILURE;
	Game game = CreateGame(2);
	if( !InitGame(&game) )
		return EXIT_FAILURE;
....

and the functions LoadMenu with CreateTexture:


Texture* CreateTexture(char* file) {
	if( NULL == file ) {
		fprintf(stderr,"Gived file path is NULL in CreateTexture
");
	}

	Texture* res = (Texture*)malloc(sizeof(Texture));
	if( NULL == res) {
		fprintf(stderr,"Can't create new texture
");
		return NULL;
	}

	res->surface = IMG_Load(file);
	if( NULL == res->surface ) {
		fprintf(stderr,"Can't load the image %s
",file);
		free(res);
		return NULL;
	}

	glGenTextures(GL_TEXTURE_2D,&(res->id));
	if( glGetError() != GL_NO_ERROR ) {
		fprintf(stderr,"Can't gen the texture id
");
		free(res);
		SDL_FreeSurface(res->surface);
		return NULL;
	}

	return res;
}

int LoadMenu(Menu* menu,char* directorypath) {
	DIR* directory;
	struct dirent* file;
	char full_path[strlen(directorypath) + 255];

	/* Getting of the menu images *************************************/
	if(NULL == (directory = opendir(directorypath)) ) {
		fprintf(stderr,"The theme %s can't be loaded
", directorypath);
		return 0;	
	}
	
	int index = 0;
	while( NULL != (file = readdir(directory)) ) {
		strcpy(full_path,directorypath);
		strcat(full_path,"/");
		strcat(full_path,file->d_name);
		
		if( 0 == strcmp(file->d_name,"arkanopong.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,1),PointXY(0.25,1),PointXY(0.25,0.8),PointXY(-0.25,0.8)),
				CreateTexture(full_path),
				-1);
			index++;
		}
		else if( 0 == strcmp(file->d_name,"1player.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,0.8),PointXY(0.25,0.8),PointXY(0.25,0.6),PointXY(-0.25,0.6)),
				CreateTexture(full_path),
				0.8);
			index++;
		}
		else if( 0 == strcmp(file->d_name,"2players.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,0.6),PointXY(0.25,0.6),PointXY(0.25,0.4),PointXY(-0.25,0.4)),
				CreateTexture(full_path),
				2);
			index++;
		}
		else if( 0 == strcmp(file->d_name,"3players.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,0.4),PointXY(0.25,0.4),PointXY(0.25,0.2),PointXY(-0.25,0.2)),
				CreateTexture(full_path),
				3);
			index++;
		}
		else if( 0 == strcmp(file->d_name,"4players.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,0.2),PointXY(0.25,0.2),PointXY(0.25,0),PointXY(-0.25,0)),
				CreateTexture(full_path),
				4);
			index++;
		}
		else if( 0 == strcmp(file->d_name,"5players.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,0),PointXY(0.25,0),PointXY(0.25,-0.2),PointXY(-0.25,-0.2)),
				CreateTexture(full_path),
				5);
			index++;
		}
		else if( 0 == strcmp(file->d_name,"6players.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,-0.2),PointXY(0.25,-0.2),PointXY(0.25,-0.4),PointXY(-0.25,-0.4)),
				CreateTexture(full_path),
				6);
			index++;
		}
		else if( 0 == strcmp(file->d_name,"switchtheme.png") ) {
			menu->items[index] = CreateMenuItem(
				CreateBox(PointXY(-0.25,-0.4),PointXY(0.25,-0.4),PointXY(0.25,-0.6),PointXY(-0.25,-0.6)),
				CreateTexture(full_path),
				0);
			index++;
		}
	}
	
	if( index < menu->nb_items ) {
		fprintf(stderr,"Missing menu images, only %d
",index);
		return 0;
	}
	
	closedir(directory);
	
	return 1;
}

Thanks in advance for your help, I’m stuck :tired:

It sounds as though you have a strange system where the laws of causality are inverted.

glGenTextures should never work before creating the context. It should only ever work after doing so.

[QUOTE=mhagain;1238083]It sounds as though you have a strange system where the laws of causality are inverted.

glGenTextures should never work before creating the context. It should only ever work after doing so.[/QUOTE]

I know that, I really can’t see why it doesn’t work…
Is there any way to check I’ve a valid context ? I’m using linux

BTW, I sometime (not always) get this error :


[xcb] Unknown sequence number while appending request
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
arkanopong: ../../src/xcb_io.c:160: append_pending_request: Assertion `!xcb_xlib_unknown_seq_number' failed.
Abandon (core dumped)

Problem resolved, it’s a stupid mistake…

I was calling glGenTextures(GL_TEXTURE_2D,&value).

It seems like GL_TEXTURE_2D had a fine value until the SDL_SetVideoMode…:doh:

glGenTextures(GL_TEXTURE_2D,&value)

is flat-out wrong to begin with. The first param is the number of texture names to be generated, not a texture mode: http://www.opengl.org/sdk/docs/man/xhtml/glGenTextures.xml

It seems like GL_TEXTURE_2D had a fine value until the SDL_SetVideoMode

I don’t understand how this could even happen. GL_TEXTURE_2D is a #defined compile-time constant from the OpenGL header file and it’s value can’t change unless you #define it to something else in your own code.

Before setting the mode you don’t have an OpenGL context, so glGenTextures should either (1) crash or (2) do nothing silently - it may seem as though it’s “working” but it is most definitely not. After setting the mode you just pass it the correct params as per the documentation and it works (if it doesn’t then you have bigger problems that just glGenTextures not working - this function call is absolutely fundamental since OpenGL 1.1)

[QUOTE=mhagain;1238122]

glGenTextures(GL_TEXTURE_2D,&value)

is flat-out wrong to begin with. The first param is the number of texture names to be generated, not a texture mode: http://www.opengl.org/sdk/docs/man/xhtml/glGenTextures.xml

I don’t understand how this could even happen. GL_TEXTURE_2D is a #defined compile-time constant from the OpenGL header file and it’s value can’t change unless you #define it to something else in your own code.

Before setting the mode you don’t have an OpenGL context, so glGenTextures should either (1) crash or (2) do nothing silently - it may seem as though it’s “working” but it is most definitely not. After setting the mode you just pass it the correct params as per the documentation and it works (if it doesn’t then you have bigger problems that just glGenTextures not working - this function call is absolutely fundamental since OpenGL 1.1)[/QUOTE]

Yup, as I said it was a stupid mistake, I think I was sleepy when I wrote the CreateTexture function ^^’

But, despite the reason, it was strangely perfectly working: I was playing my pong with textures with no problem. And even when the first exectued function of the main was CreateTexture. . .
Notice that only glGenTexture was used then, the setting of the data was made after the init of the context. . .changing the image for each texture drawing (but not anymore now)

That sounds odd.

Possible explanation: old OpenGL allows object names that weren’t generated via a glGen* call. So the values you were using were still working anyway because of being auto-initialized by the compiler, but they were working by accident, not by design. A modern core context would have caught that, but a non-core wouldn’t.