查看: 2091|回复: 0
打印 上一主题 下一主题

[WEBGL] webGL 学习概要

[复制链接]

435

主题

2

听众

6371

积分

高级设计师

Rank: 6Rank: 6

纳金币
6372
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2012-9-13 15:41:18 |只看该作者 |倒序浏览
首先,我们有个名词:“渲染器”

    渲染器是这样一些代码,在一个场景开始绘制之前,它能对场景的任何部分做任何处理。这的确十分有用,由于它运行在图形卡上,所以它能很快运行且能很便利地做各种变换。

    渲染器运行在图形卡上获得WebGL系统,它把模型视图矩阵和投影矩阵应用到场景中,而不需要使用相对较慢的JavaScript来移动场景中的每一个点和每一个三角形顶点。这相当有用并且值得额外的开销。

    下面我们来看一个简单的例子:

function initShaders() {

        var fragmentShader = getShader(gl, "shader-fs");//获取片段渲染器

        var vertexShader = getShader(gl, "shader-vs");//获取顶点渲染器



        shaderProgram = gl.createProgram();//创建渲染器对象

        gl.attachShader(shaderProgram, vertexShader);//绑定顶点渲染器

        gl.attachShader(shaderProgram, fragmentShader);//绑定片段渲染器

        gl.linkProgram(shaderProgram);//和webGL关联shaderProgram



        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {

            alert("Could not initialise shaders");

        }



        gl.useProgram(shaderProgram);//告诉webGLass使用shaderProgram



        shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");//获取属性vertexPositionAttribute

        gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);//使能



        shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");//获取属性pMatrixUniform

        shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");//获取属性pMatrixUniform

    }

至此,初始化渲染器完成。其中有个自定义函数,需要特别解释:

/**

   *这是一个比看起来要简单的函数。我们要做的是在HTML网页中寻找一个元素,其具有与传入参数匹配的ID,取出其内容并基于其类型创建一个片段渲染器或者一个顶点渲染器(以后我们将更多地解释它们的区别),接着将其传入到WebGL中编译成可以在图形卡上运行的形式。接下来,代码进行出错处理,最后完成整个处理。当然,我们只能在JavaScript中将渲染器定义为字符串而不能从HTML中提取——通过这样做,我们使其更易读,因为它们被定义为网页中的脚本,就像它们本身就是JavaScript一样.

    事实上,他动态的创建了渲染器语言编写的代码,推送给图形显卡执行,它们使

用一种特殊的与C语言有很大关系的渲染器语言所写。

*/

    function getShader(gl, 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;

        }

        alert(str);

        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;

    }

至此,创建渲染器对象完成,(实际上他实在拼接渲染器代码之后,和webGL绑定的)。

     最后,贴上完整的JS代码,如果不出意外(当然HTML自己写)页面上就能看见三角形和正方形了(合适的浏览器):

<script type="text/javascript" src="glMatrix-0.9.5.min.js"></script>



<script id="shader-fs" type="x-shader/x-fragment">

    precision mediump float;



    void main(void) {

        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);

    }

</script>



<script id="shader-vs" type="x-shader/x-vertex">

    attribute vec3 aVertexPosition;



    uniform mat4 uMVMatrix;

    uniform mat4 uPMatrix;



    void main(void) {

        gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);

    }

</script>





<script type="text/javascript"  charset="UTF-8">



    var gl;

var triangleVertexPositionBuffer;

    var squareVertexPositionBuffer;

var shaderProgram;//渲染器对象

var mvMatrix = mat4.create();//模型矩阵

