2015-05-05 2 views
1

Я пытаюсь самостоятельно изучить openGL, поэтому я купил книгу о openGL, а в первой главе - пример кода, поэтому я попробую, и что-то пошло не так. В строке 17 (glGenVertexArrays (NumVAOs, VAO);) и 18 (glBindVertexArray (VAOs [Triangles]);) - VS 2013 Ultimate сообщают об ошибке точно «Необработанное исключение в 0x77350309 в openGL_3.exe: 0xC0000005: Ошибка выполнения нарушения 0x00000000. ». Поэтому я думаю, что это что-то не так с памятью, но я не знаю, что. Кто-нибудь может мне помочь?openGL: glGenVertexArrays Нарушение прав доступа, выполняемое местоположение 0x00000000

#include <iostream> 
using namespace std; 

#include <vgl.h> 
#include <LoadShaders.h> 


enum VAO_IDs { Triangles, NumVAOs }; 
enum Buffer_IDs { ArrayBuffer, NumBuffers }; 
enum Attrib_IDs { vPosition = 0 }; 
GLuint VAOs[NumVAOs]; 
GLuint Buffers[NumBuffers]; 
const GLuint NumVertices = 6; 

void init(void) 
{ 
    glGenVertexArrays(NumVAOs, VAOs); 
    glBindVertexArray(VAOs[Triangles]); 
    GLfloat vertices[NumVertices][2] = { 
     { -0.90, -0.90 }, // Triangle 1 
     { 0.85, -0.90 }, 
     { -0.90, 0.85 }, 
     { 0.90, -0.85 }, // Triangle 2 
     { 0.90, 0.90 }, 
     { -0.85, 0.90 } 
    }; 
    glGenBuffers(NumBuffers, Buffers); 
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[ArrayBuffer]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), 
    vertices, GL_STATIC_DRAW); 
    ShaderInfo shaders[] = { 
     { GL_VERTEX_SHADER, "triangles.vert" }, 
     { GL_FRAGMENT_SHADER, "triangles.frag" }, 
     { GL_NONE, NULL } 
    }; 
    GLuint program = LoadShaders(shaders); 
    glUseProgram(program); 
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, 
    GL_FALSE, 0, BUFFER_OFFSET(0)); 
    glEnableVertexAttribArray(vPosition); 
} 

void display(void) 
{ 
    glClear(GL_COLOR_BUFFER_BIT); 
    glBindVertexArray(VAOs[Triangles]); 
    glDrawArrays(GL_TRIANGLES, 0, NumVertices); 
    glFlush(); 
} 

int main(int argc, char** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_RGBA); 
    glutInitWindowSize(512, 512); 
    glutInitContextVersion(4, 3); 
    glutInitContextProfile(GLUT_CORE_PROFILE); 
    glutCreateWindow(argv[0]); 
    if (glewInit()) { 
     cerr << "Unable to initialize GLEW ... exiting" << endl; 
     exit(EXIT_FAILURE); 
    } 
    init(); 
    glutDisplayFunc(display); 
    glutMainLoop(); 
} 

ответ

0

Вы уверены, что вы можете запросить версию 4.3до того вызова glewInit()? Для каждой версии >= 3.0 требуется WGL_ARB_create_context (Windows)/GLX_ARB_create_context (Linux), что является расширением.

Обычно, чтобы создать "современный" контекст OpenGL (3.0+) требуется:

  1. Создание временного контекста, установите его в качестве текущего.
  2. Инициализировать расширения (либо вручную, либо с загрузчиком, например GLEW или GLFW).
  3. Запросить желаемую версию (и профиль, если вы создаете версию 3.2 или выше и WGL_ARB_create_context_profile/GLX_ARB_create_context_profile есть).
  4. Удалить временный контекст с 1. и связать новый контекст.

Вы можете посмотреть по адресу:

Я не знаю, какова связь между запрашивающим контекста версии в GLUT и GLEW инициализации (I часто используют GLEW, но создание контекста - это что-то, что я всегда делают вручную, с API-интерфейсом для платформы), но, очевидно, указатели на новый API OpenGL не инициализируются при вызове glGenVertexArrays. В этом причина вашей ошибки - вы пытаетесь вызвать функцию через указатель, который равен NULL.

+0

freeglut (и весь API 'glutInitContextVersion' - это просто расширение, зависящее от freeglut, не присутствующее в других версиях GLUT) будет способствовать созданию контекста в абстрактной форме платформы, подобно GLFW, SDL или аналогичным библиотекам. На самом деле нет принципиальной проблемы с этим подходом, помимо попытки использовать 'glewInit()' без 'glewExperimental = GL_TRUE' в основном профиле. – derhass

0

я вообще согласен с ответом SGA в рекомендуя установить glewExperimental=GL_TRUE перед вызовом glewInit(). GLEW не будет инициализироваться в основном профиле, если этот параметр не установлен.

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

Я уже рассмотрел реализацию freeglut (API-интерфейса, специфичного для freeglut) glutInitContextVersion, на вопрос «Where is the documentation for glutInitContextVersion?», и выводы из этого могут быть полезны в этом случае. Цитирую себя:

Глядя в код (для текущей стабильной версии 2.8.1), один будет видеть, что freeglut реализует следующую логику: Если реализация не может FULLFILL версий ограничений, но делает поддерживаем расширение ARB_create_context, он будет генерировать некоторую ошибку , и контекст не будет создан. Однако, если запрашивается версия, , но реализация даже не поддерживает соответствующие расширения, создается устаревший контекст GL, фактически игнорируя запрос версии .

Так от отчётного поведения, я делаю вывод, что ОП было получить только унаследованного контекст, возможно, даже Microsofts умолчанию OpenGL 1.1 реализации.

Это также исключает, почему glGenVertexArrays() является указателем NULL даже после того, как glewInit() преуспел: расширение для этого контекста не поддерживается.

Вы должны проверить, что glGetString(GL_VERSION) и glGetString(GL_RENDERER) действительно возвращаются сразу после вызова glutCreateWindow(). И в зависимости от выхода вы можете рассмотреть возможность проверки/обновления ваших графических драйверов, или вы можете узнать, что ваш GPU просто не способен к современному GL вообще.

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