A real-time 3D factory simulation built with C++ and OpenGL (Fixed-Function Pipeline) as a Computer Graphics module project.
University of Moratuwa — Semester 4, Computer Graphics
The simulation runs a fully animated, looping 120-second production pipeline:
[Input Scanner] ──► Belt 1 ──► Robotic Arm Pick & Place
──► Welding Station ──► Laser Quality Scanner
──► Transfer Ramp ──► Belt 2 ──► [Output Scanner]
A second box appears on Belt 1 as soon as Box 1 reaches the scanning stage, demonstrating a continuous production flow.
- 6-stage state machine with seamless looping every 120 seconds
- Hierarchical robotic arm — 5 joints (base → shoulder → elbow → wrist → gripper) with Forward Kinematics
- Dual conveyor belts with animated scrolling textures and cylindrical rollers
- Welding station with a pop-up pusher mechanism and a gravity transfer ramp to Belt 2
- Laser quality scanner — a sliding gantry head with an additive-blended red fan beam
- Welding spark particle system — 200-particle pool with Euler gravity integration
- Dynamic lighting — 4 simultaneous light sources including a warm orange welding spotlight
- Volumetric light shafts from overhead industrial lamps (additive blending)
- 4 procedurally generated textures — conveyor stripes, floor checkerboard, raw/welded box metal
- 2D HUD overlay — stage name, timer, and progress bar using orthographic projection
- Baggage-scanner style input/output tunnels with green/amber status lights
- Storage racks in the background for environmental depth
| Platform | Requirements |
|---|---|
| macOS | Xcode Command Line Tools (includes OpenGL + GLUT frameworks) |
| Linux | libgl-dev, libglu-dev, freeglut3-dev |
| Windows | Visual Studio 2022 + FreeGLUT + OpenGL32 |
g++ main.cpp -o factory -framework OpenGL -framework GLUT -Wno-deprecated
./factoryg++ main.cpp -o factory -lGL -lGLU -lglut
./factoryg++ main.cpp -o factory.exe -lfreeglut -lopengl32 -lglu32
factory.exeNote: No external image files are required. All four textures are generated procedurally at runtime.
| Stage | Time | Description |
|---|---|---|
| 1 — Conveyor In | 0 – 20s | Raw box slides from input scanner onto Belt 1 and travels to the pickup point |
| 2 — Pick Up | 20 – 45s | Robotic arm reaches, closes gripper, and lifts the box |
| 3 — Rotate & Place | 45 – 70s | Arm sweeps 180° and lowers box onto the welding platform |
| 4 — Welding | 70 – 95s | Welding sparks fire; arm lifts and reverses back to home; dynamic orange spotlight fades in |
| 5 — Quality Scan | 95 – 110s | Laser scanner head traverses the box with a fan beam; Box 2 simultaneously emerges from the input tunnel |
| 6 — Exit | 110 – 120s | Pop-up pusher ejects the box down the 33° transfer ramp onto Belt 2; box rides to the output scanner |
| Concept | Implementation |
|---|---|
| Hierarchical Transforms | 5-joint robotic arm using nested glPushMatrix/glPopMatrix |
| Forward Kinematics | Trigonometric chain in getGripperTip() to compute gripper world position |
| Phong Lighting Model | 4 GL lights — ambient, 2 overhead factory lamps, 1 dynamic welding spot |
| Emissive Materials | GL_EMISSION for self-lit lamp bulbs |
| Procedural Textures | All textures generated from pixel math at startup — no image files |
| UV Texture Mapping | Manual glTexCoord2f per vertex; scrolling U offset animates belt motion |
| Alpha Blending | Standard blend for HUD; additive blend (GL_ONE) for laser glow & light shafts |
| Particle System | 200-slot pool, Euler gravity physics, per-particle colour-fade rendering |
| Perspective Projection | gluPerspective (45° FOV) + gluLookAt camera |
| Orthographic Overlay | gluOrtho2D for the 2D HUD without disrupting the 3D scene |
| Animation State Machine | 6-state Timeline FSM driving all subsystems deterministically |
Factory Automation and Robotics/
│
├── main.cpp # Entire project — single self-contained source file
├── README.md # This file
└── PRESENTATION_GUIDE.md # Team member presentation assignments & code walkthrough
Scene ← Master integrator
├── Timeline ← State machine (6 stages, 120s loop)
├── TextureManager ← Procedural texture generation & binding
├── RoboticArm ← Hierarchical arm + Forward Kinematics
├── ConveyorSystem ← Belts, rollers, animated part position
├── LightingSystem ← GL lights, scanner gantry, volumetric shafts
├── ParticleSystem ← Welding sparks (physics pool)
└── HUD ← 2D orthographic stage label + progress bar
| Key | Action |
|---|---|
ESC |
Quit |
| Window resize | Automatically adjusts viewport and aspect ratio |
X axis → -8 -4 0 1.5 3.5 9
[IN]══════════╗ ╔════════════════[OUT]
Scanner Belt 1 ║ ║ Belt 2 Scanner
║Arm ║
║ ║
[Welding]
[Scanner]
Key coordinates:
BELT1_START_X = -8.0— input scanner exitBELT1_END_X = -1.5— arm pickup pointWELD_X = 1.5— welding + scan platform XBELT2_START_X = 3.5— ramp bottom / belt 2 startBELT2_END_X = 9.0— output scanner entry
- No external dependencies beyond OpenGL/GLUT — fully self-contained single
.cppfile - All animation values are pure functions of
sceneTime— no accumulated state drift - Transparent objects (
GL_BLEND) are drawn last after all opaque geometry to ensure correct compositing glDepthMask(GL_FALSE)is applied for all transparent passes to avoid depth-fighting- The ramp transfer uses exact trigonometric offset (
PART_SIZE/2 / cos(pitch)) so the box face lies flush against the ramp surface - Particle spawning is gated to begin only after the arm has retracted (20% into welding stage) to prevent visual overlap
Developed by a 5-member team for the Computer Graphics module, Semester 4,
Faculty of Information Technology, University of Moratuwa.
This project was developed for academic purposes as part of a university course assignment.