OpenGL多窗口显示问题

OpenGL程序中,如果使用了VBO技术,则不能使用wglMakeCurrent在多个窗口中切换。

测试程序不使用VBO技术,直接画出球体

第二个窗口

 

使用了VBO的程序,可以使用多线程技术在多个窗口中切换。

如下图如示

 

程序主要代码如下

int DrawGLScene(GLfloat & rtri, int speed) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(-1.5f,0.0f,-10.0f); glRotatef(rtri,0.5f,1.0f,1.0f); rtri+=speed; glColor3f(0,255,0); glBegin(GL_LINES); glVertex3f(-1,-1,-1); glVertex3f(2,2,2); glEnd(); void draw3(); draw3(); return TRUE; } GLuint cubeName[2]; bool InitCubeVBO() { glGenBuffersARB(2, cubeName); glBindBufferARB(GL_ARRAY_BUFFER_ARB, cubeName[0] ); glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices) + sizeof(normals), 0, GL_STREAM_DRAW_ARB); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), vertices); glBufferSubDataARB(GL_ARRAY_BUFFER_ARB,sizeof(vertices), sizeof(normals), normals); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, cubeName[1] ); glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, sizeof(indices),indices, GL_STATIC_DRAW_ARB); return true; } void draw3() { glBindBufferARB(GL_ARRAY_BUFFER_ARB, cubeName[0] ); glNormalPointer(GL_FLOAT, 0, (void *) sizeof(vertices)); glVertexPointer(3, GL_FLOAT,0,0); glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, cubeName[1] ); glIndexPointer(GL_UNSIGNED_SHORT, 0, 0); glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glDrawElements(GL_QUADS, 24, GL_UNSIGNED_BYTE, 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); } BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag, Res & res) { GLuint PixelFormat; WNDCLASS wc; DWORD dwExStyle; DWORD dwStyle; RECT WindowRect; WindowRect.left=(long)0; WindowRect.right=(long)width; WindowRect.top=(long)0; WindowRect.bottom=(long)height; fullscreen=fullscreenflag; res.hInstance = GetModuleHandle(NULL); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = res.hInstance; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL"; if (!RegisterClass(&wc)) { } fullscreen = false; dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; dwStyle=WS_OVERLAPPEDWINDOW; AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Create The Window if (!(res.hWnd=CreateWindowEx( dwExStyle, "OpenGL", title, dwStyle | // Defined Window Style WS_CLIPSIBLINGS | // Required Window Style WS_CLIPCHILDREN, // Required Window Style 0, 0, WindowRect.right-WindowRect.left, WindowRect.bottom-WindowRect.top, NULL, NULL, res.hInstance, NULL))) { KillGLWindow(res); MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; } static PIXELFORMATDESCRIPTOR pfd= { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, bits, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, PFD_MAIN_PLANE, 0, 0, 0, 0 }; if (!(res.hDC=GetDC(res.hWnd))) { KillGLWindow(res); MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; } if (!(PixelFormat=ChoosePixelFormat(res.hDC,&pfd))) { KillGLWindow(res); MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; } if(!SetPixelFormat(res.hDC,PixelFormat,&pfd)) { KillGLWindow(res); MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; } if (!(res.hRC=wglCreateContext(res.hDC))) { KillGLWindow(res); MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; } if(!wglMakeCurrent(res.hDC,res.hRC)) { KillGLWindow(res); MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; } ShowWindow(res.hWnd,SW_SHOW); SetForegroundWindow(res.hWnd); SetFocus(res.hWnd); ReSizeGLScene(width, height); if (!InitGL()) { KillGLWindow(res); MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION); return FALSE; } return TRUE; } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=FALSE; } HasSpeedUp = false; void ThreadFunc(); HANDLE hThrd = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,NULL,0,NULL); CloseHandle(hThrd); Sleep(100); ThreadFunc(); return 0; } void ThreadFunc() { Res res; res.hDC = NULL; res.hInstance = NULL; res.hRC = NULL; res.hWnd =NULL; res.rtri=0; int speed = 1; if (!HasSpeedUp) { speed = 6; HasSpeedUp = true; } BOOL done=FALSE; MSG msg; if (!CreateGLWindow("NeHe's Solid Object Tutorial",640,480,16,fullscreen, res)) { return ; } while(!done) { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { if (msg.message==WM_QUIT) { done=TRUE; } else { TranslateMessage(&msg); DispatchMessage(&msg); } } else { if ((active && !DrawGLScene(res.rtri, speed)) || keys[VK_ESCAPE]) { done=TRUE; } else { SwapBuffers(res.hDC); } if (keys[VK_F1]) { keys[VK_F1]=FALSE; KillGLWindow(res); fullscreen=!fullscreen; if (!CreateGLWindow("NeHe's Solid Object Tutorial",640,480,16,fullscreen, res)) { return ; } } } } KillGLWindow(res); }

 

源码下载地址

你可能感兴趣的:(计算机图形学)