c++ debugging opengl segmentation-fault

c++ - Error de segmentación en glGenVertexArrays(1, & vao);



debugging opengl (4)

Mi backtrace gdb da:

(gdb) backtrace #0 0x00000000 in ?? () #1 0x0804a211 in init () at example1.cpp:147 #2 0x0804a6bc in main (argc=1, argv=0xbffff3d4) at example1.cpp:283

No muy informativo. El depurador de Eclipse al menos me permite ver que se detiene en la línea 3 a continuación:

// Create a vertex array object GLuint vao; glGenVertexArrays( 1, &vao ); glBindVertexArray( vao );

Este es un bloque muy común de ver en la programación de gl, e incluso estoy ejecutando otro código con el mismo bloque sin ningún problema. Así que estoy desconcertado.

Generar salida desde ejecución make:

g++ -g -DFREEGLUT_STATIC -DGLEW_STATIC -I../../include example1.cpp ../../Commo/InitShader.o -L/usr/lib/mesa -lGLEW -lglut -lGL -lX11 -lm -o example1

Programa que contiene el problema:

// rotating cube with two texture objects // change textures with 1 and 2 keys #include "Angel.h" const int NumTriangles = 12; // (6 faces)(2 triangles/face) const int NumVertices = 3 * NumTriangles; const int TextureSize = 64; typedef Angel::vec4 point4; typedef Angel::vec4 color4; // Texture objects and storage for texture image GLuint textures[2]; GLubyte image[TextureSize][TextureSize][3]; GLubyte image2[TextureSize][TextureSize][3]; // Vertex data arrays point4 points[NumVertices]; color4 quad_colors[NumVertices]; vec2 tex_coords[NumVertices]; // Array of rotation angles (in degrees) for each coordinate axis enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 }; int Axis = Xaxis; GLfloat Theta[NumAxes] = { 0.0, 0.0, 0.0 }; GLuint theta; //---------------------------------------------------------------------------- int Index = 0; void quad( int a, int b, int c, int d ) { point4 vertices[8] = { point4( -0.5, -0.5, 0.5, 1.0 ), point4( -0.5, 0.5, 0.5, 1.0 ), point4( 0.5, 0.5, 0.5, 1.0 ), point4( 0.5, -0.5, 0.5, 1.0 ), point4( -0.5, -0.5, -0.5, 1.0 ), point4( -0.5, 0.5, -0.5, 1.0 ), point4( 0.5, 0.5, -0.5, 1.0 ), point4( 0.5, -0.5, -0.5, 1.0 ) }; color4 colors[8] = { color4( 0.0, 0.0, 0.0, 1.0 ), // black color4( 1.0, 0.0, 0.0, 1.0 ), // red color4( 1.0, 1.0, 0.0, 1.0 ), // yellow color4( 0.0, 1.0, 0.0, 1.0 ), // green color4( 0.0, 0.0, 1.0, 1.0 ), // blue color4( 1.0, 0.0, 1.0, 1.0 ), // magenta color4( 0.0, 1.0, 1.0, 1.0 ), // white color4( 1.0, 1.0, 1.0, 1.0 ) // cyan }; quad_colors[Index] = colors[a]; points[Index] = vertices[a]; tex_coords[Index] = vec2( 0.0, 0.0 ); Index++; quad_colors[Index] = colors[a]; points[Index] = vertices[b]; tex_coords[Index] = vec2( 0.0, 1.0 ); Index++; quad_colors[Index] = colors[a]; points[Index] = vertices[c]; tex_coords[Index] = vec2( 1.0, 1.0 ); Index++; quad_colors[Index] = colors[a]; points[Index] = vertices[a]; tex_coords[Index] = vec2( 0.0, 0.0 ); Index++; quad_colors[Index] = colors[a]; points[Index] = vertices[c]; tex_coords[Index] = vec2( 1.0, 1.0 ); Index++; quad_colors[Index] = colors[a]; points[Index] = vertices[d]; tex_coords[Index] = vec2( 1.0, 0.0 ); Index++; } //---------------------------------------------------------------------------- void colorcube() { quad( 1, 0, 3, 2 ); quad( 2, 3, 7, 6 ); quad( 3, 0, 4, 7 ); quad( 6, 5, 1, 2 ); quad( 4, 5, 6, 7 ); quad( 5, 4, 0, 1 ); } //---------------------------------------------------------------------------- void init() { colorcube(); // Create a checkerboard pattern for ( int i = 0; i < 64; i++ ) { for ( int j = 0; j < 64; j++ ) { GLubyte c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0)) * 255; image[i][j][0] = c; image[i][j][1] = c; image[i][j][2] = c; image2[i][j][0] = c; image2[i][j][1] = 0; image2[i][j][2] = c; } } // Initialize texture objects glGenTextures( 2, textures ); glBindTexture( GL_TEXTURE_2D, textures[0] ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, TextureSize, TextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, image ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glBindTexture( GL_TEXTURE_2D, textures[1] ); glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, TextureSize, TextureSize, 0, GL_RGB, GL_UNSIGNED_BYTE, image2 ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glActiveTexture( GL_TEXTURE0 ); glBindTexture( GL_TEXTURE_2D, textures[0] ); // Create a vertex array object GLuint vao; glGenVertexArrays( 1, &vao ); glBindVertexArray( vao ); // Create and initialize a buffer object GLuint buffer; glGenBuffers( 1, &buffer ); glBindBuffer( GL_ARRAY_BUFFER, buffer ); glBufferData( GL_ARRAY_BUFFER, sizeof(points) + sizeof(quad_colors) + sizeof(tex_coords), NULL, GL_STATIC_DRAW ); // Specify an offset to keep track of where we''re placing data in our // vertex array buffer. We''ll use the same technique when we // associate the offsets with vertex attribute pointers. GLintptr offset = 0; glBufferSubData( GL_ARRAY_BUFFER, offset, sizeof(points), points ); offset += sizeof(points); glBufferSubData( GL_ARRAY_BUFFER, offset, sizeof(quad_colors), quad_colors ); offset += sizeof(quad_colors); glBufferSubData( GL_ARRAY_BUFFER, offset, sizeof(tex_coords), tex_coords ); // Load shaders and use the resulting shader program GLuint program = InitShader( "vshader71.glsl", "fshader71.glsl" ); glUseProgram( program ); // set up vertex arrays offset = 0; GLuint vPosition = glGetAttribLocation( program, "vPosition" ); glEnableVertexAttribArray( vPosition ); glVertexAttribPointer( vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset) ); offset += sizeof(points); GLuint vColor = glGetAttribLocation( program, "vColor" ); glEnableVertexAttribArray( vColor ); glVertexAttribPointer( vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset) ); offset += sizeof(quad_colors); GLuint vTexCoord = glGetAttribLocation( program, "vTexCoord" ); glEnableVertexAttribArray( vTexCoord ); glVertexAttribPointer( vTexCoord, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(offset) ); // Set the value of the fragment shader texture sampler variable // ("texture") to the the appropriate texture unit. In this case, // zero, for GL_TEXTURE0 which was previously set by calling // glActiveTexture(). glUniform1i( glGetUniformLocation(program, "texture"), 0 ); theta = glGetUniformLocation( program, "theta" ); glEnable( GL_DEPTH_TEST ); glClearColor( 1.0, 1.0, 1.0, 1.0 ); } void display( void ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glUniform3fv( theta, 1, Theta ); glDrawArrays( GL_TRIANGLES, 0, NumVertices ); glutSwapBuffers(); } //---------------------------------------------------------------------------- void mouse( int button, int state, int x, int y ) { if ( state == GLUT_DOWN ) { switch( button ) { case GLUT_LEFT_BUTTON: Axis = Xaxis; break; case GLUT_MIDDLE_BUTTON: Axis = Yaxis; break; case GLUT_RIGHT_BUTTON: Axis = Zaxis; break; } } } //---------------------------------------------------------------------------- void idle( void ) { Theta[Axis] += 0.01; if ( Theta[Axis] > 360.0 ) { Theta[Axis] -= 360.0; } glutPostRedisplay(); } //---------------------------------------------------------------------------- void keyboard( unsigned char key, int mousex, int mousey ) { switch( key ) { case 033: // Escape Key case ''q'': case ''Q'': exit( EXIT_SUCCESS ); break; case ''1'': glBindTexture( GL_TEXTURE_2D, textures[0] ); break; case ''2'': glBindTexture( GL_TEXTURE_2D, textures[1] ); break; } glutPostRedisplay(); } //---------------------------------------------------------------------------- int main( int argc, char **argv ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH ); glutInitWindowSize( 512, 512 ); glutInitContextVersion( 3, 2 ); glutInitContextProfile( GLUT_CORE_PROFILE ); glutCreateWindow( "Color Cube" ); glewInit(); init(); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); glutMouseFunc( mouse ); glutIdleFunc( idle ); glutMainLoop(); return 0; }


