~ubuntu-branches/ubuntu/natty/mesa/natty-proposed

« back to all changes in this revision

Viewing changes to progs/demos/projtex.c

  • Committer: Bazaar Package Importer
  • Author(s): Robert Hooker, Robert Hooker, Christopher James Halse Rogers
  • Date: 2010-09-14 08:55:40 UTC
  • mfrom: (1.2.28 upstream)
  • Revision ID: james.westby@ubuntu.com-20100914085540-m4fpl0hdjlfd4jgz
Tags: 7.9~git20100909-0ubuntu1
[ Robert Hooker ]
* New upstream git snapshot up to commit 94118fe2d4b1e5 (LP: #631413)
* New features include ATI HD5xxx series support in r600, and a vastly
  improved glsl compiler.
* Remove pre-generated .pc's, use the ones generated at build time
  instead.
* Remove all references to mesa-utils now that its no longer shipped
  with the mesa source.
* Disable the experimental ARB_fragment_shader option by default on
  i915, it exposes incomplete functionality that breaks KDE compositing
  among other things. It can be enabled via driconf still. (LP: #628930).

[ Christopher James Halse Rogers ]
* debian/patches/04_osmesa_version.diff:
  - Refresh for new upstream
* Bugs fixed in this release:
  - Fixes severe rendering corruption in Unity on radeon (LP: #628727,
    LP: #596292, LP: #599741, LP: #630315, LP: #613694, LP: #599741).
  - Also fixes rendering in gnome-shell (LP: #578619).
  - Flickering in OpenGL apps on radeon (LP: #626943, LP: #610541).
  - Provides preliminary support for new intel chips (LP: #601052).
* debian/rules:
  - Update configure flags to match upstream reshuffling.
  - Explicitly remove gallium DRI drivers that we don't want to ship.
* Update debian/gbp.conf for this Maverick-specific packaging
* libegl1-mesa-dri-x11,kms: There are no longer separate kms or x11 drivers
  for EGL, libegl1-mesa-drivers now contains a single driver that provides
  both backends.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
/* projtex.c - by David Yu and David Blythe, SGI */
3
 
 
4
 
/**
5
 
 ** Demonstrates simple projective texture mapping.
6
 
 **
7
 
 ** Button1 changes view, Button2 moves texture.
8
 
 **
9
 
 ** (See: Segal, Korobkin, van Widenfelt, Foran, and Haeberli
10
 
 **  "Fast Shadows and Lighting Effects Using Texture Mapping", SIGGRAPH '92)
11
 
 **
12
 
 ** 1994,1995 -- David G Yu
13
 
 **
14
 
 ** cc -o projtex projtex.c texture.c -lglut -lGLU -lGL -lX11 -lm
15
 
 **/
16
 
 
17
 
#include <assert.h>
18
 
#include <stdio.h>
19
 
#include <stdlib.h>
20
 
#include <math.h>
21
 
#include <GL/glew.h>
22
 
#include <GL/glut.h>
23
 
#include "readtex.h"
24
 
 
25
 
 
26
 
/* Some <math.h> files do not define M_PI... */
27
 
#ifndef M_PI
28
 
#define M_PI 3.14159265358979323846
29
 
#endif
30
 
 
31
 
#define MAX_TEX 4
32
 
int NumTextures = 1;
33
 
 
34
 
int winWidth, winHeight;
35
 
 
36
 
GLboolean redrawContinuously = GL_FALSE;
37
 
 
38
 
float angle, axis[3];
39
 
enum MoveModes {
40
 
  MoveNone, MoveView, MoveObject, MoveTexture
41
 
};
42
 
enum MoveModes mode = MoveNone;
43
 
 
44
 
GLfloat objectXform[4][4];
45
 
GLfloat textureXform[MAX_TEX][4][4];
46
 
 
47
 
void (*drawObject) (void);
48
 
void (*loadTexture) (void);
49
 
GLboolean textureEnabled = GL_TRUE;
50
 
GLboolean showProjection = GL_TRUE;
51
 
GLboolean linearFilter = GL_TRUE;
52
 
 
53
 
char *texFilename[MAX_TEX] = {
54
 
   "../images/girl.rgb",
55
 
   "../images/tile.rgb",
56
 
   "../images/bw.rgb",
57
 
   "../images/reflect.rgb"
58
 
};
59
 
 
60
 
 
61
 
GLfloat zoomFactor = 1.0;
62
 
 
63
 
/*****************************************************************/
64
 
 
65
 
 
66
 
static void
67
 
ActiveTexture(int i)
68
 
{
69
 
   glActiveTextureARB(i);
70
 
}
71
 
 
72
 
 
73
 
/* matrix = identity */
74
 
static void
75
 
matrixIdentity(GLfloat matrix[16])
76
 
{
77
 
  matrix[0] = 1.0;
78
 
  matrix[1] = 0.0;
79
 
  matrix[2] = 0.0;
80
 
  matrix[3] = 0.0;
81
 
  matrix[4] = 0.0;
82
 
  matrix[5] = 1.0;
83
 
  matrix[6] = 0.0;
84
 
  matrix[7] = 0.0;
85
 
  matrix[8] = 0.0;
86
 
  matrix[9] = 0.0;
87
 
  matrix[10] = 1.0;
88
 
  matrix[11] = 0.0;
89
 
  matrix[12] = 0.0;
90
 
  matrix[13] = 0.0;
91
 
  matrix[14] = 0.0;
92
 
  matrix[15] = 1.0;
93
 
}
94
 
 
95
 
/* matrix2 = transpose(matrix1) */
96
 
static void
97
 
matrixTranspose(GLfloat matrix2[16], GLfloat matrix1[16])
98
 
{
99
 
  matrix2[0] = matrix1[0];
100
 
  matrix2[1] = matrix1[4];
101
 
  matrix2[2] = matrix1[8];
102
 
  matrix2[3] = matrix1[12];
103
 
 
104
 
  matrix2[4] = matrix1[1];
105
 
  matrix2[5] = matrix1[5];
106
 
  matrix2[6] = matrix1[9];
107
 
  matrix2[7] = matrix1[13];
108
 
 
109
 
  matrix2[8] = matrix1[2];
110
 
  matrix2[9] = matrix1[6];
111
 
  matrix2[10] = matrix1[10];
112
 
  matrix2[11] = matrix1[14];
113
 
 
114
 
  matrix2[12] = matrix1[3];
115
 
  matrix2[13] = matrix1[7];
116
 
  matrix2[14] = matrix1[14];
117
 
  matrix2[15] = matrix1[15];
118
 
}
119
 
 
120
 
/*****************************************************************/
121
 
 
122
 
/* load SGI .rgb image (pad with a border of the specified width and color) */
123
 
#if 0
124
 
static void
125
 
imgLoad(char *filenameIn, int borderIn, GLfloat borderColorIn[4],
126
 
  int *wOut, int *hOut, GLubyte ** imgOut)
127
 
{
128
 
  int border = borderIn;
129
 
  int width, height;
130
 
  int w, h;
131
 
  GLubyte *image, *img, *p;
132
 
  int i, j, components;
133
 
 
134
 
  image = (GLubyte *) read_texture(filenameIn, &width, &height, &components);
135
 
  w = width + 2 * border;
136
 
  h = height + 2 * border;
137
 
  img = (GLubyte *) calloc(w * h, 4 * sizeof(unsigned char));
138
 
 
139
 
  p = img;
140
 
  for (j = -border; j < height + border; ++j) {
141
 
    for (i = -border; i < width + border; ++i) {
142
 
      if (0 <= j && j <= height - 1 && 0 <= i && i <= width - 1) {
143
 
        p[0] = image[4 * (j * width + i) + 0];
144
 
        p[1] = image[4 * (j * width + i) + 1];
145
 
        p[2] = image[4 * (j * width + i) + 2];
146
 
        p[3] = 0xff;
147
 
      } else {
148
 
        p[0] = borderColorIn[0] * 0xff;
149
 
        p[1] = borderColorIn[1] * 0xff;
150
 
        p[2] = borderColorIn[2] * 0xff;
151
 
        p[3] = borderColorIn[3] * 0xff;
152
 
      }
153
 
      p += 4;
154
 
    }
155
 
  }
156
 
  free(image);
157
 
  *wOut = w;
158
 
  *hOut = h;
159
 
  *imgOut = img;
160
 
}
161
 
#endif
162
 
 
163
 
 
164
 
/*****************************************************************/
165
 
 
166
 
/* Load the image file specified on the command line as the current texture */
167
 
static void
168
 
loadImageTextures(void)
169
 
{
170
 
  GLfloat borderColor[4] =
171
 
  {1.0, 1.0, 1.0, 1.0};
172
 
  int tex;
173
 
 
174
 
  for (tex = 0; tex < NumTextures; tex++) {
175
 
     GLubyte *image, *texData3, *texData4;
176
 
     GLint imgWidth, imgHeight;
177
 
     GLenum imgFormat;
178
 
     int i, j;
179
 
 
180
 
     printf("loading %s\n", texFilename[tex]);
181
 
     image = LoadRGBImage(texFilename[tex], &imgWidth, &imgHeight, &imgFormat);
182
 
     if (!image) {
183
 
        printf("can't find %s\n", texFilename[tex]);
184
 
        exit(1);
185
 
     }
186
 
     assert(imgFormat == GL_RGB);
187
 
 
188
 
     /* scale to 256x256 */
189
 
     texData3 = malloc(256 * 256 * 4);
190
 
     texData4 = malloc(256 * 256 * 4);
191
 
     assert(texData3);
192
 
     assert(texData4);
193
 
     gluScaleImage(imgFormat, imgWidth, imgHeight, GL_UNSIGNED_BYTE, image,
194
 
                   256, 256, GL_UNSIGNED_BYTE, texData3);
195
 
 
196
 
     /* convert to rgba */
197
 
     for (i = 0; i < 256 * 256; i++) {
198
 
        texData4[i*4+0] = texData3[i*3+0];
199
 
        texData4[i*4+1] = texData3[i*3+1];
200
 
        texData4[i*4+2] = texData3[i*3+2];
201
 
        texData4[i*4+3] = 128;
202
 
     }
203
 
 
204
 
     /* put transparent border around image */
205
 
     for (i = 0; i < 256; i++) {
206
 
        texData4[i*4+0] = 255;
207
 
        texData4[i*4+1] = 255;
208
 
        texData4[i*4+2] = 255;
209
 
        texData4[i*4+3] = 0;
210
 
     }
211
 
     j = 256 * 255 * 4;
212
 
     for (i = 0; i < 256; i++) {
213
 
        texData4[j + i*4+0] = 255;
214
 
        texData4[j + i*4+1] = 255;
215
 
        texData4[j + i*4+2] = 255;
216
 
        texData4[j + i*4+3] = 0;
217
 
     }
218
 
     for (i = 0; i < 256; i++) {
219
 
        j = i * 256 * 4;
220
 
        texData4[j+0] = 255;
221
 
        texData4[j+1] = 255;
222
 
        texData4[j+2] = 255;
223
 
        texData4[j+3] = 0;
224
 
     }
225
 
     for (i = 0; i < 256; i++) {
226
 
        j = i * 256 * 4 + 255 * 4;
227
 
        texData4[j+0] = 255;
228
 
        texData4[j+1] = 255;
229
 
        texData4[j+2] = 255;
230
 
        texData4[j+3] = 0;
231
 
     }
232
 
 
233
 
     ActiveTexture(GL_TEXTURE0_ARB + tex);
234
 
     glBindTexture(GL_TEXTURE_2D, tex + 1);
235
 
 
236
 
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
237
 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0,
238
 
                  GL_RGBA, GL_UNSIGNED_BYTE, texData4);
239
 
 
240
 
     if (linearFilter) {
241
 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
242
 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
243
 
     } else {
244
 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
245
 
       glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
246
 
     }
247
 
     glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
248
 
 
249
 
     free(texData3);
250
 
     free(texData4);
251
 
     free(image);
252
 
  }
253
 
}
254
 
 
255
 
/* Create a simple spotlight pattern and make it the current texture */
256
 
static void
257
 
loadSpotlightTexture(void)
258
 
{
259
 
  static int texWidth = 64, texHeight = 64;
260
 
  static GLubyte *texData;
261
 
  GLfloat borderColor[4] =
262
 
  {0.1, 0.1, 0.1, 1.0};
263
 
 
264
 
  if (!texData) {
265
 
    GLubyte *p;
266
 
    int i, j;
267
 
 
268
 
    texData = (GLubyte *) malloc(texWidth * texHeight * 4 * sizeof(GLubyte));
269
 
 
270
 
    p = texData;
271
 
    for (j = 0; j < texHeight; ++j) {
272
 
      float dy = (texHeight * 0.5 - j + 0.5) / (texHeight * 0.5);
273
 
 
274
 
      for (i = 0; i < texWidth; ++i) {
275
 
        float dx = (texWidth * 0.5 - i + 0.5) / (texWidth * 0.5);
276
 
        float r = cos(M_PI / 2.0 * sqrt(dx * dx + dy * dy));
277
 
        float c;
278
 
 
279
 
        r = (r < 0) ? 0 : r * r;
280
 
        c = 0xff * (r + borderColor[0]);
281
 
        p[0] = (c <= 0xff) ? c : 0xff;
282
 
        c = 0xff * (r + borderColor[1]);
283
 
        p[1] = (c <= 0xff) ? c : 0xff;
284
 
        c = 0xff * (r + borderColor[2]);
285
 
        p[2] = (c <= 0xff) ? c : 0xff;
286
 
        c = 0xff * (r + borderColor[3]);
287
 
        p[3] = (c <= 0xff) ? c : 0xff;
288
 
        p += 4;
289
 
      }
290
 
    }
291
 
  }
292
 
  if (linearFilter) {
293
 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
294
 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
295
 
  } else {
296
 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
297
 
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
298
 
  }
299
 
  glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
300
 
  gluBuild2DMipmaps(GL_TEXTURE_2D, 4, texWidth, texHeight,
301
 
    GL_RGBA, GL_UNSIGNED_BYTE, texData);
302
 
}
303
 
 
304
 
/*****************************************************************/
305
 
 
306
 
static void
307
 
checkErrors(void)
308
 
{
309
 
  GLenum error;
310
 
  while ((error = glGetError()) != GL_NO_ERROR) {
311
 
    fprintf(stderr, "Error: %s\n", (char *) gluErrorString(error));
312
 
  }
313
 
}
314
 
 
315
 
static void
316
 
drawCube(void)
317
 
{
318
 
  glBegin(GL_QUADS);
319
 
 
320
 
  glNormal3f(-1.0, 0.0, 0.0);
321
 
  glColor3f(0.80, 0.50, 0.50);
322
 
  glVertex3f(-0.5, -0.5, -0.5);
323
 
  glVertex3f(-0.5, -0.5, 0.5);
324
 
  glVertex3f(-0.5, 0.5, 0.5);
325
 
  glVertex3f(-0.5, 0.5, -0.5);
326
 
 
327
 
  glNormal3f(1.0, 0.0, 0.0);
328
 
  glColor3f(0.50, 0.80, 0.50);
329
 
  glVertex3f(0.5, 0.5, 0.5);
330
 
  glVertex3f(0.5, -0.5, 0.5);
331
 
  glVertex3f(0.5, -0.5, -0.5);
332
 
  glVertex3f(0.5, 0.5, -0.5);
333
 
 
334
 
  glNormal3f(0.0, -1.0, 0.0);
335
 
  glColor3f(0.50, 0.50, 0.80);
336
 
  glVertex3f(-0.5, -0.5, -0.5);
337
 
  glVertex3f(0.5, -0.5, -0.5);
338
 
  glVertex3f(0.5, -0.5, 0.5);
339
 
  glVertex3f(-0.5, -0.5, 0.5);
340
 
 
341
 
  glNormal3f(0.0, 1.0, 0.0);
342
 
  glColor3f(0.50, 0.80, 0.80);
343
 
  glVertex3f(0.5, 0.5, 0.5);
344
 
  glVertex3f(0.5, 0.5, -0.5);
345
 
  glVertex3f(-0.5, 0.5, -0.5);
346
 
  glVertex3f(-0.5, 0.5, 0.5);
347
 
 
348
 
  glNormal3f(0.0, 0.0, -1.0);
349
 
  glColor3f(0.80, 0.50, 0.80);
350
 
  glVertex3f(-0.5, -0.5, -0.5);
351
 
  glVertex3f(-0.5, 0.5, -0.5);
352
 
  glVertex3f(0.5, 0.5, -0.5);
353
 
  glVertex3f(0.5, -0.5, -0.5);
354
 
 
355
 
  glNormal3f(0.0, 0.0, 1.0);
356
 
  glColor3f(1.00, 0.80, 0.50);
357
 
  glVertex3f(0.5, 0.5, 0.5);
358
 
  glVertex3f(-0.5, 0.5, 0.5);
359
 
  glVertex3f(-0.5, -0.5, 0.5);
360
 
  glVertex3f(0.5, -0.5, 0.5);
361
 
  glEnd();
362
 
}
363
 
 
364
 
static void
365
 
drawDodecahedron(void)
366
 
{
367
 
#define A (0.5 * 1.61803)  /* (sqrt(5) + 1) / 2 */
368
 
#define B (0.5 * 0.61803)  /* (sqrt(5) - 1) / 2 */
369
 
#define C (0.5 * 1.0)
370
 
  GLfloat vertexes[20][3] =
371
 
  {
372
 
    {-A, 0.0, B},
373
 
    {-A, 0.0, -B},
374
 
    {A, 0.0, -B},
375
 
    {A, 0.0, B},
376
 
    {B, -A, 0.0},
377
 
    {-B, -A, 0.0},
378
 
    {-B, A, 0.0},
379
 
    {B, A, 0.0},
380
 
    {0.0, B, -A},
381
 
    {0.0, -B, -A},
382
 
    {0.0, -B, A},
383
 
    {0.0, B, A},
384
 
    {-C, -C, C},
385
 
    {-C, -C, -C},
386
 
    {C, -C, -C},
387
 
    {C, -C, C},
388
 
    {-C, C, C},
389
 
    {-C, C, -C},
390
 
    {C, C, -C},
391
 
    {C, C, C},
392
 
  };
393
 
#undef A
394
 
#undef B
395
 
#undef C
396
 
  GLint polygons[12][5] =
397
 
  {
398
 
    {0, 12, 10, 11, 16},
399
 
    {1, 17, 8, 9, 13},
400
 
    {2, 14, 9, 8, 18},
401
 
    {3, 19, 11, 10, 15},
402
 
    {4, 14, 2, 3, 15},
403
 
    {5, 12, 0, 1, 13},
404
 
    {6, 17, 1, 0, 16},
405
 
    {7, 19, 3, 2, 18},
406
 
    {8, 17, 6, 7, 18},
407
 
    {9, 14, 4, 5, 13},
408
 
    {10, 12, 5, 4, 15},
409
 
    {11, 19, 7, 6, 16},
410
 
  };
411
 
  int i;
412
 
 
413
 
  glColor3f(0.75, 0.75, 0.75);
414
 
  for (i = 0; i < 12; ++i) {
415
 
    GLfloat *p0, *p1, *p2, d;
416
 
    GLfloat u[3], v[3], n[3];
417
 
 
418
 
    p0 = &vertexes[polygons[i][0]][0];
419
 
    p1 = &vertexes[polygons[i][1]][0];
420
 
    p2 = &vertexes[polygons[i][2]][0];
421
 
 
422
 
    u[0] = p2[0] - p1[0];
423
 
    u[1] = p2[1] - p1[1];
424
 
    u[2] = p2[2] - p1[2];
425
 
 
426
 
    v[0] = p0[0] - p1[0];
427
 
    v[1] = p0[1] - p1[1];
428
 
    v[2] = p0[2] - p1[2];
429
 
 
430
 
    n[0] = u[1] * v[2] - u[2] * v[1];
431
 
    n[1] = u[2] * v[0] - u[0] * v[2];
432
 
    n[2] = u[0] * v[1] - u[1] * v[0];
433
 
 
434
 
    d = 1.0 / sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]);
435
 
    n[0] *= d;
436
 
    n[1] *= d;
437
 
    n[2] *= d;
438
 
 
439
 
    glBegin(GL_POLYGON);
440
 
    glNormal3fv(n);
441
 
    glVertex3fv(p0);
442
 
    glVertex3fv(p1);
443
 
    glVertex3fv(p2);
444
 
    glVertex3fv(vertexes[polygons[i][3]]);
445
 
    glVertex3fv(vertexes[polygons[i][4]]);
446
 
    glEnd();
447
 
  }
448
 
}
449
 
 
450
 
static void
451
 
drawSphere(void)
452
 
{
453
 
  int numMajor = 24;
454
 
  int numMinor = 32;
455
 
  float radius = 0.8;
456
 
  double majorStep = (M_PI / numMajor);
457
 
  double minorStep = (2.0 * M_PI / numMinor);
458
 
  int i, j;
459
 
 
460
 
  glColor3f(0.50, 0.50, 0.50);
461
 
  for (i = 0; i < numMajor; ++i) {
462
 
    double a = i * majorStep;
463
 
    double b = a + majorStep;
464
 
    double r0 = radius * sin(a);
465
 
    double r1 = radius * sin(b);
466
 
    GLfloat z0 = radius * cos(a);
467
 
    GLfloat z1 = radius * cos(b);
468
 
 
469
 
    glBegin(GL_TRIANGLE_STRIP);
470
 
    for (j = 0; j <= numMinor; ++j) {
471
 
      double c = j * minorStep;
472
 
      GLfloat x = cos(c);
473
 
      GLfloat y = sin(c);
474
 
 
475
 
      glNormal3f((x * r0) / radius, (y * r0) / radius, z0 / radius);
476
 
      glTexCoord2f(j / (GLfloat) numMinor, i / (GLfloat) numMajor);
477
 
      glVertex3f(x * r0, y * r0, z0);
478
 
 
479
 
      glNormal3f((x * r1) / radius, (y * r1) / radius, z1 / radius);
480
 
      glTexCoord2f(j / (GLfloat) numMinor, (i + 1) / (GLfloat) numMajor);
481
 
      glVertex3f(x * r1, y * r1, z1);
482
 
    }
483
 
    glEnd();
484
 
  }
485
 
}
486
 
 
487
 
/*****************************************************************/
488
 
 
489
 
float xmin = -0.035, xmax = 0.035;
490
 
float ymin = -0.035, ymax = 0.035;
491
 
float nnear = 0.1;
492
 
float ffar = 1.9;
493
 
float distance = -1.0;
494
 
 
495
 
static void
496
 
loadTextureProjection(int texUnit, GLfloat m[16])
497
 
{
498
 
  GLfloat mInverse[4][4];
499
 
 
500
 
  /* Should use true inverse, but since m consists only of rotations, we can
501
 
     just use the transpose. */
502
 
  matrixTranspose((GLfloat *) mInverse, m);
503
 
 
504
 
  ActiveTexture(GL_TEXTURE0_ARB + texUnit);
505
 
  glMatrixMode(GL_TEXTURE);
506
 
  glLoadIdentity();
507
 
  glTranslatef(0.5, 0.5, 0.0);
508
 
  glScalef(0.5, 0.5, 1.0);
509
 
  glFrustum(xmin, xmax, ymin, ymax, nnear, ffar);
510
 
  glTranslatef(0.0, 0.0, distance);
511
 
  glMultMatrixf((GLfloat *) mInverse);
512
 
  glMatrixMode(GL_MODELVIEW);
513
 
}
514
 
 
515
 
static void
516
 
drawTextureProjection(void)
517
 
{
518
 
  float t = ffar / nnear;
519
 
  GLfloat n[4][3];
520
 
  GLfloat f[4][3];
521
 
 
522
 
  n[0][0] = xmin;
523
 
  n[0][1] = ymin;
524
 
  n[0][2] = -(nnear + distance);
525
 
 
526
 
  n[1][0] = xmax;
527
 
  n[1][1] = ymin;
528
 
  n[1][2] = -(nnear + distance);
529
 
 
530
 
  n[2][0] = xmax;
531
 
  n[2][1] = ymax;
532
 
  n[2][2] = -(nnear + distance);
533
 
 
534
 
  n[3][0] = xmin;
535
 
  n[3][1] = ymax;
536
 
  n[3][2] = -(nnear + distance);
537
 
 
538
 
  f[0][0] = xmin * t;
539
 
  f[0][1] = ymin * t;
540
 
  f[0][2] = -(ffar + distance);
541
 
 
542
 
  f[1][0] = xmax * t;
543
 
  f[1][1] = ymin * t;
544
 
  f[1][2] = -(ffar + distance);
545
 
 
546
 
  f[2][0] = xmax * t;
547
 
  f[2][1] = ymax * t;
548
 
  f[2][2] = -(ffar + distance);
549
 
 
550
 
  f[3][0] = xmin * t;
551
 
  f[3][1] = ymax * t;
552
 
  f[3][2] = -(ffar + distance);
553
 
 
554
 
  glColor3f(1.0, 1.0, 0.0);
555
 
  glBegin(GL_LINE_LOOP);
556
 
  glVertex3fv(n[0]);
557
 
  glVertex3fv(n[1]);
558
 
  glVertex3fv(n[2]);
559
 
  glVertex3fv(n[3]);
560
 
  glVertex3fv(f[3]);
561
 
  glVertex3fv(f[2]);
562
 
  glVertex3fv(f[1]);
563
 
  glVertex3fv(f[0]);
564
 
  glVertex3fv(n[0]);
565
 
  glVertex3fv(n[1]);
566
 
  glVertex3fv(f[1]);
567
 
  glVertex3fv(f[0]);
568
 
  glVertex3fv(f[3]);
569
 
  glVertex3fv(f[2]);
570
 
  glVertex3fv(n[2]);
571
 
  glVertex3fv(n[3]);
572
 
  glEnd();
573
 
}
574
 
 
575
 
/*****************************************************************/
576
 
 
577
 
static void
578
 
initialize(void)
579
 
{
580
 
  GLfloat light0Pos[4] =
581
 
  {0.3, 0.3, 0.0, 1.0};
582
 
  GLfloat matAmb[4] =
583
 
  {0.01, 0.01, 0.01, 1.00};
584
 
  GLfloat matDiff[4] =
585
 
  {0.65, 0.65, 0.65, 1.00};
586
 
  GLfloat matSpec[4] =
587
 
  {0.30, 0.30, 0.30, 1.00};
588
 
  GLfloat matShine = 10.0;
589
 
  GLfloat eyePlaneS[] =
590
 
  {1.0, 0.0, 0.0, 0.0};
591
 
  GLfloat eyePlaneT[] =
592
 
  {0.0, 1.0, 0.0, 0.0};
593
 
  GLfloat eyePlaneR[] =
594
 
  {0.0, 0.0, 1.0, 0.0};
595
 
  GLfloat eyePlaneQ[] =
596
 
  {0.0, 0.0, 0.0, 1.0};
597
 
  int i;
598
 
 
599
 
  /* Setup Misc.  */
600
 
  glClearColor(0.41, 0.41, 0.31, 0.0);
601
 
 
602
 
  glEnable(GL_DEPTH_TEST);
603
 
 
604
 
  /*  glLineWidth(2.0);*/
605
 
 
606
 
  glCullFace(GL_FRONT);
607
 
  glEnable(GL_CULL_FACE);
608
 
 
609
 
  glMatrixMode(GL_PROJECTION);
610
 
  glFrustum(-0.5, 0.5, -0.5, 0.5, 1, 3);
611
 
  glMatrixMode(GL_MODELVIEW);
612
 
  glTranslatef(0, 0, -2);
613
 
 
614
 
  matrixIdentity((GLfloat *) objectXform);
615
 
  for (i = 0; i < NumTextures; i++) {
616
 
     matrixIdentity((GLfloat *) textureXform[i]);
617
 
  }
618
 
 
619
 
  glMatrixMode(GL_PROJECTION);
620
 
  glPushMatrix();
621
 
  glLoadIdentity();
622
 
  glOrtho(0, 1, 0, 1, -1, 1);
623
 
  glMatrixMode(GL_MODELVIEW);
624
 
  glPushMatrix();
625
 
  glLoadIdentity();
626
 
 
627
 
  glRasterPos2i(0, 0);
628
 
 
629
 
  glPopMatrix();
630
 
  glMatrixMode(GL_PROJECTION);
631
 
  glPopMatrix();
632
 
  glMatrixMode(GL_MODELVIEW);
633
 
 
634
 
  /* Setup Lighting */
635
 
  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmb);
636
 
  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiff);
637
 
  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpec);
638
 
  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, matShine);
