比较新颖的探索——webGL初体验

  近来有想弄弄有趣的东西,3D的页面效果,自然会想到webGL,但是介于以前一直没用过,这次也算是初体验了。

初体验的话总是让人有激情,但是这次让我太难受了。。。。。。

  为什么呢?因为webGL的初始化太蛋疼了,入门就要比canvas麻烦很多,而且如果用原生api的话各种不会看不懂啊!!!!!。好吧,抱怨完了,写在我们如果要开始webGL之旅需要一些什么

  1.  创建一个canvas元素
  2.  获取canvas的上下文
  3.  初始化视口(viewport)
  4. 创建一个或者多个包含渲染数据的数组(通常为顶点数组) 
  5. 创建一个或者多个矩阵,将顶点数组变换到屏幕空间中
  6. 创建一个或者多个着色器来实现绘制算法
  7. 使用参数初始化着色器
  8. 绘制

 

  这些看起来还不是很难,但是,着色器对于webGL是非常重要的一部分,而着色器不使用javascript编写,而是一门类似C语言的高级语言编写,并且以字符串的形式插入到代码之中。而且挺麻烦的(应该是我水平太低的原因,以后需要多多学习)

  目前在学习的书籍是《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效果都没有?)

posted @ 2013-08-26 15:38  小斯新手  阅读(567)  评论(0编辑  收藏  举报