VC++ MFC single-document application program SDI calls glGenBuffersARB(1, &pbo) method to compile and pass but execution error analysis and solution: glewInit() initialization error

1. Symptoms of the problem

  In the VC++ environment, the OpenGL program is developed under the MFC single-document application SDI. When the glGenBuffersARB(1, &pbo) method is called, the compilation is passed but an error occurs during execution. The error code is as follows:

 Unhandled exception at 0x00000000 in OpenGL program: 0xC0000005: Access violation while reading location 0x00000000
void createVBO(GLuint *vbo,int size)
{
  glGenBuffers( 1 ,vbo);//There is an error in this line of code, woohoo
  glBindBuffer(GL_ARRAY_BUFFER,*vbo);
  glBufferData(GL_ARRAY_BUFFER,size,0,GL_DYNAMIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER,0);
  CUT_CHECK_ERROR_GL();
}
It is a code for creating a buffer function. The program compiles without errors, but when it runs to glGenBuffers(1, vbo), the error of the title appears, as shown in the following figure:

2. Reason analysis

  Some GL interfaces for buffers have only been available since GL1.5, and the GL that comes with Windows only supports version 1.1. But if your graphics card supports GL1.5 or above, glew will help you complete the expansion work very well. Since you use glew, you should call glewInit to initialize these extensions before using any interface of GL, otherwise those GL Interfaces are not available. Just add glewInit at the beginning of your init method.

3. Solutions

  (1), Win32 engineering environment

     Initialize as follows

 

// Set OpenGL environment 
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 initialization
}    

 

    Then call the following code that generates the buffer ID:

glGenBuffers( 1 ,vbo); //Generate buffer identifier

    (2) Engineering environment under VC++ MFC single document application SDI

    In the engineering environment of VC++ MFC single-document application SDI, you need to call the wglMakeCurrent(m_hDC, tempContext); method first, then call the glew initialization code, and finally call the code that generates the buffer identifier. If the glewInit method is not called after wglMakeCurrent, it will cause glewInit to return 1 (or 0 on success). This leads to the preceding runtime problems. The calling sequence is given below:

  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) . Among them, the GLInit() and initGLBuffers() methods are specifically defined as follows:

 

void CRSQuickLookView::GLInit()
{
    CreateTexturePixel(); // Generate pixel buffer data for test
     // 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,            // flag 
        PFD_TYPE_RGBA,                  // color mode 
        24 ,                                    // color bits 
        0 , 0 , 0 , 0 , 0 , 0 ,
         0 , 0 , 0 , 0 , 0 , 0 , 0 ,
         32 ,                                   // depth bits 
        0 ,
         0,
        PFD_MAIN_PLANE,
        0,
        0, 0, 0
    };
    GLuint PixelFormat;
    if ((PixelFormat = ChoosePixelFormat(m_hDC, &pfd)) == 0 )
         return ;                 // Select the corresponding pixel format 
    if (!SetPixelFormat(m_hDC, PixelFormat, & pfd))
         return ;                                // Set the pixel format
     // if ((m_hRC = wglCreateContext(m_hDC)) == NULL) 
    if ((g_p00RC = wglCreateContext(m_hDC)) == NULL)
         return ;                           // Create a coloring description table 
    SetupCUDA(); // Set the CUDA environment, mainly to complete the graphics card with the strongest computing power select and setup
     // GLSetupRC();
     //if (!wglMakeCurrent(m_hDC, m_hRC)) 
    if (! wglMakeCurrent(m_hDC, g_p00RC))
         return ;                                            // Connect the shader description table to the device description table

    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);
}

 

 

 

Reference link:

1. glewInit initialization error and glewInit initialization error

2. Use vbo in opengl to draw under mfc, but the drawing fails

3. Unhandled error at 0x00000000 in OpenGL program: 0xC0000005: Access violation occurred while reading position 0x00000000

4, glGenBuffersARB runtime access violation

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325112557&siteId=291194637