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 /**
  8 	@private
  9 	@class A Texture is an image which is to be wrapped around a Model object. A 
 10 	texture has a unique ID which can be used to identify it in openGL.
 11 	
 12 	<p>To create a texture, call setup() passing in the OpenGL context as
 13 	well as the path to the image.</p>
 14 */
 15 c3dl.Texture = function()
 16 {
 17 	// textureImage will be created as an Image().
 18 	
 19 	/**
 20 		@private
 21 	*/
 22 	var textureImage = null;
 23 	var isSetup = false;
 24 
 25 
 26 	/**
 27 		@private
 28 		Get the texture ID, the texture ID is a unique number which
 29 		we can use to notify what texture in opengl we want
 30 		to work with.
 31 		
 32 		@returns {int} The ID of the texture if the texture has been 
 33 		loaded, 0 otherwise.
 34 	*/
 35 	this.getTextureID = function()
 36 	{
 37 		return textureImage.ID;
 38 	}
 39 
 40 
 41 	/**	
 42 		@private
 43 		Get the absolute path of the Texture.
 44 		
 45 		@returns {string} The absolute path of the texture using the 
 46 		image's src property.
 47 	*/
 48 	this.getAbsolutePath = function()
 49 	{
 50 		if( textureImage != null)
 51 		{
 52 			return textureImage.src;
 53 		}
 54 		else
 55 		{
 56 			c3dl.debug.logError('getTexturePath() error - texture has not been setup.');			
 57 			return false;
 58 		}
 59 	}
 60 
 61 
 62 	/** 
 63 		@private
 64 		Get the path of the image relative the main.js file.  This will
 65 		be the same path the user passes in when they call setTexture on
 66 		a model.		
 67 		
 68 		@returns {string} The relative path of texture.
 69 	*/
 70 	this.getRelativePath = function()
 71 	{
 72 		return textureImage.relativePath;
 73 	}
 74 
 75 
 76 	/**
 77 		@private
 78 		Check if the Texture has been setup.
 79 		
 80 		@returns {boolean} True if the Texture has been setup, false otherwise.
 81 	*/
 82 	this.getIsSetup = function()
 83 	{
 84 		return isSetup;
 85 	}
 86 
 87 
 88 	/**
 89 		@private
 90 		Setup can be called when the object is created to give it a
 91 		texture, but it can also be later changed by calling this method
 92 		again.
 93 		
 94 		Once the Texture has been setup, do not allow the user to set it up 
 95 		again.
 96 
 97 		@param glCanvas3D
 98 		@param {string} source
 99 		@param sourceCanvas
100 		
101 		@return {boolean} true if the Texture could be set up, false 
102 		if the texture was already setup or if setup failed.
103 	*/
104 	this.setup = function(glCanvas3D, source, sourceCanvas)
105 	{
106 		var returnCode = true;
107 		
108 		// make sure the user passed in correct variables and prevent
109 		// the user from calling this method more than once.
110 		if(source != null && glCanvas3D != null && this.getIsSetup() == false)
111 		{
112 			if(sourceCanvas == null)
113 			{
114 				textureImage = new Image();
115 				textureImage.src = source;
116 				
117 				// doing this will only store the name of the texture in 
118 				// the name variable.
119 				textureImage.relativePath = source;
120 			}
121 			else
122 			{
123 				textureImage = document.getElementById(sourceCanvas);
124 				textureImage.relativePath = sourceCanvas;
125 			}
126 			
127 			// was a bit tricky to pass in glCanvas into the onload function 
128 			// of the image, so instead they were added as properties
129 			//	textureImage.ID = 0;	
130 			textureImage.glCanvas3D = glCanvas3D;
131 			
132 			// genTextures gives us an unused texture image id, like 
133 			// a primary key only needs to be done once
134 			// don't wait for load to run since we don't konw when that will
135 			// be. if the user has given us proper values, we'll probably
136 			// be able to create the texture, worst case, we have an id
137 			// not associated with a texture
138 			textureImage.ID = glCanvas3D.createTexture();
139 			glCanvas3D.activeTexture(glCanvas3D.TEXTURE0);
140 
141 			/**
142 				@private
143 			*/
144 			textureImage.setupOpenGL = function()
145 			{
146 				// bindtexture() sets the selected texture (by id) to be 
147 				// the current texture.  the current texture is the one 
148 				// used for any operations such as assigning uv coords, 
149 				glCanvas3D.bindTexture(glCanvas3D.TEXTURE_2D, this.ID);
150 			}
151 
152 
153 			/**
154 				@private
155 				Resize the texture so it can be used in OpenGL.  The texture 
156 				may be distorted, but at least it will display something.
157 				The user will be notified their texture should be modified.		
158 			*/
159 			textureImage.resizeImage = function()
160 			{
161 				// not power-of-two, so resize it using a 2d canvas
162 				var w = c3dl.roundUpToNextPowerOfTwo(this.width);
163 				var h = c3dl.roundUpToNextPowerOfTwo(this.height);
164 				var canvas = document.createElement('canvas');
165 				canvas.width = w;
166 				canvas.height = h;
167 				var context = canvas.getContext('2d');
168 				context.drawImage(this, 0, 0, w, h);
169 				// add a property to the image, so the onload function can access the canvas created here.
170 				this.canvas = canvas;
171 			}
172 
173 
174 			/**
175 				@private
176 				Set the function to run when the image is loaded
177 			*/
178 			textureImage.onload = function()
179 			{				
180 				//
181 				this.setupOpenGL();
182 
183 				try
184 				{
185 					// place the texture into video memory
186 					this.glCanvas3D.texImage2D(glCanvas3D.TEXTURE_2D, 0, this);
187 					this.glCanvas3D.generateMipmap(glCanvas3D.TEXTURE_2D);
188 					this.isSetup = true;
189 				}
190 				catch(err)
191 				{
192 					c3dl.debug.logError('Texture exception - tried to call texImage2DHTML()');
193 				}			
194 			};
195 			
196 			if(sourceCanvas != null)
197 			{
198 				textureImage.onload();
199 			}
200 			
201 			if (this.getIsSetup())
202 			{
203 				//!! this should be false, because its initialised as true
204 				returnCode = true;
205 			}
206 		}		
207 		// user passed in a null for either the canvas or the source
208 		else
209 		{
210 			c3dl.debug.logError('null value was passed into texture load function or texture was already setup');
211 			returnCode = false;
212 		}
213 		
214 		// if the image could be setup, this variable was set to
215 		return returnCode;
216 	}
217 }
218