132001f49Smrg/*
232001f49Smrg * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
332001f49Smrg *
432001f49Smrg * Permission to use, copy, modify, distribute, and sell this software and
532001f49Smrg * its documentation for any purpose is hereby granted without fee, provided
632001f49Smrg * that (i) the above copyright notices and this permission notice appear in
732001f49Smrg * all copies of the software and related documentation, and (ii) the name of
832001f49Smrg * Silicon Graphics may not be used in any advertising or
932001f49Smrg * publicity relating to the software without the specific, prior written
1032001f49Smrg * permission of Silicon Graphics.
1132001f49Smrg *
1232001f49Smrg * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
1332001f49Smrg * ANY KIND,
1432001f49Smrg * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
1532001f49Smrg * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
1632001f49Smrg *
1732001f49Smrg * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
1832001f49Smrg * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
1932001f49Smrg * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
2032001f49Smrg * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
2132001f49Smrg * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
2232001f49Smrg * OF THIS SOFTWARE.
2332001f49Smrg */
2432001f49Smrg
2532001f49Smrg#include <stdio.h>
2632001f49Smrg#include <string.h>
2732001f49Smrg#include <stdlib.h>
2832001f49Smrg#include "glut_wrap.h"
2932001f49Smrg
3032001f49Smrg
3132001f49Smrg#define	SOLID 1
3232001f49Smrg#define	LINE 2
3332001f49Smrg#define	POINT 3
3432001f49Smrg
3532001f49Smrg
3632001f49SmrgGLenum rgb, doubleBuffer, windType;
3732001f49SmrgGLint windW, windH;
3832001f49Smrg
3932001f49SmrgGLenum dithering = GL_TRUE;
4032001f49SmrgGLenum showVerticies = GL_TRUE;
4132001f49SmrgGLenum hideBottomTriangle = GL_FALSE;
4232001f49SmrgGLenum outline = GL_TRUE;
4332001f49SmrgGLenum culling = GL_FALSE;
4432001f49SmrgGLenum winding = GL_FALSE;
4532001f49SmrgGLenum face = GL_FALSE;
4632001f49SmrgGLenum state = SOLID;
4732001f49SmrgGLenum aaMode = GL_FALSE;
4832001f49SmrgGLenum shade = GL_TRUE;
4932001f49Smrg
5032001f49SmrgGLint color1, color2, color3;
5132001f49Smrg
5232001f49Smrgfloat zRotation = 90.0;
5332001f49Smrgfloat zoom = 1.0;
5432001f49Smrg
5532001f49Smrgfloat boxA[3] = {-100, -100, 0};
5632001f49Smrgfloat boxB[3] = { 100, -100, 0};
5732001f49Smrgfloat boxC[3] = { 100,  100, 0};
5832001f49Smrgfloat boxD[3] = {-100,  100, 0};
5932001f49Smrg
6032001f49Smrgfloat p0[3] = {-125,-80, 0};
6132001f49Smrgfloat p1[3] = {-125, 80, 0};
6232001f49Smrgfloat p2[3] = { 172,  0, 0};
6332001f49Smrg
6432001f49Smrg
6532001f49Smrg#include "tkmap.c"
6632001f49Smrg
6732001f49Smrgstatic void Init(void)
6832001f49Smrg{
6932001f49Smrg    float r, g, b;
7032001f49Smrg    float percent1, percent2;
7132001f49Smrg    GLint i, j;
7232001f49Smrg
7332001f49Smrg    glClearColor(0.0, 0.0, 0.0, 0.0);
7432001f49Smrg
7532001f49Smrg    glLineStipple(1, 0xF0F0);
7632001f49Smrg
7732001f49Smrg    glEnable(GL_SCISSOR_TEST);
7832001f49Smrg
7932001f49Smrg    if (!rgb) {
8032001f49Smrg	for (j = 0; j <= 12; j++) {
8132001f49Smrg	    if (j <= 6) {
8232001f49Smrg		percent1 = j / 6.0;
8332001f49Smrg		r = 1.0 - 0.8 * percent1;
8432001f49Smrg		g = 0.2 + 0.8 * percent1;
8532001f49Smrg		b = 0.2;
8632001f49Smrg	    } else {
8732001f49Smrg		percent1 = (j - 6) / 6.0;
8832001f49Smrg		r = 0.2;
8932001f49Smrg		g = 1.0 - 0.8 * percent1;
9032001f49Smrg		b = 0.2 + 0.8 * percent1;
9132001f49Smrg	    }
9232001f49Smrg	    glutSetColor(j+18, r, g, b);
9332001f49Smrg	    for (i = 0; i < 16; i++) {
9432001f49Smrg		percent2 = i / 15.0;
9532001f49Smrg		glutSetColor(j*16+1+32, r*percent2, g*percent2, b*percent2);
9632001f49Smrg	    }
9732001f49Smrg	}
9832001f49Smrg	color1 = 18;
9932001f49Smrg	color2 = 24;
10032001f49Smrg	color3 = 30;
10132001f49Smrg    }
10232001f49Smrg}
10332001f49Smrg
10432001f49Smrgstatic void Reshape(int width, int height)
10532001f49Smrg{
10632001f49Smrg
10732001f49Smrg    windW = (GLint)width;
10832001f49Smrg    windH = (GLint)height;
10932001f49Smrg}
11032001f49Smrg
11132001f49Smrgstatic void Key2(int key, int x, int y)
11232001f49Smrg{
11332001f49Smrg
11432001f49Smrg    switch (key) {
11532001f49Smrg      case GLUT_KEY_LEFT:
11632001f49Smrg	zRotation += 0.5;
11732001f49Smrg	break;
11832001f49Smrg      case GLUT_KEY_RIGHT:
11932001f49Smrg	zRotation -= 0.5;
12032001f49Smrg	break;
12132001f49Smrg      default:
12232001f49Smrg	return;
12332001f49Smrg    }
12432001f49Smrg
12532001f49Smrg    glutPostRedisplay();
12632001f49Smrg}
12732001f49Smrg
12832001f49Smrgstatic void Key(unsigned char key, int x, int y)
12932001f49Smrg{
13032001f49Smrg
13132001f49Smrg    switch (key) {
13232001f49Smrg      case 27:
13332001f49Smrg	exit(1);
13432001f49Smrg      case 'Z':
13532001f49Smrg	zoom *= 0.75;
13632001f49Smrg	break;
13732001f49Smrg      case 'z':
13832001f49Smrg	zoom /= 0.75;
13932001f49Smrg	if (zoom > 10) {
14032001f49Smrg	    zoom = 10;
14132001f49Smrg	}
14232001f49Smrg	break;
14332001f49Smrg      case '1':
14432001f49Smrg	glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
14532001f49Smrg	break;
14632001f49Smrg      case '2':
14732001f49Smrg	glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
14832001f49Smrg	break;
14932001f49Smrg      case '3':
15032001f49Smrg	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
15132001f49Smrg	break;
15232001f49Smrg      case '4':
15332001f49Smrg	state = POINT;
15432001f49Smrg	break;
15532001f49Smrg      case '5':
15632001f49Smrg	state = LINE;
15732001f49Smrg	break;
15832001f49Smrg      case '6':
15932001f49Smrg	state = SOLID;
16032001f49Smrg	break;
16132001f49Smrg      case '7':
16232001f49Smrg	culling = !culling;
16332001f49Smrg	break;
16432001f49Smrg      case '8':
16532001f49Smrg	winding = !winding;
16632001f49Smrg	break;
16732001f49Smrg      case '9':
16832001f49Smrg	face = !face;
16932001f49Smrg	break;
17032001f49Smrg      case 'v':
17132001f49Smrg	showVerticies = !showVerticies;
17232001f49Smrg	break;
17332001f49Smrg      case 's':
17432001f49Smrg	shade = !shade;
17532001f49Smrg	(shade) ? glShadeModel(GL_SMOOTH) : glShadeModel(GL_FLAT);
17632001f49Smrg	break;
17732001f49Smrg      case 'h':
17832001f49Smrg	hideBottomTriangle = !hideBottomTriangle;
17932001f49Smrg	break;
18032001f49Smrg      case 'o':
18132001f49Smrg	outline = !outline;
18232001f49Smrg	break;
18332001f49Smrg      case 'm':
18432001f49Smrg	dithering = !dithering;
18532001f49Smrg	break;
18632001f49Smrg      case '0':
18732001f49Smrg	aaMode = !aaMode;
18832001f49Smrg	if (aaMode) {
18932001f49Smrg	    glEnable(GL_POLYGON_SMOOTH);
19032001f49Smrg	    glEnable(GL_BLEND);
19132001f49Smrg	    glBlendFunc(GL_SRC_ALPHA, GL_ONE);
19232001f49Smrg	    if (!rgb) {
19332001f49Smrg		color1 = 32;
19432001f49Smrg		color2 = 128;
19532001f49Smrg		color3 = 224;
19632001f49Smrg	    }
19732001f49Smrg	} else {
19832001f49Smrg	    glDisable(GL_POLYGON_SMOOTH);
19932001f49Smrg	    glDisable(GL_BLEND);
20032001f49Smrg	    if (!rgb) {
20132001f49Smrg		color1 = 18;
20232001f49Smrg		color2 = 24;
20332001f49Smrg		color3 = 30;
20432001f49Smrg	    }
20532001f49Smrg	}
20632001f49Smrg	break;
20732001f49Smrg      default:
20832001f49Smrg	return;
20932001f49Smrg    }
21032001f49Smrg
21132001f49Smrg    glutPostRedisplay();
21232001f49Smrg}
21332001f49Smrg
21432001f49Smrgstatic void BeginPrim(void)
21532001f49Smrg{
21632001f49Smrg
21732001f49Smrg    switch (state) {
21832001f49Smrg      case SOLID:
21932001f49Smrg	glBegin(GL_POLYGON);
22032001f49Smrg	break;
22132001f49Smrg      case LINE:
22232001f49Smrg	glBegin(GL_LINE_LOOP);
22332001f49Smrg	break;
22432001f49Smrg      case POINT:
22532001f49Smrg	glBegin(GL_POINTS);
22632001f49Smrg	break;
22732001f49Smrg      default:
22832001f49Smrg        break;
22932001f49Smrg    }
23032001f49Smrg}
23132001f49Smrg
23232001f49Smrgstatic void EndPrim(void)
23332001f49Smrg{
23432001f49Smrg
23532001f49Smrg    glEnd();
23632001f49Smrg}
23732001f49Smrg
23832001f49Smrgstatic void Draw(void)
23932001f49Smrg{
24032001f49Smrg    float scaleX, scaleY;
24132001f49Smrg
24232001f49Smrg    glViewport(0, 0, windW, windH);
24332001f49Smrg
24432001f49Smrg    glMatrixMode(GL_PROJECTION);
24532001f49Smrg    glLoadIdentity();
24632001f49Smrg    gluOrtho2D(-175, 175, -175, 175);
24732001f49Smrg    glMatrixMode(GL_MODELVIEW);
24832001f49Smrg
24932001f49Smrg    glScissor(0, 0, windW, windH);
25032001f49Smrg
25132001f49Smrg    (culling) ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
25232001f49Smrg    (winding) ? glFrontFace(GL_CCW) : glFrontFace(GL_CW);
25332001f49Smrg    (face) ? glCullFace(GL_FRONT) : glCullFace(GL_BACK);
25432001f49Smrg
25532001f49Smrg    (dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
25632001f49Smrg
25732001f49Smrg    glClear(GL_COLOR_BUFFER_BIT);
25832001f49Smrg
25932001f49Smrg    SetColor(COLOR_GREEN);
26032001f49Smrg    glBegin(GL_LINE_LOOP);
26132001f49Smrg	glVertex3fv(boxA);
26232001f49Smrg	glVertex3fv(boxB);
26332001f49Smrg	glVertex3fv(boxC);
26432001f49Smrg	glVertex3fv(boxD);
26532001f49Smrg    glEnd();
26632001f49Smrg
26732001f49Smrg    if (!hideBottomTriangle) {
26832001f49Smrg	glPushMatrix();
26932001f49Smrg
27032001f49Smrg	glScalef(zoom, zoom, zoom);
27132001f49Smrg	glRotatef(zRotation, 0, 0, 1);
27232001f49Smrg
27332001f49Smrg	SetColor(COLOR_BLUE);
27432001f49Smrg	BeginPrim();
27532001f49Smrg	    glVertex3fv(p0);
27632001f49Smrg	    glVertex3fv(p1);
27732001f49Smrg	    glVertex3fv(p2);
27832001f49Smrg	EndPrim();
27932001f49Smrg
28032001f49Smrg	if (showVerticies) {
28132001f49Smrg	    (rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
28232001f49Smrg	    glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2);
28332001f49Smrg	    (rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
28432001f49Smrg	    glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2);
28532001f49Smrg	    (rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
28632001f49Smrg	    glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2);
28732001f49Smrg	}
28832001f49Smrg
28932001f49Smrg	glPopMatrix();
29032001f49Smrg    }
29132001f49Smrg
29232001f49Smrg    scaleX = (float)(windW - 20) / 2 / 175 * (175 - 100) + 10;
29332001f49Smrg    scaleY = (float)(windH - 20) / 2 / 175 * (175 - 100) + 10;
29432001f49Smrg
29532001f49Smrg    glViewport(scaleX, scaleY, windW-2*scaleX, windH-2*scaleY);
29632001f49Smrg
29732001f49Smrg    glMatrixMode(GL_PROJECTION);
29832001f49Smrg    glLoadIdentity();
29932001f49Smrg    gluOrtho2D(-100, 100, -100, 100);
30032001f49Smrg    glMatrixMode(GL_MODELVIEW);
30132001f49Smrg
30232001f49Smrg    glScissor(scaleX, scaleY, windW-2*scaleX, windH-2*scaleY);
30332001f49Smrg
30432001f49Smrg    glPushMatrix();
30532001f49Smrg
30632001f49Smrg    glScalef(zoom, zoom, zoom);
30732001f49Smrg    glRotatef(zRotation, 0,0,1);
30832001f49Smrg
30932001f49Smrg    glPointSize(10);
31032001f49Smrg    glLineWidth(5);
31132001f49Smrg    glEnable(GL_POINT_SMOOTH);
31232001f49Smrg    glEnable(GL_LINE_STIPPLE);
31332001f49Smrg    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
31432001f49Smrg
31532001f49Smrg    SetColor(COLOR_RED);
31632001f49Smrg    BeginPrim();
31732001f49Smrg	(rgb) ? glColor3fv(RGBMap[COLOR_RED]) : glIndexf(color1);
31832001f49Smrg	glVertex3fv(p0);
31932001f49Smrg	(rgb) ? glColor3fv(RGBMap[COLOR_GREEN]) : glIndexf(color2);
32032001f49Smrg	glVertex3fv(p1);
32132001f49Smrg	(rgb) ? glColor3fv(RGBMap[COLOR_BLUE]) : glIndexf(color3);
32232001f49Smrg	glVertex3fv(p2);
32332001f49Smrg    EndPrim();
32432001f49Smrg
32532001f49Smrg    glPointSize(1);
32632001f49Smrg    glLineWidth(1);
32732001f49Smrg    glDisable(GL_POINT_SMOOTH);
32832001f49Smrg    glDisable(GL_LINE_STIPPLE);
32932001f49Smrg    glBlendFunc(GL_ONE, GL_ZERO);
33032001f49Smrg
33132001f49Smrg    if (outline) {
33232001f49Smrg	SetColor(COLOR_WHITE);
33332001f49Smrg	glBegin(GL_LINE_LOOP);
33432001f49Smrg	    glVertex3fv(p0);
33532001f49Smrg	    glVertex3fv(p1);
33632001f49Smrg	    glVertex3fv(p2);
33732001f49Smrg	glEnd();
33832001f49Smrg    }
33932001f49Smrg
34032001f49Smrg    glPopMatrix();
34132001f49Smrg
34232001f49Smrg    glFlush();
34332001f49Smrg
34432001f49Smrg    if (doubleBuffer) {
34532001f49Smrg	glutSwapBuffers();
34632001f49Smrg    }
34732001f49Smrg}
34832001f49Smrg
34932001f49Smrgstatic GLenum Args(int argc, char **argv)
35032001f49Smrg{
35132001f49Smrg    GLint i;
35232001f49Smrg
35332001f49Smrg    rgb = GL_TRUE;
35432001f49Smrg    doubleBuffer = GL_FALSE;
35532001f49Smrg
35632001f49Smrg    for (i = 1; i < argc; i++) {
35732001f49Smrg	if (strcmp(argv[i], "-ci") == 0) {
35832001f49Smrg	    rgb = GL_FALSE;
35932001f49Smrg	} else if (strcmp(argv[i], "-rgb") == 0) {
36032001f49Smrg	    rgb = GL_TRUE;
36132001f49Smrg	} else if (strcmp(argv[i], "-sb") == 0) {
36232001f49Smrg	    doubleBuffer = GL_FALSE;
36332001f49Smrg	} else if (strcmp(argv[i], "-db") == 0) {
36432001f49Smrg	    doubleBuffer = GL_TRUE;
36532001f49Smrg	} else {
36632001f49Smrg	    printf("%s (Bad option).\n", argv[i]);
36732001f49Smrg	    return GL_FALSE;
36832001f49Smrg	}
36932001f49Smrg    }
37032001f49Smrg    return GL_TRUE;
37132001f49Smrg}
37232001f49Smrg
37332001f49Smrgint main(int argc, char **argv)
37432001f49Smrg{
37532001f49Smrg    glutInit(&argc, argv);
37632001f49Smrg
37732001f49Smrg    if (Args(argc, argv) == GL_FALSE) {
37832001f49Smrg	exit(1);
37932001f49Smrg    }
38032001f49Smrg
38132001f49Smrg    windW = 600;
38232001f49Smrg    windH = 300;
38332001f49Smrg    glutInitWindowPosition(0, 0); glutInitWindowSize( windW, windH);
38432001f49Smrg
38532001f49Smrg    windType = (rgb) ? GLUT_RGB : GLUT_INDEX;
38632001f49Smrg    windType |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
38732001f49Smrg    glutInitDisplayMode(windType);
38832001f49Smrg
38932001f49Smrg    if (glutCreateWindow("Triangle Test") == GL_FALSE) {
39032001f49Smrg	exit(1);
39132001f49Smrg    }
39232001f49Smrg
39332001f49Smrg    InitMap();
39432001f49Smrg
39532001f49Smrg    Init();
39632001f49Smrg
39732001f49Smrg    glutReshapeFunc(Reshape);
39832001f49Smrg    glutKeyboardFunc(Key);
39932001f49Smrg    glutSpecialFunc(Key2);
40032001f49Smrg    glutDisplayFunc(Draw);
40132001f49Smrg    glutMainLoop();
40232001f49Smrg	return 0;
40332001f49Smrg}
404