summaryrefslogtreecommitdiff
path: root/progs/demos/engine.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-05-21 09:32:38 -0700
committerEric Anholt <eric@anholt.net>2010-05-21 12:20:39 -0700
commit68fc4b415e322f6744299e39864fbc377c6eff74 (patch)
tree4bafffd8b0105174f3c5c0ae327a005be9145990 /progs/demos/engine.c
parente4f4489e3fc0b36d72821b55794fb843b2b7fa5f (diff)
Remove demos that have moved to git+ssh://git.freedesktop.org/git/mesa/demos.
The remaining programs are ones I've had difficulty finding a build environment for to make the build system or are unit tests that should probably live next to their code instead. Hopefully people can bring over the build for remaining pieces they care about.
Diffstat (limited to 'progs/demos/engine.c')
-rw-r--r--progs/demos/engine.c1343
1 files changed, 0 insertions, 1343 deletions
diff --git a/progs/demos/engine.c b/progs/demos/engine.c
deleted file mode 100644
index ee7d5c154a..0000000000
--- a/progs/demos/engine.c
+++ /dev/null
@@ -1,1343 +0,0 @@
-/**
- * Simple engine demo (crankshaft, pistons, connecting rods)
- *
- * Brian Paul
- * June 2006
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <GL/glew.h>
-#include <GL/glut.h>
-#include "readtex.h"
-#include "trackball.h"
-
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define DEG_TO_RAD(DEG) ((DEG) * M_PI / 180.0)
-
-#define TEXTURE_FILE "../images/reflect.rgb"
-
-/* Target engine speed: */
-const int RPM = 100.0;
-
-static int Win = 0;
-
-
-/**
- * Engine description.
- */
-typedef struct
-{
- const char *Name;
- int Pistons;
- int Cranks;
- float V_Angle;
- float PistonRadius;
- float PistonHeight;
- float WristPinRadius;
- float Throw;
- float CrankPlateThickness;
- float CrankPinRadius;
- float CrankJournalRadius;
- float CrankJournalLength;
- float ConnectingRodLength;
- float ConnectingRodThickness;
- /* display list IDs */
- GLuint CrankList;
- GLuint ConnRodList;
- GLuint PistonList;
- GLuint BlockList;
-} Engine;
-
-
-typedef struct
-{
- float CurQuat[4];
- float Distance;
- /* When mouse is moving: */
- GLboolean Rotating, Translating;
- GLint StartX, StartY;
- float StartDistance;
-} ViewInfo;
-
-
-typedef enum
-{
- LIT,
- WIREFRAME,
- TEXTURED
-} RenderMode;
-
-
-typedef struct
-{
- RenderMode Mode;
- GLboolean Anim;
- GLboolean Wireframe;
- GLboolean Blend;
- GLboolean Antialias;
- GLboolean Texture;
- GLboolean UseLists;
- GLboolean DrawBox;
- GLboolean ShowInfo;
- GLboolean ShowBlock;
-} RenderInfo;
-
-
-static GLUquadric *Q;
-
-static GLfloat Theta = 0.0;
-
-static const GLfloat PistonColor[4] = { 1.0, 0.5, 0.5, 1.0 };
-static const GLfloat ConnRodColor[4] = { 0.7, 1.0, 0.7, 1.0 };
-static const GLfloat CrankshaftColor[4] = { 0.7, 0.7, 1.0, 1.0 };
-static const GLfloat BlockColor[4] = {0.8, 0.8, 0.8, 0.75 };
-
-static GLuint TextureObj;
-static GLint WinWidth = 800, WinHeight = 500;
-
-static ViewInfo View;
-static RenderInfo Render;
-
-#define NUM_ENGINES 3
-static Engine Engines[NUM_ENGINES] =
-{
- {
- "V-6",
- 6, /* Pistons */
- 3, /* Cranks */
- 90.0, /* V_Angle */
- 0.5, /* PistonRadius */
- 0.6, /* PistonHeight */
- 0.1, /* WristPinRadius */
- 0.5, /* Throw */
- 0.2, /* CrankPlateThickness */
- 0.25, /* CrankPinRadius */
- 0.3, /* CrankJournalRadius */
- 0.4, /* CrankJournalLength */
- 1.5, /* ConnectingRodLength */
- 0.1, /* ConnectingRodThickness */
- 0, /* CrankList */
- 0, /* ConnRodList */
- 0, /* PistonList */
- 0 /* BlockList */
- },
- {
- "Inline-4",
- 4, /* Pistons */
- 4, /* Cranks */
- 0.0, /* V_Angle */
- 0.5, /* PistonRadius */
- 0.6, /* PistonHeight */
- 0.1, /* WristPinRadius */
- 0.5, /* Throw */
- 0.2, /* CrankPlateThickness */
- 0.25, /* CrankPinRadius */
- 0.3, /* CrankJournalRadius */
- 0.4, /* CrankJournalLength */
- 1.5, /* ConnectingRodLength */
- 0.1, /* ConnectingRodThickness */
- 0, /* CrankList */
- 0, /* ConnRodList */
- 0, /* PistonList */
- 0 /* BlockList */
- },
- {
- "Boxer-6",
- 6, /* Pistons */
- 3, /* Cranks */
- 180.0,/* V_Angle */
- 0.5, /* PistonRadius */
- 0.6, /* PistonHeight */
- 0.1, /* WristPinRadius */
- 0.5, /* Throw */
- 0.2, /* CrankPlateThickness */
- 0.25, /* CrankPinRadius */
- 0.3, /* CrankJournalRadius */
- 0.4, /* CrankJournalLength */
- 1.5, /* ConnectingRodLength */
- 0.1, /* ConnectingRodThickness */
- 0, /* CrankList */
- 0, /* ConnRodList */
- 0, /* PistonList */
- 0 /* BlockList */
- }
-};
-
-static int CurEngine = 0;
-
-
-
-static void
-InitViewInfo(ViewInfo *view)
-{
- view->Rotating = GL_FALSE;
- view->Translating = GL_FALSE;
- view->StartX = view->StartY = 0;
- view->Distance = 12.0;
- view->StartDistance = 0.0;
- view->CurQuat[0] = -0.194143;
- view->CurQuat[1] = 0.507848;
- view->CurQuat[2] = 0.115245;
- view->CurQuat[3] = 0.831335;
-}
-
-
-static void
-InitRenderInfo(RenderInfo *render)
-{
- render->Mode = LIT;
- render->Anim = GL_TRUE;
- render->Wireframe = GL_FALSE;
- render->Blend = GL_FALSE;
- render->Antialias = GL_FALSE;
- render->Texture = GL_FALSE;
- render->DrawBox = GL_FALSE;
- render->ShowInfo = GL_TRUE;
- render->ShowBlock = GL_FALSE;
- render->UseLists = GL_FALSE;
-}
-
-
-/**
- * Set GL for given rendering mode.
- */
-static void
-SetRenderState(RenderMode mode)
-{
- static const GLfloat gray2[4] = { 0.2, 0.2, 0.2, 1.0 };
- static const GLfloat gray4[4] = { 0.4, 0.4, 0.4, 1.0 };
-
- /* defaults */
- glDisable(GL_LIGHTING);
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glDisable(GL_LINE_SMOOTH);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- glDisable(GL_TEXTURE_GEN_S);
- glDisable(GL_TEXTURE_GEN_T);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gray2);
-
- switch (mode) {
- case LIT:
- glEnable(GL_LIGHTING);
- break;
- case WIREFRAME:
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glEnable(GL_LINE_SMOOTH);
- glEnable(GL_BLEND);
- glLineWidth(1.5);
- break;
- case TEXTURED:
- glEnable(GL_LIGHTING);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_TEXTURE_GEN_S);
- glEnable(GL_TEXTURE_GEN_T);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gray4);
- break;
- default:
- ;
- }
-}
-
-
-/**
- * Animate the engine parts.
- */
-static void
-Idle(void)
-{
- /* convert degrees per millisecond to RPM: */
- const float m = 360.0 / 1000.0 / 60.0;
- GLint t = glutGet(GLUT_ELAPSED_TIME);
- Theta = ((int) (t * RPM * m)) % 360;
- glutPostRedisplay();
-}
-
-
-/**
- * Compute piston's position along its stroke.
- */
-static float
-PistonStrokePosition(float throwDist, float crankAngle, float connRodLength)
-{
- float x = throwDist * cos(DEG_TO_RAD(crankAngle));
- float y = throwDist * sin(DEG_TO_RAD(crankAngle));
- float pos = y + sqrt(connRodLength * connRodLength - x * x);
- return pos;
-}
-
-
-/**
- * Compute position of nth piston along the crankshaft.
- */
-static float
-PistonShaftPosition(const Engine *eng, int piston)
-{
- const int i = piston / (eng->Pistons / eng->Cranks);
- float z;
- assert(piston < eng->Pistons);
- z = 1.5 * eng->CrankJournalLength + eng->CrankPlateThickness
- + i * (2.0 * (eng->CrankJournalLength + eng->CrankPlateThickness));
- if (eng->Pistons > eng->Cranks) {
- if (piston & 1)
- z += eng->ConnectingRodThickness;
- else
- z -= eng->ConnectingRodThickness;
- }
- return z;
-}
-
-
-/**
- * Compute distance between two adjacent pistons
- */
-static float
-PistonSpacing(const Engine *eng)
-{
- const int pistonsPerCrank = eng->Pistons / eng->Cranks;
- const float z0 = PistonShaftPosition(eng, 0);
- const float z1 = PistonShaftPosition(eng, pistonsPerCrank);
- return z1 - z0;
-}
-
-
-/**
- * (x0, y0) = position of big end on crankshaft
- * (x1, y1) = position of small end on piston
- */
-static void
-ComputeConnectingRodPosition(float throwDist, float crankAngle,
- float connRodLength,
- float *x0, float *y0, float *x1, float *y1)
-{
- *x0 = throwDist * cos(DEG_TO_RAD(crankAngle));
- *y0 = throwDist * sin(DEG_TO_RAD(crankAngle));
- *x1 = 0.0;
- *y1 = PistonStrokePosition(throwDist, crankAngle, connRodLength);
-}
-
-
-/**
- * Compute total length of the crankshaft.
- */
-static float
-CrankshaftLength(const Engine *eng)
-{
- float len = (eng->Cranks * 2 + 1) * eng->CrankJournalLength
- + 2 * eng->Cranks * eng->CrankPlateThickness;
- return len;
-}
-
-
-/**
- * Draw a piston.
- * Axis of piston = Z axis. Wrist pin is centered on (0, 0, 0).
- */
-static void
-DrawPiston(const Engine *eng)
-{
- const int slices = 30, stacks = 4, loops = 4;
- const float innerRadius = 0.9 * eng->PistonRadius;
- const float innerHeight = eng->PistonHeight - 0.15;
- const float wristPinLength = 1.8 * eng->PistonRadius;
-
- assert(Q);
-
- glPushMatrix();
- glTranslatef(0, 0, -1.1 * eng->WristPinRadius);
-
- gluQuadricOrientation(Q, GLU_INSIDE);
-
- /* bottom rim */
- gluDisk(Q, innerRadius, eng->PistonRadius, slices, 1/*loops*/);
-
- /* inner cylinder */
- gluCylinder(Q, innerRadius, innerRadius, innerHeight, slices, stacks);
-
- /* inside top */
- glPushMatrix();
- glTranslatef(0, 0, innerHeight);
- gluDisk(Q, 0, innerRadius, slices, loops);
- glPopMatrix();
-
- gluQuadricOrientation(Q, GLU_OUTSIDE);
-
- /* outer cylinder */
- gluCylinder(Q, eng->PistonRadius, eng->PistonRadius, eng->PistonHeight,
- slices, stacks);
-
- /* top */
- glTranslatef(0, 0, eng->PistonHeight);
- gluDisk(Q, 0, eng->PistonRadius, slices, loops);
-
- glPopMatrix();
-
- /* wrist pin */
- glPushMatrix();
- glTranslatef(0, 0.5 * wristPinLength, 0.0);
- glRotatef(90, 1, 0, 0);
- gluCylinder(Q, eng->WristPinRadius, eng->WristPinRadius, wristPinLength,
- slices, stacks);
- glPopMatrix();
-}
-
-
-/**
- * Draw piston at particular position.
- */
-static void
-DrawPositionedPiston(const Engine *eng, float crankAngle)
-{
- const float pos = PistonStrokePosition(eng->Throw, crankAngle,
- eng->ConnectingRodLength);
- glPushMatrix();
- glRotatef(-90, 1, 0, 0);
- glTranslatef(0, 0, pos);
- if (eng->PistonList)
- glCallList(eng->PistonList);
- else
- DrawPiston(eng);
- glPopMatrix();
-}
-
-
-/**
- * Draw connector plate. Used for crankshaft and connecting rods.
- */
-static void
-DrawConnector(float length, float thickness,
- float bigEndRadius, float smallEndRadius)
-{
- const float bigRadius = 1.2 * bigEndRadius;
- const float smallRadius = 1.2 * smallEndRadius;
- const float z0 = -0.5 * thickness, z1 = -z0;
- GLfloat points[36][2], normals[36][2];
- int i;
-
- /* compute vertex locations, normals */
- for (i = 0; i < 36; i++) {
- const int angle = i * 10;
- float x = cos(DEG_TO_RAD(angle));
- float y = sin(DEG_TO_RAD(angle));
- normals[i][0] = x;
- normals[i][1] = y;
- if (angle >= 0 && angle <= 180) {
- x *= smallRadius;
- y = y * smallRadius + length;
- }
- else {
- x *= bigRadius;
- y *= bigRadius;
- }
- points[i][0] = x;
- points[i][1] = y;
- }
-
- /* front face */
- glNormal3f(0, 0, 1);
- glBegin(GL_POLYGON);
- for (i = 0; i < 36; i++) {
- glVertex3f(points[i][0], points[i][1], z1);
- }
- glEnd();
-
- /* back face */
- glNormal3f(0, 0, -1);
- glBegin(GL_POLYGON);
- for (i = 0; i < 36; i++) {
- glVertex3f(points[35-i][0], points[35-i][1], z0);
- }
- glEnd();
-
- /* edge */
- glBegin(GL_QUAD_STRIP);
- for (i = 0; i <= 36; i++) {
- const int j = i % 36;
- glNormal3f(normals[j][0], normals[j][1], 0);
- glVertex3f(points[j][0], points[j][1], z1);
- glVertex3f(points[j][0], points[j][1], z0);
- }
- glEnd();
-}
-
-
-/**
- * Draw a crankshaft. Shaft lies along +Z axis, starting at zero.
- */
-static void
-DrawCrankshaft(const Engine *eng)
-{
- const int slices = 20, stacks = 2;
- const int n = eng->Cranks * 4 + 1;
- const float phiStep = 360 / eng->Cranks;
- float phi = -90.0;
- int i;
- float z = 0.0;
-
- for (i = 0; i < n; i++) {
- glPushMatrix();
- glTranslatef(0, 0, z);
- if (i & 1) {
- /* draw a crank plate */
- glRotatef(phi, 0, 0, 1);
- glTranslatef(0, 0, 0.5 * eng->CrankPlateThickness);
- DrawConnector(eng->Throw, eng->CrankPlateThickness,
- eng->CrankJournalRadius, eng->CrankPinRadius);
- z += 0.2;
- if (i % 4 == 3)
- phi += phiStep;
- }
- else if (i % 4 == 0) {
- /* draw crank journal segment */
- gluCylinder(Q, eng->CrankJournalRadius, eng->CrankJournalRadius,
- eng->CrankJournalLength, slices, stacks);
- z += eng->CrankJournalLength;
- }
- else if (i % 4 == 2) {
- /* draw crank pin segment */
- glRotatef(phi, 0, 0, 1);
- glTranslatef(0, eng->Throw, 0);
- gluCylinder(Q, eng->CrankPinRadius, eng->CrankPinRadius,
- eng->CrankJournalLength, slices, stacks);
- z += eng->CrankJournalLength;
- }
- glPopMatrix();
- }
-}
-
-
-/**
- * Draw crankshaft at a particular rotation.
- * \param crankAngle current crankshaft rotation, in radians
- */
-static void
-DrawPositionedCrankshaft(const Engine *eng, float crankAngle)
-{
- glPushMatrix();
- glRotatef(crankAngle, 0, 0, 1);
- if (eng->CrankList)
- glCallList(eng->CrankList);
- else
- DrawCrankshaft(eng);
- glPopMatrix();
-}
-
-
-/**
- * Draw a connecting rod at particular position.
- * \param eng description of connecting rod to draw
- * \param crankAngle current crankshaft rotation, in radians
- */
-static void
-DrawPositionedConnectingRod(const Engine *eng, float crankAngle)
-{
- float x0, y0, x1, y1;
- float d, phi;
-
- ComputeConnectingRodPosition(eng->Throw, crankAngle,
- eng->ConnectingRodLength,
- &x0, &y0, &x1, &y1);
- d = sqrt(eng->ConnectingRodLength * eng->ConnectingRodLength - x0 * x0);
- phi = atan(x0 / d) * 180.0 / M_PI;
-
- glPushMatrix();
- glTranslatef(x0, y0, 0);
- glRotatef(phi, 0, 0, 1);
- if (eng->ConnRodList)
- glCallList(eng->ConnRodList);
- else
- DrawConnector(eng->ConnectingRodLength, eng->ConnectingRodThickness,
- eng->CrankPinRadius, eng->WristPinRadius);
- glPopMatrix();
-}
-
-
-/**
- * Draw a square with a hole in middle.
- */
-static void
-SquareWithHole(float squareSize, float holeRadius)
-{
- int i;
- glBegin(GL_QUAD_STRIP);
- glNormal3f(0, 0, 1);
- for (i = 0; i <= 360; i += 5) {
- const float x1 = holeRadius * cos(DEG_TO_RAD(i));
- const float y1 = holeRadius * sin(DEG_TO_RAD(i));
- float x2 = 0.0F, y2 = 0.0F;
- if (i > 315 || i <= 45) {
- x2 = squareSize;
- y2 = squareSize * tan(DEG_TO_RAD(i));
- }
- else if (i > 45 && i <= 135) {
- x2 = -squareSize * tan(DEG_TO_RAD(i - 90));
- y2 = squareSize;
- }
- else if (i > 135 && i <= 225) {
- x2 = -squareSize;
- y2 = -squareSize * tan(DEG_TO_RAD(i-180));
- }
- else if (i > 225 && i <= 315) {
- x2 = squareSize * tan(DEG_TO_RAD(i - 270));
- y2 = -squareSize;
- }
- glVertex2f(x1, y1); /* inner circle */
- glVertex2f(x2, y2); /* outer square */
- }
- glEnd();
-}
-
-
-/**
- * Draw block with hole through middle.
- * Hole is centered on Z axis.
- * Bottom of block is at z=0, top of block is at z = blockHeight.
- * index is in [0, count - 1] to determine which block faces are drawn.
- */
-static void
-DrawBlockWithHole(float blockSize, float blockHeight, float holeRadius,
- int index, int count)
-{
- const int slices = 30, stacks = 4;
- const float x = blockSize;
- const float y = blockSize;
- const float z0 = 0;
- const float z1 = blockHeight;
-
- assert(index < count);
- assert(Q);
- gluQuadricOrientation(Q, GLU_INSIDE);
-
- glBegin(GL_QUADS);
- /* +X face */
- glNormal3f(1, 0, 0);
- glVertex3f( x, -y, z0);
- glVertex3f( x, y, z0);
- glVertex3f( x, y, z1);
- glVertex3f( x, -y, z1);
- /* -X face */
- glNormal3f(-1, 0, 0);
- glVertex3f(-x, -y, z1);
- glVertex3f(-x, y, z1);
- glVertex3f(-x, y, z0);
- glVertex3f(-x, -y, z0);
- if (index == 0) {
- /* +Y face */
- glNormal3f(0, 1, 0);
- glVertex3f(-x, y, z1);
- glVertex3f( x, y, z1);
- glVertex3f( x, y, z0);
- glVertex3f(-x, y, z0);
- }
- if (index == count - 1) {
- /* -Y face */
- glNormal3f(0, -1, 0);
- glVertex3f(-x, -y, z0);
- glVertex3f( x, -y, z0);
- glVertex3f( x, -y, z1);
- glVertex3f(-x, -y, z1);
- }
- glEnd();
-
- /* cylinder / hole */
- gluCylinder(Q, holeRadius, holeRadius, blockHeight, slices, stacks);
-
- /* face at z0 */
- glPushMatrix();
- glRotatef(180, 1, 0, 0);
- SquareWithHole(blockSize, holeRadius);
- glPopMatrix();
-
- /* face at z1 */
- glTranslatef(0, 0, z1);
- SquareWithHole(blockSize, holeRadius);
-
- gluQuadricOrientation(Q, GLU_OUTSIDE);
-}
-
-
-/**
- * Draw the engine block.
- */
-static void
-DrawEngineBlock(const Engine *eng)
-{
- const float blockHeight = eng->Throw + 1.5 * eng->PistonHeight;
- const float cylRadius = 1.01 * eng->PistonRadius;
- const float blockSize = 0.5 * PistonSpacing(eng);
- const int pistonsPerCrank = eng->Pistons / eng->Cranks;
- int i;
-
- for (i = 0; i < eng->Pistons; i++) {
- const float z = PistonShaftPosition(eng, i);
- const int crank = i / pistonsPerCrank;
- int k;
-
- glPushMatrix();
- glTranslatef(0, 0, z);
-
- /* additional rotation for kth piston per crank */
- k = i % pistonsPerCrank;
- glRotatef(k * -eng->V_Angle, 0, 0, 1);
-
- /* the block */
- glRotatef(-90, 1, 0, 0);
- glTranslatef(0, 0, eng->Throw * 2);
- DrawBlockWithHole(blockSize, blockHeight, cylRadius,
- crank, eng->Cranks);
- glPopMatrix();
- }
-}
-
-
-/**
- * Generate display lists for engine parts.
- */
-static void
-GenerateDisplayLists(Engine *eng)
-{
- eng->CrankList = glGenLists(1);
- glNewList(eng->CrankList, GL_COMPILE);
- DrawCrankshaft(eng);
- glEndList();
-
- eng->ConnRodList = glGenLists(1);
- glNewList(eng->ConnRodList, GL_COMPILE);
- DrawConnector(eng->ConnectingRodLength, eng->ConnectingRodThickness,
- eng->CrankPinRadius, eng->WristPinRadius);
- glEndList();
-
- eng->PistonList = glGenLists(1);
- glNewList(eng->PistonList, GL_COMPILE);
- DrawPiston(eng);
- glEndList();
-
- eng->BlockList = glGenLists(1);
- glNewList(eng->BlockList, GL_COMPILE);
- DrawEngineBlock(eng);
- glEndList();
-}
-
-
-/**
- * Free engine display lists (render with immediate mode).
- */
-static void
-FreeDisplayLists(Engine *eng)
-{
- glDeleteLists(eng->CrankList, 1);
- eng->CrankList = 0;
- glDeleteLists(eng->ConnRodList, 1);
- eng->ConnRodList = 0;
- glDeleteLists(eng->PistonList, 1);
- eng->PistonList = 0;
- glDeleteLists(eng->BlockList, 1);
- eng->BlockList = 0;
-}
-
-
-/**
- * Draw complete engine.
- * \param eng description of engine to draw
- * \param crankAngle current crankshaft angle, in radians
- */
-static void
-DrawEngine(const Engine *eng, float crankAngle)
-{
- const float crankDelta = 360.0 / eng->Cranks;
- const float crankLen = CrankshaftLength(eng);
- const int pistonsPerCrank = eng->Pistons / eng->Cranks;
- int i;
-
- glPushMatrix();
- glRotatef(eng->V_Angle * 0.5, 0, 0, 1);
- glTranslatef(0, 0, -0.5 * crankLen);
-
- /* crankshaft */
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, CrankshaftColor);
- glColor4fv(CrankshaftColor);
- DrawPositionedCrankshaft(eng, crankAngle);
-
- for (i = 0; i < eng->Pistons; i++) {
- const float z = PistonShaftPosition(eng, i);
- const int crank = i / pistonsPerCrank;
- float rot = crankAngle + crank * crankDelta;
- int k;
-
- glPushMatrix();
- glTranslatef(0, 0, z);
-
- /* additional rotation for kth piston per crank */
- k = i % pistonsPerCrank;
- glRotatef(k * -eng->V_Angle, 0, 0, 1);
- rot += k * eng->V_Angle;
-
- /* piston */
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, PistonColor);
- glColor4fv(PistonColor);
- DrawPositionedPiston(eng, rot);
-
- /* connecting rod */
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ConnRodColor);
- glColor4fv(ConnRodColor);
- DrawPositionedConnectingRod(eng, rot);
- glPopMatrix();
- }
-
- if (Render.ShowBlock) {
- const GLboolean blend = glIsEnabled(GL_BLEND);
-
- glDepthMask(GL_FALSE);
- if (!blend) {
- glEnable(GL_BLEND);
- }
- glEnable(GL_CULL_FACE);
-
- glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, BlockColor);
- glColor4fv(BlockColor);
- if (eng->CrankList)
- glCallList(eng->BlockList);
- else
- DrawEngineBlock(eng);
-
- glDisable(GL_CULL_FACE);
- glDepthMask(GL_TRUE);
- if (!blend) {
- glDisable(GL_BLEND);
- }
- }
-
- glPopMatrix();
-}
-
-
-static void
-DrawBox(void)
-{
- const float xmin = -3.0, xmax = 3.0;
- const float ymin = -1.0, ymax = 3.0;
- const float zmin = -4.0, zmax = 4.0;
- const float step = 0.5;
- const float d = 0.01;
- float x, y, z;
- GLboolean lit = glIsEnabled(GL_LIGHTING);
- GLboolean tex = glIsEnabled(GL_TEXTURE_2D);
-
- glDisable(GL_LIGHTING);
- glDisable(GL_TEXTURE_2D);
- glLineWidth(1.0);
-
- glColor3f(1, 1, 1);
-
- /* Z min */
- glBegin(GL_LINES);
- for (x = xmin; x <= xmax; x += step) {
- glVertex3f(x, ymin, zmin);
- glVertex3f(x, ymax, zmin);
- }
- glEnd();
- glBegin(GL_LINES);
- for (y = ymin; y <= ymax; y += step) {
- glVertex3f(xmin, y, zmin);
- glVertex3f(xmax, y, zmin);
- }
- glEnd();
-
- /* Y min */
- glBegin(GL_LINES);
- for (x = xmin; x <= xmax; x += step) {
- glVertex3f(x, ymin, zmin);
- glVertex3f(x, ymin, zmax);
- }
- glEnd();
- glBegin(GL_LINES);
- for (z = zmin; z <= zmax; z += step) {
- glVertex3f(xmin, ymin, z);
- glVertex3f(xmax, ymin, z);
- }
- glEnd();
-
- /* X min */
- glBegin(GL_LINES);
- for (y = ymin; y <= ymax; y += step) {
- glVertex3f(xmin, y, zmin);
- glVertex3f(xmin, y, zmax);
- }
- glEnd();
- glBegin(GL_LINES);
- for (z = zmin; z <= zmax; z += step) {
- glVertex3f(xmin, ymin, z);
- glVertex3f(xmin, ymax, z);
- }
- glEnd();
-
- glColor3f(0.4, 0.4, 0.6);
- glBegin(GL_QUADS);
- /* xmin */
- glVertex3f(xmin-d, ymin, zmin);
- glVertex3f(xmin-d, ymax, zmin);
- glVertex3f(xmin-d, ymax, zmax);
- glVertex3f(xmin-d, ymin, zmax);
- /* ymin */
- glVertex3f(xmin, ymin-d, zmin);
- glVertex3f(xmax, ymin-d, zmin);
- glVertex3f(xmax, ymin-d, zmax);
- glVertex3f(xmin, ymin-d, zmax);
- /* zmin */
- glVertex3f(xmin, ymin, zmin-d);
- glVertex3f(xmax, ymin, zmin-d);
- glVertex3f(xmax, ymax, zmin-d);
- glVertex3f(xmin, ymax, zmin-d);
- glEnd();
-
- if (lit)
- glEnable(GL_LIGHTING);
- if (tex)
- glEnable(GL_TEXTURE_2D);
-}
-
-
-static void
-PrintString(const char *s)
-{
- while (*s) {
- glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s);
- s++;
- }
-}
-
-
-static int
-ComputeFPS(void)
-{
- static double t0 = -1.0;
- static int frames = 0;
- double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
- static int fps = 0;
-
- frames++;
-
- if (t0 < 0.0) {
- t0 = t;
- fps = 0;
- }
- else if (t - t0 >= 1.0) {
- fps = (int) (frames / (t - t0) + 0.5);
- t0 = t;
- frames = 0;
- }
-
- return fps;
-}
-
-
-static void
-Draw(void)
-{
- int fps;
- GLfloat rot[4][4];
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- glPushMatrix();
-
- glTranslatef(0.0, 0.0, -View.Distance);
- build_rotmatrix(rot, View.CurQuat);
- glMultMatrixf(&rot[0][0]);
-
- glPushMatrix();
- glTranslatef(0, -0.75, 0);
- if (Render.DrawBox)
- DrawBox();
- DrawEngine(Engines + CurEngine, Theta);
- glPopMatrix();
-
- glPopMatrix();
-
- fps = ComputeFPS();
- if (Render.ShowInfo) {
- GLboolean lit = glIsEnabled(GL_LIGHTING);
- GLboolean tex = glIsEnabled(GL_TEXTURE_2D);
- char s[100];
- sprintf(s, "%s %d FPS %s", Engines[CurEngine].Name, fps,
- Render.UseLists ? "Display Lists" : "Immediate mode");
- glDisable(GL_LIGHTING);
- glDisable(GL_TEXTURE_2D);
- glColor3f(1, 1 , 1);
- glWindowPos2iARB(10, 10);
- PrintString(s);
- if (lit)
- glEnable(GL_LIGHTING);
- if (tex)
- glEnable(GL_TEXTURE_2D);
- }
-
- /* also print out a periodic fps to stdout. useful for trying to
- * figure out the performance impact of rendering the string above
- * with glBitmap.
- */
- {
- static GLint T0 = 0;
- static GLint Frames = 0;
- GLint t = glutGet(GLUT_ELAPSED_TIME);
-
- Frames++;
-
- if (t - T0 >= 5000) {
- GLfloat seconds = (t - T0) / 1000.0;
- GLfloat fps = Frames / seconds;
- printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
- fflush(stdout);
- T0 = t;
- Frames = 0;
- }
- }
-
-
- glutSwapBuffers();
-}
-
-
-/**
- * Handle window resize.
- */
-static void
-Reshape(int width, int height)
-{
- float ar = (float) width / height;
- float s = 0.5;
- glViewport(0, 0, width, height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glFrustum(-ar * s, ar * s, -s, s, 2.0, 50.0);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- WinWidth = width;
- WinHeight = height;
-}
-
-
-/**
- * Handle mouse button.
- */
-static void
-Mouse(int button, int state, int x, int y)
-{
- if (button == GLUT_LEFT_BUTTON) {
- if (state == GLUT_DOWN) {
- View.StartX = x;
- View.StartY = y;
- View.Rotating = GL_TRUE;
- }
- else if (state == GLUT_UP) {
- View.Rotating = GL_FALSE;
- }
- }
- else if (button == GLUT_MIDDLE_BUTTON) {
- if (state == GLUT_DOWN) {
- View.StartX = x;
- View.StartY = y;
- View.StartDistance = View.Distance;
- View.Translating = GL_TRUE;
- }
- else if (state == GLUT_UP) {
- View.Translating = GL_FALSE;
- }
- }
-}
-
-
-/**
- * Handle mouse motion
- */
-static void
-Motion(int x, int y)
-{
- int i;
- if (View.Rotating) {
- float x0 = (2.0 * View.StartX - WinWidth) / WinWidth;
- float y0 = (WinHeight - 2.0 * View.StartY) / WinHeight;
- float x1 = (2.0 * x - WinWidth) / WinWidth;
- float y1 = (WinHeight - 2.0 * y) / WinHeight;
- float q[4];
-
- trackball(q, x0, y0, x1, y1);
- View.StartX = x;
- View.StartY = y;
- for (i = 0; i < 1; i++)
- add_quats(q, View.CurQuat, View.CurQuat);
-
- glutPostRedisplay();
- }
- else if (View.Translating) {
- float dz = 0.01 * (y - View.StartY);
- View.Distance = View.StartDistance + dz;
- glutPostRedisplay();
- }
-}
-
-
-/**
- ** Menu Callbacks
- **/
-
-static void
-OptAnimation(void)
-{
- Render.Anim = !Render.Anim;
- if (Render.Anim)
- glutIdleFunc(Idle);
- else
- glutIdleFunc(NULL);
-}
-
-static void
-OptChangeEngine(void)
-{
- CurEngine = (CurEngine + 1) % NUM_ENGINES;
-}
-
-static void
-OptRenderMode(void)
-{
- Render.Mode++;
- if (Render.Mode > TEXTURED)
- Render.Mode = 0;
- SetRenderState(Render.Mode);
-}
-
-static void
-OptDisplayLists(void)
-{
- int i;
- Render.UseLists = !Render.UseLists;
- if (Render.UseLists) {
- for (i = 0; i < NUM_ENGINES; i++) {
- GenerateDisplayLists(Engines + i);
- }
- }
- else {
- for (i = 0; i < NUM_ENGINES; i++) {
- FreeDisplayLists(Engines + i);
- }
- }
-}
-
-static void
-OptShowBlock(void)
-{
- Render.ShowBlock = !Render.ShowBlock;
-}
-
-static void
-OptShowInfo(void)
-{
- Render.ShowInfo = !Render.ShowInfo;
-}
-
-static void
-OptShowBox(void)
-{
- Render.DrawBox = !Render.DrawBox;
-}
-
-static void
-OptRotate(void)
-{
- Theta += 5.0;
-}
-
-static void
-OptExit(void)
-{
- glutDestroyWindow(Win);
- exit(0);
-}
-
-
-/**
- * Define menu entries (w/ keyboard shortcuts)
- */
-
-typedef struct
-{
- const char *Text;
- const char Key;
- void (*Function)(void);
-} MenuInfo;
-
-static const MenuInfo MenuItems[] = {
- { "Animation", 'a', OptAnimation },
- { "Change Engine", 'e', OptChangeEngine },
- { "Rendering Style", 'm', OptRenderMode },
- { "Display Lists", 'd', OptDisplayLists },
- { "Show Block", 'b', OptShowBlock },
- { "Show Info", 'i', OptShowInfo },
- { "Show Box", 'x', OptShowBox },
- { "Exit", 27, OptExit },
- { NULL, 'r', OptRotate },
- { NULL, 0, NULL }
-};
-
-
-/**
- * Handle menu selection.
- */
-static void
-MenuHandler(int entry)
-{
- MenuItems[entry].Function();
- glutPostRedisplay();
-}
-
-
-/**
- * Make pop-up menu.
- */
-static void
-MakeMenu(void)
-{
- int i;
- glutCreateMenu(MenuHandler);
- for (i = 0; MenuItems[i].Text; i++) {
- glutAddMenuEntry(MenuItems[i].Text, i);
- }
- glutAttachMenu(GLUT_RIGHT_BUTTON);
-}
-
-
-/**
- * Handle keyboard event.
- */
-static void
-Key(unsigned char key, int x, int y)
-{
- int i;
- (void) x; (void) y;
- for (i = 0; MenuItems[i].Key; i++) {
- if (MenuItems[i].Key == key) {
- MenuItems[i].Function();
- glutPostRedisplay();
- break;
- }
- }
-}
-
-
-static
-void LoadTexture(void)
-{
- GLboolean convolve = GL_FALSE;
-
- glGenTextures(1, &TextureObj);
- glBindTexture(GL_TEXTURE_2D, TextureObj);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
- glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
-
- if (convolve) {
-#define FILTER_SIZE 7
- /* use convolution to blur the texture to simulate a dull finish
- * on the object.
- */
- GLubyte *img;
- GLenum format;
- GLint w, h;
- GLfloat filter[FILTER_SIZE][FILTER_SIZE][4];
-
- for (h = 0; h < FILTER_SIZE; h++) {
- for (w = 0; w < FILTER_SIZE; w++) {
- const GLfloat k = 1.0 / (FILTER_SIZE * FILTER_SIZE);
- filter[h][w][0] = k;
- filter[h][w][1] = k;
- filter[h][w][2] = k;
- filter[h][w][3] = k;
- }
- }
-
- glEnable(GL_CONVOLUTION_2D);
- glConvolutionParameteri(GL_CONVOLUTION_2D,
- GL_CONVOLUTION_BORDER_MODE, GL_CONSTANT_BORDER);
- glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_RGBA,
- FILTER_SIZE, FILTER_SIZE,
- GL_RGBA, GL_FLOAT, filter);
-
- img = LoadRGBImage(TEXTURE_FILE, &w, &h, &format);
- if (!img) {
- printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE);
- exit(1);
- }
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
- format, GL_UNSIGNED_BYTE, img);
- free(img);
- }
- else {
- if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
- printf("Error: couldn't load texture image file %s\n", TEXTURE_FILE);
- exit(1);
- }
- }
-}
-
-
-static void
-Init(void)
-{
- const GLfloat lightColor[4] = { 0.7, 0.7, 0.7, 1.0 };
- const GLfloat specular[4] = { 0.8, 0.8, 0.8, 1.0 };
- const GLfloat backColor[4] = { 1, 1, 0, 0 };
-
- Q = gluNewQuadric();
- gluQuadricNormals(Q, GLU_SMOOTH);
-
- LoadTexture();
-
- glClearColor(0.3, 0.3, 0.3, 0.0);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- glEnable(GL_LIGHT0);
- glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
- glMaterialf(GL_FRONT, GL_SHININESS, 40);
- glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
- glEnable(GL_NORMALIZE);
-
- glMaterialfv(GL_BACK, GL_DIFFUSE, backColor);
-#if 0
- glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, 1);
-#endif
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- InitViewInfo(&View);
- InitRenderInfo(&Render);
-}
-
-
-int
-main(int argc, char *argv[])
-{
- glutInitWindowSize(WinWidth, WinHeight);
- glutInit(&argc, argv);
- glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
- Win = glutCreateWindow("OpenGL Engine Demo");
- glewInit();
- glutReshapeFunc(Reshape);
- glutMouseFunc(Mouse);
- glutMotionFunc(Motion);
- glutKeyboardFunc(Key);
- glutDisplayFunc(Draw);
- MakeMenu();
- Init();
- if (Render.Anim)
- glutIdleFunc(Idle);
- glutMainLoop();
- return 0;
-}