Skip to content

Instantly share code, notes, and snippets.

@peace098beat
Created November 18, 2018 04:03
Show Gist options
  • Save peace098beat/453fa9c6e6c21c41296501ac8a26ea7b to your computer and use it in GitHub Desktop.
Save peace098beat/453fa9c6e6c21c41296501ac8a26ea7b to your computer and use it in GitHub Desktop.
WebGLの基本[2]
<!DOCTYPE html>
<html>
<body>
<style type="text/css">
body {
border: 1;
background-color: gray;
}
#c {
/* 表示サイズ */
width: 500px;
height: 500px;
display: block;
}
</style>
<canvas id="c"></canvas>
<pre id="debug"></pre>
</body>
</html>
<!--2018-11-18 12:21-13:03 -->
<!--
* Vertex Shader
-->
<script type="notjs" id="2d-vertex-shader">
attribute vec2 a_position; uniform vec2 u_resolution; void main(){ vec2 zeroToOne = a_position / u_resolution; vec2 zeroToTwo = 2.0 * zeroToOne; vec2 clipSpace = zeroToTwo - 1.0; gl_Position = vec4(clipSpace*vec2(1,-1), 0, 1); }
</script>
<!--
- Fragment Shader
-->
<script type="notjs" id="2d-flagment-shader">
precision mediump float; uniform vec4 u_color; void main(){ gl_FragColor = u_color; }
</script>
<!--
- Main Source
-->
<script type="text/javascript">
/**
* デバッグプリント
*/
console.log = function(text) {
text = "[DEBUG] " + text + ";";
let pre = document.getElementById("debug");
// console.log(text);
pre.innerHTML += text + "<br>";
}
"use strict";
console.log("main start");
let canvas = document.getElementById("c");
let gl = canvas.getContext("webgl");
canvas = document.getElementById("c");
canvas.width = 500; // 描画バッファーのサイズ
canvas.height = 500; // 描画バッファのサイズ
/**
* シェーダーをコンパイルする
* ヘルパー関数
*/
function createShader(gl, type, source) {
let shader = gl.createShader(type);
gl.shaderSource(shader, source);
gl.compileShader(shader);
let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
}
else {
console.log(gl.getShaderInfoLog(shader));
gl.deleteShader(shader);
}
}
let vertexShaderSourceText = document.getElementById("2d-vertex-shader").text;
let fragmentShaderSourceText = document.getElementById("2d-flagment-shader").text;
let vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSourceText);
let fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSourceText);
/**
* 2つのシェーダをプログラムにリンクする
*/
function createProgram(gl, vertexShader, fragmentShader) {
let program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
// 例外処理
let success = gl.getProgramParameter(program, gl.LINK_STATUS);
if (success) {
console.log("success createProgram");
return program;
}
else {
console.log(gl.getProgramInfoLog(program));
gl.deleteProgram(program);
}
}
let program = createProgram(gl, vertexShader, fragmentShader);
// ↑までが、GLSLのコードをGPUにアップロードするまで
// 解像度
let resolutionUniformLocation = gl.getUniformLocation(program, "u_resolution");
// 頂点位置
let positionAttributeLocation = gl.getAttribLocation(program, "a_position");
let positionBuffer = gl.createBuffer();
var positions = [
10, 20,
80, 20,
10, 30,
10, 30,
80, 20,
80, 30,
];
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); // データをバッファに入れる
// **************************************************** //
// 描画
// **************************************************** //
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
// 解像度をbind
gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
// 頂点バッファーをbind
gl.enableVertexAttribArray(positionAttributeLocation); // ON
var size = 2; // 2つづつ呼び出す
var type = gl.FLOAT;
var normalize = false;
var stride = 0; // 0: = size*sizeof(type);
var offset = 0; // バッファ先頭から取り出す
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset);
// 図形の描画
// var primitiveType = gl.LIENS;
// var offset = 0; // 開始のオフセット
// var count = 6; // 頂点の数
// gl.drawArrays(primitiveType, offset, count);
// 色のポインタ?
let colorUniformLocation = gl.getUniformLocation(program, "u_color");
for (var ii = 0; ii < 2000; ++ii) {
// 四角の座標を生成
let _postions = setRectangle(gl, randomInt(250), randomInt(250), randomInt(250), randomInt(250));
// 四角の頂点を送信
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(_postions), gl.STATIC_DRAW);
// 色を選択
let r = Math.random();
let g = Math.random();
let b = Math.random();
gl.uniform4f(colorUniformLocation, r, g, b, 1);
// 4角形を描画
gl.drawArrays(gl.LINES, 0, 6);
}
function tick() {
gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
for (var ii = 0; ii < 2000; ++ii) {
// 四角の座標を生成
let _postions = setRectangle(gl, randomInt(250), randomInt(250), randomInt(250), randomInt(250));
// 四角の頂点を送信
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(_postions), gl.STATIC_DRAW);
// 色を選択
let r = Math.random();
let g = Math.random();
let b = Math.random();
gl.uniform4f(colorUniformLocation, r, g, b, 1);
// 4角形を描画
gl.drawArrays(gl.LINES, 0, 6);
}
// console.log("tick");
requestAnimationFrame(tick);
}
tick();
function randomInt(range) {
return Math.floor(Math.random() * range);
}
function setRectangle(gl, x, y, width, height) {
let x1 = x;
let y1 = y;
let x2 = x + width;
let y2 = y + height;
let positions = [
x1, y1,
x2, y1,
x1, y2,
x1, y2,
x2, y1,
x2, y2
];
return positions;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment