1 /*-------------------------------------------------------------------------
2 * drawElements Quality Program OpenGL ES Utilities
3 * ------------------------------------------------
5 * Copyright 2014 The Android Open Source Project
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
22 goog
.provide('modules.shared.glsShaderRenderCase');
23 goog
.require('framework.common.tcuImageCompare');
24 goog
.require('framework.common.tcuMatrix');
25 goog
.require('framework.common.tcuRGBA');
26 goog
.require('framework.common.tcuSurface');
27 goog
.require('framework.common.tcuTestCase');
28 goog
.require('framework.common.tcuTexture');
29 goog
.require('framework.delibs.debase.deMath');
30 goog
.require('framework.delibs.debase.deString');
31 goog
.require('framework.delibs.debase.deRandom');
32 goog
.require('framework.opengl.gluDrawUtil');
33 goog
.require('framework.opengl.gluTexture');
34 goog
.require('framework.opengl.gluTextureUtil');
35 goog
.require('framework.opengl.gluShaderProgram');
37 goog
.scope(function() {
38 var glsShaderRenderCase
= modules
.shared
.glsShaderRenderCase
;
40 var deMath
= framework
.delibs
.debase
.deMath
;
41 var deString
= framework
.delibs
.debase
.deString
;
42 var deRandom
= framework
.delibs
.debase
.deRandom
;
43 var gluTextureUtil
= framework
.opengl
.gluTextureUtil
;
44 var gluTexture
= framework
.opengl
.gluTexture
;
45 var gluDrawUtil
= framework
.opengl
.gluDrawUtil
;
46 var tcuImageCompare
= framework
.common
.tcuImageCompare
;
47 var tcuTexture
= framework
.common
.tcuTexture
;
48 var tcuMatrix
= framework
.common
.tcuMatrix
;
49 var tcuRGBA
= framework
.common
.tcuRGBA
;
50 var tcuTestCase
= framework
.common
.tcuTestCase
;
51 var tcuSurface
= framework
.common
.tcuSurface
;
52 var gluShaderProgram
= framework
.opengl
.gluShaderProgram
;
54 /** @typedef {function(glsShaderRenderCase.ShaderEvalContext)} */ glsShaderRenderCase
.ShaderEvalFunc
;
56 /** @const {number} */ glsShaderRenderCase
.GRID_SIZE
= 64;
57 /** @const {number} */ glsShaderRenderCase
.MAX_RENDER_WIDTH
= 128;
58 /** @const {number} */ glsShaderRenderCase
.MAX_RENDER_HEIGHT
= 112;
59 /** @const {Array<number>} */ glsShaderRenderCase
.DEFAULT_CLEAR_COLOR
= [0.125, 0.25, 0.5, 1.0];
60 /** @const {number} */ glsShaderRenderCase
.MAX_USER_ATTRIBS
= 4;
61 /** @const {number} */ glsShaderRenderCase
.MAX_TEXTURES
= 4;
64 * @param {Array<number>} a
65 * @return {tcuRGBA.RGBA}
67 glsShaderRenderCase
.toRGBA = function(a
) {
68 return tcuRGBA
.newRGBAComponents(
69 deMath
.clamp(Math
.round(a
[0] * 255.0), 0, 255),
70 deMath
.clamp(Math
.round(a
[1] * 255.0), 0, 255),
71 deMath
.clamp(Math
.round(a
[2] * 255.0), 0, 255),
72 deMath
.clamp(Math
.round(a
[3] * 255.0), 0, 255));
77 * @param {?(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} tex
78 * @return {gluTexture.Type}
80 glsShaderRenderCase
.getTextureType = function(tex
) {
81 if (tex
=== null || tex
.getType() <= 0)
82 return gluTexture
.Type
.TYPE_NONE
;
89 * @param {number=} indent
91 glsShaderRenderCase
.LineStream = function(indent
) {
92 indent
= indent
=== undefined ? 0 : indent
;
93 /** @type {number} */ this.m_indent
= indent
;
94 /** @type {string} */ this.m_stream
;
95 /** @type {string} */ this.m_string
;
101 glsShaderRenderCase
.LineStream
.prototype.str = function() {
102 this.m_string
= this.m_stream
;
103 return this.m_string
;
108 * @param {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)=} tex
109 * @param {tcuTexture.Sampler=} sampler
111 glsShaderRenderCase
.TextureBinding = function(tex
, sampler
) {
112 tex
= tex
=== undefined ? null : tex
;
113 sampler
= sampler
=== undefined ? null : sampler
;
114 /** @type {gluTexture.Type} */ this.m_type
= glsShaderRenderCase
.getTextureType(tex
);
115 /** @type {tcuTexture.Sampler} */ this.m_sampler
= sampler
;
116 /** @type {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} */
117 this.m_binding
= tex
;
121 * @param {tcuTexture.Sampler} sampler
123 glsShaderRenderCase
.TextureBinding
.prototype.setSampler = function(sampler
) {
124 this.m_sampler
= sampler
;
128 * @param {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} tex
130 glsShaderRenderCase
.TextureBinding
.prototype.setTexture = function(tex
) {
131 this.m_type
= glsShaderRenderCase
.getTextureType(tex
);
132 this.m_binding
= tex
;
135 /** @return {gluTexture.Type} */
136 glsShaderRenderCase
.TextureBinding
.prototype.getType = function() {
140 /** @return {tcuTexture.Sampler} */
141 glsShaderRenderCase
.TextureBinding
.prototype.getSampler = function() {
142 return this.m_sampler
;
145 /** @return {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} */
146 glsShaderRenderCase
.TextureBinding
.prototype.getBinding = function() {
147 return this.m_binding
;
152 * @param {number} gridSize
153 * @param {number} width
154 * @param {number} height
155 * @param {Array<number>} constCoords
156 * @param {Array<tcuMatrix.Matrix>} userAttribTransforms
157 * @param {Array<glsShaderRenderCase.TextureBinding>} textures
159 glsShaderRenderCase
.QuadGrid = function(gridSize
, width
, height
, constCoords
, userAttribTransforms
, textures
) {
160 /** @type {number} */ this.m_gridSize
= gridSize
;
161 /** @type {number} */ this.m_numVertices
= (gridSize
+ 1) * (gridSize
+ 1);
162 /** @type {number} */ this.m_numTriangles
= (gridSize
* gridSize
*2);
163 /** @type {Array<number>} */ this.m_constCoords
= constCoords
;
164 /** @type {Array<tcuMatrix.Matrix>} */ this.m_userAttribTransforms
= userAttribTransforms
;
165 /** @type {Array<glsShaderRenderCase.TextureBinding>} */ this.m_textures
= textures
;
166 /** @type {Array<Array<number>>} */ this.m_screenPos
= [];
167 /** @type {Array<Array<number>>} */ this.m_positions
= [];
168 /** @type {Array<Array<number>>} */ this.m_coords
= []; //!< Near-unit coordinates, roughly [-2.0 .. 2.0].
169 /** @type {Array<Array<number>>} */ this.m_unitCoords
= []; //!< Positive-only coordinates [0.0 .. 1.5].
170 /** @type {Array<number>} */ this.m_attribOne
= [];
171 /** @type {Array<Array<number>>} */ this.m_userAttribs
= [];
172 for (var attribNdx
= 0; attribNdx
< this.getNumUserAttribs(); attribNdx
++)
173 this.m_userAttribs
[attribNdx
] = [];
174 /** @type {Array<number>} */ this.m_indices
= [];
176 /** @type Array<number>} */ var viewportScale
= [width
, height
, 0, 0];
177 for (var y
= 0; y
< gridSize
+ 1; y
++)
178 for (var x
= 0; x
< gridSize
+ 1; x
++) {
179 /** @type {number} */ var sx
= x
/ gridSize
;
180 /** @type {number} */ var sy
= y
/ gridSize
;
181 /** @type {number} */ var fx
= 2.0 * sx
- 1.0;
182 /** @type {number} */ var fy
= 2.0 * sy
- 1.0;
183 /** @type {number} */ var vtxNdx
= ((y
* (gridSize
+ 1)) + x
);
185 this.m_positions
[vtxNdx
] = [fx
, fy
, 0.0, 1.0];
186 this.m_attribOne
[vtxNdx
] = 1.0;
187 this.m_screenPos
[vtxNdx
] = deMath
.multiply([sx
, sy
, 0.0, 1.0], viewportScale
);
188 this.m_coords
[vtxNdx
] = this.getCoords(sx
, sy
);
189 this.m_unitCoords
[vtxNdx
] = this.getUnitCoords(sx
, sy
);
191 for (var attribNdx
= 0; attribNdx
< this.getNumUserAttribs(); attribNdx
++)
192 this.m_userAttribs
[attribNdx
][vtxNdx
] = this.getUserAttrib(attribNdx
, sx
, sy
);
196 for (var y
= 0; y
< gridSize
; y
++)
197 for (var x
= 0; x
< gridSize
; x
++) {
198 /** @type {number} */ var stride
= gridSize
+ 1;
199 /** @type {number} */ var v00
= (y
* stride
) + x
;
200 /** @type {number} */ var v01
= (y
* stride
) + x
+ 1;
201 /** @type {number} */ var v10
= ((y
+ 1) * stride
) + x
;
202 /** @type {number} */ var v11
= ((y
+ 1) * stride
) + x
+ 1;
204 /** @type {number} */ var baseNdx
= ((y
* gridSize
) + x
) * 6;
205 this.m_indices
[baseNdx
+ 0] = v10
;
206 this.m_indices
[baseNdx
+ 1] = v00
;
207 this.m_indices
[baseNdx
+ 2] = v01
;
209 this.m_indices
[baseNdx
+ 3] = v10
;
210 this.m_indices
[baseNdx
+ 4] = v01
;
211 this.m_indices
[baseNdx
+ 5] = v11
;
215 /** @return {number} */
216 glsShaderRenderCase
.QuadGrid
.prototype.getGridSize = function() {
217 return this.m_gridSize
;
220 /** @return {number} */
221 glsShaderRenderCase
.QuadGrid
.prototype.getNumVertices = function() {
222 return this.m_numVertices
;
225 /** @return {number} */
226 glsShaderRenderCase
.QuadGrid
.prototype.getNumTriangles = function() {
227 return this.m_numTriangles
;
230 /** @return {Array<number>} */
231 glsShaderRenderCase
.QuadGrid
.prototype.getConstCoords = function() {
232 return this.m_constCoords
;
235 /** @return {Array<tcuMatrix.Matrix>} */
236 glsShaderRenderCase
.QuadGrid
.prototype.getUserAttribTransforms = function() {
237 return this.m_userAttribTransforms
;
240 /** @return {Array<glsShaderRenderCase.TextureBinding>} */
241 glsShaderRenderCase
.QuadGrid
.prototype.getTextures = function() {
242 return this.m_textures
;
245 /** @return {Array<Array<number>>} */
246 glsShaderRenderCase
.QuadGrid
.prototype.getPositions = function() {
247 return this.m_positions
;
250 /** @return {Array<number>} */
251 glsShaderRenderCase
.QuadGrid
.prototype.getAttribOne = function() {
252 return this.m_attribOne
;
255 /** @return {Array<Array<number>>} */
256 glsShaderRenderCase
.QuadGrid
.prototype.getCoordsArray = function() {
257 return this.m_coords
;
260 /** @return {Array<Array<number>>} */
261 glsShaderRenderCase
.QuadGrid
.prototype.getUnitCoordsArray = function() {
262 return this.m_unitCoords
;
266 * @param {number} attribNdx
267 * @return {Array<number>}
269 glsShaderRenderCase
.QuadGrid
.prototype.getUserAttribByIndex = function(attribNdx
) {
270 return this.m_userAttribs
[attribNdx
];
273 /** @return {Array<number>} */
274 glsShaderRenderCase
.QuadGrid
.prototype.getIndices = function() {
275 return this.m_indices
;
281 * @return {Array<number>}
283 glsShaderRenderCase
.QuadGrid
.prototype.getCoords = function(sx
, sy
) {
284 /** @type {number} */ var fx
= 2.0 * sx
- 1.0;
285 /** @type {number} */ var fy
= 2.0 * sy
- 1.0;
286 return [fx
, fy
, -fx
+ 0.33 * fy
, -0.275 * fx
- fy
];
292 * @return {Array<number>}
294 glsShaderRenderCase
.QuadGrid
.prototype.getUnitCoords = function(sx
, sy
) {
295 return [sx
, sy
, 0.33 * sx
+ 0.5 * sy
, 0.5 * sx
+ 0.25 * sy
];
301 glsShaderRenderCase
.QuadGrid
.prototype.getNumUserAttribs = function() {
302 return this.m_userAttribTransforms
.length
;
306 * @param {number} attribNdx
309 * @return {Array<number>}
311 glsShaderRenderCase
.QuadGrid
.prototype.getUserAttrib = function(attribNdx
, sx
, sy
) {
312 // homogeneous normalized screen-space coordinates
313 return tcuMatrix
.multiplyMatVec(this.m_userAttribTransforms
[attribNdx
], [sx
, sy
, 0.0, 1.0]);
320 glsShaderRenderCase
.ShaderSampler = function() {
321 /** @type {tcuTexture.Sampler} */ this.sampler
;
322 /** @type {tcuTexture.Texture2D} */ this.tex2D
= null;
323 /** @type {tcuTexture.TextureCube} */ this.texCube
= null;
324 /** @type {tcuTexture.Texture2DArray} */ this.tex2DArray
= null;
325 /** @type {tcuTexture.Texture3D} */ this.tex3D
= null;
330 * @param {glsShaderRenderCase.QuadGrid} quadGrid_
332 glsShaderRenderCase
.ShaderEvalContext = function(quadGrid_
) {
333 /** @type {Array<number>} */ this.coords
= [0, 0, 0, 0]
334 /** @type {Array<number>} */ this.unitCoords
= [0, 0, 0, 0]
335 /** @type {Array<number>} */ this.constCoords
= quadGrid_
.getConstCoords();
336 /** @type {Array<Array<number>>} */ this.in_
= [];
337 /** @type {Array<glsShaderRenderCase.ShaderSampler>} */ this.textures
= [];
338 /** @type {Array<number>} */ this.color
= [0, 0, 0, 0.0];
339 /** @type {boolean} */ this.isDiscarded
= false;
340 /** @type {glsShaderRenderCase.QuadGrid} */ this.quadGrid
= quadGrid_
;
342 /** @type {Array<glsShaderRenderCase.TextureBinding>} */ var bindings
= this.quadGrid
.getTextures();
343 assertMsgOptions(bindings
.length
<= glsShaderRenderCase
.MAX_TEXTURES
, 'Too many bindings.', false, true);
345 // Fill in texture array.
346 for (var ndx
= 0; ndx
< bindings
.length
; ndx
++) {
347 /** @type {glsShaderRenderCase.TextureBinding} */ var binding
= bindings
[ndx
];
349 this.textures
[ndx
] = new glsShaderRenderCase
.ShaderSampler();
351 if (binding
.getType() == gluTexture
.Type
.TYPE_NONE
)
354 this.textures
[ndx
].sampler
= binding
.getSampler();
356 switch (binding
.getType()) {
357 case gluTexture
.Type
.TYPE_2D
:
358 this.textures
[ndx
].tex2D
= binding
.getBinding().getRefTexture();
360 case gluTexture
.Type
.TYPE_CUBE_MAP
:
361 this.textures
[ndx
].texCube
= binding
.getBinding().getRefTexture();
363 case gluTexture
.Type
.TYPE_2D_ARRAY
:
364 this.textures
[ndx
].tex2DArray
= binding
.getBinding().getRefTexture();
366 case gluTexture
.Type
.TYPE_3D
:
367 this.textures
[ndx
].tex3D
= binding
.getBinding().getRefTexture();
370 throw new Error("Binding type not supported");
379 glsShaderRenderCase
.ShaderEvalContext
.prototype.reset = function(sx
, sy
) {
381 this.color
= [0.0, 0.0, 0.0, 1.0];
382 this.isDiscarded
= false;
385 this.coords
= this.quadGrid
.getCoords(sx
, sy
);
386 this.unitCoords
= this.quadGrid
.getUnitCoords(sx
, sy
);
388 // Compute user attributes.
389 /** @type {number} */ var numAttribs
= this.quadGrid
.getNumUserAttribs();
390 assertMsgOptions(numAttribs
<= glsShaderRenderCase
.MAX_USER_ATTRIBS
, 'numAttribs out of range', false, true);
391 for (var attribNdx
= 0; attribNdx
< numAttribs
; attribNdx
++)
392 this.in_
[attribNdx
] = this.quadGrid
.getUserAttrib(attribNdx
, sx
, sy
);
395 glsShaderRenderCase
.ShaderEvalContext
.prototype.discard = function() {
396 this.isDiscarded
= true;
400 * @param {number} unitNdx
401 * @param {Array<number>} coords
403 glsShaderRenderCase
.ShaderEvalContext
.prototype.texture2D = function(unitNdx
, coords
) {
404 if (this.textures
.length
> 0 && this.textures
[unitNdx
].tex2D
)
405 return this.textures
[unitNdx
].tex2D
.getView().sample(this.textures
[unitNdx
].sampler
, coords
, 0.0);
407 return [0.0, 0.0, 0.0, 1.0];
410 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
411 glsShaderRenderCase
.evalCoordsPassthroughX = function(c
) {
412 c
.color
[0] = c
.coords
[0];
415 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
416 glsShaderRenderCase
.evalCoordsPassthroughXY = function(c
) {
417 var swizzle01
= deMath
.swizzle(c
.coords
, [0, 1]);
418 c
.color
[0] = swizzle01
[0];
419 c
.color
[1] = swizzle01
[1];
422 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
423 glsShaderRenderCase
.evalCoordsPassthroughXYZ = function(c
) {
424 var swizzle012
= deMath
.swizzle(c
.coords
, [0, 1, 2]);
425 c
.color
[0] = swizzle012
[0];
426 c
.color
[1] = swizzle012
[1];
427 c
.color
[2] = swizzle012
[2];
430 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
431 glsShaderRenderCase
.evalCoordsPassthrough = function(c
) {
435 /** @param {glsShaderRenderCase.ShaderEvalContext} c */
436 glsShaderRenderCase
.evalCoordsSwizzleWZYX = function(c
) {
437 c
.color
= deMath
.swizzle(c
.coords
, [3, 2, 1, 0]);
442 * @param {?glsShaderRenderCase.ShaderEvalFunc=} evalFunc
444 glsShaderRenderCase
.ShaderEvaluator = function(evalFunc
) {
445 /** @type {?glsShaderRenderCase.ShaderEvalFunc} */ this.m_evalFunc
= evalFunc
|| null;
449 * @param {glsShaderRenderCase.ShaderEvalContext} ctx
451 glsShaderRenderCase
.ShaderEvaluator
.prototype.evaluate = function(ctx
) {
452 assertMsgOptions(this.m_evalFunc
!== null, 'No evaluation function specified.', false, true);
453 this.m_evalFunc(ctx
);
458 * @extends {tcuTestCase.DeqpTest}
459 * @param {string} name
460 * @param {string} description
461 * @param {boolean} isVertexCase
462 * @param {glsShaderRenderCase.ShaderEvalFunc=} evalFunc
464 glsShaderRenderCase
.ShaderRenderCase = function(name
, description
, isVertexCase
, evalFunc
) {
465 tcuTestCase
.DeqpTest
.call(this, name
, description
);
466 // evalFunc = evalFunc || null;
467 /** @type {boolean} */ this.m_isVertexCase
= isVertexCase
;
468 /** @type {?glsShaderRenderCase.ShaderEvalFunc} */ this.m_defaultEvaluator
= evalFunc
|| null;
469 /** @type {glsShaderRenderCase.ShaderEvaluator} */ this.m_evaluator
= new glsShaderRenderCase
.ShaderEvaluator(this.m_defaultEvaluator
);
470 /** @type {string} */ this.m_vertShaderSource
= '';
471 /** @type {string} */ this.m_fragShaderSource
= '';
472 /** @type {Array<number>} */ this.m_clearColor
= glsShaderRenderCase
.DEFAULT_CLEAR_COLOR
;
473 /** @type {Array<tcuMatrix.Matrix>} */ this.m_userAttribTransforms
= [];
474 /** @type {Array<glsShaderRenderCase.TextureBinding>} */ this.m_textures
= [];
475 /** @type {?gluShaderProgram.ShaderProgram} */ this.m_program
= null;
479 * @param {string} name
480 * @param {string} description
481 * @param {boolean} isVertexCase
482 * @param {glsShaderRenderCase.ShaderEvaluator} evaluator
483 * @return {glsShaderRenderCase.ShaderRenderCase}
485 glsShaderRenderCase
.ShaderRenderCase
.newWithEvaluator = function(name
, description
, isVertexCase
, evaluator
) {
486 var renderCase
= new glsShaderRenderCase
.ShaderRenderCase(name
, description
, isVertexCase
);
487 renderCase
.m_evaluator
= evaluator
;
491 glsShaderRenderCase
.ShaderRenderCase
.prototype = Object
.create(tcuTestCase
.DeqpTest
.prototype);
492 glsShaderRenderCase
.ShaderRenderCase
.prototype.constructor = glsShaderRenderCase
.ShaderRenderCase
;
494 glsShaderRenderCase
.ShaderRenderCase
.prototype.deinit = function() {
495 this.m_program
= null;
498 glsShaderRenderCase
.ShaderRenderCase
.prototype.init = function() {
502 glsShaderRenderCase
.ShaderRenderCase
.prototype.postinit = function() {
503 if (this.m_vertShaderSource
.length
=== 0 || this.m_fragShaderSource
.length
=== 0) {
504 assertMsgOptions(this.m_vertShaderSource
.length
=== 0 && this.m_fragShaderSource
.length
=== 0, 'No shader source.', false, true);
505 this.setupShaderData();
508 assertMsgOptions(!this.m_program
, 'Program defined.', false, true);
509 this.m_program
= new gluShaderProgram
.ShaderProgram(gl
, gluShaderProgram
.makeVtxFragSources(this.m_vertShaderSource
, this.m_fragShaderSource
));
512 bufferedLogToConsole(this.m_program
.program
.info
.infoLog
); // Always log shader program.
514 if (!this.m_program
.isOk())
515 throw new Error("Shader compile error.");
525 * @return {tcuTestCase.IterateResult}
527 glsShaderRenderCase
.ShaderRenderCase
.prototype.postiterate = function() {
528 assertMsgOptions(this.m_program
!== null, 'Program not specified.', false, true);
529 /** @type {?WebGLProgram} */ var programID
= this.m_program
.getProgram();
530 gl
.useProgram(programID
);
533 /** @type {Array<number>} */ var viewportSize
= this.getViewportSize();
534 /** @type {number} */ var width
= viewportSize
[0];
535 /** @type {number} */ var height
= viewportSize
[1];
537 // \todo [petri] Better handling of constCoords (render in multiple chunks, vary coords).
538 /** @type {glsShaderRenderCase.QuadGrid} */
539 var quadGrid
= new glsShaderRenderCase
.QuadGrid(
540 this.m_isVertexCase
? glsShaderRenderCase
.GRID_SIZE
: 4, width
, height
,
541 [0.125, 0.25, 0.5, 1.0], this.m_userAttribTransforms
, this.m_textures
);
544 /** @type {tcuSurface.Surface} */ var resImage
= new tcuSurface
.Surface(width
, height
);
545 this.render(resImage
, programID
, quadGrid
);
547 // Compute reference.
548 /** @type {tcuSurface.Surface} */ var refImage
= new tcuSurface
.Surface(width
, height
);
549 if (this.m_isVertexCase
)
550 this.computeVertexReference(refImage
, quadGrid
);
552 this.computeFragmentReference(refImage
, quadGrid
);
555 /** @type {boolean} */ var testOk
= this.compareImages(resImage
, refImage
, 0.05);
561 testFailedOptions("Fail", false);
563 testPassedOptions("Pass", true);
565 return tcuTestCase
.IterateResult
.STOP
;
569 * @return {tcuTestCase.IterateResult}
571 glsShaderRenderCase
.ShaderRenderCase
.prototype.iterate = function() {
572 return this.postiterate();
575 glsShaderRenderCase
.ShaderRenderCase
.prototype.setupShaderData = function() {};
578 * @param {?WebGLProgram} programId
580 glsShaderRenderCase
.ShaderRenderCase
.prototype.setup = function(programId
) {};
583 * @param {?WebGLProgram} programId
584 * @param {Array<number>} constCoords
586 glsShaderRenderCase
.ShaderRenderCase
.prototype.setupUniforms = function(programId
, constCoords
) {};
589 * @return {Array<number>}
591 glsShaderRenderCase
.ShaderRenderCase
.prototype.getViewportSize = function() {
592 return [Math
.min(gl
.canvas
.width
, glsShaderRenderCase
.MAX_RENDER_WIDTH
),
593 Math
.min(gl
.canvas
.height
, glsShaderRenderCase
.MAX_RENDER_HEIGHT
)];
597 * @param {?WebGLProgram} programId
599 glsShaderRenderCase
.ShaderRenderCase
.prototype.setupDefaultInputs = function(programId
) {
601 glsShaderRenderCase
.setupDefaultUniforms(programId
);
604 for (var ndx
= 0; ndx
< this.m_textures
.length
; ndx
++) {
605 /** @type {glsShaderRenderCase.TextureBinding} */ var tex
= this.m_textures
[ndx
];
606 /** @type {tcuTexture.Sampler} */ var sampler
= tex
.getSampler();
607 /** @type {number} */ var texTarget
= gl
.NONE
;
608 /** @type {number} */ var texObj
= 0;
610 if (tex
.getType() === gluTexture
.Type
.TYPE_NONE
)
613 switch (tex
.getType()) {
614 case gluTexture
.Type
.TYPE_2D
:
615 texTarget
= gl
.TEXTURE_2D
;
616 texObj
= tex
.getBinding().getGLTexture();
618 case gluTexture
.Type
.TYPE_CUBE_MAP
:
619 texTarget
= gl
.TEXTURE_CUBE_MAP
;
620 texObj
= tex
.getBinding().getGLTexture();
622 case gluTexture
.Type
.TYPE_2D_ARRAY
:
623 texTarget
= gl
.TEXTURE_2D_ARRAY
;
624 texObj
= tex
.getBinding().getGLTexture();
626 case gluTexture
.Type
.TYPE_3D
:
627 texTarget
= gl
.TEXTURE_3D
;
628 texObj
= tex
.getBinding().getGLTexture();
631 throw new Error("Type not supported");
634 gl
.activeTexture(gl
.TEXTURE0
+ ndx
);
635 gl
.bindTexture(texTarget
, texObj
);
636 gl
.texParameteri(texTarget
, gl
.TEXTURE_WRAP_S
, gluTextureUtil
.getGLWrapMode(sampler
.wrapS
));
637 gl
.texParameteri(texTarget
, gl
.TEXTURE_WRAP_T
, gluTextureUtil
.getGLWrapMode(sampler
.wrapT
));
638 gl
.texParameteri(texTarget
, gl
.TEXTURE_MIN_FILTER
, gluTextureUtil
.getGLFilterMode(sampler
.minFilter
));
639 gl
.texParameteri(texTarget
, gl
.TEXTURE_MAG_FILTER
, gluTextureUtil
.getGLFilterMode(sampler
.magFilter
));
641 if (texTarget
=== gl
.TEXTURE_3D
)
642 gl
.texParameteri(texTarget
, gl
.TEXTURE_WRAP_R
, gluTextureUtil
.getGLWrapMode(sampler
.wrapR
));
644 if (sampler
.compare
!= tcuTexture
.CompareMode
.COMPAREMODE_NONE
)
646 gl
.texParameteri(texTarget
, gl
.TEXTURE_COMPARE_MODE
, gl
.COMPARE_REF_TO_TEXTURE
);
647 gl
.texParameteri(texTarget
, gl
.TEXTURE_COMPARE_FUNC
, gluTextureUtil
.getGLCompareFunc(sampler
.compare
));
653 * @param {tcuSurface.Surface} result
654 * @param {?WebGLProgram} programId
655 * @param {glsShaderRenderCase.QuadGrid} quadGrid
657 glsShaderRenderCase
.ShaderRenderCase
.prototype.render = function(result
, programId
, quadGrid
) {
659 /** @type {number} */ var width
= result
.getWidth();
660 /** @type {number} */ var height
= result
.getHeight();
662 /** @type {number} */ var xOffsetMax
= gl
.drawingBufferWidth
- width
;
663 /** @type {number} */ var yOffsetMax
= gl
.drawingBufferHeight
- height
;
665 /** @type {number} */ var hash
= deString
.deStringHash(this.m_vertShaderSource
) + deString
.deStringHash(this.m_fragShaderSource
);
666 /** @type {deRandom.Random} */ var rnd
= new deRandom
.Random(hash
);
668 /** @type {number} */ var xOffset
= rnd
.getInt(0, xOffsetMax
);
669 /** @type {number} */ var yOffset
= rnd
.getInt(0, yOffsetMax
);
671 gl
.viewport(xOffset
, yOffset
, width
, height
);
674 this.setupUniforms(programId
, quadGrid
.getConstCoords());
675 this.setupDefaultInputs(programId
);
678 gl
.clearColor(this.m_clearColor
[0], this.m_clearColor
[1], this.m_clearColor
[2], this.m_clearColor
[3]);
679 gl
.clear(gl
.COLOR_BUFFER_BIT
);
682 /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays
= [];
683 /** @type {number} */ var numElements
= quadGrid
.getNumTriangles()*3;
685 glsShaderRenderCase
.getDefaultVertexArrays(quadGrid
, programId
, vertexArrays
);
687 gluDrawUtil
.draw(gl
, programId
, vertexArrays
, gluDrawUtil
.triangles(quadGrid
.getIndices()));
689 // Read back results.
690 result
.readViewport(gl
, [xOffset
, yOffset
, width
, height
]);
695 * @param {tcuSurface.Surface} result
696 * @param {glsShaderRenderCase.QuadGrid} quadGrid
698 glsShaderRenderCase
.ShaderRenderCase
.prototype.computeVertexReference = function(result
, quadGrid
) {
700 /** @type {number} */ var width
= result
.getWidth();
701 /** @type {number} */ var height
= result
.getHeight();
702 /** @type {number} */ var gridSize
= quadGrid
.getGridSize();
703 /** @type {number} */ var stride
= gridSize
+ 1;
704 /** @type {boolean} */ var hasAlpha
= gl
.getContextAttributes().alpha
;
705 /** @type {glsShaderRenderCase.ShaderEvalContext} */
706 var evalCtx
= new glsShaderRenderCase
.ShaderEvalContext(quadGrid
);
707 /** @type {Array<number>} */ var color
= [];
708 // Evaluate color for each vertex.
709 /** @type {Array<Array<number>>} */ var colors
= [];
710 for (var y
= 0; y
< gridSize
+ 1; y
++)
711 for (var x
= 0; x
< gridSize
+ 1; x
++) {
712 /** @type {number} */ var sx
= x
/ gridSize
;
713 /** @type {number} */ var sy
= y
/ gridSize
;
714 /** @type {number} */ var vtxNdx
= ((y
* (gridSize
+ 1 )) + x
);
716 evalCtx
.reset(sx
, sy
);
717 this.m_evaluator
.evaluate(evalCtx
);
718 assertMsgOptions(!evalCtx
.isDiscarded
, 'Discard is not available in vertex shader.', false, true);
719 color
= evalCtx
.color
;
724 colors
[vtxNdx
] = color
;
727 for (var y
= 0; y
< gridSize
; y
++)
728 for (var x
= 0; x
< gridSize
; x
++) {
729 /** @type {number} */ var x0
= x
/ gridSize
;
730 /** @type {number} */ var x1
= (x
+ 1) / gridSize
;
731 /** @type {number} */ var y0
= y
/ gridSize
;
732 /** @type {number} */ var y1
= (y
+ 1) / gridSize
;
734 /** @type {number} */ var sx0
= x0
* width
;
735 /** @type {number} */ var sx1
= x1
* width
;
736 /** @type {number} */ var sy0
= y0
* height
;
737 /** @type {number} */ var sy1
= y1
* height
;
738 /** @type {number} */ var oosx
= 1.0 / (sx1
- sx0
);
739 /** @type {number} */ var oosy
= 1.0 / (sy1
- sy0
);
741 /** @type {number} */ var ix0
= Math
.ceil(sx0
- 0.5);
742 /** @type {number} */ var ix1
= Math
.ceil(sx1
- 0.5);
743 /** @type {number} */ var iy0
= Math
.ceil(sy0
- 0.5);
744 /** @type {number} */ var iy1
= Math
.ceil(sy1
- 0.5);
746 /** @type {number} */ var v00
= (y
* stride
) + x
;
747 /** @type {number} */ var v01
= (y
* stride
) + x
+ 1;
748 /** @type {number} */ var v10
= ((y
+ 1) * stride
) + x
;
749 /** @type {number} */ var v11
= ((y
+ 1) * stride
) + x
+ 1;
750 /** @type {Array<number>} */ var c00
= colors
[v00
];
751 /** @type {Array<number>} */ var c01
= colors
[v01
];
752 /** @type {Array<number>} */ var c10
= colors
[v10
];
753 /** @type {Array<number>} */ var c11
= colors
[v11
];
755 for (var iy
= iy0
; iy
< iy1
; iy
++)
756 for (var ix
= ix0
; ix
< ix1
; ix
++) {
757 assertMsgOptions(deMath
.deInBounds32(ix
, 0, width
), 'Out of bounds.', false, true);
758 assertMsgOptions(deMath
.deInBounds32(iy
, 0, height
), 'Out of bounds.', false, true);
760 /** @type {number} */ var sfx
= ix
+ 0.5;
761 /** @type {number} */ var sfy
= iy
+ 0.5;
762 /** @type {number} */ var fx1
= deMath
.clamp((sfx
- sx0
) * oosx
, 0.0, 1.0);
763 /** @type {number} */ var fy1
= deMath
.clamp((sfy
- sy0
) * oosy
, 0.0, 1.0);
765 // Triangle quad interpolation.
766 /** @type {boolean} */ var tri
= fx1
+ fy1
<= 1.0;
767 /** @type {number} */ var tx
= tri
? fx1
: (1.0 - fx1
);
768 /** @type {number} */ var ty
= tri
? fy1
: (1.0 - fy1
);
769 /** @type {Array<number>} */ var t0
= tri
? c00
: c11
;
770 /** @type {Array<number>} */ var t1
= tri
? c01
: c10
;
771 /** @type {Array<number>} */ var t2
= tri
? c10
: c01
;
772 color
= deMath
.add(t0
, deMath
.add(deMath
.scale(deMath
.subtract(t1
, t0
), tx
), deMath
.scale(deMath
.subtract(t2
, t0
), ty
)));
774 result
.setPixel(ix
, iy
, glsShaderRenderCase
.toRGBA(color
).toIVec());
780 * @param {tcuSurface.Surface} result
781 * @param {glsShaderRenderCase.QuadGrid} quadGrid
783 glsShaderRenderCase
.ShaderRenderCase
.prototype.computeFragmentReference = function(result
, quadGrid
) {
785 /** @type {number} */ var width
= result
.getWidth();
786 /** @type {number} */ var height
= result
.getHeight();
787 /** @type {boolean} */ var hasAlpha
= gl
.getContextAttributes().alpha
;
788 /** @type {glsShaderRenderCase.ShaderEvalContext} */ var evalCtx
= new glsShaderRenderCase
.ShaderEvalContext(quadGrid
);
791 for (var y
= 0; y
< height
; y
++)
792 for (var x
= 0; x
< width
; x
++) {
793 /** @type {number} */ var sx
= (x
+ 0.5) / width
;
794 /** @type {number} */ var sy
= (y
+ 0.5) / height
;
796 evalCtx
.reset(sx
, sy
);
797 this.m_evaluator
.evaluate(evalCtx
);
798 // Select either clear color or computed color based on discarded bit.
799 /** @type {Array<number>} */ var color
= evalCtx
.isDiscarded
? this.m_clearColor
: evalCtx
.color
;
804 result
.setPixel(x
, y
, glsShaderRenderCase
.toRGBA(color
).toIVec());
809 * @param {tcuSurface.Surface} resImage
810 * @param {tcuSurface.Surface} refImage
811 * @param {number} errorThreshold
814 glsShaderRenderCase
.ShaderRenderCase
.prototype.compareImages = function(resImage
, refImage
, errorThreshold
) {
815 return tcuImageCompare
.fuzzyCompare("ComparisonResult", "Image comparison result", refImage
.getAccess(), resImage
.getAccess(), errorThreshold
);
819 * @param {number} number
820 * @return {string} */
821 glsShaderRenderCase
.getIntUniformName = function(number
) {
823 case 0: return "ui_zero";
824 case 1: return "ui_one";
825 case 2: return "ui_two";
826 case 3: return "ui_three";
827 case 4: return "ui_four";
828 case 5: return "ui_five";
829 case 6: return "ui_six";
830 case 7: return "ui_seven";
831 case 8: return "ui_eight";
832 case 101: return "ui_oneHundredOne";
834 throw new Error("Uniform not supported.");
839 * @param {number} number
840 * @return {string} */
841 glsShaderRenderCase
.getFloatUniformName = function(number
) {
843 case 0: return "uf_zero";
844 case 1: return "uf_one";
845 case 2: return "uf_two";
846 case 3: return "uf_three";
847 case 4: return "uf_four";
848 case 5: return "uf_five";
849 case 6: return "uf_six";
850 case 7: return "uf_seven";
851 case 8: return "uf_eight";
853 throw new Error("Uniform not supported.");
858 * @param {number} number
859 * @return {string} */
860 glsShaderRenderCase
.getFloatFractionUniformName = function(number
) {
862 case 1: return "uf_one";
863 case 2: return "uf_half";
864 case 3: return "uf_third";
865 case 4: return "uf_fourth";
866 case 5: return "uf_fifth";
867 case 6: return "uf_sixth";
868 case 7: return "uf_seventh";
869 case 8: return "uf_eighth";
871 throw new Error("Uniform not supported.");
876 * @param {?WebGLProgram} programID
878 glsShaderRenderCase
.setupDefaultUniforms = function(programID
) {
879 /** @type {?WebGLUniformLocation} */ var uniLoc
;
885 var BoolUniform = function(name
, value
) {
886 /** @type {string} */ this.name
= name
;
887 /** @type {boolean} */ this.value
= value
;
890 /** @type {Array<BoolUniform>} */ var s_boolUniforms
= [
891 new BoolUniform("ub_true", true),
892 new BoolUniform("ub_false", false)
895 for (var i
= 0; i
< s_boolUniforms
.length
; i
++) {
896 uniLoc
= gl
.getUniformLocation(programID
, s_boolUniforms
[i
].name
);
898 gl
.uniform1i(uniLoc
, s_boolUniforms
[i
].value
? 1 : 0);
906 var BVec4Uniform = function(name
, value
) {
907 /** @type {string} */ this.name
= name
;
908 /** @type {Array<boolean>} */ this.value
= value
;
911 /** @type {Array<BVec4Uniform>} */ var s_bvec4Uniforms
= [
912 new BVec4Uniform("ub4_true", [true, true, true, true]),
913 new BVec4Uniform("ub4_false", [false, false, false, false])
916 for (var i
= 0; i
< s_bvec4Uniforms
.length
; i
++) {
917 /** @type {BVec4Uniform} */ var uni
= s_bvec4Uniforms
[i
];
918 /** @type {Array<number>} */ var arr
= [];
919 arr
[0] = uni
.value
[0] ? 1 : 0;
920 arr
[1] = uni
.value
[1] ? 1 : 0;
921 arr
[2] = uni
.value
[2] ? 1 : 0;
922 arr
[3] = uni
.value
[3] ? 1 : 0;
923 uniLoc
= gl
.getUniformLocation(programID
, uni
.name
);
925 gl
.uniform4iv(uniLoc
, new Int32Array(arr
));
933 var IntUniform = function(name
, value
) {
934 /** @type {string} */ this.name
= name
;
935 /** @type {number} */ this.value
= value
;
938 /** @type {Array<IntUniform>} */ var s_intUniforms
= [
939 new IntUniform("ui_minusOne", -1),
940 new IntUniform("ui_zero", 0),
941 new IntUniform("ui_one", 1),
942 new IntUniform("ui_two", 2),
943 new IntUniform("ui_three", 3),
944 new IntUniform("ui_four", 4),
945 new IntUniform("ui_five", 5),
946 new IntUniform("ui_six", 6),
947 new IntUniform("ui_seven", 7),
948 new IntUniform("ui_eight", 8),
949 new IntUniform("ui_oneHundredOne", 101)
952 for (var i
= 0; i
< s_intUniforms
.length
; i
++) {
953 uniLoc
= gl
.getUniformLocation(programID
, s_intUniforms
[i
].name
);
955 gl
.uniform1i(uniLoc
, s_intUniforms
[i
].value
);
963 var IVec2Uniform = function(name
, value
) {
964 /** @type {string} */ this.name
= name
;
965 /** @type {Array<number>} */ this.value
= value
;
968 /** @type {Array<IVec2Uniform>} */ var s_ivec2Uniforms
= [
969 new IVec2Uniform("ui2_minusOne", [-1, -1]),
970 new IVec2Uniform("ui2_zero", [0, 0]),
971 new IVec2Uniform("ui2_one", [1, 1]),
972 new IVec2Uniform("ui2_two", [2, 2]),
973 new IVec2Uniform("ui2_four", [4, 4]),
974 new IVec2Uniform("ui2_five", [5, 5])
977 for (var i
= 0; i
< s_ivec2Uniforms
.length
; i
++) {
978 uniLoc
= gl
.getUniformLocation(programID
, s_ivec2Uniforms
[i
].name
);
980 gl
.uniform2iv(uniLoc
, new Int32Array(s_ivec2Uniforms
[i
].value
));
988 var IVec3Uniform = function(name
, value
) {
989 /** @type {string} */ this.name
= name
;
990 /** @type {Array<number>} */ this.value
= value
;
993 /** @type {Array<IVec3Uniform>} */ var s_ivec3Uniforms
= [
994 new IVec3Uniform("ui3_minusOne", [-1, -1, -1]),
995 new IVec3Uniform("ui3_zero", [0, 0, 0]),
996 new IVec3Uniform("ui3_one", [1, 1, 1]),
997 new IVec3Uniform("ui3_two", [2, 2, 2]),
998 new IVec3Uniform("ui3_four", [4, 4, 4]),
999 new IVec3Uniform("ui3_five", [5, 5, 5])
1002 for (var i
= 0; i
< s_ivec3Uniforms
.length
; i
++) {
1003 uniLoc
= gl
.getUniformLocation(programID
, s_ivec3Uniforms
[i
].name
);
1005 gl
.uniform3iv(uniLoc
, new Int32Array(s_ivec3Uniforms
[i
].value
));
1013 var IVec4Uniform = function(name
, value
) {
1014 /** @type {string} */ this.name
= name
;
1015 /** @type {Array<number>} */ this.value
= value
;
1017 /** @type {Array<IVec4Uniform>} */ var s_ivec4Uniforms
= [
1018 new IVec4Uniform("ui4_minusOne", [-1, -1, -1, -1]),
1019 new IVec4Uniform("ui4_zero", [0, 0, 0, 0]),
1020 new IVec4Uniform("ui4_one", [1, 1, 1, 1]),
1021 new IVec4Uniform("ui4_two", [2, 2, 2, 2]),
1022 new IVec4Uniform("ui4_four", [4, 4, 4, 4]),
1023 new IVec4Uniform("ui4_five", [5, 5, 5, 5])
1026 for (var i
= 0; i
< s_ivec4Uniforms
.length
; i
++) {
1027 uniLoc
= gl
.getUniformLocation(programID
, s_ivec4Uniforms
[i
].name
);
1029 gl
.uniform4iv(uniLoc
, new Int32Array(s_ivec4Uniforms
[i
].value
));
1037 var FloatUniform = function(name
, value
) {
1038 /** @type {string} */ this.name
= name
;
1039 /** @type {number} */ this.value
= value
;
1041 /** @type {Array<FloatUniform>} */ var s_floatUniforms
= [
1042 new FloatUniform("uf_zero", 0.0),
1043 new FloatUniform("uf_one", 1.0),
1044 new FloatUniform("uf_two", 2.0),
1045 new FloatUniform("uf_three", 3.0),
1046 new FloatUniform("uf_four", 4.0),
1047 new FloatUniform("uf_five", 5.0),
1048 new FloatUniform("uf_six", 6.0),
1049 new FloatUniform("uf_seven", 7.0),
1050 new FloatUniform("uf_eight", 8.0),
1051 new FloatUniform("uf_half", 1.0 / 2.0),
1052 new FloatUniform("uf_third", 1.0 / 3.0),
1053 new FloatUniform("uf_fourth", 1.0 / 4.0),
1054 new FloatUniform("uf_fifth", 1.0 / 5.0),
1055 new FloatUniform("uf_sixth", 1.0 / 6.0),
1056 new FloatUniform("uf_seventh", 1.0 / 7.0),
1057 new FloatUniform("uf_eighth", 1.0 / 8.0)
1060 for (var i
= 0; i
< s_floatUniforms
.length
; i
++) {
1061 uniLoc
= gl
.getUniformLocation(programID
, s_floatUniforms
[i
].name
);
1063 gl
.uniform1f(uniLoc
, s_floatUniforms
[i
].value
);
1071 var Vec2Uniform = function(name
, value
) {
1072 /** @type {string} */ this.name
= name
;
1073 /** @type {Array<number>} */ this.value
= value
;
1075 /** @type {Array<Vec2Uniform>} */ var s_vec2Uniforms
= [
1076 new Vec2Uniform("uv2_minusOne", [-1.0, -1.0]),
1077 new Vec2Uniform("uv2_zero", [0.0, 0.0]),
1078 new Vec2Uniform("uv2_half", [0.5, 0.5]),
1079 new Vec2Uniform("uv2_one", [1.0, 1.0]),
1080 new Vec2Uniform("uv2_two", [2.0, 2.0])
1083 for (var i
= 0; i
< s_vec2Uniforms
.length
; i
++) {
1084 uniLoc
= gl
.getUniformLocation(programID
, s_vec2Uniforms
[i
].name
);
1086 gl
.uniform2fv(uniLoc
, new Float32Array(s_vec2Uniforms
[i
].value
));
1094 var Vec3Uniform = function(name
, value
) {
1095 /** @type {string} */ this.name
= name
;
1096 /** @type {Array<number>} */ this.value
= value
;
1098 /** @type {Array<Vec3Uniform>} */ var s_vec3Uniforms
= [
1099 new Vec3Uniform("uv3_minusOne", [-1.0, -1.0, -1.0]),
1100 new Vec3Uniform("uv3_zero", [0.0, 0.0, 0.0]),
1101 new Vec3Uniform("uv3_half", [0.5, 0.5, 0.5]),
1102 new Vec3Uniform("uv3_one", [1.0, 1.0, 1.0]),
1103 new Vec3Uniform("uv3_two", [2.0, 2.0, 2.0])
1106 for (var i
= 0; i
< s_vec3Uniforms
.length
; i
++) {
1107 uniLoc
= gl
.getUniformLocation(programID
, s_vec3Uniforms
[i
].name
);
1109 gl
.uniform3fv(uniLoc
, new Float32Array(s_vec3Uniforms
[i
].value
));
1117 var Vec4Uniform = function(name
, value
) {
1118 /** @type {string} */ this.name
= name
;
1119 /** @type {Array<number>} */ this.value
= value
;
1121 /** @type {Array<Vec4Uniform>} */ var s_vec4Uniforms
= [
1122 new Vec4Uniform("uv4_minusOne", [-1.0, -1.0, -1.0, -1.0]),
1123 new Vec4Uniform("uv4_zero", [0.0, 0.0, 0.0, 0.0]),
1124 new Vec4Uniform("uv4_half", [0.5, 0.5, 0.5, 0.5]),
1125 new Vec4Uniform("uv4_one", [1.0, 1.0, 1.0, 1.0]),
1126 new Vec4Uniform("uv4_two", [2.0, 2.0, 2.0, 2.0]),
1127 new Vec4Uniform("uv4_black", [0.0, 0.0, 0.0, 1.0]),
1128 new Vec4Uniform("uv4_gray", [0.5, 0.5, 0.5, 1.0]),
1129 new Vec4Uniform("uv4_white", [1.0, 1.0, 1.0, 1.0])
1132 for (var i
= 0; i
< s_vec4Uniforms
.length
; i
++) {
1133 uniLoc
= gl
.getUniformLocation(programID
, s_vec4Uniforms
[i
].name
);
1135 gl
.uniform4fv(uniLoc
, new Float32Array(s_vec4Uniforms
[i
].value
));
1140 * @param {glsShaderRenderCase.QuadGrid} quadGrid
1141 * @param {?WebGLProgram} program
1142 * @param {Array<gluDrawUtil.VertexArrayBinding>} vertexArrays
1144 glsShaderRenderCase
.getDefaultVertexArrays = function(quadGrid
, program
, vertexArrays
) {
1145 /** @type {number} */ var numElements
= quadGrid
.getNumVertices();
1146 var posArray
= [].concat
.apply([], quadGrid
.getPositions());
1147 var coordsArray
= [].concat
.apply([], quadGrid
.getCoordsArray());
1148 var unitCoordsArray
= [].concat
.apply([], quadGrid
.getUnitCoordsArray());
1150 vertexArrays
.push(gluDrawUtil
.newFloatVertexArrayBinding("a_position", 4, numElements
, 0, posArray
));
1151 vertexArrays
.push(gluDrawUtil
.newFloatVertexArrayBinding("a_coords", 4, numElements
, 0, coordsArray
));
1152 vertexArrays
.push(gluDrawUtil
.newFloatVertexArrayBinding("a_unitCoords", 4, numElements
, 0, unitCoordsArray
));
1153 vertexArrays
.push(gluDrawUtil
.newFloatVertexArrayBinding("a_one", 1, numElements
, 0, quadGrid
.getAttribOne()));
1156 for (var userNdx
= 0; userNdx
< quadGrid
.getNumUserAttribs(); userNdx
++) {
1157 /** @type {string} */ var name
= "a_in" + userNdx
;
1158 var userAttribArray
= [].concat
.apply([], quadGrid
.getUserAttribByIndex(userNdx
));
1159 vertexArrays
.push(gluDrawUtil
.newFloatVertexArrayBinding(name
, 4, numElements
, 0, userAttribArray
));
1162 // Matrix attributes - these are set by location
1167 var Matrix = function(name
, cols
, rows
) {
1169 this.numCols
= cols
;
1170 this.numRows
= rows
;
1173 /** @type {Array<Matrix>} */ var matrices
= [
1174 new Matrix('a_mat2', 2, 2),
1175 new Matrix('a_mat2x3', 2, 3),
1176 new Matrix('a_mat2x4', 2, 4),
1177 new Matrix('a_mat3x2', 3, 2),
1178 new Matrix('a_mat3', 3, 3),
1179 new Matrix('a_mat3x4', 3, 4),
1180 new Matrix('a_mat4x2', 4, 2),
1181 new Matrix('a_mat4x3', 4, 3),
1182 new Matrix('a_mat4', 4, 4)
1185 for (var matNdx
= 0; matNdx
< matrices
.length
; matNdx
++) {
1186 /** @type {number} */ var loc
= gl
.getAttribLocation(program
, matrices
[matNdx
].name
);
1189 continue; // Not used in shader.
1191 /** @type {number} */ var numRows
= matrices
[matNdx
].numRows
;
1192 /** @type {number} */ var numCols
= matrices
[matNdx
].numCols
;
1194 for (var colNdx
= 0; colNdx
< numCols
; colNdx
++) {
1195 var data
= [].concat
.apply([], quadGrid
.getUserAttribByIndex(colNdx
));
1196 vertexArrays
.push(gluDrawUtil
.newFloatColumnVertexArrayBinding(matrices
[matNdx
].name
, colNdx
, numRows
, numElements
, 4 * 4, data
));