1 | /****************************************************************************
|
---|
2 | ** $Id: glgear.cpp 160 2006-12-11 20:15:57Z dmik $
|
---|
3 | **
|
---|
4 | ** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
|
---|
5 | **
|
---|
6 | ** This file is part of an example program for Qt. This example
|
---|
7 | ** program may be used, distributed and modified without limitation.
|
---|
8 | **
|
---|
9 | *****************************************************************************/
|
---|
10 | //
|
---|
11 | // Draws a gear.
|
---|
12 | //
|
---|
13 | // Portions of this code have been borrowed from Brian Paul's Mesa
|
---|
14 | // distribution.
|
---|
15 | //
|
---|
16 |
|
---|
17 | #include "glgear.h"
|
---|
18 |
|
---|
19 | #include <math.h>
|
---|
20 |
|
---|
21 | #if defined(Q_CC_MSVC)
|
---|
22 | #pragma warning(disable:4305) // init: truncation from const double to float
|
---|
23 | #endif
|
---|
24 |
|
---|
25 | /*
|
---|
26 | * Draw a gear wheel. You'll probably want to call this function when
|
---|
27 | * building a display list since we do a lot of trig here.
|
---|
28 | *
|
---|
29 | * Input: inner_radius - radius of hole at center
|
---|
30 | * outer_radius - radius at center of teeth
|
---|
31 | * width - width of gear
|
---|
32 | * teeth - number of teeth
|
---|
33 | * tooth_depth - depth of tooth
|
---|
34 | */
|
---|
35 | static void gear( GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
|
---|
36 | GLint teeth, GLfloat tooth_depth )
|
---|
37 | {
|
---|
38 | GLint i;
|
---|
39 | GLfloat r0, r1, r2;
|
---|
40 | GLfloat angle, da;
|
---|
41 | GLfloat u, v, len;
|
---|
42 |
|
---|
43 | r0 = inner_radius;
|
---|
44 | r1 = outer_radius - tooth_depth/2.0;
|
---|
45 | r2 = outer_radius + tooth_depth/2.0;
|
---|
46 |
|
---|
47 | const double pi = 3.14159264;
|
---|
48 | da = 2.0*pi / teeth / 4.0;
|
---|
49 |
|
---|
50 | glShadeModel( GL_FLAT );
|
---|
51 |
|
---|
52 | glNormal3f( 0.0, 0.0, 1.0 );
|
---|
53 |
|
---|
54 | /* draw front face */
|
---|
55 | glBegin( GL_QUAD_STRIP );
|
---|
56 | for (i=0;i<=teeth;i++) {
|
---|
57 | angle = i * 2.0*pi / teeth;
|
---|
58 | glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
|
---|
59 | glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
|
---|
60 | glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
|
---|
61 | glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
|
---|
62 | }
|
---|
63 | glEnd();
|
---|
64 |
|
---|
65 | /* draw front sides of teeth */
|
---|
66 | glBegin( GL_QUADS );
|
---|
67 | da = 2.0*pi / teeth / 4.0;
|
---|
68 | for (i=0;i<teeth;i++) {
|
---|
69 | angle = i * 2.0*pi / teeth;
|
---|
70 |
|
---|
71 | glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
|
---|
72 | glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
|
---|
73 | glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
|
---|
74 | glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
|
---|
75 | }
|
---|
76 | glEnd();
|
---|
77 |
|
---|
78 |
|
---|
79 | glNormal3f( 0.0, 0.0, -1.0 );
|
---|
80 |
|
---|
81 | /* draw back face */
|
---|
82 | glBegin( GL_QUAD_STRIP );
|
---|
83 | for (i=0;i<=teeth;i++) {
|
---|
84 | angle = i * 2.0*pi / teeth;
|
---|
85 | glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
|
---|
86 | glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
|
---|
87 | glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
|
---|
88 | glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
|
---|
89 | }
|
---|
90 | glEnd();
|
---|
91 |
|
---|
92 | /* draw back sides of teeth */
|
---|
93 | glBegin( GL_QUADS );
|
---|
94 | da = 2.0*pi / teeth / 4.0;
|
---|
95 | for (i=0;i<teeth;i++) {
|
---|
96 | angle = i * 2.0*pi / teeth;
|
---|
97 |
|
---|
98 | glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
|
---|
99 | glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
|
---|
100 | glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
|
---|
101 | glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
|
---|
102 | }
|
---|
103 | glEnd();
|
---|
104 |
|
---|
105 |
|
---|
106 | /* draw outward faces of teeth */
|
---|
107 | glBegin( GL_QUAD_STRIP );
|
---|
108 | for (i=0;i<teeth;i++) {
|
---|
109 | angle = i * 2.0*pi / teeth;
|
---|
110 |
|
---|
111 | glVertex3f( r1*cos(angle), r1*sin(angle), width*0.5 );
|
---|
112 | glVertex3f( r1*cos(angle), r1*sin(angle), -width*0.5 );
|
---|
113 | u = r2*cos(angle+da) - r1*cos(angle);
|
---|
114 | v = r2*sin(angle+da) - r1*sin(angle);
|
---|
115 | len = sqrt( u*u + v*v );
|
---|
116 | u /= len;
|
---|
117 | v /= len;
|
---|
118 | glNormal3f( v, -u, 0.0 );
|
---|
119 | glVertex3f( r2*cos(angle+da), r2*sin(angle+da), width*0.5 );
|
---|
120 | glVertex3f( r2*cos(angle+da), r2*sin(angle+da), -width*0.5 );
|
---|
121 | glNormal3f( cos(angle), sin(angle), 0.0 );
|
---|
122 | glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), width*0.5 );
|
---|
123 | glVertex3f( r2*cos(angle+2*da), r2*sin(angle+2*da), -width*0.5 );
|
---|
124 | u = r1*cos(angle+3*da) - r2*cos(angle+2*da);
|
---|
125 | v = r1*sin(angle+3*da) - r2*sin(angle+2*da);
|
---|
126 | glNormal3f( v, -u, 0.0 );
|
---|
127 | glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), width*0.5 );
|
---|
128 | glVertex3f( r1*cos(angle+3*da), r1*sin(angle+3*da), -width*0.5 );
|
---|
129 | glNormal3f( cos(angle), sin(angle), 0.0 );
|
---|
130 | }
|
---|
131 |
|
---|
132 | glVertex3f( r1*cos(0.0), r1*sin(0.0), width*0.5 );
|
---|
133 | glVertex3f( r1*cos(0.0), r1*sin(0.0), -width*0.5 );
|
---|
134 |
|
---|
135 | glEnd();
|
---|
136 |
|
---|
137 |
|
---|
138 | glShadeModel( GL_SMOOTH );
|
---|
139 |
|
---|
140 | /* draw inside radius cylinder */
|
---|
141 | glBegin( GL_QUAD_STRIP );
|
---|
142 | for (i=0;i<=teeth;i++) {
|
---|
143 | angle = i * 2.0*pi / teeth;
|
---|
144 | glNormal3f( -cos(angle), -sin(angle), 0.0 );
|
---|
145 | glVertex3f( r0*cos(angle), r0*sin(angle), -width*0.5 );
|
---|
146 | glVertex3f( r0*cos(angle), r0*sin(angle), width*0.5 );
|
---|
147 | }
|
---|
148 | glEnd();
|
---|
149 |
|
---|
150 | }
|
---|
151 |
|
---|
152 | void GLGear::draw()
|
---|
153 | {
|
---|
154 | glPushMatrix();
|
---|
155 | glRotatef( view_rotx, 1.0, 0.0, 0.0 );
|
---|
156 | glRotatef( view_roty, 0.0, 1.0, 0.0 );
|
---|
157 | glRotatef( view_rotz, 0.0, 0.0, 1.0 );
|
---|
158 |
|
---|
159 | glPushMatrix();
|
---|
160 | glTranslatef( -3.0, -2.0, 0.0 );
|
---|
161 | glRotatef( angle, 0.0, 0.0, 1.0 );
|
---|
162 | glCallList(gear1);
|
---|
163 | glPopMatrix();
|
---|
164 |
|
---|
165 | glPushMatrix();
|
---|
166 | glTranslatef( 3.1, -2.0, 0.0 );
|
---|
167 | glRotatef( -2.0*angle-9.0, 0.0, 0.0, 1.0 );
|
---|
168 | glCallList(gear2);
|
---|
169 | glPopMatrix();
|
---|
170 |
|
---|
171 | glPushMatrix();
|
---|
172 | glTranslatef( -3.1, 2.2, -1.8 );
|
---|
173 | glRotatef( 90.0, 1.0, 0.0, 0.0 );
|
---|
174 | glRotatef( 2.0*angle-2.0, 0.0, 0.0, 1.0 );
|
---|
175 | glCallList(gear3);
|
---|
176 | glPopMatrix();
|
---|
177 |
|
---|
178 | glPopMatrix();
|
---|
179 | }
|
---|
180 |
|
---|
181 | GLGear::GLGear( QWidget *parent, const char *name, WFlags f )
|
---|
182 | : GLControlWidget( parent, name, 0, f )
|
---|
183 | {
|
---|
184 | scale = 1.0;
|
---|
185 | setAnimationDelay( 15 );
|
---|
186 | view_rotx = 20.0;
|
---|
187 | view_roty = 30.0;
|
---|
188 | view_rotz = 0.0;
|
---|
189 | angle = 0.0;
|
---|
190 | }
|
---|
191 |
|
---|
192 | void GLGear::initializeGL()
|
---|
193 | {
|
---|
194 | static GLfloat pos[4] = {5.0, 5.0, 10.0, 1.0 };
|
---|
195 | static GLfloat ared[4] = {0.8, 0.1, 0.0, 1.0 };
|
---|
196 | static GLfloat agreen[4] = {0.0, 0.8, 0.2, 1.0 };
|
---|
197 | static GLfloat ablue[4] = {0.2, 0.2, 1.0, 1.0 };
|
---|
198 |
|
---|
199 | glLightfv( GL_LIGHT0, GL_POSITION, pos );
|
---|
200 | glEnable( GL_CULL_FACE );
|
---|
201 | glEnable( GL_LIGHTING );
|
---|
202 | glEnable( GL_LIGHT0 );
|
---|
203 | glEnable( GL_DEPTH_TEST );
|
---|
204 |
|
---|
205 | /* make the gears */
|
---|
206 | gear1 = glGenLists(1);
|
---|
207 | glNewList(gear1, GL_COMPILE);
|
---|
208 | glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ared );
|
---|
209 | gear( 1.0, 4.0, 1.0, 20, 0.7 );
|
---|
210 | glEndList();
|
---|
211 |
|
---|
212 | gear2 = glGenLists(1);
|
---|
213 | glNewList(gear2, GL_COMPILE);
|
---|
214 | glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, agreen );
|
---|
215 | gear( 0.5, 2.0, 2.0, 10, 0.7 );
|
---|
216 | glEndList();
|
---|
217 |
|
---|
218 | gear3 = glGenLists(1);
|
---|
219 | glNewList(gear3, GL_COMPILE);
|
---|
220 | glMaterialfv( GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ablue );
|
---|
221 | gear( 1.3, 2.0, 0.5, 10, 0.7 );
|
---|
222 | glEndList();
|
---|
223 |
|
---|
224 | glEnable( GL_NORMALIZE );
|
---|
225 | }
|
---|
226 |
|
---|
227 |
|
---|
228 | void GLGear::resizeGL( int width, int height )
|
---|
229 | {
|
---|
230 | GLfloat w = (float) width / (float) height;
|
---|
231 | GLfloat h = 1.0;
|
---|
232 |
|
---|
233 | glViewport( 0, 0, width, height );
|
---|
234 | glMatrixMode(GL_PROJECTION);
|
---|
235 | glLoadIdentity();
|
---|
236 | glFrustum( -w, w, -h, h, 5.0, 60.0 );
|
---|
237 | glMatrixMode(GL_MODELVIEW);
|
---|
238 | glLoadIdentity();
|
---|
239 | glTranslatef( 0.0, 0.0, -40.0 );
|
---|
240 | }
|
---|
241 |
|
---|
242 |
|
---|
243 | void GLGear::paintGL()
|
---|
244 | {
|
---|
245 | glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
|
---|
246 | glPushMatrix();
|
---|
247 | transform();
|
---|
248 | draw();
|
---|
249 | drawText();
|
---|
250 |
|
---|
251 | glPushAttrib( GL_LIGHTING_BIT | GL_TEXTURE_BIT );
|
---|
252 | glDisable( GL_LIGHTING );
|
---|
253 | glDisable( GL_TEXTURE_2D );
|
---|
254 | qglColor( green );
|
---|
255 | glLineWidth( 1.0 );
|
---|
256 | glBegin( GL_LINES );
|
---|
257 | {
|
---|
258 | glVertex3f( 0.0, 0.0, 0.0 );
|
---|
259 | glVertex3f( 2.98, 2.98, 2.98 );
|
---|
260 | }
|
---|
261 | glEnd();
|
---|
262 | renderText( 3.0, 3.0, 3.0, "Gears", QFont( "helvetica", 12, QFont::Bold, TRUE ) );
|
---|
263 | glPopMatrix();
|
---|
264 | glPopAttrib();
|
---|
265 | }
|
---|
266 |
|
---|
267 | void GLGear::animate()
|
---|
268 | {
|
---|
269 | angle += 2.0;
|
---|
270 | view_roty += 1.0;
|
---|
271 | updateGL();
|
---|
272 | }
|
---|