可以让OpenGL自动生成纹理坐标,而不是使用glTexCoord*()函数显示地分配纹理坐标
void glTexGeni (GLenum coord, GLenum pname, GLint param);
coord | pname | param |
{GL_S,GL_T}或{GL_R,GL_Q} | GL_TEXTURE_GEN_MODE | GL_OBJECT_LINEAR GL_EYE_LINEAR GL_SPHERE_MAP GL_NORMAL_MAP GL_REFLECTION_MAP |
GL_OBJECT_PLANE | 浮点型数值 | |
GL_EYE_PLANE | 浮点型数值 |
GL_OBJECT_LINEAR:物体模式,纹理会跟随物体的转动而转动(左图)
GL_EYE_LINEAR:视觉模式,纹理部会跟随物体的转动而转动,始终保持原状(右图)
GL_SPHERE_MAP:环境纹理(球体贴图)具有很好的反射效果
GL_REFLECTION_MAP:环境纹理(反射纹理)可替换GL_SPHERE_MAP
GL_NORMAL_MAP:常用于立方体贴图,或者散射与反射的场景
GL_NORMAL_MAP球体贴图 GL_REFLECTION_MAP球体贴图
纹理贴图做法
1设置纹理环绕模式
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
2.设置纹理生成模式
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
3.启用自动生成纹理
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
立方图纹理
立方图纹理是一种比较特殊的纹理技术,它用6幅二维图像构成一个以原点为中心的纹理立方体,对于每个片段,纹理坐标(S,T,R)被当做方向向量看待,每个纹理单元都表示从原点所看到的纹理立方体上的图像
可以调用glTexImage2D函数6次,分别使用他target参数表示立方体的各个面(+X,-X,+Y,-Y,+Z,-Z)从而创建一个立方体
glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image4); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image2); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image5); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image3); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image6); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
#include "header.h" #define stripeImageWidth 16 #define checkImageWidth 16 #define checkImageHeight 16 #define imageSize 4 static GLubyte image1[imageSize][imageSize][4]; static GLubyte image2[imageSize][imageSize][4]; static GLubyte image3[imageSize][imageSize][4]; static GLubyte image4[imageSize][imageSize][4]; static GLubyte image5[imageSize][imageSize][4]; static GLubyte image6[imageSize][imageSize][4]; static GLubyte checkImage[checkImageWidth][checkImageHeight][4]; static GLubyte stripeImage[4*stripeImageWidth]; static GLuint texName; static GLfloat xequalzero[] = {1.0, 0.0, 0.0, 0.0}; static GLfloat slanted[] = {1.0, 1.0, 1.0, 0.0}; static GLfloat *currentCoeff; static GLenum currentPlane; static GLint currentGenMode; double angle=0.0; enum Shape { CUBE, SPHERE, TEAPOT, CONE }shape; shape=TEAPOT; void makeImage() { int i,j,c; for ( i=0;i<checkImageWidth;i++) { for (j = 0; j < checkImageHeight; j++) { if(j%4==0) { checkImage[i][j][0]=0; checkImage[i][j][1]=255; checkImage[i][j][2]=0; checkImage[i][j][3]=255;; j++; if(j>=checkImageHeight) { break; } checkImage[i][j][0]=0; checkImage[i][j][1]=255; checkImage[i][j][2]=0; checkImage[i][j][3]=255;; }else { checkImage[i][j][0]=255; checkImage[i][j][1]=0; checkImage[i][j][2]=0; checkImage[i][j][3]=255; } } } for (i = 0; i < imageSize; i++) { for (j = 0; j < imageSize; j++) { //c = ((((i&0x1)==0)^((j&0x1))==0))*255; image1[i][j][0] = (GLubyte) 255; image1[i][j][1] = (GLubyte) 0; image1[i][j][2] = (GLubyte) 0; image1[i][j][3] = (GLubyte) 255; image2[i][j][0] = (GLubyte) 0; image2[i][j][1] = (GLubyte) 255; image2[i][j][2] = (GLubyte) 0; image2[i][j][3] = (GLubyte) 255; image3[i][j][0] = (GLubyte) 0; image3[i][j][1] = (GLubyte) 0; image3[i][j][2] = (GLubyte) 255; image3[i][j][3] = (GLubyte) 255; image4[i][j][0] = (GLubyte) 255; image4[i][j][1] = (GLubyte) 255; image4[i][j][2] = (GLubyte) 0; image4[i][j][3] = (GLubyte) 255; image5[i][j][0] = (GLubyte) 255; image5[i][j][1] = (GLubyte) 0; image5[i][j][2] = (GLubyte) 255; image5[i][j][3] = (GLubyte) 255; image6[i][j][0] = (GLubyte) 0; image6[i][j][1] = (GLubyte) 255; image6[i][j][2] = (GLubyte) 255; image6[i][j][3] = (GLubyte) 255; } } } void display(void) { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //glRotated(-90,1,0,0); glRotated(angle,0,1,1); glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_CUBE_MAP_EXT); glBindTexture(GL_TEXTURE_2D,texName); if(shape==TEAPOT) { glEnable(GL_TEXTURE_2D); glutSolidTeapot(100); }else if(shape==SPHERE) { glEnable(GL_TEXTURE_2D); glutSolidSphere(100,50,32); }else if(shape==CUBE) { glEnable(GL_TEXTURE_CUBE_MAP_EXT); glutSolidCube(100); }else if(shape==CONE) { glEnable(GL_TEXTURE_2D); glutWireCone(200,200,16,16); } glutSwapBuffers(); glFlush(); } void init() { makeImage(); glClearColor(0,0,0,0); glClearDepth(1.0); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glShadeModel(GL_SMOOTH); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glGenTextures(1,&texName); glBindTexture(GL_TEXTURE_2D,texName); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, checkImageWidth, checkImageHeight,0,GL_RGBA, GL_UNSIGNED_BYTE, checkImage); 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_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); } void reshape(int w, int h) { glViewport(0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-400,400,-300,300,-1000,1000); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void keyboard(unsigned char key,int x,int y) { switch (key) { case 't': shape=TEAPOT; //glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); //glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glutPostRedisplay(); break; case 's': shape=SPHERE; glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); glutPostRedisplay(); break; case 'c': shape=CUBE; glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_R, GL_REPEAT); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image4); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image2); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image5); glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image3); glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT, 0, GL_RGBA, imageSize, imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image6); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); //glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); //glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); glutPostRedisplay(); break; case 'n': shape=CONE; //glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); //glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glutPostRedisplay(); break; case 'e': glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR); glutPostRedisplay(); break; case 'o': glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glutPostRedisplay(); break; } } void rotate() { angle+=0.1; glutPostRedisplay(); } void mouse(int button,int state,int x,int y) { switch(button) { case GLUT_LEFT_BUTTON: if(GLUT_DOWN==state) { glutIdleFunc(rotate); } break; case GLUT_RIGHT_BUTTON: if(GLUT_DOWN==state) { glutIdleFunc(0); } break; } } int main(int argc,char **argv) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH); glutInitWindowSize(800,600); glutInitWindowPosition(100,100); glutCreateWindow("纹理坐标自动生成"); glewInit(); init(); glutDisplayFunc(display); glutKeyboardFunc(keyboard); glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMainLoop(); }