kopia lustrzana https://github.com/cyoung/stratux
207 wiersze
6.4 KiB
JavaScript
207 wiersze
6.4 KiB
JavaScript
function ahrsRenderer(location_id) {
|
|
this.gcontext = {}; // globals
|
|
this.gl = null;
|
|
|
|
this.width = -1;
|
|
this.height = -1;
|
|
|
|
this.locationID = location_id;
|
|
this.canvas = document.getElementById(location_id);
|
|
this.canvas_container = document.getElementById(location_id).parentElement;
|
|
}
|
|
|
|
ahrsRenderer.prototype = {
|
|
constructor: ahrsRenderer,
|
|
|
|
_init_canvas: function () {
|
|
var gl = initWebGL(this.locationID);
|
|
if (!gl)
|
|
return;
|
|
this.gl = gl;
|
|
|
|
vertex_shader = 'uniform mat4 u_modelViewProjMatrix; uniform mat4 u_normalMatrix; uniform vec3 lightDir; attribute vec3 vNormal; attribute vec4 vColor; attribute vec4 vPosition; varying float v_Dot; varying vec4 v_Color; void main() { gl_Position = u_modelViewProjMatrix * vPosition; v_Color = vColor; vec4 transNormal = u_normalMatrix * vec4(vNormal, 1); v_Dot = max(dot(transNormal.xyz, lightDir), 0.0); }';
|
|
fragment_shader = 'precision mediump float; varying float v_Dot; varying vec4 v_Color; void main() { gl_FragColor = vec4(v_Color.xyz * v_Dot, v_Color.a * 0.95); }';
|
|
|
|
var vertexShader = loadShaderVertexScript(gl, vertex_shader);
|
|
var fragmentShader = loadShaderFragmentScript(gl, fragment_shader);
|
|
|
|
var program = gl.createProgram();
|
|
|
|
gl.attachShader(program, vertexShader);
|
|
gl.attachShader(program, fragmentShader);
|
|
|
|
// Bind attributes
|
|
gl.bindAttribLocation(program, 0, "vNormal");
|
|
gl.bindAttribLocation(program, 1, "vColor");
|
|
gl.bindAttribLocation(program, 2, "vPosition");
|
|
|
|
gl.linkProgram(program);
|
|
|
|
var linked = gl.getProgramParameter(program, gl.LINK_STATUS);
|
|
if (!linked && !gl.isContextLost()) {
|
|
// something went wrong with the link
|
|
var error = gl.getProgramInfoLog(program);
|
|
log("Error in program linking:" + error);
|
|
gl.deleteProgram(program);
|
|
gl.deleteProgram(fragmentShader);
|
|
gl.deleteProgram(vertexShader);
|
|
} else {
|
|
gl.useProgram(program);
|
|
gl.clearColor(0, 0, 0, 0) // rgba for background color
|
|
gl.clearDepth(10000); //??
|
|
|
|
if (false /* funcky blending */ ) {
|
|
gl.disable(gl.DEPTH_TEST);
|
|
gl.enable(gl.BLEND);
|
|
gl.depthFunc(gl.LESS);
|
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
|
|
} else {
|
|
gl.enable(gl.DEPTH_TEST);
|
|
gl.enable(gl.BLEND);
|
|
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
}
|
|
|
|
this.gcontext.program = program;
|
|
}
|
|
},
|
|
|
|
init: function () {
|
|
this._init_canvas(); // init the canvas
|
|
g = this.gcontext;
|
|
gl = this.gl;
|
|
|
|
if (gl === null)
|
|
return;
|
|
|
|
// Set up a uniform variable for the shaders
|
|
gl.uniform3f(gl.getUniformLocation(g.program, "lightDir"), 0, 1, -1);
|
|
|
|
// Create a box. On return 'gl' contains a 'box' property with
|
|
// the BufferObjects containing the arrays for vertices,
|
|
// normals, texture coords, and indices.
|
|
// g.box = makeBox(gl);
|
|
g.box = makePaperAirplane(gl);
|
|
|
|
// Create some matrices to use later and save their locations in the shaders
|
|
g.mvMatrix = new J3DIMatrix4();
|
|
g.u_normalMatrixLoc = gl.getUniformLocation(g.program, "u_normalMatrix");
|
|
g.normalMatrix = new J3DIMatrix4();
|
|
g.u_modelViewProjMatrixLoc =
|
|
gl.getUniformLocation(g.program, "u_modelViewProjMatrix");
|
|
g.mvpMatrix = new J3DIMatrix4();
|
|
|
|
// Enable all of the vertex attribute arrays.
|
|
gl.enableVertexAttribArray(0);
|
|
gl.enableVertexAttribArray(1);
|
|
gl.enableVertexAttribArray(2);
|
|
// Set up all the vertex attributes for vertices, normals and colors
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, g.box.vertexObject);
|
|
gl.vertexAttribPointer(2, 3, gl.FLOAT, false, 0, 0);
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, g.box.normalObject);
|
|
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
|
|
gl.bindBuffer(gl.ARRAY_BUFFER, g.box.colorObject);
|
|
gl.vertexAttribPointer(1, 4, gl.UNSIGNED_BYTE, false, 0, 0);
|
|
|
|
// Bind the index array
|
|
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, g.box.indexObject);
|
|
|
|
this.pitch = 0;
|
|
this.roll = 0;
|
|
this.heading = 0;
|
|
|
|
this.resize();
|
|
},
|
|
|
|
resize: function () {
|
|
gl = this.gl;
|
|
g = this.gcontext;
|
|
if (gl === null)
|
|
return;
|
|
|
|
var canvasWidth = this.canvas_container.offsetWidth - 12; // was (2*(this.canvas_container.offsetLeft)) // account for padding adjustments
|
|
|
|
if (canvasWidth !== this.width) {
|
|
this.width = canvasWidth;
|
|
this.height = canvasWidth *0.5;
|
|
|
|
this.canvas.width = this.width;
|
|
this.canvas.height = this.height;
|
|
// Set the viewport and projection matrix for the scene
|
|
gl.viewport(0, 0, this.width, this.height);
|
|
g.perspectiveMatrix = new J3DIMatrix4();
|
|
g.perspectiveMatrix.perspective(30, this.width / this.height, 1, 10000);
|
|
g.perspectiveMatrix.lookat( 0, 0, 4, // eye location
|
|
0, 0, 0, // focal point
|
|
0, 1, 0); // up vector
|
|
}
|
|
},
|
|
|
|
orientation: function (x, y, z) {
|
|
if (x > 360) x -= 360;
|
|
if (y > 360) y -= 360;
|
|
if (z > 360) z -= 360;
|
|
this.pitch = x; // need to reorient to level
|
|
this.roll = y;
|
|
this.heading = z;
|
|
},
|
|
|
|
animate: function (t, x, y, z) {
|
|
var FPS = 24; // we assume we can maintain a certain frame rate
|
|
var x_inc = ((x - this.pitch) / (FPS * t));
|
|
var y_inc = ((y - this.roll) / (FPS * t));
|
|
// let the animation wrap aroung gracefully
|
|
if ((z < this.heading) && (this.heading - z) > 180)
|
|
z += 360;
|
|
var z_inc = ((z - this.heading) / (FPS * t));
|
|
var _this = this;
|
|
//console.log(z_inc);
|
|
var frames = 0;
|
|
var f = function () {
|
|
_this.pitch += x_inc;
|
|
_this.roll += y_inc;
|
|
_this.heading += z_inc;
|
|
if (frames < (FPS * t)) {
|
|
_this.draw();
|
|
frames++
|
|
window.requestAnimationFrame(f, _this.canvas); // recurse
|
|
} else {
|
|
_this.orientation(x, y, z);
|
|
}
|
|
};
|
|
f();
|
|
},
|
|
|
|
draw: function () {
|
|
this.resize();
|
|
gl = this.gl;
|
|
g = this.gcontext;
|
|
if (gl === null)
|
|
return;
|
|
|
|
// Clear the canvas
|
|
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
|
|
// Make a model/view matrix.
|
|
g.mvMatrix.makeIdentity();
|
|
|
|
g.mvMatrix.rotate(15, 1, 0, 0); // adjust viewing angle slightly by pitching the airplane up
|
|
|
|
g.mvMatrix.rotate(-this.pitch, 1, 0, 0);
|
|
g.mvMatrix.rotate(-this.roll, 0, 0, 1);
|
|
g.mvMatrix.rotate(-this.heading, 0, 1, 0);
|
|
|
|
// Construct the normal matrix from the model-view matrix and pass it in
|
|
g.normalMatrix.load(g.mvMatrix);
|
|
g.normalMatrix.invert();
|
|
g.normalMatrix.transpose();
|
|
g.normalMatrix.setUniform(gl, g.u_normalMatrixLoc, false);
|
|
|
|
// Construct the model-view * projection matrix and pass it in
|
|
g.mvpMatrix.load(g.perspectiveMatrix);
|
|
g.mvpMatrix.multiply(g.mvMatrix);
|
|
g.mvpMatrix.setUniform(gl, g.u_modelViewProjMatrixLoc, false);
|
|
|
|
// Draw the object
|
|
gl.drawElements(gl.TRIANGLES, g.box.numIndices, gl.UNSIGNED_BYTE, 0);
|
|
}
|
|
} |