639
 
 
640
 
  glEnable(GL_COLOR_MATERIAL);
641
 
 
642
 
  glLightfv(GL_LIGHT0, GL_POSITION, light0Pos);
643
 
  glEnable(GL_LIGHT0);
644
 
 
645
 
  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
646
 
  glEnable(GL_LIGHTING);
647
 
 
648
 
  /* Setup Texture */
649
 
 
650
 
  (*loadTexture) ();
651
 
 
652
 
 
653
 
  for (i = 0; i < NumTextures; i++) {
654
 
     ActiveTexture(GL_TEXTURE0_ARB + i);
655
 
 
656
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
657
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
658
 
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
659
 
 
660
 
     glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
661
 
     glTexGenfv(GL_S, GL_EYE_PLANE, eyePlaneS);
662
 
 
663
 
     glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
664
 
     glTexGenfv(GL_T, GL_EYE_PLANE, eyePlaneT);
665
 
 
666
 
     glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
667
 
     glTexGenfv(GL_R, GL_EYE_PLANE, eyePlaneR);
668
 
 
669
 
     glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
670
 
     glTexGenfv(GL_Q, GL_EYE_PLANE, eyePlaneQ);
671
 
  }
672
 
}
673
 
 
674
 
static void
675
 
display(void)
676
 
