OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2010, Google Inc. | 2 * Copyright 2010, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 | 55 |
56 /** | 56 /** |
57 * The number of elements. Non-zero for array types, zero for non-array | 57 * The number of elements. Non-zero for array types, zero for non-array |
58 * types. | 58 * types. |
59 * @type {number} | 59 * @type {number} |
60 */ | 60 */ |
61 this.numElements = numElements || 0; | 61 this.numElements = numElements || 0; |
62 | 62 |
63 /** | 63 /** |
64 * The semantic of the parameter. This is always in UPPERCASE. | 64 * The semantic of the parameter. This is always in UPPERCASE. |
65 * @type {o3d.Stream.Semantic} | 65 * @type {string} |
66 */ | 66 */ |
67 this.semantic = semantic || o3d.Stream.UNKNOWN_SEMANTIC; | 67 this.semantic = semantic || ''; |
68 | 68 |
69 /** | 69 /** |
70 * If this is a standard parameter (SAS) this will be the name of the type | 70 * If this is a standard parameter (SAS) this will be the name of the type |
71 * of Param needed. Otherwise it will be the empty string. | 71 * of Param needed. Otherwise it will be the empty string. |
72 * | 72 * |
73 * Standard Parameters are generally handled automatically by o3d but you | 73 * Standard Parameters are generally handled automatically by o3d but you |
74 * can supply your own if you have a unique situation. | 74 * can supply your own if you have a unique situation. |
75 * | 75 * |
76 * @type {string} | 76 * @type {string} |
77 */ | 77 */ |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
259 */ | 259 */ |
260 o3d.Effect.prototype.loadFromFXString = | 260 o3d.Effect.prototype.loadFromFXString = |
261 function(shaderString) { | 261 function(shaderString) { |
262 var splitIndex = shaderString.indexOf('// #o3d SplitMarker'); | 262 var splitIndex = shaderString.indexOf('// #o3d SplitMarker'); |
263 return this.loadVertexShaderFromString(shaderString.substr(0, splitIndex)) && | 263 return this.loadVertexShaderFromString(shaderString.substr(0, splitIndex)) && |
264 this.loadPixelShaderFromString(shaderString.substr(splitIndex)); | 264 this.loadPixelShaderFromString(shaderString.substr(splitIndex)); |
265 }; | 265 }; |
266 | 266 |
267 | 267 |
268 /** | 268 /** |
| 269 * Generates an array of indexed strings. For example, given 'arr' and a size |
| 270 * of 10, generates 'arr[0]', 'arr[1]', 'arr[2]' up to 'arr[9]'. |
| 271 * |
| 272 * @param {string} base The name of the array. |
| 273 * @param {number} size The number of elements in the array. |
| 274 * @return {!Array.<string>} |
| 275 * @private |
| 276 */ |
| 277 o3d.Effect.prototype.getParamArrayNames_ = function(base, size) { |
| 278 var names = []; |
| 279 for (var i = 0; i < size; i++) { |
| 280 names[i] = base + '[' + i + ']'; |
| 281 } |
| 282 return names; |
| 283 } |
| 284 |
| 285 |
| 286 /** |
269 * Iterates through the active uniforms of the program and gets the | 287 * Iterates through the active uniforms of the program and gets the |
270 * location of each one and stores them by name in the uniforms | 288 * location of each one and stores them by name in the uniforms |
271 * object. | 289 * object. |
272 * @private | 290 * @private |
273 */ | 291 */ |
274 o3d.Effect.prototype.getUniforms_ = | 292 o3d.Effect.prototype.getUniforms_ = |
275 function() { | 293 function() { |
276 this.uniforms_ = {}; | 294 this.uniforms_ = {}; |
277 var numUniforms = this.gl.getProgramParameter( | 295 var numUniforms = this.gl.getProgramParameter( |
278 this.program_, this.gl.ACTIVE_UNIFORMS); | 296 this.program_, this.gl.ACTIVE_UNIFORMS); |
279 for (var i = 0; i < numUniforms; ++i) { | 297 for (var i = 0; i < numUniforms; ++i) { |
280 var info = this.gl.getActiveUniform(this.program_, i); | 298 var info = this.gl.getActiveUniform(this.program_, i); |
281 this.uniforms_[info.name] = {info: info, | 299 if (info.name.indexOf('[') != -1) { |
282 location: this.gl.getUniformLocation(this.program_, info.name)}; | 300 // This is an array param and we need to individually query each item in |
| 301 // the array to get its location. |
| 302 var baseName = info.name.substring(0, info.name.indexOf('[')); |
| 303 var names = this.getParamArrayNames_(baseName, info.size); |
| 304 var locations = []; |
| 305 for (var j = 0; j < names.length; j++) { |
| 306 locations[j] = this.gl.getUniformLocation(this.program_, names[j]); |
| 307 } |
| 308 this.uniforms_[baseName] = { |
| 309 info: {name: baseName, size: info.size, type: info.type}, |
| 310 kind: o3d.Effect.ARRAY, |
| 311 locations: locations /* mind the s */ |
| 312 }; |
| 313 } else { |
| 314 // Not an array param. |
| 315 this.uniforms_[info.name] = { |
| 316 info: info, |
| 317 kind: o3d.Effect.ELEMENT, |
| 318 location: this.gl.getUniformLocation(this.program_, info.name) |
| 319 }; |
| 320 } |
283 } | 321 } |
284 }; | 322 }; |
285 | 323 |
286 | 324 |
287 /** | 325 /** |
288 * Iterates through the active attributes of the program and gets the | 326 * Iterates through the active attributes of the program and gets the |
289 * location of each one and stores them by name in the attributes | 327 * location of each one and stores them by name in the attributes |
290 * object. | 328 * object. |
291 * @private | 329 * @private |
292 */ | 330 */ |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 o3d.Effect.paramTypes_[gl.INT] = 'ParamInteger'; | 365 o3d.Effect.paramTypes_[gl.INT] = 'ParamInteger'; |
328 o3d.Effect.paramTypes_[gl.BOOL] = 'ParamBoolean'; | 366 o3d.Effect.paramTypes_[gl.BOOL] = 'ParamBoolean'; |
329 o3d.Effect.paramTypes_[gl.FLOAT_MAT4] = 'ParamMatrix4'; | 367 o3d.Effect.paramTypes_[gl.FLOAT_MAT4] = 'ParamMatrix4'; |
330 o3d.Effect.paramTypes_[gl.SAMPLER_2D] = 'ParamSampler'; | 368 o3d.Effect.paramTypes_[gl.SAMPLER_2D] = 'ParamSampler'; |
331 o3d.Effect.paramTypes_[gl.SAMPLER_CUBE] = 'ParamSampler'; | 369 o3d.Effect.paramTypes_[gl.SAMPLER_CUBE] = 'ParamSampler'; |
332 } | 370 } |
333 | 371 |
334 return o3d.Effect.paramTypes_; | 372 return o3d.Effect.paramTypes_; |
335 } | 373 } |
336 | 374 |
| 375 |
337 /** | 376 /** |
338 * A map linking names of certain attributes in the shader to the corresponding | 377 * A map linking names of certain attributes in the shader to the corresponding |
339 * semantic and semantic index. | 378 * semantic and semantic index. |
340 * @private | 379 * @private |
341 */ | 380 */ |
342 o3d.Effect.semanticMap_ = { | 381 o3d.Effect.semanticMap_ = { |
343 'position': {semantic: o3d.Stream.POSITION, index: 0, gl_index: 0}, | 382 'position': {semantic: o3d.Stream.POSITION, index: 0, gl_index: 0}, |
344 'normal': {semantic: o3d.Stream.NORMAL, index: 0, gl_index: 1}, | 383 'normal': {semantic: o3d.Stream.NORMAL, index: 0, gl_index: 1}, |
345 'tangent': {semantic: o3d.Stream.TANGENT, index: 0, gl_index: 2}, | 384 'tangent': {semantic: o3d.Stream.TANGENT, index: 0, gl_index: 2}, |
346 'binormal': {semantic: o3d.Stream.BINORMAL, index: 0, gl_index: 3}, | 385 'binormal': {semantic: o3d.Stream.BINORMAL, index: 0, gl_index: 3}, |
(...skipping 21 matching lines...) Expand all Loading... |
368 * depending on your application it may be more appropriate to pass in a | 407 * depending on your application it may be more appropriate to pass in a |
369 * Transform, Effect, Element or DrawElement. | 408 * Transform, Effect, Element or DrawElement. |
370 * | 409 * |
371 * @param {!o3d.ParamObject} param_object The param object on which the | 410 * @param {!o3d.ParamObject} param_object The param object on which the |
372 * new paramters will be created. | 411 * new paramters will be created. |
373 */ | 412 */ |
374 o3d.Effect.prototype.createUniformParameters = | 413 o3d.Effect.prototype.createUniformParameters = |
375 function(param_object) { | 414 function(param_object) { |
376 var sasTypes = o3d.Param.sasTypes_; | 415 var sasTypes = o3d.Param.sasTypes_; |
377 var paramTypes = o3d.Effect.getParamTypes_(this.gl); | 416 var paramTypes = o3d.Effect.getParamTypes_(this.gl); |
378 | |
379 for (var name in this.uniforms_) { | 417 for (var name in this.uniforms_) { |
380 var info = this.uniforms_[name].info; | 418 var uniformData = this.uniforms_[name]; |
381 if (!sasTypes[name]) { | 419 if (!sasTypes[name]) { |
382 param_object.createParam(info.name, paramTypes[info.type]); | 420 switch (uniformData.kind) { |
| 421 case o3d.Effect.ARRAY: |
| 422 param_object.createParam(name, 'ParamParamArray'); |
| 423 break; |
| 424 case o3d.Effect.STRUCT: |
| 425 o3d.notImplemented(); |
| 426 break; |
| 427 case o3d.Effect.ELEMENT: |
| 428 default: |
| 429 param_object.createParam(name, paramTypes[uniformData.info.type]); |
| 430 break; |
| 431 } |
383 } | 432 } |
384 } | 433 } |
385 }; | 434 }; |
386 | 435 |
387 | 436 |
388 /** | 437 /** |
389 * For each of the effect's uniform parameters, if it is a SAS parameter | 438 * For each of the effect's uniform parameters, if it is a SAS parameter |
390 * creates corresponding StandardParamMatrix4 parameters on the given | 439 * creates corresponding StandardParamMatrix4 parameters on the given |
391 * ParamObject. Note that SAS parameters are handled automatically by the | 440 * ParamObject. Note that SAS parameters are handled automatically by the |
392 * rendering system. so except in some rare cases there is no reason to call | 441 * rendering system. so except in some rare cases there is no reason to call |
(...skipping 22 matching lines...) Expand all Loading... |
415 | 464 |
416 | 465 |
417 /** | 466 /** |
418 * Gets info about the parameters this effect needs. | 467 * Gets info about the parameters this effect needs. |
419 * @return {!Array.<!o3d.EffectParameterInfo>} an array of | 468 * @return {!Array.<!o3d.EffectParameterInfo>} an array of |
420 * EffectParameterInfo objects. | 469 * EffectParameterInfo objects. |
421 */ | 470 */ |
422 o3d.Effect.prototype.getParameterInfo = function() { | 471 o3d.Effect.prototype.getParameterInfo = function() { |
423 var infoArray = []; | 472 var infoArray = []; |
424 var sasTypes = o3d.Param.sasTypes_; | 473 var sasTypes = o3d.Param.sasTypes_; |
| 474 var semanticMap = o3d.Effect.semanticMap_; |
425 var paramTypes = o3d.Effect.getParamTypes_(this.gl); | 475 var paramTypes = o3d.Effect.getParamTypes_(this.gl); |
426 var semanticMap = o3d.Effect.semanticMap_; | |
427 | 476 |
428 for (var name in this.uniforms_) { | 477 for (var name in this.uniforms_) { |
429 var info = this.uniforms_[name].info; | 478 var uniformData = this.uniforms_[name]; |
430 var sasTypeName = sasTypes[name] || ''; | 479 var sasClassName = sasTypes[name] || ''; |
431 var className = paramTypes[info.type] || ''; | 480 var dataType = paramTypes[uniformData.info.type] || ''; |
432 var numElements = 0; // TODO(petersont): Add array support. | 481 var numElements = (uniformData.kind == o3d.Effect.ARRAY) ? |
433 var semantic = (semanticMap[name] && semanticMap[name].semantic) ? | 482 uniformData.info.size : 0; // 0 if a non-array type. |
434 semanticMap[name].semantic : o3d.Stream.UNKNOWN_SEMANTIC; | 483 var semantic = semanticMap[name] ? name : ''; |
435 | |
436 infoArray.push(new o3d.EffectParameterInfo( | 484 infoArray.push(new o3d.EffectParameterInfo( |
437 name, className, numElements, semantic, sasTypeName)); | 485 name, dataType, numElements, semantic.toUpperCase(), sasClassName)); |
438 } | 486 } |
439 | 487 |
440 return infoArray; | 488 return infoArray; |
441 }; | 489 }; |
442 | 490 |
443 | 491 |
444 /** | 492 /** |
445 * Gets info about the streams this effect needs. | 493 * Gets info about the streams this effect needs. |
446 * @return {!Array.<!o3d.EffectStreamInfo>} an array of | 494 * @return {!Array.<!o3d.EffectStreamInfo>} an array of |
447 * EffectStreamInfo objects. | 495 * EffectStreamInfo objects. |
448 */ | 496 */ |
449 o3d.Effect.prototype.getStreamInfo = function() { | 497 o3d.Effect.prototype.getStreamInfo = function() { |
450 var infoList = []; | 498 var infoList = []; |
451 | 499 |
452 for (var name in this.attributes_) { | 500 for (var name in this.attributes_) { |
453 var semantic_index_pair = o3d.Effect.semanticMap_[name]; | 501 var semantic_index_pair = o3d.Effect.semanticMap_[name]; |
454 infoList.push(new o3d.EffectStreamInfo( | 502 infoList.push(new o3d.EffectStreamInfo( |
455 semantic_index_pair.semantic, semantic_index_pair.index)); | 503 semantic_index_pair.semantic, semantic_index_pair.index)); |
456 } | 504 } |
457 return infoList; | 505 return infoList; |
458 }; | 506 }; |
459 | 507 |
460 | 508 |
461 /** | 509 /** |
462 * Searches the objects in the given list for parameters to apply to the | 510 * Searches the objects in the given list for parameters to apply to the |
463 * uniforms defined on this effects program, and applies them, favoring | 511 * uniforms defined on this effects program, and applies them, favoring |
464 * the objects nearer the begining of the list. | 512 * the objects nearer the beginning of the list. |
465 * | 513 * |
466 * @param {!Array.<!o3d.ParamObject>} object_list The param objects to search. | 514 * @param {!Array.<!o3d.ParamObject>} object_list The param objects to search. |
467 * @private | 515 * @private |
468 */ | 516 */ |
469 o3d.Effect.prototype.searchForParams_ = function(object_list) { | 517 o3d.Effect.prototype.searchForParams_ = function(object_list) { |
470 var filled_map = {}; | 518 var filled_map = {}; |
471 for (var name in this.uniforms_) { | 519 for (var name in this.uniforms_) { |
472 filled_map[name] = false; | 520 filled_map[name] = false; |
473 } | 521 } |
474 this.gl.useProgram(this.program_); | 522 this.gl.useProgram(this.program_); |
475 o3d.Param.texture_index_ = 0; | 523 o3d.Param.texture_index_ = 0; |
476 for (var i = 0; i < object_list.length; ++i) { | 524 for (var i = 0; i < object_list.length; ++i) { |
477 var obj = object_list[i]; | 525 var obj = object_list[i]; |
478 for (var name in this.uniforms_) { | 526 for (var name in this.uniforms_) { |
479 var uniformInfo = this.uniforms_[name]; | 527 var uniformInfo = this.uniforms_[name]; |
480 if (filled_map[name]) { | 528 if (filled_map[name]) { |
481 continue; | 529 continue; |
482 } | 530 } |
483 var param = obj.getParam(name); | 531 var param = obj.getParam(name); |
484 if (param) { | 532 if (param) { |
485 param.applyToLocation(this.gl, uniformInfo.location); | 533 if (uniformInfo.kind == o3d.Effect.ARRAY) { |
| 534 param.applyToLocations(this.gl, uniformInfo.locations); |
| 535 } else { |
| 536 param.applyToLocation(this.gl, uniformInfo.location); |
| 537 } |
486 filled_map[name] = true; | 538 filled_map[name] = true; |
487 } | 539 } |
488 } | 540 } |
489 } | 541 } |
490 | 542 |
491 this.updateHelperConstants_(this.gl.displayInfo.width, | 543 this.updateHelperConstants_(this.gl.displayInfo.width, |
492 this.gl.displayInfo.height); | 544 this.gl.displayInfo.height); |
493 filled_map[o3d.Effect.HELPER_CONSTANT_NAME] = true; | 545 filled_map[o3d.Effect.HELPER_CONSTANT_NAME] = true; |
494 | |
495 for (var name in this.uniforms_) { | 546 for (var name in this.uniforms_) { |
496 if (!filled_map[name]) { | 547 if (!filled_map[name]) { |
497 throw ('Uniform param not filled: "'+ name + '"'); | 548 if (this.uniforms_[name].info.type == this.gl.SAMPLER_2D) { |
| 549 if (this.gl.client.reportErrors_()) { |
| 550 this.gl.client.error_callback("Missing ParamSampler"); |
| 551 } |
| 552 var defaultParamSampler = o3d.ParamSampler.defaultParamSampler_; |
| 553 defaultParamSampler.gl = this.gl; |
| 554 defaultParamSampler.applyToLocation(this.gl, |
| 555 this.uniforms_[name].location); |
| 556 } else { |
| 557 throw ('Uniform param not filled: "'+ name + '"'); |
| 558 } |
498 } | 559 } |
499 } | 560 } |
500 }; | 561 }; |
501 | 562 |
502 | 563 |
503 /** | 564 /** |
504 * Updates certain parameters used to make the GLSL shaders have the | 565 * Updates certain parameters used to make the GLSL shaders have the |
505 * same clipping semantics as D3D's. | 566 * same clipping semantics as D3D's. |
506 * @param {number} width width of the viewport in pixels | 567 * @param {number} width width of the viewport in pixels |
507 * @param {number} height height of the viewport in pixels | 568 * @param {number} height height of the viewport in pixels |
(...skipping 28 matching lines...) Expand all Loading... |
536 * MatrixLoadOrder, | 597 * MatrixLoadOrder, |
537 * ROW_MAJOR, Matrix parameters are loaded in row-major order (DX-style). | 598 * ROW_MAJOR, Matrix parameters are loaded in row-major order (DX-style). |
538 * COLUMN_MAJOR, Matrix parameters are loaded in column-major order | 599 * COLUMN_MAJOR, Matrix parameters are loaded in column-major order |
539 * (OpenGL-style). | 600 * (OpenGL-style). |
540 */ | 601 */ |
541 o3d.Effect.ROW_MAJOR = 0; | 602 o3d.Effect.ROW_MAJOR = 0; |
542 o3d.Effect.COLUMN_MAJOR = 1; | 603 o3d.Effect.COLUMN_MAJOR = 1; |
543 | 604 |
544 | 605 |
545 /** | 606 /** |
| 607 * UniformType, |
| 608 * ELEMENT, the param is a single gl.* element |
| 609 * ARRAY, the param is an array of same-typed elements |
| 610 * STRUCT, not implemented |
| 611 */ |
| 612 o3d.Effect.ELEMENT = 0; |
| 613 o3d.Effect.ARRAY = 1; |
| 614 o3d.Effect.STRUCT = 2; |
| 615 |
| 616 |
| 617 /** |
546 * The order in which matrix data is loaded to the GPU. | 618 * The order in which matrix data is loaded to the GPU. |
547 * @type {o3d.Effect.MatrixLoadOrder} | 619 * @type {o3d.Effect.MatrixLoadOrder} |
548 */ | 620 */ |
549 o3d.Effect.prototype.matrix_load_order_ = o3d.Effect.ROW_MAJOR; | 621 o3d.Effect.prototype.matrix_load_order_ = o3d.Effect.ROW_MAJOR; |
550 | 622 |
551 | 623 |
552 /** | 624 /** |
553 * The source for the shaders on this Effect. | 625 * The source for the shaders on this Effect. |
554 * @type {string} | 626 * @type {string} |
555 */ | 627 */ |
556 o3d.Effect.prototype.source_ = ''; | 628 o3d.Effect.prototype.source_ = ''; |
557 | |
558 | |
OLD | NEW |