WebGLその8:2Dライブラリ
せっかくなので2D関係の関数を作り、まとめてみました
■index.html
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>SanoWebGLSample08.html</title> </head> <script type="text/javascript" src="webglut03.js"></script> <script> //------------------------------------------------------------------------ // //------------------------------------------------------------------------ var imageData; //イメージデータ //------------------------------------------------------------------------ // 初期化 //------------------------------------------------------------------------ function init() { // gl用コンテキストを取得 Ginit( document.getElementById("c") ); G2Dinit(); // テクスチャ登録 imageData = GsetImage( "ren01.jpg" ); // メインループ登録 setInterval( "MainLoop()", 33 ); } //------------------------------------------------------------------------ // メインループ //------------------------------------------------------------------------ function MainLoop() { // 画面クリア Gclear(); // 描画 G2Dimage( imageData, 10, 10, 100, 100 ); G2Dimage( imageData, 50, 50, 200, 200 ); //ポリゴン描画 G2DsetColor( 0.5, 0.2, 1.0, 1 ); G2Dpolygon( 0, 0, 200, 30, 100, 100 ); //BOX描画 G2DsetColor( 1.0, 1.0, 1.0, 1 ); G2Dbox( 300, 100, 200, 200 ); //ライン描画 G2DsetColor( 0.0, 1.0, 0.0, 1 ); G2Dline( 10, 150, 40, 400 ); //ラインBOX描画 G2DsetColor( 0.0, 1.0, 1.0, 1 ); G2DlineBox( 150, 350, 200, 50 ); } </script> </head> <body onload="init();"> <canvas id="c" style="border:none" width="640" height="480"> </body> </html>
■webglut03.js
(function(np){ var gl = null; var spriteShaderI = null; var spriteShaderP = null; var spriteVertex = null; var spriteUV = null; var colorLocation; np.Ginit = function( canvas ) { try { gl = canvas.getContext( "experimental-webgl" ); gl.viewportWidth = canvas.width; gl.viewportHeight= canvas.height; } catch (e) {} if (!gl) { alert( "WebGL に対応してないです" ); return; } gl.clearColor( 0.0, 0.0, 0.0, 1.0 ); gl.clearDepth( 1.0 ); gl.enable( gl.DEPTH_TEST ); gl.depthFunc( gl.LEQUAL ); return gl; }; //-------------------------------------------------------------- // //-------------------------------------------------------------- np.G2Dinit = function() { gl.enable( gl.DEPTH_TEST ); gl.enable( gl.BLEND ); gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA ); gl.enable( gl.TEXTURE_2D ); //---------------------------------------------------------------------- var shaderVsI = "attribute vec2 pos;"+ "attribute vec2 uv;"+ "uniform vec2 u_resolution;"+ "varying vec2 texCoord;"+ "void main(void)"+ "{"+ " gl_Position = vec4( pos * u_resolution + vec2( -1, 1) , 0, 1);"+ " texCoord = uv;"+ "}"; var shaderFsI = "precision highp float;"+ "uniform sampler2D sampler2d;"+ "varying vec2 texCoord;"+ "void main(void)"+ "{"+ " gl_FragColor = texture2D(sampler2d, texCoord);"+ "}"; spriteShaderI = gl.createProgram(); gl.attachShader( spriteShaderI, ggetShader( gl, shaderVsI, gl.VERTEX_SHADER ) ); gl.attachShader( spriteShaderI, ggetShader( gl, shaderFsI, gl.FRAGMENT_SHADER ) ); gl.linkProgram( spriteShaderI ); if (!gl.getProgramParameter( spriteShaderI, gl.LINK_STATUS ) ) { alert( "initShaders" ); } gl.useProgram( spriteShaderI ); spriteShaderI.vertexPositionAttribute = gl.getAttribLocation( spriteShaderI, "pos" ); gl.enableVertexAttribArray( spriteShaderI.vertexPositionAttribute ); spriteShaderI.textureCoordAttribute = gl.getAttribLocation( spriteShaderI, "uv" ); gl.enableVertexAttribArray( spriteShaderI.textureCoordAttribute ); // var resolutionLocation = gl.getUniformLocation( spriteShaderI, "u_resolution" ); gl.uniform2f( resolutionLocation, 2/gl.viewportWidth, -2/gl.viewportHeight ); //---------------------------------------------------------------------- var shaderVsP = "attribute vec2 pos;"+ "uniform vec2 u_resolution;"+ "void main(void)"+ "{"+ " gl_Position = vec4( pos * u_resolution + vec2( -1, 1) , 0, 1);"+ "}"; var shaderFsP = "precision highp float;"+ "uniform vec4 u_color;"+ "void main(void)"+ "{"+ " gl_FragColor = u_color;"+ "}"; spriteShaderP = gl.createProgram(); gl.attachShader( spriteShaderP, ggetShader( gl, shaderVsP, gl.VERTEX_SHADER ) ); gl.attachShader( spriteShaderP, ggetShader( gl, shaderFsP, gl.FRAGMENT_SHADER ) ); gl.linkProgram( spriteShaderP ); if (!gl.getProgramParameter( spriteShaderP, gl.LINK_STATUS ) ) { alert( "initShaders" ); } gl.useProgram( spriteShaderP ); spriteShaderP.vertexPositionAttribute = gl.getAttribLocation( spriteShaderP, "pos" ); gl.enableVertexAttribArray( spriteShaderP.vertexPositionAttribute ); colorLocation = gl.getUniformLocation( spriteShaderP, "u_color"); gl.uniform4f( colorLocation, 1, 0, 1, 1 ); var resolutionLocation2 = gl.getUniformLocation( spriteShaderP, "u_resolution" ); gl.uniform2f( resolutionLocation2, 2/gl.viewportWidth, -2/gl.viewportHeight ); //---------------------------------------------------------------------- // バッファに頂点をセット spriteVertex = gl.createBuffer(); // UV情報の設定 var uvData = [ 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0 ]; spriteUV = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, spriteUV ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(uvData), gl.STATIC_DRAW ); return spriteShaderI; } //-------------------------------------------------------------- // //-------------------------------------------------------------- np.Gclear = function() { gl.viewport( 0, 0, gl.viewportWidth, gl.viewportHeight ); gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT ); } //-------------------------------------------------------------- // //-------------------------------------------------------------- var ggetShader = function( gl, str, type ) { var shader; shader = gl.createShader( type ) gl.shaderSource( shader, str ); gl.compileShader( shader ); if (!gl.getShaderParameter( shader, gl.COMPILE_STATUS ) ) { alert( gl.getShaderInfoLog( shader ) ); return null; } return shader; }; //-------------------------------------------------------------- // //-------------------------------------------------------------- np.GinitShaders = function( vsName, fsName ) { var vsStr = document.getElementById( vsName ).innerText; var fsStr = document.getElementById( fsName ).innerText; var shaderProgram; shaderProgram = gl.createProgram(); var vertex_shader = ggetShader( gl, vsStr, gl.VERTEX_SHADER ); var fragment_shader = ggetShader( gl, fsStr, gl.FRAGMENT_SHADER ); gl.attachShader( shaderProgram, vertex_shader ); gl.attachShader( shaderProgram, fragment_shader ); gl.linkProgram( shaderProgram ); if (!gl.getProgramParameter( shaderProgram, gl.LINK_STATUS ) ) { alert( "initShaders" ); } gl.useProgram( shaderProgram ); return shaderProgram; }; //-------------------------------------------------------------- // //-------------------------------------------------------------- np.GsetImage = function( imageName ) { var imageData = gl.createTexture(); imageData.image = new Image(); imageData.image.onload = function() { gl.bindTexture( gl.TEXTURE_2D, imageData ); gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, imageData.image ); gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR ); gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR ); gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE ); gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE ); gl.bindTexture( gl.TEXTURE_2D, null ); } imageData.image.src = imageName; return imageData; } //-------------------------------------------------------------- // //-------------------------------------------------------------- np.G2Dimage = function( iMag, wx, wy, wwidth, wheight ) { gl.useProgram( spriteShaderI ); var vertices =[ wx, wy, wx+wwidth, wy, wx, wy+wheight, wx+wwidth, wy+wheight ]; gl.bindBuffer( gl.ARRAY_BUFFER, spriteVertex ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW ); gl.vertexAttribPointer( spriteShaderI.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0 ); gl.bindBuffer( gl.ARRAY_BUFFER, spriteUV ); gl.vertexAttribPointer( spriteShaderI.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); gl.bindTexture( gl.TEXTURE_2D, iMag ); gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 ); } //-------------------------------------------------------------- // //-------------------------------------------------------------- np.G2DsetColor = function( ir, ig, ib, ia ) { gl.useProgram( spriteShaderP ); gl.uniform4f( colorLocation, ir, ig, ib, ia ); } //-------------------------------------------------------------- // //-------------------------------------------------------------- np.G2Dpolygon = function( ix0, iy0, ix1, iy1, ix2, iy2 ) { gl.useProgram( spriteShaderP ); var vertices =[ ix0, iy0, ix1, iy1, ix2, iy2 ]; gl.bindBuffer( gl.ARRAY_BUFFER, spriteVertex ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW ); gl.vertexAttribPointer( spriteShaderP.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0 ); gl.drawArrays( gl.TRIANGLES, 0, 3 ); } //-------------------------------------------------------------- // //-------------------------------------------------------------- np.G2Dbox = function( wx, wy, wwidth, wheight ) { gl.useProgram( spriteShaderP ); var vertices =[ wx, wy, wx+wwidth, wy, wx, wy+wheight, wx+wwidth, wy+wheight ]; gl.bindBuffer( gl.ARRAY_BUFFER, spriteVertex ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW ); gl.vertexAttribPointer( spriteShaderP.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0 ); gl.drawArrays( gl.TRIANGLE_STRIP, 0, 4 ); } //-------------------------------------------------------------- // //-------------------------------------------------------------- np.G2Dline = function( ix0, iy0, ix1, iy1 ) { gl.useProgram( spriteShaderP ); var vertices =[ ix0, iy0, ix1, iy1 ]; gl.bindBuffer( gl.ARRAY_BUFFER, spriteVertex ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW ); gl.vertexAttribPointer( spriteShaderP.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0 ); gl.drawArrays( gl.LINES, 0, 2 ); } //-------------------------------------------------------------- // //-------------------------------------------------------------- np.G2DlineBox = function( wx, wy, wwidth, wheight ) { gl.useProgram( spriteShaderP ); var vertices =[ wx, wy, wx+wwidth, wy, wx+wwidth, wy+wheight, wx, wy+wheight, wx, wy ]; gl.bindBuffer( gl.ARRAY_BUFFER, spriteVertex ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW ); gl.vertexAttribPointer( spriteShaderP.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0 ); gl.drawArrays( gl.LINE_STRIP, 0, 5 ); } })(this);