比較新穎的探索——webGL初體驗

  近來有想弄弄有趣的東西,3D的頁面效果,天然會想到webGL,可是介於之前一直沒用過,此次也算是初體驗了。javascript

初體驗的話老是讓人有激情,可是此次讓我太難受了。。。。。。html

  爲何呢?由於webGL的初始化太蛋疼了,入門就要比canvas麻煩不少,並且若是用原生api的話各類不會看不懂啊!!!!!。好吧,抱怨完了,寫在咱們若是要開始webGL之旅須要一些什麼java

  1.  建立一個canvas元素
  2.  獲取canvas的上下文
  3.  初始化視口(viewport)
  4. 建立一個或者多個包含渲染數據的數組(一般爲頂點數組) 
  5. 建立一個或者多個矩陣,將頂點數組變換到屏幕空間中
  6. 建立一個或者多個着色器來實現繪製算法
  7. 使用參數初始化着色器
  8. 繪製

 

  這些看起來還不是很難,可是,着色器對於webGL是很是重要的一部分,而着色器不使用javascript編寫,而是一門相似C語言的高級語言編寫,而且以字符串的形式插入到代碼之中。並且挺麻煩的(應該是我水平過低的緣由,之後須要多多學習)web

  目前在學習的書籍是《WebGL:Up and Running》的中文版(汗),原著做者爲Tony Parisi,根據受權,應該是可使用其中的一部分代碼做爲回答問題或者學習資料,因此我就把最本來的webGL方式調用粘貼下啦,學習一下(我預計我應該記不住,也看不太懂這些參數要怎麼弄)算法

  

<html>

<head>
<title>WebGL Up And Running &mdash; Example 1</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">

<script type="text/javascript">

    function initWebGL(canvas) {

        var gl;
        try 
        {
            gl = canvas.getContext("experimental-webgl");
        } 
        catch (e)
        {
            var msg = "Error creating WebGL Context!: " + e.toString();
            alert(msg);
            throw Error(msg);
        }

        return gl;        
     }

    function initViewport(gl, canvas)
    {
        gl.viewport(0, 0, canvas.width, canvas.height);
    }

    var projectionMatrix, modelViewMatrix;

    function initMatrices()
    {
       // The transform matrix for the square - translate back in Z for the camera
       modelViewMatrix = new Float32Array(
               [1, 0, 0, 0,
                0, 1, 0, 0, 
                0, 0, 1, 0, 
                0, 0, -3.333, 1]);
       
       // The projection matrix (for a 45 degree field of view)
       projectionMatrix = new Float32Array(
               [2.41421, 0, 0, 0,
                0, 2.41421, 0, 0,
                0, 0, -1.002002, -1, 
                0, 0, -0.2002002, 0]);
    
    }

    // Create the vertex data for a square to be drawn
    function createSquare(gl) {
        var vertexBuffer;
        vertexBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
        var verts = [
             .5,  .5,  0.0,
            -.5,  .5,  0.0,
             .5, -.5,  0.0,
            -.5, -.5,  0.0
        ];
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
        var square = {buffer:vertexBuffer, vertSize:3, nVerts:4, primtype:gl.TRIANGLE_STRIP};
        return square;
    }

    function createShader(gl, str, type) {
        var shader;
        if (type == "fragment") {
            shader = gl.createShader(gl.FRAGMENT_SHADER);
        } else if (type == "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;
    }
    
    var vertexShaderSource =
        
        "    attribute vec3 vertexPos;\n" +
        "    uniform mat4 modelViewMatrix;\n" +
        "    uniform mat4 projectionMatrix;\n" +
        "    void main(void) {\n" +
        "        // Return the transformed and projected vertex value\n" +
        "        gl_Position = projectionMatrix * modelViewMatrix * \n" +
        "            vec4(vertexPos, 1.0);\n" +
        "    }\n";

    var fragmentShaderSource = 
        "    void main(void) {\n" +
        "    // Return the pixel color: always output white\n" +
        "    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n" +
        "}\n";


    var shaderProgram, shaderVertexPositionAttribute, shaderProjectionMatrixUniform, shaderModelViewMatrixUniform;

    function initShader(gl) {

        // load and compile the fragment and vertex shader
        //var fragmentShader = getShader(gl, "fragmentShader");
        //var vertexShader = getShader(gl, "vertexShader");
        var fragmentShader = createShader(gl, fragmentShaderSource, "fragment");
        var vertexShader = createShader(gl, vertexShaderSource, "vertex");

        // link them together into a new program
        shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.linkProgram(shaderProgram);

        // get pointers to the shader params
        shaderVertexPositionAttribute = gl.getAttribLocation(shaderProgram, "vertexPos");
        gl.enableVertexAttribArray(shaderVertexPositionAttribute);
        
        shaderProjectionMatrixUniform = gl.getUniformLocation(shaderProgram, "projectionMatrix");
        shaderModelViewMatrixUniform = gl.getUniformLocation(shaderProgram, "modelViewMatrix");

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

     function draw(gl, obj) {

         // clear the background (with black)
         gl.clearColor(0.0, 0.0, 0.0, 1.0);
         gl.clear(gl.COLOR_BUFFER_BIT);

         // set the vertex buffer to be drawn
         gl.bindBuffer(gl.ARRAY_BUFFER, obj.buffer);

         // set the shader to use
         gl.useProgram(shaderProgram);

         // connect up the shader parameters: vertex position and projection/model matrices
         gl.vertexAttribPointer(shaderVertexPositionAttribute, obj.vertSize, gl.FLOAT, false, 0, 0);
         gl.uniformMatrix4fv(shaderProjectionMatrixUniform, false, projectionMatrix);
         gl.uniformMatrix4fv(shaderModelViewMatrixUniform, false, modelViewMatrix);

         // draw the object
         gl.drawArrays(obj.primtype, 0, obj.nVerts);
      }
          
    function onLoad() {
        var canvas = document.getElementById("webglcanvas");
        var gl = initWebGL(canvas);
        initViewport(gl, canvas);
        initMatrices();
        var square = createSquare(gl);
        initShader(gl);
        draw(gl, square);
    }


</script>


</head>


<body onload="onLoad();">

    <canvas id="webglcanvas" style="border: none;" width="500" height="500"></canvas>

</body>

</html>

恩,最後畫出來的效果應該是一個黑框裏面有一個白色的正方形(什麼?這麼長一堆設置連一點點的3d效果都沒有?)canvas

相關文章
相關標籤/搜索