Skip to content

Commit b10c885

Browse files
committed
Tilemap shader WIP.
1 parent f494c86 commit b10c885

4 files changed

Lines changed: 264 additions & 0 deletions

File tree

build/config.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
<script src="$path/src/pixi/renderers/webgl/shaders/StripShader.js"></script>
6565
<script src="$path/src/pixi/renderers/webgl/shaders/PrimitiveShader.js"></script>
6666
<script src="$path/src/pixi/renderers/webgl/shaders/ComplexPrimitiveShader.js"></script>
67+
<script src="$path/src/pixi/renderers/webgl/shaders/TilemapShader.js"></script>
6768
<script src="$path/src/pixi/renderers/webgl/utils/WebGLGraphics.js"></script>
6869
<script src="$path/src/pixi/renderers/webgl/WebGLRenderer.js"></script>
6970
<script src="$path/src/pixi/renderers/webgl/utils/WebGLBlendModeManager.js"></script>
@@ -84,6 +85,8 @@
8485
<script src="$path/src/pixi/primitives/Graphics.js"></script>
8586
<script src="$path/src/pixi/primitives/GraphicsData.js"></script>
8687
88+
<script src="$path/src/pixi/extras/Tilemap.js"></script>
89+
8790
8891
EOL;
8992

src/pixi/extras/Tilemap.js

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
PIXI.Tilemap = function(texture)
2+
{
3+
PIXI.DisplayObjectContainer.call(this);
4+
5+
/**
6+
* The texture of the Tilemap
7+
*
8+
* @property texture
9+
* @type Texture
10+
*/
11+
this.texture = texture;
12+
13+
/**
14+
* Whether the Tilemap is dirty or not
15+
*
16+
* @property dirty
17+
* @type Boolean
18+
*/
19+
this.dirty = true;
20+
21+
/**
22+
* The blend mode to be applied to the sprite. Set to PIXI.blendModes.NORMAL to remove any blend mode.
23+
*
24+
* @property blendMode
25+
* @type Number
26+
* @default PIXI.blendModes.NORMAL;
27+
*/
28+
this.blendMode = PIXI.blendModes.NORMAL;
29+
30+
this.uvs = new PIXI.Float32Array([0, 1,
31+
1, 1,
32+
1, 0,
33+
0, 1]);
34+
35+
this.vertices = new PIXI.Float32Array([0, 0,
36+
100, 0,
37+
100, 100,
38+
0, 100]);
39+
40+
this.colors = new PIXI.Float32Array([1, 1, 1, 1]);
41+
42+
this.indices = new PIXI.Uint16Array([0, 1, 2, 3]);
43+
44+
};
45+
46+
// constructor
47+
PIXI.Tilemap.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
48+
PIXI.Tilemap.prototype.constructor = PIXI.Tilemap;
49+
50+
PIXI.Tilemap.prototype.update = function() {};
51+
PIXI.Tilemap.prototype.postUpdate = function() {};
52+
53+
PIXI.Tilemap.prototype._renderWebGL = function(renderSession)
54+
{
55+
// if the sprite is not visible or the alpha is 0 then no need to render this element
56+
if(!this.visible || this.alpha <= 0)return;
57+
58+
renderSession.spriteBatch.stop();
59+
60+
// init! init!
61+
if(!this._vertexBuffer)this._initWebGL(renderSession);
62+
63+
renderSession.shaderManager.setShader(renderSession.shaderManager.tilemapShader);
64+
65+
this._renderTilemap(renderSession);
66+
67+
renderSession.spriteBatch.start();
68+
};
69+
70+
PIXI.Tilemap.prototype._initWebGL = function(renderSession)
71+
{
72+
var gl = renderSession.gl;
73+
74+
this._vertexBuffer = gl.createBuffer();
75+
this._indexBuffer = gl.createBuffer();
76+
this._uvBuffer = gl.createBuffer();
77+
this._colorBuffer = gl.createBuffer();
78+
79+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
80+
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
81+
82+
gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer);
83+
gl.bufferData(gl.ARRAY_BUFFER, this.uvs, gl.STATIC_DRAW);
84+
85+
gl.bindBuffer(gl.ARRAY_BUFFER, this._colorBuffer);
86+
gl.bufferData(gl.ARRAY_BUFFER, this.colors, gl.STATIC_DRAW);
87+
88+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer);
89+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
90+
};
91+
92+
PIXI.Tilemap.prototype._renderTilemap = function(renderSession)
93+
{
94+
var gl = renderSession.gl;
95+
var projection = renderSession.projection,
96+
offset = renderSession.offset,
97+
shader = renderSession.shaderManager.tilemapShader;
98+
99+
renderSession.blendModeManager.setBlendMode(this.blendMode);
100+
101+
// gl.uniformMatrix3fv(shader.translationMatrix, false, this.worldTransform.toArray(true));
102+
gl.uniform2f(shader.projectionVector, projection.x, -projection.y);
103+
gl.uniform2f(shader.offsetVector, -offset.x, -offset.y);
104+
gl.uniform1f(shader.alpha, this.worldAlpha);
105+
106+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vertexBuffer);
107+
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
108+
gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
109+
110+
// update the uvs
111+
gl.bindBuffer(gl.ARRAY_BUFFER, this._uvBuffer);
112+
gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
113+
114+
gl.activeTexture(gl.TEXTURE0);
115+
116+
// check if a texture is dirty..
117+
if(this.texture.baseTexture._dirty[gl.id])
118+
{
119+
renderSession.renderer.updateTexture(this.texture.baseTexture);
120+
}
121+
else
122+
{
123+
// bind the current texture
124+
gl.bindTexture(gl.TEXTURE_2D, this.texture.baseTexture._glTextures[gl.id]);
125+
}
126+
127+
// dont need to upload!
128+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._indexBuffer);
129+
gl.drawElements(PIXI.Strip.DrawModes.TRIANGLE_STRIP, this.indices.length, gl.UNSIGNED_SHORT, 0);
130+
131+
};
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/**
2+
* @author Mat Groves http://matgroves.com/ @Doormat23
3+
*/
4+
5+
/**
6+
* @class TilemapShader
7+
* @constructor
8+
* @param gl {WebGLContext} the current WebGL drawing context
9+
*/
10+
PIXI.TilemapShader = function(gl)
11+
{
12+
/**
13+
* @property _UID
14+
* @type Number
15+
* @private
16+
*/
17+
this._UID = PIXI._UID++;
18+
19+
/**
20+
* @property gl
21+
* @type WebGLContext
22+
*/
23+
this.gl = gl;
24+
25+
/**
26+
* The WebGL program.
27+
* @property program
28+
* @type Any
29+
*/
30+
this.program = null;
31+
32+
/**
33+
* The fragment shader.
34+
* @property fragmentSrc
35+
* @type Array
36+
*/
37+
this.fragmentSrc = [
38+
'precision mediump float;',
39+
'varying vec2 vTextureCoord;',
40+
'varying vec4 vColor;',
41+
'uniform sampler2D uSampler;',
42+
'void main(void) {',
43+
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
44+
'}'
45+
];
46+
47+
/**
48+
* The vertex shader.
49+
* @property vertexSrc
50+
* @type Array
51+
*/
52+
this.vertexSrc = [
53+
'attribute vec2 aVertexPosition;',
54+
'attribute vec2 aTextureCoord;',
55+
'attribute vec4 aColor;',
56+
57+
'uniform vec2 projectionVector;',
58+
59+
'varying vec2 vTextureCoord;',
60+
'varying vec4 vColor;',
61+
62+
'const vec2 center = vec2(-1.0, 1.0);',
63+
64+
'void main(void) {',
65+
' gl_Position = vec4((aVertexPosition / projectionVector) + center, 0.0, 1.0);',
66+
' vTextureCoord = aTextureCoord;',
67+
' vec3 color = mod(vec3(aColor.y / 65536.0, aColor.y / 256.0, aColor.y), 256.0) / 256.0;',
68+
' vColor = vec4(color * aColor.x, aColor.x);',
69+
'}'
70+
];
71+
72+
this.init();
73+
};
74+
75+
PIXI.TilemapShader.prototype.constructor = PIXI.TilemapShader;
76+
77+
/**
78+
* Initialises the shader.
79+
*
80+
* @method init
81+
*/
82+
PIXI.TilemapShader.prototype.init = function()
83+
{
84+
var gl = this.gl;
85+
86+
var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
87+
88+
gl.useProgram(program);
89+
90+
// get and store the uniforms for the shader
91+
this.uSampler = gl.getUniformLocation(program, 'uSampler');
92+
93+
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
94+
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
95+
this.dimensions = gl.getUniformLocation(program, 'dimensions');
96+
// this.uMatrix = gl.getUniformLocation(program, 'uMatrix');
97+
98+
// get and store the attributes
99+
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
100+
this.aPositionCoord = gl.getAttribLocation(program, 'aPositionCoord');
101+
102+
this.aScale = gl.getAttribLocation(program, 'aScale');
103+
this.aRotation = gl.getAttribLocation(program, 'aRotation');
104+
105+
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
106+
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
107+
108+
this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute];
109+
110+
this.program = program;
111+
};
112+
113+
/**
114+
* Destroys the shader.
115+
*
116+
* @method destroy
117+
*/
118+
PIXI.StripShader.prototype.destroy = function()
119+
{
120+
this.gl.deleteProgram( this.program );
121+
this.uniforms = null;
122+
this.gl = null;
123+
124+
this.attribute = null;
125+
};

src/pixi/renderers/webgl/utils/WebGLShaderManager.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ PIXI.WebGLShaderManager.prototype.setContext = function(gl)
6666

6767
// the next one is used for rendering triangle strips
6868
this.stripShader = new PIXI.StripShader(gl);
69+
70+
this.tilemapShader = new PIXI.TilemapShader(gl);
71+
6972
this.setShader(this.defaultShader);
7073
};
7174

@@ -153,5 +156,7 @@ PIXI.WebGLShaderManager.prototype.destroy = function()
153156

154157
this.stripShader.destroy();
155158

159+
this.tilemapShader.destroy();
160+
156161
this.gl = null;
157162
};

0 commit comments

Comments
 (0)