lightgl.js を使って OpenGL のコードを JavaScript に移植してみる

inomasa さんの OpenGL のサンプルコード「[C++ GLUT OpenGL 媒介変数の描画](http://qiita.com/inomasa/items/51bfc21259ebf2be8813)」が JavaScript に移植しやすそうだったので、試しに移植してみました。

移植には、[以前](http://qiita.com/cx20/items/22814731a1e39daf6a1e)、紹介した軽量 WebGL ライブラリ「[lightgl.js](https://github.com/evanw/lightgl.js/)」を用いています。
[lightgl.js](https://github.com/evanw/lightgl.js/) には「[OpenGL immediate mode](http://evanw.github.io/lightgl.js/tests/immediatemode.html)」というモードがあり、ほぼ OpenGL の書き方のまま JavaScript に移植することが可能となっています。

```html:index.html
<script src="lightgl.js"></script>
```

```js:index.js
var gl = GL.create();

function rad(i){
    return (i * Math.PI / 180);
}

gl.ondraw = function() {
    gl.clearColor(0.0, 0.0, 0.0, 1.0);
    gl.clear(gl.COLOR_BUFFER_BIT);
    gl.translate(0, 0, -2.5);

    drawGraph();     // 基準線の描画
    drawCycloid();   // サイクロイド曲線
    drawAsteroid();  // アステロイド曲線(星芒形)
    drawCardioid();  // カージオイド曲線(心臓型)
    drawInvolute();  // インボリュード曲線
    drawLissajous(); // リサージュ図形
};

// 基準線の描画
function drawGraph() {
    gl.begin(gl.LINES);
    gl.color(1.0, 1.0, 1.0);
    gl.vertex(-1.0, 0.0, 0.0);
    gl.vertex(1.0, 0.0, 0.0);
    gl.vertex(0.0, 1.0, 0.0);
    gl.vertex(0.0, -1.0, 0.0);
    gl.end();
}

// サイクロイド曲線
function drawCycloid() {
    var a = 0.5 / Math.PI;
    gl.color(0.0, 0.0, 1.0);
    gl.begin(gl.POINTS);
    for (var i = 0; i < 360; ++i) {
        var x = a * (rad(i) - Math.sin(rad(i)));
        var y = a * (1 - Math.cos(rad(i)));
        var z = 0.0;
        gl.vertex(x, y, z);
    }
    gl.end();
}

// アステロイド曲線(星芒形)
function drawAsteroid() {
    var a = 0.5;
    gl.begin(gl.POINTS);
    gl.color(1.0, 0.0, 0.0);
    for (var i = 0; i < 360; ++i) {
        var x = a * (Math.cos(i) * Math.cos(i) * Math.cos(i));
        var y = a * (Math.sin(i) * Math.sin(i) * Math.sin(i));
        var z = 0.0;
        gl.vertex(x, y, z);
    }
    gl.end();
}

// カージオイド曲線(心臓型)
function drawCardioid() {
    var a = 0.5;
    gl.begin(gl.POINTS);
    gl.color(0.0, 1.0, 1.0);
    for (var i = 0; i < 360; ++i) {
        var x = a * (1 + Math.cos(i)) * Math.cos(i);
        var y = a * (1 + Math.cos(i)) * Math.sin(i);
        var z = 0.0;
        gl.vertex(x, y, z);
    }
    gl.end();
}

// インボリュード曲線
function drawInvolute() {
    var a = 0.05;
    gl.begin(gl.POINTS);
    gl.color(1.0, 0.0, 1.0);
    for (var i = 0; i < 1460; ++i) {
        var x = a * (Math.cos(rad(i)) + (rad(i) * Math.sin(rad(i))));
        var y = a * (Math.sin(rad(i)) - (rad(i) * Math.cos(rad(i))));
        var z = 0.0;
        gl.vertex(x, y, z);
    }
    gl.end();
}

// リサージュ図形
function drawLissajous() {
    var A = 1.0;
    var B = 1.0;
    var a = 3.0;
    var b = 4.0;
    var v = 0.0;
    // A , B は振り幅  a,b は各周波数 v は位相差
    gl.begin(gl.POINTS);
    gl.color(1.0, 1.0, 0.0);
    for (var i = 0; i < 1080; ++i) {
        var x = A * Math.sin(a * i + v);
        var y = B * Math.sin(b * i);
        var z = 0.0;
        gl.vertex(x, y, z);
    }
    gl.end();
}

gl.fullscreen();
```
### 主な変更箇所

|OpenGL   |lightgl.js |
|:------------|:----------|
|float        |var        |
|int          |var        |
|sin()        |Math.sin() |
|cos()        |Math.cos() |
|glBegin()    |gl.begin() |
|glEnd()      |gl.end()   |
|glColor3d()  |gl.color() |
|glVertex2d() |gl.vertex()|
|GL_POINTS    |gl.POINTS  |
|GL_LINES     |gl.LINES   |

### 実行結果

[[WebGL] lightgl.js を使って OpenGL のコードを移植してみるテスト](http://jsdo.it/cx20/9lSI) 
![light.jsを使ったOpenGLコードの移植](http://jsdo-static-contents.s3.amazonaws.com/images/capture/9/l/S/9lSI.jpg)