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(HWND, UINT, WPARAM, LPARAM);  // 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.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // 真正精细的透视修正 

  90.     return TRUE;   // 初始化 OK




  91. //绘制场景功能
  92. int OpenGLFrameWork::DrawGLScene(GLvoid)            // 从这里开始进行所有的绘制
  93. {     
  94.     //第一课内容
  95.     //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    // 清除屏幕和深度缓存
  96.     //glLoadIdentity();              // 重置当前的模型观察矩阵
  97.     //return TRUE;                   // 一切 OK
  98.     //第二课到第四课
  99.     return this->DrawGLScene_4();



  100. // 正常销毁窗口功能
  101. GLvoid OpenGLFrameWork::KillGLWindow(GLvoid)  
  102. {   
  103.     if (fullscreen)  // 我们处于全屏模式吗?
  104.     {  
  105.         ChangeDisplaySettings(NULL,0); // 是的话,切换回桌面
  106.         ShowCursor(TRUE); // 显示鼠标指针
  107.     }
  108.     if (!wglMakeCurrent(NULL,NULL)) // 我们能否释放DC和RC描述表?
  109.     {  
  110.         MessageBox(NULL,(LPCWSTR)"Release Of DC And RC Failed.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 

  111. MB_ICONINFORMATION);
  112.     }
  113.     if (!wglDeleteContext(hRC)) // 我们能否删除RC?
  114.     {  
  115.         MessageBox(NULL,(LPCWSTR)"Release Rendering Context Failed.",(LPCWSTR)"SHUTDOWN 

  116. ERROR",MB_OK | MB_ICONINFORMATION);
  117.     }
  118.     hRC=NULL;  // 将RC设为 NULL
  119.     if (hDC && !ReleaseDC(hWnd,hDC))     // 我们能否释放 DC?
  120.     {
  121.         MessageBox(NULL,(LPCWSTR)"Release Device Context Failed.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 

  122. MB_ICONINFORMATION);
  123.         hDC=NULL;                        // 将 DC 设为 NULL
  124.     }
  125.     if (hWnd && !DestroyWindow(hWnd))    // 能否销毁窗口?
  126.     {
  127.         MessageBox(NULL,(LPCWSTR)"Could Not Release hWnd.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 

  128. MB_ICONINFORMATION);
  129.         hWnd=NULL;                        // 将 hWnd 设为 NULL
  130.     }

  131.     if (!UnregisterClass((LPCWSTR)"OpenGL",hInstance))    // 能否注销类?
  132.     {
  133.         MessageBox(NULL,(LPCWSTR)"Could Not Unregister Class.",(LPCWSTR)"SHUTDOWN ERROR",MB_OK | 

  134. MB_ICONINFORMATION);
  135.         hInstance=NULL;                // 将 hInstance 设为 NULL
  136.     }

  137. }


  138. //创建窗口功能
  139. BOOL OpenGLFrameWork::CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
  140. {
  141.     GLuint PixelFormat;  // 保存查找匹配的结果 
  142.     WNDCLASS wc;         // 窗口类结构 

  143.     DWORD dwExStyle;     // 扩展窗口风格
  144.     DWORD dwStyle;       // 窗口风格

  145.     RECT WindowRect;                 // 取得矩形的左上角和右下角的坐标值
  146.     WindowRect.left=(long)0;         // 将Left   设为 0
  147.     WindowRect.right=(long)width;    // 将Right  设为要求的宽度
  148.     WindowRect.top=(long)0;          // 将Top    设为 0 
  149.     WindowRect.bottom=(long)height;  // 将Bottom 设为要求的高度   

  150.     this->fullscreen=fullscreenflag;  // 设置全局全屏标志 

  151.     hInstance = GetModuleHandle(NULL);                // 取得我们窗口的实例  
  152.     wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;    // 移动时重画,并为窗口取得DC
  153.     wc.lpfnWndProc = (WNDPROC) WndProc;               // WndProc处理消息
  154.     wc.cbClsExtra = 0;                                // 无额外窗口数据
  155.     wc.cbWndExtra = 0;                                // 无额外窗口数据
  156.     wc.hInstance = this->hInstance;                         // 设置实例
  157.     wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);           // 装入缺省图标
  158.     wc.hCursor = LoadCursor(NULL, IDC_ARROW);         // 装入鼠标指针
  159.     wc.hbrBackground = NULL;                          // GL不需要背景
  160.     wc.lpszMenuName = NULL;                           // 不需要菜单
  161.     wc.lpszClassName = (LPCWSTR)"OpenGL";                      // 设定类名字 

  162.     if (!RegisterClass(&wc))                          // 尝试注册窗口类
  163.     {
  164.         MessageBox(NULL,(LPCWSTR)"Failed To Register The Window Class.",

  165. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  166.         return FALSE;                                 //退出并返回FALSE
  167.     }

  168.     if (this->fullscreen)                          // 要尝试全屏模式吗?
  169.     {
  170.         DEVMODE dmScreenSettings;// 设备模式
  171.         memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // 确保内存分配
  172.         dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Devmode 结构的大小
  173.         dmScreenSettings.dmPelsWidth = width; // 所选屏幕宽度
  174.         dmScreenSettings.dmPelsHeight = height; // 所选屏幕高度
  175.         dmScreenSettings.dmBitsPerPel = bits; // 每象素所选的色彩深度
  176.         dmScreenSettings.dmFields = DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
  177.         //尝试设置显示模式并返回结果。注: CDS_FULLSCREEN 移去了状态条。
  178.         if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
  179.         {
  180.             // 若模式失败,提供两个选项:退出或在窗口内运行。
  181.             if (MessageBox(NULL,(LPCWSTR)"The Requested Fullscreen Mode Is Not Supported By/n 

  182. Your Video Card. Use Windowed Mode Instead?",(LPCWSTR)"NeHe GL", MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
  183.             {
  184.                 this->fullscreen=FALSE;// 选择窗口模式(Fullscreen=FALSE)
  185.             }
  186.             else
  187.             {
  188.                 // Pop Up A Message Box Letting User Know The Program Is Closing.
  189.                 MessageBox(NULL,(LPCWSTR)"Program Will Now Close.",

  190. (LPCWSTR)"ERROR",MB_OK|MB_ICONSTOP);
  191.                 return FALSE;//退出并返回 FALSE
  192.             }
  193.         }
  194.     }
  195.     if(this->fullscreen)// 仍处于全屏模式吗?
  196.     {
  197.         dwExStyle=WS_EX_APPWINDOW;//扩展窗体风格
  198.         dwStyle=WS_POPUP;//窗体风格
  199.         ShowCursor(FALSE);// 隐藏鼠标指针
  200.     }
  201.     else
  202.     {
  203.         dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;// 扩展窗体风格
  204.         dwStyle=WS_OVERLAPPEDWINDOW;// 窗体风格
  205.     }
  206.     AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);// 调整窗口达到真正要求的大小
  207.     if (!(hWnd=CreateWindowEx(dwExStyle,// 扩展窗体风格
  208.         (LPCWSTR)"OpenGL",//类名字
  209.         (LPCWSTR)title,//窗口标题
  210.         WS_CLIPSIBLINGS|// 必须的窗体风格属性
  211.         WS_CLIPCHILDREN|// 必须的窗体风格属性
  212.         dwStyle,// 选择的窗体属性
  213.         0,0,//窗口位置
  214.         WindowRect.right-WindowRect.left,// 计算调整好的窗口宽度
  215.         WindowRect.bottom-WindowRect.top,// 计算调整好的窗口高度
  216.         NULL,// 无父窗口
  217.         NULL,// 无菜单
  218.         hInstance,// 实例
  219.         NULL)))  // 不向WM_CREATE传递任何东东
  220.     {
  221.         this->KillGLWindow();// 重置显示区
  222.         MessageBox(NULL,(LPCWSTR)"Window Creation Error.",

  223. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  224.         return FALSE;// 返回 FALSE
  225.     }
  226.     static PIXELFORMATDESCRIPTOR pfd=
  227.     {
  228.         sizeof(PIXELFORMATDESCRIPTOR),   //上诉格式描述符的大小
  229.         1,                               // 版本号
  230.         PFD_DRAW_TO_WINDOW |             // 格式必须支持窗口
  231.         PFD_SUPPORT_OPENGL |             // 格式必须支持OpenGL
  232.         PFD_DOUBLEBUFFER,                // 必须支持双缓冲
  233.         PFD_TYPE_RGBA,                   // 申请 RGBA 格式
  234.         bits,                            // 选定色彩深度
  235.         0, 0, 0, 0, 0, 0,                // 忽略的色彩位
  236.         0,                               // 无Alpha缓存
  237.         0,                               // 忽略Shift Bit
  238.         0,                               // 无聚集缓存
  239.         0, 0, 0, 0,                      // 忽略聚集位
  240.         16,                              // 16位 Z-缓存 (深度缓存)
  241.         0,                               // 无模板缓存
  242.         0,                               // 无辅助缓存
  243.         PFD_MAIN_PLANE,                  // 主绘图层
  244.         0,                               // 保留
  245.         0, 0, 0                          // 忽略层遮罩
  246.     };  //pfd 告诉窗口我们所希望的东东
  247.     if (!(this->hDC=GetDC(this->hWnd)))  //取得设备描述表了么?
  248.     {
  249.         this->KillGLWindow();                                                              // 重

  250. 置显示区
  251.         MessageBox(NULL,(LPCWSTR)"Can't Create A GL Device Context.",

  252. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  253.         return FALSE;                                                                // 返回 

  254. FALSE
  255.     }

  256.     if (!(PixelFormat=ChoosePixelFormat(this->hDC,&pfd))) // Windows 找到相应的象素格式了吗?
  257.     {
  258.         this->KillGLWindow();                                                             // 重置

  259. 显示区
  260.         MessageBox(NULL,(LPCWSTR)"Can't Find A Suitable PixelFormat.",

  261. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  262.         return FALSE;                                                               // 返回 FALSE
  263.     }

  264.     if(!SetPixelFormat(this->hDC,PixelFormat,&pfd)) // 能够设置象素格式么?
  265.     {
  266.         this->KillGLWindow();                                                             // 重置

  267. 显示区
  268.         MessageBox(NULL,(LPCWSTR)"Can't Set The PixelFormat.",

  269. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  270.         return FALSE;                                                               // 返回 FALSE
  271.     }

  272.     if (!(hRC=wglCreateContext(this->hDC)))   // 能否取得着色描述表?
  273.     {
  274.         this->KillGLWindow();                                                             // 重置

  275. 显示区
  276.         MessageBox(NULL,(LPCWSTR)"Can't Create A GL Rendering Context.",

  277. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  278.         return FALSE;                                                               // 返回 FALSE
  279.     }

  280.     if(!wglMakeCurrent(this->hDC,this->hRC)) // 尝试激活着色描述表
  281.     {
  282.         this->KillGLWindow();                                                             // 重置

  283. 显示区
  284.         MessageBox(NULL,(LPCWSTR)"Can't Activate The GL Rendering Context.",

  285. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  286.         return FALSE;                                                               // 返回 FALSE
  287.     }

  288.     ShowWindow(this->hWnd,SW_SHOW);// 显示窗口
  289.     SetForegroundWindow(this->hWnd);// 略略提高优先级
  290.     SetFocus(this->hWnd);// 设置键盘的焦点至此窗口
  291.     this->ReSizeGLScene(width, height); // 设置透视 GL 屏幕  

  292.     if (!this->InitGL())                                                              // 初始化新建的

  293. GL窗口
  294.     {
  295.         this->KillGLWindow();                                                             // 重置

  296. 显示区
  297.         MessageBox(NULL,(LPCWSTR)"Initialization Failed.",

  298. (LPCWSTR)"ERROR",MB_OK|MB_ICONEXCLAMATION);
  299.         return FALSE;                                                               // 返回 FALSE
  300.     }

  301.     return TRUE; // 成功

  302. }


  303. //第一课内容  框架
  304. //第二课内容  三角形/正方形
  305. //第三课内容  着色
  306. //第四课内容  转起来
  307. int OpenGLFrameWork::DrawGLScene_4(GLvoid) // 此过程中包括所有的绘制代码
  308. {
  309.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清除屏幕及深度缓存
  310.     glLoadIdentity(); // 重置视口

  311.     glTranslatef(-1.5f,0.0f,-6.0f); // 左移 1.5 单位,并移入屏幕 6.0

  312.     glRotatef(rtri,0.0f,1.0f,0.0f); // 绕Y轴旋转三角形 ( 新增 )

  313.     glBegin(GL_TRIANGLES); // 绘制三角形
  314.     glColor3f(1.0f,0.0f,0.0f); //设置当前色为红色
  315.     glVertex3f( 0.0f, 1.0f, 0.0f); // 上顶点

  316.     glColor3f(0.0f,1.0f,0.0f);//设置当前色为绿色
  317.     glVertex3f(-1.0f,-1.0f, 0.0f); // 左下

  318.     glColor3f(0.0f,0.0f,1.0f);//设置当前色为蓝色
  319.     glVertex3f( 1.0f,-1.0f, 0.0f); // 右下
  320.     glEnd(); // 三角形绘制结束

  321.     //glTranslatef(3.0f,0.0f,0.0f); // 右移3单位

  322.     glLoadIdentity(); // 重置模型观察矩阵
  323.     glTranslatef(1.5f,0.0f,-6.0f); // 右移1.5单位,并移入屏幕 6.0
  324.     glRotatef(rquad,0.0f,0.0f,1.0f); // 绕X轴旋转四边形 ( 新增 )


  325.     glColor3f(0.5f,0.5f,1.0f); // 一次性将当前色设置为蓝色
  326.     glBegin(GL_QUADS); // 绘制正方形
  327.     glVertex3f(-1.0f, 1.0f, 0.0f); // 左上
  328.     glVertex3f( 1.0f, 1.0f, 0.0f); // 右上

  329.     glColor3f(1.0f,0.0f,0.0f); //设置当前色为红色
  330.     glVertex3f( 1.0f,-1.0f, 0.0f); // 左下
  331.     glVertex3f(-1.0f,-1.0f, 0.0f); // 右下
  332.     glEnd(); // 正方形绘制结束

  333.     this->rtri-=0.5f;   // 增加三角形的旋转变量(新增)
  334.     this->rquad+=0.35f; // 减少四边形的旋转变量(新增)


  335.     return TRUE; // 继续运行

  336. }