{
677
 
  int i;
678
 
 
679
 
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
680
 
 
681
 
  if (textureEnabled) {
682
 
    if (mode == MoveTexture || mode == MoveView) {
683
 
      /* Have OpenGL compute the new transformation (simple but slow). */
684
 
      for (i = 0; i < NumTextures; i++) {
685
 
        glPushMatrix();
686
 
        glLoadIdentity();
687
 
#if 0
688
 
        if (i & 1)
689
 
           glRotatef(angle, axis[0], axis[1], axis[2]);
690
 
        else
691
 
#endif
692
 
           glRotatef(angle*(i+1), axis[0], axis[1], axis[2]);
693
 
 
694
 
        glMultMatrixf((GLfloat *) textureXform[i]);
695
 
        glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) textureXform[i]);
696
 
        glPopMatrix();
697
 
      }
698
 
    }
699
 
    for (i = 0; i < NumTextures; i++) {
700
 
       loadTextureProjection(i, (GLfloat *) textureXform[i]);
701
 
    }
702
 
 
703
 
    if (showProjection) {
704
 
      for (i = 0; i < NumTextures; i++) {
705
 
        ActiveTexture(GL_TEXTURE0_ARB + i);
706
 
        glPushMatrix();
707
 
        glMultMatrixf((GLfloat *) textureXform[i]);
708
 
        glDisable(GL_LIGHTING);
709
 
        drawTextureProjection();
710
 
        glEnable(GL_LIGHTING);
711
 
        glPopMatrix();
712
 
      }
713
 
    }