¿Has intentado probar en otros sistemas con diferentes tarjetas gráficas? Si su código cumple con la especificación OpenGL y se bloquea misteriosamente dentro de una función que se llama correctamente con parámetros válidos, bien podría ser un error del controlador. Si se trata de un error del controlador, se verá reducido a conjeturas, realizando cambios bruscos y creando gradualmente una exasperación saludable de que una gran corporación con miles de millones de dólares produzca excusas para un controlador de tarjeta gráfica. ¡Buena suerte!


Funciona bien para mí:

GL_VERSION : 4.1.10750 Compatibility Profile Context GL_VENDOR : ATI Technologies Inc. GL_RENDERER : AMD Radeon HD 6500 Series

EDITAR: Estoy usando las últimas versiones de FreeGLUT (2.8.0 RC2) y GLEW (1.7.0), lo que puede marcar la diferencia si confía en las versiones distribuidas.


Ubuntu 10.04 por ejemplo viene con glew 1.50 que glGenVertexArrays no funciona sin el indicador glewExperimental . por lo tanto, depende de la versión glew


glewExperimental = GL_TRUE; glewInit();

Debería hacer la magia

Controladores experimentales

GLEW obtiene información sobre las extensiones compatibles del controlador de gráficos. Sin embargo, los controladores experimentales o de prelanzamiento podrían no informar todas las extensiones disponibles a través del mecanismo estándar, en cuyo caso GLEW lo informará sin respaldo. Para evitar esta situación, el glewExperimental global glewExperimental se puede activar configurándolo en GL_TRUE antes de llamar a glewInit() , lo que garantiza que todas las extensiones con puntos de entrada válidos estarán expuestos.