LoginSignup
2
0

More than 5 years have passed since last update.

WebGLで最小限のコードでテクスチャ

Last updated at Posted at 2014-12-12

WebGLで三角形にテクスチャを貼るための大体最小限のコードです。残念ながらファイル1つというわけにはなってません。

  • 画像ファイルがいる
  • 画像ファイルをローカルで利用しようとするとクロスドメインなんとかに引っかかるので、webサーバを立てる必要がある

webサーバに関しては、http://qiita.com/sudahiroshi/items/e74d61d939f18779970d このあたりを参考にするとらくできるのではないでしょうか。

texture.html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>WebGL triangle</title>

    <script id="shader-vs" type="x-shader/x-vertex">
        attribute vec3 aVertexPosition;
        attribute vec2 aTexCoord;

        varying vec2 vTexCoord;

        void main(void) {
            gl_Position = vec4(aVertexPosition, 1.0);
            vTexCoord = aTexCoord;
        }
    </script>

    <script id="shader-fs" type="x-shader/x-fragment">
        precision mediump float;

        uniform sampler2D texture0;

        varying vec2 vTexCoord;

        void main(void) {
            gl_FragColor = texture2D(texture0, vTexCoord);
        }
    </script>

    <script type="text/javascript">
        var gl;
        var shaderProgram;
        var triangleVertexPositionBuffer;

        function initGL(canvas) {
            try {
                gl = canvas.getContext("experimental-webgl");
                gl.viewport(0, 0, canvas.width, canvas.height);
            } catch (e) {
                console.log(e);
            }
            if (!gl) {
                alert("Could not initialize WebGL, sorry :-(");
            }
        }

        function getShader(id) {
            var shaderScript = document.getElementById(id);
            if (!shaderScript) {
                return null;
            }

            var str = "";
            var k = shaderScript.firstChild;
            while (k) {
                if (k.nodeType == 3) {
                    str += k.textContent;
                }
                k = k.nextSibling;
            }

            var shader;
            if (shaderScript.type == "x-shader/x-fragment") {
                shader = gl.createShader(gl.FRAGMENT_SHADER);
            } else if (shaderScript.type == "x-shader/x-vertex") {
                shader = gl.createShader(gl.VERTEX_SHADER);
            } else {
                return null;
            }

            gl.shaderSource(shader, str);
            gl.compileShader(shader);

            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                alert(gl.getShaderInfoLog(shader));
                return null;
            }

            return shader;
        }

        function initShaders() {
            var fragmentShader = getShader("shader-fs");
            var vertexShader = getShader("shader-vs");

            shaderProgram = gl.createProgram();
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);
            gl.linkProgram(shaderProgram);

            if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                alert("Could not initialise shaders");
            }

            gl.useProgram(shaderProgram);

            shaderProgram.vertexPositionAttribute =
                gl.getAttribLocation(shaderProgram, "aVertexPosition");

            shaderProgram.texCoordAttribute =
                gl.getAttribLocation(shaderProgram, "aTexCoord");

            shaderProgram.textureLocation =
                gl.getUniformLocation(shaderProgram, "texture0");
        }

        function initBuffers() {
            triangleVertexPositionBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
            var vertices = [
                 0.0,  1.0,  0.0,
                -1.0, -1.0,  0.0,
                 1.0, -1.0,  0.0
            ];
            gl.bufferData(
                gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
            triangleVertexPositionBuffer.itemSize = 3;
            triangleVertexPositionBuffer.numItems = 3;

            var texcoords = [
                0.0, 1.0,
                0.0, 0.0,
                1.0, 0.0,
            ];
            texCoordBuffer = gl.createBuffer();
            gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
            gl.bufferData(
                gl.ARRAY_BUFFER, new Float32Array(texcoords), gl.STATIC_DRAW);
            texCoordBuffer.itemSize = 2;
            texCoordBuffer.numItems = 3;
        }

        var texture;
        function initTexture() {
            texture = gl.createTexture();
            var image = document.getElementById("qiita");
            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
            gl.texImage2D(
                gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
            gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
            gl.bindTexture(gl.TEXTURE_2D, null);
        }

        function drawScene() {
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
            gl.vertexAttribPointer(
                shaderProgram.vertexPositionAttribute,
                triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

            gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
            gl.vertexAttribPointer(
                shaderProgram.texCoordAttribute,
                texCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(shaderProgram.texCoordAttribute);

            gl.bindTexture(gl.TEXTURE_2D, texture);
            gl.uniform1i(shaderProgram.textureLocation, 0);            

            gl.drawArrays(
                gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
        }

        function webGLStart() {
            var canvas = document.getElementById("gl-canvas");
            initGL(canvas);
            initShaders();
            initBuffers();
            initTexture();

            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.enable(gl.DEPTH_TEST);

            drawScene();
        }
    </script>


</head>

  <body>
    <canvas id="gl-canvas" width="480" height="320"></canvas>
  </body>

  <img id="qiita" src="./qiita.png" onload="webGLStart();">
</html>
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0