C++ glGenVertexArrays(1, &vao) 处的分段错误;
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8302625/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Segmentation fault at glGenVertexArrays( 1, &vao );
提问by Rooster
My gdb backtrace gives:
我的 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
Not very informative. Eclipse debugger at least lets me see that it stops on line 3 below:
不是很翔实。Eclipse 调试器至少让我看到它在下面的第 3 行停止:
// Create a vertex array object
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
This is a very common block to see in gl programming, and I'm even running other code with the same block with no problem. So I'm baffled.
这是在 gl 编程中很常见的一个块,我什至用相同的块运行其他代码也没有问题。所以我很困惑。
Build output from running make:
运行 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
Program containing the problem:
包含问题的程序:
// 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;
}
回答by KoKuToru
glewExperimental = GL_TRUE;
glewInit();
Should do the magic
应该施展魔法
GLEW obtains information on the supported extensions from the graphics driver. Experimental or pre-release drivers, however, might not report every available extension through the standard mechanism, in which case GLEW will report it unsupported. To circumvent this situation, the
glewExperimental
global switch can be turned on by setting it toGL_TRUE
before callingglewInit()
, which ensures that all extensions with valid entry points will be exposed.
GLEW 从图形驱动程序获取有关支持的扩展的信息。然而,实验性或预发布驱动程序可能不会通过标准机制报告每个可用的扩展,在这种情况下,GLEW 将报告它不受支持。为了避免这种情况,
glewExperimental
可以通过将全局开关设置为GL_TRUE
before call来打开全局开关glewInit()
,这确保所有具有有效入口点的扩展都将被公开。
回答by genpfault
Works fine for me:
对我来说很好用:
GL_VERSION : 4.1.10750 Compatibility Profile Context
GL_VENDOR : ATI Technologies Inc.
GL_RENDERER : AMD Radeon HD 6500 Series
EDIT:I'm using the latest versions of FreeGLUT (2.8.0 RC2) and GLEW (1.7.0), which may make a difference if you're relying on distro-supplied versions.
编辑:我使用的是最新版本的 FreeGLUT (2.8.0 RC2) 和 GLEW (1.7.0),如果您依赖发行版提供的版本,这可能会有所不同。
回答by AshleysBrain
Have you tried testing on other systems with different graphics cards? If your code meets the OpenGL spec and it mysteriously crashes inside a function that is correctly called with valid parameters, it could well be a driver bug. If it's a driver bug, you're reduced to guesswork, making shotgun changes, and gradually building up a healthy exasperation that a huge corporation with billions of dollars produce absolutely crap excuses for a graphics card driver. Good luck!
您是否尝试过在具有不同显卡的其他系统上进行测试?如果您的代码符合 OpenGL 规范,并且在使用有效参数正确调用的函数中神秘崩溃,则很可能是驱动程序错误。如果这是一个驱动程序错误,你只能靠猜测,做出霰弹枪更改,并逐渐建立一个健康的愤怒,一个拥有数十亿美元的大公司为显卡驱动程序提供绝对废话的借口。祝你好运!
回答by Nadim Farhat
Ubuntu 10.04 for example comes with glew 1.50 which glGenVertexArrays
doesn't work without the glewExperimental
flag.
so it is glew version dependent
例如,Ubuntu 10.04 带有 glew 1.50,它glGenVertexArrays
在没有glewExperimental
标志的情况下不起作用。所以它依赖于版本