1. 程式人生 > >OpenGL基礎圖形程式設計--紋理對映

OpenGL基礎圖形程式設計--紋理對映

12.1 基本步驟

    計算機三維圖形通過給面貼紋理來表現表面細節。OpenGL預設設定是關閉貼紋理的,所以必須先用命令開啟紋理計算。OpenGL體系內有一塊紋理記憶體,在有硬體加速的情況下,可能是位於顯示卡的VRAM裡,否則會是OpenGL庫管理的一塊記憶體。在這個紋理記憶體裡圖片是以特定的內部格式儲存的,有的顯示卡還支援壓縮紋理技術,所以將紋理畫素從應用程式記憶體傳到紋理記憶體需要進行格式轉換。這在OpenGL中是通過分別描述畫素在應用程式記憶體和紋理記憶體的格式來完成的,真正轉換工作OpenGL會在內部完成。OpenGL術語稱應用程式記憶體讀出畫素的過程為解碼(UNPACK)

,而向紋理記憶體寫畫素的過程為編碼(PACK)。用glPixelStore*(GL_[UN]PACK_*,引數值);命令設定編碼[解碼]格式。對於貼紋理過程我們只需關心解碼過程。如今的顯示卡通常都有比較大的視訊記憶體,其中有一部份是專門的紋理儲存區,有的卡還可以將最多64M系統記憶體對映為紋理記憶體,所以我們有可能把經常要用的紋理就保留在紋理記憶體裡以提高程式效能。
  紋理對映是一個相當複雜的過程,這節只簡單地敘述一下最基本的執行紋理對映所需的步驟。基本步驟如下:
  1)定義紋理(glGenTextures()、glBindTexture())、2)控制紋理(glTexParameteri())、3)說明紋理對映方式(glTexEnv)、4)繪製場景,給出頂點的紋理座標和幾何座標。
  注意
:紋理對映只能在RGBA方式下執行,不能運用於顏色表方式。下面舉出一個最簡單的紋理對映應用例子:

       注意:紋理影象必須是2的N次冪,紋理影象的寬高比必須是(2的n次冪:1)。因為在mipmap技術中,小的紋理圖通常是通過對最大的紋理圖進行濾波處理得到的,每個紋素的值時一個紋理圖中4個相應紋素的平均值。但是讓美工做出2次方紋理,並且整張圖的空間利用率要高,是很難的。

  例12-1 簡單紋理對映應用例程texsmpl.c

  1. #include <GL/gl.h>
  2. #include <GL/glu.h>
  3. #include <GL/glaux.h>
  4. #pragma comment(lib, "OpenGL32.lib")
  5. #pragma comment(lib, "GLU32.lib")
  6. #pragma comment(lib, "GlAux.lib")
  7. void myinit(void);  
  8. void makeImage(void);  
  9. void CALLBACK myReshape(GLsizei w, GLsizei h);  
  10. void CALLBACK display(void);  
  11. /* 建立紋理 */
  12. #define ImageWidth 64
  13. #define ImageHeight 64
  14. GLubyte Image[ImageWidth][ImageHeight][3];  
  15. void makeImage(void)  
  16. {  
  17.     int i, j, r,g,b;  
  18.     for (i = 0; i < ImageWidth; i++)  
  19.     {  
  20.         for (j = 0; j < ImageHeight; j++)  
  21.         {  
  22.             r=(i*j)%255;  
  23.             g=(4*i)%255;  
  24.             b=(4*j)%255;  
  25.             Image[i][j][0] = (GLubyte) r;  
  26.             Image[i][j][1] = (GLubyte) g;  
  27.             Image[i][j][2] = (GLubyte) b;  
  28.         }  
  29.     }  
  30. }  
  31. void myinit(void)  
  32. {  
  33.     glClearColor (0.0, 0.0, 0.0, 0.0);  
  34.     glEnable(GL_DEPTH_TEST);  
  35.     glDepthFunc(GL_LESS);  
  36.     makeImage();  
  37.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);  
  38.     /* 定義紋理 */
  39.     glTexImage2D(GL_TEXTURE_2D, 0, 3, ImageWidth,  
  40.     ImageHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, &Image[0][0][0]);  
  41.     /* 控制濾波 */
  42.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);  
  43.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);  
  44.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);  
  45.     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);  
  46.     /* 說明對映方式*/
  47.     glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);  
  48.     /* 啟動紋理對映 */
  49.     glEnable(GL_TEXTURE_2D);  
  50.     glShadeModel(GL_FLAT);  
  51. }  
  52. void CALLBACK display(void)  
  53. {  
  54.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  
  55.     /* 設定紋理座標和物體幾何座標 */
  56.     glBegin(GL_QUADS);  
  57.     glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, -1.0, 0.0);  
  58.     glTexCoord2f(0.0, 1.0); glVertex3f(-2.0, 1.0, 0.0);  
  59.     glTexCoord2f(1.0, 1.0); glVertex3f(0.0, 1.0, 0.0);  
  60.     glTexCoord2f(1.0, 0.0); glVertex3f(0.0, -1.0, 0.0);  
  61.     glTexCoord2f(0.0, 0.0); glVertex3f(1.0, -1.0, 0.0);  
  62.     glTexCoord2f(0.0, 1.0); glVertex3f(1.0, 1.0, 0.0);  
  63.     glTexCoord2f(1.0, 1.0); glVertex3f(2.41421, 1.0, -1.41421);  
  64.     glTexCoord2f(1.0, 0.0); glVertex3f(2.41421, -1.0, -1.41421);  
  65.     glEnd();  
  66.     glFlush();  
  67. }  
  68. void CALLBACK myReshape(GLsizei w, GLsizei h)  
  69. {  
  70.     glViewport(0, 0, w, h);  
  71.     glMatrixMode(GL_PROJECTION);  
  72.     glLoadIdentity();  
  73.     gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0);  
  74.     glMatrixMode(GL_MODELVIEW);  
  75.     glLoadIdentity();  
  76.     glTranslatef(0.0, 0.0, -3.6);  
  77. }  
  78. void main(void)  
  79. {  
  80.     auxInitDisplayMode (AUX_SINGLE | AUX_RGBA);  
  81.     auxInitPosition (0, 0, 500, 500);  
  82.     auxInitWindow (_T("Simple Texture Map"));  
  83.     myinit();  
  84.     auxReshapeFunc (myReshape);  
  85.     auxMainLoop(display);  
  86. }  

