tess.c revision 32001f49
1/*
2 * Copyright (c) 1993-1997, Silicon Graphics, Inc.
3 * ALL RIGHTS RESERVED
4 * Permission to use, copy, modify, and distribute this software for
5 * any purpose and without fee is hereby granted, provided that the above
6 * copyright notice appear in all copies and that both the copyright notice
7 * and this permission notice appear in supporting documentation, and that
8 * the name of Silicon Graphics, Inc. not be used in advertising
9 * or publicity pertaining to distribution of the software without specific,
10 * written prior permission.
11 *
12 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
13 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
14 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
15 * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
16 * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
17 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
18 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
19 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
20 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
21 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
22 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
23 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
24 *
25 * US Government Users Restricted Rights
26 * Use, duplication, or disclosure by the Government is subject to
27 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
28 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
29 * clause at DFARS 252.227-7013 and/or in similar or successor
30 * clauses in the FAR or the DOD or NASA FAR Supplement.
31 * Unpublished-- rights reserved under the copyright laws of the
32 * United States.  Contractor/manufacturer is Silicon Graphics,
33 * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
34 *
35 * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
36 */
37
38/*
39 *  tess.c
40 *  This program demonstrates polygon tessellation.
41 *  Two tesselated objects are drawn.  The first is a
42 *  rectangle with a triangular hole.  The second is a
43 *  smooth shaded, self-intersecting star.
44 *
45 *  Note the exterior rectangle is drawn with its vertices
46 *  in counter-clockwise order, but its interior clockwise.
47 *  Note the combineCallback is needed for the self-intersecting
48 *  star.  Also note that removing the TessProperty for the
49 *  star will make the interior unshaded (WINDING_ODD).
50 */
51#include "glut_wrap.h"
52#include <stdlib.h>
53#include <stdio.h>
54
55#ifdef GLU_VERSION_1_2
56
57GLuint startList;
58
59static void display (void) {
60   glClear(GL_COLOR_BUFFER_BIT);
61   glColor3f(1.0, 1.0, 1.0);
62   glCallList(startList);
63   glCallList(startList + 1);
64   glFlush();
65}
66
67static void GLAPIENTRY beginCallback(GLenum which)
68{
69   glBegin(which);
70}
71
72static void GLAPIENTRY errorCallback(GLenum errorCode)
73{
74   const GLubyte *estring;
75
76   estring = gluErrorString(errorCode);
77   fprintf(stderr, "Tessellation Error: %s\n", (char *) estring);
78   exit(0);
79}
80
81static void GLAPIENTRY endCallback(void)
82{
83   glEnd();
84}
85
86static void GLAPIENTRY vertexCallback(GLvoid *vertex)
87{
88   const GLdouble *pointer;
89
90   pointer = (GLdouble *) vertex;
91   glColor3dv(pointer+3);
92   glVertex3dv(pointer);
93}
94
95/*  combineCallback is used to create a new vertex when edges
96 *  intersect.  coordinate location is trivial to calculate,
97 *  but weight[4] may be used to average color, normal, or texture
98 *  coordinate data.  In this program, color is weighted.
99 */
100static void GLAPIENTRY combineCallback(GLdouble coords[3],
101                     GLdouble *vertex_data[4],
102                     GLfloat weight[4], GLdouble **dataOut )
103{
104   GLdouble *vertex;
105   int i;
106
107   vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));
108
109   vertex[0] = coords[0];
110   vertex[1] = coords[1];
111   vertex[2] = coords[2];
112   for (i = 3; i < 6; i++)
113      vertex[i] = weight[0] * vertex_data[0][i]
114                  + weight[1] * vertex_data[1][i]
115                  + weight[2] * vertex_data[2][i]
116                  + weight[3] * vertex_data[3][i];
117   *dataOut = vertex;
118}
119
120static void init (void)
121{
122   GLUtesselator *tobj;
123   GLdouble rect[4][3] = {{50.0, 50.0, 0.0},
124                          {200.0, 50.0, 0.0},
125                          {200.0, 200.0, 0.0},
126                          {50.0, 200.0, 0.0}};
127   GLdouble tri[3][3] = {{75.0, 75.0, 0.0},
128                         {125.0, 175.0, 0.0},
129                         {175.0, 75.0, 0.0}};
130   GLdouble star[5][6] = {{250.0, 50.0, 0.0, 1.0, 0.0, 1.0},
131                          {325.0, 200.0, 0.0, 1.0, 1.0, 0.0},
132                          {400.0, 50.0, 0.0, 0.0, 1.0, 1.0},
133                          {250.0, 150.0, 0.0, 1.0, 0.0, 0.0},
134                          {400.0, 150.0, 0.0, 0.0, 1.0, 0.0}};
135
136   glClearColor(0.0, 0.0, 0.0, 0.0);
137
138   startList = glGenLists(2);
139
140   tobj = gluNewTess();
141   gluTessCallback(tobj, GLU_TESS_VERTEX, &glVertex3dv);
142   gluTessCallback(tobj, GLU_TESS_BEGIN, &beginCallback);
143   gluTessCallback(tobj, GLU_TESS_END, &endCallback);
144   gluTessCallback(tobj, GLU_TESS_ERROR, &errorCallback);
145
146   /*  rectangle with triangular hole inside  */
147   glNewList(startList, GL_COMPILE);
148   glShadeModel(GL_FLAT);
149   gluTessBeginPolygon(tobj, NULL);
150      gluTessBeginContour(tobj);
151         gluTessVertex(tobj, rect[0], rect[0]);
152         gluTessVertex(tobj, rect[1], rect[1]);
153         gluTessVertex(tobj, rect[2], rect[2]);
154         gluTessVertex(tobj, rect[3], rect[3]);
155      gluTessEndContour(tobj);
156      gluTessBeginContour(tobj);
157         gluTessVertex(tobj, tri[0], tri[0]);
158         gluTessVertex(tobj, tri[1], tri[1]);
159         gluTessVertex(tobj, tri[2], tri[2]);
160      gluTessEndContour(tobj);
161   gluTessEndPolygon(tobj);
162   glEndList();
163
164   gluTessCallback(tobj, GLU_TESS_VERTEX, &vertexCallback);
165   gluTessCallback(tobj, GLU_TESS_BEGIN, &beginCallback);
166   gluTessCallback(tobj, GLU_TESS_END, &endCallback);
167   gluTessCallback(tobj, GLU_TESS_ERROR, &errorCallback);
168   gluTessCallback(tobj, GLU_TESS_COMBINE, &combineCallback);
169
170   /*  smooth shaded, self-intersecting star  */
171   glNewList(startList + 1, GL_COMPILE);
172   glShadeModel(GL_SMOOTH);
173   gluTessProperty(tobj, GLU_TESS_WINDING_RULE,
174                   GLU_TESS_WINDING_POSITIVE);
175   gluTessBeginPolygon(tobj, NULL);
176      gluTessBeginContour(tobj);
177         gluTessVertex(tobj, star[0], star[0]);
178         gluTessVertex(tobj, star[1], star[1]);
179         gluTessVertex(tobj, star[2], star[2]);
180         gluTessVertex(tobj, star[3], star[3]);
181         gluTessVertex(tobj, star[4], star[4]);
182      gluTessEndContour(tobj);
183   gluTessEndPolygon(tobj);
184   glEndList();
185   gluDeleteTess(tobj);
186}
187
188static void reshape (int w, int h)
189{
190   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
191   glMatrixMode(GL_PROJECTION);
192   glLoadIdentity();
193   gluOrtho2D(0.0, (GLdouble) w, 0.0, (GLdouble) h);
194}
195
196/* ARGSUSED1 */
197static void keyboard(unsigned char key, int x, int y)
198{
199   switch (key) {
200      case 27:
201         exit(0);
202         break;
203   }
204}
205
206int main(int argc, char** argv)
207{
208   glutInit(&argc, argv);
209   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
210   glutInitWindowSize(500, 500);
211   glutCreateWindow(argv[0]);
212   init();
213   glutDisplayFunc(display);
214   glutReshapeFunc(reshape);
215   glutKeyboardFunc(keyboard);
216   glutMainLoop();
217   return 0;
218}
219
220#else
221int main(int argc, char** argv)
222{
223    fprintf (stderr, "This program demonstrates the new tesselator API in GLU 1.2.\n");
224    fprintf (stderr, "Your GLU library does not support this new interface, sorry.\n");
225    return 0;
226}
227#endif
228