zoukankan      html  css  js  c++  java
  • [OpenGL(Win32)] 3D 轮廓字体

    GLUT库(v1.1):https://files.cnblogs.com/hcbin/glutdlls37beta.zip

    注:暂时只支持英文

     

    //注:本人使用VS2008创建此程序
    /*
        1.VS2008->"新建"->"项目"->"Visual C++"->选择"空项目"->输入名称"test.sln"
        2.在test项目的"解决方案资源管理器"的"源文件"上->右击添加新的"C++文件"->输入名称"test.cpp"或添加已有的cpp文件
        3.双击打开test.cpp文件->在菜单栏上选择"项目"->"test属性"->"配置属性"->"C/C++"->"代码生成"->在右边将"运行时库"改为:MTd[含大量调试信息]/MT(一般情况下Debug用MTd, Release用MT)
        [第3步是为了生成的程序可以在其它没有安装VS2008的电脑上运行, 没有设置会有错误警告]
    */

    /*****************************************新添加的代码*****************************************/
    #include 
    <stdio.h>                                                   //标准输入/输出库的头文件
    #include <math.h>                                                    //数学库
    #include <stdarg.h>                                                  //用来定义可变参数的头文件
    /*
    *********************************************************************************************/
    #include 
    <GL/glut.h>                                                 //包含OpenGL实用库


    HDC       hDC   
    = NULL;                                              //窗口着色描述表句柄
    HWND      hWnd  = NULL;                                              //保存窗口句柄
    HGLRC     hGLRC = NULL;                                              //OpenGL渲染描述表句柄
    HINSTANCE hInstance;                                                 //保存程序的实例

    BOOL keys[
    256];                                                      //保存键盘按键的数组
    BOOL active     = TRUE;                                              //窗口的活动标志, 缺省为TRUE
    BOOL fullscreen = TRUE;                                              //全屏标志, 缺省为全屏模式
    UINT winWidth   = 640,                                               //窗体宽度
         winHeight  = 480,                                               //窗体高度
         winBits    = 16;                                                //颜色深度(可选8/16/32)

    /*****************************************新添加的代码*****************************************/
    GLuint 
    base;                                                         //绘制字体的显示列表的开始位置
    GLYPHMETRICSFLOAT gmf[256];                                          //保存256个轮廓字体显示列表中对应的每一个列表的位置和方向的信息

    void BuildFont(){
        HFONT font, oldfont;                                             
    //字体句柄, 旧的字体句柄

        
    base = glGenLists(256);                                          //创建256个显示列表
        font = CreateFont(                                               //创建字体
            -24,                                                         //字体高度(告诉Windows寻找基于CHARACTER高度的字体.如果是正数, 就寻找基于CELL的高度相匹配的字体)
            0,                                                           //字体宽度(使用默认值)
            0,                                                           //字体的旋转角度Angle Of Escapement
            0,                                                           //字体底线的旋转角度Orientation Angle
            FW_BOLD,                                                     //字体的重量(0-1000)[FW_DONTCARE是0, FW_NORMAL是400, FW_BOLD是700, FW_BLACK是900]
            FALSE,                                                       //是否使用斜体
            FALSE,                                                       //是否使用下划线
            FALSE,                                                       //是否使用删除线
            ANSI_CHARSET,                                                //设置字符集
            OUT_TT_PRECIS,                                               //输出精度
            CLIP_DEFAULT_PRECIS,                                         //裁剪精度
            ANTIALIASED_QUALITY,                                         //输出质量
            DEFAULT_PITCH | FF_DONTCARE,                                 //Pitch And Family
            "Times New Roman"                                            //字体名称
        );

        oldfont 
    = (HFONT)SelectObject(hDC, font);                        //选择需要的字体
        wglUseFontOutlines(                                              //使用Windows的wgl函数来创建字体
            hDC,                                                         //设置当前窗口设备描述表的句柄
            0,                                                           //用于创建显示列表字体的第1个字符的ASCII值
            255,                                                         //字符数
            base,                                                        //第1个显示列表的名称
            0.0f,                                                        //字体的光滑度, 越小越光滑, 0.0为最光滑的状态
            0.2f,                                                        //在Z方向突出的距离(即轮廓字体的厚度)
            WGL_FONT_POLYGONS,                                           //使用多边形来生成字符, 每个顶点具有独立的法线(WGL_FONT_LINES:使用线形生成字符)
            gmf                                                          //一个接收字形度量数据的数组的地址, 每个数组元素用它对应的显示列表字符的数据填充
        );
        SelectObject(hDC, oldfont);                                      
    //选择原来的字体
        DeleteObject(font);                                              //删除字体
    }

    void glPrintf(const char *fmt, ...){
        
    if(!fmt) return;                                                 //如果无输入则返回

        
    char text[256];                                                  //保存文字串
        va_list ap;                                                      //指向一个变量列表的指针
        va_start(ap, fmt);                                               //分析可变参数
            vsprintf(text, fmt, ap);                                     //把参数值写入字符串
        va_end(ap);                                                      //结束分析

        
    /////////////////////将字符串居中/////////////////////
        float length = 0.0f;                                             //保存字符串的长度
        for(UINT i=0;i<strlen(text);i++){                                //查找整个字符串的长度
            length += gmf[text[i]].gmfCellIncX;                          //计算轮廓后字符串的宽度(gmfCellIncX表示显示位置从已绘制上的上一个字符向右移动的真正距离)
        }
        glTranslatef(
    -length/2.0f0.0f0.0f);                          //把字符串置于最左边
        //////////////////////////////////////////////////////

        glPushAttrib(GL_LIST_BIT);                                       
    //把显示列表属性压入属性堆栈
        glListBase(base);                                                //设置显示列表的基础值为0
        glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);               //调用显示列表绘制字符串
        glPopAttrib();                                                   //弹出属性堆栈
    }

    void KillFont(){                                                     //删除显示列表
        glDeleteLists(base256);                                        //删除256个显示列表
    }
    /**********************************************************************************************/

    //重置OpenGL窗口大小
    GLvoid ReSizeGLScene(UINT width, UINT height){
        
    if(height <= 0){ height = 1; }                                   //防止被零除且防止负数存在

        glViewport(
    00, (GLsizei)width, (GLsizei)height);               //重置当前的视口

        glMatrixMode(GL_PROJECTION);                                     
    //选择投影矩阵
        glLoadIdentity();                                                //重置投影矩阵

        gluPerspective(
    45.0f, (GLdouble)width / (GLdouble)height, 0.1f100.0f); //设置视口的大小

        glMatrixMode(GL_MODELVIEW);                                      
    //选择模型观察矩阵
        glLoadIdentity();                                                //重置模型观察矩阵
    }

    //对OpenGL窗口进行初始化设置
    BOOL InitGL(GLvoid){
        glShadeModel(GL_SMOOTH);                                         
    //启用阴影平滑
        glClearColor(0.0f0.0f0.0f0.5f);                            //黑色背景
        glClearDepth(1.0f);                                              //设置深度缓存
        glEnable(GL_DEPTH_TEST);                                         //启用深度测试
        glDepthFunc(GL_LEQUAL);                                          //所作深度测试的类型
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);               //告诉系统对透视进行修正
    /*
    ****************************************新添加的代码*****************************************/
        BuildFont();                                                     
    //创建字体
    /*
    *********************************************************************************************/
        
    return TRUE;                                                     //初始化成功
    }

    //从这里开始进行所有的绘制
    BOOL DrawGLScene(GLvoid){
        glClear(GL_COLOR_BUFFER_BIT 
    | GL_DEPTH_BUFFER_BIT);              //清除屏幕和深度缓存
        glLoadIdentity();                                                //重置当前的模型观察矩阵
    /*
    ****************************************新添加的代码*****************************************/
        
    static GLfloat rot = 0.0f;                                       //旋转变量
        glTranslatef(0.0f0.0f-15.0f);                                //移入屏幕15个单位

        glRotatef(rot, 
    1.0f0.0f0.0f);                                //沿X轴旋转
        glRotated(rot * 1.5f0.0f1.0f0.0f);                         //沿Y轴旋转
        glRotatef(rot * 1.4f0.0f0.0f1.0f);                         //沿Z轴旋转

        
    /////////////////根据字体位置设置颜色/////////////////
        float r = 1.0f * float(cos(rot / 20.0f)),                        //红色
              g = 1.0f * float(sin(rot / 25.0f)),                        //绿色
              b = 1.0f - 0.5f * float(cos(rot / 17.0f));                 //蓝色
        glColor3f(r, g, b);                                              //设置颜色
        //////////////////////////////////////////////////////

        glPrintf(
    "3D Active OpenGL Text - %3.2f", rot / 50);             //输出文字到屏幕

        rot 
    += 0.5f;                                                     //增加旋转变量
    /*
    *********************************************************************************************/
        
    return TRUE;                                                     //绘制场景成功
    }

    //销毁窗口
    GLvoid KillGLWindow(GLvoid){
        
    if(fullscreen){                                                  //是否处于全屏模式
            ChangeDisplaySettings(NULL, 0);                              //切换回桌面
            ShowCursor(TRUE);                                            //显示鼠标指针
        }

        
    if(hGLRC){                                                       //是否拥有OpenGL描述表
            if(!wglMakeCurrent(NULL, NULL)){                             //是否已释放DC和RC描述表
                MessageBox(NULL, "释放DC或RC失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            }

            
    if(!wglDeleteContext(hGLRC)){                                //是否已删除RC
                MessageBox(NULL, "释放RC失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            }
            hGLRC 
    = NULL;                                                //将RC设为NULL
        }

        
    if(hDC && !ReleaseDC(hWnd, hDC)){                                //是否已释放DC
            MessageBox(NULL, "释放DC失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            hDC 
    = NULL;                                                  //将DC设为NULL
        }

        
    if(hWnd && !DestroyWindow(hWnd)){                                //是否已销毁窗口
            MessageBox(NULL, "销毁窗口失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            hWnd 
    = NULL;                                                 //将hWnd设为NULL
        }

        
    if(!UnregisterClass("OpenGL", hInstance)){                       //是否已注销类
            MessageBox(NULL, "注销窗口类失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            hInstance 
    = NULL;                                            //将hInstance设为NULL
        }
    /*****************************************新添加的代码*****************************************/
        KillFont();                                                      
    //删除字体
    /*
    *********************************************************************************************/
    }

    LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
        
    //WndProc(窗口的句柄, 窗口的消息, 附加的消息内容, 附加的消息内容)
        switch(uMsg){                                                    //检查Windows消息
            case WM_ACTIVATE:                                            //监视窗口激活消息
                if(!HIWORD(wParam)){                                     //检查最小化状态
                    active = TRUE;                                       //程序处于激活状态
                }else{
                    active 
    = FALSE;                                      //程序不再激活
                }
                
    return 0;                                                //返回消息循环

            
    case WM_CLOSE:                                               //收到Close消息
                PostQuitMessage(0);                                      //发出退出消息
                return 0;                                                //返回

            
    case WM_KEYDOWN:                                             //有键被按下
                keys[wParam] = TRUE;                                     //设为TRUE
                return 0;                                                //返回

            
    case WM_KEYUP:                                               //有键被放开
                keys[wParam] = FALSE;                                    //设为FALSE
                return 0;                                                //返回

            
    case WM_SIZE:                                                //调整OpenGL窗口大小
                ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));           //LoWord=Width, HiWord=Height
                return 0;                                                //返回

            
    case WM_SYSCOMMAND:                                          //系统中断命令
                switch(wParam){                                          //检查系统调用
                    case SC_SCREENSAVE:                                  //运行屏保
                    case SC_MONITORPOWER:                                //显示器要进入节电模式
                        return 0;                                        //阻止发生
                }
                
    break;                                                   //退出
        }
        
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }

    BOOL CreateGLWindow(
    const char *title, UINT width, UINT height, UINT bits, BOOL fullscreenflag){
        
    //CreateGLWindow(标题, 宽度, 高度, 颜色的位深, 是否使用全屏模式)
        GLuint   PixelFormat;                                            //保存查找匹配的结果
        DWORD    dwStyle, dwExStyle;                                     //窗口风格, 扩展窗口风格
        RECT     WindowRect;                                             //取得矩形的左上角和右下角的坐标值
        WNDCLASS wc;                                                     //窗口类结构

        hInstance  
    = GetModuleHandle(NULL);                              //取得我们窗口的实例
        fullscreen = fullscreenflag;                                     //设置全局全屏标志

        WindowRect.top    
    = (long)0;                                     //将Top    设为 0
        WindowRect.left   = (long)0;                                     //将Left   设为 0
        WindowRect.right  = (long)width;                                 //将Right  设为要求的宽度
        WindowRect.bottom = (long)height;                                //将Bottom 设为要求的高度

        
    /*
                像素格式明确了OpenGL绘制平面的特性, 如象素缓冲区是单缓冲还是双缓冲, 数据是 RGBA方式还是Color Index方式等.每个OpenGL显示设
            备一般用名为PIXELFORMATDESCRIPTOR的结构来表示某个的像素格式, 这个结构包含26个属性信息.Win32定义PIXELFORMATDESCRIPTOR如下所示:

            typedef struct tagPIXELFORMATDESCRIPTOR
            { //pfd
              WORD  nSize;           //是象素格式描述子结构的大小, sizeof(PIXELFORMATDESCRIPTOR)设定其值
              WORD  nVersion;        //是PIXELFORMATDESCRIPTOR结构的版本, 一般设为1
              DWORD dwFlags;         //是一组表明象素缓冲特性的标志位, 如缓冲是否支持GDI或OpenGL等
              BYTE  iPixelType;      //说明象素数据类型是RGBA还是颜色索引
              BYTE  cColorBits;      //每个颜色缓冲区中颜色位平面的数目, 对颜色索引方式是缓冲区大小
              BYTE  cRedBits;        //每个RGBA颜色缓冲区中红色位平面的数目
              BYTE  cRedShift;       //每个RGBA颜色缓冲区中红色位平面的偏移数
              BYTE  cGreenBits;      //每个RGBA颜色缓冲区中绿色位平面的数目
              BYTE  cGreenShift;     //每个RGBA颜色缓冲区中绿色位平面的偏移数
              BYTE  cBlueBits;       //每个RGBA颜色缓冲区中蓝色位平面的数目
              BYTE  cBlueShift;      //每个RGBA颜色缓冲区中蓝色位平面的偏移数
              BYTE  cAlphaBits;      //每个RGBA颜色缓冲区中alpha位平面的数目(保留的, 现不支持)
              BYTE  cAlphaShift;     //每个RGBA颜色缓冲区中alpha位平面的偏移数(保留的, 现不支持)
              BYTE  cAccumBits;      //累加缓冲区中全部位平面的数目
              BYTE  cAccumRedBits;   //累加缓冲区中红色位平面的数目
              BYTE  cAccumGreenBits; //累加缓冲区中绿色位平面的数目
              BYTE  cAccumBlueBits;  //累加缓冲区中蓝色位平面的数目
              BYTE  cAccumAlphaBits; //累加缓冲区中alpha位平面的数目
              BYTE  cDepthBits;      //Z(深度)缓冲区的深度
              BYTE  cStencilBits;    //模板缓冲区的深度
              BYTE  cAuxBuffers;     //轴向缓冲区的数量(一般1.0版本不支持)
              BYTE  iLayerType;      //被忽略, 为了一致性而包含的
              BYTE  bReserved;       //表层和底层平面的数量::位0-3表最多15层表层平面, 位4-7表底层
              DWORD dwLayerMask;     //被忽略, 为了一致性而包含的
              DWORD dwVisibleMask;   //是透明色彩的值(RGBA方式)或是一个底层平面的索引(Index)
              DWORD dwDamageMask;    //被忽略, 为了一致性而包含的
            } PIXELFORMATDESCRIPTOR;
        
    */

        
    const PIXELFORMATDESCRIPTOR pfd =                                //pfd告诉窗口使用的像素格式
        {
            
    sizeof(PIXELFORMATDESCRIPTOR),                               //上述格式描述符的大小
            1,                                                           //版本号
            PFD_DOUBLEBUFFER | PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,  //格式支持双缓冲, 支持窗口, 支持OpenGL
            PFD_TYPE_RGBA,                                               //申请RGBA格式
            bits,                                                        //选定色彩深度
            00000000,                                      //忽略的色彩位(前6位), 无Alpha缓存(第7位), 忽略Shift Bit(第8位)
            0,                                                           //无累加缓存
            0000,                                                  //忽略聚集位
            16,                                                          //16位Z-缓存(深度缓存) 
            0,                                                           //无蒙板缓存
            0,                                                           //无辅助缓存
            PFD_MAIN_PLANE,                                              //主绘图层
            0,                                                           //不使用重叠层
            000                                                      //忽略层遮罩
        };

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

        
    if(!RegisterClass(&wc)){                                         //尝试注册窗口类
            MessageBox(NULL, "注册窗口类错误!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //退出并返回FALSE
        }

        
    if(fullscreen){                                                  //尝试全屏模式
            DEVMODE dmScreenSettings;                                    //设备模式
            memset(&dmScreenSettings, 0sizeof(dmScreenSettings));      //确保内存清空为零
            dmScreenSettings.dmSize       = sizeof(dmScreenSettings);    //DEVMODE结构的大小
            dmScreenSettings.dmBitsPerPel = bits;                        //每象素所选的色彩深度
            dmScreenSettings.dmPelsWidth  = width;                       //所选屏幕宽度
            dmScreenSettings.dmPelsHeight = height;                      //所选屏幕高度
            dmScreenSettings.dmFields     = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

            
    //尝试设置显示模式并返回结果(注:CDS_FULLSCREEN 移去了状态条)
            if(ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL){
                
    if(MessageBox(NULL, "全屏模式失败!是否使用窗口模式?""错误", MB_YESNO | MB_ICONQUESTION) == IDYES){
                    fullscreen 
    = FALSE;                                  //选择窗口模式
                }else{
                    MessageBox(NULL, 
    "程序退出!""错误", MB_OK | MB_ICONSTOP);
                    
    return FALSE;                                        //退出并返回FALSE
                }
            }
        }

        
    if(fullscreen){                                                  //仍处于全屏模式
            dwStyle   = WS_POPUP;                                        //窗体风格
            dwExStyle = WS_EX_APPWINDOW;                                 //扩展窗体风格
            ShowCursor(FALSE);                                           //隐藏鼠标指针
        }else{
            dwStyle   
    = WS_OVERLAPPEDWINDOW;                             //窗体风格
            dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;              //扩展窗体风格
        }

        AdjustWindowRectEx(
    &WindowRect, dwStyle, FALSE, dwExStyle);      //调整窗口达到真正要求的大小

        
    if(!(hWnd = CreateWindowEx(dwExStyle,                            //扩展窗体风格
                                   "OpenGL",                             //类名字
                                   title,                                //窗口标题
                                   dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, //必须的窗体风格属性
                                   00,                                 //窗口左上角X坐标和Y坐标位置
                                   WindowRect.right - WindowRect.left,   //计算调整好的窗口高度的宽度
                                   WindowRect.bottom - WindowRect.top,   //计算调整好的窗口高度的高度
                                   NULL,                                 //无父窗口
                                   NULL,                                 //无菜单
                                   hInstance,                            //实例
                                   NULL))){                              //不向WM_CREATE传递任何信息
            KillGLWindow();                                              //重置显示区
            MessageBox(NULL, "窗口创建失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //窗口创建失败
        }

        
    if(!(hDC = GetDC(hWnd))){                                        //是否取得设备描述表
            KillGLWindow();                                              //重置显示区
            MessageBox(NULL, "创建设备描述表失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //创建设备描述表失败
        }

        
    if(!(PixelFormat = ChoosePixelFormat(hDC, &pfd))){               //是否Windows找到相应的象素格式
            KillGLWindow();                                              //重置显示区
            MessageBox(NULL, "没有相匹配的像素格式!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //没有相匹配的像素格式
        }

        
    if(!SetPixelFormat(hDC, PixelFormat, &pfd)){                     //是否能设置象素格式
            KillGLWindow();                                              //重置显示区
            MessageBox(NULL, "设置像素格式失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //设置像素格式失败
        }

        
    if(!(hGLRC = wglCreateContext(hDC))){                            //是否能取得OpenGL渲染描述表
            KillGLWindow();                                              //重置显示区
            MessageBox(NULL, "创建OpenGL渲染表失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //创建OpenGL渲染表失败
        }
        
    if(!wglMakeCurrent(hDC, hGLRC)){                                 //尝试激活着色描述表
            KillGLWindow();                                              //重置显示区
            MessageBox(NULL, "激活当前OpenGL渲染表失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //激活当前OpenGL渲染表失败
        }

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

        
    if(!InitGL()){                                                   //初始化新建的GL窗口
            KillGLWindow();
            MessageBox(NULL, 
    "初始化失败!""错误", MB_OK | MB_ICONEXCLAMATION);
            
    return FALSE;                                                //初始化失败
        }

        
    return TRUE;                                                     //创建窗口成功
    }

    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd){
        
    //WinMain(当前窗口实例, 前一个窗口实例, 命令行参数, 窗口显示状态)
        MSG  msg;                                                        //Windowsx消息结构
        BOOL done = FALSE;                                               //用来退出循环的BOOL变量

        winWidth  
    = 640;                                                 //定义窗口宽度
        winHeight = 480;                                                 //定义窗口高度
        winBits   = 16;                                                  //定颜色深度为

        
    //提示用户选择运行模式
        if(MessageBox(NULL, "是否使用全屏模式?""OpenGL", MB_YESNO | MB_ICONQUESTION) == IDNO){
            fullscreen 
    = FALSE;                                          //FALSE为窗口模式
        }

        
    //创建OpenGL窗口
        if(!CreateGLWindow("OpenGL", winWidth, winHeight, winBits, fullscreen)){
            
    return 0;                                                    //失败退出
        }
        
    while(!done){                                                    //保持循环直到done=TRUE
            if(PeekMessage(&msg, NULL, 00, PM_REMOVE)){                //是否在等待消息
                if(msg.message == WM_QUIT){                              //收到退出消息
                    done = TRUE;                                         //是, 则done=TRUE
                }else{                                                   //不是, 处理窗口消息
                    TranslateMessage(&msg);                              //翻译消息
                    DispatchMessage(&msg);                               //发送消息
                }
            }
    else{                                                       //如果没有消息
                
    //绘制场景。监视ESC键和来自DrawGLScene()的退出消息
                if(active){                                              //程序是否激活
                    if(keys[VK_ESCAPE]){                                 //是否ESC按下
                        done = TRUE;                                     //ESC发出退出信号
                    }else{                                               //不是退出的时候, 刷新屏幕
                        DrawGLScene();                                   //绘制场景
                        SwapBuffers(hDC);                                //交换缓存(双缓存)
                    }
                }

                
    if(keys[VK_F1]){                                         //是否按下F1键
                    keys[VK_F1] = FALSE;                                 //若是, 使对应的Key数组中的值为FALSE
                    KillGLWindow();                                      //销毁当前的窗口
                    
    //切换全屏/窗口模式
                    if(!CreateGLWindow("OpenGL", winWidth, winHeight, winBits, !fullscreen)){ //重建OpenGL窗口
                        return 0;                                        //如果窗口未能创建, 程序退出
                    }
                }
            }
        }
        
    //关闭程序
        KillGLWindow();                                                  //销毁窗口
        return msg.wParam;                                               //退出程序
    }
     
  • 相关阅读:
    Navicat for SQLite之外键(05)
    UIButton
    多线程中的API
    UIImageView
    IOS中实现单例
    IOS中的多线程【二】— NSOperation和NSOperationQueue
    IOS中的多线程
    OC中新增的数据类型
    【转】c# DBF数据库导入导出实例
    【经验】学习新知识的经验
  • 原文地址:https://www.cnblogs.com/hcbin/p/1670009.html
Copyright © 2011-2022 走看看