PDA

View Full Version : glTexImage2D seg fault



gib
08-06-2002, 01:08 AM
I have run into a segmentation fault problem with code that is based on the example program glmovie.c that comes with the SMPEG library for playing mpegs. The code uses textures and tiling to display mpeg frames that are not (in general) powers of 2 in size.

My program plays an mpeg OK, but if in the program I close it then try to play it again I get the seg fault. I have isolated the problem to the first glTexImage2D() call when the textures are being created for the second time (I delete them when the mpeg is closed).

A simple test program shows that the error occurs even when no drawing is done with the textures. In the drawing function it is enough to bind the texture then do:

glPixelStorei(GL_UNPACK_ROW_LENGTH, width);

with a value of width that exceeds 521 to cause the seg fault later when the textures are recreated.
The test program (which uses SDL, though I'm sure the error is in the OpenGL part) is as follows:

/* To test creating and deleting textures */

#include "SDL.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <GL/gl.h>
#include <GL/glu.h>

int ntex = 1;
static GLuint* texture_ids = NULL;
GLubyte* frame = NULL;

void draw(void)
{
GLuint i;
GLenum glerr;
GLint movie_width=768;
GLint skip_rows=0;
GLint skip_pixels=0;

glLoadIdentity( );

for (i = 0; i < ntex; i++) {
glBindTexture( GL_TEXTURE_2D, texture_ids[i] );
glPixelStorei( GL_UNPACK_ROW_LENGTH, movie_width );
glPixelStorei( GL_UNPACK_SKIP_ROWS, skip_rows );
glPixelStorei( GL_UNPACK_SKIP_PIXELS, skip_pixels );

/*
* Drawing goes here, using glTexSubImage2D().
*/
fprintf(stderr,"Now drawing frame\n");

glerr = glGetError();
if (glerr != GL_NO_ERROR)
fprintf(stderr,"GL ERROR: %d %s\n",glerr, gluErrorString(glerr));
}
}

int main(void)
{
int i, k;
GLubyte* pixels; /* initial black texels */
SDL_Surface* screen;

if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_AUDIO ) < 0 ) {
fprintf( stderr, "Couldn't initialize SDL\n" );
return 1;
}
screen = SDL_SetVideoMode(1024, 768, 0, SDL_OPENGL|SDL_FULLSCREEN);
if ( !screen ) {
fprintf( stderr, "Couldn't set 1024x768 GL video mode: %s\n", SDL_GetError());
return 1;
}
for (k=0; k < 2; k++) {
glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
glEnable( GL_TEXTURE_2D );
glEnable( GL_DITHER );

if (texture_ids)
free(texture_ids);
texture_ids = (GLuint*) malloc( sizeof( GLuint ) * ntex );
if( !texture_ids ) {
return 1;
}

glGenTextures( ntex, texture_ids );

for (i=0; i<ntex; i++) {
fprintf(stderr,"# %d texture_ids: %d\n",i,texture_ids[i]);
}

/* Specify the textures, initially all black */
for ( i = 0; i < ntex; i++ ) {

pixels = (GLubyte*) malloc( 256*256 * 4 );
memset( pixels, 0, 256*256 * 4 );
if( !pixels ) {
glDeleteTextures( ntex, texture_ids );
return 1;
}

/* Do all of our useful binding. */
glBindTexture( GL_TEXTURE_2D, texture_ids[i] );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

/* Specify our 256x256 black texture. */
glTexImage2D( GL_TEXTURE_2D,
0,
GL_RGB,
256,
256,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,
pixels );
free( pixels );
}

draw();

glDeleteTextures(ntex, texture_ids);

}
return 0;
}

gib
08-11-2002, 02:19 PM
My problem was solved by using glPushClientAttrib() and glPopClientAttrib().