OpenGL学习笔记【4】——给立方体纹理贴图(texture)
今天我学习了对一个正方体贴纹理:
这次先奉上源代码:
#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); //旋转矩阵,这里绕x轴旋转。
glRotatef(yrot,0.0f,1.0f,0.0f); //旋转矩阵,这里绕y轴旋转。
glRotatef(zrot,0.0f,0.0f,1.0f); //绕z轴旋转,这里zrot是角度制的度数。
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); // 清楚颜色数据和深度数据(清屏)
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f);
DrawCube();
glutSwapBuffers(); //交换缓冲区。显示图形
}
// 载入一个.bmp格式的贴图纹理
int LoadGLTextures(GLuint & unTexture, const char * chFileName)
{
AUX_RGBImageRec *TextureImage; //保存贴图数据的指针
TextureImage = auxDIBImageLoad("Data/NeHe.bmp"); //载入贴图数据
glGenTextures(1, &unTexture); // 创建一个纹理,unTexture
glBindTexture(GL_TEXTURE_2D, unTexture); //绑定纹理,然后对该纹理区添加纹理数据
//设置纹理的信息,
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); //设置滤波为线性滤波
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"); //载入纹理贴图
}
// 当窗口大小改变时,会调用这个函数
void reshape(GLsizei w,GLsizei h)
{
//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
glViewport(0,0,w,h); //设置视口
glMatrixMode(GL_PROJECTION); //设置矩阵模式为投影变换矩阵,
glLoadIdentity(); //变为单位矩阵
gluPerspective(60, (GLfloat)w / h, 0, 1000); //设置投影矩阵
glMatrixMode(GL_MODELVIEW); //设置矩阵模式为视图矩阵(模型)
glLoadIdentity(); //变为单位矩阵
}
// 闲置函数,当主循环空闲时就会调用这个函数
void MyIdle( void )
{
Sleep(10);
xrot+=0.3f; //增加旋转的角度。
yrot+=0.2f;
zrot+=0.4f;
glutPostRedisplay();
}
int main( int argc, char ** argv)
{
glutInit(&argc, argv); //Opnegl初始化
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA); //设置显示模式为双缓冲,RGEBA
glutInitWindowSize (800, 600); //窗口大小
glutInitWindowPosition (100, 100); //窗口位置
glutCreateWindow ("hello"); //创建一个标题为hello的窗口
init (); //初始化资源,这里一定要在创建窗口以后,不然会无效。
glutDisplayFunc(display); //窗口大小改变时的回调
glutReshapeFunc(reshape); //绘制图形时的回调
glutIdleFunc(MyIdle);
glutMainLoop(); //主循环。
return 0;
}
#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); //旋转矩阵,这里绕x轴旋转。
glRotatef(yrot,0.0f,1.0f,0.0f); //旋转矩阵,这里绕y轴旋转。
glRotatef(zrot,0.0f,0.0f,1.0f); //绕z轴旋转,这里zrot是角度制的度数。
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); // 清楚颜色数据和深度数据(清屏)
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f);
DrawCube();
glutSwapBuffers(); //交换缓冲区。显示图形
}
// 载入一个.bmp格式的贴图纹理
int LoadGLTextures(GLuint & unTexture, const char * chFileName)
{
AUX_RGBImageRec *TextureImage; //保存贴图数据的指针
TextureImage = auxDIBImageLoad("Data/NeHe.bmp"); //载入贴图数据
glGenTextures(1, &unTexture); // 创建一个纹理,unTexture
glBindTexture(GL_TEXTURE_2D, unTexture); //绑定纹理,然后对该纹理区添加纹理数据
//设置纹理的信息,
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); //设置滤波为线性滤波
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"); //载入纹理贴图
}
// 当窗口大小改变时,会调用这个函数
void reshape(GLsizei w,GLsizei h)
{
//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
glViewport(0,0,w,h); //设置视口
glMatrixMode(GL_PROJECTION); //设置矩阵模式为投影变换矩阵,
glLoadIdentity(); //变为单位矩阵
gluPerspective(60, (GLfloat)w / h, 0, 1000); //设置投影矩阵
glMatrixMode(GL_MODELVIEW); //设置矩阵模式为视图矩阵(模型)
glLoadIdentity(); //变为单位矩阵
}
// 闲置函数,当主循环空闲时就会调用这个函数
void MyIdle( void )
{
Sleep(10);
xrot+=0.3f; //增加旋转的角度。
yrot+=0.2f;
zrot+=0.4f;
glutPostRedisplay();
}
int main( int argc, char ** argv)
{
glutInit(&argc, argv); //Opnegl初始化
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA); //设置显示模式为双缓冲,RGEBA
glutInitWindowSize (800, 600); //窗口大小
glutInitWindowPosition (100, 100); //窗口位置
glutCreateWindow ("hello"); //创建一个标题为hello的窗口
init (); //初始化资源,这里一定要在创建窗口以后,不然会无效。
glutDisplayFunc(display); //窗口大小改变时的回调
glutReshapeFunc(reshape); //绘制图形时的回调
glutIdleFunc(MyIdle);
glutMainLoop(); //主循环。
return 0;
}
主要流程:
OpneGL的流程,先初始化。
1. 在Init函数中,初始化我们的信息:
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"); //载入纹理贴图
这里的顺序是可以打乱的,记住一定要载入纹理,我这里是写了一个函数来载入。然后要启用纹理贴图。glEnable(GL_TEXTURE_2D);。还有一件事情是比不可少的,就是一定要启用裁剪,并且一定要用GL_BACK。我也不知道为什么,反正用glut创建的窗口就不可以,如果是直接用windows下创建的不用这个也是可以的。原理暂时还不清楚。
2 . 然后是绘制图形:
就是绘制一个正方体,并贴上图。
glTexCoord2f(0.0f, 1.0f); 这是贴图的纹理坐标,在0-1范围内,他就是把一张纹理看成0-1的区域,这就是用他该区域的纹理贴图。
glVertex3f(-1.0f, 1.0f, -1.0f); //画点,这里画点后,他的纹理就有上面的贴图的纹理坐标来确定。就确定了这点的贴图信息。
3.新加了一个idle函数,他能在循环空闲的时候调用,我们用他来改变旋转的角度并重画图形,这样就可以看到图形动起来了。