Maiden webgl show.
Refered from https://webglfundamentals.org.
license: mit |
Maiden webgl show.
Refered from https://webglfundamentals.org.
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
canvas { outline: 1px dotted gray; } | |
</style> | |
</head> | |
<script id="shader-vs" type="x-shader/x-vertex"> | |
attribute vec2 a_position; | |
uniform vec2 u_resolution; | |
uniform vec2 u_translation; | |
uniform vec2 u_rotation; | |
uniform vec2 u_scale; | |
void main () { | |
// scale the position | |
vec2 scaledPosition = a_position * u_scale; | |
// rotate the position | |
vec2 rotatedPosition = vec2( | |
scaledPosition.x * u_rotation.y + scaledPosition.y * u_rotation.x, | |
scaledPosition.y * u_rotation.y - scaledPosition.x * u_rotation.x | |
//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 rectangle points from pixel 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 * vec2(1, -1), 0, 1); | |
} | |
</script> | |
<script id="shader-fs" type="x-shader/x-fragment"> | |
precision mediump float; | |
uniform vec4 u_color; | |
void main () { | |
gl_FragColor = u_color; | |
} | |
</script> | |
<canvas id="webgl" width="500" height="300"></canvas> | |
<body> | |
<script> | |
function main () { | |
var canvas = document.getElementById("webgl"); | |
var gl = canvas.getContext("webgl"); | |
var program = webglUtils.createProgramFromScripts(gl, | |
["shader-vs", "shader-fs"]); | |
// look up where the vertex data needs to go | |
var positionLocation = gl.getAttribLocation(program, "a_position"); | |
// look up uniforms | |
var resolutionLocation = gl.getUniformLocation(program, "u_resolution"); | |
var colorLocation = gl.getUniformLocation(program, "u_color"); | |
var translationLocation = gl.getUniformLocation(program, "u_translation"); | |
var rotationLocation = gl.getUniformLocation(program, "u_rotation"); | |
var scaleLocation = gl.getUniformLocation(program, "u_scale"); | |
// create a buffer to put position in | |
var positionBuffer = gl.createBuffer(); | |
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); | |
var gui = new dat.GUI(); | |
var obj = {moveX: 200, moveY: 120, angle: 90, scaleX: 1, scaleY: 1}; | |
var translation = [200, 120]; | |
var rotation = [0, 1]; | |
var scale = [obj.scaleX, obj.scaleY]; | |
var width = 100, height = 30; | |
var color = [Math.random(), Math.random(), Math.random(), 1]; | |
gui.add(obj, "moveX").min(0).max(canvas.width) | |
.onChange(function (value) { | |
translation[0] = value; | |
drawScene(); | |
}); | |
gui.add(obj, "moveY").min(0).max(canvas.height) | |
.onChange(function (value) { | |
translation[1] = value; | |
drawScene(); | |
}); | |
gui.add(obj, "angle").min(0).max(360).onChange(function (val) { | |
var rad = val * Math.PI / 180; | |
rotation = [Math.cos(rad), Math.sin(rad)]; | |
drawScene(); | |
}); | |
gui.add(obj, "scaleX").min(-2).max(2).onChange(function(val) { | |
obj.scaleX = val; | |
scale = [obj.scaleX, obj.scaleY]; | |
drawScene(); | |
}); | |
gui.add(obj, "scaleY").min(-2).max(2).onChange(function(val) { | |
obj.scaleY = val; | |
scale = [obj.scaleX, obj.scaleY]; | |
drawScene(); | |
}); | |
drawScene(); | |
function drawScene () { | |
webglUtils.resizeCanvasToDisplaySize(gl.canvas); | |
// tell webgl hwo to convert from clip space to pixels | |
gl.viewport(0, 0, canvas.width, canvas.height); | |
// clear the canvas | |
gl.clear(gl.COLOR_BUFFER_BIT); | |
// tell it user our program; | |
gl.useProgram(program); | |
// turn on the attribute | |
gl.enableVertexAttribArray(positionLocation); | |
// bind the positon buffer | |
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); | |
// setup a rectangel | |
setRectangle(gl, translation[0], translation[1], width, height); | |
// tell the attribute how to get data out of position buffer | |
var size = 2; | |
var type = gl.FLOAT; | |
var normalized = false; | |
var stride = 0; | |
var offset = 0; | |
gl.vertexAttribPointer(positionLocation, size, type, normalized, stride, offset); | |
// set the resolution | |
gl.uniform2f(resolutionLocation, canvas.width, canvas.height); | |
// set the color | |
gl.uniform4fv(colorLocation, color); | |
// set the translation | |
gl.uniform2fv(translationLocation, translation); | |
// set the rotation | |
gl.uniform2fv(rotationLocation, rotation); | |
// set the scale | |
gl.uniform2fv(scaleLocation, scale); | |
// draw the rectangle | |
gl.drawArrays(gl.TRIANGLES, 0, 18); | |
} | |
function setRectangle (gl, x, y, width, height) { | |
gl.bufferData( | |
gl.ARRAY_BUFFER, | |
new Float32Array([ | |
// left column | |
0, 0, | |
30, 0, | |
0, 150, | |
0, 150, | |
30, 0, | |
30, 150, | |
// top rung | |
30, 0, | |
100, 0, | |
30, 30, | |
30, 30, | |
100, 0, | |
100, 30, | |
// middle rung | |
30, 60, | |
67, 60, | |
30, 90, | |
30, 90, | |
67, 60, | |
67, 90, | |
]), | |
gl.STATIC_DRAW | |
); | |
} | |
} | |
main(); | |
</script> | |
</body> |