sources:


website:
more info here


screenshot:
studies/grafik/Computergrafik-Code4/Aufgabe11/cgtessellator.cpp
download file

  1 //
  2 // Computergraphik I
  3 // Prof. Dr. Juergen Doellner
  4 // Sommersemester 2001
  5 //
  6 // Rahmenprogramm fuer Aufgabenzettel 4
  7 //
  8
  9 // Stephan Brumme, 702544
 10 // last changes: May 20, 2001
 11
 12 #include "cgtessellator.h"
 13
 14 // Function Makro
 15 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
 16 #define FUNC GLvoid(*)(...)
 17 #elif defined(_MSC_VER)
 18 #define FUNC void(__stdcall*)()
 19 #else
 20 #define FUNC GLvoid(*)()
 21 #endif
 22
 23 // GLU tesselator globale Hilfsfunktionen
 24
 25 // Fehler abfangen
 26 void CALLBACK error(GLenum err) {
 27     cerr << gluErrorString(err) << endl;   
 28 }
 29
 30 // Schnitt von Kanten, nimmt keine Änderungen vor
 31 void CALLBACK combineCallback(GLdouble coords[3],
 32                               GLdouble *vertex_data[4],
 33                               GLfloat weight[4], GLdouble **dataOut )

 34 {
 35     GLdouble* vertex = new GLdouble[3];
 36     vertex[0] = coords[0];
 37     vertex[1] = coords[1];
 38     vertex[2] = coords[2];       
 39     *dataOut = vertex;
 40 }
 41
 42 // stellt Ecke dar
 43 void CALLBACK vertexCallback(GLvoid *vertex)
 44 {
 45     glVertex3dv((GLdouble*)vertex);
 46 }
 47
 48 // beginnt ein Primitv
 49 void CALLBACK beginCallback(GLenum which)
 50 {
 51     glBegin(which);
 52 }
 53
 54 // beendet ein Primitiv
 55 void CALLBACK endCallback()
 56 {
 57     glEnd();
 58 }
 59
 60
 61 // CGTessellator
 62 CGTessellator::CGTessellator()
 63     // Anlegen des TessObj
 64     tobj_ = gluNewTess();
 65     gluTessProperty(tobj_, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
 66
 67     // Datenstruktur initialisieren
 68     pos_ = 0;
 69     contours_ = 1;
 70     contourSize_[0] = 0;
 71 }
 72
 73 CGTessellator::~CGTessellator() {
 74     // Zerstoeren des TessObj
 75     gluDeleteTess(tobj_);
 76 }
 77
 78 // Setze Punkte fuer einen Stern
 79 void CGTessellator::defineStar() {
 80     // 5 Punkte insgesamt
 81     pos_ = 5;
 82     // 1 Kontur
 83     contours_ = 1;
 84     // diese Kontur enthält alle bisher definierten Punkte
 85     contourSize_[0] = 5;
 86     pts_[0] = Point(150.0, 150.0);
 87     pts_[1] = Point(225.0, 300.0);
 88     pts_[2] = Point(300.0, 150.0);
 89     pts_[3] = Point(150.0, 250.0);
 90     pts_[4] = Point(300.0, 250.0);
 91
 92     // Stern zeichnen
 93     glutPostRedisplay();
 94 }
 95
 96 void CGTessellator::onInit() {
 97     glClearColor(1, 1, 1, 1)
 98
 99     // festlegen der Vertex, Begin, End und Error Callback
100     // Beispiel: Combine Callback, Achtung: FUNC-Cast!
101     gluTessCallback(tobj_, GLU_TESS_COMBINE, (FUNC) &combineCallback);
102     gluTessCallback(tobj_, GLU_TESS_VERTEX, (FUNC) &vertexCallback);
103
104
105     gluTessCallback(tobj_, GLU_TESS_BEGIN, (FUNC) &beginCallback);
106     gluTessCallback(tobj_, GLU_TESS_END, (FUNC) &endCallback);
107
108     gluTessCallback(tobj_, GLU_TESS_ERROR, (FUNC) &error);
109 }
110
111 void CGTessellator::drawPolygon() {
112     gluTessBeginPolygon(tobj_, NULL);
113
114     // alle Punkte durchlaufen
115     int nVertexPtr = 0;
116
117     // alle Polygone
118     for (int nContour = 0; nContour < contours_; nContour++)
119     {
120         gluTessBeginContour(tobj_);
121
122         // alle Eckpunkte eines Polygons
123         for (int nVertex=0; nVertex<contourSize_[nContour]; nVertex++)
124         {
125             gluTessVertex(tobj_, pts_[nVertexPtr].dta_, pts_[nVertexPtr].dta_);
126             nVertexPtr++;
127         }
128
129         gluTessEndContour(tobj_);
130     }
131     gluTessEndPolygon(tobj_);
132     // Tessellation des Polygons mit GLU-Routinen
133 }
134
135 void CGTessellator::onDraw() {
136     glClear(GL_COLOR_BUFFER_BIT);
137
138     // Zeichnen des Polygons (blau)
139     glColor3f(0.5,0.5,1);
140     drawPolygon();
141
142     // Zeichnen des Polygon-Randes (schwarz), benutzt erneut Tessellator
143     glColor3f(0,0,0);
144     gluTessProperty(tobj_, GLU_TESS_BOUNDARY_ONLY, GL_TRUE);
145     drawPolygon();
146     gluTessProperty(tobj_, GLU_TESS_BOUNDARY_ONLY, GL_FALSE);
147
148     // Zeichnen der Eckpunkte (rot)
149     glPointSize(4);
150     glColor3d(1,0,0);
151
152     glBegin(GL_POINTS);
153     for (int i = 0; i < pos_; i++)
154         glVertex2dv(pts_[i].dta_);
155     glEnd();
156    
157     // tauschen wie im Swingerclub
158     swapBuffers();
159 }
160
161 void CGTessellator::onSize(unsigned int newWidth, unsigned int newHeight) {
162     glClear(GL_COLOR_BUFFER_BIT);
163     glViewport(0, 0, newWidth - 1, newHeight - 1);
164    
165     glMatrixMode(GL_PROJECTION_MATRIX);
166     glLoadIdentity();
167     gluOrtho2D(0, newWidth-1, 0, newHeight-1);
168     glMatrixMode(GL_MODELVIEW_MATRIX)
169    
170 }
171
172 void CGTessellator::onKey(unsigned char key) {   
173     // Key Belegung
174     switch (key) {
175         // beenden
176     case 'q': exit(0); break;
177
178         // Stern zeichnen
179     case 's': defineStar(); break;
180
181         // neue Kontur beginnen
182     case 'k': contourSize_[contours_++] = 0; break;
183
184         // alle Punkte/Bildschirm löschen
185     case 'c': contours_ = 1;
186               contourSize_[0] = 0;
187               pos_ = 0;
188               break;
189
190         // Tessellationsalgorithmen
191     case '1': gluTessProperty(tobj_, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); break;
192     case '2': gluTessProperty(tobj_, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); break;
193     case '3': gluTessProperty(tobj_, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE); break;
194     case '4': gluTessProperty(tobj_, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NEGATIVE); break;
195     case '5': gluTessProperty(tobj_, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ABS_GEQ_TWO); break;
196     }
197
198     // und neu zeichnen
199     glutPostRedisplay();
200 }
201
202 void CGTessellator::onButton(MouseButton button, MouseButtonEvent event,
203                             int x, int y)
{   
204     // Punkt speichern
205     pts_[pos_] = Point(x, y);
206     contourSize_[contours_-1]++;
207     pos_++;
208
209     // und neu zeichnen
210     glutPostRedisplay();
211 }
212
213 int main(int argc, char* argv[]) {
214     CGTessellator tess;
215     tess.start(argc, argv, "CGTessellator, Stephan Brumme, 702544",
216         CGTessellator::ColorBuffer| CGTessellator::DoubleBuffer | CGTessellator::StencilBuffer,
217         200, 400, 400)
;
218     return(0);
219 }
220