| 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 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 117 o3d.EffectStreamInfo.prototype.semanticIndex = 0; | 117 o3d.EffectStreamInfo.prototype.semanticIndex = 0; |
| 118 | 118 |
| 119 | 119 |
| 120 /** | 120 /** |
| 121 * An Effect contains a vertex and pixel shader. | 121 * An Effect contains a vertex and pixel shader. |
| 122 * @constructor | 122 * @constructor |
| 123 */ | 123 */ |
| 124 o3d.Effect = function() { | 124 o3d.Effect = function() { |
| 125 o3d.ParamObject.call(this); | 125 o3d.ParamObject.call(this); |
| 126 this.program_ = null; | 126 this.program_ = null; |
| 127 this.uniforms_ = {}; |
| 128 this.attributes_ = {}; |
| 127 }; | 129 }; |
| 128 o3d.inherit('Effect', 'ParamObject'); | 130 o3d.inherit('Effect', 'ParamObject'); |
| 129 | 131 |
| 130 | 132 |
| 131 /** | 133 /** |
| 134 * An object mapping the names of uniform variables to objects containing |
| 135 * information about the variable. |
| 136 * @type {Object} |
| 137 * @private |
| 138 */ |
| 139 o3d.Effect.prototype.uniforms_ = {}; |
| 140 |
| 141 |
| 142 /** |
| 143 * An object mapping the names of attributes to objects containing |
| 144 * information about the attribute. |
| 145 * @type {Object} |
| 146 * @private |
| 147 */ |
| 148 o3d.Effect.prototype.attributes_ = {}; |
| 149 |
| 150 |
| 151 /** |
| 132 * Indicates whether the vertex shader has been loaded, so we can | 152 * Indicates whether the vertex shader has been loaded, so we can |
| 133 * postpone linking until both shaders are in. | 153 * postpone linking until both shaders are in. |
| 134 * | 154 * |
| 135 * @type {boolean} | 155 * @type {boolean} |
| 136 */ | 156 */ |
| 137 o3d.Effect.prototype.vertexShaderLoaded_ = false; | 157 o3d.Effect.prototype.vertexShaderLoaded_ = false; |
| 138 | 158 |
| 139 | 159 |
| 140 /** | 160 /** |
| 141 * Indicates whether the fragment shader has been loaded, so we can | 161 * Indicates whether the fragment shader has been loaded, so we can |
| 142 * postpone linking until both shaders are in. | 162 * postpone linking until both shaders are in. |
| 143 * | 163 * |
| 144 * @type {boolean} | 164 * @type {boolean} |
| 145 */ | 165 */ |
| 146 o3d.Effect.prototype.fragmentShaderLoaded_ = false; | 166 o3d.Effect.prototype.fragmentShaderLoaded_ = false; |
| 147 | 167 |
| 148 | 168 |
| 149 /** | 169 /** |
| 150 * Binds standard attribute locations for the shader. | 170 * Binds standard attribute locations for the shader. |
| 151 */ | 171 */ |
| 152 o3d.Effect.prototype.bindAttributesAndLinkIfReady = function() { | 172 o3d.Effect.prototype.bindAttributesAndLinkIfReady = function() { |
| 153 if (this.vertexShaderLoaded_ && this.fragmentShaderLoaded_) { | 173 if (this.vertexShaderLoaded_ && this.fragmentShaderLoaded_) { |
| 154 var attributes = ['position', 'normal', 'tangent', 'binormal', 'color', | 174 var attributes = ['position', 'normal', 'tangent', 'binormal', 'color', |
| 155 'texCoord0', 'texCoord1', 'texCoord2', 'texCoord3', | 175 'texCoord0', 'texCoord1', 'texCoord2', 'texCoord3', |
| 156 'texCoord4', 'texCoord5', 'texCoord6', 'texCoord7']; | 176 'texCoord4', 'texCoord5', 'texCoord6', 'texCoord7']; |
| 157 for (var i = 0; i < attributes.length; ++i) { | 177 for (var i = 0; i < attributes.length; ++i) { |
| 158 this.gl.bindAttribLocation(this.program_, i, attributes[i]); | 178 this.gl.bindAttribLocation(this.program_, i, attributes[i]); |
| 159 } | 179 } |
| 160 this.gl.linkProgram(this.program_); | 180 this.gl.linkProgram(this.program_); |
| 161 this.getAllUniforms(); | 181 this.getUniforms_(); |
| 182 this.getAttributes_(); |
| 162 } | 183 } |
| 163 }; | 184 }; |
| 164 | 185 |
| 165 | 186 |
| 166 /** | 187 /** |
| 167 * Helper function for loadVertexShaderFromString and | 188 * Helper function for loadVertexShaderFromString and |
| 168 * loadPixelShaderFromString that takes the type as an argument. | 189 * loadPixelShaderFromString that takes the type as an argument. |
| 169 * @param {string} shaderString The shader code. | 190 * @param {string} shaderString The shader code. |
| 170 * @param {number} type The type of the shader: either | 191 * @param {number} type The type of the shader: either |
| 171 * VERTEX_SHADER or FRAGMENT_SHADER. | 192 * VERTEX_SHADER or FRAGMENT_SHADER. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 */ | 227 */ |
| 207 o3d.Effect.prototype.loadPixelShaderFromString = | 228 o3d.Effect.prototype.loadPixelShaderFromString = |
| 208 function(shaderString) { | 229 function(shaderString) { |
| 209 this.loadShaderFromString(shaderString, this.gl.FRAGMENT_SHADER); | 230 this.loadShaderFromString(shaderString, this.gl.FRAGMENT_SHADER); |
| 210 this.fragmentShaderLoaded_ = true; | 231 this.fragmentShaderLoaded_ = true; |
| 211 this.bindAttributesAndLinkIfReady(); | 232 this.bindAttributesAndLinkIfReady(); |
| 212 }; | 233 }; |
| 213 | 234 |
| 214 | 235 |
| 215 /** | 236 /** |
| 237 * Loads a glsl vertex shader and pixel shader from one string. |
| 238 * Assumes the vertex shader and pixel shader are separated by |
| 239 * the text '// #o3d SplitMarker'. |
| 240 * @param {string} shaderString The string. |
| 241 */ |
| 242 o3d.Effect.prototype.loadFromFXString = |
| 243 function(shaderString) { |
| 244 var splitIndex = shaderString.indexOf('// #o3d SplitMarker'); |
| 245 this.loadVertexShaderFromString(shaderString.substr(0, splitIndex)); |
| 246 this.loadPixelShaderFromString(shaderString.substr(splitIndex)); |
| 247 }; |
| 248 |
| 249 |
| 250 /** |
| 216 * Iterates through the active uniforms of the program and gets the | 251 * Iterates through the active uniforms of the program and gets the |
| 217 * location of each one and stores them by name in the uniforms | 252 * location of each one and stores them by name in the uniforms |
| 218 * object. | 253 * object. |
| 254 * @private |
| 219 */ | 255 */ |
| 220 o3d.Effect.prototype.getAllUniforms = | 256 o3d.Effect.prototype.getUniforms_ = |
| 221 function() { | 257 function() { |
| 222 this.uniforms = {}; | 258 this.uniforms_ = {}; |
| 223 var numUniforms = this.gl.getProgramParameter( | 259 var numUniforms = this.gl.getProgramParameter( |
| 224 this.program_, this.gl.ACTIVE_UNIFORMS); | 260 this.program_, this.gl.ACTIVE_UNIFORMS); |
| 225 for (var i = 0; i < numUniforms; ++i) { | 261 for (var i = 0; i < numUniforms; ++i) { |
| 226 var info = this.gl.getActiveUniform(this.program_, i); | 262 var info = this.gl.getActiveUniform(this.program_, i); |
| 227 this.uniforms[info.name] = {info:info, | 263 this.uniforms_[info.name] = {info:info, |
| 264 location:this.gl.getUniformLocation(this.program_, info.name)}; |
| 265 } |
| 266 }; |
| 267 |
| 268 |
| 269 /** |
| 270 * Iterates through the active uniforms of the program and gets the |
| 271 * location of each one and stores them by name in the uniforms |
| 272 * object. |
| 273 * @private |
| 274 */ |
| 275 o3d.Effect.prototype.getAttributes_ = |
| 276 function() { |
| 277 this.attributes_ = {}; |
| 278 var numAttributes = this.gl.getProgramParameter( |
| 279 this.program_, this.gl.ACTIVE_ATTRIBUTES); |
| 280 for (var i = 0; i < numAttributes; ++i) { |
| 281 var info = this.gl.getActiveAttrib(this.program_, i); |
| 282 this.attributes_[info.name] = {info:info, |
| 228 location:this.gl.getUniformLocation(this.program_, info.name)}; | 283 location:this.gl.getUniformLocation(this.program_, info.name)}; |
| 229 } | 284 } |
| 230 }; | 285 }; |
| 231 | 286 |
| 232 | 287 |
| 233 /** | 288 /** |
| 234 * For each of the effect's uniform parameters, creates corresponding | 289 * For each of the effect's uniform parameters, creates corresponding |
| 235 * parameters on the given ParamObject. Skips SAS Parameters. | 290 * parameters on the given ParamObject. Skips SAS Parameters. |
| 236 * | 291 * |
| 237 * If a Param with the same name but the wrong type already exists on the | 292 * If a Param with the same name but the wrong type already exists on the |
| (...skipping 27 matching lines...) Expand all Loading... |
| 265 'worldViewTranspose': true, | 320 'worldViewTranspose': true, |
| 266 'worldProjectionTranspose': true, | 321 'worldProjectionTranspose': true, |
| 267 'worldViewProjectionTranspose': true, | 322 'worldViewProjectionTranspose': true, |
| 268 'worldInverseTranspose': true, | 323 'worldInverseTranspose': true, |
| 269 'viewInverseTranspose': true, | 324 'viewInverseTranspose': true, |
| 270 'projectionInverseTranspose': true, | 325 'projectionInverseTranspose': true, |
| 271 'worldViewInverseTranspose': true, | 326 'worldViewInverseTranspose': true, |
| 272 'worldProjectionInverseTranspose': true, | 327 'worldProjectionInverseTranspose': true, |
| 273 'worldViewProjectionInverseTranspose': true}; | 328 'worldViewProjectionInverseTranspose': true}; |
| 274 | 329 |
| 275 for (name in this.uniforms) { | 330 for (name in this.uniforms_) { |
| 276 var info = this.uniforms[name].info; | 331 var info = this.uniforms_[name].info; |
| 277 | 332 |
| 278 if (sasNames[name]) | 333 if (sasNames[name]) |
| 279 continue; | 334 continue; |
| 280 | 335 |
| 281 var paramType = ''; | 336 var paramType = ''; |
| 282 switch (info.type) { | 337 switch (info.type) { |
| 283 case this.gl.FLOAT: | 338 case this.gl.FLOAT: |
| 284 paramType = 'ParamFloat'; | 339 paramType = 'ParamFloat'; |
| 285 break; | 340 break; |
| 286 case this.gl.FLOAT_VEC2: | 341 case this.gl.FLOAT_VEC2: |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 return []; | 401 return []; |
| 347 }; | 402 }; |
| 348 | 403 |
| 349 | 404 |
| 350 /** | 405 /** |
| 351 * Gets info about the streams this effect needs. | 406 * Gets info about the streams this effect needs. |
| 352 * @return {!Array.<!o3d.EffectStreamInfo>} an array of | 407 * @return {!Array.<!o3d.EffectStreamInfo>} an array of |
| 353 * EffectStreamInfo objects. | 408 * EffectStreamInfo objects. |
| 354 */ | 409 */ |
| 355 o3d.Effect.prototype.getStreamInfo = function() { | 410 o3d.Effect.prototype.getStreamInfo = function() { |
| 356 var r = []; | 411 var infoList = []; |
| 357 // TODO(petersont): This is a stub, will remove later and replace with | |
| 358 // something that actually gets its streams from the shader. | |
| 359 var standard_semantic_index_pairs = [ | |
| 360 {semantic: o3d.Stream.POSITION, index: 0}, | |
| 361 {semantic: o3d.Stream.NORMAL, index: 0}, | |
| 362 {semantic: o3d.Stream.COLOR, index: 0}, | |
| 363 {semantic: o3d.Stream.TEXCOORD, index: 0} | |
| 364 ]; | |
| 365 | 412 |
| 366 for (var i = 0; i < standard_semantic_index_pairs.length; ++i) { | 413 for (var name in this.attributes_) { |
| 367 var p = standard_semantic_index_pairs[i]; | 414 var attributes = { |
| 368 r.push(new o3d.EffectStreamInfo(p.semantic, p.index)); | 415 'position': {semantic: o3d.Stream.POSITION, index: 0}, |
| 416 'normal': {semantic: o3d.Stream.NORMAL, index: 0}, |
| 417 'tangent': {semantic: o3d.Stream.TANGENT, index: 0}, |
| 418 'binormal': {semantic: o3d.Stream.BINORMAL, index: 0}, |
| 419 'color': {semantic: o3d.Stream.COLOR, index: 0}, |
| 420 'texCoord0': {semantic: o3d.Stream.TEXCOORD, index: 0}, |
| 421 'texCoord1': {semantic: o3d.Stream.TEXCOORD, index: 1}, |
| 422 'texCoord2': {semantic: o3d.Stream.TEXCOORD, index: 2}, |
| 423 'texCoord3': {semantic: o3d.Stream.TEXCOORD, index: 3}, |
| 424 'texCoord4': {semantic: o3d.Stream.TEXCOORD, index: 4}, |
| 425 'texCoord5': {semantic: o3d.Stream.TEXCOORD, index: 5}, |
| 426 'texCoord6': {semantic: o3d.Stream.TEXCOORD, index: 6}, |
| 427 'texCoord7': {semantic: o3d.Stream.TEXCOORD, index: 7}}; |
| 428 var semantic_index_pair = attributes[name]; |
| 429 infoList.push(new o3d.EffectStreamInfo( |
| 430 semantic_index_pair.semantic, semantic_index_pair.index)); |
| 369 } | 431 } |
| 370 return r; | 432 return infoList; |
| 371 }; | 433 }; |
| 372 | 434 |
| 373 | 435 |
| 374 /** | 436 /** |
| 375 * Searches the objects in the given list for parameters to apply to the | 437 * Searches the objects in the given list for parameters to apply to the |
| 376 * uniforms defined on this effects program, and applies them, favoring | 438 * uniforms defined on this effects program, and applies them, favoring |
| 377 * the objects nearer the begining of the list. | 439 * the objects nearer the begining of the list. |
| 378 * | 440 * |
| 379 * @param {!Array.<!o3d.ParamObject>} object_list The param objects to search. | 441 * @param {!Array.<!o3d.ParamObject>} object_list The param objects to search. |
| 442 * @private |
| 380 */ | 443 */ |
| 381 o3d.Effect.prototype.searchForParams = function(object_list) { | 444 o3d.Effect.prototype.searchForParams_ = function(object_list) { |
| 382 var filled_map = {}; | 445 var filled_map = {}; |
| 383 for (name in this.uniforms) { | 446 for (name in this.uniforms_) { |
| 384 filled_map[name] = false; | 447 filled_map[name] = false; |
| 385 } | 448 } |
| 386 this.gl.useProgram(this.program_); | 449 this.gl.useProgram(this.program_); |
| 450 o3d.Param.texture_index_ = 0; |
| 387 for (var i = 0; i < object_list.length; ++i) { | 451 for (var i = 0; i < object_list.length; ++i) { |
| 388 var obj = object_list[i]; | 452 var obj = object_list[i]; |
| 389 for (name in this.uniforms) { | 453 for (name in this.uniforms_) { |
| 390 var uniformInfo = this.uniforms[name]; | 454 var uniformInfo = this.uniforms_[name]; |
| 391 if (filled_map[name]) { | 455 if (filled_map[name]) { |
| 392 continue; | 456 continue; |
| 393 } | 457 } |
| 394 var param = obj.getParam(name); | 458 var param = obj.getParam(name); |
| 395 if (param) { | 459 if (param) { |
| 396 param.applyToLocation(this.gl, uniformInfo.location); | 460 param.applyToLocation(this.gl, uniformInfo.location); |
| 397 filled_map[name] = true; | 461 filled_map[name] = true; |
| 398 } | 462 } |
| 399 } | 463 } |
| 400 } | 464 } |
| 401 | 465 |
| 402 for (name in this.uniforms) { | 466 for (name in this.uniforms_) { |
| 403 if (!filled_map[name]) { | 467 if (!filled_map[name]) { |
| 404 throw ('Uniform param not filled: '+name); | 468 throw ('Uniform param not filled: '+name); |
| 405 } | 469 } |
| 406 } | 470 } |
| 407 }; | 471 }; |
| 408 | 472 |
| 409 | 473 |
| 410 /** | 474 /** |
| 411 * @type {number} | 475 * @type {number} |
| 412 */ | 476 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 429 o3d.Effect.prototype.matrix_load_order_ = o3d.Effect.ROW_MAJOR; | 493 o3d.Effect.prototype.matrix_load_order_ = o3d.Effect.ROW_MAJOR; |
| 430 | 494 |
| 431 | 495 |
| 432 /** | 496 /** |
| 433 * The source for the shaders on this Effect. | 497 * The source for the shaders on this Effect. |
| 434 * @type {string} | 498 * @type {string} |
| 435 */ | 499 */ |
| 436 o3d.Effect.prototype.source_ = ''; | 500 o3d.Effect.prototype.source_ = ''; |
| 437 | 501 |
| 438 | 502 |
| OLD | NEW |