glsShaderRenderCase.js (48630B)
1 /*------------------------------------------------------------------------- 2 * drawElements Quality Program OpenGL ES Utilities 3 * ------------------------------------------------ 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 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 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 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. 18 * 19 */ 20 21 'use strict'; 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'); 36 37 goog.scope(function() { 38 var glsShaderRenderCase = modules.shared.glsShaderRenderCase; 39 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; 53 54 /** @typedef {function(glsShaderRenderCase.ShaderEvalContext)} */ glsShaderRenderCase.ShaderEvalFunc; 55 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; 62 63 /** 64 * @param {Array<number>} a 65 * @return {tcuRGBA.RGBA} 66 */ 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)); 73 }; 74 75 /** 76 * Helper function 77 * @param {?(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} tex 78 * @return {gluTexture.Type} 79 */ 80 glsShaderRenderCase.getTextureType = function(tex) { 81 if (tex === null || tex.getType() <= 0) 82 return gluTexture.Type.TYPE_NONE; 83 else 84 return tex.getType(); 85 }; 86 87 /** 88 * @constructor 89 * @param {number=} indent 90 */ 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; 96 }; 97 98 /** 99 * @return {string} 100 */ 101 glsShaderRenderCase.LineStream.prototype.str = function() { 102 this.m_string = this.m_stream; 103 return this.m_string; 104 }; 105 106 /** 107 * @constructor 108 * @param {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)=} tex 109 * @param {tcuTexture.Sampler=} sampler 110 */ 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; 118 }; 119 120 /** 121 * @param {tcuTexture.Sampler} sampler 122 */ 123 glsShaderRenderCase.TextureBinding.prototype.setSampler = function(sampler) { 124 this.m_sampler = sampler; 125 }; 126 127 /** 128 * @param {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} tex 129 */ 130 glsShaderRenderCase.TextureBinding.prototype.setTexture = function(tex) { 131 this.m_type = glsShaderRenderCase.getTextureType(tex); 132 this.m_binding = tex; 133 }; 134 135 /** @return {gluTexture.Type} */ 136 glsShaderRenderCase.TextureBinding.prototype.getType = function() { 137 return this.m_type; 138 }; 139 140 /** @return {tcuTexture.Sampler} */ 141 glsShaderRenderCase.TextureBinding.prototype.getSampler = function() { 142 return this.m_sampler; 143 }; 144 145 /** @return {(gluTexture.Texture2D|gluTexture.TextureCube|gluTexture.Texture2DArray|gluTexture.Texture3D)} */ 146 glsShaderRenderCase.TextureBinding.prototype.getBinding = function() { 147 return this.m_binding; 148 }; 149 150 /** 151 * @constructor 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 158 */ 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 = []; 175 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); 184 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); 190 191 for (var attribNdx = 0; attribNdx < this.getNumUserAttribs(); attribNdx++) 192 this.m_userAttribs[attribNdx][vtxNdx] = this.getUserAttrib(attribNdx, sx, sy); 193 } 194 195 // Compute indices. 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; 203 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; 208 209 this.m_indices[baseNdx + 3] = v10; 210 this.m_indices[baseNdx + 4] = v01; 211 this.m_indices[baseNdx + 5] = v11; 212 } 213 }; 214 215 /** @return {number} */ 216 glsShaderRenderCase.QuadGrid.prototype.getGridSize = function() { 217 return this.m_gridSize; 218 }; 219 220 /** @return {number} */ 221 glsShaderRenderCase.QuadGrid.prototype.getNumVertices = function() { 222 return this.m_numVertices; 223 }; 224 225 /** @return {number} */ 226 glsShaderRenderCase.QuadGrid.prototype.getNumTriangles = function() { 227 return this.m_numTriangles; 228 }; 229 230 /** @return {Array<number>} */ 231 glsShaderRenderCase.QuadGrid.prototype.getConstCoords = function() { 232 return this.m_constCoords; 233 }; 234 235 /** @return {Array<tcuMatrix.Matrix>} */ 236 glsShaderRenderCase.QuadGrid.prototype.getUserAttribTransforms = function() { 237 return this.m_userAttribTransforms; 238 }; 239 240 /** @return {Array<glsShaderRenderCase.TextureBinding>} */ 241 glsShaderRenderCase.QuadGrid.prototype.getTextures = function() { 242 return this.m_textures; 243 }; 244 245 /** @return {Array<Array<number>>} */ 246 glsShaderRenderCase.QuadGrid.prototype.getPositions = function() { 247 return this.m_positions; 248 }; 249 250 /** @return {Array<number>} */ 251 glsShaderRenderCase.QuadGrid.prototype.getAttribOne = function() { 252 return this.m_attribOne; 253 }; 254 255 /** @return {Array<Array<number>>} */ 256 glsShaderRenderCase.QuadGrid.prototype.getCoordsArray = function() { 257 return this.m_coords; 258 }; 259 260 /** @return {Array<Array<number>>} */ 261 glsShaderRenderCase.QuadGrid.prototype.getUnitCoordsArray = function() { 262 return this.m_unitCoords; 263 }; 264 265 /** 266 * @param {number} attribNdx 267 * @return {Array<number>} 268 */ 269 glsShaderRenderCase.QuadGrid.prototype.getUserAttribByIndex = function(attribNdx) { 270 return this.m_userAttribs[attribNdx]; 271 }; 272 273 /** @return {Array<number>} */ 274 glsShaderRenderCase.QuadGrid.prototype.getIndices = function() { 275 return this.m_indices; 276 }; 277 278 /** 279 * @param {number} sx 280 * @param {number} sy 281 * @return {Array<number>} 282 */ 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]; 287 }; 288 289 /** 290 * @param {number} sx 291 * @param {number} sy 292 * @return {Array<number>} 293 */ 294 glsShaderRenderCase.QuadGrid.prototype.getUnitCoords = function(sx, sy) { 295 return [sx, sy, 0.33 * sx + 0.5 * sy, 0.5 * sx + 0.25 * sy]; 296 }; 297 298 /** 299 * @return {number} 300 */ 301 glsShaderRenderCase.QuadGrid.prototype.getNumUserAttribs = function() { 302 return this.m_userAttribTransforms.length; 303 }; 304 305 /** 306 * @param {number} attribNdx 307 * @param {number} sx 308 * @param {number} sy 309 * @return {Array<number>} 310 */ 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]); 314 }; 315 316 /** 317 * @constructor 318 * @struct 319 */ 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; 326 }; 327 328 /** 329 * @constructor 330 * @param {glsShaderRenderCase.QuadGrid} quadGrid_ 331 */ 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_; 341 342 /** @type {Array<glsShaderRenderCase.TextureBinding>} */ var bindings = this.quadGrid.getTextures(); 343 assertMsgOptions(bindings.length <= glsShaderRenderCase.MAX_TEXTURES, 'Too many bindings.', false, true); 344 345 // Fill in texture array. 346 for (var ndx = 0; ndx < bindings.length; ndx++) { 347 /** @type {glsShaderRenderCase.TextureBinding} */ var binding = bindings[ndx]; 348 349 this.textures[ndx] = new glsShaderRenderCase.ShaderSampler(); 350 351 if (binding.getType() == gluTexture.Type.TYPE_NONE) 352 continue; 353 354 this.textures[ndx].sampler = binding.getSampler(); 355 356 switch (binding.getType()) { 357 case gluTexture.Type.TYPE_2D: 358 this.textures[ndx].tex2D = binding.getBinding().getRefTexture(); 359 break; 360 case gluTexture.Type.TYPE_CUBE_MAP: 361 this.textures[ndx].texCube = binding.getBinding().getRefTexture(); 362 break; 363 case gluTexture.Type.TYPE_2D_ARRAY: 364 this.textures[ndx].tex2DArray = binding.getBinding().getRefTexture(); 365 break; 366 case gluTexture.Type.TYPE_3D: 367 this.textures[ndx].tex3D = binding.getBinding().getRefTexture(); 368 break; 369 default: 370 throw new Error("Binding type not supported"); 371 } 372 } 373 }; 374 375 /** 376 * @param {number} sx 377 * @param {number} sy 378 */ 379 glsShaderRenderCase.ShaderEvalContext.prototype.reset = function(sx, sy) { 380 // Clear old values 381 this.color = [0.0, 0.0, 0.0, 1.0]; 382 this.isDiscarded = false; 383 384 // Compute coords 385 this.coords = this.quadGrid.getCoords(sx, sy); 386 this.unitCoords = this.quadGrid.getUnitCoords(sx, sy); 387 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); 393 }; 394 395 glsShaderRenderCase.ShaderEvalContext.prototype.discard = function() { 396 this.isDiscarded = true; 397 }; 398 399 /** 400 * @param {number} unitNdx 401 * @param {Array<number>} coords 402 */ 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); 406 else 407 return [0.0, 0.0, 0.0, 1.0]; 408 }; 409 410 /** @param {glsShaderRenderCase.ShaderEvalContext} c */ 411 glsShaderRenderCase.evalCoordsPassthroughX = function(c) { 412 c.color[0] = c.coords[0]; 413 }; 414 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]; 420 }; 421 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]; 428 }; 429 430 /** @param {glsShaderRenderCase.ShaderEvalContext} c */ 431 glsShaderRenderCase.evalCoordsPassthrough = function(c) { 432 c.color = c.coords; 433 }; 434 435 /** @param {glsShaderRenderCase.ShaderEvalContext} c */ 436 glsShaderRenderCase.evalCoordsSwizzleWZYX = function(c) { 437 c.color = deMath.swizzle(c.coords, [3, 2, 1, 0]); 438 }; 439 440 /** 441 * @constructor 442 * @param {?glsShaderRenderCase.ShaderEvalFunc=} evalFunc 443 */ 444 glsShaderRenderCase.ShaderEvaluator = function(evalFunc) { 445 /** @type {?glsShaderRenderCase.ShaderEvalFunc} */ this.m_evalFunc = evalFunc || null; 446 }; 447 448 /** 449 * @param {glsShaderRenderCase.ShaderEvalContext} ctx 450 */ 451 glsShaderRenderCase.ShaderEvaluator.prototype.evaluate = function(ctx) { 452 assertMsgOptions(this.m_evalFunc !== null, 'No evaluation function specified.', false, true); 453 this.m_evalFunc(ctx); 454 }; 455 456 /** 457 * @constructor 458 * @extends {tcuTestCase.DeqpTest} 459 * @param {string} name 460 * @param {string} description 461 * @param {boolean} isVertexCase 462 * @param {glsShaderRenderCase.ShaderEvalFunc=} evalFunc 463 */ 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; 476 }; 477 478 /** 479 * @param {string} name 480 * @param {string} description 481 * @param {boolean} isVertexCase 482 * @param {glsShaderRenderCase.ShaderEvaluator} evaluator 483 * @return {glsShaderRenderCase.ShaderRenderCase} 484 */ 485 glsShaderRenderCase.ShaderRenderCase.newWithEvaluator = function(name, description, isVertexCase, evaluator) { 486 var renderCase = new glsShaderRenderCase.ShaderRenderCase(name, description, isVertexCase); 487 renderCase.m_evaluator = evaluator; 488 return renderCase; 489 }; 490 491 glsShaderRenderCase.ShaderRenderCase.prototype = Object.create(tcuTestCase.DeqpTest.prototype); 492 glsShaderRenderCase.ShaderRenderCase.prototype.constructor = glsShaderRenderCase.ShaderRenderCase; 493 494 glsShaderRenderCase.ShaderRenderCase.prototype.deinit = function() { 495 this.m_program = null; 496 }; 497 498 glsShaderRenderCase.ShaderRenderCase.prototype.init = function() { 499 this.postinit(); 500 }; 501 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(); 506 } 507 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)); 510 511 try { 512 bufferedLogToConsole(this.m_program.program.info.infoLog); // Always log shader program. 513 514 if (!this.m_program.isOk()) 515 throw new Error("Shader compile error."); 516 } 517 catch (exception) { 518 // Clean up. 519 this.deinit(); 520 throw exception; 521 } 522 }; 523 524 /** 525 * @return {tcuTestCase.IterateResult} 526 */ 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); 531 532 // Create quad grid. 533 /** @type {Array<number>} */ var viewportSize = this.getViewportSize(); 534 /** @type {number} */ var width = viewportSize[0]; 535 /** @type {number} */ var height = viewportSize[1]; 536 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); 542 543 // Render result. 544 /** @type {tcuSurface.Surface} */ var resImage = new tcuSurface.Surface(width, height); 545 this.render(resImage, programID, quadGrid); 546 547 // Compute reference. 548 /** @type {tcuSurface.Surface} */ var refImage = new tcuSurface.Surface(width, height); 549 if (this.m_isVertexCase) 550 this.computeVertexReference(refImage, quadGrid); 551 else 552 this.computeFragmentReference(refImage, quadGrid); 553 554 // Compare. 555 /** @type {boolean} */ var testOk = this.compareImages(resImage, refImage, 0.05); 556 557 // De-initialize. 558 gl.useProgram(null); 559 560 if (!testOk) 561 testFailedOptions("Fail", false); 562 else 563 testPassedOptions("Pass", true); 564 565 return tcuTestCase.IterateResult.STOP; 566 }; 567 568 /** 569 * @return {tcuTestCase.IterateResult} 570 */ 571 glsShaderRenderCase.ShaderRenderCase.prototype.iterate = function() { 572 return this.postiterate(); 573 }; 574 575 glsShaderRenderCase.ShaderRenderCase.prototype.setupShaderData = function() {}; 576 577 /** 578 * @param {?WebGLProgram} programId 579 */ 580 glsShaderRenderCase.ShaderRenderCase.prototype.setup = function(programId) {}; 581 582 /** 583 * @param {?WebGLProgram} programId 584 * @param {Array<number>} constCoords 585 */ 586 glsShaderRenderCase.ShaderRenderCase.prototype.setupUniforms = function(programId, constCoords) {}; 587 588 /** 589 * @return {Array<number>} 590 */ 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)]; 594 }; 595 596 /** 597 * @param {?WebGLProgram} programId 598 */ 599 glsShaderRenderCase.ShaderRenderCase.prototype.setupDefaultInputs = function(programId) { 600 // SETUP UNIFORMS. 601 glsShaderRenderCase.setupDefaultUniforms(programId); 602 603 // SETUP TEXTURES. 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; 609 610 if (tex.getType() === gluTexture.Type.TYPE_NONE) 611 continue; 612 613 switch (tex.getType()) { 614 case gluTexture.Type.TYPE_2D: 615 texTarget = gl.TEXTURE_2D; 616 texObj = tex.getBinding().getGLTexture(); 617 break; 618 case gluTexture.Type.TYPE_CUBE_MAP: 619 texTarget = gl.TEXTURE_CUBE_MAP; 620 texObj = tex.getBinding().getGLTexture(); 621 break; 622 case gluTexture.Type.TYPE_2D_ARRAY: 623 texTarget = gl.TEXTURE_2D_ARRAY; 624 texObj = tex.getBinding().getGLTexture(); 625 break; 626 case gluTexture.Type.TYPE_3D: 627 texTarget = gl.TEXTURE_3D; 628 texObj = tex.getBinding().getGLTexture(); 629 break; 630 default: 631 throw new Error("Type not supported"); 632 } 633 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)); 640 641 if (texTarget === gl.TEXTURE_3D) 642 gl.texParameteri(texTarget, gl.TEXTURE_WRAP_R, gluTextureUtil.getGLWrapMode(sampler.wrapR)); 643 644 if (sampler.compare != tcuTexture.CompareMode.COMPAREMODE_NONE) 645 { 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)); 648 } 649 } 650 }; 651 652 /** 653 * @param {tcuSurface.Surface} result 654 * @param {?WebGLProgram} programId 655 * @param {glsShaderRenderCase.QuadGrid} quadGrid 656 **/ 657 glsShaderRenderCase.ShaderRenderCase.prototype.render = function(result, programId, quadGrid) { 658 // Buffer info. 659 /** @type {number} */ var width = result.getWidth(); 660 /** @type {number} */ var height = result.getHeight(); 661 662 /** @type {number} */ var xOffsetMax = gl.drawingBufferWidth - width; 663 /** @type {number} */ var yOffsetMax = gl.drawingBufferHeight - height; 664 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); 667 668 /** @type {number} */ var xOffset = rnd.getInt(0, xOffsetMax); 669 /** @type {number} */ var yOffset = rnd.getInt(0, yOffsetMax); 670 671 gl.viewport(xOffset, yOffset, width, height); 672 673 // Setup program. 674 this.setupUniforms(programId, quadGrid.getConstCoords()); 675 this.setupDefaultInputs(programId); 676 677 // Clear. 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); 680 681 // Draw. 682 /** @type {Array<gluDrawUtil.VertexArrayBinding>} */ var vertexArrays = []; 683 /** @type {number} */ var numElements = quadGrid.getNumTriangles()*3; 684 685 glsShaderRenderCase.getDefaultVertexArrays(quadGrid, programId, vertexArrays); 686 687 gluDrawUtil.draw(gl, programId, vertexArrays, gluDrawUtil.triangles(quadGrid.getIndices())); 688 689 // Read back results. 690 result.readViewport(gl, [xOffset, yOffset, width, height]); 691 692 }; 693 694 /** 695 * @param {tcuSurface.Surface} result 696 * @param {glsShaderRenderCase.QuadGrid} quadGrid 697 **/ 698 glsShaderRenderCase.ShaderRenderCase.prototype.computeVertexReference = function(result, quadGrid) { 699 // Buffer info. 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); 715 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; 720 721 if (!hasAlpha) 722 color[3] = 1.0; 723 724 colors[vtxNdx] = color; 725 } 726 // Render quads. 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; 733 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); 740 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); 745 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]; 754 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); 759 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); 764 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))); 773 774 result.setPixel(ix, iy, glsShaderRenderCase.toRGBA(color).toIVec()); 775 } 776 } 777 }; 778 779 /** 780 * @param {tcuSurface.Surface} result 781 * @param {glsShaderRenderCase.QuadGrid} quadGrid 782 **/ 783 glsShaderRenderCase.ShaderRenderCase.prototype.computeFragmentReference = function(result, quadGrid) { 784 // Buffer info. 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); 789 790 // Render. 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; 795 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; 800 801 if (!hasAlpha) 802 color[3] = 1.0; 803 804 result.setPixel(x, y, glsShaderRenderCase.toRGBA(color).toIVec()); 805 } 806 }; 807 808 /** 809 * @param {tcuSurface.Surface} resImage 810 * @param {tcuSurface.Surface} refImage 811 * @param {number} errorThreshold 812 * @return {boolean} 813 */ 814 glsShaderRenderCase.ShaderRenderCase.prototype.compareImages = function(resImage, refImage, errorThreshold) { 815 return tcuImageCompare.fuzzyCompare("ComparisonResult", "Image comparison result", refImage.getAccess(), resImage.getAccess(), errorThreshold); 816 }; 817 818 /** 819 * @param {number} number 820 * @return {string} */ 821 glsShaderRenderCase.getIntUniformName = function(number) { 822 switch (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"; 833 default: 834 throw new Error("Uniform not supported."); 835 } 836 }; 837 838 /** 839 * @param {number} number 840 * @return {string} */ 841 glsShaderRenderCase.getFloatUniformName = function(number) { 842 switch (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"; 852 default: 853 throw new Error("Uniform not supported."); 854 } 855 }; 856 857 /** 858 * @param {number} number 859 * @return {string} */ 860 glsShaderRenderCase.getFloatFractionUniformName = function(number) { 861 switch (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"; 870 default: 871 throw new Error("Uniform not supported."); 872 } 873 }; 874 875 /** 876 * @param {?WebGLProgram} programID 877 */ 878 glsShaderRenderCase.setupDefaultUniforms = function(programID) { 879 /** @type {?WebGLUniformLocation} */ var uniLoc; 880 // Bool. 881 /** 882 * @constructor 883 * @struct 884 */ 885 var BoolUniform = function(name, value) { 886 /** @type {string} */ this.name = name; 887 /** @type {boolean} */ this.value = value; 888 }; 889 890 /** @type {Array<BoolUniform>} */ var s_boolUniforms = [ 891 new BoolUniform("ub_true", true), 892 new BoolUniform("ub_false", false) 893 ]; 894 895 for (var i = 0; i < s_boolUniforms.length; i++) { 896 uniLoc = gl.getUniformLocation(programID, s_boolUniforms[i].name); 897 if (uniLoc != null) 898 gl.uniform1i(uniLoc, s_boolUniforms[i].value ? 1 : 0); 899 } 900 901 // BVec4. 902 /** 903 * @constructor 904 * @struct 905 */ 906 var BVec4Uniform = function(name, value) { 907 /** @type {string} */ this.name = name; 908 /** @type {Array<boolean>} */ this.value = value; 909 }; 910 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]) 914 ]; 915 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); 924 if (uniLoc != null) 925 gl.uniform4iv(uniLoc, new Int32Array(arr)); 926 } 927 928 // Int. 929 /** 930 * @constructor 931 * @struct 932 */ 933 var IntUniform = function(name, value) { 934 /** @type {string} */ this.name = name; 935 /** @type {number} */ this.value = value; 936 }; 937 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) 950 ]; 951 952 for (var i = 0; i < s_intUniforms.length; i++) { 953 uniLoc = gl.getUniformLocation(programID, s_intUniforms[i].name); 954 if (uniLoc != null) 955 gl.uniform1i(uniLoc, s_intUniforms[i].value); 956 } 957 958 // IVec2. 959 /** 960 * @constructor 961 * @struct 962 */ 963 var IVec2Uniform = function(name, value) { 964 /** @type {string} */ this.name = name; 965 /** @type {Array<number>} */ this.value = value; 966 }; 967 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]) 975 ]; 976 977 for (var i = 0; i < s_ivec2Uniforms.length; i++) { 978 uniLoc = gl.getUniformLocation(programID, s_ivec2Uniforms[i].name); 979 if (uniLoc != null) 980 gl.uniform2iv(uniLoc, new Int32Array(s_ivec2Uniforms[i].value)); 981 } 982 983 // IVec3. 984 /** 985 * @constructor 986 * @struct 987 */ 988 var IVec3Uniform = function(name, value) { 989 /** @type {string} */ this.name = name; 990 /** @type {Array<number>} */ this.value = value; 991 }; 992 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]) 1000 ]; 1001 1002 for (var i = 0; i < s_ivec3Uniforms.length; i++) { 1003 uniLoc = gl.getUniformLocation(programID, s_ivec3Uniforms[i].name); 1004 if (uniLoc != null) 1005 gl.uniform3iv(uniLoc, new Int32Array(s_ivec3Uniforms[i].value)); 1006 } 1007 1008 // IVec4. 1009 /** 1010 * @constructor 1011 * @struct 1012 */ 1013 var IVec4Uniform = function(name, value) { 1014 /** @type {string} */ this.name = name; 1015 /** @type {Array<number>} */ this.value = value; 1016 }; 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]) 1024 ]; 1025 1026 for (var i = 0; i < s_ivec4Uniforms.length; i++) { 1027 uniLoc = gl.getUniformLocation(programID, s_ivec4Uniforms[i].name); 1028 if (uniLoc != null) 1029 gl.uniform4iv(uniLoc, new Int32Array(s_ivec4Uniforms[i].value)); 1030 } 1031 1032 // Float. 1033 /** 1034 * @constructor 1035 * @struct 1036 */ 1037 var FloatUniform = function(name, value) { 1038 /** @type {string} */ this.name = name; 1039 /** @type {number} */ this.value = value; 1040 }; 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) 1058 ]; 1059 1060 for (var i = 0; i < s_floatUniforms.length; i++) { 1061 uniLoc = gl.getUniformLocation(programID, s_floatUniforms[i].name); 1062 if (uniLoc != null) 1063 gl.uniform1f(uniLoc, s_floatUniforms[i].value); 1064 } 1065 1066 // Vec2. 1067 /** 1068 * @constructor 1069 * @struct 1070 */ 1071 var Vec2Uniform = function(name, value) { 1072 /** @type {string} */ this.name = name; 1073 /** @type {Array<number>} */ this.value = value; 1074 }; 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]) 1081 ]; 1082 1083 for (var i = 0; i < s_vec2Uniforms.length; i++) { 1084 uniLoc = gl.getUniformLocation(programID, s_vec2Uniforms[i].name); 1085 if (uniLoc != null) 1086 gl.uniform2fv(uniLoc, new Float32Array(s_vec2Uniforms[i].value)); 1087 } 1088 1089 // Vec3. 1090 /** 1091 * @constructor 1092 * @struct 1093 */ 1094 var Vec3Uniform = function(name, value) { 1095 /** @type {string} */ this.name = name; 1096 /** @type {Array<number>} */ this.value = value; 1097 }; 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]) 1104 ]; 1105 1106 for (var i = 0; i < s_vec3Uniforms.length; i++) { 1107 uniLoc = gl.getUniformLocation(programID, s_vec3Uniforms[i].name); 1108 if (uniLoc != null) 1109 gl.uniform3fv(uniLoc, new Float32Array(s_vec3Uniforms[i].value)); 1110 } 1111 1112 // Vec4. 1113 /** 1114 * @constructor 1115 * @struct 1116 */ 1117 var Vec4Uniform = function(name, value) { 1118 /** @type {string} */ this.name = name; 1119 /** @type {Array<number>} */ this.value = value; 1120 }; 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]) 1130 ]; 1131 1132 for (var i = 0; i < s_vec4Uniforms.length; i++) { 1133 uniLoc = gl.getUniformLocation(programID, s_vec4Uniforms[i].name); 1134 if (uniLoc != null) 1135 gl.uniform4fv(uniLoc, new Float32Array(s_vec4Uniforms[i].value)); 1136 } 1137 }; 1138 1139 /** 1140 * @param {glsShaderRenderCase.QuadGrid} quadGrid 1141 * @param {?WebGLProgram} program 1142 * @param {Array<gluDrawUtil.VertexArrayBinding>} vertexArrays 1143 */ 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()); 1149 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())); 1154 1155 // a_inN. 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)); 1160 } 1161 1162 // Matrix attributes - these are set by location 1163 /** 1164 * @constructor 1165 * @struct 1166 */ 1167 var Matrix = function(name, cols, rows) { 1168 this.name = name; 1169 this.numCols = cols; 1170 this.numRows = rows; 1171 }; 1172 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) 1183 ]; 1184 1185 for (var matNdx = 0; matNdx < matrices.length; matNdx++) { 1186 /** @type {number} */ var loc = gl.getAttribLocation(program, matrices[matNdx].name); 1187 1188 if (loc < 0) 1189 continue; // Not used in shader. 1190 1191 /** @type {number} */ var numRows = matrices[matNdx].numRows; 1192 /** @type {number} */ var numCols = matrices[matNdx].numCols; 1193 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)); 1197 } 1198 } 1199 }; 1200 });