glGenVertexArrays(1,&vao)的分割错误;
我的gdb回溯给出:
(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
不是很丰富。 Eclipsedebugging器至less让我看到它停在下面的第3行:
// Create a vertex array object GLuint vao; glGenVertexArrays( 1, &vao ); glBindVertexArray( vao );
这是在gl编程中看到的一个非常常见的块,我甚至用同一个块运行其他代码,没有问题。 所以我很困惑。
从运行make构build输出:
g++ -g -DFREEGLUT_STATIC -DGLEW_STATIC -I../../include example1.cpp ../../Commo/InitShader.o -L/usr/lib/mesa -lGLEW -lglut -lGL -lX11 -lm -o example1
包含问题的程序:
// 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; }
glewExperimental = GL_TRUE; glewInit();
应该做的魔术
实验性驱动
GLEW从graphics驱动程序获取受支持的扩展的信息。 然而,实验驱动程序或预发布驱动程序可能不会通过标准机制报告每个可用的扩展,在这种情况下,GLEW将报告它不受支持。 为了避免这种情况,在调用
glewInit()
之前,可以通过将glewExperimental
全局开关设置为GL_TRUE
来开启glewExperimental
全局开关,这将确保所有具有有效入口点的扩展都将被暴露。
为我工作得很好:
GL_VERSION : 4.1.10750 Compatibility Profile Context GL_VENDOR : ATI Technologies Inc. GL_RENDERER : AMD Radeon HD 6500 Series
编辑:我使用FreeGLUT(2.8.0 RC2)和GLEW(1.7.0)的最新版本,如果您依靠发行版提供的版本,这可能会有所作为。
您是否尝试过使用不同显卡的其他系统进行testing? 如果你的代码符合OpenGL规范,它会在一个被有效参数正确调用的函数内神秘地崩溃,这可能是一个驱动程序错误。 如果这是一个驱动程序错误,那么你就会沦为猜测,霰弹枪的变化,并逐渐build立起一个健康的愤怒,一个拥有数十亿美元的巨大公司为graphics卡驱动程序提供绝对的废话。 祝你好运!
例如,Ubuntu 10.04配备了glw 1.50,如果没有glewExperimental
标志, glGenVertexArrays
无法工作。 所以它是依赖于版本的