标签:文档 nan 技术 top tle argv block com over
1、问题症状
在VC++环境下,利用MFC单文档应用程序SDI下开发OpenGL程序,当调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错,出错代码如下:
OpenGL程序中的0x00000000 处未处理的异常: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
void createVBO(GLuint *vbo,int size) { glGenBuffers(1,vbo);//该行代码出错,呜呜 glBindBuffer(GL_ARRAY_BUFFER,*vbo); glBufferData(GL_ARRAY_BUFFER,size,0,GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER,0); CUT_CHECK_ERROR_GL(); }
是一个建立缓冲区函数的代码,程序编译没有错误,但是运行到glGenBuffers(1,vbo)时,出现标题的错误,如下图所示:
2、原因分析
关于缓冲区的一些GL接口,是从GL1.5才开始有的,而windows自带的GL只支持到1.1版本。但如果你的显卡支持GL1.5以上的话,glew就很好的帮你完成了扩展工作,既然你用glew,那么就应该在使用GL任何一个接口前首先调用glewInit来初始化这些扩展,否则那些GL接口都不能使用。在你的init方法开头添加加glewInit就可以了。
3、解决办法
(1)、Win32工程环境
先按如下代码初始化
//设置OpenGL环境 void SetupGL(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize (WINDOW_WIDTH, WINDOW_HEIGHT); glutCreateWindow(ProgramName); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutReshapeFunc(reshape); glutIdleFunc(idle); glewInit();//glew初始化 }
然后再调用下面的产生缓冲区标识的代码:
glGenBuffers(1,vbo);//产生缓冲区标识
(2)、VC++ MFC单文档应用程序SDI下工程环境
在VC++ MFC单文档应用程序SDI下工程环境下,需要先调用wglMakeCurrent(m_hDC, tempContext);方法,然后再调用glew初始化代码,最后再调用产生缓冲区标识的代码。如果未在wglMakeCurrent之后调用glewInit方法,则会造成glewInit返回1(成功返回0)。从而导致前面的运行时问题出现。下面给出调用次序:
CRSQuickLookView::OnCreate--_>GLInit()--->GetSafeHdc()--->ChoosePixelFormat(m_hDC, &pfd)--->SetPixelFormat(m_hDC, PixelFormat, &pfd)--->wglCreateContext(m_hDC)--->wglMakeCurrent(m_hDC, g_p00RC)--->glewInit()--->initGLBuffers()--->glGenBuffers(1,vbo)。其中,GLInit()和initGLBuffers()方法具体定义如下:
void CRSQuickLookView::GLInit() { CreateTexturePixel();//产生测试的像素缓冲区数据 //m_hDC = ::GetDC(m_hWnd); CDC* clientDC = new CClientDC(this); m_hDC = clientDC->GetSafeHdc(); if (m_hDC == NULL) return; static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, //标志 PFD_TYPE_RGBA, //颜色模式 24, //颜色位数 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, //深度位数 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; GLuint PixelFormat; if ((PixelFormat = ChoosePixelFormat(m_hDC, &pfd)) == 0) return; //选择相应像素格式 if (!SetPixelFormat(m_hDC, PixelFormat, &pfd)) return; //设置像素格式 //if ((m_hRC = wglCreateContext(m_hDC)) == NULL) if ((g_p00RC = wglCreateContext(m_hDC)) == NULL) return; //创建着色描述表 SetupCUDA();//设置CUDA环境,主要完成最强计算能力显卡的选择和设置 //GLSetupRC(); //if (!wglMakeCurrent(m_hDC, m_hRC)) if (!wglMakeCurrent(m_hDC, g_p00RC)) return; //将着色描述表连接到设备描述表 int re=glewInit(); initGLBuffers(); }
void CRSQuickLookView::initGLBuffers() { // create pixel buffer object to store final image glGenBuffers(1, &pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo); glBufferData(GL_PIXEL_UNPACK_BUFFER, width * height * sizeof(GLubyte) * 3, pPixelData, GL_DYNAMIC_DRAW);//GL_STREAM_DRAW_ARB glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); checkCudaErrors(cudaGLRegisterBufferObject(pbo)); // create texture for display glGenTextures(1, &_texture); glBindTexture(GL_TEXTURE_2D, _texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); }
参考链接:
1、glewInit初始化的错误和glewInit初始化的错误
3、OpenGL程序中的0x00000000 处未处理的错误: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
VC++ MFC单文档应用程序SDI下调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错原因分析及解决办法:glewInit()初始化的错误
标签:文档 nan 技术 top tle argv block com over
原文地址:https://www.cnblogs.com/rainbow70626/p/8976088.html