feat(webgl): Replace legacy GL with modern OpenGL ES 3.0

Major refactoring to remove ALL legacy OpenGL immediate mode calls from
WEBGL_GAL and replace them with WebGL 2.0/OpenGL ES 3.0 compatible code.

Key changes:
- Add MVP matrix uniform support (replaces glMatrixMode/glOrtho/glLoadMatrix)
- Add matrix math helpers (computeOrthoMatrix, multiplyMatrix4x4, etc.)
- Replace glBegin/glEnd/glVertex with vertex manager pattern
- Rewrite DrawCursor to use vertex manager and DrawLine() calls
- Rewrite DrawBitmap to use vertex manager with SHADER_FONT mode
- Replace glEnableClientState with glVertexAttribPointer
- Replace glDrawBuffer with glDrawBuffers (WebGL 2.0 API)
- Add fullscreen_quad.cpp/h for compositor Present()
- Update SHADER class with mat4 uniform support
- Add MultiplyMatrix() to vertex_manager for Transform()
- Remove all legacy GL stubs from wasm_stubs.cpp

Build now completes with FULL_ES3 mode (no LEGACY_GL_EMULATION).
Remaining issue: wxWidgets GL library calls glColor3f internally.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Viktor Vaczi 2026-01-07 23:33:49 +01:00
commit d2f1a496f5
27 changed files with 840 additions and 349 deletions

View file

@ -61,6 +61,11 @@ fi
# (Makefile only tracks object file dependencies, not linker flag changes)
rm -f "$OUTPUT_DIR"/*.js "$OUTPUT_DIR"/*.wasm 2>/dev/null || true
# Generate shaders (converts GLSL 1.20 to GLSL ES 3.00)
echo ""
echo "Generating WebGL shaders..."
python3 generate_shaders.py
echo ""
echo "Building..."
if [ "$DEBUG_BUILD" = "1" ]; then

View file

@ -68,12 +68,11 @@ BASE_LDFLAGS = -sALLOW_MEMORY_GROWTH=1 \
-sEXPORT_NAME='createGALTest' \
-sENVIRONMENT=web
# GL-specific flags - LEGACY_GL_EMULATION handles legacy GL calls (glBegin/glEnd)
# WebGL 2.0 for modern shader support
EM_GL_FLAGS = -sLEGACY_GL_EMULATION=1 -sMAX_WEBGL_VERSION=2
GL_SHIM = $(PROJECT_ROOT)/wasm/shims/gl_immediate_shim.js
# GL-specific flags - WebGL 2.0 with full ES3 support
# No LEGACY_GL_EMULATION - WEBGL_GAL uses VBOs and custom shaders
EM_GL_FLAGS = -sFULL_ES3=1 -sMAX_WEBGL_VERSION=2
LDFLAGS = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(EM_GL_FLAGS) --js-library=$(GL_SHIM) $(WX_LDFLAGS)
LDFLAGS = $(DEBUG_LDFLAGS) $(BASE_LDFLAGS) $(EM_GL_FLAGS) $(WX_LDFLAGS)
# Templates
JS = $(TOOLS_ROOT)/wx.js
@ -117,6 +116,7 @@ WEBGL_SRCS = webgl/webgl_gal.cpp \
webgl/cached_container_ram.cpp \
webgl/shader.cpp \
webgl/webgl_compositor.cpp \
webgl/fullscreen_quad.cpp \
webgl/utils.cpp \
webgl/gl_context_mgr.cpp \
webgl/gl_resources.cpp \

View file

@ -11,61 +11,187 @@ import sys
import re
def convert_glsl120_to_es100(shader_source, is_fragment_shader):
def convert_glsl120_to_es300(shader_source, is_fragment_shader):
"""
Convert GLSL 1.20 (OpenGL 2.1) shader to GLSL ES 1.00 (WebGL 1.0).
Convert GLSL 1.20 (OpenGL 2.1) shader to GLSL ES 3.00 (WebGL 2.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)
Key changes:
- #version 120 -> #version 300 es (must be ABSOLUTE first line!)
- Move any comments before #version to after declarations
- Add precision qualifiers
- attribute -> in
- varying -> out (vertex) / in (fragment)
- gl_FragColor -> custom output variable (fragment)
- texture2D -> texture
- Fix int * float type issues (2 * x -> 2.0 * x)
- Fix int / float type issues (x / 4 -> x / 4.0)
Legacy GL built-in conversions (for KiCad shaders):
- gl_ModelViewProjectionMatrix -> uniform u_modelViewProjectionMatrix
- gl_Vertex -> attribute a_vertex
- gl_Color -> attribute a_color (vertex) / varying v_color (fragment)
- gl_FrontColor -> varying v_color (vertex output)
- gl_TexCoord[0] -> varying v_texCoord
- ftransform() -> u_modelViewProjectionMatrix * a_vertex
"""
lines = shader_source.split('\n')
result = []
added_precision = False
version_replaced = False
# Pattern to find integer literals multiplied by variables
# Matches patterns like "2 * var" or "2* var" etc
# Track what legacy built-ins are used so we can add declarations
uses_mvp_matrix = 'gl_ModelViewProjectionMatrix' in shader_source or 'ftransform()' in shader_source
uses_gl_vertex = 'gl_Vertex' in shader_source or 'ftransform()' in shader_source
uses_gl_color = 'gl_Color' in shader_source
uses_gl_front_color = 'gl_FrontColor' in shader_source
uses_gl_texcoord = 'gl_TexCoord' in shader_source
uses_gl_multitexcoord0 = 'gl_MultiTexCoord0' in shader_source
# GLSL ES 3.00 requires #version to be the ABSOLUTE first line
# Collect any comments before #version to add after declarations
pre_version_comments = []
in_multiline_comment = False
# Patterns to fix type issues
int_mult_pattern = re.compile(r'\b(\d+)\s*\*\s*([a-zA-Z_])')
div_int_pattern = re.compile(r'([a-zA-Z_)\]]+)\s*/\s*(\d+)(?!\.)')
for line in lines:
stripped = line.strip()
# Skip the #version directive - ES 1.00 doesn't use it
# Before #version is found, collect comments and empty lines
if not version_replaced:
# Track multiline comment state
if '/*' in stripped and '*/' not in stripped:
in_multiline_comment = True
pre_version_comments.append(line)
continue
elif in_multiline_comment:
pre_version_comments.append(line)
if '*/' in stripped:
in_multiline_comment = False
continue
elif stripped.startswith('//') or stripped == '' or ('/*' in stripped and '*/' in stripped):
pre_version_comments.append(line)
continue
# Replace #version 120 with #version 300 es + precision + legacy built-in replacements
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
result.append('#version 300 es')
result.append('precision highp float;')
result.append('precision highp int;')
if is_fragment_shader:
result.append('out vec4 fragColor;')
# Fragment shader receives varyings from vertex shader
if uses_gl_color or uses_gl_front_color:
result.append('in vec4 v_color;')
if uses_gl_texcoord:
result.append('in vec2 v_texCoord;')
else:
# Vertex shader - add uniforms and attributes for legacy built-ins
if uses_mvp_matrix:
result.append('uniform mat4 u_modelViewProjectionMatrix;')
if uses_gl_vertex:
result.append('in vec4 a_vertex;')
if uses_gl_color:
result.append('in vec4 a_color;')
if uses_gl_multitexcoord0:
result.append('in vec4 a_texCoord0;')
# Vertex shader outputs varyings
if uses_gl_front_color or uses_gl_color:
result.append('out vec4 v_color;')
if uses_gl_texcoord:
result.append('out vec2 v_texCoord;')
# Add back any pre-version comments after the declarations
if pre_version_comments:
result.append('') # Blank line before comments
result.extend(pre_version_comments)
version_replaced = True
continue
# Convert attribute to in (vertex shaders only)
if not is_fragment_shader and stripped.startswith('attribute '):
line = line.replace('attribute ', 'in ', 1)
# Convert varying to out (vertex) or in (fragment)
if stripped.startswith('varying '):
if is_fragment_shader:
line = line.replace('varying ', 'in ', 1)
else:
line = line.replace('varying ', 'out ', 1)
# Convert gl_FragColor to fragColor (fragment shaders)
if is_fragment_shader and 'gl_FragColor' in line:
line = line.replace('gl_FragColor', 'fragColor')
# Convert texture2D to texture
if 'texture2D' in line:
line = line.replace('texture2D', 'texture')
# Convert legacy GL built-ins
# ftransform() -> u_modelViewProjectionMatrix * a_vertex (must be done before other replacements)
if 'ftransform()' in line:
line = line.replace('ftransform()', 'u_modelViewProjectionMatrix * a_vertex')
# gl_ModelViewProjectionMatrix -> u_modelViewProjectionMatrix
if 'gl_ModelViewProjectionMatrix' in line:
line = line.replace('gl_ModelViewProjectionMatrix', 'u_modelViewProjectionMatrix')
# gl_Vertex -> a_vertex
if 'gl_Vertex' in line:
line = line.replace('gl_Vertex', 'a_vertex')
# gl_FrontColor -> v_color (vertex shader output)
if 'gl_FrontColor' in line:
line = line.replace('gl_FrontColor', 'v_color')
# gl_Color -> a_color (vertex) or v_color (fragment)
if 'gl_Color' in line:
if is_fragment_shader:
line = line.replace('gl_Color', 'v_color')
else:
line = line.replace('gl_Color', 'a_color')
# gl_TexCoord[0].st or gl_TexCoord[0].xy -> v_texCoord
if 'gl_TexCoord' in line:
# Handle gl_TexCoord[0].st and gl_TexCoord[0].xy
line = re.sub(r'gl_TexCoord\[0\]\.st', 'v_texCoord', line)
line = re.sub(r'gl_TexCoord\[0\]\.xy', 'v_texCoord', line)
# Handle bare gl_TexCoord[0] (less common)
line = re.sub(r'gl_TexCoord\[0\]', 'vec4(v_texCoord, 0.0, 0.0)', line)
# gl_MultiTexCoord0 -> a_texCoord0 (for SMAA shaders)
if 'gl_MultiTexCoord0' in line:
line = re.sub(r'gl_MultiTexCoord0\.st', 'a_texCoord0.st', line)
line = re.sub(r'gl_MultiTexCoord0\.xy', 'a_texCoord0.xy', line)
line = line.replace('gl_MultiTexCoord0', 'a_texCoord0')
# Fix uniform int -> uniform float (GLSL ES 3.00 doesn't allow implicit int/float conversion)
# This specifically handles u_fontTextureWidth which is multiplied with floats
if 'uniform int ' in line:
line = line.replace('uniform int ', 'uniform float ')
# 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)
# Fix float / int type issues: "x / 4" -> "x / 4.0"
def fix_div_int(match):
var_part = match.group(1)
int_val = match.group(2)
return f'{var_part} / {int_val}.0'
line = div_int_pattern.sub(fix_div_int, 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
# If no #version was found, DON'T add one - the shader will get its version
# from a runtime preamble (e.g. SMAA shaders). Just do basic conversions.
# NOTE: If the shader has no #version, we still need to convert legacy GL built-ins
return '\n'.join(result)
@ -75,11 +201,10 @@ def convert_shader_to_cpp(source_path, var_name):
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)
# Convert GLSL 1.20 to GLSL ES 3.00 for WebGL 2.0
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)
shader_source = convert_glsl120_to_es300(shader_source, is_fragment)
data = shader_source.encode('utf-8')
# Convert to hex array

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -5,9 +5,9 @@
namespace KIGFX {
namespace BUILTIN_SHADERS {
static unsigned char glsl_smaa_pass_1_frag_color_bytes[] = { 0x2f, 0x2f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x45, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x20, 0x28, 0x57, 0x65, 0x62, 0x47, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x45, 0x64, 0x67, 0x65, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x29, 0x2e, 0x78, 0x79, 0x3b, 0x0a, 0x7d, 0x00 };
static unsigned char glsl_smaa_pass_1_frag_color_bytes[] = { 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x45, 0x64, 0x67, 0x65, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x29, 0x2e, 0x78, 0x79, 0x3b, 0x0a, 0x7d, 0x00 };
std::string glsl_smaa_pass_1_frag_color = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_1_frag_color_bytes), 243);
std::string glsl_smaa_pass_1_frag_color = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_1_frag_color_bytes), 156);
}
}

