这里讨论的是二维纹理
1.图取图像数据
void readimage(char* filename, BYTE* imagedata)//所读图片均为24位bmp,且宽度补齐至四字节边界
{
BITMAPFILEHEADER bf; //文件头
BITMAPINFOHEADER bi; //信息头
int m_ImageWidth; //图象宽度
int m_ImageHeight; //图象高度
FILE *fp1; //文件指针,fp1为源文件
//打开文件,到文件指针
if ((fp1 = fopen(filename, "rb")) == NULL)
{
MessageBox(NULL, "文件打开错误", "warning", MB_OK);
}
fread((LPSTR)&bf, sizeof(BITMAPFILEHEADER), 1, fp1); //读取文件头,读取以后文件指针在文件头末尾(即信息头)
fread((LPSTR)&bi, sizeof(BITMAPINFOHEADER), 1, fp1); //读取信息头
m_ImageWidth = bi.biWidth; //给图象宽度赋值
m_ImageHeight = bi.biHeight; //给图象高度赋值
fread(imagedata, m_ImageHeight*m_ImageWidth * 3, 1, fp1); //读取图象数据
fclose(fp1);
}
注意:读进来的图像为BGR,要调整为RGB
void adjustimage(BYTE* imagedata, int w, int h)
{
BYTE temp;
for (int i = 0; iglEnable(GL_TEXTURE_2D);
注意:图像的像素要与数组对应,下面的是256*256
//------------------------设置纹理----------------------------------
void loadtexture()
{
glGenTextures(2, &texName);//2表示有两个纹理
glBindTexture(GL_TEXTURE_2D, texName);
{
BYTE imagemoon[256][256][3]; //墙壁2的纹理
readimage("D:\\wall2.bmp", &imagemoon[0][0][0]);
adjustimage(&imagemoon[0][0][0], 256, 256);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, imagemoon);
}
{
BYTE imagesky[256][256][3];
readimage("D:\\wall1.bmp", &imagesky[0][0][0]);//墙壁1的纹理
adjustimage(&imagesky[0][0][0], 256, 256);
glBindTexture(GL_TEXTURE_2D, texName + 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, imagesky);
}
}
glEnable(GL_TEXTURE_2D);
例子:坐标要对应,纹理用单位表示,(0.0,0.0)表示左下角(1.0,1.0)表示右上角
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//printf("At:%.2f %.2f %.2f\n",r*cos(c*du),h,r*sin(c*du)); //这就是视点的坐标
glLoadIdentity();
gluLookAt(r*cos(c*du), h, r*sin(c*du), 0, 0, 0, 0, 1, 0); //从视点看远点,y轴方向(0,1,0)是上方向
glColor3f(1.0f, 0.0f, 0.0f);
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
//地面
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texName + 2);
glColor3f(0.0, 1.0, 1.0);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3f(5.0f,-2.0f,3.0f);
glTexCoord2f(1.0, 0.0); glVertex3f(-5.0f, -2.0f, 3.0f);
glTexCoord2f(1.0, 1.0); glVertex3f(-5.0f, -2.0f, -3.0f);
glTexCoord2f(0.0, 1.0); glVertex3f(5.0f, -2.0f, -3.0f);
glEnd();
//左墙
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texName + 1);
glBegin(GL_POLYGON);
glTexCoord2f(0.0, 0.0); glVertex3f(-2.0, 0.0, 1.5);
glTexCoord2f(0.0, 0.66); glVertex3f(-2.0, 2.0, 1.5);
glTexCoord2f(0.5, 1.0); glVertex3f(-2.0, 3.0, 0.0);
glTexCoord2f(1.0, 0.66); glVertex3f(-2.0, 2.0, -1.5);
glTexCoord2f(1.0, 0.0); glVertex3f(-2.0, 0.0, -1.5);
glEnd();
glPopMatrix();
glFlush();
glutSwapBuffers();
glDisable(GL_TEXTURE_2D);
}
5.对于圆柱和圆锥
将圆柱和圆锥看做是由很多线组成的,使用三角函数和一个循环就可以画出
//圆柱
glTranslatef(-3.0, -2.0, 2.0);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texName );
glBegin( GL_QUAD_STRIP);
double t = 0.0;double dt = 2*PI/nslice;
for (int j = 0; j <= nslice; ++j)
{
glTexCoord2f( t/(2*PI), 1.0); glVertex3f( cos( t), 2.0, -sin( t));
glTexCoord2f( t/(2*PI), 0.0); glVertex3f( cos( t), 0.0, -sin( t));
t = t + dt;
}
glEnd();
glPopMatrix();
//圆锥
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texName + 4 );
glBegin( GL_QUAD_STRIP);
double tt = 0.0;double dtt = 2*PI/nslice;
for (int j = 0; j <= nslice; ++j)
{
glTexCoord2f( tt/(2*PI), 1.0); glVertex3f( 0.0, 2.0, 0.0);
glTexCoord2f( tt/(2*PI), 0.0); glVertex3f( cos( tt), 0.0, -sin( tt));
tt = tt + dtt;
}
glEnd();
glPopMatrix();