BIT304 Computer Graphics

Computer GraphicsUnit 1010 min read

OpenGL Basics, Animation & Callback Functions

Unit 10 of Computer Graphics explores OpenGL’s architecture, polygon rendering, animation techniques, and callback functions with real-world examples (e.g., game engines, 3D modeling tools) and hands-on traces of code execution.

TAKEAWAYS:

  • OpenGL is a cross-platform API for rendering 2D/3D graphics via state machines and callbacks (e.g., display(), reshape()).
  • Polygons are drawn using glBegin()/glEnd() or modern vertex buffers (VBOs) for efficiency.
  • Animation relies on frame updates (e.g., glutTimerFunc()) and transformation matrices (e.g., glRotatef()).
  • Callbacks handle events like keyboard input or window resizing via glutKeyboardFunc() or glutReshapeFunc().
  • Real-world use: Games (e.g., Unreal Engine uses OpenGL for rendering), apps (e.g., eSewa’s 3D data visualizations), and simulations (e.g., NTC’s traffic route animations).
  • Exam focus: Code snippets, callback flowcharts, and polygon rendering steps.

OpenGL Overview: Architecture and State Machine

OpenGL (Open Graphics Library) is a low-level API for hardware-accelerated rendering. It uses a state machine model:

  • State: Current settings (e.g., color, matrix mode).
  • Commands: Modify state (e.g., glColor3f(1.0, 0, 0) sets red).
  • Rendering pipeline: Vertex processing → rasterization → shading → display.
glBegin/glEndApplicationOpenGL State MachineVertex ProcessingRasterizationFragment ShadingFramebufferDisplay
OpenGL rendering pipeline with highlighted vertex processing and rasterization stages (eSewa’s 3D bar chart example)
flowchart LR
    A["Application"] -->|"glBegin/glEnd"| B["OpenGL State Machine"]
    B --> C["Vertex Processing"]
    C --> D["Rasterization"]
    D --> E["Fragment Shading"]
    E --> F["Framebuffer"]
    F --> G["Display"]

Real-world link:

  • eSewa’s 3D data dashboards use OpenGL to render interactive charts (e.g., transaction flows as rotating 3D bars). The glRotatef() function animates these bars by updating their transformation matrices per frame.

Polygon Creation in OpenGL

Polygons are defined using primitives (points, lines, triangles, quads). Two methods:

  1. Immediate Mode (legacy):
    glBegin(GL_POLYGON);
        glVertex2f(0.0, 0.0);  // Bottom-left
        glVertex2f(1.0, 0.0);  // Bottom-right
        glVertex2f(0.5, 1.0);  // Top
    glEnd();
    
    Visual:

```figure
{"type":"graph","fns":[{"expr":"0.5*x + 1","label":"y = 0.5x + 1 (Top edge)"},{"expr":"0","label":"y = 0 (Bottom edge)"}],"x":[-1,2],"points":[{"x":0,"y":0,"label":"A (0,0)"},{"x":1,"y":0,"label":"B (1,0)"},{"x":1,"y":1.5,"label":"C (1,1.5)"},{"x":0,"y":1,"label":"D (0,1)"}],"caption":"Daraz order queue polygon vertices (A→B→C→D) with dynamic height (y-coordinate of C/D)"}
10213243
Vertex array before `glBegin(GL_TRIANGLE_FAN)` (order matters for winding)
  1. Modern Mode (recommended):
    • Use Vertex Buffer Objects (VBOs) for GPU efficiency.
    • Example: Render a quad (rectangle) with VBOs.
      float vertices[] = {0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0};
      GLuint vbo;
      glGenBuffers(1, &vbo);
      glBindBuffer(GL_ARRAY_BUFFER, vbo);
      glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
      glDrawArrays(GL_QUADS, 0, 4);  // Draw 4 vertices as a quad
      

Worked Example: Daraz Order Queue as a Polygon Imagine Daraz’s order status dashboard visualizing pending orders as a pulsing polygon:

  • Vertices: (0,0), (100,0), (100,50), (0,50) (width=100px, height=50px).
  • Animation: Scale the polygon vertically to simulate order volume changes.
    void display() {
        glClear(GL_COLOR_BUFFER_BIT);
        glColor3f(0.0, 0.7, 0.0);  // Green for "processing"
        glBegin(GL_QUADS);
            glVertex2f(0, 0);
            glVertex2f(100, 0);
            glVertex2f(100, current_height);  // Dynamic height
            glVertex2f(0, current_height);
        glEnd();
        glutSwapBuffers();
    }
    void update(int value) {
        current_height = (current_height + 5) % 100;  // Pulse between 0-100
        glutTimerFunc(100, update, 0);  // Update every 100ms
        glutPostRedisplay();
    }
    

Callback Functions in OpenGL

Callbacks are event handlers registered with glut (or freeglut). Key callbacks:

Callback Purpose Example Use Case
glutDisplayFunc() Redraw the scene Update polygon positions
glutReshapeFunc() Handle window resizing Adjust viewport with glViewport()
glutKeyboardFunc() Process keyboard input Rotate a 3D model with arrow keys
glutTimerFunc() Trigger periodic updates Animation frames (e.g., NEPSE stock chart)

Example: Rotating a Cube with Keyboard Callbacks

float angle = 0;
void keyboard(unsigned char key, int x, int y) {
    if (key == 'r') angle += 5;  // Increment rotation angle
    glutPostRedisplay();
}
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    glPushMatrix();
        glRotatef(angle, 0, 1, 0);  // Rotate around Y-axis
        glutSolidCube(1.0);        // Draw a cube
    glPopMatrix();
    glutSwapBuffers();
}

Real-world link:

  • Pathao’s driver app uses glutTimerFunc() to update real-time location markers (polygons representing driver vehicles) every second. The callback recalculates vertex positions based on GPS data.

Animation Techniques

Animation in OpenGL relies on:

  1. Frame updates: Modify object states (e.g., position, rotation) per frame.
  2. Transformation matrices: Use glTranslatef(), glRotatef(), glScalef().
  3. Timers: glutTimerFunc() schedules updates.
stateDiagram-v2
    [*] --> MovingCar
    MovingCar -->|car_pos += 0.1| MovingCar : GL_LINE_STRIP
    MovingCar -->|car_pos > 10.0| Loop
    Loop --> MovingCar : car_pos = 0
    MovingCar --> [*] : glutTimerFunc(50, update, 0)
Kathmandu traffic route animation state machine (Pathao driver app example)

Example: Kathmandu Traffic Routes as Animated Lines Simulate vehicle movement along a road using line strips:

float car_pos = 0;
void update(int value) {
    car_pos += 0.1;  // Move car forward
    if (car_pos > 10.0) car_pos = 0;  // Loop
    glutTimerFunc(50, update, 0);     // 20 FPS
    glutPostRedisplay();
}
void display() {
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 0, 0);  // Red car
    glBegin(GL_LINE_STRIP);
        glVertex2f(0, 0);
        glVertex2f(car_pos, 0);  // Dynamic position
    glEnd();
    glutSwapBuffers();
}

Visual:



OpenGL vs. Modern Alternatives

Feature OpenGL (Legacy) Modern Alternatives (WebGL, Vulkan)
Ease of Use Complex state machine Higher-level APIs (e.g., Three.js)
Performance Good (but verbose) Optimized for mobile/GPU
Cross-Platform Yes (Windows/Linux/macOS) Yes (WebGL runs in browsers)
Learning Curve Steep (manual memory management) Gentler (e.g., Unity’s C# API)
API evolutionSubset for browsersLow-level competitionPlatform-specificOpenGLVulkanDirectX 12MetalWebGL
Modern graphics APIs and their relationships to OpenGL

Exam Tip: Compare OpenGL’s immediate mode (simple but slow) vs. VBOs (fast but complex). Always prefer VBOs in exams unless asked for legacy code.


In the Real World

  1. eSewa’s 3D Data Visualization

    • Idea Used: OpenGL’s glRotatef() and glTranslatef() animate 3D bar charts showing transaction volumes.
    • How: Each bar is a polygon whose height corresponds to transaction count. Callbacks update heights dynamically when new data arrives.
  2. NTC’s Traffic Simulation

    • Idea Used: Line strips (GL_LINE_STRIP) represent roads, and glutTimerFunc() updates vehicle positions (polygons) in real-time.
    • How: The system reads GPS data from buses/trucks and renders their paths as moving lines, helping planners identify congestion.
  3. Khalti’s Security Animation

    • Idea Used: Polygon clipping and rotation (glClipPlane()) to visualize secure transaction zones.
    • How: During login, a rotating shield (polygon) animates around the user’s input field, using glRotatef() to create a "locking" effect.

Exam Tip: How to Score Full Marks

  1. For polygon creation:

    • Always show vertex order (clockwise/counter-clockwise matters for backface culling).
    • Include both immediate and VBO methods in answers (examiners love comparisons).
    • Example trace:
      glBegin(GL_TRIANGLES);
          glVertex2f(0,0);  // Step 1: Define vertex 1
          glVertex2f(1,0);  // Step 2: Define vertex 2
          glVertex2f(0.5,1); // Step 3: Define vertex 3
      glEnd();             // Step 4: End primitive
      
  2. For callbacks:

    • Draw a flowchart of the callback chain (e.g., main() → glutDisplayFunc() → display()).
    • Show one full execution trace (e.g., how glutKeyboardFunc() updates a variable).
flowchart TD
    A["glutKeyboardFunc('r')"] --> B["angle += 5\n(rotation increment)"]
    B --> C["glutPostRedisplay()\n(requeue display)"]
    C --> D["display()\n(glRotatef(angle, 0, 0, 1))"]
    D --> E["Framebuffer\n(redraw)"]
  1. For animation:

    • Explain the timer loop (glutTimerFunc() → update() → glutPostRedisplay()).
    • Use small numbers in examples (e.g., rotate by 5° per frame, not 360°).
  2. Avoid common mistakes:

    • ❌ Forgetting glutSwapBuffers() (causes flickering).
    • ❌ Not initializing OpenGL context (glutInit(), glutCreateWindow()).
    • ❌ Using glBegin()/glEnd() without checking if VBOs are required.

Pro Tip: Memorize these 5 OpenGL commands for quick marks:

  1. glBegin()/glEnd() – Define primitives.
  2. glVertex2f() – Specify vertices.
  3. glRotatef() – Rotate objects.
  4. glutDisplayFunc() – Register redraw handler.
  5. glutTimerFunc() – Schedule updates.

Based on the TU BIT syllabus for Computer Graphics (BIT304), unit 10.

Discussion

Loading…