1/*
2 * Test cylindrical texcoord wrapping
3 */
4
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <math.h>
9#include "glut_wrap.h"
10
11static int Win;
12static int WinWidth = 600, WinHeight = 400;
13static GLfloat Xrot = 0, Yrot = 0;
14static GLboolean CylWrap = GL_TRUE;
15static GLboolean Lines = GL_FALSE;
16
17
18
19static void
20PrintString(const char *s)
21{
22   while (*s) {
23      glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
24      s++;
25   }
26}
27
28
29static void
30DrawSample(GLboolean wrap)
31{
32   float p;
33
34   glEnable(GL_TEXTURE_2D);
35
36   if (Lines) {
37      /* texured lines */
38      float t;
39      for (t = 0; t <= 1.0; t += 0.125) {
40         float y = -1.0 + 2.0 * t;
41         glBegin(GL_LINE_STRIP);
42         for (p = 0.0; p <= 1.001; p += 0.05) {
43            float x = -2.0 + p * 4.0;
44            float s = p + 0.5;
45            if (wrap && s > 1.0)
46               s -= 1.0;
47            glTexCoord2f(s, t);  glVertex2f(x, y);
48         }
49         glEnd();
50      }
51   }
52   else {
53      /* texured quads */
54      glBegin(GL_QUAD_STRIP);
55      for (p = 0.0; p <= 1.001; p += 0.1) {
56         float x = -2.0 + p * 4.0;
57         float s = p + 0.5;
58         if (wrap && s > 1.0)
59            s -= 1.0;
60         glTexCoord2f(s, 0);  glVertex2f(x, -1);
61         glTexCoord2f(s, 1);  glVertex2f(x, +1);
62      }
63      glEnd();
64   }
65
66   glDisable(GL_TEXTURE_2D);
67
68   /* hash marks */
69   glColor3f(0,0,0);
70   glBegin(GL_LINES);
71   for (p = 0.0; p <= 1.001; p += 0.1) {
72      float x = -2.0 + p * 4.0;
73      glVertex2f(x, -1.1);
74      glVertex2f(x, -0.8);
75   }
76   glEnd();
77
78   /* labels */
79   glColor3f(1,1,1);
80   for (p = 0.0; p <= 1.001; p += 0.1) {
81      char str[100];
82      float x = -2.0 + p * 4.0;
83      float s = p + 0.5;
84
85      if (wrap && s > 1.0)
86         s -= 1.0;
87
88      sprintf(str, "%3.1f", s);
89      glRasterPos2f(x, -1.2);
90      glBitmap(0, 0, 0, 0, -11, 0, NULL);
91      PrintString(str);
92      if (p == 0.0) {
93         glBitmap(0, 0, 0, 0, -55, 0, NULL);
94         PrintString("s =");
95      }
96   }
97}
98
99
100static void
101Draw(void)
102{
103   glClear(GL_COLOR_BUFFER_BIT);
104
105   glPushMatrix();
106      glRotatef(Xrot, 1, 0, 0);
107      glRotatef(Yrot, 0, 1, 0);
108
109      glPushMatrix();
110         glTranslatef(0, +1.2, 0);
111         DrawSample(GL_FALSE);
112      glPopMatrix();
113
114      /* set Mesa back-door state for testing cylindrical wrap mode */
115      if (CylWrap)
116         glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 0.125);
117
118      glPushMatrix();
119         glTranslatef(0, -1.2, 0);
120         DrawSample(GL_TRUE);
121      glPopMatrix();
122
123      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_PRIORITY, 1.0);
124
125   glPopMatrix();
126
127   glutSwapBuffers();
128}
129
130
131static void
132Reshape(int width, int height)
133{
134   WinWidth = width;
135   WinHeight = height;
136   glViewport(0, 0, width, height);
137   glMatrixMode(GL_PROJECTION);
138   glLoadIdentity();
139   glFrustum(-1.0, 1.0, -1.0, 1.0, 3.0, 25.0);
140   glMatrixMode(GL_MODELVIEW);
141   glLoadIdentity();
142   glTranslatef(0.0, 0.0, -10.0);
143}
144
145
146static void
147Key(unsigned char key, int x, int y)
148{
149   (void) x;
150   (void) y;
151   switch (key) {
152   case 'c':
153   case 'C':
154      CylWrap = !CylWrap;
155      if (CylWrap)
156         printf("Cylindrical wrap on.\n");
157      else
158         printf("Cylindrical wrap off.\n");
159      break;
160   case 'l':
161   case 'L':
162      Lines = !Lines;
163      break;
164   case 27:
165      glutDestroyWindow(Win);
166      exit(0);
167      break;
168   }
169   glutPostRedisplay();
170}
171
172
173static void
174SpecialKey(int key, int x, int y)
175{
176   const GLfloat step = 3.0;
177   (void) x;
178   (void) y;
179   switch (key) {
180   case GLUT_KEY_UP:
181      Xrot -= step;
182      break;
183   case GLUT_KEY_DOWN:
184      Xrot += step;
185      break;
186   case GLUT_KEY_LEFT:
187      Yrot -= step;
188      break;
189   case GLUT_KEY_RIGHT:
190      Yrot += step;
191      break;
192   }
193   glutPostRedisplay();
194}
195
196
197static void
198MakeSineWaveTexture(void)
199{
200   GLubyte tex[128][512][4];
201   int i, j;
202
203   for (j = 0; j < 128; j++) {
204      for (i = 0; i < 512; i++) {
205         float x = i / 511.0 * 2.0 * M_PI + M_PI * 0.5;
206         float y0 = sin(x) * 0.5 + 0.5;
207         int jy0 = y0 * 128;
208         float y1 = sin(x + M_PI) * 0.5 + 0.5;
209         int jy1 = y1 * 128;
210         if (j < jy0)
211            tex[j][i][0] = 0xff;
212         else
213            tex[j][i][0] = 0;
214         if (j < jy1)
215            tex[j][i][1] = 0xff;
216         else
217            tex[j][i][1] = 0;
218         tex[j][i][2] = 0;
219         tex[j][i][3] = 0xff;
220      }
221   }
222
223   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 128, 0,
224                GL_RGBA, GL_UNSIGNED_BYTE, tex);
225   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
226   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
227   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
228}
229
230
231static void
232Init(void)
233{
234   glBindTexture(GL_TEXTURE_2D, 5);
235   MakeSineWaveTexture();
236
237   glClearColor(0.5, 0.5, 0.5, 0.0);
238   glPointSize(3.0);
239
240   printf("Press 'c' to toggle cylindrical wrap mode.\n");
241   printf("Press 'l' to toggle line / quad drawing.\n");
242}
243
244
245int
246main(int argc, char *argv[])
247{
248   glutInit(&argc, argv);
249   glutInitWindowSize(WinWidth, WinHeight);
250   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
251   Win = glutCreateWindow(argv[0]);
252   glutReshapeFunc(Reshape);
253   glutSpecialFunc(SpecialKey);
254   glutKeyboardFunc(Key);
255   glutDisplayFunc(Draw);
256   Init();
257   glutMainLoop();
258   return 0;
259}
260