Multiply projection and model matrices in shader

This will allow rendering the primary view, picking view, and "touching
color" view with different projection matrices without needing to
recalculate the model matrix for every Drawable every time.
This commit is contained in:
Christopher Willis-Ford
2016-05-27 11:55:15 -07:00
parent c24cfaaf4c
commit 36439bf665
3 changed files with 13 additions and 24 deletions

View File

@@ -24,10 +24,10 @@ function Drawable(renderer, gl) {
*/
this._uniforms = {
/**
* The model-view-projection matrix.
* The model matrix, to concat with the projection matrix at draw time.
* @type {module:twgl/m4.Mat4}
*/
u_mvp: twgl.m4.identity(),
u_modelMatrix: twgl.m4.identity(),
/**
* The nominal (not necessarily current) size of the current skin.
@@ -131,19 +131,6 @@ Drawable.getDrawableByID = function (drawableID) {
return Drawable._allDrawables[drawableID];
};
/**
* Dirty the transforms of all Drawables.
* Call this when the projection matrix changes, for example.
*/
Drawable.dirtyAllTransforms = function () {
for (var drawableID in Drawable._allDrawables) {
if (Drawable._allDrawables.hasOwnProperty(drawableID)) {
var drawable = Drawable._allDrawables[drawableID];
drawable.setTransformDirty();
}
}
};
// TODO: fall back on a built-in skin to protect against network problems
Drawable._DEFAULT_SKIN = {
squirrel: '7e24c99c1b853e52f8e7f9004416fa34.png',
@@ -403,18 +390,18 @@ Drawable.prototype._setSkinSize = function (width, height, costumeResolution) {
* @private
*/
Drawable.prototype._calculateTransform = function () {
var mvp = this._uniforms.u_mvp;
var modelMatrix = this._uniforms.u_modelMatrix;
var projection = this._renderer.getProjectionMatrix();
twgl.m4.translate(projection, this._position, mvp);
twgl.m4.identity(modelMatrix);
twgl.m4.translate(modelMatrix, this._position, modelMatrix);
var rotation = (270 - this._direction) * Math.PI / 180;
twgl.m4.rotateZ(mvp, rotation, mvp);
twgl.m4.rotateZ(modelMatrix, rotation, modelMatrix);
var scaledSize = twgl.v3.mulScalar(
this._uniforms.u_skinSize, this._scale / 100);
scaledSize[2] = 0; // was NaN because u_skinSize has only 2 components
twgl.m4.scale(mvp, scaledSize, mvp);
twgl.m4.scale(modelMatrix, scaledSize, modelMatrix);
this._transformDirty = false;
};

View File

@@ -79,7 +79,6 @@ RenderWebGL.prototype.setStageSize = function (xLeft, xRight, yBottom, yTop) {
this._yBottom = yBottom;
this._yTop = yTop;
this._projection = twgl.m4.ortho(xLeft, xRight, yBottom, yTop, -1, 1);
Drawable.dirtyAllTransforms();
};
/**
@@ -118,9 +117,11 @@ RenderWebGL.prototype.draw = function () {
currentShader = newShader;
gl.useProgram(currentShader.program);
twgl.setBuffersAndAttributes(gl, currentShader, this._bufferInfo);
twgl.setUniforms(
currentShader, {u_projectionMatrix: this._projection});
twgl.setUniforms(currentShader, {u_fudge: window.fudge || 0});
}
twgl.setUniforms(currentShader, drawable.getUniforms());
twgl.setUniforms(currentShader, {u_fudge: window.fudge || 0});
twgl.drawBufferInfo(gl, gl.TRIANGLES, this._bufferInfo);
}
};

View File

@@ -1,4 +1,5 @@
uniform mat4 u_mvp;
uniform mat4 u_projectionMatrix;
uniform mat4 u_modelMatrix;
attribute vec2 a_position;
attribute vec2 a_texCoord;
@@ -6,6 +7,6 @@ attribute vec2 a_texCoord;
varying vec2 v_texCoord;
void main() {
gl_Position = u_mvp * vec4(a_position, 0, 1);
gl_Position = u_projectionMatrix * u_modelMatrix * vec4(a_position, 0, 1);
v_texCoord = a_texCoord;
}