OpenGL學習進程(3)第一課:初始化窗體


    本節是OpenGL學習的第一個課時,下面介紹如何初始化一個窗體:

 

    (1)顯示一個有藍色背景的窗體:

#include <GL/glut.h>
#include <stdlib.h>

void display(void)
{
   /* clear all pixels  */
   glClear (GL_COLOR_BUFFER_BIT);

   glFlush ();
}

int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
   glutInitWindowSize (250, 250); 
   glutInitWindowPosition (100, 100);
   glutCreateWindow ("藍色背景窗體");
   glClearColor (0.0, 0.0, 1.0, 0.0);
   glutDisplayFunc(display); 
   glutMainLoop();
   return 0;
}

    代碼解釋:

    Several routines perform tasks necessary for initializing a window: 

      1) glutInit(int *argc, char **argv) 

      initializes GLUT and processes any command,line arguments (for X, this would be options such as -display and -geometry). glutInit() should be called before any other GLUT routine. 
      2)glutInitDisplayMode(unsigned int mode)

  specifies whether to use an RGBA or color-index color model. You can also specify whether you want a single- or double-buffered window. (If you’re working in colorindex mode, you’ll want to load certain colors into the color map; use glutSetColor() to do this.) Finally, you can use this routine to indicate that you want the window to have an associated depth, stencil, multisampling, and/or accumulation buffer. For example, if you want a window with double buffering, the RGBA color model, and a depth buffer, you might call glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH).

      3)glutInitWindowPosition(int x, int y)

      specifies the screen location for the upper-left corner of your window.

      4)glutInitWindowSize(int width, int height)

  specifies the size, in pixels, of your window.

      5)glutInitContextVersion(int majorVersion, int minorVersion)

  specifies which version of OpenGL you want to use. (This is a new addition available only when using Freeglut, and was introduced with OpenGL Version 3.0. See “OpenGL Contexts” on page 27 for more details on OpenGL contexts and versions.)

      6)glutInitContextFlags(int flags)

  specifes the type of OpenGL context you want to use. For normal OpenGL operation, you can omit this call from your program. However, if you want to use a forward-compatible OpenGL context, you will need to call this routine. (This is also a new addition available only in Freeglut, and was introduced with OpenGL Version 3.0. See “OpenGL Contexts” on page 27 for more details on the types of OpenGL contexts.)

      7)int glutCreateWindow(char *string)

  creates a window with an OpenGL context. It returns a unique identifier for the new window. Be warned: until glutMainLoop() is called, the window is not yet displayed.

    低級win32 api初始化一個窗體是比較復雜的,glut庫簡化了這個過程。

    回調函數:

    即win32的消息循環系統。

      1)glutDisplayFunc調用一個函數,該函數會不斷的被調用。

      2)glutMainLoop用於啟動程序,並使程序不斷在運行,不退出,即進入消息循環。

      3)glClearColor用於清除緩沖區顏色,並重新設置新的顏色。

      4)guFlush刷新OpenGl命令隊列,如果不調用此方法,那么重新繪制的圖形將無法顯示。

 

    (2)顯示一個帶有白色矩形黑色背景的窗體:

