OpenGL中的3D文字繪製

轉自http://blog.csdn.net/augusdi/article/details/20572533

代碼如下:

/*****************************************新添加的代碼*****************************************/  
#include <Windows.h>  
#include <stdio.h>                                                   //標準輸入/輸出庫的頭文件  
#include <math.h>                                                    //數學庫  
#include <stdarg.h>                                                  //用來定義可變參數的頭文件  
/**********************************************************************************************/  
#include <GL/glut.h>                                                 //包含OpenGL實用庫  
#pragma comment(lib,"glut32.lib")  
  
  
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.0f, 0.0f, 0.0f);                          //把字符串置於最左邊  
    //////////////////////////////////////////////////////  
  
    glPushAttrib(GL_LIST_BIT);                                       //把顯示列表屬性壓入屬性堆棧  
    glListBase(base);                                                //設置顯示列表的基礎值爲0  
    glCallLists(strlen(text), GL_UNSIGNED_BYTE, text);               //調用顯示列表繪製字符串  
    glPopAttrib();                                                   //彈出屬性堆棧  
}  
  
void KillFont()                                                      //刪除顯示列表  
{  
    glDeleteLists(base, 256);                                        //刪除256個顯示列表  
}  
/**********************************************************************************************/  
  
//重置OpenGL窗口大小  
GLvoid ReSizeGLScene(UINT width, UINT height)  
{  
    if(height <= 0){ height = 1; }                                   //防止被零除且防止負數存在  
  
    glViewport(0, 0, (GLsizei)width, (GLsizei)height);               //重置當前的視口  
  
    glMatrixMode(GL_PROJECTION);                                     //選擇投影矩陣  
    glLoadIdentity();                                                //重置投影矩陣  
  
    gluPerspective(45.0f, (GLdouble)width / (GLdouble)height, 0.1f, 100.0f); //設置視口的大小  
  
    glMatrixMode(GL_MODELVIEW);                                      //選擇模型觀察矩陣  
    glLoadIdentity();                                                //重置模型觀察矩陣  
}  
  
//對OpenGL窗口進行初始化設置  
BOOL InitGL(GLvoid)  
{  
    glShadeModel(GL_SMOOTH);                                         //啓用陰影平滑  
    glClearColor(0.0f, 0.0f, 0.0f, 0.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.0f, 0.0f, -15.0f);                                //移入屏幕15個單位  
  
    glRotatef(rot, 1.0f, 0.0f, 0.0f);                                //沿X軸旋轉  
    glRotated(rot * 1.5f, 0.0f, 1.0f, 0.0f);                         //沿Y軸旋轉  
    glRotatef(rot * 1.4f, 0.0f, 0.0f, 1.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,                                                        //選定色彩深度  
        0, 0, 0, 0, 0, 0, 0, 0,                                      //忽略的色彩位(前6位), 無Alpha緩存(第7位), 忽略Shift Bit(第8位)  
        0,                                                           //無累加緩存  
        0, 0, 0, 0,                                                  //忽略聚集位  
        16,                                                          //16位Z-緩存(深度緩存)   
        0,                                                           //無蒙板緩存  
        0,                                                           //無輔助緩存  
        PFD_MAIN_PLANE,                                              //主繪圖層  
        0,                                                           //不使用重疊層  
        0, 0, 0                                                      //忽略層遮罩  
    };  
  
    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, 0, sizeof(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, //必須的窗體風格屬性  
                               0, 0,                                 //窗口左上角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, 0, 0, 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;                                               //退出程序  
}  



(暫時只支持英文)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章