| 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 | }
|
|---|