| 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 |