openGL:glGenVertexArrays执行位置0x00000000的访问冲突

时间:2015-05-05 19:18:16

标签: c++ opengl

我正在尝试自己学习openGL,所以我买了一本关于openGL的书,第一章是示例代码,所以我试了一下,出了点问题。在第17行(glGenVertexArrays(NumVAOs,VAOs);)和18(glBindVertexArray(VAOs [Triangles]);)是VS 2013 Ultimate正确报告错误“openGL_3.exe中0x77350309处的未处理异常:0xC0000005:访问冲突执行位置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();
}

3 个答案:

答案 0 :(得分:1)

您可以尝试设置:

glewExperimental = GL_TRUE;
在致电glewInit()之前

。来源:

https://stackoverflow.com/a/20822876/833188

https://stackoverflow.com/a/22820845/833188

答案 1 :(得分:0)

您确定在致电4.3之前可以请求版本glewInit() 吗?每个版本>= 3.0都需要WGL_ARB_create_context (Windows) / GLX_ARB_create_context (Linux),这是一个扩展名。

通常,要创建“现代” OpenGL上下文(3.0+),需要:

  1. 创建临时上下文,将其设置为当前。
  2. 初始化扩展程序(手动或使用加载程序,如GLEWGLFW)。
  3. 请求所需的版本(和个人资料,如果您创建版本3.2或更高版本,并且WGL_ARB_create_context_profile / GLX_ARB_create_context_profile存在)。
  4. 1.删除临时上下文并绑定新上下文。
  5. 您可能需要查看:

    我不知道,在GLUTGLEW初始化中请求上下文版本之间的联系是什么(我经常使用GLEW,但是上下文的创建就是这样,我总是手动执行,使用特定于平台的API),但很明显,当您调用glGenVertexArrays时,不会初始化指向新OpenGL API的指针。这就是你错误的原因 - 你试图通过指针调用函数,这是NULL

答案 2 :(得分:0)

我普遍同意Sga的回答,建议在致电glewExperimental=GL_TRUE之前设置glewInit()。如果未设置此选项,GLEW将无法在核心配置文件中初始化。

然而,glewInit() 失败的事实意味着OP根本没有获得核心配置文件(或者GLEW最终已经修复,但更多的是理论上的可能性。)

我已经看过freeglut针对问题“Where is the documentation for glutInitContextVersion?”的(freeglut特定的)glutInitContextVersion API的实现,并且从那时起的结论可能对这种情况有所帮助。引用自己:

  

从查看代码(对于当前的稳定版本2.8.1),一个   将看到freeglut实现了以下逻辑:如果   实现不能满足版本约束,但确实如此   支持ARB_create_context扩展,它会产生一些错误   并且不会创建任何上下文。但是,如果要求版本,   但实施甚至不支持相关的扩展,   创建遗留GL上下文,实际上忽略了版本   完全要求。

因此,根据报告的行为,我推断OP只获得遗留上下文,甚至可能是Microsofts默认的OpenGL 1.1实现。

这也解释了glGenVertexArrays()成为glewInit()成功后glGetString(GL_VERSION)为空指针的原因:此上下文不支持该扩展名。

您应该在glGetString(GL_RENDERER)电话后检查glutCreateWindow().html()实际返回的内容。根据输出情况,您可能会考虑检查/更新图形驱动程序,或者您可能知道您的GPU根本无法使用现代GL。