2011-11-28 3 views
47

Мой GDB трассировку дает:.вина Сегментация на glGenVertexArrays (1, &vao);

(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 

Не очень информативно Eclipse, отладчик по крайней мере, позволяет мне видеть, что он останавливается на линии 3 ниже:

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

Этот это очень распространенный блок, который можно увидеть в программировании gl, и я даже запускаю другой код с тем же блоком без проблем. Поэтому я сбитый с толку.

Сборка выхода из бега:

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; 
} 
+0

Есть ли в третьей строке строка 147 примера1.cpp? –

+6

Извините; этого недостаточно, чтобы даже начать работу над этой проблемой. Как вы [загрузите указатели на функции OpenGL] (http://www.opengl.org/wiki/Load_OpenGL_Functions)? Вы используете [library] (http://www.opengl.org/wiki/OpenGL_Loading_Library), или вы делаете это вручную? Если это библиотека, вы ее инициализировали? Что это за библиотека?Если вы сделаете это вручную, какое значение указателя вы вернели для 'glGenVertexArrays'? –

+0

@Marcelo Line 147 - это init(), в котором находится этот блок. Кроме того, в init() есть больше. – Rooster

ответ

116
glewExperimental = GL_TRUE; 
glewInit(); 

Если сделать магию


Experimental Drivers

GLEW получает информацию о поддерживаемых расширениях из графических драйвера. Однако экспериментальные или предварительные версии драйверов могут не сообщать о каждом доступном расширении через стандартный механизм, в котором случай GLEW сообщает об этом без поддержки. Чтобы обойти эту ситуацию, глобальный переключатель glewExperimental может быть включен, установив его на GL_TRUE перед вызовом glewInit(), что гарантирует, что будут открыты все расширения с действительными точками входа.

+2

Чувак! Ты жжешь! Оно работает. И спасибо также тем, кто работал со мной. – Rooster

+1

Ну, у меня была такая же проблема несколько недель назад :) – KoKuToru

+0

Я очень благодарю вас за это, я рассмотрю причину, по которой это исправление работает, но правильно. Я просто рад, что решил свою проблему! – lollancf37

0

вы пробовали тестирование на других системах с различными графическими картами? Если ваш код соответствует спецификации OpenGL, и он загадочно падает внутри функции, которая правильно вызывается с допустимыми параметрами, это может быть ошибкой драйвера. Если это ошибка водителя, вы сводились к догадкам, изменениям дробовика и постепенному росту здорового раздражения, которое огромная корпорация с миллиардами долларов производит абсолютно дерзкие оправдания для драйвера видеокарты. Удачи!

+0

У меня нет. Но стоит ли даже попробовать, так как я могу назвать ту же функцию просто отлично в другой программе на этой же машине? – Rooster

+0

Да, это определенно стоит проверить, потому что ошибки драйверов могут быть абсолютно бессмысленными и случайными. Поверьте мне, я потратил много часов, разбивая мне голову на стол по ошибкам драйвера OpenGL. Стандарт драйверов ужасен, даже nVidia и ATI, и не заставляйте меня работать на Intel. – AshleysBrain

+0

Ничего себе. Ну, пока программирование OpenGL было ... весело. И я имею в виду это самым саркастическим способом. – Rooster

1

отлично работает для меня:

screenshot

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

EDIT: Я использую последние версии FreeGLUT (2.8.0 RC2) и GLEW (1.7.0), который может имеют значение, если вы полагаетесь на дистрибутивные версии.

0

Ubuntu 10,04, например, поставляется с GLEW 1.50, который glGenVertexArrays не работает без glewExperimental флага. , так что он зависит от версии видеозаписей

Смежные вопросы