学习OpenGL总结一

来源:互联网 发布:chimee蒙文软件下载 编辑:程序博客网 时间:2024/04/29 19:56
  1. 学习OpenGL总结一
  2. OpenGL_FirstWin32.h 内容如下:
  3. #pragma once
  4. #include "resource.h"
  5. // Open GL 头文件: vp;hsg date:2008_12_26
  6. #include <gl/gl.h>         //OpenGL32库的头文件
  7. #include <gl/glu.h>        //GLu32库的头文件
  8. LRESULT CALLBACK WndProc(HWNDUINTWPARAMLPARAM);  // WndProc的定义
  9. //定义OpenGL框架类
  10. class OpenGLFrameWork
  11. {
  12.     public :
  13.           OpenGLFrameWork();
  14.           ~OpenGLFrameWork();
  15.     public:
  16.        GLvoid ReSizeGLScene(GLsizei width, GLsizei height);    // 重置并初始化GL窗口大小
  17.        virtual int InitGL(GLvoid);
  18.        virtual int DrawGLScene(GLvoid);            // 从这里开始进行所有的绘制
  19.        int DrawGLScene_4(GLvoid);
  20.        GLvoid KillGLWindow(GLvoid);        // 正常销毁窗口
  21.        virtual BOOL CreateGLWindow(char* title, int width, int height, int bits, bool 
  22. fullscreenflag);
  23.     protected:
  24.         GLfloat rtri; // 用于三角形的角度 ( 新增 )
  25.         GLfloat rquad; // 用于四边形的角度 ( 新增 )
  26.         GLfloat xrot; // X 旋转量 ( 新增 )
  27.         GLfloat yrot; // Y 旋转量 ( 新增 )
  28.         GLfloat zrot; // Z 旋转量 ( 新增 )
  29.         GLuint texture[1]; // 存储一个纹理 ( 新增 ) 
  30.    public :
  31.         HGLRC hRC;        // 永久着色描述表
  32.         HDC hDC;          // 私有GDI设备描述表
  33.         HWND hWnd;        // 保存我们的窗口句柄
  34.         HINSTANCE hInstance;   // 保存程序的实例  
  35.         bool keys[256];         // 用于键盘例程的数组
  36.         bool active;       // 窗口的活动标志,缺省为TRUE
  37.         bool fullscreen;   // 全屏标志缺省设定成全屏模式
  38. };
  39. //实现方法 OpenGL框架类
  40. //初始化类
  41. OpenGLFrameWork::OpenGLFrameWork()
  42. {
  43.         this->hRC=NULL;        // 永久着色描述表
  44.         this->hDC=NULL;          // 私有GDI设备描述表
  45.         this->hWnd=NULL;        // 保存我们的窗口句柄
  46.         this->active=TRUE;       // 窗口的活动标志,缺省为TRUE
  47.         this->fullscreen=FALSE;   // 全屏标志缺省设定成全屏模式TRUE
  48.         for(int i=0;i<256;i++)
  49.         {
  50.             this->keys[i]=FALSE;
  51.         }
  52.         rtri=0;
  53.         rquad=0;
  54.         xrot=0;
  55.         yrot=0;
  56.         zrot=0;
  57.         //texture=;
  58. };
  59. OpenGLFrameWork::~OpenGLFrameWork() 
  60. {
  61.     //this->KillGLWindow();
  62. }
  63. //重设GLScene大小功能
  64. GLvoid OpenGLFrameWork::ReSizeGLScene(GLsizei width, GLsizei height)    // 重置并初始化GL窗口大小
  65. {
  66.     if (height==0)    // 防止被零除                     
  67.     {
  68.         height=1;     // 将Height设为1
  69.     }
  70.     glViewport(0, 0, width, height);  // 重置当前的视口(Viewport) 
  71.     glMatrixMode(GL_PROJECTION);
  72.     glLoadIdentity();
  73.     // 计算窗口的外观比例
  74.     gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
  75.     glMatrixMode(GL_MODELVIEW);
  76.     glLoadIdentity();
  77. //初始化GL功能
  78. int OpenGLFrameWork::InitGL(GLvoid)
  79.     //if (!LoadGLTextures()) // 调用纹理载入子例程( 新增 )
  80.     //{
  81.     //  return FALSE; // 如果未能载入,返回FALSE( 新增 )
  82.     //}
  83.     //glEnable(GL_TEXTURE_2D); // 启用纹理映射( 新增 )
  84.     glShadeModel(GL_SMOOTH);    //启用smooth shading(阴影平滑)
  85.     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);  // 黑色背景 
  86.     glClearDepth(1.0f);         // 设置深度缓存
  87.     glEnable(GL_DEPTH_TEST);    // 启用深度测试
  88.     glDepthFunc(GL_LEQUAL);     // 所作深度测试的类型
  89.     
  90.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // 真正精细的透视修正 
  91.     return TRUE;   // 初始化 OK
  92. //绘制场景功能
  93. int OpenGLFrameWork::DrawGLScene(GLvoid)            // 从这里开始进行所有的绘制
  94. {     
  95.     //第一课内容
  96.     //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清除屏幕和深度缓存
  97.     //glLoadIdentity();              // 重置当前的模型观察矩阵
  98.     //return TRUE;                   // 一切 OK
  99.     //第二课到第四课
  100.     return this->DrawGLScene_4();
  101. // 正常销毁窗口功能
  102. GLvoid OpenGLFrameWork::KillGLWindow(GLvoid)  
  103. {   
  104.     if (fullscreen)  // 我们处于全屏模式吗?
  105.     {  
  106.         ChangeDisplaySettings(NULL,0); // 是的话,切换回桌面
  107.         ShowCursor(TRUE); // 显示鼠标指针
  108.     }
  109.     if (!wglMakeCurrent(NULL,NULL)) // 我们能否释放DC和RC描述表?
  110.     {  
  111.         MessageBox(NULL,(LPCWSTR)"Release Of DC And RC Failed.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 
  112. MB_ICONINFORMATION);
  113.     }
  114.     if (!wglDeleteContext(hRC)) // 我们能否删除RC?
  115.     {  
  116.         MessageBox(NULL,(LPCWSTR)"Release Rendering Context Failed.",(LPCWSTR)"SHUTDOWN 
  117. ERROR",MB_OK | MB_ICONINFORMATION);
  118.     }
  119.     hRC=NULL;  // 将RC设为 NULL
  120.     if (hDC && !ReleaseDC(hWnd,hDC))     // 我们能否释放 DC?
  121.     {
  122.         MessageBox(NULL,(LPCWSTR)"Release Device Context Failed.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 
  123. MB_ICONINFORMATION);
  124.         hDC=NULL;                        // 将 DC 设为 NULL
  125.     }
  126.     if (hWnd && !DestroyWindow(hWnd))    // 能否销毁窗口?
  127.     {
  128.         MessageBox(NULL,(LPCWSTR)"Could Not Release hWnd.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 
  129. MB_ICONINFORMATION);
  130.         hWnd=NULL;                        // 将 hWnd 设为 NULL
  131.     }
  132.     if (!UnregisterClass((LPCWSTR)"OpenGL",hInstance))    // 能否注销类?
  133.     {
  134.         MessageBox(NULL,(LPCWSTR)"Could Not Unregister Class.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 
  135. MB_ICONINFORMATION);
  136.         hInstance=NULL;                // 将 hInstance 设为 NULL
  137.     }
  138. }
  139. //创建窗口功能
  140. BOOL OpenGLFrameWork::CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
  141. {
  142.     GLuint PixelFormat;  // 保存查找匹配的结果 
  143.     WNDCLASS wc;         // 窗口类结构 
  144.     DWORD dwExStyle;     // 扩展窗口风格
  145.     DWORD dwStyle;       // 窗口风格
  146.      
  147.     RECT WindowRect;                 // 取得矩形的左上角和右下角的坐标值
  148.     WindowRect.left=(long)0;         // 将Left   设为 0
  149.     WindowRect.right=(long)width;    // 将Right  设为要求的宽度
  150.     WindowRect.top=(long)0;          // 将Top    设为 0 
  151.     WindowRect.bottom=(long)height;  // 将Bottom 设为要求的高度   
  152.     
  153.     this->fullscreen=fullscreenflag;  // 设置全局全屏标志 
  154.     
  155.     hInstance = GetModuleHandle(NULL);                // 取得我们窗口的实例  
  156.     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;    // 移动时重画,并为窗口取得DC
  157.     wc.lpfnWndProc = (WNDPROC) WndProc;               // WndProc处理消息
  158.     wc.cbClsExtra = 0;                                // 无额外窗口数据
  159.     wc.cbWndExtra = 0;                                // 无额外窗口数据
  160.     wc.hInstance = this->hInstance;                         // 设置实例
  161.     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);           // 装入缺省图标
  162.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);         // 装入鼠标指针
  163.     wc.hbrBackground = NULL;                          // GL不需要背景
  164.     wc.lpszMenuName = NULL;                           // 不需要菜单
  165.     wc.lpszClassName = (LPCWSTR)"OpenGL";                      // 设定类名字 
  166.     
  167.     if (!RegisterClass(&wc))                          // 尝试注册窗口类
  168.     {
  169.         MessageBox(NULL,(LPCWSTR)"Failed To Register The Window Class.",
  170. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  171.         return FALSE;                                 //退出并返回FALSE
  172.     }
  173.     if (this->fullscreen)                          // 要尝试全屏模式吗?
  174.     {
  175.         DEVMODE dmScreenSettings;// 设备模式
  176.         memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // 确保内存分配
  177.         dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Devmode 结构的大小
  178.         dmScreenSettings.dmPelsWidth = width; // 所选屏幕宽度
  179.         dmScreenSettings.dmPelsHeight = height; // 所选屏幕高度
  180.         dmScreenSettings.dmBitsPerPel = bits; // 每象素所选的色彩深度
  181.         dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
  182.         //尝试设置显示模式并返回结果。注: CDS_FULLSCREEN 移去了状态条。
  183.         if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
  184.         {
  185.             // 若模式失败,提供两个选项:退出或在窗口内运行。
  186.             if (MessageBox(NULL,(LPCWSTR)"The Requested Fullscreen Mode Is Not Supported By/n 
  187. Your Video Card. Use Windowed Mode Instead?",(LPCWSTR)"NeHe GL", MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
  188.             {
  189.                 this->fullscreen=FALSE;// 选择窗口模式(Fullscreen=FALSE)
  190.             }
  191.             else
  192.             {
  193.                 // Pop Up A Message Box Letting User Know The Program Is Closing.
  194.                 MessageBox(NULL,(LPCWSTR)"Program Will Now Close.",
  195. (LPCWSTR)"ERROR",MB_OK|MB_ICONSTOP);
  196.                 return FALSE;//退出并返回 FALSE
  197.             }
  198.         }
  199.     }
  200.     if(this->fullscreen)// 仍处于全屏模式吗?
  201.     {
  202.         dwExStyle=WS_EX_APPWINDOW;//扩展窗体风格
  203.         dwStyle=WS_POPUP;//窗体风格
  204.         ShowCursor(FALSE);// 隐藏鼠标指针
  205.     }
  206.     else
  207.     {
  208.         dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;// 扩展窗体风格
  209.         dwStyle=WS_OVERLAPPEDWINDOW;// 窗体风格
  210.     }
  211.     AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);// 调整窗口达到真正要求的大小
  212.     if (!(hWnd=CreateWindowEx(dwExStyle,// 扩展窗体风格
  213.         (LPCWSTR)"OpenGL",//类名字
  214.         (LPCWSTR)title,//窗口标题
  215.         WS_CLIPSIBLINGS|// 必须的窗体风格属性
  216.         WS_CLIPCHILDREN|// 必须的窗体风格属性
  217.         dwStyle,// 选择的窗体属性
  218.         0,0,//窗口位置
  219.         WindowRect.right-WindowRect.left,// 计算调整好的窗口宽度
  220.         WindowRect.bottom-WindowRect.top,// 计算调整好的窗口高度
  221.         NULL,// 无父窗口
  222.         NULL,// 无菜单
  223.         hInstance,// 实例
  224.         NULL)))  // 不向WM_CREATE传递任何东东
  225.     {
  226.         this->KillGLWindow();// 重置显示区
  227.         MessageBox(NULL,(LPCWSTR)"Window Creation Error.",
  228. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  229.         return FALSE;// 返回 FALSE
  230.     }
  231.     static PIXELFORMATDESCRIPTOR pfd=
  232.     {
  233.         sizeof(PIXELFORMATDESCRIPTOR),   //上诉格式描述符的大小
  234.         1,                               // 版本号
  235.         PFD_DRAW_TO_WINDOW |             // 格式必须支持窗口
  236.         PFD_SUPPORT_OPENGL |             // 格式必须支持OpenGL
  237.         PFD_DOUBLEBUFFER,                // 必须支持双缓冲
  238.         PFD_TYPE_RGBA,                   // 申请 RGBA 格式
  239.         bits,                            // 选定色彩深度
  240.         0, 0, 0, 0, 0, 0,                // 忽略的色彩位
  241.         0,                               // 无Alpha缓存
  242.         0,                               // 忽略Shift Bit
  243.         0,                               // 无聚集缓存
  244.         0, 0, 0, 0,                      // 忽略聚集位
  245.         16,                              // 16位 Z-缓存 (深度缓存)
  246.         0,                               // 无模板缓存
  247.         0,                               // 无辅助缓存
  248.         PFD_MAIN_PLANE,                  // 主绘图层
  249.         0,                               // 保留
  250.         0, 0, 0                          // 忽略层遮罩
  251.     };  //pfd 告诉窗口我们所希望的东东
  252.     if (!(this->hDC=GetDC(this->hWnd)))  //取得设备描述表了么?
  253.     {
  254.         this->KillGLWindow();                                                              // 重
  255. 置显示区
  256.         MessageBox(NULL,(LPCWSTR)"Can't Create A GL Device Context.",
  257. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  258.         return FALSE;                                                                // 返回 
  259. FALSE
  260.     }
  261.     if (!(PixelFormat=ChoosePixelFormat(this->hDC,&pfd))) // Windows 找到相应的象素格式了吗?
  262.     {
  263.         this->KillGLWindow();                                                             // 重置
  264. 显示区
  265.         MessageBox(NULL,(LPCWSTR)"Can't Find A Suitable PixelFormat.",
  266. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  267.         return FALSE;                                                               // 返回 FALSE
  268.     }
  269.     if(!SetPixelFormat(this->hDC,PixelFormat,&pfd)) // 能够设置象素格式么?
  270.     {
  271.         this->KillGLWindow();                                                             // 重置
  272. 显示区
  273.         MessageBox(NULL,(LPCWSTR)"Can't Set The PixelFormat.",
  274. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  275.         return FALSE;                                                               // 返回 FALSE
  276.     }
  277.     if (!(hRC=wglCreateContext(this->hDC)))   // 能否取得着色描述表?
  278.     {
  279.         this->KillGLWindow();                                                             // 重置
  280. 显示区
  281.         MessageBox(NULL,(LPCWSTR)"Can't Create A GL Rendering Context.",
  282. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  283.         return FALSE;                                                               // 返回 FALSE
  284.     }
  285.     if(!wglMakeCurrent(this->hDC,this->hRC)) // 尝试激活着色描述表
  286.     {
  287.         this->KillGLWindow();                                                             // 重置
  288. 显示区
  289.         MessageBox(NULL,(LPCWSTR)"Can't Activate The GL Rendering Context.",
  290. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  291.         return FALSE;                                                               // 返回 FALSE
  292.     }
  293.     ShowWindow(this->hWnd,SW_SHOW);// 显示窗口
  294.     SetForegroundWindow(this->hWnd);// 略略提高优先级
  295.     SetFocus(this->hWnd);// 设置键盘的焦点至此窗口
  296.     this->ReSizeGLScene(width, height); // 设置透视 GL 屏幕  
  297.     
  298.     if (!this->InitGL())                                                              // 初始化新建的
  299. GL窗口
  300.     {
  301.         this->KillGLWindow();                                                             // 重置
  302. 显示区
  303.         MessageBox(NULL,(LPCWSTR)"Initialization Failed.",
  304. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  305.         return FALSE;                                                               // 返回 FALSE
  306.     }
  307.     
  308.     return TRUE; // 成功
  309. }
  310. //第一课内容  框架
  311. //第二课内容  三角形/正方形
  312. //第三课内容  着色
  313. //第四课内容  转起来
  314. int OpenGLFrameWork::DrawGLScene_4(GLvoid) // 此过程中包括所有的绘制代码
  315. {
  316.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
  317.     glLoadIdentity(); // 重置视口
  318.     glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0
  319.     glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转三角形 ( 新增 )
  320.     glBegin(GL_TRIANGLES); // 绘制三角形
  321.     glColor3f(1.0f,0.0f,0.0f); //设置当前色为红色
  322.     glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点
  323.     glColor3f(0.0f,1.0f,0.0f);//设置当前色为绿色
  324.     glVertex3f(-1.0f,-1.0f, 0.0f); // 左下
  325.     glColor3f(0.0f,0.0f,1.0f);//设置当前色为蓝色
  326.     glVertex3f( 1.0f,-1.0f, 0.0f); // 右下
  327.     glEnd(); // 三角形绘制结束
  328.     //glTranslatef(3.0f,0.0f,0.0f); // 右移3单位
  329.     glLoadIdentity(); // 重置模型观察矩阵
  330.     glTranslatef(1.5f,0.0f,-6.0f); // 右移1.5单位,并移入屏幕 6.0
  331.     glRotatef(rquad,0.0f,0.0f,1.0f); // 绕X轴旋转四边形 ( 新增 )
  332.     glColor3f(0.5f,0.5f,1.0f); // 一次性将当前色设置为蓝色
  333.     glBegin(GL_QUADS); // 绘制正方形
  334.     glVertex3f(-1.0f, 1.0f, 0.0f); // 左上
  335.     glVertex3f( 1.0f, 1.0f, 0.0f); // 右上
  336.     glColor3f(1.0f,0.0f,0.0f); //设置当前色为红色
  337.     glVertex3f( 1.0f,-1.0f, 0.0f); // 左下
  338.     glVertex3f(-1.0f,-1.0f, 0.0f); // 右下
  339.     glEnd(); // 正方形绘制结束
  340.     this->rtri-=0.5f;   // 增加三角形的旋转变量(新增)
  341.     this->rquad+=0.35f; // 减少四边形的旋转变量(新增)
  342.     return TRUE; // 继续运行
  343. }