VC编程之VC++ MFC单文档应用程序SDI下调用glGenBuffersARB方法编译通过但执行时出错
小标 2018-09-04 来源 : 阅读 1201 评论 0

摘要:本文主要向大家介绍了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频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 1 不喜欢 | 0
看完这篇文章有何感觉?已经有1人表态,100%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程