source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/extras/renderers/plugins/SpritePlugin.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 8.4 KB
Line 
1/**
2 * @author mikael emtinger / http://gomo.se/
3 * @author alteredq / http://alteredqualia.com/
4 */
5
6THREE.SpritePlugin = function () {
7
8 var _gl, _renderer, _texture;
9
10 var vertices, faces, vertexBuffer, elementBuffer;
11 var program, attributes, uniforms;
12
13 this.init = function ( renderer ) {
14
15 _gl = renderer.context;
16 _renderer = renderer;
17
18 vertices = new Float32Array( [
19 - 0.5, - 0.5, 0, 0,
20 0.5, - 0.5, 1, 0,
21 0.5, 0.5, 1, 1,
22 - 0.5, 0.5, 0, 1
23 ] );
24
25 faces = new Uint16Array( [
26 0, 1, 2,
27 0, 2, 3
28 ] );
29
30 vertexBuffer = _gl.createBuffer();
31 elementBuffer = _gl.createBuffer();
32
33 _gl.bindBuffer( _gl.ARRAY_BUFFER, vertexBuffer );
34 _gl.bufferData( _gl.ARRAY_BUFFER, vertices, _gl.STATIC_DRAW );
35
36 _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
37 _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, faces, _gl.STATIC_DRAW );
38
39 program = createProgram();
40
41 attributes = {
42 position: _gl.getAttribLocation ( program, 'position' ),
43 uv: _gl.getAttribLocation ( program, 'uv' )
44 };
45
46 uniforms = {
47 uvOffset: _gl.getUniformLocation( program, 'uvOffset' ),
48 uvScale: _gl.getUniformLocation( program, 'uvScale' ),
49
50 rotation: _gl.getUniformLocation( program, 'rotation' ),
51 scale: _gl.getUniformLocation( program, 'scale' ),
52
53 color: _gl.getUniformLocation( program, 'color' ),
54 map: _gl.getUniformLocation( program, 'map' ),
55 opacity: _gl.getUniformLocation( program, 'opacity' ),
56
57 modelViewMatrix: _gl.getUniformLocation( program, 'modelViewMatrix' ),
58 projectionMatrix: _gl.getUniformLocation( program, 'projectionMatrix' ),
59
60 fogType: _gl.getUniformLocation( program, 'fogType' ),
61 fogDensity: _gl.getUniformLocation( program, 'fogDensity' ),
62 fogNear: _gl.getUniformLocation( program, 'fogNear' ),
63 fogFar: _gl.getUniformLocation( program, 'fogFar' ),
64 fogColor: _gl.getUniformLocation( program, 'fogColor' ),
65
66 alphaTest: _gl.getUniformLocation( program, 'alphaTest' )
67 };
68
69 var canvas = document.createElement( 'canvas' );
70 canvas.width = 8;
71 canvas.height = 8;
72
73 var context = canvas.getContext( '2d' );
74 context.fillStyle = '#ffffff';
75 context.fillRect( 0, 0, canvas.width, canvas.height );
76
77 _texture = new THREE.Texture( canvas );
78 _texture.needsUpdate = true;
79
80 };
81
82 this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
83
84 var sprites = scene.__webglSprites,
85 nSprites = sprites.length;
86
87 if ( ! nSprites ) return;
88
89 // setup gl
90
91 _gl.useProgram( program );
92
93 _gl.enableVertexAttribArray( attributes.position );
94 _gl.enableVertexAttribArray( attributes.uv );
95
96 _gl.disable( _gl.CULL_FACE );
97 _gl.enable( _gl.BLEND );
98
99 _gl.bindBuffer( _gl.ARRAY_BUFFER, vertexBuffer );
100 _gl.vertexAttribPointer( attributes.position, 2, _gl.FLOAT, false, 2 * 8, 0 );
101 _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
102
103 _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, elementBuffer );
104
105 _gl.uniformMatrix4fv( uniforms.projectionMatrix, false, camera.projectionMatrix.elements );
106
107 _gl.activeTexture( _gl.TEXTURE0 );
108 _gl.uniform1i( uniforms.map, 0 );
109
110 var oldFogType = 0;
111 var sceneFogType = 0;
112 var fog = scene.fog;
113
114 if ( fog ) {
115
116 _gl.uniform3f( uniforms.fogColor, fog.color.r, fog.color.g, fog.color.b );
117
118 if ( fog instanceof THREE.Fog ) {
119
120 _gl.uniform1f( uniforms.fogNear, fog.near );
121 _gl.uniform1f( uniforms.fogFar, fog.far );
122
123 _gl.uniform1i( uniforms.fogType, 1 );
124 oldFogType = 1;
125 sceneFogType = 1;
126
127 } else if ( fog instanceof THREE.FogExp2 ) {
128
129 _gl.uniform1f( uniforms.fogDensity, fog.density );
130
131 _gl.uniform1i( uniforms.fogType, 2 );
132 oldFogType = 2;
133 sceneFogType = 2;
134
135 }
136
137 } else {
138
139 _gl.uniform1i( uniforms.fogType, 0 );
140 oldFogType = 0;
141 sceneFogType = 0;
142
143 }
144
145
146 // update positions and sort
147
148 var i, sprite, material, fogType, scale = [];
149
150 for( i = 0; i < nSprites; i ++ ) {
151
152 sprite = sprites[ i ];
153 material = sprite.material;
154
155 if ( sprite.visible === false ) continue;
156
157 sprite._modelViewMatrix.multiplyMatrices( camera.matrixWorldInverse, sprite.matrixWorld );
158 sprite.z = - sprite._modelViewMatrix.elements[ 14 ];
159
160 }
161
162 sprites.sort( painterSortStable );
163
164 // render all sprites
165
166 for( i = 0; i < nSprites; i ++ ) {
167
168 sprite = sprites[ i ];
169
170 if ( sprite.visible === false ) continue;
171
172 material = sprite.material;
173
174 _gl.uniform1f( uniforms.alphaTest, material.alphaTest );
175 _gl.uniformMatrix4fv( uniforms.modelViewMatrix, false, sprite._modelViewMatrix.elements );
176
177 scale[ 0 ] = sprite.scale.x;
178 scale[ 1 ] = sprite.scale.y;
179
180 if ( scene.fog && material.fog ) {
181
182 fogType = sceneFogType;
183
184 } else {
185
186 fogType = 0;
187
188 }
189
190 if ( oldFogType !== fogType ) {
191
192 _gl.uniform1i( uniforms.fogType, fogType );
193 oldFogType = fogType;
194
195 }
196
197 if ( material.map !== null ) {
198
199 _gl.uniform2f( uniforms.uvOffset, material.map.offset.x, material.map.offset.y );
200 _gl.uniform2f( uniforms.uvScale, material.map.repeat.x, material.map.repeat.y );
201
202 } else {
203
204 _gl.uniform2f( uniforms.uvOffset, 0, 0 );
205 _gl.uniform2f( uniforms.uvScale, 1, 1 );
206
207 }
208
209 _gl.uniform1f( uniforms.opacity, material.opacity );
210 _gl.uniform3f( uniforms.color, material.color.r, material.color.g, material.color.b );
211
212 _gl.uniform1f( uniforms.rotation, material.rotation );
213 _gl.uniform2fv( uniforms.scale, scale );
214
215 _renderer.setBlending( material.blending, material.blendEquation, material.blendSrc, material.blendDst );
216 _renderer.setDepthTest( material.depthTest );
217 _renderer.setDepthWrite( material.depthWrite );
218
219 if ( material.map && material.map.image && material.map.image.width ) {
220
221 _renderer.setTexture( material.map, 0 );
222
223 } else {
224
225 _renderer.setTexture( _texture, 0 );
226
227 }
228
229 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
230
231 }
232
233 // restore gl
234
235 _gl.enable( _gl.CULL_FACE );
236
237 };
238
239 function createProgram () {
240
241 var program = _gl.createProgram();
242
243 var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
244 var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
245
246 _gl.shaderSource( vertexShader, [
247
248 'precision ' + _renderer.getPrecision() + ' float;',
249
250 'uniform mat4 modelViewMatrix;',
251 'uniform mat4 projectionMatrix;',
252 'uniform float rotation;',
253 'uniform vec2 scale;',
254 'uniform vec2 uvOffset;',
255 'uniform vec2 uvScale;',
256
257 'attribute vec2 position;',
258 'attribute vec2 uv;',
259
260 'varying vec2 vUV;',
261
262 'void main() {',
263
264 'vUV = uvOffset + uv * uvScale;',
265
266 'vec2 alignedPosition = position * scale;',
267
268 'vec2 rotatedPosition;',
269 'rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;',
270 'rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;',
271
272 'vec4 finalPosition;',
273
274 'finalPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );',
275 'finalPosition.xy += rotatedPosition;',
276 'finalPosition = projectionMatrix * finalPosition;',
277
278 'gl_Position = finalPosition;',
279
280 '}'
281
282 ].join( '\n' ) );
283
284 _gl.shaderSource( fragmentShader, [
285
286 'precision ' + _renderer.getPrecision() + ' float;',
287
288 'uniform vec3 color;',
289 'uniform sampler2D map;',
290 'uniform float opacity;',
291
292 'uniform int fogType;',
293 'uniform vec3 fogColor;',
294 'uniform float fogDensity;',
295 'uniform float fogNear;',
296 'uniform float fogFar;',
297 'uniform float alphaTest;',
298
299 'varying vec2 vUV;',
300
301 'void main() {',
302
303 'vec4 texture = texture2D( map, vUV );',
304
305 'if ( texture.a < alphaTest ) discard;',
306
307 'gl_FragColor = vec4( color * texture.xyz, texture.a * opacity );',
308
309 'if ( fogType > 0 ) {',
310
311 'float depth = gl_FragCoord.z / gl_FragCoord.w;',
312 'float fogFactor = 0.0;',
313
314 'if ( fogType == 1 ) {',
315
316 'fogFactor = smoothstep( fogNear, fogFar, depth );',
317
318 '} else {',
319
320 'const float LOG2 = 1.442695;',
321 'float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );',
322 'fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );',
323
324 '}',
325
326 'gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );',
327
328 '}',
329
330 '}'
331
332 ].join( '\n' ) );
333
334 _gl.compileShader( vertexShader );
335 _gl.compileShader( fragmentShader );
336
337 _gl.attachShader( program, vertexShader );
338 _gl.attachShader( program, fragmentShader );
339
340 _gl.linkProgram( program );
341
342 return program;
343
344 };
345
346 function painterSortStable ( a, b ) {
347
348 if ( a.z !== b.z ) {
349
350 return b.z - a.z;
351
352 } else {
353
354 return b.id - a.id;
355
356 }
357
358 };
359
360};
Note: See TracBrowser for help on using the repository browser.