714
 
    for (i = 0; i < NumTextures; i++) {
715
 
      ActiveTexture(GL_TEXTURE0_ARB + i);
716
 
      glEnable(GL_TEXTURE_2D);
717
 
      glEnable(GL_TEXTURE_GEN_S);
718
 
      glEnable(GL_TEXTURE_GEN_T);
719
 
      glEnable(GL_TEXTURE_GEN_R);
720
 
      glEnable(GL_TEXTURE_GEN_Q);
721
 
    }
722
 
  }
723
 
  if (mode == MoveObject || mode == MoveView) {
724
 
    /* Have OpenGL compute the new transformation (simple but slow). */
725
 
    glPushMatrix();
726
 
    glLoadIdentity();
727
 
    glRotatef(angle, axis[0], axis[1], axis[2]);
728
 
    glMultMatrixf((GLfloat *) objectXform);
729
 
    glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) objectXform);
730
 
    glPopMatrix();
731
 
  }
732
 
  glPushMatrix();
733
 
  glMultMatrixf((GLfloat *) objectXform);
734
 
  (*drawObject) ();
735
 
  glPopMatrix();
736
 
 
737
 
  for (i = 0; i < NumTextures; i++) {
738
 
    ActiveTexture(GL_TEXTURE0_ARB + i);
739
 
    glDisable(GL_TEXTURE_2D);
740
 
    glDisable(GL_TEXTURE_GEN_S);
741
 
    glDisable(GL_TEXTURE_GEN_T);
742
 
    glDisable(GL_TEXTURE_GEN_R);
743
 
    glDisable(GL_TEXTURE_GEN_Q);
744
 
  }