View file

@ -5,9 +5,9 @@
namespace KIGFX {
namespace BUILTIN_SHADERS {
static unsigned char glsl_smaa_pass_1_frag_luma_bytes[] = { 0x2f, 0x2f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x45, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x20, 0x28, 0x57, 0x65, 0x62, 0x47, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x4c, 0x75, 0x6d, 0x61, 0x45, 0x64, 0x67, 0x65, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x29, 0x2e, 0x78, 0x79, 0x3b, 0x0a, 0x7d, 0x00 };
static unsigned char glsl_smaa_pass_1_frag_luma_bytes[] = { 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2e, 0x78, 0x79, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x4c, 0x75, 0x6d, 0x61, 0x45, 0x64, 0x67, 0x65, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x29, 0x2e, 0x78, 0x79, 0x3b, 0x0a, 0x7d, 0x00 };
std::string glsl_smaa_pass_1_frag_luma = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_1_frag_luma_bytes), 242);
std::string glsl_smaa_pass_1_frag_luma = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_1_frag_luma_bytes), 155);
}
}

View file

@ -5,9 +5,9 @@
namespace KIGFX {
namespace BUILTIN_SHADERS {
static unsigned char glsl_smaa_pass_1_vert_bytes[] = { 0x2f, 0x2f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x45, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x20, 0x28, 0x57, 0x65, 0x62, 0x47, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x5f, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x45, 0x64, 0x67, 0x65, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x53, 0x28, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x66, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x29, 0x3b, 0x0a, 0x0a, 0x7d, 0x00 };
static unsigned char glsl_smaa_pass_1_vert_bytes[] = { 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x45, 0x64, 0x67, 0x65, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x53, 0x28, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x20, 0x20, 0x3d, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a, 0x20, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x3b, 0x0a, 0x7d, 0x00 };
std::string glsl_smaa_pass_1_vert = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_1_vert_bytes), 252);
std::string glsl_smaa_pass_1_vert = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_1_vert_bytes), 189);
}
}

View file

@ -5,9 +5,9 @@
namespace KIGFX {
namespace BUILTIN_SHADERS {
static unsigned char glsl_smaa_pass_2_frag_bytes[] = { 0x2f, 0x2f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x45, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x20, 0x28, 0x57, 0x65, 0x62, 0x47, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x65, 0x64, 0x67, 0x65, 0x73, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x61, 0x72, 0x65, 0x61, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x65, 0x64, 0x67, 0x65, 0x73, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x61, 0x72, 0x65, 0x61, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e, 0x2c, 0x30, 0x2e, 0x2c, 0x30, 0x2e, 0x2c, 0x30, 0x2e, 0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x00 };
static unsigned char glsl_smaa_pass_2_frag_bytes[] = { 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x65, 0x64, 0x67, 0x65, 0x73, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x61, 0x72, 0x65, 0x61, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x65, 0x64, 0x67, 0x65, 0x73, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x61, 0x72, 0x65, 0x61, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x76, 0x65, 0x63, 0x34, 0x28, 0x30, 0x2e, 0x2c, 0x30, 0x2e, 0x2c, 0x30, 0x2e, 0x2c, 0x30, 0x2e, 0x29, 0x29, 0x3b, 0x0a, 0x7d, 0x00 };
std::string glsl_smaa_pass_2_frag = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_2_frag_bytes), 372);
std::string glsl_smaa_pass_2_frag = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_2_frag_bytes), 280);
}
}

View file

@ -5,9 +5,9 @@
namespace KIGFX {
namespace BUILTIN_SHADERS {
static unsigned char glsl_smaa_pass_2_vert_bytes[] = { 0x2f, 0x2f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x45, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x20, 0x28, 0x57, 0x65, 0x62, 0x47, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x5f, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x53, 0x28, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x29, 0x3b, 0x0a, 0x7d, 0x00 };
static unsigned char glsl_smaa_pass_2_vert_bytes[] = { 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x5b, 0x33, 0x5d, 0x3b, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x57, 0x65, 0x69, 0x67, 0x68, 0x74, 0x43, 0x61, 0x6c, 0x63, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x53, 0x28, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x70, 0x69, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a, 0x20, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x3b, 0x0a, 0x7d, 0x00 };
std::string glsl_smaa_pass_2_vert = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_2_vert_bytes), 295);
std::string glsl_smaa_pass_2_vert = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_2_vert_bytes), 229);
}
}

View file

