<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL</title>
<script type="text/javascript" src="http://g...content-available-to-author-only...b.com/webgl-fundamentals/webgl/resources/webgl-utils.js"></script>
<script>
var gl;
function initGL() {
// Get A WebGL context
var canvas = document.getElementById("canvas");
gl = getWebGLContext(canvas);
if (!gl) {
return;
}
}
var positionLocation;
var resolutionLocation;
var colorLocation;
var translationLocation;
var rotationLocation;
var translation = [];
var rotation = [];
var angle;
function initShaders() {
// setup GLSL program
vertexShader = createShaderFromScriptElement(gl, "2d-vertex-shader");
fragmentShader = createShaderFromScriptElement(gl, "2d-fragment-shader");
program = createProgram(gl, [vertexShader, fragmentShader]);
gl.useProgram(program);
// look up where the vertex data needs to go.
positionLocation = gl.getAttribLocation(program, "a_position");
// lookup uniforms
resolutionLocation = gl.getUniformLocation(program, "u_resolution");
colorLocation = gl.getUniformLocation(program, "u_color");
translationLocation = gl.getUniformLocation(program, "u_translation");
rotationLocation = gl.getUniformLocation(program, "u_rotation");
// set the resolution
gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
}
function initBuffers() {
// Create a buffer.
var buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.enableVertexAttribArray(positionLocation);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
// Set Geometry.
setGeometry();
}
function setColor(red, green, blue) {
gl.uniform4f(colorLocation, red, green, blue, 1);
}
// Draw the scene.
function drawScene() {
// Set the translation.
gl.uniform2fv(translationLocation, translation);
// Set the rotation.
gl.uniform2fv(rotationLocation, rotation);
// Draw the geometry.
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
}
function setGeometry() {//Here is clearly set the x (100) larger than y (50)
var vertices = [
-100, -50,
-100, 50,
100, 50,
100, -50 ];
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(vertices),
gl.STATIC_DRAW);
}
function animate() {//I removed the animation so you could look at the problem specifically
translation[0] = 100;
translation[1] = 100;
angle = 0.0;
rotation[0] = Math.sin(angle);
rotation[1] = Math.cos(angle);
}
function tick() {
gl.clear(gl.COLOR_BUFFER_BIT);
requestAnimFrame(tick);
initBuffers();
animate();
drawScene();
}
function start() {
initGL();
initShaders();
setColor(0.2, 0.5, 0.5);
tick();
}
</script>
<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
attribute vec2 a_position;
uniform vec2 u_resolution;
uniform vec2 u_translation;
uniform vec2 u_rotation;
void main() {
vec2 rotatedPosition = vec2(
a_position.x * u_rotation.y + a_position.y * u_rotation.x,
a_position.y * u_rotation.y - a_position.x * u_rotation.x);
// Add in the translation.
vec2 position = rotatedPosition + u_translation;
// convert the position from pixels to 0.0 to 1.0
vec2 zeroToOne = position / u_resolution;
// convert from 0->1 to 0->2
vec2 zeroToTwo = zeroToOne * 2.0;
// convert from 0->2 to -1->+1 (clipspace)
vec2 clipSpace = zeroToTwo - 1.0;
gl_Position = vec4(clipSpace , 0, 1);
}
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 u_color;
void main() {
gl_FragColor = u_color;
}
</script>
</head>
<body onload = "start();">
<canvas id="canvas" width="900" height="500"></canvas>
</body>
</html>
PCFET0NUWVBFIGh0bWw+CjxodG1sPgo8aGVhZD4KPG1ldGEgY2hhcnNldD0idXRmLTgiPgo8dGl0bGU+V2ViR0w8L3RpdGxlPgogICAgPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaHR0cDovL2cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLmIuY29tL3dlYmdsLWZ1bmRhbWVudGFscy93ZWJnbC9yZXNvdXJjZXMvd2ViZ2wtdXRpbHMuanMiPjwvc2NyaXB0Pgo8c2NyaXB0PgogICAgdmFyIGdsOwogICAgZnVuY3Rpb24gaW5pdEdMKCkgewogICAgICAvLyBHZXQgQSBXZWJHTCBjb250ZXh0CiAgICAgIHZhciBjYW52YXMgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgiY2FudmFzIik7CiAgICAgIGdsID0gZ2V0V2ViR0xDb250ZXh0KGNhbnZhcyk7CiAgICAgIGlmICghZ2wpIHsKICAgICAgICByZXR1cm47CiAgICAgIH0KICAgIH0KICAgIHZhciBwb3NpdGlvbkxvY2F0aW9uOwogICAgdmFyIHJlc29sdXRpb25Mb2NhdGlvbjsKICAgIHZhciBjb2xvckxvY2F0aW9uOwogICAgdmFyIHRyYW5zbGF0aW9uTG9jYXRpb247CiAgICB2YXIgcm90YXRpb25Mb2NhdGlvbjsKICAgIHZhciB0cmFuc2xhdGlvbiA9IFtdOwogICAgdmFyIHJvdGF0aW9uID0gW107CiAgICB2YXIgYW5nbGU7CiAgICBmdW5jdGlvbiBpbml0U2hhZGVycygpIHsKICAgICAgLy8gc2V0dXAgR0xTTCBwcm9ncmFtCiAgICAgIHZlcnRleFNoYWRlciA9IGNyZWF0ZVNoYWRlckZyb21TY3JpcHRFbGVtZW50KGdsLCAiMmQtdmVydGV4LXNoYWRlciIpOwogICAgICBmcmFnbWVudFNoYWRlciA9IGNyZWF0ZVNoYWRlckZyb21TY3JpcHRFbGVtZW50KGdsLCAiMmQtZnJhZ21lbnQtc2hhZGVyIik7CiAgICAgIHByb2dyYW0gPSBjcmVhdGVQcm9ncmFtKGdsLCBbdmVydGV4U2hhZGVyLCBmcmFnbWVudFNoYWRlcl0pOwogICAgICBnbC51c2VQcm9ncmFtKHByb2dyYW0pOwoKICAgICAgLy8gbG9vayB1cCB3aGVyZSB0aGUgdmVydGV4IGRhdGEgbmVlZHMgdG8gZ28uCiAgICAgIHBvc2l0aW9uTG9jYXRpb24gPSBnbC5nZXRBdHRyaWJMb2NhdGlvbihwcm9ncmFtLCAiYV9wb3NpdGlvbiIpOwoKICAgICAgLy8gbG9va3VwIHVuaWZvcm1zCiAgICAgIHJlc29sdXRpb25Mb2NhdGlvbiA9IGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAidV9yZXNvbHV0aW9uIik7CiAgICAgIGNvbG9yTG9jYXRpb24gPSBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgInVfY29sb3IiKTsKICAgICAgdHJhbnNsYXRpb25Mb2NhdGlvbiA9IGdsLmdldFVuaWZvcm1Mb2NhdGlvbihwcm9ncmFtLCAidV90cmFuc2xhdGlvbiIpOwogICAgICAgIHJvdGF0aW9uTG9jYXRpb24gPSBnbC5nZXRVbmlmb3JtTG9jYXRpb24ocHJvZ3JhbSwgInVfcm90YXRpb24iKTsKCiAgICAgIC8vIHNldCB0aGUgcmVzb2x1dGlvbgogICAgICBnbC51bmlmb3JtMmYocmVzb2x1dGlvbkxvY2F0aW9uLCBjYW52YXMud2lkdGgsIGNhbnZhcy5oZWlnaHQpOwogICAgfQogICAgZnVuY3Rpb24gaW5pdEJ1ZmZlcnMoKSB7CiAgICAgIC8vIENyZWF0ZSBhIGJ1ZmZlci4KICAgICAgdmFyIGJ1ZmZlciA9IGdsLmNyZWF0ZUJ1ZmZlcigpOwogICAgICBnbC5iaW5kQnVmZmVyKGdsLkFSUkFZX0JVRkZFUiwgYnVmZmVyKTsKICAgICAgZ2wuZW5hYmxlVmVydGV4QXR0cmliQXJyYXkocG9zaXRpb25Mb2NhdGlvbik7CiAgICAgIGdsLnZlcnRleEF0dHJpYlBvaW50ZXIocG9zaXRpb25Mb2NhdGlvbiwgMiwgZ2wuRkxPQVQsIGZhbHNlLCAwLCAwKTsKICAgICAgICAKICAgICAgLy8gU2V0IEdlb21ldHJ5LgogICAgICBzZXRHZW9tZXRyeSgpOwogICAgfQoKICAgIGZ1bmN0aW9uIHNldENvbG9yKHJlZCwgZ3JlZW4sIGJsdWUpIHsKICAgICAgICBnbC51bmlmb3JtNGYoY29sb3JMb2NhdGlvbiwgcmVkLCBncmVlbiwgYmx1ZSwgMSk7CiAgICB9CiAgICAvLyBEcmF3IHRoZSBzY2VuZS4KICAgIGZ1bmN0aW9uIGRyYXdTY2VuZSgpIHsKICAgICAgICAvLyBTZXQgdGhlIHRyYW5zbGF0aW9uLgogICAgICAgIGdsLnVuaWZvcm0yZnYodHJhbnNsYXRpb25Mb2NhdGlvbiwgdHJhbnNsYXRpb24pOwogICAgICAgIC8vIFNldCB0aGUgcm90YXRpb24uCiAgICAgICAgZ2wudW5pZm9ybTJmdihyb3RhdGlvbkxvY2F0aW9uLCByb3RhdGlvbik7CgogICAgICAgIC8vIERyYXcgdGhlIGdlb21ldHJ5LgogICAgICAgIGdsLmRyYXdBcnJheXMoZ2wuVFJJQU5HTEVfRkFOLCAwLCA0KTsKICAgIH0KCgogICAgZnVuY3Rpb24gc2V0R2VvbWV0cnkoKSB7Ly9IZXJlIGlzIGNsZWFybHkgc2V0IHRoZSB4ICgxMDApIGxhcmdlciB0aGFuIHkgKDUwKQogICAgICAgIHZhciB2ZXJ0aWNlcyA9IFsKICAgICAgICAgICAgIC0xMDAsIC01MCwKICAgICAgICAgICAgIC0xMDAsIDUwLAogICAgICAgICAgICAgMTAwLCA1MCwKICAgICAgICAgICAgIDEwMCwgLTUwIF07CiAgICAgICAgICBnbC5idWZmZXJEYXRhKAogICAgICAgICAgICAgZ2wuQVJSQVlfQlVGRkVSLAogICAgICAgICAgICAgbmV3IEZsb2F0MzJBcnJheSh2ZXJ0aWNlcyksCiAgICAgICAgICAgICBnbC5TVEFUSUNfRFJBVyk7CiAgICB9CgogICAgZnVuY3Rpb24gYW5pbWF0ZSgpIHsvL0kgcmVtb3ZlZCB0aGUgYW5pbWF0aW9uIHNvIHlvdSBjb3VsZCBsb29rIGF0IHRoZSBwcm9ibGVtIHNwZWNpZmljYWxseQogICAgICAgIHRyYW5zbGF0aW9uWzBdID0gMTAwOwogICAgICAgIHRyYW5zbGF0aW9uWzFdID0gMTAwOwogICAgYW5nbGUgPSAwLjA7CiAgICAgICAgcm90YXRpb25bMF0gPSBNYXRoLnNpbihhbmdsZSk7CiAgICAgICAgcm90YXRpb25bMV0gPSBNYXRoLmNvcyhhbmdsZSk7CiAgICB9CiAgICBmdW5jdGlvbiB0aWNrKCkgewogICAgICAgIGdsLmNsZWFyKGdsLkNPTE9SX0JVRkZFUl9CSVQpOwogICAgICAgIHJlcXVlc3RBbmltRnJhbWUodGljayk7CiAgICAgICAgaW5pdEJ1ZmZlcnMoKTsKICAgICAgICBhbmltYXRlKCk7CiAgICAgICAgZHJhd1NjZW5lKCk7CiAgICB9CiAgICAKICAgIGZ1bmN0aW9uIHN0YXJ0KCkgewogICAgICAgIGluaXRHTCgpOwogICAgICAgIGluaXRTaGFkZXJzKCk7CiAgICAgICAgc2V0Q29sb3IoMC4yLCAwLjUsIDAuNSk7CiAgICAgICAgdGljaygpOwogICAgfQo8L3NjcmlwdD4KICAgICAgICAKPCEtLSB2ZXJ0ZXggc2hhZGVyIC0tPgo8c2NyaXB0IGlkPSIyZC12ZXJ0ZXgtc2hhZGVyIiB0eXBlPSJ4LXNoYWRlci94LXZlcnRleCI+CiAgICBhdHRyaWJ1dGUgdmVjMiBhX3Bvc2l0aW9uOwoKICAgIHVuaWZvcm0gdmVjMiB1X3Jlc29sdXRpb247CiAgICB1bmlmb3JtIHZlYzIgdV90cmFuc2xhdGlvbjsKICAgIHVuaWZvcm0gdmVjMiB1X3JvdGF0aW9uOwogICAgdm9pZCBtYWluKCkgewogICAgICAgIHZlYzIgcm90YXRlZFBvc2l0aW9uID0gdmVjMigKICAgICAgICBhX3Bvc2l0aW9uLnggKiB1X3JvdGF0aW9uLnkgKyBhX3Bvc2l0aW9uLnkgKiB1X3JvdGF0aW9uLngsCiAgICAgICAgYV9wb3NpdGlvbi55ICogdV9yb3RhdGlvbi55IC0gYV9wb3NpdGlvbi54ICogdV9yb3RhdGlvbi54KTsKICAgICAgICAKICAgICAgIC8vIEFkZCBpbiB0aGUgdHJhbnNsYXRpb24uCiAgICAgICB2ZWMyIHBvc2l0aW9uID0gcm90YXRlZFBvc2l0aW9uICsgdV90cmFuc2xhdGlvbjsKCiAgICAgICAvLyBjb252ZXJ0IHRoZSBwb3NpdGlvbiBmcm9tIHBpeGVscyB0byAwLjAgdG8gMS4wCiAgICAgICB2ZWMyIHplcm9Ub09uZSA9IHBvc2l0aW9uIC8gdV9yZXNvbHV0aW9uOwoKICAgICAgIC8vIGNvbnZlcnQgZnJvbSAwLT4xIHRvIDAtPjIKICAgICAgIHZlYzIgemVyb1RvVHdvID0gemVyb1RvT25lICogMi4wOwoKICAgICAgIC8vIGNvbnZlcnQgZnJvbSAwLT4yIHRvIC0xLT4rMSAoY2xpcHNwYWNlKQogICAgICAgdmVjMiBjbGlwU3BhY2UgPSB6ZXJvVG9Ud28gLSAxLjA7CgogICAgICAgZ2xfUG9zaXRpb24gPSB2ZWM0KGNsaXBTcGFjZSAsIDAsIDEpOwogICAgfQo8L3NjcmlwdD4KPCEtLSBmcmFnbWVudCBzaGFkZXIgLS0+CjxzY3JpcHQgaWQ9IjJkLWZyYWdtZW50LXNoYWRlciIgdHlwZT0ieC1zaGFkZXIveC1mcmFnbWVudCI+CiAgICBwcmVjaXNpb24gbWVkaXVtcCBmbG9hdDsKCiAgICB1bmlmb3JtIHZlYzQgdV9jb2xvcjsKCiAgICB2b2lkIG1haW4oKSB7CiAgICAgICBnbF9GcmFnQ29sb3IgPSB1X2NvbG9yOwogICAgfQo8L3NjcmlwdD4KPC9oZWFkPgo8Ym9keSBvbmxvYWQgPSAic3RhcnQoKTsiPgoKICAgIDxjYW52YXMgaWQ9ImNhbnZhcyIgd2lkdGg9IjkwMCIgaGVpZ2h0PSI1MDAiPjwvY2FudmFzPgo8L2JvZHk+CjwvaHRtbD4=