今天我學(xué)習(xí)了對一個正方體貼紋理:
這次先奉上源代碼:
#pragma comment(lib, "glaux.lib")
#include <gl\glaux.h>
#include <gl\glut.h>

GLuint g_texture = 0;
GLfloat xrot =0;
GLfloat yrot =0;
GLfloat zrot =0; // Keep Going


//繪制一個立方體
int DrawCube(void)


{
glBindTexture(GL_TEXTURE_2D, g_texture); //使用貼圖紋理

glPushMatrix(); //壓入變換矩陣

glRotatef(xrot,1.0f,0.0f,0.0f); //旋轉(zhuǎn)矩陣,這里繞x軸旋轉(zhuǎn)。
glRotatef(yrot,0.0f,1.0f,0.0f); //旋轉(zhuǎn)矩陣,這里繞y軸旋轉(zhuǎn)。
glRotatef(zrot,0.0f,0.0f,1.0f); //繞z軸旋轉(zhuǎn),這里zrot是角度制的度數(shù)。

glBegin(GL_QUADS); //啟用四邊形帶繪制模式繪制

// 繪制前面,這里開始確定紋理坐標,然后是確定點的位置
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);

// 繪制后面
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);

// 上面
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);

//底面
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
// 右面
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, -1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f);

// 左面
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f);

glEnd();

glPopMatrix(); //彈出變換矩陣

return 1;

}
void display(void)


{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清楚顏色數(shù)據(jù)和深度數(shù)據(jù)(清屏)
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f);

DrawCube();

glutSwapBuffers(); //交換緩沖區(qū)。顯示圖形
}

//載入一個.bmp格式的貼圖紋理
int LoadGLTextures(GLuint& unTexture, const char* chFileName)


{
AUX_RGBImageRec *TextureImage; //保存貼圖數(shù)據(jù)的指針
TextureImage = auxDIBImageLoad("Data/NeHe.bmp"); //載入貼圖數(shù)據(jù)

glGenTextures(1, &unTexture); // 創(chuàng)建一個紋理,unTexture

glBindTexture(GL_TEXTURE_2D, unTexture); //綁定紋理,然后對該紋理區(qū)添加紋理數(shù)據(jù)

//設(shè)置紋理的信息,
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage->sizeX, TextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //設(shè)置濾波為線性濾波
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //線性濾波

if (TextureImage) //釋放資源

{
if (TextureImage->data)

{
free(TextureImage->data);
}
free(TextureImage);
}

return 1;
}


//初始化
void init (void)


{
glClearColor (0.0, 0.0, 0.0, 0.0); //清理顏色,為黑色,(也可認為是背景顏色)

glCullFace(GL_BACK); //背面裁剪(背面不可見)
glEnable(GL_CULL_FACE); //啟用裁剪
glEnable(GL_TEXTURE_2D);
LoadGLTextures(g_texture, "Data/NeHe.bmp"); //載入紋理貼圖
}

//當窗口大小改變時,會調(diào)用這個函數(shù)
void reshape(GLsizei w,GLsizei h)


{
//這里小說明一下:矩陣模式是不同的,他們各自有一個矩陣。投影相關(guān)
//只能用投影矩陣。(只是目前情況下哦,等我學(xué)多了可能就知道為什么了。)

glViewport(0,0,w,h); //設(shè)置視口
glMatrixMode(GL_PROJECTION); //設(shè)置矩陣模式為投影變換矩陣,
glLoadIdentity(); //變?yōu)閱挝痪仃?/span>
gluPerspective(60, (GLfloat)w / h, 0, 1000); //設(shè)置投影矩陣
glMatrixMode(GL_MODELVIEW); //設(shè)置矩陣模式為視圖矩陣(模型)
glLoadIdentity(); //變?yōu)閱挝痪仃?/span>
}

//閑置函數(shù),當主循環(huán)空閑時就會調(diào)用這個函數(shù)
void MyIdle(void)


{
Sleep(10);
xrot+=0.3f; //增加旋轉(zhuǎn)的角度。
yrot+=0.2f;
zrot+=0.4f;
glutPostRedisplay();
}

int main(int argc, char** argv)


{
glutInit(&argc, argv); //Opnegl初始化
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA); //設(shè)置顯示模式為雙緩沖,RGEBA

glutInitWindowSize (800, 600); //窗口大小
glutInitWindowPosition (100, 100); //窗口位置
glutCreateWindow ("hello"); //創(chuàng)建一個標題為hello的窗口
init (); //初始化資源,這里一定要在創(chuàng)建窗口以后,不然會無效。
glutDisplayFunc(display); //窗口大小改變時的回調(diào)
glutReshapeFunc(reshape); //繪制圖形時的回調(diào)
glutIdleFunc(MyIdle);
glutMainLoop(); //主循環(huán)。
return 0;
}
主要流程:
OpneGL的流程,先初始化。
1. 在Init函數(shù)中,初始化我們的信息:
glClearColor (0.0, 0.0, 0.0, 0.0); //清理顏色,為黑色,(也可認為是背景顏色)
glCullFace(GL_BACK); //背面裁剪(背面不可見)
glEnable(GL_CULL_FACE); //啟用裁剪
glEnable(GL_TEXTURE_2D);
LoadGLTextures(g_texture, "Data/NeHe.bmp"); //載入紋理貼圖
這里的順序是可以打亂的,記住一定要載入紋理,我這里是寫了一個函數(shù)來載入。然后要啟用紋理貼圖。glEnable(GL_TEXTURE_2D);。還有一件事情是比不可少的,就是一定要啟用裁剪,并且一定要用GL_BACK。我也不知道為什么,反正用glut創(chuàng)建的窗口就不可以,如果是直接用windows下創(chuàng)建的不用這個也是可以的。原理暫時還不清楚。
2 . 然后是繪制圖形:
就是繪制一個正方體,并貼上圖。
glTexCoord2f(0.0f, 1.0f); 這是貼圖的紋理坐標,在0-1范圍內(nèi),他就是把一張紋理看成0-1的區(qū)域,這就是用他該區(qū)域的紋理貼圖。
glVertex3f(-1.0f, 1.0f, -1.0f); //畫點,這里畫點后,他的紋理就有上面的貼圖的紋理坐標來確定。就確定了這點的貼圖信息。
3.新加了一個idle函數(shù),他能在循環(huán)空閑的時候調(diào)用,我們用他來改變旋轉(zhuǎn)的角度并重畫圖形,這樣就可以看到圖形動起來了。