glBindBuffer 崩溃 - 带有 glew 的 VBO 实现

Posted

技术标签:

【中文标题】glBindBuffer 崩溃 - 带有 glew 的 VBO 实现【英文标题】:glBindBuffer crash - VBO implementation with glew 【发布时间】:2012-10-04 22:02:40 【问题描述】:

我一直在尝试在我的计算机上实现 VBO,但遇到了分段错误:

Unhandled exception at 0x00000000 in attocube.exe: 0xC0000005: Access violation

错误出现在我在void init() 中调用glBindBuffer(GL_ARRAY_BUFFER, ID); 的那一行。 我使用了以下问题的代码:How to get VBO working

#include <windows.h>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>

#pragma comment(lib,"glew32.lib")

GLuint ID;

void init()
    glewInit();
    glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
    glShadeModel(GL_FLAT);
    glEnableClientState(GL_VERTEX_ARRAY);
    float data[][2] = 50,50,100,50,75,100;
    glGenBuffers(1,&ID);
    glBindBuffer(GL_ARRAY_BUFFER, ID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);


void reshape(int w, int h)
    glViewport(0,0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0f, (GLdouble) w, 0.0f, (GLdouble) h);


void display()
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(0.0f,0.0f,0.0f);
    glBindBuffer(GL_ARRAY_BUFFER, ID);
    glVertexPointer(2, GL_FLOAT, 2*sizeof(float), 0);
    glDrawArrays(GL_TRIANGLES,0,3);
    glFlush();  


int main(int argc, char **argv)
    glutInit(&argc,argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowSize(500,500);
    glutInitWindowPosition(300,300);
    glutCreateWindow(argv[0]);
    init();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
    return 0;

我的配置如下: Windows 7 / Geforce GTX 570 / glew 1.9.0

【问题讨论】:

为我工作。你的glewInit() 调用成功了吗? 我把这个GLenum err = glewInit(); if (GLEW_OK != err) /* Problem: glewInit failed, something is seriously wrong. */ fprintf(stderr, "Error: %s\n", glewGetErrorString(err)); 放了,没有收到任何错误信息。 能否请您在 GLEW 初始化后添加以下内容fprintf(stderr, "Address of glBindBuffer: %p\n", glBindBuffer); 并告诉我们输出结果。 glGetString(GL_RENDERER);的内容也可能是一个很好的诊断 【参考方案1】:

您的代码缺少对所需 OpenGL 版本可用性的任何检查(或者在您使用扩展的情况下,如果存在扩展)。您必须始终检查请求的功能是否实际存在。

见http://glew.sourceforge.net/basic.html第二段

现在顶点缓冲区对象是一个非常普遍的功能,它们不太可能不可用。但是崩溃表明这就是问题所在。因此,请确保您正确安装了正确的驱动程序。

【讨论】:

他在 GeForce 570 上;对于不支持比 GL 1.5 更好的硬件,您找不到足够老的驱动程序。您可能找不到不支持 GL 4.0 的驱动程序。 @NicolBolas:对。但是:驱动程序是否正确安装? Windows 7 本身只在 Direct3D 层上带来了糟糕的 OpenGL-1.4,它不支持 VBO!(如您所知,GL 1.5 引入了 VBO)。所以解决方案是去 NVidia 网站,下载功能齐全的驱动程序并安装它,而不是微软剥离的版本。 我的显卡驱动已经更新到306.23版本了。【参考方案2】:

我正在使用远程桌面连接的工作站工作。我刚刚尝试直接在机器上运行代码并且它可以工作。 VBO 不适用于 RDC。我觉得自己真的很愚蠢。非常感谢您的帮助。

【讨论】:

嗯,这并不奇怪:RDC 不在 GPU 上进行图形处理。因此,这意味着 Windows 7 的低功能后备 OpenGL 实现(仅支持 OpenGL-1.4)开始发挥作用。您对此无能为力。如果您的程序检测到在 RDC 环境中运行,您可以放入 Mesa 的软件渲染器 opengl32.dll,但性能会很差。 我不认为我会开始搞乱 RDC。我将为标准用户开发我的程序。感谢您的帮助。【参考方案3】:

我在使用 GL glewInit(); 之前设置glewExperimental = GL_TRUE; 解决了它。

【讨论】:

【参考方案4】:

不管怎样,除了远程桌面问题,使用 GLEW 检查 VBO 的代码是这样的:

bool hasVBO = GLEW_ARB_vertex_buffer_object == TRUE;
bool hasVAO = GLEW_ARB_vertex_array_object == TRUE;

【讨论】:

【参考方案5】:

对于那些仍然遇到这个问题的人,如果你从另一个不是渲染线程的线程调用glBindBuffer,你的程序将会崩溃。无论如何,至少在使用 Allegro 5 时。我通过将我的 VBO 代码移动到主线程来解决这个问题,并且崩溃停止了。

【讨论】:

【参考方案6】:

我让远程桌面在两台 Win7 PC 之间工作,运行 OpenGL 4.3:

在批处理文件中,输入:

tscon 1 /dest:console /PASSWORD:yourPassword
cd C:\your\Exe\Folder
start yourProgram.exe
C:\Windows\System32\rundll32.exe user32.dll,LockWorkStation

以管理员身份运行。 它将关闭会话、打开控制台(您的 PC 现在已登录,任何人都可以上前使用)、启动程序并锁定屏幕。

然后您将使用远程桌面重新连接;并且您的程序应该正在运行,使用服务器的图形硬件加速。

这假设您的远程会话 ID 为 1。要检查,请运行命令窗口“查询会话”,并查看以“>”开头的行。

【讨论】:

以上是关于glBindBuffer 崩溃 - 带有 glew 的 VBO 实现的主要内容,如果未能解决你的问题,请参考以下文章

QtQuick 2 是不是支持 glBindBuffer?

使用带有 glew 的 VBO 访问冲突

使用glew时opengl崩溃

OpenGL glBufferStorage 崩溃

glCreateShader 崩溃了

带有 SDL 和 GLEW 的 OpenGL,错误:48