feat(webgl): Fix GL initialization and add GLSL ES shader conversion
Progress on WEBGL_GAL rendering: - Fix GLImmediateShim initialization by adding GL function dependencies (glBegin, glEnd, glVertex2f, etc.) to $GLImmediateShim__deps - Add COLOR4D(EDA_COLOR_T) constructor stub to wasm_stubs.cpp - Fix GAL context locking - add LockContext/UnlockContext calls - Add exception catching to build (-sNO_DISABLE_EXCEPTION_CATCHING) - Create GLSL ES 1.00 shader converter in generate_shaders.py: - Remove #version 120 directive (ES 1.00 default) - Add precision highp float/int qualifiers - Convert int * float to float literals (2 * x -> 2.0 * x) - Update build script to clean output files for linker flag changes - Add console capture to test spec for debugging Current status: - WASM builds and loads successfully - GLImmediateShim initializes correctly - WEBGL_GAL creates successfully - Shader compilation fails due to Emscripten LEGACY_GL_EMULATION prepending code that conflicts with custom shader precision Next: Investigate shader compilation with LEGACY_GL_EMULATION or consider alternative approaches for GL compatibility. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
c23bc974be
commit
6c2cf85177
17 changed files with 182 additions and 24 deletions
|
|
@ -9,11 +9,79 @@ KiCad's BUILTIN_SHADERS namespace.
|
|||
import os
|
||||
import sys
|
||||
|
||||
import re
|
||||
|
||||
def convert_glsl120_to_es100(shader_source, is_fragment_shader):
|
||||
"""
|
||||
Convert GLSL 1.20 (OpenGL 2.1) shader to GLSL ES 1.00 (WebGL 1.0).
|
||||
|
||||
GLSL ES 1.00 is similar to GLSL 1.20 but:
|
||||
- No #version directive needed (defaults to 100)
|
||||
- Needs precision qualifiers
|
||||
- attribute/varying are the correct keywords (not in/out)
|
||||
- gl_FragColor is correct (not custom output)
|
||||
- texture2D is correct (not texture)
|
||||
- STRICT: int * float not allowed - need explicit float literals
|
||||
|
||||
Main changes needed:
|
||||
- Remove #version 120 (ES 1.00 is default)
|
||||
- Add precision qualifiers
|
||||
- Fix int * float type issues (2 * x -> 2.0 * x)
|
||||
"""
|
||||
lines = shader_source.split('\n')
|
||||
result = []
|
||||
added_precision = False
|
||||
|
||||
# Pattern to find integer literals multiplied by variables
|
||||
# Matches patterns like "2 * var" or "2* var" etc
|
||||
int_mult_pattern = re.compile(r'\b(\d+)\s*\*\s*([a-zA-Z_])')
|
||||
|
||||
for line in lines:
|
||||
stripped = line.strip()
|
||||
|
||||
# Skip the #version directive - ES 1.00 doesn't use it
|
||||
if stripped.startswith('#version'):
|
||||
# Add precision qualifiers instead
|
||||
if not added_precision:
|
||||
result.append('// GLSL ES 1.00 (WebGL 1.0) - converted from GLSL 1.20')
|
||||
result.append('precision highp float;')
|
||||
result.append('precision highp int;')
|
||||
result.append('')
|
||||
added_precision = True
|
||||
continue
|
||||
|
||||
# Fix int * float type issues: "2 * x" -> "2.0 * x"
|
||||
# Only convert integers that don't already have a decimal point
|
||||
def fix_int_mult(match):
|
||||
int_val = match.group(1)
|
||||
var_start = match.group(2)
|
||||
# Add .0 to make it a float literal
|
||||
return f'{int_val}.0 * {var_start}'
|
||||
|
||||
line = int_mult_pattern.sub(fix_int_mult, line)
|
||||
|
||||
result.append(line)
|
||||
|
||||
# If no version was found but we haven't added precision yet, add it at the start
|
||||
if not added_precision:
|
||||
prefix = ['// GLSL ES 1.00 (WebGL 1.0)', 'precision highp float;', 'precision highp int;', '']
|
||||
result = prefix + result
|
||||
|
||||
return '\n'.join(result)
|
||||
|
||||
|
||||
def convert_shader_to_cpp(source_path, var_name):
|
||||
"""Convert a shader file to C++ header content."""
|
||||
with open(source_path, 'rb') as f:
|
||||
data = f.read()
|
||||
|
||||
# Convert GLSL 1.20 to GLSL ES 1.00 for WebGL 1.0 compatibility
|
||||
# (ES 1.00 is closer to GLSL 1.20 and doesn't conflict with Emscripten prepends)
|
||||
shader_source = data.decode('utf-8')
|
||||
is_fragment = '_frag' in var_name or 'frag' in source_path.lower()
|
||||
shader_source = convert_glsl120_to_es100(shader_source, is_fragment)
|
||||
data = shader_source.encode('utf-8')
|
||||
|
||||
# Convert to hex array
|
||||
hex_values = ', '.join(f'0x{b:02x}' for b in data)
|
||||
hex_values += ', 0x00' # Null terminate
|
||||
|
|
|
|||
Loading…
Reference in a new issue