freeglut 使用筆記

1. 介紹

GLUT 代表 OpenGL 應用工具包,英文全稱爲 OpenGL Utility Toolkit,是一個和窗口系統無關的軟件包,可以跨平臺使用,而 freeglut 是 GLUT 的一個完全開源替代庫,對 GLUT 進行了擴展,本文使用的就是 freeglut 開源庫。

2. glut 部分函數詳解

void glut Init(int *argc, char **argv);

這個函數用來初始化 GLUT 庫,這個函數的參數從 main 函數獲取,也可以直接定義,格式比較固定,如下所示:

int numInit = 1;
char* InitDummy = "";
glutInit(&numInit, &InitDummy);

void glutInitDisplayMode(unsigned int mode); 

這個函數設置圖形的顯示模式,參數 mode 可選爲:

  • GLUT_RGBA:默認的使用模式,表示欲簡歷 RGBA 模式的窗口。
  • GLUT_SINGLE:只使用單緩存
  • GLUT_DOUBLE:使用雙緩存,避免在刷新圖形的時候出現閃屏白屏或者圖形不動的問題,在顯示動畫是很有用。
  • GLUT_DEPTH:使用深度緩存

多個選項可以同時使用,如下所示:

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);  // 雙緩衝緩衝,RGBA格式

void glutInitWindowPosition(int x, int y); 

設置初始窗口的位置,窗口左上角相對於桌面座標(x,y),如下所示:

glutInitWindowPosition(1, 1); 

void glutInitWindowSize(int width, int height); 

設置初始窗口的大小,width 爲窗口圖形的列數,height 爲窗口圖形的行數,如下所示:

glutInitWindowSize(512, 512); 

void glutMainLoop(void); 

讓glut程序進入事件循環.在一個glut程序中最多隻能調用一次,且必須調用.一旦調用,會直到程序結束才返回。而 freeglut 庫對該函數進行了擴展,對應的是glutMainLoopEvent(),該函數可以自動退出。

glutMainLoop(); 

或

glutMainLoopEvent();

int glutCreateWindow(const char *title);

產生一個頂層的窗口。title作爲窗口的名字,也就是窗口標題欄顯示的內容。返回值是生成窗口的標記符,可用函數glutGetWindow()加以引用,也可以使用glutDestroyWindow(int win)函數將其銷燬。用法如下:

int win =  glutCreateWindow("figure");

...

glutDestroyWindow(win);

void glutPostRedisplay(void);

標記當前窗口的圖像層需要重新繪製,在glutMainLoopglutMainLoopEvent函數的事件處理循環的下一個循環中,將調用該窗口的顯示回調函數重繪該窗口的圖像層。在動畫顯示中非常有用。用法如下:

glutPostRedisplay();

void glutSwapBuffers(void);

當窗口模式爲雙緩存時,此函數的功能就是把後臺緩存的內容交換到前臺顯示。當然,只有單緩存時,使用它的功能跟用glFlush()一樣。而使用雙緩存是爲了把完整圖畫一次性顯示在窗口上,或者是爲了實現動畫。用法如下:

glutSwapBuffers();

void glutSetOption ( GLenum option_flag, int value );

設置窗口的狀態和選項。
+ GLUT_ACTION_ON_WINDOW_CLOSE
+ GLUT_ACTION_EXIT
+ GLUT_ACTION_GLUTMAINLOOP_RETURNS
+ GLUT_ACTION_CONTINUE_EXECUTION

用法如下:

glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);

void glutDisplayFunc(void (*func)(void));

註冊當前窗口的顯示回調函數。參數 func 爲 void func() 的函數,完成具體的繪製操作這個函數告訴 GLUT 當窗口內容必須被繪製時,那個函數將被調用。當窗口改變大小或者從被覆蓋的狀態中恢復,或者由於調用glutPostRedisplay()函數要求GLUT更新時,執行func參數指定的函數。用法如下:


static void Display(void)
{
    Bitmap *bitmap = *(get_bitmap_ptr());
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawPixels(bitmap->col, bitmap->row, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->pixels);
    glFlush();
    glutSwapBuffers(); // 雙緩衝緩存
}

...

glutDisplayFunc(Display);

void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));

註冊當前窗口的鍵盤迴調函數,參數 func 爲 void func(unsigned char key, int x, int y),key 爲按鍵的ASCII碼x,y 爲當按下鍵時鼠標的座標,相對於窗口左上角,以像素爲單位,當敲擊鍵盤按鍵(除了特殊按鍵,即glutSpecialFunc()中處理的按鍵,詳見glutSpecialFunc())時調用。用法如下:

void processKeys(unsigned char key, int x, int y) 
{

    if (key == 27)
    {
        glutLeaveMainLoop();
     }
}

3. 一個例子

首先定義一個 Bitmap 類,需要把freeglut.hfreeglut_ext.hfreeglut_std.hglut.hfreeglut.libfreeglut.dll添加到相應的庫目錄。


class Bitmap
{
public:
    unsigned char *pixels; // 指向數據的內存區域
    int col, row; // 寬和高

    /* 構造函數,初始化 */
    Bitmap(int width, int height)
    {
        Bitmap **bitmap = get_bitmap_ptr();
        *bitmap = this;
        pixels = (unsigned char*)malloc(width * height * 4 * sizeof(unsigned char));
        memset(pixels, 0, width * height * 4 * sizeof(unsigned char));
        col = width;
        row = height;
    }

    /* 析構函數 */
    ~Bitmap()
    {
        delete[] pixels;
    }
    /* 圖像內存首地址*/
    unsigned char* get_ptr(void) const   
    { 
        return pixels; 
    }

    /* 顯示初始化 */
    void DisplayInit()
    {
        int numInit = 1;
        char* InitDummy = "";
        glutInit(&numInit, &InitDummy); // 初始化
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);  // 雙緩衝緩衝,RGBA格式
        glutInitWindowPosition(1, 1); // 窗口起始位置,相對顯示器的左上角位置
        glutInitWindowSize(col, row); // 窗口初始大小
        glutCreateWindow("bitmap"); // 創建窗口
        glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
    }

    /* 顯示更新 */
    void Imshow()
    {
        glutDisplayFunc(Display); // 顯示
        glutMainLoopEvent(); // 使用glutMainLoop() 將不會退出
        glutPostRedisplay(); // 刷新
    }

private:
    // static method used for glut callbacks
    static Bitmap** get_bitmap_ptr(void)
    {
        static Bitmap *gBitmap;
        return &gBitmap;
    }

    /* 顯示函數 */
    static void Display(void)
    {
        Bitmap *bitmap = *(get_bitmap_ptr());
        glClearColor(0.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawPixels(bitmap->col, bitmap->row, GL_RGBA, GL_UNSIGNED_BYTE, bitmap->pixels);
        glFlush();
        glutSwapBuffers(); // 雙緩衝緩存
    }
};

使用類:

    int col = 512;
    int row = 512;

    Bitmap bitmap(col, row);
    unsigned char *ptr = bitmap.get_ptr();
    bitmap.DisplayInit(); // 初始化

    for(;;)
    {
        /* 此處完成圖像的更新 */ 
        bitmap.Imshow();
    }

上述代碼就可以完成一個動畫的繪製和顯示,其中的幾個如下所示:

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

4. 參考

freeglut下載
本文完整代碼

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