@ -5,9 +5,9 @@
namespace KIGFX {
namespace BUILTIN_SHADERS {
static unsigned char glsl_smaa_pass_3_frag_bytes[] = { 0x2f, 0x2f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x45, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x20, 0x28, 0x57, 0x65, 0x62, 0x47, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x68, 0x6f, 0x6f, 0x64, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x78, 0x29, 0x3b, 0x0a, 0x7d, 0x00 };
static unsigned char glsl_smaa_pass_3_frag_bytes[] = { 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x69, 0x6e, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x78, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x68, 0x6f, 0x6f, 0x64, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x53, 0x28, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x2c, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x2c, 0x20, 0x62, 0x6c, 0x65, 0x6e, 0x64, 0x54, 0x65, 0x78, 0x29, 0x3b, 0x0a, 0x7d, 0x00 };
std::string glsl_smaa_pass_3_frag = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_3_frag_bytes), 274);
std::string glsl_smaa_pass_3_frag = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_3_frag_bytes), 187);
}
}

View file

@ -5,9 +5,9 @@
namespace KIGFX {
namespace BUILTIN_SHADERS {
static unsigned char glsl_smaa_pass_3_vert_bytes[] = { 0x2f, 0x2f, 0x20, 0x47, 0x4c, 0x53, 0x4c, 0x20, 0x45, 0x53, 0x20, 0x31, 0x2e, 0x30, 0x30, 0x20, 0x28, 0x57, 0x65, 0x62, 0x47, 0x4c, 0x20, 0x31, 0x2e, 0x30, 0x29, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x3b, 0x0a, 0x70, 0x72, 0x65, 0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x69, 0x6e, 0x74, 0x3b, 0x0a, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3b, 0x0a, 0x76, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x67, 0x6c, 0x5f, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x68, 0x6f, 0x6f, 0x64, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x53, 0x28, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, 0x28, 0x29, 0x3b, 0x0a, 0x7d, 0x00 };
static unsigned char glsl_smaa_pass_3_vert_bytes[] = { 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x3b, 0x0a, 0x6f, 0x75, 0x74, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x2e, 0x73, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x53, 0x4d, 0x41, 0x41, 0x4e, 0x65, 0x69, 0x67, 0x68, 0x62, 0x6f, 0x72, 0x68, 0x6f, 0x6f, 0x64, 0x42, 0x6c, 0x65, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x56, 0x53, 0x28, 0x20, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x2c, 0x20, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x20, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x20, 0x2a, 0x20, 0x61, 0x5f, 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x3b, 0x0a, 0x7d, 0x00 };
std::string glsl_smaa_pass_3_vert = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_3_vert_bytes), 254);
std::string glsl_smaa_pass_3_vert = std::string(reinterpret_cast<char const*>(glsl_smaa_pass_3_vert_bytes), 192);
}
}

View file

@ -388,3 +388,7 @@ KICAD_SINGLETON::~KICAD_SINGLETON() {
delete m_GLContextManager;
m_GLContextManager = nullptr;
}
// Legacy GL stubs removed - all rendering now uses modern OpenGL ES 3.0
// If you get linker errors about missing GL functions, the calling code needs
// to be rewritten to use VBOs/shaders instead of immediate mode.

View file

@ -0,0 +1,178 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "fullscreen_quad.h"
#include "utils.h"
using namespace KIGFX;
FULLSCREEN_QUAD::FULLSCREEN_QUAD() :
m_initialized( false ),
m_quadVBO( 0 ),
m_quadVAO( 0 ),
m_triangleVBO( 0 ),
m_triangleVAO( 0 )
{
}
FULLSCREEN_QUAD::~FULLSCREEN_QUAD()
{
Cleanup();
}
void FULLSCREEN_QUAD::Initialize()
{
if( m_initialized )
return;
// Quad vertices: 2 triangles covering -1 to +1 in clip space
// Each vertex has: x, y, z, w (position) + s, t, 0, 0 (texcoord)
// Note: z=0, w=1 for positions; texcoords map [0,1] to screen
static const float quadVertices[] = {
// First triangle (top-left, bottom-left, top-right)
// Position (x,y,z,w) TexCoord (s,t,0,0)
-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // top-left
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-left
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // top-right
// Second triangle (top-right, bottom-left, bottom-right)
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, // top-right
-1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom-left
1.0f, -1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, // bottom-right
};
// Create quad VAO and VBO
glGenVertexArrays( 1, &m_quadVAO );
glGenBuffers( 1, &m_quadVBO );
glBindVertexArray( m_quadVAO );
glBindBuffer( GL_ARRAY_BUFFER, m_quadVBO );
glBufferData( GL_ARRAY_BUFFER, sizeof( quadVertices ), quadVertices, GL_STATIC_DRAW );
// Position attribute (a_vertex) - location 0
glVertexAttribPointer( VERTEX_ATTRIB_LOC, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( float ),
(void*) 0 );
glEnableVertexAttribArray( VERTEX_ATTRIB_LOC );
// TexCoord attribute (a_texCoord0) - location 1
glVertexAttribPointer( TEXCOORD_ATTRIB_LOC, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( float ),
(void*) ( 4 * sizeof( float ) ) );
glEnableVertexAttribArray( TEXCOORD_ATTRIB_LOC );
glBindVertexArray( 0 );
checkGlError( "creating fullscreen quad VBO", __FILE__, __LINE__ );
// Oversized triangle vertices: covers entire screen with one triangle
// Uses coordinates that extend beyond the viewport
static const float triangleVertices[] = {
// Position (x,y,z,w) TexCoord (s,t,0,0)
-1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, // top-left
-1.0f, -3.0f, 0.0f, 1.0f, 0.0f, -1.0f, 0.0f, 0.0f, // bottom-left (extended)
3.0f, 1.0f, 0.0f, 1.0f, 2.0f, 1.0f, 0.0f, 0.0f, // top-right (extended)
};
// Create triangle VAO and VBO
glGenVertexArrays( 1, &m_triangleVAO );
glGenBuffers( 1, &m_triangleVBO );
glBindVertexArray( m_triangleVAO );
glBindBuffer( GL_ARRAY_BUFFER, m_triangleVBO );
glBufferData( GL_ARRAY_BUFFER, sizeof( triangleVertices ), triangleVertices, GL_STATIC_DRAW );
// Position attribute (a_vertex) - location 0
glVertexAttribPointer( VERTEX_ATTRIB_LOC, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( float ),
(void*) 0 );
glEnableVertexAttribArray( VERTEX_ATTRIB_LOC );
// TexCoord attribute (a_texCoord0) - location 1
glVertexAttribPointer( TEXCOORD_ATTRIB_LOC, 4, GL_FLOAT, GL_FALSE, 8 * sizeof( float ),
(void*) ( 4 * sizeof( float ) ) );
glEnableVertexAttribArray( TEXCOORD_ATTRIB_LOC );
glBindVertexArray( 0 );
checkGlError( "creating fullscreen triangle VBO", __FILE__, __LINE__ );
m_initialized = true;
}
void FULLSCREEN_QUAD::Draw()
{
if( !m_initialized )
Initialize();
glBindVertexArray( m_quadVAO );
glDrawArrays( GL_TRIANGLES, 0, 6 );
glBindVertexArray( 0 );
}
void FULLSCREEN_QUAD::DrawTriangle()
{
if( !m_initialized )
Initialize();
glBindVertexArray( m_triangleVAO );
glDrawArrays( GL_TRIANGLES, 0, 3 );
glBindVertexArray( 0 );
}
void FULLSCREEN_QUAD::Cleanup()
{
if( m_quadVBO )
{
glDeleteBuffers( 1, &m_quadVBO );
m_quadVBO = 0;
}
if( m_quadVAO )
{
glDeleteVertexArrays( 1, &m_quadVAO );
m_quadVAO = 0;
}
if( m_triangleVBO )
{
glDeleteBuffers( 1, &m_triangleVBO );
m_triangleVBO = 0;
}
if( m_triangleVAO )
{
glDeleteVertexArrays( 1, &m_triangleVAO );
m_triangleVAO = 0;
}
m_initialized = false;
}
// Global instance
static FULLSCREEN_QUAD s_fullscreenQuad;
FULLSCREEN_QUAD& KIGFX::GetFullscreenQuad()
{
return s_fullscreenQuad;
}

View file

