以2D表面为例展示纹理贴图,用opengl设置一个2D纹理,颜色存储在32*32*3的数组中,对应的纹理坐标为0<=s, t<=1.0. 画出几个正方形表面,分别以GL_CLAMP(纹理坐标大于1或小于0都被规范到1和0),GL_REPEAT(类似平铺,超过0或1的部分忽略整数位进行贴图),GL_MODULATE(纹理颜色与对象颜色相乘), GL_REPLACE(纹理颜色替换对象颜色)几种形式进行贴图。
1 #include <GLUT/GLUT.h> 2 3 GLsizei winWidht = 500, winHeight = 500; 4 5 void init (void) 6 { 7 glClearColor(1.0, 1.0, 1.0, 0.0); 8 9 glMatrixMode(GL_PROJECTION); 10 glLoadIdentity(); 11 gluOrtho2D(-5, 5, -5, 5); 12 } 13 14 void xyCoords (void) 15 { 16 glBegin(GL_LINES); 17 glColor3f(0.0, 0.0, 0.0); 18 glVertex2i(-10, 0); 19 glVertex2i(10, 0); 20 glVertex2i(0, -10); 21 glVertex2i(0, 10); 22 glEnd(); 23 } 24 25 void lineTextureMapping (void) 26 { 27 GLint k; 28 GLubyte texLine [16]; 29 30 for (k = 0; k <= 2; k +=2) { 31 texLine [4*k] = 0; 32 texLine [4*k+1] = 255; 33 texLine [4*k+2] = 0; 34 texLine [4*k+3] = 255; 35 } 36 37 for (k = 1; k <= 3; k +=2) { 38 texLine [4*k] = 255; 39 texLine [4*k+1] = 0; 40 texLine [4*k+2] = 0; 41 texLine [4*k+3] = 255; 42 } 43 44 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 45 glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 46 47 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texLine); 48 glEnable(GL_TEXTURE_1D); 49 50 glColor3f(1.0, 1.0, 1.0); 51 glBegin(GL_LINES); 52 glTexCoord1f(0.25); 53 glVertex2f(-4.5, 4.0); 54 glTexCoord1f(1.0); 55 glVertex2f(-4.5, -4.0); 56 glEnd(); 57 58 glDisable(GL_TEXTURE_1D); 59 } 60 61 void surfaceTextureMapping (void) 62 { 63 GLint k, j; 64 GLubyte texArray [32][32][4]; 65 66 for (k = 0; k < 32; k++) { 67 for (j = 0; j < 32; j++) { 68 texArray [k][j][0] = 255 - k*j/4; 69 texArray [k][j][1] = 128 + k*j/8; 70 texArray [k][j][2] = 0; 71 texArray [k][j][3] = 255; 72 } 73 } 74 75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 76 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 77 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, texArray); 78 glEnable(GL_TEXTURE_2D); 79 80 glColor3f(0.5, 0.5, 0.5); // 与纹理值相乘,因此会发暗 81 glBegin(GL_QUADS); 82 glTexCoord2f(0.0, 0.0); 83 glVertex2f(0.0, 0.0); 84 glTexCoord2f(3.0, 0.0); 85 glVertex2f(3.0, 0.0); 86 glTexCoord2f(3.0, 3.0); 87 glVertex2f(3.0, 3.0); 88 glTexCoord2f(0.0, 3.0); 89 glVertex2f(0.0, 3.0); 90 glEnd(); 91 92 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 93 glColor3f(0.5, 0.5, 0.5); // 替换为纹理颜色,则不会像前一个图案那样发暗 94 glBegin(GL_QUADS); 95 glTexCoord2f(0.0, 0.0); 96 glVertex2f(-4.0, -4.0); 97 glTexCoord2f(1.0, 0.0); 98 glVertex2f(-1.0, -4.0); 99 glTexCoord2f(1.0, 1.0); 100 glVertex2f(-1.0, -1.0); 101 glTexCoord2f(0.0, 1.0); 102 glVertex2f(-4.0, -1.0); 103 glEnd(); 104 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); 105 106 // 不允许纹理坐标超过1,因此小于0的设为0,大于1的设为1 107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 108 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 109 glColor3f(1.0, 1.0, 1.0); 110 glBegin(GL_QUADS); 111 glTexCoord2f(0.0, 0.0); 112 glVertex2f(-4.0, 0.0); 113 glTexCoord2f(2, 0.0); 114 glVertex2f(-1.0, 0.0); 115 glTexCoord2f(2, 2); 116 glVertex2f(-1.0, 3.0); 117 glTexCoord2f(0.0, 2); 118 glVertex2f(-4.0, 3.0); 119 glEnd(); 120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); 121 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); 122 123 glDisable(GL_TEXTURE_2D); 124 } 125 126 void displayFcn (void) 127 { 128 glClear(GL_COLOR_BUFFER_BIT); 129 130 // lineTextureMapping(); 131 surfaceTextureMapping(); 132 xyCoords(); 133 134 glFlush(); 135 } 136 137 void winReshapeFcn (GLint newWidth, GLint newHeight) 138 { 139 glViewport(0, 0, newWidth, newHeight); 140 } 141 142 int main(int argc, char * argv[]) 143 { 144 glutInit(&argc, argv); 145 glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); 146 glutInitWindowSize(winWidht, winHeight); 147 glutInitWindowPosition(100, 100); 148 glutCreateWindow("texture mapping"); 149 150 init(); 151 glutDisplayFunc(displayFcn); 152 glutReshapeFunc(winReshapeFcn); 153 glutMainLoop(); 154 155 return 0; 156 }