745
 
 
746
 
  if (zoomFactor > 1.0) {
747
 
    glDisable(GL_DEPTH_TEST);
748
 
    glCopyPixels(0, 0, winWidth / zoomFactor, winHeight / zoomFactor, GL_COLOR);
749
 
    glEnable(GL_DEPTH_TEST);
750
 
  }
751
 
  glFlush();
752
 
  glutSwapBuffers();
753
 
  checkErrors();
754
 
}
755
 
 
756
 
/*****************************************************************/
757
 
 
758
 
/* simple trackball-like motion control */
759
 
static float lastPos[3];
760
 
static int lastTime;
761
 
 
762
 
static void
763
 
ptov(int x, int y, int width, int height, float v[3])
764
 
{
765
 
  float d, a;
766
 
 
767
 
  /* project x,y onto a hemi-sphere centered within width, height */
768
 
  v[0] = (2.0 * x - width) / width;
769
 
  v[1] = (height - 2.0 * y) / height;
770
 
  d = sqrt(v[0] * v[0] + v[1] * v[1]);
771
 
  v[2] = cos((M_PI / 2.0) * ((d < 1.0) ? d : 1.0));
772
 
  a = 1.0 / sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
773
 
  v[0] *= a;
774
 
  v[1] *= a;
775
 
  v[2] *= a;
776
 
}
777
 
 
778
 