@ -0,0 +1,97 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file fullscreen_quad.h
* @brief VBO-based fullscreen quad for WebGL texture compositing.
* Replaces legacy GL immediate mode (glBegin/glVertex/glEnd).
*/
#ifndef FULLSCREEN_QUAD_H_
#define FULLSCREEN_QUAD_H_
#include "kiglew.h"
namespace KIGFX
{
/**
* A VBO-based fullscreen quad for drawing textures to the screen.
* Used by compositor and antialiasing passes.
*/
class FULLSCREEN_QUAD
{
public:
FULLSCREEN_QUAD();
~FULLSCREEN_QUAD();
/**
* Initialize the VBO and VAO. Must be called after GL context is created.
*/
void Initialize();
/**
* Draw the fullscreen quad. Assumes a shader is already bound.
* The shader must have:
* - a_vertex (location 0): vec4 position
* - a_texCoord0 (location 1): vec4 texture coordinates
*/
void Draw();
/**
* Draw a fullscreen triangle (more efficient than quad for some GPUs).
* Uses an oversized triangle that covers the entire screen.
*/
void DrawTriangle();
/**
* Check if initialized.
*/
bool IsInitialized() const { return m_initialized; }
/**
* Clean up GL resources.
*/
void Cleanup();
// Attribute locations used by the fullscreen quad
static const GLuint VERTEX_ATTRIB_LOC = 0;
static const GLuint TEXCOORD_ATTRIB_LOC = 1;
private:
bool m_initialized;
GLuint m_quadVBO; ///< VBO for quad vertices (6 vertices, 2 triangles)
GLuint m_quadVAO; ///< VAO for quad
GLuint m_triangleVBO; ///< VBO for single oversized triangle
GLuint m_triangleVAO; ///< VAO for triangle
};
/**
* Get the global fullscreen quad instance.
* This is lazily initialized on first use.
*/
FULLSCREEN_QUAD& GetFullscreenQuad();
} // namespace KIGFX
#endif /* FULLSCREEN_QUAD_H_ */

View file