圖12-1 簡單紋理對映


  以上程式執行結果是將一塊紋理對映到兩個正方形上去。這兩個正方形都是按透視投影方式繪製,其中一個正對觀察者,另一個向後傾斜45度角。圖形的紋理是由函式makeImage()產生的,並且所有紋理對映的初始化工作都在程式myinit()中進行。由glTexImage2d()說明了一個全解析度的影象,其引數指出了影象的尺寸、影象型別、影象位置和影象的其它特性;下面連續呼叫函式glTexParameter*()說明紋理怎樣纏繞物體和當象素與紋理陣列中的單個元素(texel,暫稱紋素)不能精確匹配時如何過濾顏色;接著用函式glTexEnv*()設定畫圖方式為GL_DECAL,即多邊形完全用紋理影象中的顏色來畫,不考慮多邊形在未被紋理對映前本身的顏色;最後,呼叫函式glEnable()啟動紋理對映。子程式display()畫了兩個正方形,其中紋理座標與幾何座標一起說明,glTexCoord*()函式類似於glNormal*()函式,不過它是設定紋理座標,之後任何頂點都把這個紋理座標與頂點座標聯絡起來,直到再次呼叫 glTexCoord*()改變當前紋理座標。

12.2、紋理定義

  12.2.1 二維紋理定義的函式


  void glTexImage2D(GLenum target,GLint level,GLint internalFormat,
           GLsizei width, glsizei height,GLint border,
           GLenum format,GLenum type, const GLvoid *pixels);

    引數 target  GL_TEXTURE_2D (二維紋理 GL_PROXY_TEXTURE_2D (二維代理紋理), 代理紋理暫且不提。

       引數 level 指定了紋理對映細節的級別,用在mipmap中。基本的紋理影象級別為0在後面的mipmap部分講解
     引數 internalFormat 指定了紋理儲存在視訊記憶體中的內部格式,取值在下表。為相容 OpenGL1.0 internalFormat 可以取值 123分別對應常量 LUMINANCELUMINANCE_ALPHA,  RGB,  RGBA。

格式

註解

GL_ALPHA

Alpha 

GL_DEPTH_COMPONENT

深度值

GL_LUMINCE

灰度值

GL_LUMINANCE_ALPHA

灰度值和 Alpha 

GL_INTENSITY

亮度值

GL_RGB

Red, Green, Blue三原色值

GL_RGBA

Red, Green, Blue Alpha 

  引數width和height給出了紋理影象的長度和寬度,引數border為紋理邊界寬度,它通常為0,width和height必須是2m+2b,這裡m是整數,長和寬可以有不同的值,b是border的值。紋理對映的最大尺寸依賴於OpenGL,但它至少必須是使用64x64(若帶邊界為66x66),若width和height設定為0,則紋理對映有效地關閉。
  接下來的三個引數主要定義了影象資料的格式。引數 Format 指定了紋理儲存在視訊記憶體中的內部格式。引數 format 定義了影象資料陣列 texels 中的格式。可以取值如下:

格式

註解

GL_COLOR_INDEX

顏色索引值

相關推薦

OpenGL基礎圖形程式設計--紋理對映

12.1 基本步驟     計算機三維圖形通過給面貼紋理來表現表面細節。OpenGL預設設定是關閉貼紋理的,所以必須先用命令開啟紋理計算。OpenGL體系內有一塊紋理記憶體,在有硬體加速的情況下,可能是位於顯示卡的VRAM裡,否則會是OpenGL庫管理的一塊記憶

OpenGL基礎圖形程式設計(一)OpenGL與3D圖形世界

一、OpenGL與3D圖形世界1.1、OpenGL使人們進入三維圖形世界  我們生活在一個充滿三維物體的三維世界中,為了使計算機能精確地再現這些物體,我們必須能在三維空間描繪這些物體。我們又生活在一個充滿資訊的世界中,能否儘快地理解並運用這些資訊將直接影響事業的成敗,所以我

OpenGL基礎圖形程式設計(九)OpenGL顏色

九、OpenGL顏色   幾乎所有OpenGL應用目的都是在螢幕視窗內繪製彩色圖形,所以顏色在OpenGL程式設計中佔有很重要的地位。這裡的顏色與繪畫中的顏色概念不一樣,它屬於RGB顏色空間,只在監視器螢幕上顯示。另外,螢幕視窗座標是以象素為單位,因此組成圖形的每個象素都有

OpenGL基礎圖形程式設計

一、OpenGL與3D圖形世界 1.1、OpenGL使人們進入三維圖形世界   我們生活在一個充滿三維物體的三維世界中,為了使計算機能精確地再現這些物體,我們必須能在三維空間描繪這些物體。我們又生活在一個充滿資訊的世界中,能否儘快地理解並運用這些資訊將直接影響

OpenGL3D圖形繪製/紋理對映

1.3D圖形繪製 3D圖形也是由2D的面片組合而成,一個需要注意的問題是所有的面片繪製要麼是逆時針要麼是順時針,因此每三個點確定一個三角形或者每四個點確定一個四邊形,再有餘下的點時,按新的形狀處理。以下以一個旋轉的金字塔和立方體為例, /******************

計算機圖形學-紋理對映

先放個圖 利用MFC框架實現紋理對映 紋理對映主要包括紋理定義、紋理控制、紋理對映方式、紋理座標和紋理物件等 1 首先建立點陣圖類 class CBMPLoader { public: CBMPLoader(); ~CBMPLoader(); bool Lo

OpenGL紋理對映--基礎

紋理對映意思就是把圖片(或者說紋理)對映到3D模型的一個或多個面上。紋理可以是任何圖片,使用紋理對映可以增加3D物體的真實感,我們常見的紋理有磚,植物葉子等等。 下圖中是使用紋理對映和沒有使用紋理對映四面體的比較。       要使用紋理對映,我們必須做以下三件

【一篇文章帶你讀完《C++遊戲與圖形程式設計基礎 第2版》】

《C++遊戲與圖形程式設計基礎 第2版》 下載地址:https://download.csdn.net/download/qq_23996157/10745496 AGK(App Game Kit)下載地址:https://download.csdn.net/download/qq_2

3D 圖形程式設計的數學基礎 1 向量及其運算

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

OpenGL ES (3):平面圖形-表面紋理貼圖

1.簡介 上一篇已經將一個平面圖形繪製出來了,這一次我們將在上一次繪製出來的圖形的表面上進行紋理貼圖。 圖片準備:(寬高須為2的N次方) 最終圖片是以Bitmap形式。現在考慮如何把這張圖片對映到繪製的平面上? 所以這裡也需要一個數組float[] 用於設定紋理座

NeHe OpenGL教程 第六課:紋理對映 程式碼

#include <windows.h> // Windows的標頭檔案 #include <glew.h> // 包含最新的gl.h,glu.h庫 #include <glut.h> // 包含OpenGL實用庫 #include <stdio.h

3D 圖形程式設計的數學基礎 3 矩陣基本變換

                     這裡開始,是真正的與3D圖形程式設計相關的知識了,前兩節只能算是純數學。    平移矩陣  要想將向量(x, y, z, 1)沿x軸平移個單位,沿y軸平移,沿z軸平移個單位,我們只需要將該向量與如下矩陣相乘。  N(p) =   從中可以看出4*4矩陣N中的N41,N

OpenGL】遊戲程式設計常用TGA影象格式詳解以及載入紋理程式設計實現

TGA格式影象是遊戲中十分常見的一種影象格式,所以有必要了解其內部格式以及程式設計實現。 TGA影象一般有非壓縮和壓縮兩種格式,下面分別進行介紹。 一、非壓縮TGA影象 注:前面的標記綠色的部分(共12位元組)表示對於所有的非壓縮TGA格式影象值都是相同的!所以通常用來

android opengl es--紋理對映,光照

import zhou.ne.he.four.FourRend; import zhou.ne.he.one.OneRend; import zhou.ne.he.thri.ThriRend; import zhou.ne.he.two.TwoRend; import a

【Qt OpenGL教程】06:紋理對映

void MyGLWidget::paintGL() //從這裡開始進行所以的繪製 { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清除螢幕和深度快取 glLoadIden

3D 圖形程式設計的數學基礎(3) 矩陣基本變換

這裡開始,是真正的與3D圖形程式設計相關的知識了,前兩節只能算是純數學。 平移矩陣 要想將向量(x, y, z, 1)沿x軸平移個單位,沿y軸平移,沿z軸平移個單位,我們只需要將該向量與如下矩陣相乘。 N(p) = 從中可以看出4*4矩陣N中的N41,

OpenGL學習腳印: 二維紋理對映(2D textures)

寫在前面 前面兩節介紹了向量和矩陣,以及座標和轉換相關的數學,再繼續討論模型變換等其他包含數學內容的部分之前,本節介紹二維紋理對映,為後面學習做一個準備。紋理對映本身也是比較大的主題,本節只限於討論二維紋理的基本使用,對於紋理對映的其他方法,後面會繼續

OpenGL快速給圖形新增紋理含圓柱圓錐

這裡討論的是二維紋理 1.圖取影象資料 void readimage(char* filename, BYTE* imagedata)//所讀圖片均為24位bmp,且寬度補齊至四位元組邊界 { BITMAPFILEHEADER bf; //檔案頭 BITMAPINF

渲染世界的OpenGL 基礎紋理

基礎紋理的大體步驟: 載入紋理影象 設定紋理貼圖引數 管理多重紋理 生成Mip貼圖 使用各向異性過濾 載入壓縮紋理 紋理貼圖(Texture mapping):紋理只是一種能夠應用到場景當中三角形上的影象資料,他通過經過過濾的紋理單元填充到實心區域

高階圖形程式設計(基於opengl)——開譯說明

        TOM McREYNOLDS 和DAVID BLYTHE 寫的這本書,讀好感覺特別好,對圖形程式設計進階有很好的幫助,今天決定開始翻譯一下這本書,也是學習英語的目的吧 概述 計算機圖形學從早期的線框圖和游標距離現在已經很久了。今天任何人都可以有一臺可以