/**

mat4.create=function(a){

var b=new glMatrixArrayType(16);

if(a)

{

b[0]=a[0];

b[1]=a[1];

b[2]=a[2];

b[3]=a[3];

b[4]=a[4];

b[5]=a[5];

b[6]=a[6];

b[7]=a[7];

b[8]=a[8];

b[9]=a[9];

b[10]=a[10];

b[11]=a[11];

b[12]=a[12];

b[13]=a[13];

b[14]=a[14];

b[15]=a[15]

}

return b

};*/

    var pMatrix = mat4.create();//投影矩阵

    function initGL(canvas) {



        try {

canvas.width=screen.width;

canvas.height=screen.height;

            gl = canvas.getContext("experimental-webgl");

            gl.viewportWidth = canvas.width;

            gl.viewportHeight = canvas.height;

        } catch (e) {

        }

        if (!gl) {

            alert("Could not initialise WebGL, sorry :-(");

        }

    }



    /**

*这是一个比看起来要简单的函数。我们要做的是在HTML网页中寻找一个元素,其具有与传入参数匹配的ID,取出其内容并基于其类型创建一个片段渲染器或者一个顶点渲染器(以后我们将更多地解释它们的区别),接着将其传入到WebGL中编译成可以在图形卡上运行的形式。接下来,代码进行出错处理,最后完成整个处理。当然,我们只能在JavaScript中将渲染器定义为字符串而不能从HTML中提取——通过这样做,我们使其更易读,因为它们被定义为网页中的脚本,就像它们本身就是JavaScript一样.

    事实上,他动态的创建了渲染器语言编写的代码,推送给图形显卡执行,它们使

用一种特殊的与C语言有很大关系的渲染器语言所写。

*/

    function getShader(gl, 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;

        }

        alert(str);

        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(gl, "shader-fs");//获取片段渲染器

        var vertexShader = getShader(gl, "shader-vs");//获取顶点渲染器



        shaderProgram = gl.createProgram();//创建渲染器对象

        gl.attachShader(shaderProgram, vertexShader);//绑定顶点渲染器

        gl.attachShader(shaderProgram, fragmentShader);//绑定片段渲染器

        gl.linkProgram(shaderProgram);//和webGL关联shaderProgram



        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {

            alert("Could not initialise shaders");

        }



        gl.useProgram(shaderProgram);//告诉webGLass使用shaderProgram



        shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");//获取属性vertexPositionAttribute

        gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);//使能



        shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");//获取属性pMatrixUniform

        shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");//获取属性pMatrixUniform

    }





   



    function setMatrixUniforms() {

        gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix);//将渲染器和投影矩阵绑定

        gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix);//将渲染器和模型矩阵绑定

    }

/**

*初始化图形缓存区  缓冲区实际上是图形卡上的内存

*/

    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);//vertices填充缓存区

        triangleVertexPositionBuffer.itemSize = 3;//缓存区的列

        triangleVertexPositionBuffer.numItems = 3;//缓存区的行  三个独立的顶点位置(numItems),其中每一个由三个数(itemSize)组成



        squareVertexPositionBuffer = gl.createBuffer();//正方形

        gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);

        vertices = [

             1.0,  1.0,  0.0,

            -1.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);

        squareVertexPositionBuffer.itemSize = 3;

        squareVertexPositionBuffer.numItems = 4;

    }



//将两个对象的顶点位置放置到图形卡上————————绘制图形

    function drawScene() {

        gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);//告诉 WebGL画布的大小

        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);//清除画布



//mat4.perspective=function(a,b,c,d,e){a=c*Math.tan(a*Math.PI/360);b=a*b;return mat4.***stum(-b,b,-a,a,c,d,e)};

        mat4.perspective(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0, pMatrix);//为场景设置***参数



//mat3.identity=function(a){a[0]=1;a[1]=0;a[2]=0;a[3]=0;a[4]=1;a[5]=0;a[6]=0;a[7]=0;a[8]=1;return a};

        mat4.identity(mvMatrix);//



        mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]);//变换

        gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);

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

        setMatrixUniforms();//把矩阵参数传到图形卡,这个函数将模型视图矩阵和投影矩阵从JavaScript中转移到WebGL中,并与渲染器相关

        gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);//从顶点数组的第0项开始一直到第numItems个元素,将顶点数组绘制成三角形

//alert("triangle Finish!");



        mat4.translate(mvMatrix, [3.0, 0.0, 0.0]);

        gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);

        gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);

        setMatrixUniforms();

        gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);

    }







    function webGLStart() {

        var canvas = document.getElementById("lesson01-canvas");

        initGL(canvas);

        initShaders();

        initBuffers();

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

        gl.enable(gl.DEPTH_TEST);



        drawScene();

    }

</script>

希望您有所收获,也希望我有所进步!

夜深了,当所有离你远去的时候,你选择了编程,无所谓成功或者成就,只为真实的向梦想靠近,孤独并快乐着!晚上下班时,看见地铁站两个年轻人,忘情地抱着吉他,唱着歌,他们贫穷却快乐着!有时候人生或许就是这样,坚强地活着,并快乐!我没有能力给他们钱,但我却有跟唱歌者同样的心情,或是爱,或是情,那些远去的,那些我们真正在乎的东西!
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

手机版|纳金网 ( 闽ICP备2021016425号-2/3

GMT+8, 2024-9-20 20:27 , Processed in 0.092299 second(s), 32 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部