//該程序的作用是在一個黑色的窗口中央畫一個白色的矩形。
#include <GL/glut.h>                  //GLUT的頭文件(本來OpenGL程序一般還要包含<GL/gl.h><GL/glu.h>,但GLUT的頭文件中已經自動將這兩個文件包含了,不必再次包含。)
//注意函數名的大小寫 void myDisplay()                    //這種gl開頭的函數是OpenGL的標准函數 { glClear(GL_COLOR_BUFFER_BIT);         //9.清除操作。GL_COLOR_BUFFER_BIT表示清除顏色。glClear還可以用來清除其他東西。 glRectf(-0.5,-0.5f,0.5f,0.5f);         //10.畫一個矩形。四個參數代表位於對角線的兩個點的橫縱坐標。 glFlush();                     //11.保證前面的OpenGL命令能夠立即執行,而不是在緩沖區等待。(作用跟fflush(stdout)類似) } int main(int argc, char *argv[]) //這種以glut開頭的函數都是GLUT工具包所提供的函數 { glutInit(&argc, argv);              //1.對GLUT進行初始化,這個函數必須在其它的GLUT使用之前調用一次。 glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE); //2.設置顯示方式。GLUT_RGB表示使用RGB顏色,GLUT_INDEX表示使用INDEX(索引顏色);GLUT_SINGLE表示使用單緩沖,GLUT_DOUBLE(使用雙緩沖)。 glutInitWindowPosition(100,100); //3.設置窗口在屏幕中的位置。 //4.glutInitWindowSize設置窗口的大小 glutCreateWindow("黑色的背景白色的矩形"); //5.根據前面的信息創建窗口,標題為設置的參數。 glutDisplayFunc(&myDisplay);          //6.當需要畫圖的時候,這個函數就被調用.(寄存回調) glutMainLoop();                  //7.當窗口被創建時,並不立即顯示在屏幕上。這個函數有將窗口顯示在屏幕上的作用。進行一個消息循環,當窗口關閉時這個函數才會返回。 return 0; } //8.當需要畫圖時,我們在glutDisplayFunc()中設置了“當需要畫圖時,調用myDisplay函數”。myDisplay用來畫圖,下面介紹myDisplay中的函數。

 

    (3)詳細介紹:

    1)glutInitDisplayMode()函數:

      函數的功能是:設置顯示方式;

      函數原型是:void glutInitDisplayMode(unsigned int mode);

      1.mode參數是一個GLUT庫里預定義的可能的布爾組合。可以使用mode去指定顏色模式數量緩沖區類型

      下面是是mode的所有可能取值:

      2.像素顏色在圖形硬件中的存儲方式有兩種:RGBA和INDEX(像素索引)。

      RGB色彩模式:是工業界的一種顏色標准,是通過對紅(R)、綠(G)、藍(B)三個顏色通道的變化以及它們相互之間的疊加來得到各式各樣的顏色的,RGB即是代表紅、綠、藍三個通道的顏色,這個標准幾乎包括了人類視力所能感知的所有顏色,是目前運用最廣的顏色系統之一。 RGBA在RGB的基礎上多了控制alpha透明度的參數。以上R、G、B三個參數,正整數值的取值范圍為:0 - 255。百分數值的取值范圍為:0.0% - 100.0%。超出范圍的數值將被截至其最接近的取值極限。並非所有瀏覽器都支持使用百分數值。A參數,取值在0~1之間,不可為負值。

      INDEX色彩模式:采用一個顏色表存放並索引圖像中的顏色。如果原圖像中的一種顏色沒有出現在查照表中,程序會選取已有顏色中最相近的顏色或使用已有顏色模擬該種顏色。能減小文件大小,同時保持視覺上的品質不變。 

      3.設置單緩沖區或雙緩沖區窗口:

      GLUT_SINGLE:單緩沖區窗口,當不需要用戶交互時用單緩沖,需要用戶交互時要用雙緩沖

      GLUT_DOUBLE:雙緩沖區窗口,這是產生流暢動畫必須選的。Glut使用雙緩沖只需要在顯示回調函數中使用函數glutSwapBuffers()取代glFlush()。

    2)glClear()與glClearColor()函數:

      glClear函數原型:void glClear(GLbitfield mask);

      GLbitfield:可以使用|運算符組合不同的緩沖標志位,表明需要清除的緩沖。

      (例如glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)表示要清除顏色緩沖以及深度緩沖)

      1.緩沖區的種類:(緩沖區的作用:http://blog.sina.com.cn/s/blog_5dc7bbf801010fdr.html)

  緩沖區                  名稱
顏色緩沖區           GL_COLOR_BUFFER_BIT              //也就是幀緩沖區(FRAME_BUFFER),你需要渲染的場景最終每一個像素都要寫入該緩沖區,然后由它在渲染到屏幕上顯示
深度緩沖區           GL_DEPTH_BUFFER_BIT            //與幀緩沖區對應,用於記錄上面每個像素的深度值,通過深度緩沖區,我們可以進行深度測試,從而確定像素的遮擋關系,保證渲染正確。
累積緩沖區           GL_ACCUM_BUFFER_BIT            //累積緩存也存儲RGBA顏色數據, 將一系列的圖像合成一幅圖像.
模板緩沖區           GL_STENCIM_BUFFER_BIT           //與深度緩沖大小相同,通過設置模版緩沖每個像素的值,我們可以指定在渲染的時候只渲染某些像素,從而可以達到一些特殊的效果

      2.glclear()函數的功能:

      清除上次顯示的結果,每次繪制前都必須調用。

glClearColor(0.00.00.00.0);  //將清除顏色設為黑色。(僅僅設置了顏色,並沒有用這個顏色去清除任何區域)
glClear(GL_COLOR_BUFFER_BIT);      //實際完成了把整個窗口清除為黑色的任務。像素檢驗、裁剪檢驗、抖動和緩存的寫屏蔽都會影響glClear的操作,其中,裁剪范圍限制了清除的區域,而glClear命令還會忽略alpha函數、融合函數、邏輯操作、模板、紋理映射和z緩存;

      OpenGL 在每一幀開始要調用glClearColor來設置背景色,相當於畫布的顏色。必須強調: glClearColor只起到Set的作用,並不Clear任何。

    3)glFlush()函數:

      保證繪圖命令將被執行,而不是存儲在緩沖區 中等待其他的OpenGL命令。就是強制刷新。

      (OpenGL是使用一條渲染管線線性處理命令的,一般情況下,我們提交給OpenGL的指令並不是馬上送到驅動程序里執行的,而是放到一個緩沖區里面,等這個緩沖區滿了再一次過發到驅動程序里執行;很多時候只有幾條指令是填充不滿那個緩沖區的,就是說這些指令根本沒有被發送到驅動里,所以我們要調用glFlush來強制把這些指令送到驅動里進行處理。)

 

    (4)繪制窗體的案例:

  繪制帶有紅色背景並且有一個藍色的矩形的窗體:(測試glClear函數和glClearColor函數)

#include <GL/glut.h>

void myDisplay(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    //glClearColor(0.0,0.0,1.0,0.0);//重新設置填充色為藍色,即窗口背景顏色
    glColor3f(0.0f, 0.0f, 1.0f);//設置畫筆的顏色為藍色
    glRectf(-0.5f,-0.5f,0.5f,0.5f);
    glFlush();
}
int main(int argc, char *argv[])
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
    glutInitWindowPosition(600,300);
    glutInitWindowSize(400,200);
    glutCreateWindow("我的練習1:紅色背景藍色矩形");
    glClearColor(1.0,0.0,0.0,0.0);//設置背景填充色為紅色
    glutDisplayFunc(&myDisplay);//經過測試,寄存回調過程加不加取地址符都正確。
    glutMainLoop();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM