Wha# Emscripten LEGACY_GL_EMULATION - Immediate Mode Notes

## Overview

This document describes the behavior and limitations of Emscripten's `LEGACY_GL_EMULATION` when using OpenGL immediate mode (glBegin/glEnd) in WebAssembly builds.

## Key Finding: Color Per Vertex Requirement

**Emscripten's immediate mode requires color to be specified per-vertex, not using OpenGL's "current color" semantic.**

### Standard OpenGL Behavior

In desktop OpenGL, you can set a color once and it applies to all subsequent vertices:

```cpp
glBegin(GL_TRIANGLES);
    glColor3f(1.0f, 0.0f, 0.0f);  // Set current color to red
    glVertex3f(0, 0, 0);           // Uses red
    glVertex3f(1, 0, 0);           // Still uses red
    glVertex3f(0, 1, 0);           // Still uses red
glEnd();
```

### Emscripten Behavior

In Emscripten's LEGACY_GL_EMULATION, you **must** call `glColor*()` before **each** `glVertex*()`:

```cpp
glBegin(GL_TRIANGLES);
    glColor3f(1.0f, 0.0f, 0.0f);  // Color for vertex 1
    glVertex3f(0, 0, 0);
    glColor3f(1.0f, 0.0f, 0.0f);  // Color for vertex 2 - REQUIRED!
    glVertex3f(1, 0, 0);
    glColor3f(1.0f, 0.0f, 0.0f);  // Color for vertex 3 - REQUIRED!
    glVertex3f(0, 1, 0);
glEnd();
```

### Why This Happens

Emscripten's GLImmediate module calculates vertex stride based on enabled attributes:
- Position (glVertex3f): 16 bytes (4 floats: x, y, z, w)
- Color (glColor3f/4f): 4 bytes (4 unsigned bytes: r, g, b, a)
- **Total stride: 20 bytes per vertex**

The `numVertices` calculation is:
```javascript
numVertices = 4 * vertexCounter / stride
```

If color is only specified once but vertices are specified multiple times, `vertexCounter` won't be evenly divisible by `stride`, causing the assertion:
```
Assertion failed: `numVertices` must be an integer.
```

## Verified Working Functions

The following immediate mode primitives work correctly with the color-per-vertex pattern:

| Primitive | Status | Notes |
|-----------|--------|-------|
| GL_TRIANGLES | Working | RGB color interpolation works |
| GL_QUADS | Working | Use glVertex3f (glVertex2f also works) |
| GL_LINES | Working | |
| GL_LINE_STRIP | Working | |
| GL_LINE_LOOP | Working | |

## Unsupported Functions

- `glVertex2d` - Not implemented in Emscripten, use `glVertex2f` or `glVertex3f` instead

## Build Flags

Enable legacy GL emulation with these Emscripten flags:
```
-sLEGACY_GL_EMULATION
-sMAX_WEBGL_VERSION=2
```

You may see these warnings (they are expected):
```
WARNING: using emscripten GL emulation. This is a collection of limited workarounds, do not expect it to work.
WARNING: using emscripten GL immediate mode emulation. This is very limited in what it supports
```

## Implications for KiCad

KiCad uses immediate mode in several places:
1. Cursor rendering in `opengl_gal.cpp`
2. Bitmap quad rendering
3. Antialiasing overlays

Any code that sets a color once and draws multiple vertices will need modification for WASM builds.

### Possible Solutions

1. **Compatibility layer**: Wrap glColor/glVertex calls to automatically replicate colors
2. **Code modification**: Update KiCad's GAL to always specify color per-vertex
3. **VBO migration**: Convert immediate mode code to use Vertex Buffer Objects

## Test Results

All immediate mode tests pass with the color-per-vertex pattern:
- RGB triangle with smooth color interpolation
- Yellow quad
- White line
- Cyan line strip
- Magenta line loop

See `apps/minimal_test.cpp` for working examples.
