1 /* 2 Copyright (c) 2008 Seneca College 3 Licenced under the MIT License (http://www.c3dl.org/index.php/mit-license/) 4 */ 5 6 /** 7 @class c3dl.Effect specifies exactly how a geometric object should 8 be rendered. An Effect is an instantiation of an EffectTemplate, which 9 is a template for creating effects with similar results. 10 11 <p> 12 Effects are composed of a vertex shader, fragment shader and a rendering 13 callback. The shaders perform the transformation, lighting calculations 14 and anything else necessary. The callback typically sets the uniform and 15 vertex attributes. 16 </p> 17 18 <p> 19 When the library is told to render an object which has an effect, it will first call 20 the rendering callback. This allows the user to do things such as toggle depth 21 tests, set the uniform variables, or adjust any other rendering state variables 22 required to perform the required rendering. The shader programs are then executed 23 and the object is rendered. 24 </p> 25 26 <p> 27 Some effect templates have already been written and using them requires minimal 28 effort. 29 <code><pre> 30 // c3dl.effects is a namespace which contains premade effects. 31 var effect = new c3dl.Effect(); 32 effect.init(c3dl.effects.GOOCH); 33 var teapot = c3dl.Collada(); 34 teapot.init('teapot.dae'); 35 // the effect's parameters were not set, so the default Gooch params 36 // will be used. 37 teapot.setEffect(effect); 38 </pre></code> 39 </p> 40 41 <p> 42 In the example above, none of the Gooch parameters were set, therefore 43 the default Gooch parameters are used. However, not all effects have 44 default parameters and therefore some need to be set. Wheather an effect 45 has default parameters is noted in c3dl.effects. 46 </p> 47 */ 48 c3dl.Effect = function() 49 { 50 // the effect this object is instantiating. 51 this.effectTemplate = null; 52 53 // these can be changed from the default ones created by the effect template. 54 this.instanceParams = []; 55 56 // prevent the effect from being initialized more than once. 57 this.isInitialized = false; 58 59 /** 60 Call this after the Effect has been created. Once the Effect has been 61 created and initialized, its parameters can be set. 62 63 @param {c3dl.EffectTemplate} effectTemplate 64 */ 65 this.init = function(effectTemplate) 66 { 67 //c3dl.debug.logWarning(effectTemplate); 68 69 var check = true; 70 71 if(check || effectTemplate instanceof c3dl.EffectTemplate) 72 { 73 // keep a reference to the template as it holds the shaders 74 // which will need to be compiled during rendering. 75 this.effectTemplate = effectTemplate; 76 77 // copy over the parameters which comprise of 78 // names, types and default values. 79 this.instanceParams = c3dl.copyObj(effectTemplate.getParameters()); 80 81 // prevent the Effect from being initialized more than once. 82 this.isInitialized = true; 83 } 84 else 85 { 86 c3dl.debug.logWarning("Invalid argument passed to c3dl.Effect's init()."); 87 } 88 } 89 90 /** 91 Get the EffectTemplate which was used to create this Effect. 92 93 @returns {c3dl.EffectTemplate} the effect template which was used to 94 create this effect. 95 */ 96 this.getEffectTemplate = function() 97 { 98 return this.effectTemplate; 99 } 100 101 /** 102 Get the value of the parameter 'paramName'. 103 104 @param {String} paramName 105 106 @returns the value of 'paramName' or null if parameter does not exist or 107 has not been set. 108 */ 109 this.getParameter = function(paramName) 110 { 111 var isFound = false; 112 var returnVal = null; 113 114 for(var i=0; i< this.instanceParams.length; i++) 115 { 116 if(this.instanceParams[i].name == paramName) 117 { 118 isFound = true; 119 returnVal = this.instanceParams[i].value; 120 } 121 } 122 123 if(!isFound) 124 { 125 c3dl.debug.logWarning("Effect getParameter(): '" + paramName + "' does not exist."); 126 } 127 128 return returnVal; 129 } 130 131 /** 132 Set the value of the parameter 'paramName' to 'paramvalue'. 133 134 @param {String} paramName Name of the parameter to set. 135 @param {} paramValue The value to set the parameter. 136 137 If the value does not match the parameter's type, a warning will 138 be displayed and the parameter will not be set. 139 */ 140 this.setParameter = function(paramName, paramValue) 141 { 142 // When the instance effect is initialized, all the default parameters from the effect 143 // are copied to the instance effect and then they can be changed with setParameter. 144 // Otherwise, there would be no place to store the values. 145 if(this.isInitialized == false) 146 { 147 c3dl.debug.logWarning("Effect must be initialized with init() " + 148 "before setting its parameters."); 149 } 150 else 151 { 152 var isFound = false; 153 154 for(var i=0; !isFound && i < this.instanceParams.length; i++) 155 { 156 if( paramName == this.instanceParams[i].name) 157 { 158 isFound = true; 159 160 // check if the value matches the parameter's type 161 if(paramValue.constructor == this.instanceParams[i].type) 162 { 163 this.instanceParams[i].value = paramValue; 164 } 165 else 166 { 167 // The value 'true' does not match parameter 'warmColor' type. 168 169 // The value 'true' cannot be assigned to parameter 'warmColor' 170 // because it is the incorrect type. Check the Effect documentation 171 // for the correct type. 172 c3dl.debug.logWarning( "The value '" + paramValue + "' cannot be assigned " + 173 "to parameter '" + paramName + "' because it is the " + 174 "incorrect type. Check the c3dl.effects documentation " + 175 " for the correct type."); 176 } 177 } 178 } 179 180 if(!isFound) 181 { 182 c3dl.debug.logWarning("Effect setParameter(): '" + paramName + "' does not exist."); 183 } 184 } 185 } 186 } 187