@ -59,6 +59,8 @@ GPU_MANAGER::GPU_MANAGER( VERTEX_CONTAINER* aContainer ) :
m_container( aContainer ),
m_shader( nullptr ),
m_shaderAttrib( 0 ),
m_vertexAttrib( 0 ),
m_colorAttrib( 0 ),
m_enableDepthTest( true )
{
}
@ -73,6 +75,8 @@ void GPU_MANAGER::SetShader( SHADER& aShader )
{
m_shader = &aShader;
m_shaderAttrib = m_shader->GetAttribute( "a_shaderParams" );
m_vertexAttrib = m_shader->GetAttribute( "a_vertex" );
m_colorAttrib = m_shader->GetAttribute( "a_color" );
if( m_shaderAttrib == -1 )
{
@ -159,14 +163,19 @@ void GPU_CACHED_MANAGER::EndDrawing()
else
glDisable( GL_DEPTH_TEST );
// Prepare buffers
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
// Bind vertices data buffers
glBindBuffer( GL_ARRAY_BUFFER, cached->GetBufferHandle() );
glVertexPointer( COORD_STRIDE, GL_FLOAT, VERTEX_SIZE, (GLvoid*) COORD_OFFSET );
glColorPointer( COLOR_STRIDE, GL_UNSIGNED_BYTE, VERTEX_SIZE, (GLvoid*) COLOR_OFFSET );
// Modern vertex attributes (replacing legacy glEnableClientState/glVertexPointer/glColorPointer)
// Vertex position (a_vertex)
glEnableVertexAttribArray( m_vertexAttrib );
glVertexAttribPointer( m_vertexAttrib, COORD_STRIDE, GL_FLOAT, GL_FALSE, VERTEX_SIZE,
(GLvoid*) COORD_OFFSET );
// Vertex color (a_color) - note: normalize=GL_TRUE for unsigned bytes to [0,1]
glEnableVertexAttribArray( m_colorAttrib );
glVertexAttribPointer( m_colorAttrib, COLOR_STRIDE, GL_UNSIGNED_BYTE, GL_TRUE, VERTEX_SIZE,
(GLvoid*) COLOR_OFFSET );
if( m_shader != nullptr ) // Use shader if applicable
{
@ -231,9 +240,9 @@ void GPU_CACHED_MANAGER::EndDrawing()
glBindBuffer( GL_ARRAY_BUFFER, 0 );
cached->ClearDirty();
// Deactivate vertex array
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
// Deactivate vertex arrays (modern vertex attributes)
glDisableVertexAttribArray( m_colorAttrib );
glDisableVertexAttribArray( m_vertexAttrib );
if( m_shader != nullptr )
{
@ -292,12 +301,16 @@ void GPU_NONCACHED_MANAGER::EndDrawing()
else
glDisable( GL_DEPTH_TEST );
// Prepare buffers
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_COLOR_ARRAY );
// Modern vertex attributes (replacing legacy glEnableClientState/glVertexPointer/glColorPointer)
// Vertex position (a_vertex)
glEnableVertexAttribArray( m_vertexAttrib );
glVertexAttribPointer( m_vertexAttrib, COORD_STRIDE, GL_FLOAT, GL_FALSE, VERTEX_SIZE,
coordinates );
glVertexPointer( COORD_STRIDE, GL_FLOAT, VERTEX_SIZE, coordinates );
glColorPointer( COLOR_STRIDE, GL_UNSIGNED_BYTE, VERTEX_SIZE, colors );
// Vertex color (a_color) - note: normalize=GL_TRUE for unsigned bytes to [0,1]
glEnableVertexAttribArray( m_colorAttrib );
glVertexAttribPointer( m_colorAttrib, COLOR_STRIDE, GL_UNSIGNED_BYTE, GL_TRUE, VERTEX_SIZE,
colors );
if( m_shader != nullptr ) // Use shader if applicable
{
@ -315,9 +328,9 @@ void GPU_NONCACHED_MANAGER::EndDrawing()
wxLogTrace( traceGalProfile, wxT( "Noncached manager size: %d" ), m_container->GetSize() );
#endif /* KICAD_GAL_PROFILE */
// Deactivate vertex array
glDisableClientState( GL_COLOR_ARRAY );
glDisableClientState( GL_VERTEX_ARRAY );
// Deactivate vertex arrays
glDisableVertexAttribArray( m_colorAttrib );
glDisableVertexAttribArray( m_vertexAttrib );
if( m_shader != nullptr )
{

View file

@ -93,6 +93,8 @@ protected:
///< Location of shader attributes (for glVertexAttribPointer)
int m_shaderAttrib;
int m_vertexAttrib; ///< Location of a_vertex attribute
int m_colorAttrib; ///< Location of a_color attribute
///< true: enable Z test when drawing
bool m_enableDepthTest;

View file

@ -33,15 +33,13 @@
#if defined( __EMSCRIPTEN__ )
// Prevent real GLEW header from being included (Emscripten has one too)
// We provide our own compatibility stubs below
#ifndef __glew_h__
#define __glew_h__
#endif
// WebGL2/GLES3: Modern shader functions (glUseProgram, etc.)
// WebGL2/GLES3: Modern shader functions
// Note: NO legacy GL includes - all rendering uses VBOs/shaders
#include <GLES3/gl3.h>
// Legacy GL emulation: glMatrixMode, glColor4d, glBegin/glEnd, etc.
#include <GL/gl.h>
// GLU tesselator - provided by wasm/stubs/glu_wasm_impl.cpp
#include <GL/glu.h>
@ -154,54 +152,11 @@
(void)callback; (void)userParam;
}
// GLdouble type for double-precision functions
// GLdouble type (needed for some API signatures)
#ifndef GLdouble
typedef double GLdouble;
#endif
// Double-precision GL function wrappers - LEGACY_GL_EMULATION only provides float versions
// These convert double arguments to float and call the float variants
inline void glVertex2d(GLdouble x, GLdouble y) {
glVertex2f((GLfloat)x, (GLfloat)y);
}
inline void glVertex3d(GLdouble x, GLdouble y, GLdouble z) {
glVertex3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
inline void glColor4d(GLdouble r, GLdouble g, GLdouble b, GLdouble a) {
glColor4f((GLfloat)r, (GLfloat)g, (GLfloat)b, (GLfloat)a);
}
inline void glColor3d(GLdouble r, GLdouble g, GLdouble b) {
glColor3f((GLfloat)r, (GLfloat)g, (GLfloat)b);
}
inline void glTranslated(GLdouble x, GLdouble y, GLdouble z) {
glTranslatef((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
inline void glScaled(GLdouble x, GLdouble y, GLdouble z) {
glScalef((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
inline void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) {
glRotatef((GLfloat)angle, (GLfloat)x, (GLfloat)y, (GLfloat)z);
}
inline void glNormal3d(GLdouble x, GLdouble y, GLdouble z) {
glNormal3f((GLfloat)x, (GLfloat)y, (GLfloat)z);
}
inline void glTexCoord2d(GLdouble s, GLdouble t) {
glTexCoord2f((GLfloat)s, (GLfloat)t);
}
inline void glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) {
glRectf((GLfloat)x1, (GLfloat)y1, (GLfloat)x2, (GLfloat)y2);
}
inline void glLoadMatrixd(const GLdouble* m) {
GLfloat fm[16];
for(int i = 0; i < 16; i++) fm[i] = (GLfloat)m[i];
glLoadMatrixf(fm);
}
inline void glMultMatrixd(const GLdouble* m) {
GLfloat fm[16];
for(int i = 0; i < 16; i++) fm[i] = (GLfloat)m[i];
glMultMatrixf(fm);
}
// Display lists - not supported in WebGL, stub implementations
inline GLuint glGenLists(GLsizei range) { (void)range; return 0; }
inline GLboolean glIsList(GLuint list) { (void)list; return GL_FALSE; }
@ -210,22 +165,6 @@
inline void glCallList(GLuint list) { (void)list; }
inline void glDeleteLists(GLuint list, GLsizei range) { (void)list; (void)range; }
// Lighting and material functions - stubs (lighting not fully supported in WebGL)
inline void glLightModeli(GLenum pname, GLint param) { (void)pname; (void)param; }
inline void glColorMaterial(GLenum face, GLenum mode) { (void)face; (void)mode; }
inline void glMaterialf(GLenum face, GLenum pname, GLfloat param) {
(void)face; (void)pname; (void)param;
}
inline void glMaterialfv(GLenum face, GLenum pname, const GLfloat* params) {
(void)face; (void)pname; (void)params;
}
inline void glLightfv(GLenum light, GLenum pname, const GLfloat* params) {
(void)light; (void)pname; (void)params;
}
inline void glLightf(GLenum light, GLenum pname, GLfloat param) {
(void)light; (void)pname; (void)param;
}
#elif defined( __unix__ ) and not defined( __APPLE__ )
#ifdef KICAD_USE_EGL

View file

@ -172,6 +172,13 @@ void SHADER::SetParameter( int aParameterNumber, const VECTOR2D& aValue ) const
}
void SHADER::SetParameter( int aParameterNumber, const float* aMatrix4x4 ) const
{
assert( (unsigned) aParameterNumber < parameterLocation.size() );
glUniformMatrix4fv( parameterLocation[aParameterNumber], 1, GL_FALSE, aMatrix4x4 );
}
int SHADER::GetAttribute( const std::string& aAttributeName ) const
{
return glGetAttribLocation( programNumber, aAttributeName.c_str() );

View file

@ -180,6 +180,7 @@ public:
void SetParameter( int aParameterNumber, int aValue ) const;
void SetParameter( int aParameterNumber, const VECTOR2D& aValue ) const;
void SetParameter( int aParameterNumber, float f0, float f1, float f2, float f3 ) const;
void SetParameter( int aParameterNumber, const float* aMatrix4x4 ) const; ///< Set 4x4 matrix
/**
* Get an attribute location.

View file

@ -231,6 +231,18 @@ public:
m_transform = glm::scale( m_transform, glm::vec3( aX, aY, aZ ) );
}
/**
* Multiply the current transformation matrix by the given matrix.
*
* It is the equivalent of the glMultMatrixf() function.
*
* @param aMatrix is a 4x4 transformation matrix to multiply.
*/
inline void MultiplyMatrix( const glm::mat4& aMatrix )
{
m_transform = m_transform * aMatrix;
}
/**
* Push the current transformation matrix stack.
*

View file

@ -23,6 +23,7 @@
#include "webgl_antialiasing.h"
#include "webgl_compositor.h"
#include "fullscreen_quad.h"
#include "utils.h"
#include <gal/color4d.h>
@ -99,33 +100,8 @@ namespace
{
void draw_fullscreen_primitive()
{
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glBegin( GL_TRIANGLES );
glTexCoord2f( 0.0f, 1.0f );
glVertex2f( -1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 1.0f );
glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 1.0f, 1.0f );
glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 0.0f );
glVertex2f( 1.0f, -1.0f );
glEnd();
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
// Use VBO-based fullscreen quad (replaces legacy immediate mode)
KIGFX::GetFullscreenQuad().Draw();
}
} // namespace
@ -234,7 +210,7 @@ VECTOR2I ANTIALIASING_SMAA::GetInternalBufferSize()
void ANTIALIASING_SMAA::loadShaders()
{
// Load constant textures
glEnable( GL_TEXTURE_2D );
// Note: GL_TEXTURE_2D enable not needed in WebGL 2.0
glActiveTexture( GL_TEXTURE0 );
glGenTextures( 1, &smaaAreaTex );
@ -281,18 +257,25 @@ void ANTIALIASING_SMAA::loadShaders()
"#define SMAA_CORNER_ROUNDING 0\n";
edge_detect_shader = BUILTIN_SHADERS::glsl_smaa_pass_1_frag_luma;
// set up shaders
// set up shaders - Use GLSL ES 3.00 for WebGL 2.0
std::string vert_preamble( R"SHADER(
#version 120
#define SMAA_GLSL_2_1
#version 300 es
precision highp float;
precision highp int;
#define SMAA_GLSL_3
#define SMAA_INCLUDE_VS 1
#define SMAA_INCLUDE_PS 0
uniform vec4 SMAA_RT_METRICS;
in vec4 a_vertex;
in vec4 a_texCoord0;
)SHADER" );
std::string frag_preamble( R"SHADER(
#version 120
#define SMAA_GLSL_2_1
#version 300 es
precision highp float;
precision highp int;
out vec4 fragColor;
#define SMAA_GLSL_3
#define SMAA_INCLUDE_VS 0
#define SMAA_INCLUDE_PS 1
uniform vec4 SMAA_RT_METRICS;
@ -476,25 +459,8 @@ namespace
{
void draw_fullscreen_triangle()
{
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glBegin( GL_TRIANGLES );
glTexCoord2f( 0.0f, 1.0f );
glVertex2f( -1.0f, 1.0f );
glTexCoord2f( 0.0f, -1.0f );
glVertex2f( -1.0f, -3.0f );
glTexCoord2f( 2.0f, 1.0f );
glVertex2f( 3.0f, 1.0f );
glEnd();
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
// Use VBO-based fullscreen triangle (replaces legacy immediate mode)
KIGFX::GetFullscreenQuad().DrawTriangle();
}
} // namespace
@ -505,7 +471,7 @@ void ANTIALIASING_SMAA::Present()
glDisable( GL_BLEND );
glDisable( GL_DEPTH_TEST );
glEnable( GL_TEXTURE_2D );
// Note: GL_TEXTURE_2D enable not needed in WebGL 2.0
//
// pass 1: main-buffer -> smaaEdgesBuffer

View file

@ -31,6 +31,7 @@
*/
#include "webgl_compositor.h"
#include "fullscreen_quad.h"
#include "utils.h"
#include <gal/color4d.h>
@ -49,12 +50,62 @@ WEBGL_COMPOSITOR::WEBGL_COMPOSITOR() :
m_mainFbo( 0 ),
m_depthBuffer( 0 ),
m_curFbo( DIRECT_RENDERING ),
m_currentAntialiasingMode( GAL_ANTIALIASING_MODE::AA_NONE )
m_currentAntialiasingMode( GAL_ANTIALIASING_MODE::AA_NONE ),
m_blitTexUniform( -1 )
{
m_antialiasing = std::make_unique<ANTIALIASING_NONE>( this );
}
void WEBGL_COMPOSITOR::initBlitShader()
{
// Simple blit shader for texture compositing
// Replaces legacy fixed-function GL_MODULATE texturing
static const char* blitVertexShader =
"#version 300 es\n"
"precision highp float;\n"
"\n"
"in vec4 a_vertex;\n"
"in vec4 a_texCoord0;\n"
"\n"
"out vec2 v_texCoord;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = a_vertex;\n"
" v_texCoord = a_texCoord0.xy;\n"
"}\n";
static const char* blitFragmentShader =
"#version 300 es\n"
"precision highp float;\n"
"\n"
"uniform sampler2D u_texture;\n"
"\n"
"in vec2 v_texCoord;\n"
"out vec4 fragColor;\n"
"\n"
"void main()\n"
"{\n"
" fragColor = texture( u_texture, v_texCoord );\n"
"}\n";
m_blitShader = std::make_unique<SHADER>();
m_blitShader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_VERTEX, blitVertexShader );
m_blitShader->LoadShaderFromStrings( KIGFX::SHADER_TYPE_FRAGMENT, blitFragmentShader );
m_blitShader->Link();
checkGlError( "linking blit shader", __FILE__, __LINE__ );
m_blitTexUniform = m_blitShader->AddParameter( "u_texture" );
checkGlError( "getting blit texture uniform", __FILE__, __LINE__ );
m_blitShader->Use();
m_blitShader->SetParameter( m_blitTexUniform, 0 ); // Texture unit 0
m_blitShader->Deactivate();
}
WEBGL_COMPOSITOR::~WEBGL_COMPOSITOR()
{
if( m_initialized )
@ -138,6 +189,12 @@ void WEBGL_COMPOSITOR::Initialize()
m_initialized = true;
// Initialize blit shader for texture compositing
initBlitShader();
// Initialize fullscreen quad VBO
GetFullscreenQuad().Initialize();
m_antialiasing->Init();
}
@ -194,7 +251,7 @@ unsigned int WEBGL_COMPOSITOR::CreateBuffer( VECTOR2I aDimensions )
checkGlError( "binding framebuffer texture target", __FILE__, __LINE__ );
// Set texture parameters
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
// Note: glTexEnvf is not available in WebGL 2.0, texturing mode is handled by shaders
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA8, aDimensions.x, aDimensions.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr );
checkGlError( "creating framebuffer texture", __FILE__, __LINE__ );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
@ -272,7 +329,9 @@ void WEBGL_COMPOSITOR::SetBuffer( unsigned int aBufferHandle )
if( m_curFbo != DIRECT_RENDERING )
{
m_curBuffer = aBufferHandle - 1;
glDrawBuffer( m_buffers[m_curBuffer].attachmentPoint );
// WebGL 2.0/OpenGL ES 3.0: use glDrawBuffers instead of glDrawBuffer
GLenum drawBuffers[] = { m_buffers[m_curBuffer].attachmentPoint };
glDrawBuffers( 1, drawBuffers );
checkGlError( "setting draw buffer", __FILE__, __LINE__ );
glViewport( 0, 0, m_buffers[m_curBuffer].dimensions.x, m_buffers[m_curBuffer].dimensions.y );
@ -327,37 +386,14 @@ void WEBGL_COMPOSITOR::DrawBuffer( unsigned int aSourceHandle, unsigned int aDes
glDisable( GL_DEPTH_TEST );
glBlendFunc( GL_ONE, GL_ONE_MINUS_SRC_ALPHA );
// Enable texturing and bind the main texture
glEnable( GL_TEXTURE_2D );
// Bind the source texture
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, m_buffers[aSourceHandle - 1].textureTarget );
// Draw a full screen quad with the texture
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glLoadIdentity();
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glLoadIdentity();
glBegin( GL_TRIANGLES );
glTexCoord2f( 0.0f, 1.0f );
glVertex2f( -1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 1.0f );
glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 1.0f, 1.0f );
glVertex2f( 1.0f, 1.0f );
glTexCoord2f( 0.0f, 0.0f );
glVertex2f( -1.0f, -1.0f );
glTexCoord2f( 1.0f, 0.0f );
glVertex2f( 1.0f, -1.0f );
glEnd();
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glPopMatrix();
// Use blit shader and draw fullscreen quad
m_blitShader->Use();
GetFullscreenQuad().Draw();
m_blitShader->Deactivate();
}

View file

@ -37,8 +37,11 @@
#include <gal/compositor.h>
#include "webgl_antialiasing.h"
#include "fullscreen_quad.h"
#include "shader.h"
#include <gal/gal_display_options.h>
#include <deque>
#include <memory>
namespace KIGFX
{
@ -133,6 +136,15 @@ protected:
GAL_ANTIALIASING_MODE m_currentAntialiasingMode;
std::unique_ptr<OPENGL_PRESENTOR> m_antialiasing;
// Blit shader for compositing (replacing legacy fixed-function pipeline)
std::unique_ptr<SHADER> m_blitShader;
int m_blitTexUniform; ///< Location of texture uniform
/**
* Initialize the blit shader for texture compositing.
*/
void initBlitShader();
};
} // namespace KIGFX

View file

@ -69,6 +69,97 @@ using namespace KIGFX::BUILTIN_FONT;
static void InitTesselatorCallbacks( GLUtesselator* aTesselator );
//-----------------------------------------------------------------------------
// Matrix math helpers for WebGL (replacing legacy glMatrixMode/glOrtho/etc.)
//-----------------------------------------------------------------------------
/**
* Compute orthographic projection matrix (column-major for OpenGL).
* Equivalent to glOrtho().
*/
static void computeOrthoMatrix( float* m, float left, float right,
float bottom, float top, float nearVal, float farVal )
{
memset( m, 0, 16 * sizeof( float ) );
m[0] = 2.0f / ( right - left );
m[5] = 2.0f / ( top - bottom );
m[10] = -2.0f / ( farVal - nearVal );
m[12] = -( right + left ) / ( right - left );
m[13] = -( top + bottom ) / ( top - bottom );
m[14] = -( farVal + nearVal ) / ( farVal - nearVal );
m[15] = 1.0f;
}
/**
* Set matrix to identity (column-major).
*/
static void setIdentityMatrix( float* m )
{
memset( m, 0, 16 * sizeof( float ) );
m[0] = m[5] = m[10] = m[15] = 1.0f;
}
/**
* Multiply two 4x4 matrices: result = a * b (column-major).
* result must not alias a or b.
*/
static void multiplyMatrix4x4( float* result, const float* a, const float* b )
{
for( int col = 0; col < 4; col++ )
{
for( int row = 0; row < 4; row++ )
{
result[col * 4 + row] = 0.0f;
for( int k = 0; k < 4; k++ )
{
result[col * 4 + row] += a[k * 4 + row] * b[col * 4 + k];
}
}
}
}
/**
* Convert MATRIX3x3D (row-major 3x3) to float[16] (column-major 4x4).
* The 3x3 matrix is embedded in the upper-left of the 4x4 matrix,
* with the translation in column 3 (elements 12, 13).
*/
static void convertMatrix3x3ToFloat4x4( float* m, const MATRIX3x3D& src )
{
// Column-major 4x4 from row-major 3x3:
// [ src[0][0] src[0][1] 0 src[0][2] ]
// [ src[1][0] src[1][1] 0 src[1][2] ]
// [ src[2][0] src[2][1] 1 src[2][2] ]
// [ 0 0 0 1 ]
//
// In column-major storage:
// Column 0: m[0], m[1], m[2], m[3]
// Column 1: m[4], m[5], m[6], m[7]
// Column 2: m[8], m[9], m[10], m[11]
// Column 3: m[12], m[13], m[14], m[15]
m[0] = static_cast<float>( src.m_data[0][0] ); // col 0, row 0
m[1] = static_cast<float>( src.m_data[1][0] ); // col 0, row 1
m[2] = static_cast<float>( src.m_data[2][0] ); // col 0, row 2
m[3] = 0.0f; // col 0, row 3
m[4] = static_cast<float>( src.m_data[0][1] ); // col 1, row 0
m[5] = static_cast<float>( src.m_data[1][1] ); // col 1, row 1
m[6] = static_cast<float>( src.m_data[2][1] ); // col 1, row 2
m[7] = 0.0f; // col 1, row 3
m[8] = 0.0f; // col 2, row 0
m[9] = 0.0f; // col 2, row 1
m[10] = 1.0f; // col 2, row 2
m[11] = 0.0f; // col 2, row 3
m[12] = static_cast<float>( src.m_data[0][2] ); // col 3, row 0 (translation x)
m[13] = static_cast<float>( src.m_data[1][2] ); // col 3, row 1 (translation y)
m[14] = static_cast<float>( src.m_data[2][2] ); // col 3, row 2
m[15] = 1.0f; // col 3, row 3
}
//-----------------------------------------------------------------------------
static wxGLAttributes getGLAttribs()
{
wxGLAttributes attribs;
@ -562,13 +653,12 @@ void WEBGL_GAL::BeginDrawing()
if( !m_isInitialized )
init();
// Set up the view port
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
// Create the screen transformation (Do the RH-LH conversion here)
glOrtho( 0, (GLint) m_screenSize.x, (GLsizei) m_screenSize.y, 0,
-m_depthRange.x, -m_depthRange.y );
// Set up the projection matrix (replacing legacy glMatrixMode/glOrtho)
float projMatrix[16];
computeOrthoMatrix( projMatrix, 0.0f, static_cast<float>( m_screenSize.x ),
static_cast<float>( m_screenSize.y ), 0.0f,
static_cast<float>( -m_depthRange.x ),
static_cast<float>( -m_depthRange.y ) );
if( !m_isFramebufferInitialized )
{
@ -599,10 +689,7 @@ void WEBGL_GAL::BeginDrawing()
m_compositor->Begin();
// Disable 2D Textures
glDisable( GL_TEXTURE_2D );
glShadeModel( GL_FLAT );
// Note: GL_TEXTURE_2D not used in WebGL 2.0, texturing controlled by shaders
// Enable the depth buffer
glEnable( GL_DEPTH_TEST );
@ -612,21 +699,13 @@ void WEBGL_GAL::BeginDrawing()
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glMatrixMode( GL_MODELVIEW );
// Set up the world <-> screen transformation
// Set up the world <-> screen transformation (replacing legacy glMatrixMode/glLoadMatrixd)
ComputeWorldScreenMatrix();
GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
matrixData[0] = m_worldScreenMatrix.m_data[0][0];
matrixData[1] = m_worldScreenMatrix.m_data[1][0];
matrixData[2] = m_worldScreenMatrix.m_data[2][0];
matrixData[4] = m_worldScreenMatrix.m_data[0][1];
matrixData[5] = m_worldScreenMatrix.m_data[1][1];
matrixData[6] = m_worldScreenMatrix.m_data[2][1];
matrixData[12] = m_worldScreenMatrix.m_data[0][2];
matrixData[13] = m_worldScreenMatrix.m_data[1][2];
matrixData[14] = m_worldScreenMatrix.m_data[2][2];
glLoadMatrixd( matrixData );
float modelViewMatrix[16];
convertMatrix3x3ToFloat4x4( modelViewMatrix, m_worldScreenMatrix );
// Compute MVP matrix = projection * modelview
multiplyMatrix4x4( m_mvpMatrix, projMatrix, modelViewMatrix );
// Set defaults
SetFillColor( m_fillColor );
@ -691,6 +770,7 @@ void WEBGL_GAL::BeginDrawing()
renderingOffset.y *= screenPixelSize.y;
m_shader->SetParameter( ufm_antialiasingOffset, renderingOffset );
m_shader->SetParameter( ufm_minLinePixelWidth, GetMinLineWidth() );
m_shader->SetParameter( ufm_modelViewProjectionMatrix, m_mvpMatrix );
m_shader->Deactivate();
// Something between BeginDrawing and EndDrawing seems to depend on
@ -754,8 +834,8 @@ void WEBGL_GAL::EndDrawing()
cntComposite.Start();
// Be sure that the framebuffer is not colorized (happens on specific GPU&drivers combinations)
glColor4d( 1.0, 1.0, 1.0, 1.0 );
// Note: In legacy GL, we'd set glColor4d(1,1,1,1) here to avoid tinting.
// In modern GL with shaders, this is not needed.
// Draw the remaining contents, blit the rendering targets to the screen, swap the buffers
m_compositor->DrawBuffer( m_mainBuffer );
@ -1539,71 +1619,89 @@ void WEBGL_GAL::DrawBitmap( const BITMAP_BASE& aBitmap, double alphaBlend )
double w = (double) aBitmap.GetSizePixels().x * scale;
double h = (double) aBitmap.GetSizePixels().y * scale;
auto xform = m_currentManager->GetTransformation();
glm::vec4 v0 = xform * glm::vec4( -w / 2, -h / 2, 0.0, 0.0 );
glm::vec4 v1 = xform * glm::vec4( w / 2, h / 2, 0.0, 0.0 );
glm::vec4 trans = xform[3];
auto texture_id = m_bitmapCache->RequestBitmap( &aBitmap );
if( !glIsTexture( texture_id ) ) // ensure the bitmap texture is still valid
return;
glDepthFunc( GL_ALWAYS );
// Compute texture coordinates with mirroring
float texStartX = aBitmap.IsMirroredX() ? 1.0f : 0.0f;
float texEndX = aBitmap.IsMirroredX() ? 0.0f : 1.0f;
float texStartY = aBitmap.IsMirroredY() ? 1.0f : 0.0f;
float texEndY = aBitmap.IsMirroredY() ? 0.0f : 1.0f;
glAlphaFunc( GL_GREATER, 0.01f );
glEnable( GL_ALPHA_TEST );
// Handle rotation by rotating texture coordinates around center (0.5, 0.5)
double rotRad = aBitmap.Rotation().AsRadians();
if( std::abs( rotRad ) > 0.001 )
{
auto rotateTexCoord = [rotRad]( float& u, float& v )
{
float cu = u - 0.5f;
float cv = v - 0.5f;
float cosR = static_cast<float>( cos( rotRad ) );
float sinR = static_cast<float>( sin( rotRad ) );
u = cu * cosR - cv * sinR + 0.5f;
v = cu * sinR + cv * cosR + 0.5f;
};
rotateTexCoord( texStartX, texStartY );
rotateTexCoord( texEndX, texStartY );
rotateTexCoord( texEndX, texEndY );
rotateTexCoord( texStartX, texEndY );
}
glMatrixMode( GL_TEXTURE );
glPushMatrix();
glTranslated( 0.5, 0.5, 0.5 );
glRotated( aBitmap.Rotation().AsDegrees(), 0, 0, 1 );
glTranslated( -0.5, -0.5, -0.5 );
glMatrixMode( GL_MODELVIEW );
glPushMatrix();
glTranslated( trans.x, trans.y, trans.z );
glEnable( GL_TEXTURE_2D );
// Bind the bitmap texture
glActiveTexture( GL_TEXTURE0 );
glBindTexture( GL_TEXTURE_2D, texture_id );
float texStartX = aBitmap.IsMirroredX() ? 1.0 : 0.0;
float texEndX = aBitmap.IsMirroredX() ? 0.0 : 1.0;
float texStartY = aBitmap.IsMirroredY() ? 1.0 : 0.0;
float texEndY = aBitmap.IsMirroredY() ? 0.0 : 1.0;
// Setup for drawing
glDepthFunc( GL_ALWAYS );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glBegin( GL_QUADS );
glColor4f( 1.0, 1.0, 1.0, alpha );
glTexCoord2f( texStartX, texStartY );
glVertex3f( v0.x, v0.y, m_layerDepth );
glColor4f( 1.0, 1.0, 1.0, alpha );
glTexCoord2f( texEndX, texStartY);
glVertex3f( v1.x, v0.y, m_layerDepth );
glColor4f( 1.0, 1.0, 1.0, alpha );
glTexCoord2f( texEndX, texEndY);
glVertex3f( v1.x, v1.y, m_layerDepth );
glColor4f( 1.0, 1.0, 1.0, alpha );
glTexCoord2f( texStartX, texEndY);
glVertex3f( v0.x, v1.y, m_layerDepth );
glEnd();
// Use the vertex manager to draw a textured quad (same pattern as DrawGlyph)
// The shader uses texture coordinates from SHADER_FONT parameters
m_currentManager->Reserve( 6 );
m_currentManager->Color( 1.0f, 1.0f, 1.0f, alpha );
glBindTexture( GL_TEXTURE_2D, 0 );
// Quad vertices: centered at origin, width w, height h
/* Quad layout:
* v0 (-w/2, -h/2) v1 (w/2, -h/2)
* +---------------+
* | / |
* | / |
* | / |
* |/ |
* +---------------+
* v2 (-w/2, h/2) v3 (w/2, h/2)
*/
// Triangle 1: v0, v1, v2
m_currentManager->Shader( SHADER_FONT, texStartX, texStartY );
m_currentManager->Vertex( -w / 2, -h / 2, m_layerDepth ); // v0
m_currentManager->Shader( SHADER_FONT, texEndX, texStartY );
m_currentManager->Vertex( w / 2, -h / 2, m_layerDepth ); // v1
m_currentManager->Shader( SHADER_FONT, texStartX, texEndY );
m_currentManager->Vertex( -w / 2, h / 2, m_layerDepth ); // v2
// Triangle 2: v1, v3, v2
m_currentManager->Shader( SHADER_FONT, texEndX, texStartY );
m_currentManager->Vertex( w / 2, -h / 2, m_layerDepth ); // v1
m_currentManager->Shader( SHADER_FONT, texEndX, texEndY );
m_currentManager->Vertex( w / 2, h / 2, m_layerDepth ); // v3
m_currentManager->Shader( SHADER_FONT, texStartX, texEndY );
m_currentManager->Vertex( -w / 2, h / 2, m_layerDepth ); // v2
// Note: texture unbinding and state restoration happens in EndDrawing
glDepthFunc( GL_LESS );
#ifdef DISABLE_BITMAP_CACHE
glDeleteTextures( 1, &texture_id );
#endif
glPopMatrix();
glMatrixMode( GL_TEXTURE );
glPopMatrix();
glMatrixMode( GL_MODELVIEW );
glDisable( GL_ALPHA_TEST );
glDepthFunc( GL_LESS );
}
@ -1831,19 +1929,17 @@ void WEBGL_GAL::DrawGrid()
++gridEndY;
glDisable( GL_DEPTH_TEST );
glDisable( GL_TEXTURE_2D );
// Note: GL_TEXTURE_2D not used in WebGL 2.0
if( m_gridStyle == GRID_STYLE::DOTS )
{
glEnable( GL_STENCIL_TEST );
glStencilFunc( GL_ALWAYS, 1, 1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_INCR );
glColor4d( 0.0, 0.0, 0.0, 0.0 );
SetStrokeColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) );
}
else
{
glColor4d( m_gridColor.r, m_gridColor.g, m_gridColor.b, m_gridColor.a );
SetStrokeColor( m_gridColor );
}
@ -1893,7 +1989,6 @@ void WEBGL_GAL::DrawGrid()
if( m_gridStyle == GRID_STYLE::DOTS )
{
glStencilFunc( GL_NOTEQUAL, 0, 1 );
glColor4d( m_gridColor.r, m_gridColor.g, m_gridColor.b, m_gridColor.a );
SetStrokeColor( m_gridColor );
}
@ -1919,7 +2014,7 @@ void WEBGL_GAL::DrawGrid()
}
glEnable( GL_DEPTH_TEST );
glEnable( GL_TEXTURE_2D );
// Note: GL_TEXTURE_2D not used in WebGL 2.0
}
@ -1966,19 +2061,23 @@ void WEBGL_GAL::ClearScreen()
void WEBGL_GAL::Transform( const MATRIX3x3D& aTransformation )
{
GLdouble matrixData[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 };
// Convert 3x3 matrix to 4x4 matrix (column-major order for GLM)
// The 3x3 matrix represents a 2D affine transformation
glm::mat4 matrix( 1.0f );
matrixData[0] = aTransformation.m_data[0][0];
matrixData[1] = aTransformation.m_data[1][0];
matrixData[2] = aTransformation.m_data[2][0];
matrixData[4] = aTransformation.m_data[0][1];
matrixData[5] = aTransformation.m_data[1][1];
matrixData[6] = aTransformation.m_data[2][1];
matrixData[12] = aTransformation.m_data[0][2];
matrixData[13] = aTransformation.m_data[1][2];
matrixData[14] = aTransformation.m_data[2][2];
matrix[0][0] = static_cast<float>( aTransformation.m_data[0][0] );
matrix[0][1] = static_cast<float>( aTransformation.m_data[1][0] );
matrix[0][2] = static_cast<float>( aTransformation.m_data[2][0] );
glMultMatrixd( matrixData );
matrix[1][0] = static_cast<float>( aTransformation.m_data[0][1] );
matrix[1][1] = static_cast<float>( aTransformation.m_data[1][1] );
matrix[1][2] = static_cast<float>( aTransformation.m_data[2][1] );
matrix[3][0] = static_cast<float>( aTransformation.m_data[0][2] );
matrix[3][1] = static_cast<float>( aTransformation.m_data[1][2] );
matrix[3][2] = static_cast<float>( aTransformation.m_data[2][2] );
m_currentManager->MultiplyMatrix( matrix );
}
@ -2690,22 +2789,14 @@ void WEBGL_GAL::blitCursor()
const COLOR4D color = getCursorColor();
GLboolean depthTestEnabled = glIsEnabled( GL_DEPTH_TEST );
glDisable( GL_DEPTH_TEST );
// Use non-cached manager to draw cursor lines (same pattern as DrawGrid)
RENDER_TARGET savedTarget = m_currentTarget;
SetTarget( TARGET_NONCACHED );
m_nonCachedManager->EnableDepthTest( false );
glActiveTexture( GL_TEXTURE0 );
glDisable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glLineWidth( 1.0 );
glColor4d( color.r, color.g, color.b, color.a );
glMatrixMode( GL_PROJECTION );
glPushMatrix();
glTranslated( 0, 0, -0.5 );
glBegin( GL_LINES );
// Set cursor appearance
SetStrokeColor( color );
SetLineWidth( 1.0f * getWorldPixelSize() / GetScaleFactor() );
if( m_crossHairMode == CROSS_HAIR_MODE::FULLSCREEN_DIAGONAL )
{
@ -2714,8 +2805,6 @@ void WEBGL_GAL::blitCursor()
VECTOR2D screenBottomRight = m_screenWorldMatrix * VECTOR2D( m_screenSize );
// For 45-degree lines passing through cursor position
// Line equation: y = x + (cy - cx) for positive slope
// Line equation: y = -x + (cy + cx) for negative slope
double cx = m_cursorPosition.x;
double cy = m_cursorPosition.y;
@ -2725,8 +2814,7 @@ void WEBGL_GAL::blitCursor()
VECTOR2D pos_end( screenBottomRight.x, screenBottomRight.x + offset1 );
// Draw positive slope diagonal
glVertex2d( pos_start.x, pos_start.y );
glVertex2d( pos_end.x, pos_end.y );
DrawLine( pos_start, pos_end );
// Calculate intersections for negative slope diagonal (y = -x + offset)
double offset2 = cy + cx;
@ -2734,24 +2822,22 @@ void WEBGL_GAL::blitCursor()
VECTOR2D neg_end( screenBottomRight.x, offset2 - screenBottomRight.x );
// Draw negative slope diagonal
glVertex2d( neg_start.x, neg_start.y );
glVertex2d( neg_end.x, neg_end.y );
DrawLine( neg_start, neg_end );
}
else
{
glVertex2d( cursorCenter.x, cursorBegin.y );
glVertex2d( cursorCenter.x, cursorEnd.y );
glVertex2d( cursorBegin.x, cursorCenter.y );
glVertex2d( cursorEnd.x, cursorCenter.y );
// Standard crosshair
DrawLine( VECTOR2D( cursorCenter.x, cursorBegin.y ),
VECTOR2D( cursorCenter.x, cursorEnd.y ) );
DrawLine( VECTOR2D( cursorBegin.x, cursorCenter.y ),
VECTOR2D( cursorEnd.x, cursorCenter.y ) );
}
glEnd();
// Flush cursor geometry
m_nonCachedManager->EndDrawing();
glPopMatrix();
if( depthTestEnabled )
glEnable( GL_DEPTH_TEST );
// Restore target
SetTarget( savedTarget );
}
@ -2877,6 +2963,10 @@ void WEBGL_GAL::setupShaderParameters()
ufm_pixelSizeMultiplier = m_shader->AddParameter( "u_pixelSizeMultiplier" );
ufm_antialiasingOffset = m_shader->AddParameter( "u_antialiasingOffset" );
ufm_minLinePixelWidth = m_shader->AddParameter( "u_minLinePixelWidth" );
ufm_modelViewProjectionMatrix = m_shader->AddParameter( "u_modelViewProjectionMatrix" );
// Initialize MVP matrix to identity
setIdentityMatrix( m_mvpMatrix );
}

View file

@ -386,6 +386,10 @@ private:
GLint ufm_minLinePixelWidth;
GLint ufm_fontTexture;
GLint ufm_fontTextureWidth;
GLint ufm_modelViewProjectionMatrix; ///< MVP matrix uniform location
/// Current model-view-projection matrix (column-major for OpenGL)
float m_mvpMatrix[16];
/// wx cursor showing the current native cursor.
WX_CURSOR_TYPE m_currentwxCursor;