<!doctype html>
<head>
<title>cube1</title>
<script src="minMatrix.js"></script>
</head>
<body>
<canvas id="canvas" width="640" height="480"></canvas>
<div id="msg"></div>
<script id="vs" type="text/x-vertex">
// 頂点シェイダー
attribute vec3 position;
attribute vec4 color;
uniform mat4 mvpMatrix;
varying vec4 vColor;
void main(void) {
vColor = color;
gl_Position = mvpMatrix * vec4(position, 1.0);
}
</script>
<script id="fs" type="text/x-fragment">
// 断片シェイダー
precision mediump float;
varying vec4 vColor;
void main(void) {
gl_FragColor = vColor;
}
</script>
<script>
var gl; // webgl context
var mat = new matIV();
var pMatrix = mat.create(); // perspective
var indexCount;
var loc = {};
var angle = 0;
var fps;
var fpsCount;
var secSave;
onload = function() {
gl = canvas.getContext("experimental-webgl");
var vShader = createShader("vs");
var fShader = createShader("fs");
var program = createProgram(vShader, fShader);
gl.useProgram(program);
var model = cube();
var vbo = createVbo(model.positions);
setAttribute(program, "position", vbo, 3);
var vbo = createVbo(model.colors);
setAttribute(program, "color", vbo, 4);
var ibo = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Int16Array(model.indices), gl.STATIC_DRAW);
indexCount = model.indices.length;
loc.mvpMatrix = gl.getUniformLocation(program, "mvpMatrix");
mat.perspective(45, canvas.width / canvas.height, 0.1, 10, pMatrix);
gl.enable(gl.CULL_FACE);
gl.frontFace(gl.CW);
gl.enable(gl.DEPTH_TEST);
gl.depthFunc(gl.LEQUAL);
draw();
};
function draw() {
var sec = (new Date()).getSeconds();
if (secSave != sec) {
fps = fpsCount;
fpsCount = 0;
secSave = sec;
}
fpsCount++;
msg.innerHTML = "fps=" + fps + " angle=" + angle;
gl.clearColor(0x64 / 0xff, 0x95 / 0xff, 0xed / 0xff, 1.0);
gl.clearDepth(1.0);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
var vMatrix = mat.create();
var vpMatrix = mat.create();
var mvpMatrix = mat.create();
mat.lookAt([0, 1, 3], [0, 0, 0], [0, 1, 0], vMatrix);
mat.multiply(pMatrix, vMatrix, vpMatrix);
angle = (angle + 2) % 360;
var rad = angle * Math.PI / 180;
var mMatrix = mat.identity(mat.create());
mat.rotate(mMatrix, rad, [0, 1, 0], mMatrix);
mat.multiply(vpMatrix, mMatrix, mvpMatrix);
gl.uniformMatrix4fv(loc.mvpMatrix, false, mvpMatrix);
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_SHORT, 0);
gl.flush();
setTimeout(draw, 1000 / 30);
}
function createShader(id) {
var element = document.getElementById(id);
if (! element) return;
const types = {
"text/x-vertex": gl.VERTEX_SHADER,
"text/x-fragment": gl.FRAGMENT_SHADER,
};
var shader = gl.createShader(types[element.type]);
gl.shaderSource(shader, element.text);
gl.compileShader(shader);
if (! gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return;
}
return shader;
}
function createProgram(vs, fs) {
var program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (! gl.getProgramParameter(program, gl.LINK_STATUS)) {
alert(gl.getProgramInfoLog(program));
return;
}
return program;
}
function createVbo(data) {
var vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
return vbo;
}
function setAttribute(program, name, vbo, stride) {
var location = gl.getAttribLocation(program, name);
gl.enableVertexAttribArray(location);
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.vertexAttribPointer(location, stride, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, null);
}
function cube() {
var model = {};
model.positions = [
-0.5, -0.5, 0.5,
0.5, -0.5, 0.5,
0.5, -0.5, -0.5,
-0.5, -0.5, -0.5,
-0.5, 0.5, 0.5,
0.5, 0.5, 0.5,
0.5, 0.5, -0.5,
-0.5, 0.5, -0.5,
];
model.colors = [
0, 0, 1, 1,
1, 0, 1, 1,
1, 0, 0, 1,
0, 0, 0, 1,
0, 1, 1, 1,
1, 1, 1, 1,
1, 1, 0, 1,
0, 1, 0, 1,
];
model.indices = [
0, 4, 5, 5, 1, 0,
1, 5, 6, 6, 2, 1,
2, 6, 7, 7, 3, 2,
3, 7, 4, 4, 0, 3,
4, 7, 6, 6, 5, 4,
2, 1, 0, 0, 3, 2,
];
return model;
}
</script>
</body>