Merge branch 'mesa_7_5_branch' into mesa_7_6_branch
[mesa.git] / progs / glsl / texaaline.c
1 /**
2 * AA lines with texture mapped quads
3 *
4 * Brian Paul
5 * 9 Feb 2008
6 */
7
8
9 #include <assert.h>
10 #include <string.h>
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <math.h>
14 #include <GL/glew.h>
15 #include <GL/glut.h>
16
17
18 static GLint WinWidth = 300, WinHeight = 300;
19 static GLint win = 0;
20 static GLfloat Width = 8.;
21
22 /*
23 * Quad strip for line from v0 to v1:
24 *
25 1 3 5 7
26 +---+---------------------+---+
27 | |
28 | *v0 v1* |
29 | |
30 +---+---------------------+---+
31 0 2 4 6
32 */
33 static void
34 QuadLine(const GLfloat *v0, const GLfloat *v1, GLfloat width)
35 {
36 GLfloat dx = v1[0] - v0[0];
37 GLfloat dy = v1[1] - v0[1];
38 GLfloat len = sqrt(dx*dx + dy*dy);
39 float dx0, dx1, dx2, dx3, dx4, dx5, dx6, dx7;
40 float dy0, dy1, dy2, dy3, dy4, dy5, dy6, dy7;
41
42 dx /= len;
43 dy /= len;
44
45 width *= 0.5; /* half width */
46 dx = dx * (width + 0.0);
47 dy = dy * (width + 0.0);
48
49 dx0 = -dx+dy; dy0 = -dy-dx;
50 dx1 = -dx-dy; dy1 = -dy+dx;
51
52 dx2 = 0+dy; dy2 = -dx+0;
53 dx3 = 0-dy; dy3 = +dx+0;
54
55 dx4 = 0+dy; dy4 = -dx+0;
56 dx5 = 0-dy; dy5 = +dx+0;
57
58 dx6 = dx+dy; dy6 = dy-dx;
59 dx7 = dx-dy; dy7 = dy+dx;
60
61 /*
62 printf("dx, dy = %g, %g\n", dx, dy);
63 printf(" dx0, dy0: %g, %g\n", dx0, dy0);
64 printf(" dx1, dy1: %g, %g\n", dx1, dy1);
65 printf(" dx2, dy2: %g, %g\n", dx2, dy2);
66 printf(" dx3, dy3: %g, %g\n", dx3, dy3);
67 */
68
69 glBegin(GL_QUAD_STRIP);
70 glTexCoord2f(0, 0);
71 glVertex2f(v0[0] + dx0, v0[1] + dy0);
72 glTexCoord2f(0, 1);
73 glVertex2f(v0[0] + dx1, v0[1] + dy1);
74
75 glTexCoord2f(0.5, 0);
76 glVertex2f(v0[0] + dx2, v0[1] + dy2);
77 glTexCoord2f(0.5, 1);
78 glVertex2f(v0[0] + dx3, v0[1] + dy3);
79
80 glTexCoord2f(0.5, 0);
81 glVertex2f(v1[0] + dx2, v1[1] + dy2);
82 glTexCoord2f(0.5, 1);
83 glVertex2f(v1[0] + dx3, v1[1] + dy3);
84
85 glTexCoord2f(1, 0);
86 glVertex2f(v1[0] + dx6, v1[1] + dy6);
87 glTexCoord2f(1, 1);
88 glVertex2f(v1[0] + dx7, v1[1] + dy7);
89 glEnd();
90 }
91
92
93 static float Cos(float a)
94 {
95 return cos(a * M_PI / 180.);
96 }
97
98 static float Sin(float a)
99 {
100 return sin(a * M_PI / 180.);
101 }
102
103 static void
104 Redisplay(void)
105 {
106 float cx = 0.5 * WinWidth, cy = 0.5 * WinHeight;
107 float len = 0.5 * WinWidth - 20.0;
108 int i;
109
110 glClear(GL_COLOR_BUFFER_BIT);
111
112 glColor3f(1, 1, 1);
113
114 glEnable(GL_BLEND);
115 glEnable(GL_TEXTURE_2D);
116
117 for (i = 0; i < 360; i+=5) {
118 float v0[2], v1[2];
119 v0[0] = cx + 40 * Cos(i);
120 v0[1] = cy + 40 * Sin(i);
121 v1[0] = cx + len * Cos(i);
122 v1[1] = cy + len * Sin(i);
123 QuadLine(v0, v1, Width);
124 }
125
126 {
127 float v0[2], v1[2], x;
128 for (x = 0; x < 1.0; x += 0.2) {
129 v0[0] = cx + x;
130 v0[1] = cy + x * 40 - 20;
131 v1[0] = cx + x + 5.0;
132 v1[1] = cy + x * 40 - 20;
133 QuadLine(v0, v1, Width);
134 }
135 }
136
137 glDisable(GL_BLEND);
138 glDisable(GL_TEXTURE_2D);
139
140 glutSwapBuffers();
141 }
142
143
144 static void
145 Reshape(int width, int height)
146 {
147 WinWidth = width;
148 WinHeight = height;
149 glViewport(0, 0, width, height);
150 glMatrixMode(GL_PROJECTION);
151 glLoadIdentity();
152 glOrtho(0, width, 0, height, -1, 1);
153 glMatrixMode(GL_MODELVIEW);
154 glLoadIdentity();
155 }
156
157
158 static void
159 CleanUp(void)
160 {
161 glutDestroyWindow(win);
162 }
163
164
165 static void
166 Key(unsigned char key, int x, int y)
167 {
168 (void) x;
169 (void) y;
170
171 switch(key) {
172 case 'w':
173 Width -= 0.5;
174 break;
175 case 'W':
176 Width += 0.5;
177 break;
178 case 27:
179 CleanUp();
180 exit(0);
181 break;
182 }
183 #if 0
184 if (Width < 3)
185 Width = 3;
186 #endif
187 printf("Width = %g\n", Width);
188 glutPostRedisplay();
189 }
190
191
192 static float
193 ramp4(GLint i, GLint size)
194 {
195 float d;
196 if (i < 4 ) {
197 d = i / 4.0;
198 }
199 else if (i >= size - 5) {
200 d = 1.0 - (i - (size - 5)) / 4.0;
201 }
202 else {
203 d = 1.0;
204 }
205 return d;
206 }
207
208 static float
209 ramp2(GLint i, GLint size)
210 {
211 float d;
212 if (i < 2 ) {
213 d = i / 2.0;
214 }
215 else if (i >= size - 3) {
216 d = 1.0 - (i - (size - 3)) / 2.0;
217 }
218 else {
219 d = 1.0;
220 }
221 return d;
222 }
223
224 static float
225 ramp1(GLint i, GLint size)
226 {
227 float d;
228 if (i == 0 || i == size-1) {
229 d = 0.0;
230 }
231 else {
232 d = 1.0;
233 }
234 return d;
235 }
236
237
238 /**
239 * Make an alpha texture for antialiasing lines.
240 * Just a linear fall-off ramp for now.
241 * Should have a number of different textures for different line widths.
242 * Could try a bell-like-curve....
243 */
244 static void
245 MakeTexture(void)
246 {
247 #define SZ 8
248 GLfloat tex[SZ][SZ]; /* alpha tex */
249 int i, j;
250 for (i = 0; i < SZ; i++) {
251 for (j = 0; j < SZ; j++) {
252 #if 0
253 float k = (SZ-1) / 2.0;
254 float dx = fabs(i - k) / k;
255 float dy = fabs(j - k) / k;
256 float d;
257
258 dx = 1.0 - dx;
259 dy = 1.0 - dy;
260 d = dx * dy;
261
262 #else
263 float d = ramp1(i, SZ) * ramp1(j, SZ);
264 printf("%d, %d: %g\n", i, j, d);
265 #endif
266 tex[i][j] = d;
267 }
268 }
269
270 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, SZ, SZ, 0, GL_ALPHA, GL_FLOAT, tex);
271 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
272 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
273 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
274 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
275 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
276 #undef SZ
277 }
278
279
280 static void
281 MakeMipmap(void)
282 {
283 #define SZ 64
284 GLfloat tex[SZ][SZ]; /* alpha tex */
285 int level;
286
287 glPixelStorei(GL_UNPACK_ROW_LENGTH, SZ);
288 for (level = 0; level < 7; level++) {
289 int sz = 1 << (6 - level);
290 int i, j;
291 for (i = 0; i < sz; i++) {
292 for (j = 0; j < sz; j++) {
293 if (level == 6)
294 tex[i][j] = 1.0;
295 else if (level == 5)
296 tex[i][j] = 0.5;
297 else
298 tex[i][j] = ramp1(i, sz) * ramp1(j, sz);
299 }
300 }
301
302 glTexImage2D(GL_TEXTURE_2D, level, GL_ALPHA,
303 sz, sz, 0, GL_ALPHA, GL_FLOAT, tex);
304 }
305
306 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
307 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
308 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
309 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
310 //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4);
311 ////glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5);
312
313 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
314 #undef SZ
315 }
316
317
318 static void
319 Init(void)
320 {
321 const char *version;
322
323 (void) MakeTexture;
324 (void) ramp4;
325 (void) ramp2;
326
327 version = (const char *) glGetString(GL_VERSION);
328 if (version[0] != '2' || version[1] != '.') {
329 printf("This program requires OpenGL 2.x, found %s\n", version);
330 exit(1);
331 }
332
333 glClearColor(0.3f, 0.3f, 0.3f, 0.0f);
334
335 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER));
336
337 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
338 #if 0
339 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
340 #elif 0
341 MakeTexture();
342 #else
343 MakeMipmap();
344 #endif
345 }
346
347
348 static void
349 ParseOptions(int argc, char *argv[])
350 {
351 }
352
353
354 int
355 main(int argc, char *argv[])
356 {
357 glutInit(&argc, argv);
358 glutInitWindowSize(WinWidth, WinHeight);
359 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
360 win = glutCreateWindow(argv[0]);
361 glewInit();
362 glutReshapeFunc(Reshape);
363 glutKeyboardFunc(Key);
364 glutDisplayFunc(Redisplay);
365 ParseOptions(argc, argv);
366 Init();
367 glutMainLoop();
368 return 0;
369 }