[OpenGL] 基于win32api建立多窗口GL应用程序

55 篇文章 0 订阅

建立多窗口openGL程序,可以用来制作各种GL控制或者多视图GL程序,为以后设计组态openGL引擎试验。

 

基础知识

 

1.OpenGL与其他窗体应用程序消息循环上的不同

这个大家都知道,因为其他窗体应用程序不需要实时绘制,但需要实时监听消息响应,所以为了提高性能,openGL和其他窗体程序的消息循环写法有一点点不一样。(就因为如此,所以我们需要使用多线程来建立不同的窗口)

 

a.一般窗体程序(例如MFC)消息循环机制如下:

1 MSG msg;
2 while(GetMessage(&msg,NULL,0,0))
3 {
4  TranslateMessage(&msg);
5  DispatchMessage(&msg);
6 }

这么的话需要等系统的WM_PAINT消息才去重新绘制,对3D动画程序来说肯定效率低下,但对窗体应用程序来说却很节省资源。

 

b.OpenGL改进后的循环如下:

01 while(!done)     
02
03 {
04   if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) 
05
06   {
07
08     if (msg.message==WM_QUIT)  
09         done=TRUE;   
10     else     
11
12     {
13
14       TranslateMessage(&msg);    // 翻译消息
15       DispatchMessage(&msg);    // 发送消息
16     }
17   }
18
19   else       
20   {
21
22     DrawGL(); //绘制gl窗口
23
24   }
25
26 }

PeekMessage和GetMessage区别就是他不会等函数返回就直接往下执行了,效率当然高很多。

2.多线程

由于第一点原因,所以我们使用多线程。多线程win32api函数:
 CreateThread();
返回一个句柄。

这样就能建立多个线程独立运行各个窗口函数,建立其他窗口来控制openGL绘制或者建立多个窗口不同视角来显示GL物体等。窗体间能建立父子关系,可以想象下photoshop,就可以知道这种多窗口程序有多诱人了^ ^.当然还可以做窗口停靠。

 

示例代码:

 

文件1:

01 #include <windows.h>
02 #include <gl\glew.h>
03 #include <gl\glut.h>
04 #include "ControlPad.h"
05
06 void display(void)
07 {
08  glClear(GL_COLOR_BUFFER_BIT);
09
10  glutSwapBuffers();
11 }
12
13 void init(void)
14 {
15  glClearColor(0.0,0.0,0.0,0.0);
16  glMatrixMode(GL_PROJECTION);
17   
18  glLoadIdentity();
19  glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
20 }
21
22 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstace,LPSTRlpCmdLine,int nCmdShow)
23 {
24  int argc = 2;
25  char* argv[] = {"Jerry","OpenGL"};
26  glutInit(&argc,argv);
27  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
28  glutInitWindowSize(800,600);
29  glutInitWindowPosition(100,100);
30  glutCreateWindow("TestMode");
31
32   
33
34  //重点在这里
35
36  HANDLE hThread;
37  hThread = CreateThread(NULL,0,WinControlMain,NULL,0,NULL);
38  CloseHandle(hThread);
39
40   
41
42  init();
43  glutDisplayFunc(display);
44  glutMainLoop();
45  return 0;
46 }

文件2:ControlPad.cpp

01 #include <windows.h>
02 #include <stdio.h>
03 #include "ControlPad.h"
04
05 LRESULT CALLBACK WinProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
06 {
07  switch(uMsg)
08  {
09  case WM_CHAR:
10   char szChar[20];
11   //sprintf(szChar,"char code is %d",wParam);
12   MessageBox(hwnd,szChar,"char",0);
13   break;
14  case WM_DESTROY:
15   PostQuitMessage(0);
16   break;
17  default:
18   return DefWindowProc(hwnd,uMsg,wParam,lParam);
19  }
20  return 0;
21 }
22
23 DWORD WINAPI WinControlMain(LPVOID lpParameter)
24 {
25  WNDCLASS wndcls;
26  wndcls.cbClsExtra = 0;
27  wndcls.cbWndExtra = 0;
28  wndcls.hbrBackground = (HBRUSH)COLOR_BACKGROUND;//GetStockObject(BLACK_BRUSH);
29  wndcls.hCursor = LoadCursor(NULL,IDC_CROSS);
30  wndcls.hIcon = LoadIcon(NULL,IDI_ERROR);
31  wndcls.hInstance = 0;//hInstance;
32  wndcls.lpfnWndProc = WinProc;
33  wndcls.lpszClassName = "GL Control";
34  wndcls.lpszMenuName = NULL;
35  wndcls.style = CS_HREDRAW | CS_VREDRAW;
36  RegisterClass(&wndcls);
37
38  HWND hwnd;
39  hwnd = CreateWindow("GL Control","GL Control",WS_OVERLAPPEDWINDOW,0,0,600,400,NULL,NULL,0,NULL);
40
41  ShowWindow(hwnd,SW_SHOWNORMAL);
42  UpdateWindow(hwnd);
43
44  MSG msg;
45  while(GetMessage(&msg,NULL,0,0))
46  {
47   TranslateMessage(&msg);
48   DispatchMessage(&msg);
49  }
50  return msg.wParam;
51 }

当然我这里写的比较简单,做个示范提供个思路而已,等待以后慢慢扩展。我故意避开mfc,考虑到以后效率问题^^,其实在mfc里可以更简单的做这个,但是咱们提倡直接win32api。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值