@@ -77,51 +77,6 @@ abstract class _GlRenderer {
7777/// This class gets instantiated on demand by Vertices constructor. For apps
7878/// that don't use Vertices WebGlRenderer will be removed from release binary.
7979class _WebGlRenderer implements _GlRenderer {
80- // Vertex shader transforms pixel space [Vertices.positions] to
81- // final clipSpace -1..1 coordinates with inverted Y Axis.
82- static const _vertexShaderTriangle = '''
83- #version 300 es
84- layout (location=0) in vec4 position;
85- layout (location=1) in vec4 color;
86- uniform mat4 u_ctransform;
87- uniform vec4 u_scale;
88- uniform vec4 u_shift;
89- out vec4 vColor;
90- void main() {
91- gl_Position = ((u_ctransform * position) * u_scale) + u_shift;
92- vColor = color.zyxw;
93- }''' ;
94- // This fragment shader enables Int32List of colors to be passed directly
95- // to gl context buffer for rendering by decoding RGBA8888.
96- static const _fragmentShaderTriangle = '''
97- #version 300 es
98- precision highp float;
99- in vec4 vColor;
100- out vec4 fragColor;
101- void main() {
102- fragColor = vColor;
103- }''' ;
104-
105- // WebGL 1 version of shaders above for compatibility with Safari.
106- static const _vertexShaderTriangleEs1 = '''
107- attribute vec4 position;
108- attribute vec4 color;
109- uniform mat4 u_ctransform;
110- uniform vec4 u_scale;
111- uniform vec4 u_shift;
112- varying vec4 vColor;
113- void main() {
114- gl_Position = ((u_ctransform * position) * u_scale) + u_shift;
115- vColor = color.zyxw;
116- }''' ;
117- // WebGL 1 version of shaders above for compatibility with Safari.
118- static const _fragmentShaderTriangleEs1 = '''
119- precision highp float;
120- varying vec4 vColor;
121- void main() {
122- gl_FragColor = vColor;
123- }''' ;
124-
12580 @override
12681 void drawVertices (
12782 html.CanvasRenderingContext2D ? context,
@@ -161,16 +116,16 @@ class _WebGlRenderer implements _GlRenderer {
161116 if (widthInPixels == 0 || heightInPixels == 0 ) {
162117 return ;
163118 }
119+ final String vertexShader = _writeVerticesVertexShader ();
120+ final String fragmentShader = _writeVerticesFragmentShader ();
164121 _GlContext gl =
165122 _OffscreenCanvas .createGlContext (widthInPixels, heightInPixels)! ;
166- _GlProgram glProgram = webGLVersion == 1
167- ? gl.useAndCacheProgram (
168- _vertexShaderTriangleEs1, _fragmentShaderTriangleEs1)!
169- : gl.useAndCacheProgram (
170- _vertexShaderTriangle, _fragmentShaderTriangle)! ;
171-
172- Object ? transformUniform = gl.getUniformLocation (glProgram.program, 'u_ctransform' );
173- Matrix4 transformAtOffset = transform.clone ()..translate (- offsetX, - offsetY);
123+ _GlProgram glProgram = gl.useAndCacheProgram (vertexShader, fragmentShader)! ;
124+
125+ Object ? transformUniform = gl.getUniformLocation (glProgram.program,
126+ 'u_ctransform' );
127+ Matrix4 transformAtOffset = transform.clone ()
128+ ..translate (- offsetX, - offsetY);
174129 gl.setUniformMatrix4fv (transformUniform, false , transformAtOffset.storage);
175130
176131 // Set uniform to scale 0..width/height pixels coordinates to -1..1
@@ -186,18 +141,21 @@ class _WebGlRenderer implements _GlRenderer {
186141 assert (positionsBuffer != null ); // ignore: unnecessary_null_comparison
187142 gl.bindArrayBuffer (positionsBuffer);
188143 gl.bufferData (positions, gl.kStaticDraw);
144+ Object ? positionLoc = gl.getAttribLocation (glProgram.program, 'position' );
189145 js_util.callMethod (
190- gl.glContext! , 'vertexAttribPointer' , < dynamic > [0 , 2 , gl.kFloat, false , 0 , 0 ]);
146+ gl.glContext! , 'vertexAttribPointer' , < dynamic > [
147+ positionLoc, 2 , gl.kFloat, false , 0 , 0 ,
148+ ]);
191149 gl.enableVertexAttribArray (0 );
192150
193151 // Setup color buffer.
194152 Object ? colorsBuffer = gl.createBuffer ();
195153 gl.bindArrayBuffer (colorsBuffer);
196154 // Buffer kBGRA_8888.
197155 gl.bufferData (vertices._colors, gl.kStaticDraw);
198-
156+ Object ? colorLoc = gl. getAttribLocation (glProgram.program, 'color' );
199157 js_util.callMethod (gl.glContext! , 'vertexAttribPointer' ,
200- < dynamic > [1 , 4 , gl.kUnsignedByte, true , 0 , 0 ]);
158+ < dynamic > [colorLoc , 4 , gl.kUnsignedByte, true , 0 , 0 ]);
201159 gl.enableVertexAttribArray (1 );
202160 gl.clear ();
203161 final int vertexCount = positions.length ~ / 2 ;
@@ -209,6 +167,51 @@ class _WebGlRenderer implements _GlRenderer {
209167 context.restore ();
210168 }
211169
170+ /// Vertex shader transforms pixel space [Vertices.positions] to
171+ /// final clipSpace -1..1 coordinates with inverted Y Axis.
172+ /// #version 300 es
173+ /// layout (location=0) in vec4 position;
174+ /// layout (location=1) in vec4 color;
175+ /// uniform mat4 u_ctransform;
176+ /// uniform vec4 u_scale;
177+ /// uniform vec4 u_shift;
178+ /// out vec4 vColor;
179+ /// void main() {
180+ /// gl_Position = ((u_ctransform * position) * u_scale) + u_shift;
181+ /// v_color = color.zyxw;
182+ /// }
183+ String _writeVerticesVertexShader () {
184+ ShaderBuilder builder = ShaderBuilder (webGLVersion);
185+ builder.addIn (ShaderType .kVec4, name: 'position' );
186+ builder.addIn (ShaderType .kVec4, name: 'color' );
187+ builder.addUniform (ShaderType .kMat4, name: 'u_ctransform' );
188+ builder.addUniform (ShaderType .kVec4, name: 'u_scale' );
189+ builder.addUniform (ShaderType .kVec4, name: 'u_shift' );
190+ builder.addOut (ShaderType .kVec4, name: 'v_color' );
191+ ShaderMethod method = builder.addMethod ('main' );
192+ method.addStatement ('gl_Position = ((u_ctransform * position) * u_scale) + u_shift;' );
193+ method.addStatement ('v_color = color.zyxw;' );
194+ return builder.build ();
195+ }
196+
197+ /// This fragment shader enables Int32List of colors to be passed directly
198+ /// to gl context buffer for rendering by decoding RGBA8888.
199+ /// #version 300 es
200+ /// precision mediump float;
201+ /// in vec4 vColor;
202+ /// out vec4 fragColor;
203+ /// void main() {
204+ /// fragColor = vColor;
205+ /// }
206+ String _writeVerticesFragmentShader () {
207+ ShaderBuilder builder = ShaderBuilder .fragment (webGLVersion);
208+ builder.floatPrecision = ShaderPrecision .kMedium;
209+ builder.addIn (ShaderType .kVec4, name: 'v_color' );
210+ ShaderMethod method = builder.addMethod ('main' );
211+ method.addStatement ('${builder .fragmentColor .name } = v_color;' );
212+ return builder.build ();
213+ }
214+
212215 @override
213216 void drawHairline (html.CanvasRenderingContext2D ? _ctx, Float32List positions) {
214217 assert (positions != null ); // ignore: unnecessary_null_comparison
@@ -547,7 +550,15 @@ class _GlContext {
547550 /// Returns reference to uniform in program.
548551 Object ? getUniformLocation (Object ? program, String uniformName) {
549552 return js_util
550- .callMethod (glContext! , 'getUniformLocation' , < dynamic > [program, uniformName]);
553+ .callMethod (glContext! , 'getUniformLocation' ,
554+ < dynamic > [program, uniformName]);
555+ }
556+
557+ /// Returns reference to attribute in program.
558+ Object ? getAttribLocation (Object ? program, String uniformName) {
559+ return js_util
560+ .callMethod (glContext! , 'getAttribLocation' ,
561+ < dynamic > [program, uniformName]);
551562 }
552563
553564 /// Sets vec2 uniform values.
0 commit comments