Fork me on GitHub

API Documentation


Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 675 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 675 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 747 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 747 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 760 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 760 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 798 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 798 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 835 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 847 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 852 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 874 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 877 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 880 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 883 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 886 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 889 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 892 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 895 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 898 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 901 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 910 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 914 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 918 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 918 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 928 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 928 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 938 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 938 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 941 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 941 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1001 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1001 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1003 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1003 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1003 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1003 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1003 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1003 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1048 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1048 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1063 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1074 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1108 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1108 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1184 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1184 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1230 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29

Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_material_glge_material.js.html, line: 1230 in /homepages/22/d163487924/htdocs/glge/wp-content/themes/glge/manual.php on line 29
  1 /*
  2 GLGE WebGL Graphics Engine
  3 Copyright (c) 2010, Paul Brunt
  4 All rights reserved.
  5 
  6 Redistribution and use in source and binary forms, with or without
  7 modification, are permitted provided that the following conditions are met:
  8     * Redistributions of source code must retain the above copyright
  9       notice, this list of conditions and the following disclaimer.
 10     * Redistributions in binary form must reproduce the above copyright
 11       notice, this list of conditions and the following disclaimer in the
 12       documentation and/or other materials provided with the distribution.
 13     * Neither the name of GLGE nor the
 14       names of its contributors may be used to endorse or promote products
 15       derived from this software without specific prior written permission.
 16 
 17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 18 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 20 DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
 21 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 22 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 23 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 24 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 25 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 27 */
 28 
 29 /**
 30  * @fileOverview
 31  * @name glge_material.js
 32  * @author me@paulbrunt.co.uk
 33  */
 34 
 35 
 36 (function(GLGE){
 37 
 38 
 39 
 40 
 41 var materialIdx=0;
 42 
 43 /**
 44 * @class The Material class creates materials to be applied to objects in the graphics engine
 45 * @see GLGE.Object
 46 * @augments GLGE.Animatable
 47 * @augments GLGE.QuickNotation
 48 * @augments GLGE.JSONLoader
 49 * @augments GLGE.Events
 50 */
 51 GLGE.Material=function(uid){
 52 	this.layers=[];
 53 	this.layerlisteners=[];
 54 	this.textures=[];
 55 	this.lights=[];
 56 	this.color={r:1,g:1,b:1,a:1};
 57 	this.specColor={r:1,g:1,b:1};
 58 	this.reflect=0.8;
 59 	this.shine=10;
 60 	this.specular=1;
 61 	this.emit={r:0,g:0,b:0};
 62 	this.alpha=1;
 63 	this.materialIdx=materialIdx++;
 64 	GLGE.Assets.registerAsset(this,uid);
 65 };
 66 GLGE.augment(GLGE.Animatable,GLGE.Material);
 67 GLGE.augment(GLGE.QuickNotation,GLGE.Material);
 68 GLGE.augment(GLGE.JSONLoader,GLGE.Material);
 69 GLGE.augment(GLGE.Events,GLGE.Material);
 70 
 71 
 72 /**
 73  * @name GLGE.Material#shaderupdate
 74  * @event fires when the shader for this material needs updating
 75  * @param {object} data
 76  */
 77  
 78  /**
 79  * @name GLGE.Material#downloadComplete
 80  * @event fires when all the assets for this material have finished loading
 81  * @param {object} data
 82  */
 83 
 84 /**
 85 * @constant 
 86 * @description Flag for material colour
 87 */
 88 GLGE.M_COLOR=1; 
 89 /**
 90 * @constant 
 91 * @description Flag for material normal
 92 */
 93 GLGE.M_NOR=2;
 94 /**
 95 * @constant 
 96 * @description Flag for material alpha
 97 */
 98 GLGE.M_ALPHA=4; 
 99 /**
100 * @constant 
101 * @description Flag for material specular color
102 */
103 GLGE.M_SPECCOLOR=8; 
104 /**
105 * @constant 
106 * @description Flag for material specular cvalue
107 */
108 GLGE.M_SPECULAR=16;
109 /**
110 * @constant 
111 * @description Flag for material shineiness
112 */
113 GLGE.M_SHINE=32; 
114 /**
115 * @constant 
116 * @description Flag for material reflectivity
117 */
118 GLGE.M_REFLECT=64;
119 /**
120 * @constant 
121 * @description Flag for material emision
122 */
123 GLGE.M_EMIT=128;
124 /**
125 * @constant 
126 * @description Flag for material alpha
127 */
128 GLGE.M_ALPHA=256;
129 /**
130 * @constant 
131 * @description Flag for masking with textures red value
132 */
133 GLGE.M_MSKR=512;
134 /**
135 * @constant 
136 * @description Flag for masking with textures green value
137 */
138 GLGE.M_MSKG=1024;
139 /**
140 * @constant 
141 * @description Flag for masking with textures blue value
142 */
143 GLGE.M_MSKB=2048;
144 /**
145 * @constant 
146 * @description Flag for masking with textures alpha value
147 */
148 GLGE.M_MSKA=4096;
149 /**
150 * @constant 
151 * @description Flag for mapping of the height in parallax mapping
152 */
153 GLGE.M_HEIGHT=8192;
154 
155 156 /**
157 * @constant 
158 * @description Flag for ambient mapping
159 */
160 GLGE.M_AMBIENT=16384;
161 
162 /**
163 * @constant 
164 * @description Flag for Steep parallax mapng
165 */
166 GLGE.M_STEEP=32768;
167 
168 /**
169 * @constant 
170 * @description Enumeration for first UV layer
171 */
172 GLGE.UV1=0;
173 /**
174 * @constant 
175 * @description Enumeration for second UV layer
176 */
177 GLGE.UV2=1;
178 /**
179 * @constant 
180 * @description Enumeration for normal texture coords
181 */
182 GLGE.MAP_NORM=3;
183 
184 /**
185 * @constant 
186 * @description Enumeration for object texture coords
187 */
188 GLGE.MAP_OBJ=4;
189 
190 /**
191 * @constant 
192 * @description Enumeration for reflection coords
193 */
194 GLGE.MAP_REF=5;
195 
196 /**
197 * @constant 
198 * @description Enumeration for environment coords
199 */
200 GLGE.MAP_ENV=6;
201 
202 /**
203 * @constant 
204 * @description Enumeration for view coords
205 */
206 GLGE.MAP_VIEW=7;
207 
208 /**
209 * @constant 
210 * @description Enumeration for point coords
211 */
212 GLGE.MAP_POINT=8;
213 
214 
215 /**
216 * @constant 
217 * @description Enumeration for mix blending mode
218 */
219 GLGE.BL_MIX=0;
220 
221 /**
222 * @constant 
223 * @description Enumeration for mix blending mode
224 */
225 GLGE.BL_MUL=1;
226 
227 
228 /**
229 * @constant 
230 * @description Enumeration for no use of vertex color
231 */
232 GLGE.VC_NONE=0;
233 
234 /**
235 * @constant 
236 * @description Enumeration for base vertex color mode
237 */
238 GLGE.VC_BASE=1;
239 
240 /**
241 * @constant 
242 * @description Enumeration for muliply vertex color mode
243 */
244 GLGE.VC_MUL=2;
245 
246 /**
247 * @constant 
248 * @description Enumeration for vertex color sets ambient lighting
249 */
250 GLGE.VC_AMB=3;
251 
252 /**
253 * @constant 
254 * @description Enumeration for vertex color multiplied by ambient lighting
255 */
256 GLGE.VC_AMBMUL=4;
257 
258 
259 	
260 GLGE.Material.prototype.layers=null;
261 GLGE.Material.prototype.className="Material";
262 GLGE.Material.prototype.textures=null;
263 GLGE.Material.prototype.color=null;
264 GLGE.Material.prototype.specColor=null;
265 GLGE.Material.prototype.specular=null;
266 GLGE.Material.prototype.emit={r:0,g:0,b:0};
267 GLGE.Material.prototype.shine=null;
268 GLGE.Material.prototype.reflect=null;
269 GLGE.Material.prototype.lights=null;
270 GLGE.Material.prototype.alpha=null;
271 GLGE.Material.prototype.ambient={r:0,g:0,b:0};
272 GLGE.Material.prototype.shadow=true;
273 GLGE.Material.prototype.shadeless=false;
274 GLGE.Material.prototype.downloadComplete=false;
275 GLGE.Material.prototype.vertexColorMode=GLGE.VC_BASE;
276 
277 
278 /**
279 * Sets the vertex color mode. Default is to override the base color VC_MUL will multiply the vertex color with the resulting color
280 * @param {boolean} value The vertex color mode
281 */
282 GLGE.Material.prototype.setVertexColorMode=function(value){
283 	this.vertexColorMode=value;
284 	this.fireEvent("shaderupdate",{});
285 	return this;
286 };
287 /**
288 * Gets the vertex color mode
289 * @returns {boolean} The vertex color mode
290 */
291 GLGE.Material.prototype.getVertexColorMode=function(value){
292 	return this.vertexColorMode;
293 };
294 
295 /**
296 * Sets the fall back material the material will be used if this one fails to produce a program
297 * @param {boolean} value The fallback material
298 */
299 GLGE.Material.prototype.setFallback=function(value){
300 	this.fallback=value;
301 	return this;
302 };
303 /**
304 * Gets the fallback material, if program fails then the fallback will be used
305 * @returns {boolean} The fallback material
306 */
307 GLGE.Material.prototype.getFallback=function(value){
308 	return this.fallback;
309 };
310 
311 /**
312 * Sets the flag indicateing if the material is shadeless
313 * @param {boolean} value The shadeless flag
314 */
315 GLGE.Material.prototype.setShadeless=function(value){
316 	this.shadeless=value;
317 	return this;
318 };
319 /**
320 * Gets the shadeless flag
321 * @returns {boolean} The shadeless flag
322 */
323 GLGE.Material.prototype.getShadeless=function(value){
324 	return this.shadeless;
325 };
326 /**
327 * Sets the flag indicateing the material should or shouldn't recieve shadows
328 * @param {boolean} value The recieving shadow flag
329 */
330 GLGE.Material.prototype.setShadow=function(value){
331 	this.shadow=value;
332 	return this;
333 };
334 /**
335 * gets the show flag
336 * @returns {boolean} The shadow flag
337 */
338 GLGE.Material.prototype.getShadow=function(value){
339 	return this.shadow;
340 };
341 /**
342 * Sets the base colour of the material
343 * @param {string} color The colour of the material
344 */
345 GLGE.Material.prototype.setColor=function(color){
346 	if(!color.r){
347 		color=GLGE.colorParse(color);
348 	}
349 	this.color={r:color.r,g:color.g,b:color.b};
350 	//this.fireEvent("shaderupdate",{});
351 	return this;
352 };
353 /**
354 * Sets the red base colour of the material
355 * @param {Number} r The new red level 0-1
356 */
357 GLGE.Material.prototype.setColorR=function(value){
358 	this.color={r:value,g:this.color.g,b:this.color.b,a:this.color.a};
359 	return this;
360 };
361 /**
362 * Sets the green base colour of the material
363 * @param {Number} g The new green level 0-1
364 */
365 GLGE.Material.prototype.setColorG=function(value){
366 	this.color={r:this.color.r,g:value,b:this.color.b,a:this.color.a};
367 	return this;
368 };
369 /**
370 * Sets the blue base colour of the material
371 * @param {Number} b The new blue level 0-1
372 */
373 GLGE.Material.prototype.setColorB=function(value){
374 	this.color={r:this.color.r,g:this.color.g,b:value,a:this.color.a};
375 	return this;
376 };
377 /**
378 * Gets the red base colour of the material
379 * @returns The red level 0-1
380 */
381 GLGE.Material.prototype.getColorR=function(value){
382 	return this.color.r;
383 };
384 /**
385 * Gets the green base colour of the material
386 * @returns The green level 0-1
387 */
388 GLGE.Material.prototype.getColorG=function(value){
389 	return this.color.g;
390 };
391 /**
392 * Gets the blue base colour of the material
393 * @returns The blue level 0-1
394 */
395 GLGE.Material.prototype.getColorB=function(value){
396 	return this.color.b;
397 };
398 /**
399 * Gets the current base color of the material
400 * @return {[r,g,b]} The current base color
401 */
402 GLGE.Material.prototype.getColor=function(){
403 	return this.color;
404 };
405 /**
406 * Sets the base specular colour of the material
407 * @param {string} color The new specular colour
408 */
409 GLGE.Material.prototype.setSpecularColor=function(color){
410 	if(!color.r){
411 		color=GLGE.colorParse(color);
412 	}
413 	this.specColor={r:parseFloat(color.r),g:parseFloat(color.g),b:parseFloat(color.b)};
414 	this.fireEvent("shaderupdate",{});
415 	return this;
416 };
417 /**
418 * Gets the ambient lighting of the material
419 * @return {[r,g,b]} The current ambient lighting
420 */
421 GLGE.Material.prototype.getAmbient=function(){
422 	return this.ambient;
423 };
424 
425 
426 /**
427 * Sets the ambient lighting of the material
428 * @param {string} color The new specular colour
429 */
430 GLGE.Material.prototype.setAmbient=function(color){
431 	if(!color.r){
432 		color=GLGE.colorParse(color);
433 	}
434 	this.ambient={r:parseFloat(color.r),g:parseFloat(color.g),b:parseFloat(color.b)};
435 	this.fireEvent("shaderupdate",{});
436 437 	return this;
438 };
439 /**
440 * Gets the current base specular color of the material
441 * @return {[r,g,b]} The current base specular color
442 */
443 GLGE.Material.prototype.getSpecularColor=function(){
444 	return this.specColor;
445 };
446 
447 
448 /**
449 * Sets the alpha of the material
450 * @param {Number} value how much alpha
451 */
452 GLGE.Material.prototype.setAlpha=function(value){
453 	this.alpha=value;
454 	return this;
455 };
456 /**
457 * Gets the alpha of the material
458 * @return {Number} The current alpha of the material
459 */
460 GLGE.Material.prototype.getAlpha=function(){
461 	return this.alpha;
462 };
463 /**
464 * Sets the specular of the material
465 * @param {Number} value how much specular
466 */
467 GLGE.Material.prototype.setSpecular=function(value){
468 	this.specular=value;
469 	this.fireEvent("shaderupdate",{});
470 	return this;
471 };
472 /**
473 * Gets the specular of the material
474 * @return {Number} The current specular of the material
475 */
476 GLGE.Material.prototype.getSpecular=function(){
477 	return this.specular;
478 };
479 /**
480 * Sets the shininess of the material
481 * @param {Number} value how much shine
482 */
483 GLGE.Material.prototype.setShininess=function(value){
484 	if (value<=0) value=0.001;
485 	this.shine=value;
486 	this.fireEvent("shaderupdate",{});
487 	return this;
488 };
489 /**
490 * Gets the shininess of the material
491 * @return {Number} The current shininess of the material
492 */
493 GLGE.Material.prototype.getShininess=function(){
494 	return this.shine;
495 };
496 /**
497 * Sets how much the material should emit
498 * @param {Number} color what color to emit
499 */
500 GLGE.Material.prototype.setEmit=function(color){
501 	if(color>0) color={r:color,g:color,b:color};
502 	if(!color.r){
503 		color=GLGE.colorParse(color);
504 	}
505 	this.emit={r:parseFloat(color.r),g:parseFloat(color.g),b:parseFloat(color.b)};
506 	this.fireEvent("shaderupdate",{});
507 	return this;
508 };
509 /**
510 * Sets how much the Red material should emit
511 * @param {Number} value what Red to emit
512 */
513 GLGE.Material.prototype.setEmitR=function(value){
514 	this.emit.r=parseFloat(value);
515 	return this;
516 };
517 /**
518 * Sets how much the green material should emit
519 * @param {Number} value what green to emit
520 */
521 GLGE.Material.prototype.setEmitG=function(value){
522 	this.emit.g=parseFloat(value);
523 	return this;
524 };
525 /**
526 * Sets how much the blue material should emit
527 * @param {Number} value what blue to emit
528 */
529 GLGE.Material.prototype.setEmitB=function(value){
530 	this.emit.b=parseFloat(value);
531 	return this;
532 };
533 /**
534 * Sets how much the Red material should emit
535 * @returns Red to emit
536 */
537 GLGE.Material.prototype.getEmitR=function(value){
538 	return this.emit.r;
539 };
540 /**
541 * Sets how much the green material should emit
542 * @returns green to emit
543 */
544 GLGE.Material.prototype.getEmitG=function(value){
545 	return this.emit.g;
546 };
547 /**
548 * Sets how much the blue material should emit
549 * @returns blue to emit
550 */
551 GLGE.Material.prototype.getEmitB=function(value){
552 	return this.emit.b;
553 };
554 
555 /**
556 * Gets the amount this material emits
557 * @return {Number} The emit value for the material
558 */
559 GLGE.Material.prototype.getEmit=function(){
560 	return this.emit;
561 };
562 /**
563 * Sets reflectivity of the material
564 * @param {Number} value how much to reflect (0-1)
565 */
566 GLGE.Material.prototype.setReflectivity=function(value){
567 	this.reflect=value;
568 	this.fireEvent("shaderupdate",{});
569 	return this;
570 };
571 /**
572 * Gets the materials reflectivity
573 * @return {Number} The reflectivity of the material
574 */
575 GLGE.Material.prototype.getReflectivity=function(){
576 	return this.reflect;
577 };
578 
579 /**
580 * Sets the material to output with 0 alpha or 1 alpha
581 * @param {boolean} value binary alpha flag
582 */
583 GLGE.Material.prototype.setBinaryAlpha=function(value){
584 	this.binaryAlpha=value;
585 	this.fireEvent("shaderupdate",{});
586 	return this;
587 };
588 /**
589 * Gets the binary alpha flag
590 * @return {boolean} The binary alpha flag
591 */
592 GLGE.Material.prototype.getBinaryAlpha=function(){
593 	return this.binaryAlpha;
594 };
595 
596 /**
597 * Add a new layer to the material
598 * @param {MaterialLayer} layer The material layer to add to the material
599 */
600 GLGE.Material.prototype.addMaterialLayer=function(layer){
601 	if(typeof layer=="string")  layer=GLGE.Assets.get(layer);
602 	this.layers.push(layer);
603 	var material=this;
604 	var listener=function(event){
605 		material.fireEvent("shaderupdate",{});
606 	};
607 	this.layerlisteners.push(listener);
608 	layer.addEventListener("shaderupdate",listener);
609 	this.fireEvent("shaderupdate",{});
610 	return this;
611 };
612 
613 /**
614 * Removes a layer from the material
615 * @param {MaterialLayer} layer The material layer to remove
616 */
617 GLGE.Material.prototype.removeMaterialLayer=function(layer){
618 	var idx=this.layers.indexOf(layer);
619 	if(idx>=0){
620 		this.layers.splice(idx,1);
621 		layer.removeEventListener("shaderupdate",this.layerlisteners[idx]);
622 		this.layerlisteners.splice(idx,1);
623 		this.fireEvent("shaderupdate",{});
624 	}
625 	return this;
626 };
627 
628 /**
629 * Gets all the materials layers
630 * @returns {GLGE.MaterialLayer[]} all of the layers contained within this material
631 */
632 GLGE.Material.prototype.getLayers=function(){
633 	return this.layers;
634 };
635 /**
636 * Generate the code required to calculate the texture coords for each layer
637 * @private
638 */
639 GLGE.Material.prototype.getLayerCoords=function(shaderInjection){
640 		var shader=[];
641 		shader.push("vec4 texturePos;\n"); 
642 		for(var i=0; i<this.layers.length;i++){
643 			shader.push("textureCoords"+i+"=vec3(0.0,0.0,0.0);\n"); 
644 			
645 			if(this.layers[i].mapinput==GLGE.UV1 || this.layers[i].mapinput==GLGE.UV2){
646 				shader.push("texturePos=vec4(vec2(UVCoord["+(this.layers[i].mapinput*2)+"],(1.0-UVCoord["+(this.layers[i].mapinput*2+1)+"])),1.0,1.0);\n");
647 			}
648 			
649 			if(this.layers[i].mapinput==GLGE.MAP_NORM){
650 				shader.push("texturePos=vec4(normalize(n.xyz),1.0);\n");
651 			}
652 			if(this.layers[i].mapinput==GLGE.MAP_OBJ){
653 				shader.push("texturePos=vec4(normalize(OBJCoord.xyz),1.0);\n");
654 			}
655 			
656 			if(this.layers[i].mapinput==GLGE.MAP_REF){
657 				//will need to do in fragment to take the normal maps into account!
658 				shader.push("texturePos=vec4(reflect(normalize(eyevec.xyz),normalize(n.xyz)),1.0);\n");
659 			}
660 			
661 
662 			
663 			if(this.layers[i].mapinput==GLGE.MAP_ENV){
664 				//will need to do in fragment to take the normal maps into account!
665 				shader.push("texturePos=envMat * vec4(reflect(normalize(eyevec.xyz),normalize(n.xyz)),1.0);\n");
666 			}
667 			
668 			shader.push("textureCoords"+i+"=(layer"+i+"Matrix * texturePos).xyz;\n");
669 
670 			if(shaderInjection && ~shaderInjection.indexOf("GLGE_Texcoord")){
671 				shader.push("textureCoords"+i+"=GLGE_Texcoord("+i+",textureCoords"+i+");\n");
672 			}
673 			
674 		}
675 		
676 		return shader.join("");
677 }
678 /**
679 * Generate the fragment shader program for this material
680 * @private
681 */
682 GLGE.Material.prototype.getVertexVarying=function(){
683 	var shader=[];
684 	for(var i=0; i<this.layers.length;i++){
685 		shader.push("uniform mat4 layer"+i+"Matrix;\n");  
686 		shader.push("varying vec3 textureCoords"+i+";\n"); 
687 	}
688 	return shader.join("");
689 }
690 
691 GLGE.Material.prototype.registerPasses=function(gl,object){
692 	for(var i=0; i<this.textures.length;i++){
693 		if(this.textures[i].registerPasses) this.textures[i].registerPasses(gl,object);
694 	}
695 }
696 
697 /**
698 * Generate the fragment shader program for this material
699 * @private
700 */
701 GLGE.Material.prototype.getFragmentShader=function(lights,colors,shaderInjection){
702 	var shader="#ifdef GL_ES\nprecision mediump float;\n#endif\n#define GLGE_FRAGMENT\n";
703 	if(shaderInjection) shader+=shaderInjection;
704 	var tangent=false;
705 	for(var i=0; i<lights.length;i++){
706 		if(lights[i].type==GLGE.L_POINT || lights[i].type==GLGE.L_SPOT || lights[i].type==GLGE.L_DIR){
707 			shader=shader+"varying vec3 lightvec"+i+";\n"; 
708 			shader=shader+"varying float lightdist"+i+";\n";  
709 		}
710 	}
711 	shader=shader+"varying vec3 n;\n";  
712 	shader=shader+"varying vec3 t;\n";  
713 	shader=shader+"varying vec4 UVCoord;\n";
714 	shader=shader+"varying vec3 eyevec;\n"; 
715 	shader=shader+"varying vec3 OBJCoord;\n";
716 	if(colors) shader=shader+"varying vec4 vcolor;\n";
717 	 shader=shader+"uniform sampler2D sky;\n";
718 	//texture uniforms
719 	for(var i=0; i<this.textures.length;i++){
720 		if(this.textures[i].className=="Texture") shader=shader+"uniform sampler2D TEXTURE"+i+";\n";
721 		if(this.textures[i].className=="TextureCanvas") shader=shader+"uniform sampler2D TEXTURE"+i+";\n";
722 		if(this.textures[i].className=="TextureVideo") shader=shader+"uniform sampler2D TEXTURE"+i+";\n";
723 		if(this.textures[i].className=="TextureCube") shader=shader+"uniform samplerCube TEXTURE"+i+";\n";
724 	}
725 	
726 	var cnt=1;
727 	var shadowlights=[];
728 	var num;
729 	for(var i=0; i<lights.length;i++){
730 	    if(lights[i].type==GLGE.L_OFF) continue;
731 			shader=shader+"uniform vec3 lightcolor"+i+";\n";  
732 			shader=shader+"uniform vec3 lightAttenuation"+i+";\n";  
733 			shader=shader+"uniform float spotCosCutOff"+i+";\n";  
734 			shader=shader+"uniform float spotExp"+i+";\n";  
735 			shader=shader+"uniform vec3 lightdir"+i+";\n";  
736 			shader=shader+"uniform mat4 lightmat"+i+";\n";
737 			shader=shader+"uniform float shadowbias"+i+";\n"; 
738 			shader=shader+"uniform int shadowsamples"+i+";\n";  
739 			shader=shader+"uniform float shadowsoftness"+i+";\n";  
740 			shader=shader+"uniform bool castshadows"+i+";\n";  
741 			shader=shader+"uniform vec2 shadowoffset"+i+";\n";  
742 			if(lights[i].getCastShadows() && this.shadow){
743 				shader=shader+"varying vec4 spotcoord"+i+";\n";  
744 				num=this.textures.length+(cnt++);
745 				shader=shader+"uniform sampler2D TEXTURE"+num+";\n";
746 				shadowlights[i]=num;
747 			}
748 	}
749 	for(i=0; i<this.layers.length;i++){		
750 		shader=shader+"varying vec3 textureCoords"+i+";\n";
751 		shader=shader+"uniform float layeralpha"+i+";\n";
752 		if(this.layers[i].mapinput==GLGE.MAP_VIEW){
753 			shader=shader+"uniform mat4 layer"+i+"Matrix;\n";
754 		}
755 		if((this.layers[i].mapto & GLGE.M_HEIGHT) == GLGE.M_HEIGHT || (this.layers[i].mapto & GLGE.M_STEEP) == GLGE.M_STEEP){
756 			shader=shader+"uniform float layerheight"+i+";\n";
757 		}
758 	}
759 	
760 	shader=shader+"uniform vec4 baseColor;\n";
761 	shader=shader+"uniform vec3 specColor;\n";
762 	shader=shader+"uniform float shine;\n";
763 	shader=shader+"uniform float specular;\n";
764 	shader=shader+"uniform float reflective;\n";
765 	shader=shader+"uniform vec3 emit;\n";
766 	shader=shader+"uniform float alpha;\n";
767 	shader=shader+"uniform vec3 amb;\n";
768 	shader=shader+"uniform float fognear;\n";
769 	shader=shader+"uniform float fogfar;\n";
770 	shader=shader+"uniform int fogtype;\n";
771 	shader=shader+"uniform vec3 fogcolor;\n";
772 	shader=shader+"uniform float far;\n";
773 	shader=shader+"uniform mat4 worldInverseTranspose;\n"; 
774     shader=shader+"uniform mat4 projection;\n"; 
775     shader=shader+"uniform bool emitpass;\n"; 
776     shader=shader+"uniform bool shadeless;\n"; 
777     
778 	shader=shader+"void main(void)\n";
779 	shader=shader+"{\n";
780 	shader=shader+"float att;\n"; 
781 	shader=shader+"int texture;\n"; 
782 	shader=shader+"float mask=1.0;\n";
783 	shader=shader+"float spec=specular;\n"; 
784 	shader=shader+"vec3 specC=specColor;\n"; 
785 	shader=shader+"vec4 view;\n"; 
786 	shader=shader+"vec3 textureCoords=vec3(0.0,0.0,0.0);\n"; 
787 	shader=shader+"float ref=reflective;\n";
788 	shader=shader+"float sh=shine;\n"; 
789 	shader=shader+"vec3 em=emit;\n"; 
790 	shader=shader+"float al=alpha;\n"; 
791 	shader=shader+"vec3 amblight=amb;\n"; 
792 	shader=shader+"vec4 normalmap= vec4(n,0.0);\n"
793 	if(colors && this.vertexColorMode==GLGE.VC_BASE){
794 		shader=shader+"vec4 color= vcolor;";
795 		shader=shader+"al = vcolor.a;";
796 	}else{
797 		shader=shader+"vec4 color = baseColor;"; //set the initial color
798 	}
799 	shader=shader+"float pheight=0.0;\n"
800 	shader=shader+"vec3 textureHeight=vec3(0.0,0.0,0.0);\n";
801 	shader=shader+"vec3 normal = normalize(n);\n";
802 	shader=shader+"vec3 b = vec3(0.0,0.0,0.0);\n";
803 	var diffuseLayer=0;
804 	var anyAlpha=false;
805 	for(i=0; i<this.layers.length;i++){
806 		
807 		shader=shader+"textureCoords=textureCoords"+i+"+textureHeight;\n";
808 		shader=shader+"mask=layeralpha"+i+"*mask;\n";
809 		
810 		if(this.layers[i].mapinput==GLGE.MAP_VIEW){
811 			shader=shader+"view=projection * vec4(-eyevec,1.0);\n";
812 			shader=shader+"textureCoords=view.xyz/view.w*0.5+0.5;\n";
813 			shader=shader+"textureCoords=(layer"+i+"Matrix*vec4(textureCoords,1.0)).xyz+textureHeight;\n";
814 		}
815     	
816 		if(this.layers[i].mapinput==GLGE.MAP_POINT){
817 			shader=shader+"textureCoords=vec3(gl_PointCoord,1.0);\n";
818 		}
819     	
820         
821 			
822 		if(this.layers[i].getTexture().className=="Texture" || this.layers[i].getTexture().className=="TextureCanvas"  || this.layers[i].getTexture().className=="TextureVideo" ){
823 			var txcoord="xy";
824 			var sampletype="2D";
825 		}else{
826 			var txcoord="xyz";
827 			var sampletype="Cube";
828 		}
829 		
830 		if((this.layers[i].mapto & GLGE.M_COLOR) == GLGE.M_COLOR){			
831 			diffuseLayer=i;
832 			
833 			if(this.layers[i].blendMode==GLGE.BL_MUL){
834 				shader=shader+"color = color*(1.0-mask) + color*texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+")*mask;\n";
835 			}
836 			else 
837 			{
838 				shader=shader+"color = color*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+")*mask;\n";
839 			}
840 		}        
841 		
842 		if((this.layers[i].mapto & GLGE.M_HEIGHT) == GLGE.M_HEIGHT){
843 			//do paralax stuff
844 			shader=shader+"pheight = texture2D(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").x;\n";
845 			shader=shader+"textureHeight =vec3((layerheight"+i+"* (pheight-0.5)  * normalize(eyevec).xy*vec2(1.0,-1.0)),0.0);\n";
846 		}
847 		if((this.layers[i].mapto & GLGE.M_STEEP) == GLGE.M_STEEP){
848 			shader=shader+"b=normalize(cross(t.xyz,n));\n";
849 			shader=shader+"vec3 neye=normalize(eyevec.xyz);"
850 			shader=shader+"neye = vec3(dot(neye,t),dot(neye,b),dot(neye,n));";
851 			shader=shader+"neye = normalize(neye);";
852 			shader=shader+"float stepheight"+i+"=layerheight"+i+";";
853 			
854 			shader=shader+"float steepstep"+i+"=(1.0/8.0)*stepheight"+i+"/neye.z;";
855 			shader=shader+"float steepdisplace"+i+"=0.0;";
856 
857 			shader=shader+"for(int steepcount"+i+"=0;steepcount"+i+"<8;steepcount"+i+"++){";
858 			shader=shader+"pheight = texture2D(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+"+vec2(neye.x,neye.y)*steepdisplace"+i+").x;\n";
859 			shader=shader+"if(pheight*stepheight"+i+">neye.z*steepdisplace"+i+"){";
860 			shader=shader+"textureHeight=vec3(vec2(neye.x,neye.y)*steepdisplace"+i+",0.0);";
861 			shader=shader+"}else{";
862 			shader=shader+"steepdisplace"+i+"-=steepstep"+i+";";
863 			shader=shader+"steepstep"+i+"*=0.5;";
864 			shader=shader+"}";
865 			shader=shader+"steepdisplace"+i+"+=steepstep"+i+";";
866 
867 			shader=shader+"}";
868 		}
869 		if((this.layers[i].mapto & GLGE.M_SPECCOLOR) == GLGE.M_SPECCOLOR){
870 			shader=shader+"specC = specC*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
871 		}
872 		if((this.layers[i].mapto & GLGE.M_MSKR) == GLGE.M_MSKR){
873 			shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").r;\n";
874 		}
875 		if((this.layers[i].mapto & GLGE.M_MSKG) == GLGE.M_MSKG){
876 			shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").g;\n";
877 		}
878 		if((this.layers[i].mapto & GLGE.M_MSKB) == GLGE.M_MSKB){
879 			shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").b;\n";
880 		}
881 		if((this.layers[i].mapto & GLGE.M_MSKA) == GLGE.M_MSKA){
882 			shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").a;\n";
883 		}
884 		if((this.layers[i].mapto & GLGE.M_SPECULAR) == GLGE.M_SPECULAR){
885 			shader=shader+"spec = spec*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").r*mask;\n";
886 		}
887 		if((this.layers[i].mapto & GLGE.M_REFLECT) == GLGE.M_REFLECT){
888 			shader=shader+"ref = ref*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").g*mask;\n";
889 		}
890 		if((this.layers[i].mapto & GLGE.M_SHINE) == GLGE.M_SHINE){
891 			shader=shader+"sh = sh*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").b*mask*255.0;\n";
892 		}
893 		if((this.layers[i].mapto & GLGE.M_EMIT) == GLGE.M_EMIT){
894 			shader=shader+"em = em*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
895 		}
896 		if((this.layers[i].mapto & GLGE.M_NOR) == GLGE.M_NOR){
897 			shader=shader+"normalmap = normalmap*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+")*mask;\n";
898 			shader=shader+"normal = normalmap.rgb;\n";
899 			shader=shader+"normal = 2.0*(vec3(normal.r, -normal.g, normal.b) - vec3(0.5, -0.5, 0.5));";
900 			shader=shader+"b=normalize(cross(t.xyz,n));\n";
901 			shader=shader+"normal = normal.x*t + normal.y*b + normal.z*n;";
902 			shader=shader+"normal = normalize(normal);";
903 			
904 		}
905 		if((this.layers[i].mapto & GLGE.M_ALPHA) == GLGE.M_ALPHA){
906 			anyAlpha=true;
907 			shader=shader+"al = al*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").a*mask;\n";
908 		}
909 910 		if((this.layers[i].mapto & GLGE.M_AMBIENT) == GLGE.M_AMBIENT){
911 			shader=shader+"amblight = amblight*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
912 		}
913 	}		
914 	if (!anyAlpha && this.layers.length) {
915 		if(this.layers[diffuseLayer].getTexture().className=="Texture" || this.layers[diffuseLayer].getTexture().className=="TextureCanvas"  || this.layers[diffuseLayer].getTexture().className=="TextureVideo" ) {
916 			var txcoord="xy";
917 			var sampletype="2D";
918 		}else{
919 			var txcoord="xyz";
920 			var sampletype="Cube";
921 		}
922 		shader=shader+"al = al*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[diffuseLayer].texture.idx+", textureCoords."+txcoord+").a*al*mask;\n";        
923 	}
924 	if(colors && this.vertexColorMode==GLGE.VC_MUL){
925 		shader=shader+"color *= vcolor;";
926 	}
927 	if(this.binaryAlpha) {
928 		shader=shader+"if(al<0.5) discard;\n";
929 		shader=shader+"al=1.0;\n";
930 	}else{
931 		shader=shader+"if(al==0.0) discard;\n";
932 	}
933 	shader=shader+"vec3 lightvalue=amblight;\n"; 
934 	if(colors && this.vertexColorMode==GLGE.VC_AMB){
935 		shader=shader+"lightvalue = vcolor.rgb;";
936 	}
937 	if(colors && this.vertexColorMode==GLGE.VC_AMBMUL){
938 		shader=shader+"lightvalue *= vcolor.rgb;";
939 	}
940 	
941 	shader=shader+"float dotN,spotEffect;";
942 	shader=shader+"vec3 lightvec=vec3(0.0,0.0,0.0);";
943 	shader=shader+"vec3 viewvec=vec3(0.0,0.0,0.0);";
944 	shader=shader+"vec3 specvalue=vec3(0.0,0.0,0.0);";
945 	shader=shader+"vec2 scoord=vec2(0.0,0.0);";
946 	shader=shader+"float sDepth=0.0;";
947 	shader=shader+"float spotmul=0.0;";
948 	shader=shader+"float rnd=0.0;";
949 	shader=shader+"float spotsampleX=0.0;";
950 	shader=shader+"float spotsampleY=0.0;";
951 	shader=shader+"float totalweight=0.0;";
952 	shader=shader+"int cnt=0;";
953 	shader=shader+"float specularSmoothStepValue=.125;\n";
954 	shader=shader+"vec2 spotoffset=vec2(0.0,0.0);";
955 	shader=shader+"float dp=0.0;";
956 	
957 	shader=shader+"vec4 dist;float depth,m1,m2,prob,variance;\n";
958 	shader=shader+"if (normal.z<0.0) {normal.z=0.0;}\n";
959 	
960     
961     shader=shader+"float fogfact=1.0;";
962     shader=shader+"if(fogtype=="+GLGE.FOG_QUADRATIC+" || fogtype=="+GLGE.FOG_SKYQUADRATIC+") fogfact=clamp(pow(max((fogfar - length(eyevec)) / (fogfar - fognear),0.0),2.0),0.0,1.0);\n";
963     shader=shader+"if(fogtype=="+GLGE.FOG_LINEAR+" || fogtype=="+GLGE.FOG_SKYLINEAR+") fogfact=clamp((fogfar - length(eyevec)) / (fogfar - fognear),0.0,1.0);\n";
964     
965     
966     shader=shader+"if (emitpass) {gl_FragColor=vec4(em,1.0);} else if (shadeless) {\n";
967      shader=shader+"gl_FragColor=vec4(color.rgb,al);\n";
968     shader=shader+"} else {\n";
969     
970 	for(var i=0; i<lights.length;i++){
971 	    if(lights[i].type==GLGE.L_OFF) continue;
972 		shader=shader+"lightvec=lightvec"+i+";\n";  
973 		shader=shader+"viewvec=eyevec;\n"; 
974 		
975 		
976 		if(lights[i].type==GLGE.L_POINT){ 
977 			shader=shader+"dotN=max(dot(normal,normalize(-lightvec)),0.0);\n";       
978 			shader=shader+"att = 1.0 / (lightAttenuation"+i+"[0] + lightAttenuation"+i+"[1] * lightdist"+i+" + lightAttenuation"+i+"[2] * lightdist"+i+" * lightdist"+i+");\n";
979 980 			shader=shader+"if(dotN>0.0){\n";
981 			if(lights[i].diffuse){
982 				shader=shader+"lightvalue += att * dotN * lightcolor"+i+";\n";
983 			}
984 			shader=shader+"}\n";
985 			if(lights[i].specular){
986 				shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN)*att * specC * lightcolor"+i+" * spec  * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3*sh);\n";
987 			}
988 			
989 			
990 			
991 		}
992 		shader=shader+"spotEffect = 0.0;\n";
993 		if(lights[i].type==GLGE.L_SPOT){
994 			shader=shader+"spotEffect = dot(normalize(lightdir"+i+"), normalize(-lightvec"+i+"));";	
995 			shader=shader+"if (spotEffect > spotCosCutOff"+i+""+(!this.spotCutOff ? " || spotEffect>0.0" : "")+") {\n";		
996 			shader=shader+"spotEffect = pow(spotEffect, spotExp"+i+");";
997 			//spot shadow stuff
998 			if(lights[i].getCastShadows() && this.shadow){
999 				shader=shader+"scoord=(((spotcoord"+i+".xy)/spotcoord"+i+".w)+1.0)/2.0;\n";
1000 				shader=shader+"if(scoord.x>0.0 && scoord.x<1.0 && scoord.y>0.0 && scoord.y<1.0){\n";
1001 				shader=shader+"dist=texture2D(TEXTURE"+(shadowlights[i])+", scoord);\n";
1002 				if(lights[i].spotSoftness==0){
1003 					shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0))*"+lights[i].distance+".0;\n";
1004 					shader=shader+"if(depth<length(lightvec"+i+")) spotmul=1.0; else spotmul=0.0;\n";
1005 				}else{
1006 					shader=shader+"m1 = pow(dot(dist, vec4(0.00390625,1.0,0.0,0.0)),2.0);\n";
1007 					shader=shader+"m2 = dot(dist, vec4(0.0,0.0,0.00390625,1.0));\n";				
1008 					shader=shader+"variance = min(max(m1-m2*m2, 0.0) + 0.000002, 1.0);;\n";
1009 					shader=shader+"depth=length(lightvec"+i+")/"+lights[i].distance+".0-m2;\n";
1010 					shader=shader+"prob=variance /(  variance + depth*depth );\n";
1011 					shader=shader+"prob=smoothstep("+lights[i].spotSoftnessDistance.toFixed(2)+",1.0,prob);\n";
1012 					shader=shader+"if (depth<=0.0) prob=1.0;\n";
1013 					shader=shader+"spotmul=1.0-prob;\n";
1014 				}
1015 				shader=shader+"spotEffect=spotEffect*(1.0-spotmul);\n";
1016 				shader=shader+"}\n";
1017 			}
1018 			shader=shader+"dotN=max(dot(normal,normalize(-lightvec)),0.0);\n";  
1019 			
1020 			if(lights[i].negativeShadow){
1021 				shader=shader+"if(dotN>0.0){\n";
1022 				if(lights[i].diffuse){
1023 					shader=shader+"lightvalue -= (1.0-spotEffect) / (lightAttenuation"+i+"[0] + lightAttenuation"+i+"[1] * lightdist"+i+" + lightAttenuation"+i+"[2] * lightdist"+i+" * lightdist"+i+");\n";
1024 				}
1025 				shader=shader+"}\n";
1026 			}else{     
1027 				shader=shader+"att = spotEffect / (lightAttenuation"+i+"[0] + lightdist"+i+"*(lightAttenuation"+i+"[1]  + lightAttenuation"+i+"[2] * lightdist"+i+"));\n";
1028 			
1029 				shader=shader+"if(dotN>0.0){\n";
1030 				if(lights[i].diffuse){
1031 					shader=shader+"lightvalue += att * dotN * lightcolor"+i+";\n";
1032 				}
1033 				shader=shader+"}\n";
1034 				if(lights[i].specular){
1035 				    shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN) * att * specC * lightcolor"+i+" * spec  * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3 * sh);\n";
1036 				}
1037 			}
1038 			
1039 			
1040 			shader=shader+"}\n";
1041 		}
1042 		if(lights[i].type==GLGE.L_DIR){
1043 			shader=shader+"dotN=max(dot(normal,-normalize(lightvec)),0.0);\n";    
1044 
1045 			if(lights[i].getCastShadows() && this.shadow){
1046 				shader=shader+"float shadowfact"+i+" = 0.0;\n";
1047 				shader=shader+"float level"+i+" = 1.0;\n";
1048 				shader=shader+"scoord=((spotcoord"+i+".xy)+1.0)/2.0;\n";
1049 				var levels=lights[i].getCascadeLevels();
1050 				for(var l=1;l<levels;l++){
1051 				shader=shader+"if(scoord.x<0.0 || scoord.x>1.0 || scoord.y<0.0 || scoord.y>1.0) {scoord=((spotcoord"+i+".xy-shadowoffset"+i+")*"+Math.pow(0.5,l).toFixed(5)+"+shadowoffset"+i+"+1.0)/2.0;level"+i+"="+(l+1).toFixed(2)+";};\n";
1052 				}
1053 				shader=shader+"scoord.y=scoord.y/"+levels.toFixed(2)+"+1.0-"+((1/levels).toFixed(5))+"*level"+i+";\n";
1054 				
1055 				if(lights[i].samples==0){
1056 					shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord);\n";
1057 					shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0))*"+((+lights[i].distance).toFixed(2))+";\n";
1058 					shader=shader+"sDepth = ((spotcoord"+i+".z)/spotcoord"+i+".w+1.0)/2.0;\n";
1059 							
1060 					shader=shader+"if(scoord.x>0.0 && scoord.x<1.0 && scoord.y>0.0 && scoord.y<1.0 && sDepth-shadowbias"+i+"-depth>0.0) {\n";
1061 					shader=shader+"shadowfact"+i+"=pow(clamp(2.0*length(eyevec)/"+((+lights[i].distance).toFixed(2))+",0.0,1.0),1.2);\n";
1062 					shader=shader+"}else{shadowfact"+i+"=1.0;}\n";	
1063 				}else{
1064 					shader=shader+"rnd=(fract(sin(dot(scoord,vec2(12.9898,78.233))) * 43758.5453)-0.5)*0.5;\n"; //generate random number
1065 					for(var x=-lights[i].samples;x<=lights[i].samples;x++){
1066 						for(var y=-lights[i].samples;y<=lights[i].samples;y++){
1067 							shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord+vec2("+(x/lights[i].bufferWidth).toFixed(4)+","+(y/lights[i].bufferHeight).toFixed(4)+")*shadowsoftness"+i+"*100.0/level"+i+"+vec2("+(1.0/lights[i].bufferWidth).toFixed(4)+","+(1.0/lights[i].bufferHeight).toFixed(4)+")*rnd);\n";
1068 							shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0))*"+((+lights[i].distance).toFixed(2))+";\n";
1069 							shader=shader+"sDepth = ((spotcoord"+i+".z)/spotcoord"+i+".w+1.0)/2.0;\n";
1070 							
1071 							shader=shader+"if(scoord.x>0.0 && scoord.x<1.0 && scoord.y>0.0 && scoord.y<1.0 && sDepth-shadowbias"+i+"-depth>0.0) {\n";
1072 							shader=shader+"shadowfact"+i+"+=pow(clamp(2.0*length(eyevec)/"+((+lights[i].distance).toFixed(2))+",0.0,1.0),2.0);\n";
1073 							shader=shader+"}else{shadowfact"+i+"+=1.0;}\n";		
1074 						}
1075 					}
1076 					shader=shader+"shadowfact"+i+"/="+((lights[i].samples*2+1)*(lights[i].samples*2+1)).toFixed(1)+";\n";
1077 				}
1078 			}else{
1079 				shader=shader+"float shadowfact"+i+" = 1.0;\n";
1080 			}
1081 			if(lights[i].diffuse){
1082 				if(lights[i].negativeShadow){
1083 					shader=shader+"lightvalue -= lightcolor"+i+"-(dotN * lightcolor"+i+" * shadowfact"+i+");\n";
1084 				}else{
1085 					shader=shader+"lightvalue += dotN * lightcolor"+i+" * shadowfact"+i+";\n";
1086 				}
1087 			}
1088 			if(lights[i].specular){
1089 				shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN) * specC * lightcolor"+i+" * spec  * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3 * sh);\n";
1090 			}
1091 		}
1092 	}
1093 		
1094 	shader=shader+"lightvalue = (lightvalue)*ref;\n";
1095 	
1096 	shader=shader+"vec3 fc=fogcolor.rgb;\n";
1097 	shader=shader+"if(fogtype=="+GLGE.FOG_SKYLINEAR+" || fogtype=="+GLGE.FOG_SKYQUADRATIC+"){";
1098 	shader=shader+"vec4 view=projection * vec4(-eyevec,1.0);\n";
1099 	shader=shader+"vec2 fogCoords=view.xy/view.w*0.5+0.5;\n";
1100 	shader=shader+"fc=texture2D(sky,fogCoords.xy).rgb;\n";
1101 	//shader=shader+"fogfact=1.0-(1.0-fogfact)*min(length(fc)/1.73,1.0);\n";
1102 	shader=shader+"}\n";
1103 			
1104 	shader=shader+"vec4 finalColor =vec4(specvalue.rgb+color.rgb*lightvalue.rgb+em.rgb,al)*fogfact+vec4(fc,al)*(1.0-fogfact);\n";
1105 	if(shaderInjection && ~shaderInjection.indexOf("GLGE_FragColor")){
1106 		shader=shader+"finalColor=GLGE_FragColor(finalColor);\n";
1107 	}
1108 	shader=shader+"gl_FragColor = finalColor;";
1109 	if(GLGE.DEBUGNORMALS) shader=shader+"gl_FragColor = vec4(normal.rgb,1.0);";
1110 	if(GLGE.DEBUGCOORD0) shader=shader+"gl_FragColor = vec4(textureCoords0.rg,0.0,1.0);";
1111 
1112 
1113     shader=shader+"}\n"; //end emit pass test
1114     
1115     shader=shader+"}\n";
1116     
1117 	return shader;
1118 };
1119 /**
1120 * Set the uniforms needed to render this material
1121 * @private
1122 */
1123 GLGE.Material.prototype.textureUniforms=function(gl,shaderProgram,lights,object){
1124 	if(this.animation) this.animate();
1125 	var pc=shaderProgram.caches;
1126 		
1127 	if(!pc.baseColor || pc.baseColor.r!=this.color.r || pc.baseColor.g!=this.color.g || pc.baseColor.b!=this.color.b || pc.baseColor.a!=this.color.a){
1128 		if(!this.ccache || this.ccache.r!=this.color.r || this.ccache.g!=this.color.g || this.ccache.b!=this.color.b || this.ccache.a!=this.color.a){
1129 			this.ccache=this.color;
1130 			this.glColor=new Float32Array([this.color.r,this.color.g,this.color.b,this.color.a]);
1131 		}
1132 		gl.uniform4fv(GLGE.getUniformLocation(gl,shaderProgram, "baseColor"), this.glColor);
1133 		pc.baseColor=this.color;
1134 	}
1135 	if(pc.specColor!=this.specColor){
1136 		if(this.sccache!=this.specColor){
1137 			this.sccache=this.specColor;
1138 			this.glspecColor=new Float32Array([this.specColor.r,this.specColor.g,this.specColor.b]);
1139 		}
1140 		gl.uniform3fv(GLGE.getUniformLocation(gl,shaderProgram, "specColor"), this.glspecColor);
1141 		pc.specColor=this.specColor;
1142 	}
1143 	if(pc.emit!=this.emit){
1144 		gl.uniform3f(GLGE.getUniformLocation(gl,shaderProgram, "emit"), this.emit.r,this.emit.g,this.emit.b);
1145 		pc.emit=this.emit;
1146 	}
1147 	if(pc.specular!=this.specular){
1148 		GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "specular"), this.specular);
1149 		pc.specular=this.specular;
1150 	}
1151 	if(pc.shine!=this.shine){
1152 		GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "shine"), this.shine);
1153 		pc.shine=this.shine;
1154 	}
1155 	if(pc.reflect!=this.reflect){
1156 		GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "reflective"), this.reflect);
1157 		pc.reflect=this.reflect;
1158 	}
1159 	if(pc.alpha!=this.alpha){
1160 		GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "alpha"), this.alpha);
1161 		pc.alpha=this.alpha;
1162 	}
1163 	if(pc.shadeless==undefined || pc.shadeless!=this.shadeless){
1164 		GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "shadeless"), this.shadeless);
1165 		pc.shadeless=this.shadeless;
1166 	}
1167 	
1168 	if(gl.scene.skyTexture){
1169 1170 		gl.activeTexture(gl["TEXTURE0"]);
1171 		
1172 		gl.bindTexture(gl.TEXTURE_2D, gl.scene.skyTexture);
1173 		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
1174 		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
1175 		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1176 		gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1177 		
1178 		GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "sky"), 0);
1179 	}
1180 	
1181 	/*
1182 	if(this.ambient && pc.ambient!=this.ambient){
1183 		gl.uniform3fv(GLGE.getUniformLocation(gl,shaderProgram, "amb"), new Float32Array([this.ambient.r,this.ambient.g,this.ambient.b]));
1184 		pc.ambient=this.ambient;
1185 	}
1186 	*/
1187 	var cnt=1;
1188 	var num=0;
1189 	if(!pc["lightcolor"]){
1190 		pc["lightcolor"]=[];
1191 		pc["lightAttenuation"]=[];
1192 		pc["spotCosCutOff"]=[];
1193 		pc["spotExponent"]=[];
1194 		pc["shadowbias"]=[];
1195 		pc["castshadows"]=[];
1196 		pc["shadowsamples"]=[];
1197 		pc["shadowsoftness"]=[];
1198 	}
1199 	for(var i=0; i<lights.length;i++){
1200 	    if(lights[i].type==GLGE.L_OFF) continue;
1201 		if(pc["lightcolor"][i]!=lights[i].color){
1202 			GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,shaderProgram, "lightcolor"+i), lights[i].color.r,lights[i].color.g,lights[i].color.b);
1203 			pc["lightcolor"][i]=lights[i].color;
1204 		}
1205 		if(pc["lightAttenuation"][i]!=lights[i].constantAttenuation){
1206 			GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,shaderProgram, "lightAttenuation"+i), lights[i].constantAttenuation,lights[i].linearAttenuation,lights[i].quadraticAttenuation);
1207 			pc["lightAttenuation"][i]=lights[i].constantAttenuation;
1208 		}
1209 		if(pc["spotCosCutOff"][i]!=lights[i].spotCosCutOff){
1210 			GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "spotCosCutOff"+i), lights[i].spotCosCutOff);
1211 			pc["spotCosCutOff"][i]=lights[i].spotCosCutOff;
1212 		}
1213 		if(pc["spotExponent"][i]!=lights[i].spotExponent){
1214 			GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "spotExp"+i), lights[i].spotExponent);
1215 			pc["spotExponent"][i]=lights[i].spotExponent;
1216 			
1217 		}
1218 		if(pc["shadowbias"][i]!=lights[i].shadowBias){
1219 			GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "shadowbias"+i), lights[i].shadowBias);
1220 			pc["shadowbias"][i]=lights[i].shadowBias;
1221 		}
1222 		if(pc["shadowsoftness"][i]!=lights[i].softness){
1223 			GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "shadowsoftness"+i), lights[i].softness);
1224 			pc["shadowsoftness"][i]=lights[i].softness;
1225 		}
1226 		    
1227 		//shadow code
1228 		if(lights[i].getCastShadows() && this.shadow) {	
1229 			num=this.textures.length+(cnt++);
1230 			gl.activeTexture(gl["TEXTURE"+num]);
1231 			gl.bindTexture(gl.TEXTURE_2D, lights[i].texture);
1232 			gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
1233 			gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
1234 			gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
1235 			gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
1236 			GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "TEXTURE"+num), num);	
1237 		}
1238 	
1239 			
1240 	}
1241 	
1242 	if(!shaderProgram.glarrays.layermat) shaderProgram.glarrays.layermat=[];
1243 	
1244 
1245 		
1246 	var scale,offset;
1247 	for(i=0; i<this.layers.length;i++){
1248 		if(this.layers[i].animation) this.layers[i].animate();
1249 		scale=this.layers[i].getScale();
1250 		offset=this.layers[i].getOffset();		
1251 		if(!shaderProgram.glarrays.layermat[i]) shaderProgram.glarrays.layermat[i]=new Float32Array(this.layers[i].getMatrix());
1252 			else GLGE.mat4gl(this.layers[i].getMatrix(),shaderProgram.glarrays.layermat[i]);	
1253 		
1254 		try{GLGE.setUniformMatrix(gl,"Matrix4fv",GLGE.getUniformLocation(gl,shaderProgram, "layer"+i+"Matrix"), true, shaderProgram.glarrays.layermat[i]);}catch(e){}
1255 		
1256 		GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "layeralpha"+i), this.layers[i].getAlpha());
1257 		GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "layerheight"+i), this.layers[i].getHeight());
1258 	}
1259     
1260 	for(var i=0; i<this.textures.length;i++){
1261 		
1262 			gl.activeTexture(gl["TEXTURE"+(i+1)]);
1263 			if(this.textures[i].doTexture(gl,object)){
1264 			}
1265 			GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "TEXTURE"+i), i+1);
1266 	}	
1267 
1268 };
1269 
1270 /**
1271 * Adds a new texture to this material
1272 * @returns {boolean} true if all resources have loaded false otherwise
1273 */
1274 GLGE.Material.prototype.isComplete=function(){
1275     for(var i=0;i<this.textures.length;i++){
1276         if(!this.textures[i].isComplete) continue;
1277         if(!this.textures[i].isComplete()) return false;
1278     }
1279     return true;
1280 }
1281 
1282 /**
1283 * Adds a new texture to this material
1284 * @param {String} image URL of the image to be used by the texture
1285 * @return {Number} index of the new texture
1286 */
1287 GLGE.Material.prototype.addTexture=function(texture){	
1288 	if(typeof texture=="string")  texture=GLGE.Assets.get(texture);
1289     var material=this;
1290     texture.addEventListener("downloadComplete",function(){
1291         if(material.isComplete()) material.fireEvent("downloadComplete");
1292     });
1293 	this.textures.push(texture);
1294 	texture.idx=this.textures.length-1;
1295 	this.fireEvent("shaderupdate",{});
1296 	return this;
1297 };
1298 GLGE.Material.prototype.addTextureCube=GLGE.Material.prototype.addTexture;
1299 GLGE.Material.prototype.addTextureCamera=GLGE.Material.prototype.addTexture;
1300 GLGE.Material.prototype.addTextureCanvas=GLGE.Material.prototype.addTexture;
1301 GLGE.Material.prototype.addTextureVideo=GLGE.Material.prototype.addTexture;
1302 
1303 GLGE.DEFAULT_MATERIAL=new GLGE.Material();
1304 
1305 
1306 })(GLGE);