static void
779
 
startMotion(int x, int y, int but, int time)
780
 
{
781
 
  if (but == GLUT_LEFT_BUTTON) {
782
 
    mode = MoveView;
783
 
  } else if (but == GLUT_MIDDLE_BUTTON) {
784
 
    mode = MoveTexture;
785
 
  } else {
786
 
    return;
787
 
  }
788
 
 
789
 
  lastTime = time;
790
 
  ptov(x, y, winWidth, winHeight, lastPos);
791
 
}
792
 
 
793
 
static void
794
 
animate(void)
795
 
{
796
 
  glutPostRedisplay();
797
 
}
798
 
 
799
 
static void
800
 
vis(int visible)
801
 
{
802
 
  if (visible == GLUT_VISIBLE) {
803
 
    if (redrawContinuously)
804
 
      glutIdleFunc(animate);
805
 
  } else {
806
 
    if (redrawContinuously)
807
 
      glutIdleFunc(NULL);
808
 
  }
809
 
}
810
 
 
811
 
static void
812
 
stopMotion(int but, int time)
813
 
{
814
 
  if ((but == GLUT_LEFT_BUTTON && mode == MoveView) ||
815
 
    (but == GLUT_MIDDLE_BUTTON && mode == MoveTexture)) {
816
 
  } else {
817
 
    return;
818
 
  }
819
 
 
820
 
  if (time == lastTime) {
821
 
     /*    redrawContinuously = GL_TRUE;*/
822
 
    glutIdleFunc(animate);
823
 
  } else {
824
 
    angle = 0.0;
825
 
    redrawContinuously = GL_FALSE;
826
 
    glutIdleFunc(0);
827
 
  }
828
 
  if (!redrawContinuously) {
829
 
    mode = MoveNone;
830
 
  }
831
 
}
832
 
 
833
 
