摘要:本文主要向大家介绍了VC编程之VC++ MFC单文档应用程序SDI下调用glGenBuffersARB方法编译通过但执行时出错,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
本文主要向大家介绍了VC编程之VC++ MFC单文档应用程序SDI下调用glGenBuffersARB方法编译通过但执行时出错,通过具体的内容向大家展示,希望对大家学习VC编程有所帮助。
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初始化的错误
2、在mfc下使用opengl中的vbo进行绘制,绘制失败
3、OpenGL程序中的0x00000000 处未处理的错误: 0xC0000005: 读取位置 0x00000000 时发生访问冲突
4、glGenBuffersARB 运行时访问冲突
5、OpenGL程序中与glew相关的未处理异常的解决方案
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言VC/MFC频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号