OpenGL学习笔记【4】——给立方体纹理贴图(texture)

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.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
    glTexCoord2f(
1.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
    glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
    glTexCoord2f(
0.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);

    
// 绘制后面
    glTexCoord2f(1.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);
    glTexCoord2f(
1.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
    glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
    glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);

    
// 上面
    glTexCoord2f(0.0f1.0f); glVertex3f(-1.0f,  1.0f-1.0f);
    glTexCoord2f(
0.0f0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
    glTexCoord2f(
1.0f0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
    glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);

    
//底面
    glTexCoord2f(1.0f1.0f); glVertex3f(-1.0f-1.0f-1.0f);
    glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f-1.0f-1.0f);
    glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);
    glTexCoord2f(
1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
    
    
// 右面
    glTexCoord2f(1.0f0.0f); glVertex3f( 1.0f-1.0f-1.0f);
    glTexCoord2f(
1.0f1.0f); glVertex3f( 1.0f,  1.0f-1.0f);
    glTexCoord2f(
0.0f1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);
    glTexCoord2f(
0.0f0.0f); glVertex3f( 1.0f-1.0f,  1.0f);

    
// 左面
    glTexCoord2f(0.0f0.0f); glVertex3f(-1.0f-1.0f-1.0f);
    glTexCoord2f(
1.0f0.0f); glVertex3f(-1.0f-1.0f,  1.0f);
    glTexCoord2f(
1.0f1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);
    glTexCoord2f(
0.0f1.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, 03, 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.00.00.00.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, 01000);    //设置投影矩阵
    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 (
800600);            //窗口大小
    glutInitWindowPosition (100100);        //窗口位置
    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函数,他能在循环空闲的时候调用,我们用他来改变旋转的角度并重画图形,这样就可以看到图形动起来了。

你可能感兴趣的:(OpenGL学习笔记【4】——给立方体纹理贴图(texture))