/** * gl_immediate_shim.js * * Custom OpenGL immediate mode shims for KiCad WASM port. * Fixes Emscripten LEGACY_GL_EMULATION issues: * 1. Color-per-vertex requirement - injects color before each vertex automatically * 2. Missing double-precision functions (glVertex2d, glVertex3d, glColor3d, glColor4d) * * Usage: emcc ... --js-library=lib/gl_immediate_shim.js */ addToLibrary({ // ================================================================== // GLImmediateShim - State tracking and function wrapping // ================================================================== $GLImmediateShim__deps: ['$GLImmediate'], $GLImmediateShim__postset: 'GLImmediateShim.init();', $GLImmediateShim: { // Current color state (persistent across vertices) currentColor: null, // Track if we're inside glBegin/glEnd block inBeginEnd: false, // Track if color was called since the last vertex // This prevents double-injection when code already calls color per vertex colorCalledSinceLastVertex: false, // Original functions we're wrapping origFns: {}, // Initialization flag initialized: false, init: function() { if (GLImmediateShim.initialized) return; if (typeof GLImmediate === 'undefined') { // GLImmediate not ready yet, will be called again console.log('[GLImmediateShim] Waiting for GLImmediate...'); return; } console.log('[GLImmediateShim] Initializing OpenGL immediate mode shims'); // Initialize current color to white (OpenGL default) GLImmediateShim.currentColor = new Float32Array([1.0, 1.0, 1.0, 1.0]); // Store original functions GLImmediateShim.origFns = { glBegin: _glBegin, glEnd: _glEnd, glVertex2f: _glVertex2f, glVertex3f: _glVertex3f, glColor3f: _glColor3f, glColor4f: _glColor4f, }; // Install shims _glBegin = GLImmediateShim.shimBegin; _glEnd = GLImmediateShim.shimEnd; _glVertex2f = GLImmediateShim.shimVertex2f; _glVertex3f = GLImmediateShim.shimVertex3f; _glColor3f = GLImmediateShim.shimColor3f; _glColor4f = GLImmediateShim.shimColor4f; GLImmediateShim.initialized = true; console.log('[GLImmediateShim] Initialized successfully'); }, // ================================================================== // Shim implementations // ================================================================== shimBegin: function(mode) { GLImmediateShim.inBeginEnd = true; GLImmediateShim.colorCalledSinceLastVertex = false; GLImmediateShim.origFns.glBegin(mode); }, shimEnd: function() { GLImmediateShim.inBeginEnd = false; GLImmediateShim.origFns.glEnd(); }, shimColor3f: function(r, g, b) { var c = GLImmediateShim.currentColor; c[0] = r; c[1] = g; c[2] = b; c[3] = 1.0; if (GLImmediateShim.inBeginEnd) { // Mark that color was explicitly called for this vertex GLImmediateShim.colorCalledSinceLastVertex = true; } GLImmediateShim.origFns.glColor3f(r, g, b); }, shimColor4f: function(r, g, b, a) { var c = GLImmediateShim.currentColor; c[0] = r; c[1] = g; c[2] = b; c[3] = a; if (GLImmediateShim.inBeginEnd) { // Mark that color was explicitly called for this vertex GLImmediateShim.colorCalledSinceLastVertex = true; } GLImmediateShim.origFns.glColor4f(r, g, b, a); }, // Inject current color before each vertex (only if not already called) injectColor: function() { if (!GLImmediateShim.inBeginEnd) return; // Only inject color if it wasn't already called for this vertex if (!GLImmediateShim.colorCalledSinceLastVertex) { var c = GLImmediateShim.currentColor; GLImmediateShim.origFns.glColor4f(c[0], c[1], c[2], c[3]); } // Reset the flag for the next vertex GLImmediateShim.colorCalledSinceLastVertex = false; }, shimVertex2f: function(x, y) { GLImmediateShim.injectColor(); GLImmediateShim.origFns.glVertex2f(x, y); }, shimVertex3f: function(x, y, z) { GLImmediateShim.injectColor(); GLImmediateShim.origFns.glVertex3f(x, y, z); }, }, // ================================================================== // Double-precision vertex functions (missing in Emscripten) // ================================================================== glVertex2d__deps: ['glVertex2f'], glVertex2d: function(x, y) { _glVertex2f(x, y); }, glVertex3d__deps: ['glVertex3f'], glVertex3d: function(x, y, z) { _glVertex3f(x, y, z); }, glVertex4d__deps: ['glVertex4f'], glVertex4d: function(x, y, z, w) { _glVertex4f(x, y, z, w); }, // ================================================================== // Double-precision color functions // ================================================================== glColor3d__deps: ['glColor3f'], glColor3d: function(r, g, b) { _glColor3f(r, g, b); }, glColor4d__deps: ['glColor4f'], glColor4d: function(r, g, b, a) { _glColor4f(r, g, b, a); }, }); // Ensure GLImmediateShim is included in the build if (typeof extraLibraryFuncs !== 'undefined') { extraLibraryFuncs.push('$GLImmediateShim'); }