以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>View Code
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 }