• 比较新颖的探索——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;
    " +
            "    uniform mat4 modelViewMatrix;
    " +
            "    uniform mat4 projectionMatrix;
    " +
            "    void main(void) {
    " +
            "        // Return the transformed and projected vertex value
    " +
            "        gl_Position = projectionMatrix * modelViewMatrix * 
    " +
            "            vec4(vertexPos, 1.0);
    " +
            "    }
    ";
    
        var fragmentShaderSource = 
            "    void main(void) {
    " +
            "    // Return the pixel color: always output white
    " +
            "    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
    " +
            "}
    ";
    
    
        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效果都没有?)

  • 相关阅读:
    许可管理工具
    浅谈MapControl控件和PageLayoutControl控件
    通过Bresenham算法实现完成矢量线性多边形向栅格数据的转化
    四叉树算法原理与实现
    OC系列foundation Kit基础-NSNumber
    OC系列foundation Kit基础-NSdictionary
    OC系列foundation Kit基础-NSMutableArray
    OC系列foundation Kit基础-NSArray
    OC系列foundation Kit基础-NSMutableString
    OC系列foundation Kit基础-NSString
  • 原文地址:https://www.cnblogs.com/yansi/p/3282746.html
Copyright © 2020-2023  润新知