Fork me on GitHub

API Documentation


Warning: DOMDocument::loadHTMLFile() [domdocument.loadhtmlfile]: htmlParseEntityRef: no name in jsdoc/symbols/src/src_renderable_glge_text.js.html, line: 375 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_renderable_glge_text.js.html, line: 376 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_renderable_glge_text.js.html, line: 377 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_text.js
 32  * @author me@paulbrunt.co.uk
 33  */
 34 
 35 
 36 (function(GLGE){
 37 
 38 
 39 
 40 
 41 
 42 /**
 43 * @class Text that can be rendered in a scene
 44 * @augments GLGE.Animatable
 45 * @augments GLGE.Placeable
 46 * @augments GLGE.QuickNotation
 47 * @augments GLGE.JSONLoader
 48 */
 49 GLGE.Text=function(uid){
 50 	this.canvas=document.createElement("canvas");
 51 	this.scaleCanvas=document.createElement("canvas");
 52 	this.color={r:1.0,g:1.0,b:1.0};
 53 	GLGE.Assets.registerAsset(this,uid);
 54 }
 55 GLGE.augment(GLGE.Placeable,GLGE.Text);
 56 GLGE.augment(GLGE.Animatable,GLGE.Text);
 57 GLGE.augment(GLGE.QuickNotation,GLGE.Text);
 58 GLGE.augment(GLGE.JSONLoader,GLGE.Text);
 59 GLGE.Text.prototype.className="Text";
 60 GLGE.Text.prototype.zTrans=true;
 61 GLGE.Text.prototype.canvas=null;
 62 GLGE.Text.prototype.aspect=1.0;
 63 GLGE.Text.prototype.color=null;
 64 GLGE.Text.prototype.text="";
 65 GLGE.Text.prototype.font="Times";
 66 GLGE.Text.prototype.size=100;
 67 GLGE.Text.prototype.pickType=GLGE.TEXT_TEXTPICK;
 68 GLGE.Text.prototype.pickable=true;
 69 GLGE.Text.prototype.alpha=1;
 70 
 71 /**
 72 * Gets the pick type for this text
 73 * @returns {string} the pick type
 74 */
 75 GLGE.Text.prototype.getPickType=function(){
 76 	return this.pickType;
 77 };
 78 /**
 79 * Sets the pick type GLGE.TEXT_BOXPICK for picking based on bound box or GLGE.TEXT_TEXTPICK for pixel perfect text picking
 80 * @param {Number} value the picking type
 81 */
 82 GLGE.Text.prototype.setPickType=function(value){
 83 	this.pickType=value;
 84 	return this;
 85 };
 86 /**
 87 * Gets the font of the text
 88 * @returns {string} the font of the text
 89 */
 90 GLGE.Text.prototype.getFont=function(){
 91 	return this.size;
 92 };
 93 /**
 94 * Sets the font of the text
 95 * @param {Number} value the font of the text
 96 */
 97 GLGE.Text.prototype.setFont=function(value){
 98 	this.font=value;
 99 	if(this.gl) this.updateCanvas(this.gl);
100 	return this;
101 };
102 /**
103 * Gets the size of the text
104 * @returns {string} the size of the text
105 */
106 GLGE.Text.prototype.getSize=function(){
107 	return this.size;
108 };
109 /**
110 * Sets the size of the text
111 * @param {Number} value the size of the text
112 */
113 GLGE.Text.prototype.setSize=function(value){
114 	this.size=value;
115 	if(this.gl) this.updateCanvas(this.gl);
116 	return this;
117 };
118 /**
119 * Gets the rendered text
120 * @returns {string} the text rendered
121 */
122 GLGE.Text.prototype.getText=function(){
123 	return this.text;
124 };
125 /**
126 * Sets the text to be rendered
127 * @param {Number} value the text to render
128 */
129 GLGE.Text.prototype.setText=function(value){
130 	this.text=value;
131 	if(this.gl) this.updateCanvas(this.gl);
132 	return this;
133 };
134 /**
135 * Sets the base colour of the text
136 * @param {string} color The colour of the material
137 */
138 GLGE.Text.prototype.setColor=function(color){
139 	color=GLGE.colorParse(color);
140 	this.color={r:color.r,g:color.g,b:color.b};
141 	return this;
142 };
143 /**
144 * Sets the red base colour of the text
145 * @param {Number} r The new red level 0-1
146 */
147 GLGE.Text.prototype.setColorR=function(value){
148 	this.color.r=value;
149 	return this;
150 };
151 /**
152 * Sets the green base colour of the text
153 * @param {Number} g The new green level 0-1
154 */
155 GLGE.Text.prototype.setColorG=function(value){
156 	this.color.g=value;
157 	return this;
158 };
159 /**
160 * Sets the blue base colour of the text
161 * @param {Number} b The new blue level 0-1
162 */
163 GLGE.Text.prototype.setColorB=function(value){
164 	this.color.b=value;
165 	return this;
166 };
167 /**
168 * Gets the current base color of the text
169 * @return {[r,g,b]} The current base color
170 */
171 GLGE.Text.prototype.getColor=function(){
172 	return this.color;
173 	return this;
174 };
175 
176 /**
177 * Sets the alpha
178 * @param {Number} b The new alpha level 0-1
179 */
180 GLGE.Text.prototype.setAlpha=function(value){
181 	this.alpha=value;
182 	return this;
183 };
184 
185 /**
186 * Gets the alpha
187 * @returns The alpha level
188 */
189 GLGE.Text.prototype.getAlpha=function(){
190 	return this.alpha;
191 };
192 
193 /**
194 * Sets the Z Transparency of this text
195 * @param {boolean} value Does this object need blending?
196 */
197 GLGE.Text.prototype.setZtransparent=function(value){
198 	this.zTrans=value;
199 	return this;
200 }
201 /**
202 * Gets the z transparency
203 * @returns boolean
204 */
205 GLGE.Text.prototype.isZtransparent=function(){
206 	return this.zTrans;
207 }
208 /**
209 * Creates the shader program for the object
210 * @private
211 */
212 GLGE.Text.prototype.GLGenerateShader=function(gl){
213 	if(this.GLShaderProgram) gl.deleteProgram(this.GLShaderProgram);
214 
215 	//Vertex Shader
216 	var vertexStr="";
217 	vertexStr+="attribute vec3 position;\n";
218 	vertexStr+="attribute vec2 uvcoord;\n";
219 	vertexStr+="varying vec2 texcoord;\n";
220 	vertexStr+="uniform mat4 Matrix;\n";
221 	vertexStr+="uniform mat4 PMatrix;\n";
222 	vertexStr+="varying vec4 pos;\n";
223 	
224 	vertexStr+="void main(void){\n";
225 	vertexStr+="texcoord=uvcoord;\n";    
226 	vertexStr+="pos = Matrix * vec4(position,1.0);\n";
227 	vertexStr+="gl_Position = PMatrix * pos;\n";
228 	vertexStr+="}\n";
229 	
230 	//Fragment Shader
231 	var fragStr="#ifdef GL_ES\nprecision highp float;\n#endif\n";
232 	fragStr=fragStr+"uniform sampler2D TEXTURE;\n";
233 	fragStr=fragStr+"varying vec2 texcoord;\n";
234 	fragStr=fragStr+"uniform mat4 Matrix;\n";
235 	fragStr=fragStr+"varying vec4 pos;\n";
236 	fragStr=fragStr+"uniform float far;\n";
237 	fragStr=fragStr+"uniform bool depthrender;\n";
238 	fragStr=fragStr+"uniform float distance;\n";
239 	fragStr=fragStr+"uniform int picktype;\n";
240 	fragStr=fragStr+"uniform vec3 pickcolor;\n";
241 	fragStr=fragStr+"uniform vec3 color;\n";
242 	fragStr=fragStr+"uniform float alpha;\n";
243 	fragStr=fragStr+"void main(void){\n";
244 	fragStr=fragStr+"float ob=pow(min(1.0,abs(dot(normalize(Matrix[2].rgb),vec3(0.0,0.0,1.0)))*2.0),1.5);\n";
245 	fragStr=fragStr+"float a=texture2D(TEXTURE,texcoord).a*alpha*ob;\n";
246 	fragStr=fragStr+"if(picktype=="+GLGE.TEXT_BOXPICK+"){gl_FragColor = vec4(pickcolor,1.0);}"
247 	fragStr=fragStr+"else if(picktype=="+GLGE.TEXT_TEXTPICK+"){if(alpha<1.0) discard; gl_FragColor = vec4(pickcolor,alpha);}"
248 	fragStr=fragStr+"else{gl_FragColor = vec4(color.rgb,a);};\n";
249 	fragStr=fragStr+"if (depthrender) { if(a<0.5) discard; float depth = gl_FragCoord.z / gl_FragCoord.w;\n";
250 	fragStr=fragStr+"vec4 rgba=fract(depth/distance * vec4(16777216.0, 65536.0, 256.0, 1.0));\n";
251 	fragStr=fragStr+"gl_FragColor=rgba-rgba.rrgb*vec4(0.0,0.00390625,0.00390625,0.00390625);}\n";
252 	fragStr=fragStr+"}\n";
253 	
254 	this.GLFragmentShader=gl.createShader(gl.FRAGMENT_SHADER);
255 	this.GLVertexShader=gl.createShader(gl.VERTEX_SHADER);
256 
257 
258 	gl.shaderSource(this.GLFragmentShader, fragStr);
259 	gl.compileShader(this.GLFragmentShader);
260 	if (!gl.getShaderParameter(this.GLFragmentShader, gl.COMPILE_STATUS)) {
261 	      GLGE.error(gl.getShaderInfoLog(this.GLFragmentShader));
262 	      return;
263 	}
264 	
265 	//set and compile the vertex shader
266 	//need to set str
267 	gl.shaderSource(this.GLVertexShader, vertexStr);
268 	gl.compileShader(this.GLVertexShader);
269 	if (!gl.getShaderParameter(this.GLVertexShader, gl.COMPILE_STATUS)) {
270 		GLGE.error(gl.getShaderInfoLog(this.GLVertexShader));
271 		return;
272 	}
273 	
274 	this.GLShaderProgram = gl.createProgram();
275 	gl.attachShader(this.GLShaderProgram, this.GLVertexShader);
276 	gl.attachShader(this.GLShaderProgram, this.GLFragmentShader);
277 	gl.linkProgram(this.GLShaderProgram);	
278 }
279 /**
280 * Initiallize all the GL stuff needed to render to screen
281 * @private
282 */
283 GLGE.Text.prototype.GLInit=function(gl){
284 	this.gl=gl;
285 	this.createPlane(gl);
286 	this.GLGenerateShader(gl);
287 	
288 	this.glTexture=gl.createTexture();
289 	this.updateCanvas(gl);
290 }
291 /**
292 * Updates the canvas texture
293 * @private
294 */
295 GLGE.Text.prototype.updateCanvas=function(gl){
296 	var canvas = this.canvas;
297 	canvas.width=1;
298 	canvas.height=this.size*1.2;
299 	var ctx = canvas.getContext("2d");
300 	ctx.font = this.size+"px "+this.font;
301 	canvas.width=ctx.measureText(this.text).width;
302 	canvas.height=this.size*1.2;
303 	 ctx = canvas.getContext("2d");
304 	ctx.textBaseline="top";
305 	ctx.font = (this.extra||"") + " " + this.size+"px "+this.font;
306 	this.aspect=canvas.width/canvas.height;
307 	ctx.fillText(this.text, 0, 0);   
308 	
309 	var height=Math.pow(2,Math.ceil(Math.log(canvas.height))/(Math.log(2)));
310 	var width=Math.pow(2,Math.ceil(Math.log(canvas.width))/(Math.log(2)));
311 
312 	this.scaleCanvas.height=height;
313 	this.scaleCanvas.width=width;
314 
315 	this.scaleContext=this.scaleCanvas.getContext("2d");
316 	this.scaleContext.clearRect(0,0,width,height);
317 	this.scaleContext.drawImage(canvas, 0, 0, width, height);
318 	
319 	gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
320 	//TODO: fix this when minefield is upto spec
321 	try{gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.scaleCanvas);}
322 	catch(e){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.scaleCanvas,null);}
323 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
324 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
325 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR_MIPMAP_LINEAR);
326 	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
327 	gl.generateMipmap(gl.TEXTURE_2D);
328 	
329 	gl.bindTexture(gl.TEXTURE_2D, null);
330 }
331 
332 /**
333 * Renders the text to the render buffer
334 * @private
335 */
336 GLGE.Text.prototype.GLRender=function(gl,renderType,pickindex){
337 	if(!this.gl){
338 		this.GLInit(gl);
339 	}	
340 	if(renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_PICK || renderType==GLGE.RENDER_SHADOW){
341 		//if look at is set then look
342 		if(this.lookAt) this.Lookat(this.lookAt);
343 		
344 		if(gl.program!=this.GLShaderProgram){
345 			gl.useProgram(this.GLShaderProgram);
346 			gl.program=this.GLShaderProgram;
347 		}
348 					
349 		var attribslot;
350 		//disable all the attribute initially arrays - do I really need this?
351 		for(var i=0; i<8; i++) gl.disableVertexAttribArray(i);
352 		attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "position");
353 
354 		gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
355 		gl.enableVertexAttribArray(attribslot);
356 		gl.vertexAttribPointer(attribslot, this.posBuffer.itemSize, gl.FLOAT, false, 0, 0);
357 		
358 		attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "uvcoord");
359 		gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
360 		gl.enableVertexAttribArray(attribslot);
361 		gl.vertexAttribPointer(attribslot, this.uvBuffer.itemSize, gl.FLOAT, false, 0, 0);
362 		
363 		gl.activeTexture(gl["TEXTURE0"]);
364 		gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
365 		GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "TEXTURE"),0);
366 		
367 		if(!pickindex) pickindex=0;
368 		var b = pickindex >> 16 & 0xFF; 
369 		var g = pickindex >> 8 & 0xFF; 
370 		var r = pickindex & 0xFF;
371 		GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "pickcolor"),r/255,g/255,b/255);
372 		
373 		if(renderType==GLGE.RENDER_PICK){
374 			GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "picktype"), this.pickType);	
375 		}else{
376 			GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "picktype"), 0);	
377 		}
378 		var distance=gl.scene.camera.getFar();
379 		GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "distance"), distance);
380 		if(renderType==GLGE.RENDER_SHADOW){
381 			GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "depthrender"), 1);
382 		}else{
383 			GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "depthrender"), 0);
384 		}
385 		
386 		
387 		if(!this.GLShaderProgram.glarrays) this.GLShaderProgram.glarrays={};
388 
389 		
390 		//generate and set the modelView matrix
391 		var scalefactor=this.size/100;
392 		var mMatrix=GLGE.mulMat4(gl.scene.camera.getViewMatrix(),GLGE.mulMat4(this.getModelMatrix(),GLGE.scaleMatrix(this.aspect*scalefactor,scalefactor,scalefactor)));
393 		var mUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "Matrix");
394 		if(!this.GLShaderProgram.glarrays.mMatrix) this.GLShaderProgram.glarrays.mMatrix=new Float32Array(mMatrix);
395 			else GLGE.mat4gl(mMatrix,this.GLShaderProgram.glarrays.mMatrix);
396 		GLGE.setUniformMatrix(gl,"Matrix4fv",mUniform, true, this.GLShaderProgram.glarrays.mMatrix);
397 		
398 		var mUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "PMatrix");
399 
400 		if(!this.GLShaderProgram.glarrays.pMatrix) this.GLShaderProgram.glarrays.pMatrix=new Float32Array(gl.scene.camera.getProjectionMatrix());
401 			else GLGE.mat4gl(gl.scene.camera.getProjectionMatrix(),this.GLShaderProgram.glarrays.pMatrix);
402 		GLGE.setUniformMatrix(gl,"Matrix4fv",mUniform, true, this.GLShaderProgram.glarrays.pMatrix);
403 				
404 		var farUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "far");
405 		GLGE.setUniform(gl,"1f",farUniform, gl.scene.camera.getFar());
406 			
407 		var alphaUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "alpha");
408 		GLGE.setUniform(gl,"1f",alphaUniform, this.alpha);
409 		
410 		//set the color
411 		GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "color"), this.color.r,this.color.g,this.color.b);
412 		
413 		gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
414 		gl.drawElements(gl.TRIANGLES, this.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
415 		gl.scene.lastMaterial=null;
416 	}
417 }
418 /**
419 * creates the plane mesh to draw
420 * @private
421 */
422 GLGE.Text.prototype.createPlane=function(gl){
423 	//create the vertex positions
424 	if(!this.posBuffer) this.posBuffer = gl.createBuffer();
425 	gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
426 	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,1,0,-1,1,0,-1,-1,0,1,-1,0]), gl.STATIC_DRAW);
427 	this.posBuffer.itemSize = 3;
428 	this.posBuffer.numItems = 4;
429 	//create the vertex uv coords
430 	if(!this.uvBuffer) this.uvBuffer = gl.createBuffer();
431 	gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
432 	gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,0,1,0,1,1,0,1]), gl.STATIC_DRAW);
433 	this.uvBuffer.itemSize = 2;
434 	this.uvBuffer.numItems = 4;
435 	//create the faces
436 	if(!this.GLfaces) this.GLfaces = gl.createBuffer();
437 	gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
438 	gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([2,1,0,0,3,2]), gl.STATIC_DRAW);
439 	this.GLfaces.itemSize = 1;
440 	this.GLfaces.numItems = 6;
441 }
442 
443 
444 })(GLGE);