static void
834
 
trackMotion(int x, int y)
835
 
{
836
 
  float curPos[3], dx, dy, dz;
837
 
 
838
 
  ptov(x, y, winWidth, winHeight, curPos);
839
 
 
840
 
  dx = curPos[0] - lastPos[0];
841
 
  dy = curPos[1] - lastPos[1];
842
 
  dz = curPos[2] - lastPos[2];
843
 
  angle = 90.0 * sqrt(dx * dx + dy * dy + dz * dz);
844
 
 
845
 
  axis[0] = lastPos[1] * curPos[2] - lastPos[2] * curPos[1];
846
 
  axis[1] = lastPos[2] * curPos[0] - lastPos[0] * curPos[2];
847
 
  axis[2] = lastPos[0] * curPos[1] - lastPos[1] * curPos[0];
848
 
 
849
 
  lastTime = glutGet(GLUT_ELAPSED_TIME);
850
 
  lastPos[0] = curPos[0];
851
 
  lastPos[1] = curPos[1];
852
 
  lastPos[2] = curPos[2];
853
 
  glutPostRedisplay();
854
 
}
855
 
 
856
 
/*****************************************************************/
857
 
 
858
 
static void
859
 
object(void)
860
 
{
861
 
  static int object;
862
 
 
863
 
  object++;
864
 
  object %= 3;
865
 
  switch (object) {
866
 
  case 0:
867
 
    drawObject = drawCube;
868
 
    break;
869
 
  case 1:
870
 
    drawObject = drawDodecahedron;
871
 
    break;
872
 
  case 2:
873
 
    drawObject = drawSphere;
874
 
    break;
875
 
  default:
876
 
    break;
877
 
  }
878
 
}
879
 
 
880
 
