import { gl_Colors_template } from "./render-utils"; class ShaderMaker { /** * * @param {'VERTEX_SHADER' | 'FRAGMENT_SHADER'} type * @param {string} source */ constructor(type, source) { this.type = type; this.source = source; } /** * @param {WebGL2RenderingContext} gl * @return {WebGLShader} */ make(gl) { const shader = gl.createShader(gl[this.type]); gl.shaderSource(shader, this.source); gl.compileShader(shader); const ok = gl.getShaderParameter(shader, gl.COMPILE_STATUS); if (!ok) { console.log('创建类型为 ' + this.type + ' 的着色器失败!'); } return shader; } } const colorsLength = gl_Colors_template.length << 1; const vertexShader = new ShaderMaker('VERTEX_SHADER', `#version 300 es precision mediump float; in ivec2 pos; in ivec3 control; out vec4 v_color; uniform float posYFactor; uniform vec2 scale; uniform vec2 offset; uniform vec3 colorOffset; uniform vec4 colors[${colorsLength}]; uniform vec2 shifts[7]; // 基础八位图偏移量,为了性能,pos 只传入整数,需要的坐标负数由该值提供 uniform vec2 widthShifts[9]; // 用于构造线宽的偏移 void main() { vec2 shift = shifts[control.x]; vec2 ws = widthShifts[control.y]; vec4 color = colors[control.z]; v_color = vec4( color.x + colorOffset.x, color.y + colorOffset.y, color.z + colorOffset.z, color.w ); // 为了性能,传递进来进来的都是整数,pos.y 需要除以 posYFactor float posX = float(pos.x); float posY = float(pos.y) / posYFactor; // 偏移包括三部分:用户滚动时发生的全局位移、为了设置线宽发生的位移、与 scale 无关的额外位移 float offsetX = offset.x + ws.x + shift.x; float offsetY = offset.y + ws.y + shift.y; gl_Position = vec4( posX * scale.x + offsetX, posY * scale.y + offsetY, 1, 1 ); }`); const fragmentShader = new ShaderMaker('FRAGMENT_SHADER', `#version 300 es precision mediump float; in vec4 v_color; out vec4 outColor; void main() { outColor = v_color; }`); export { vertexShader, fragmentShader }