今天学习了纹理,奉上源代码:
#pragma comment(lib, "glaux.lib")
#include "gl\glaux.h"
#include <gl\glut.h>
/**//* 创建纹理 */
#define ImageWidth 64
#define ImageHeight 64
GLubyte Image[ImageWidth][ImageHeight][3];
GLfloat sgenparams[] = {1.0,1.0,1.0};
void makeImage(void)
{
int i, j, r,g,b;
for (i = 0; i < ImageWidth; i++)
{
for (j = 0; j < ImageHeight; j++)
{
r=(i*j)%255;
g=(4*i)%255;
b=(4*j)%255;
Image[i][j][0] = (GLubyte) r;
Image[i][j][1] = (GLubyte) g;
Image[i][j][2] = (GLubyte) b;
}
}
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // 清楚颜色数据和深度数据(清屏)
glColor3f(1.0,1.0,1.0);
glLoadIdentity(); //初始变换矩阵为单位矩阵
glColor3f(1,1,1); //设置颜色为白色
//绘制一个实心的茶壶
glPushMatrix ();
glTranslatef(-4,2,0);
glFrontFace(GL_CW);
glutSolidTeapot(1);
glFrontFace(GL_CCW);
glPopMatrix ();
//绘制一个实心的球体
glPushMatrix();
glTranslatef(-1, 2, 0);
glutSolidSphere(1, 32,32);
glPopMatrix();
//绘制一个面
glPushMatrix();
glFrontFace(GL_CW);
glBegin(GL_QUADS);
glTexCoord2f(0,0); glVertex3f(0,0,0);
glTexCoord2f(0,1); glVertex3f(0,3,0);
glTexCoord2f(1,1); glVertex3f(3,3,0);
glTexCoord2f(1,0); glVertex3f(3,0,0);
glEnd();
glPopMatrix();
glutSwapBuffers(); //交换缓冲区。显示图形
}
//初始化
void init (void)
{
glClearColor (0.5, 0.5, 0.5, 0.0); //清理颜色,为黑色,(也可认为是背景颜色)
makeImage(); //创建纹理数据
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); //设置像素存储方式
glTexImage2D(GL_TEXTURE_2D, 0, 3, ImageWidth, ImageHeight,
0, GL_RGB, GL_UNSIGNED_BYTE, &Image[0][0][0]); //设置纹理信息
//设置s方向纹理重复,为重复设置。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//是指t方向的纹理重复,超出1范围的像素纹理都为1处的纹理像素
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
//设置滤波方式为线性滤波
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
//设置纹理和物体表面颜色处理方式
//只用纹理颜色,不关心物体表面颜色
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//和物体表面颜色做与运算。
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//做融合运算,我还不知道具体是什么东东。
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_BLEND);
//glEnable(GL_BLEND);
//自动生成坐标的方式。
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, sgenparams);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
glTexGenfv(GL_S, GL_OBJECT_PLANE, sgenparams);
//如果有自动生成坐标,他就会自动生成,就算你有glTexCoord2f()。
//glEnable(GL_TEXTURE_GEN_T);
//glEnable(GL_TEXTURE_GEN_S); //启动自动生成s方向自动生成纹理
glEnable(GL_TEXTURE_2D); //启动一维纹理
GLfloat ligPos[] = {0,0,5,0} ;
glLightfv(GL_LIGHT0, GL_POSITION, ligPos);
//glEnable(GL_LIGHTING); //启动光照
glEnable(GL_LIGHT0); //启动第一个光源light0
//glEnable(GL_AUTO_NORMAL); //XXX不知道
//glEnable(GL_NORMALIZE); //XXx不知道
//不知道是什么,用了,球就不能正常显示了。,但是不用,茶壶就不能正常显示了。
//glFrontFace(GL_CW);
glMaterialf (GL_FRONT, GL_SHININESS, 64.0); //设置材质的高光为64
glEnable(GL_DEPTH_TEST); //启动深度裁剪
glDepthFunc(GL_LEQUAL); //裁剪方式为小于等于
glCullFace(GL_BACK); //裁剪方式为背面剔除
glEnable(GL_CULL_FACE); //启动面片剔除
}
//当窗口大小改变时,会调用这个函数
void reshape(GLsizei w,GLsizei h)
{
//这里小说明一下:矩阵模式是不同的,他们各自有一个矩阵。投影相关
//只能用投影矩阵。(只是目前情况下哦,等我学多了可能就知道为什么了。)
glViewport(0,0,w,h); //设置视口
glMatrixMode(GL_PROJECTION); //设置矩阵模式为投影变换矩阵,
glLoadIdentity(); //变为单位矩阵
//gluPerspective(60, (GLfloat)w / h, 0, 1000); //设置投影矩阵
glOrtho(-6.0, 6.0, -6.0 * h / w, 6.0* h / w, -10, 10); //为了不变形,则要长和宽成比例
glMatrixMode(GL_MODELVIEW); //设置矩阵模式为视图矩阵(模型)
glLoadIdentity(); //变为单位矩阵
}
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); //绘制图形时的回调
glutMainLoop(); //主循环。
return 0;
}
这章学的太晕,还需要回头再学习,记得当时也是纹理处了问题换的学习方法,这次还是有问题。呵呵。看来基础不好学这里是会卡壳的。学到的主要有:
设置纹理的流程:
创建纹理数据,书上说必须是2的整数倍,而且最小为64。-->设置纹理数据,用glTexImage2D设置一个二维的纹理数据-->设置纹理映射的控制参数,参数主要包括滤波,重复和简约,函数用glTexParameterf()。映射中和物体表面颜色的处理函数用glTexEnvf等。-->启动纹理.glEnable(GL_TEXTURE_2D);--》绘制图形。主要流程就是这样了。
主要函数:
void glTexImage2D(GLenum target,GLint level,GLint components,GLsizei width, glsizei height,GLint border,GLenum format,GLenum type, const GLvoid *pixels);Target就设置为GL_TEXTURE_2D, level表示纹理分级的级数,我们现在只有一种纹理,就设置为0参数level表示多级分辨率的纹理图像的级数,若只有一种分辨率,则level设为0。components参数是哪些颜色分量进行调整和混合。具体功能不知道,我用的是3,表示RGB。Width,height参数是像素的宽和高,border是边框大小,format是颜色类型,我选择的是GL_RGB,type是数据的类型,就用GL_UNSIGNED_BYTE,pixels参数就是数据源了。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);设置重复设置方式,这里是S方向的,也就是说如果纹理坐标超过了这个范围,就从头算的。
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 滤波方式,这里是线性滤波,也就是说算两个像素的插值时用线性的方法算。这样可以更平滑一点。
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); 就是映射中和物体表面颜色的处理方式,我选择的纹理颜色。
初始化就差不多了,还有很多其他的函数,也不完全清楚是做什么的。
在绘制图形的时候,就用glTexCoord2f(0,0); 来确定纹理的坐标。
这次学的晕晕的,以后再回来学习,函数参数的具体说明请看书上,书上说的很好,可惜我没有消化。哎。。。加油。