static void
881
 
nop(void)
882
 
{
883
 
}
884
 
 
885
 
static void
886
 
texture(void)
887
 
{
888
 
  static int texture = 0;
889
 
 
890
 
  texture++;
891
 
  texture %= 3;
892
 
  if (texture == 1 && texFilename == NULL) {
893
 
    /* Skip file texture if not loaded. */
894
 
    texture++;
895
 
  }
896
 
  switch (texture) {
897
 
  case 0:
898
 
    loadTexture = nop;
899
 
    textureEnabled = GL_FALSE;
900
 
    break;
901
 
  case 1:
902
 
    loadTexture = loadImageTextures;
903
 
    (*loadTexture) ();
904
 
    textureEnabled = GL_TRUE;
905
 
    break;
906
 
  case 2:
907
 
    loadTexture = loadSpotlightTexture;
908
 
    (*loadTexture) ();
909
 
    textureEnabled = GL_TRUE;
910
 
    break;
911
 
  default:
912
 
    break;
913
 
  }
914
 
}
915
 
 
916
 
static void
917
 
help(void)
918
 
{
919
 
  printf("'h'   - help\n");
920
 
  printf("'l'   - toggle linear/nearest filter\n");
921
 
  printf("'s'   - toggle projection frustum\n");
922
 
  printf("'t'   - toggle projected texture\n");
923
 
  printf("'o'   - toggle object\n");
924
 
  printf("'z'   - increase zoom factor\n");
925
 
  printf("'Z'   - decrease zoom factor\n");
926
 
  printf("left mouse     - move view\n");
927
 
  printf("middle mouse   - move projection\n");
928
 
}
929
 
 
930
 
/* ARGSUSED1 */
931
 
static void
932
 
key(unsigned char key, int x, int y)
933
 
{
934
 
  switch (key) {
935
 
  case '\033':
936
 
    exit(0);
937
 
    break;
938
 
  case 'l':
939
 
    linearFilter = !linearFilter;
940
 
    (*loadTexture) ();
941
 
    break;
942
 
  case 's':
943
 
    showProjection = !showProjection;
944
 
    break;
945
 
  case 't':
946
 
    texture();
947
 
    break;
948
 
  case 'o':
949
 
    object();
950
 
    break;
951
 
  case 'z':
952
 
    zoomFactor += 1.0;
953
 
    glPixelZoom(zoomFactor, zoomFactor);
954
 
    glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor);
955
 
    break;
956
 
  case 'Z':
957
 
    zoomFactor -= 1.0;
958
 
    if (zoomFactor < 1.0)
959
 
      zoomFactor = 1.0;
960
 
    glPixelZoom(zoomFactor, zoomFactor);
961
 
    glViewport(0, 0, winWidth / zoomFactor, winHeight / zoomFactor);
962
 
    break;
963
 
  case 'h':
964
 
    help();
965
 
    break;
966
 
  }
967
 
  glutPostRedisplay();
968
 
}
969
 
 
970
 
static void
971
 
mouse(int button, int state, int x, int y)
972
 
{
973
 
  if (state == GLUT_DOWN)
974
 
    startMotion(x, y, button, glutGet(GLUT_ELAPSED_TIME));
975
 
  else if (state == GLUT_UP)
976
 
    stopMotion(button, glutGet(GLUT_ELAPSED_TIME));
977
 
  glutPostRedisplay();
978
 
}
979
 
 
980
 
static void
981
 
reshape(int w, int h)
982
 
{
983
 
  winWidth = w;
984
 
  winHeight = h;
985
 
  glViewport(0, 0, w / zoomFactor, h / zoomFactor);
986
 
}
987
 
 
988
 
 
989
 
static void
990
 
menu(int selection)
991
 
{
992
 
  if (selection == 666) {
993
 
    exit(0);
994
 
  }
995
 
  key((unsigned char) selection, 0, 0);
996
 
}
997
 
 
998
 
int
999
 
main(int argc, char **argv)
1000
 
{
1001
 
  glutInitWindowSize(500,500);
1002
 
  glutInit(&argc, argv);
1003
 
  glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
1004
 
  (void) glutCreateWindow("projtex");
1005
 
  glewInit();
1006
 
 
1007
 
  if (argc > 1) {
1008
 
     NumTextures = atoi(argv[1]);
1009
 
  }
1010
 
  assert(NumTextures <= MAX_TEX);
1011
 
 
1012
 
  loadTexture = loadImageTextures;
1013
 
  drawObject = drawCube;
1014
 
  initialize();
1015
 
  glutDisplayFunc(display);
1016
 
  glutKeyboardFunc(key);
1017
 
  glutReshapeFunc(reshape);
1018
 
  glutMouseFunc(mouse);
1019
 
  glutMotionFunc(trackMotion);
1020
 
  glutVisibilityFunc(vis);
1021
 
  glutCreateMenu(menu);
1022
 
  glutAddMenuEntry("Toggle showing projection", 's');
1023
 
  glutAddMenuEntry("Switch texture", 't');
1024
 
  glutAddMenuEntry("Switch object", 'o');
1025
 
  glutAddMenuEntry("Toggle filtering", 'l');
1026
 
  glutAddMenuEntry("Quit", 666);
1027
 
  glutAttachMenu(GLUT_RIGHT_BUTTON);
1028
 
  texture();
1029
 
  glutMainLoop();
1030
 
  return 0;             /* ANSI C requires main to return int. */
1031
 
}