歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenGL超級寶典學習筆記——Using OpenGL(三)

OpenGL狀態機

    繪制3D圖形是一項復雜的任務。我們需要許多的屬性,比如光照屬性,材料屬性,紋理等。如果我們在每次繪制圖形的時候,都去設置這些屬性,或者以參數的形式傳進去。那工作量非常大,而且還易出錯。所以OpenGL使用了狀態模式,來管理這些屬性,使得圖形編程變得更簡潔,容易。

    光照屬性,材料屬性等等屬性變量的集合就是管線的狀態。狀態機是一系列狀態變量的集合的抽象模型。每個狀態變量可以有不同的值,例如打開或關閉等。

打開狀態可以使用:

void glEnable(GLenum capability);

關閉狀態可以使用

void glDisable(GLenum capability);

例子:

打開光照

glEnable(GL_LIGHTING);

關閉光照

glDisable(GL_LIGHTING);

Opengl還提供了檢查這些狀態的方法:

GLboolean glIsEnabled(GLenum capability);

不是所有的狀態變量只有簡單的打開或關閉的狀態。許多OpenGL的函數設置這些狀態值一直到被改變為止。你可以隨時查找這些狀態變量的值。OpenGL提供了各種類型的超找函數。

void glGetBooleanv(GLenum pname, GLboolean params);

void glGetDoublev(GLenum panme, GLdouble params);

void glGetFloatv(GLenum pname, GLfloat params);

void glGetIntegerv(GLenum pname, GLint params);

每一個函數返回一個值或者一個值數組,存儲在你提供的參數params中。

保存和恢復狀態

OpenGL提供了保存和恢復狀態的方法。是使用棧(後進先出LIFO)的方式來保存這些變量的。

兩個OpenGL的命令如下:

保存狀態 void glPushAttrib(GLbitfield mask);

恢復狀態 void glPopAttrib(GLbitfield mask);

參數是使用位段的方式來保存狀態。這就意味著你可以在單個函數調用中用位OR操作來表示多個狀態。

例如:

glPushAttrib(GL_TEXTURE_BIT|GL_LIGHTING_BIT);

獲取時:

glPopAttrib(mask);

if (mask & GL_LIGHTING_BIT == GL_LIGHTING_BIT)  glEnable(GL_LIGHTING);

OpenGL的錯誤處理

OpenGL在內部維護了一組錯誤標志,每個標志代表一種不同類型的錯誤。當一個錯誤發生時,與這個錯誤相對應的標志會被設置。我們可以調用glGetError(void)來檢查這些標志。

GLenum glGetError(void);

glGetError會返回一個錯誤值。如果被設置的錯誤值不止一個,glGetError仍然只返回一個值。需要遍歷不斷去取值,持續檢查錯誤值,直到返回GL_NO_ERROR。

錯誤代碼
描述

GL_INVALID_ENUM
枚舉值超出函數范圍

GL_INVALID_VALUE
數值參數超出范圍

GL_INVALID_OPERATION
在當前的狀態下操作非法

GL_STACK_OVERFLOW
堆棧上溢

GL_STACK_UNDERFLOW
堆棧下溢

GL_OUT_OF_MEMORY
沒有足夠的內存來執行這條命令

GL_TABLE_TOO_LARGE
指定的表太大

GL_NO_ERROR
沒有出現錯誤

我們可以使用GLU函數庫的另一個函數gluErrorString來獲得一個錯誤標志的字符串描述

const GLubyte gluErrorString(GLenum errorCode);

這個函數將錯誤標志作為它的唯一參數,並返回一個描述這個錯誤的靜態字符串。

例子: 如果當前的錯誤標志位GL_INVALID_ENUM,則

gluErrorString(glGetError()); 將返回

invalid enumerant 

獲取版本

有時候我們希望利用一個特定環境所提供的特定功能。我們需要針對不同的環境進行編程的話,我們需要知道OpenGL驅動程序的生產商和版本號。可以調用glGetString

const GLubyte glGetString(GLenum name);

這個函數返回一個靜態的字符串,描述了GL函數庫的相關信息。

GLU函數庫提供了另一個對應的函數gluGetString.

const GLubyte gluGetString(GLenum name);

這個函數返回一個字符串,描述它所請求的GLU函數的相關信息。

glHint

有時我們需要在性能和渲染效果中進行選擇,而glHint能給OpenGL提供一個啟示,你更關注渲染效果還是性能。

glHint允許指定偏重與視覺還是性能,函數原型如下:

void glHint(GLenum target, GLenum mode);

target指定行為類型。mode參數則告訴OpenGL我們最為關心的部分。這是唯一一個完全依賴於生產商的實現的函數。

檢查擴展

OpenGL允許廠商進行擴展。要檢查一個驅動程序包含了哪些擴展。如下:

const char szExtensions = glGetString(GL_EXTENTIONS);

這個字符串包含了驅動程序支持的所有擴展名稱(用空格分隔)。查找希望使用的擴展:

if(strstr(extensions, “WGL_EXT_swap_control”)  != NULL)
{
    wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress(“wglSwapIntervalEXT”);
    if (wglSwapIntervalEXT != NULL)
          wglSwapIntervalEXT(1);
}

使用這種方法,還應該確保擴展後面的那個字符串是空格或NULL,否則如果這個擴展被WGL_EXT_swap_control2所取代。此時C運行時函數strstr仍然找到第一個字符串,但是我們無法確定第二個的行為和第一個是否相同。

OpenGL的擴展前綴

前綴 廠商 SGI silicon Graphics IBM IBM WGL MicroSoft NV NVida ATI ATI EXT 跨廠商 ARB_ ARB標准

NVida的擴展得到了廣泛的使用,ATI也支持了NVida的擴展。

ARB批准的擴展,是通過OpenGL ARB的審查的擴展。

OpenGL超級寶典 第4版 中文版PDF+英文版+源代碼 見  http://www.linuxidc.com/Linux/2013-10/91413.htm

OpenGL編程指南(原書第7版)中文掃描版PDF 下載 http://www.linuxidc.com/Linux/2012-08/67925.htm

OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm

Ubuntu 13.04 安裝 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm

OpenGL三維球體數據生成與繪制【附源碼】 http://www.linuxidc.com/Linux/2013-04/83235.htm

Ubuntu下OpenGL編程基礎解析 http://www.linuxidc.com/Linux/2013-03/81675.htm

如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm 

更多《OpenGL超級寶典學習筆記》相關知識 見 http://www.linuxidc.com/search.aspx?where=nkey&keyword=34581

Copyright © Linux教程網 All Rights Reserved