目前光栅位置:
目前光栅位置就是開始繪制下一幅位圖/圖像的螢幕位置。 //左下角
glRasterPos2f(GLfloat x, GLfloat y);
glRasterPos3f(GLfloat x, GLfloat y, GLfloat z);
1、4版本中,glWindowsPos*()作為glRasterPos*()的替代品,它用視窗坐标指定目前光栅位置,不必把它的x和y坐标通過
模型視圖和投影矩陣進行變換,也不會被裁剪出視口區域。更容易混合使用2D文本和3D圖形,而不必再各種變換狀态之間反複切換。
glGetFloatv(GLenum pname, GLfloat *params);
//使用GL_CURRENT_RASTER_POSITION為pname擷取目前光栅位置。
glGetBooleanv(GLenum pname, GLboolean *params);
//使用GL_CURRENT_RASTER_POSITION_VALUE為pname确定目前光栅位置是否有效。
在設定了光栅位置之後,可以使用glBitmap()繪制位圖。
glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove,
GLfloat ymove, const GLubyte *bitmap); //xmove表示位圖光栅化之後光栅位置的x增加值
選擇位圖的顔色:
glColor*()和glIndex*()設定目前顔色或目前顔色索引,還可以設定狀态變量GL_CURRENT_RASTER_COLOR和
GL_CURRENT_INDEX.光栅顔色狀态變量是在調用glRasterPos*()時根據目前顔色設定的:
glColor3f(1.0, 1.0, 1.0);
glRasterPos3fv(position);
glColor3f(1.0, 0.0, 0.0);
glBitmap(...); //位圖顔色是白色的!!!
OpenGL提供了3個基本的函數來操縱圖像資料:
glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format,
GLenum type, GLvoid *pixels);
//從幀緩沖區讀取一個矩形像素數組,并把資料儲存在記憶體中。
glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
//把記憶體中儲存的一個矩形像素數組寫入到幀緩存區中由glRasterPos*()指定的目前位置
glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type);
//把一個矩形像素數組從幀緩沖區的一個部分複制到另一部分,資料不會寫入記憶體
OpenGL所支援的所有像素存儲模式都是由glPixelStore*()函數控制的,一般,可以連續幾次調用這個函數,成批設定幾個參數值。
glPixelStorei(GLenum pname, GLint param);
pname參數值:
GL_UNPACK_SWAP_BYTES: 若FALSE,記憶體中的字元順序采用OpenGL客戶機自身的方案,否則反轉位元組順序
GL_UNPACK_LSB_FIRST:隻适合在位圖上繪制或讀取1位圖像,若FALSE(預設),資料位從位元組的最高有效位開始提取。
GL_UNPACK_ROW_LENGTH:
GL_UNPACK_SKIP_ROWS
GL_UNPACK_SKIP_ROWS
GL_UNPACK_ALIGNMENT
GL_UNPACK_IMAGE_HEIGHT
GL_UNPACK_SKIP_IMAGES
像素傳輸操作:當圖像從記憶體傳輸到幀緩沖區或者從幀緩沖區傳輸到記憶體時,可以更改顔色成分的範圍(0.0-1.0),或執行任意的顔色索引或
顔色成分的轉換,這種在像素傳輸期間所執行的轉換成為像素傳輸操作,由glPixelTransfer*()和glPixelMap*()控制。
放大、縮小或翻轉圖像:
glPixelZoom(GLfloat xfactor, GLfloat yfactor);
//設定像素寫入操作glDrawPixels()和glCopyPixels()中x和y方向的縮放因子,負的縮放因子根據目前的光栅位置對圖像進行翻轉。
顔色矩陣:
從RGB顔色空間轉換為CMY顔色空間:
GLfloat rgb2cmy[16] = {
-1, 0, 0, 0,
0, -1, 0, 0,
0, 0, -1, 0,
1, 1, 1, 1
};
glMatrixMode(GL_COLOR);
glLoadMatrixf(rgb2cmy);
glMatrixMode(GL_MODELVIEW);
紋理貼圖:
glEnable(GL_TEXTURE_2D); // 1D, 2D, 3D, GL_TEXTURE_CUBE_MAP立方圖紋理
glGenTextures(GLsizei n, GLuint *textures);
glBindTexture(GLenum target, GLuint texture);
glTexParameteri(GLenum target, GLenum pname, GLint param);
glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
GLint border, GLenum format,GLenum type, const GLvoid *pixels);
gluScaleImage(GLenum format, GLint widthin, GLint heightin, GLenum typein, const void *datain,
GLint widthout, GLint heightout, GLenum typeout, void *dataout);
glCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width,
GLsizei height, GLint border);
替換紋理:
glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid *pixels);
從幀緩沖區中讀取一塊像素矩形替換一個現有紋理數組的一部分:
glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y,
GLsizei width, GLsizei height);
mipmap:
當紋理對象迅速遠離觀察點而去時,在經過一些過濾點時,經過過濾的紋理圖像可能出現突然的變化,為了避免這種人工痕迹,可以
指定一系列預先過濾的分辨率遞減的紋理圖像,稱為mipmap。如果不使用mipmap,當紋理映射到更小的物體上時,若物體移動,會閃爍或抖動。
為了使用mipmap, 必須提供全系列的大小為2的整數次方的紋理對象,範圍從最大值到1×1紋理單元,例如如果最高分辨率的紋理圖像是64*16,
還必須提供大小分别是32*8,16*4,8*2,4*1,2*1,1*1的紋理圖像。
可以使用glGenerateMipmap(GLenum target);為與target相關聯的紋理圖像生成一組完整的mipmap。
若已建立了最高分辨率的mipmap,可使用glutBuild2DMipmaps()建立和定義一系列大小遞減的mipmap,直到1*1紋理單元。
計算和加載mipmap層的一個子集,可以調用glutBuild2DMipmapLevels()。
為了控制mipmap層,可以向glTexParameter*()傳遞GL_TEXTURE_BASE_LEVEL、GL_TEXTURE_MAX_LEVEL、GL_TEXTURE_MIN_LOD
和GL_TEXTURE_MAX_LOD。前兩個控制哪些mipmap層被使用,後兩個用于控制縮放因子λ的活動範圍。
若紋理圖像大小64*32,多邊形大小8*16,ρ=8.0(取最大值),λ=3.0.
過濾:
使用glTexParameter*()函數指定放大和縮小過濾方法:
glTexParameteri(GLenum target, GLenum pname, GLint param);
eg: glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glIsTexture(GLuint texture);判斷一個紋理是否處于使用中,texture是由glGenTextures()函數傳回的。
可以把紋理圖像的顔色與物體表面原先的顔色進行組合:使用glTexEnv*()函數
glTexEnvf(GLenum target, GLenum pname, GLfloat param);
//target必須是GL_TEXTURE_FILTER_CONTROL或GL_TEXTURE_ENV
如果target是GL_TEXTURE_FILTER_CONTROL,pname必須是GL_TEXTURE_LOD_BIAS,param必須是浮點值,作為
mipmap細節層參數的偏移值。
如果target是GL_TEXTURE_ENV,且pname是GL_TEXTURE_ENV_MODE,那麼param必須是如下值之一:GL_DECAL,
GL_REPLACE, GL_MODULATE, GL_BLEND, GL_ADD, GL_COMBINE;如果pname是GL_TEXTURE_ENV_COLOR,param就是顔色RGBA數組。
紋理坐标映射:
glTexCoord2f(GLfloat s, GLfloat t); glVertex3f(GLfloat x, GLfloat y, GLfloat z);
紋理坐标自動生成:
可以使用紋理貼圖生成模型的輪廓線,或者模拟具有光澤的模型對任意環境的反射,為了實作這些效果,可以讓OpenGL自動生成紋理坐标:
glTexGeni(GLenum coord, GLenum pname, GLint param);
//coord必須是GL_S, GL_T, GL_R, GL_Q; pname取值GL_TEXTURE_GEN_MODE, GL_OBJECT_PLANE, GL_EYE_PLANE
球形紋理:
為了自動生成紋理坐标,對環境紋理貼圖提供支援,可使用如下代碼:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
立方圖紋理:
立方圖紋理使用6幅二維紋理圖像構成一個以原點為中心的紋理立方體。立方體紋理非常适用于實作環境、反射和光照效果。立方體紋理還可把
紋理環繞到球體上,使紋理單元均勻地分布于各個面上。
可以調用glTexImage2D() 6次,分别使用target參數表示立方體的各個面(+X, -X, +Y, -Y, +Z, -Z):
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image6);
因為立方圖紋理所占的記憶體時普通2D紋理的6倍,是以應把立方圖紋理視為一個整體,為它指定紋理參數并建立紋理對象,
而不是為6個面分别指定紋理參數:
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
啟用立方圖紋理:
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
GL_REFLECTION_MAP所使用的計算方式和GL_SPHERE_MAP相同,它非常适用于環境紋理貼圖,可替代GL_SPHERE_MAP.
GL_NORMAL_MAP适用于渲染無限遠處光源及散射反射的場景
多重紋理的步驟:
1、對于每個紋理機關,建立相關的紋理狀态,使用glActiveTexture()更改目前的紋理機關,
調用glGetIntegerv(GL_MAX_TEXTURE_UNITS,...)查詢目前OpenGL實作所支援的紋理機關的數量。
2、在指定頂點時,使用glMultiTexCoord*()為每個頂點指定多個紋理坐标,分别用于不同的紋理機關。
1、glActiveTexture(GLenum texUnit);
//選擇可以由紋理函數進行修改的目前紋理機關.texUnit是一個符号常量,形式為GL_TEXTUREi
eg:
GLuint texNames[2];
glGenTextures(2, texNames);
glBindTexture(GL_TEXTURE_2D, texNames[0]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, texels0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, REPEAT);
glBindTexture(GL_TEXTURE_2D, texNames[1]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, texels1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texNames[0]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glTranslatef(0.5f, 0.5f, 0.0f);
glRotatef(45.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(-0.5f, -0.5f, 0.0f);
glMatrixMode(GL_MODELVIEW);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texNames[1]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
在第一個紋理機關渲染完成後, 這個經過紋理處理的多邊形便發送到第二個紋理機關。
儲存恢複紋理機關的紋理狀态(紋理矩陣狀态除外):
glPushAttrib(GLbitfield mask); glPushClientAttrib(GLbitfield mask); //Pop
2、在多重紋理中,每個頂點隻有一組紋理坐标是不夠的,需要為每個頂點的每個紋理機關都指定一組紋理坐标,使用glMutiTexCoord*().
eg: //為多重紋理指定頂點
glBegin(GL_TRIANGLES);
glMultiTexCoord2f(GL_TEXTURE0, 0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE1, 1.0, 0.0);
glVertex2f(0.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE0, 0.5, 1.0);
glMultiTexCoord2f(GL_TEXTURE1, 0.5, 1.0);
glVertex2f(50.0, 100.0);
glMultiTexCoord2f(GL_TEXTURE0, 1.0, 0.0);
glMultiTexCoord2f(GL_TEXTURE1, 1.0, 1.0);
glVertex2f(100.0, 0.0);
glEnd();
使用多重紋理時,指定紋理坐标除了顯示調用glMultiTexCoord*(),還可以使用紋理坐标自動生成(glTexGenf();)和
頂點數組(glTexCoordPointer();)。