WebGLその6:2D座標

2Dで制御したいい場合、WebGLそのままだと(-1,-1)-(1,1)というように2Dゲームには扱いにくい座標になっています。
これを(0,0)-(640,480)にできれば簡単に制御できます。

■index.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SanoWebGLSample06.html</title>
</head>
<script type="text/javascript" src="webglut01.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
//------------------------------------------------------------------------
//    ヴァーテックスシェーダー
//------------------------------------------------------------------------
attribute vec2 pos;
uniform vec2 u_resolution;
void main(void)
{
    vec2 zeroToOne = pos / u_resolution;
    vec2 zeroToTwo = zeroToOne * 2.0;
    vec2 clipSpace = zeroToTwo - 1.0;
    gl_Position = vec4( clipSpace * vec2(1, -1), 0, 1);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
//------------------------------------------------------------------------
//    ピクセルシェーダー
//------------------------------------------------------------------------
void main(void)
{
    gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );
}
</script>
<script>
//------------------------------------------------------------------------
//    
//------------------------------------------------------------------------
var    gl;                //gl用コンテキスト
var    vertexModel;    //頂点
var    shaderProgram;    //シェーダー
//------------------------------------------------------------------------
//    初期化
//------------------------------------------------------------------------
function    init()
{
    // gl用コンテキストを取得
    gl    = Ginit( document.getElementById("c") );
    // シェーダ初期化
    shaderProgram    = GinitShaders( "shader-vs", "shader-fs" );
    shaderProgram.vertexPositionAttribute = gl.getAttribLocation( shaderProgram, "pos" );
    gl.enableVertexAttribArray( shaderProgram.vertexPositionAttribute );
    //
    var resolutionLocation = gl.getUniformLocation( shaderProgram, "u_resolution" );
    gl.uniform2f( resolutionLocation, gl.viewportWidth, gl.viewportHeight );
    //    モデル設定
    initMode();
    //    メインループ登録
    setInterval( "MainLoop()", 33 );
}
//------------------------------------------------------------------------
//    メインループ
//------------------------------------------------------------------------
function MainLoop()
{
    // 画面クリア
    Gclear();
    // 描画
    drawMode();
}
//------------------------------------------------------------------------
//    モデル情報の初期化
//------------------------------------------------------------------------
function    initMode()
{
    // バッファに頂点をセット
    var    vertices    =[
        10, 20,
        100, 40,
        10, 60,
    ];
    vertexModel    = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexModel );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW );

    vertexModel.itemSize = 2;
    vertexModel.numItems = 3;
}
//------------------------------------------------------------------------
//    モデル情報の描画
//------------------------------------------------------------------------
function    drawMode()
{
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexModel );
    gl.vertexAttribPointer( shaderProgram.vertexPositionAttribute, vertexModel.itemSize, gl.FLOAT, false, 0, 0 );
    gl.drawArrays( gl.TRIANGLES, 0, vertexModel.numItems );
}

</script>
</head>
<body onload="init();">
<canvas id="c" style="border:none" width="640" height="480">
</body>
</html>

■[WebGLその3:ポリゴン表示]で使われた「webglut01.js」を使います。
http://d.hatena.ne.jp/sanoh/20120328
■これを画面に出すと

■最適化
上のプログラムでもいいのですが、最適化すると
index.html

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>SanoWebGLSample06.html</title>
</head>
<script type="text/javascript" src="webglut01.js"></script>
<script id="shader-vs" type="x-shader/x-vertex">
//------------------------------------------------------------------------
//    ヴァーテックスシェーダー
//------------------------------------------------------------------------
attribute vec2 pos;
uniform vec2 u_resolution;
void main(void)
{
    gl_Position = vec4( pos * u_resolution + vec2( -1, 1) , 0, 1);
}
</script>
<script id="shader-fs" type="x-shader/x-fragment">
//------------------------------------------------------------------------
//    ピクセルシェーダー
//------------------------------------------------------------------------
void main(void)
{
    gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 );
}
</script>
<script>
//------------------------------------------------------------------------
//    
//------------------------------------------------------------------------
var    gl;                //gl用コンテキスト
var    vertexModel;    //頂点
var    shaderProgram;    //シェーダー
//------------------------------------------------------------------------
//    初期化
//------------------------------------------------------------------------
function    init()
{
    // gl用コンテキストを取得
    gl    = Ginit( document.getElementById("c") );
    // シェーダ初期化
    shaderProgram    = GinitShaders( "shader-vs", "shader-fs" );
    shaderProgram.vertexPositionAttribute = gl.getAttribLocation( shaderProgram, "pos" );
    gl.enableVertexAttribArray( shaderProgram.vertexPositionAttribute );
    //
    var resolutionLocation = gl.getUniformLocation( shaderProgram, "u_resolution" );
    gl.uniform2f( resolutionLocation, 2/gl.viewportWidth, -2/gl.viewportHeight );
    //    モデル設定
    initMode();
    //    メインループ登録
    setInterval( "MainLoop()", 33 );
}
//------------------------------------------------------------------------
//    メインループ
//------------------------------------------------------------------------
function MainLoop()
{
    // 画面クリア
    Gclear();
    // 描画
    drawMode();
}
//------------------------------------------------------------------------
//    モデル情報の初期化
//------------------------------------------------------------------------
function    initMode()
{
    // バッファに頂点をセット
    var    vertices    =[
        10, 20,
        100, 40,
        10, 60,
    ];
    vertexModel    = gl.createBuffer();
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexModel );
    gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW );

    vertexModel.itemSize = 2;
    vertexModel.numItems = 3;
}
//------------------------------------------------------------------------
//    モデル情報の描画
//------------------------------------------------------------------------
function    drawMode()
{
    gl.bindBuffer( gl.ARRAY_BUFFER, vertexModel );
    gl.vertexAttribPointer( shaderProgram.vertexPositionAttribute, vertexModel.itemSize, gl.FLOAT, false, 0, 0 );
    gl.drawArrays( gl.TRIANGLES, 0, vertexModel.numItems );
}

</script>
</head>
<body onload="init();">
<canvas id="c" style="border:none" width="640" height="480">
</body>
</html>

となします。
バーテックスシェーダーを

attribute vec2 pos;
uniform vec2 u_resolution;
void main(void)
{
    gl_Position = vec4( pos * u_resolution + vec2( -1, 1) , 0, 1);
}

と短くするために

    gl.uniform2f( resolutionLocation, 2/gl.viewportWidth, -2/gl.viewportHeight );

事前にパラメータをある程度計算するようにしています。