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
4, glGenBuffersARB runtime access violation