WEBGL学习【一】初识WEBGL

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78352374 ...
版权声明:本文为博主原创文章,未经博主允许不得转载。更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/78352374
<html lang="zh-CN">

<head>
    <title>NeHe's WebGL</title>
    <meta charset="UTF-8"/>
    <!--引入需要的库文件-->
    <script type="text/javascript" src="Oak3D_v_0_5.js"></script>

    <!--片元着色器;为JavaScript片段指定一个ID编号,后面我可以更具这个ID编号来获取这段片元着色器的JavaScript片段代码-->
    <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>

    <!--顶点着色器;后面可以通过ID编号来获取这段顶点着色器代码-->
    <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">

        var gl;
        //初始化WEBGL
        function initGL(canvas) {
            try {
                //获取WEBGL上下文
                gl = canvas.getContext("experimental-webgl");
                //gl这个上下文中存放了一些属性(canvas的宽度、长度和其他相关属性数据)
                //设置我的视口的宽度和高度
                gl.viewportWidth = canvas.width;
                gl.viewportHeight = canvas.height;
            } catch (e) {
            }
            //如果获取失败
            if (!gl) {
                alert("Could not initialise WebGL, sorry :-(");
            }
        }


        //获取我的着色器对象
        function getShader(gl, id) {
            //根据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;
            //1.根据着色器的类型创建相应的着色器对象
            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;
            }

            //2.向着色器对象中指定相应的GLSL ES源代码(以字符串的形式传递进去)
            gl.shaderSource(shader, str);
            //3.开始编译着色器(编译成为二进制的可执行文件)
            gl.compileShader(shader);

            //检查下着色器的状态(是否编译成功)
            if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
                alert(gl.getShaderInfoLog(shader));
                return null;
            }

            return shader;
        }


        //一个着色器对象必须包含一个顶点着色器和一个片元着色器
        var shaderProgram;

        //初始化着色器
        function initShaders() {
            //获取我的顶点着色器和片元着色器
            var fragmentShader = getShader(gl, "shader-fs");
            var vertexShader = getShader(gl, "shader-vs");

            //每一个program中可以存放一个顶点着色器和一个片元着色器
            //4.创建我的程序对象
            shaderProgram = gl.createProgram();
            //5.为程序对象分配着色器对象
            gl.attachShader(shaderProgram, vertexShader);
            gl.attachShader(shaderProgram, fragmentShader);

            //6.链接程序对象
            /**
             * 1.可以保证顶点着色器和片元着色器同名并且是同类型的
             * 2.attributeuniformvarying变量个数不超过着色器的上限
             */
            gl.linkProgram(shaderProgram);
            //检测是否连接成功
            if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
                alert("Could not initialise shaders");
            }
            //7.告诉WEBGL要使用的程序对象
            gl.useProgram(shaderProgram);

            //指定一个新的属性;gl.enableVertexAttribArray,我们使用它来告诉WebGL我们会用一个数组来为属性赋值
            shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
            gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);

            //program中取得另外的两个属性值(模型视图投影矩阵)
            shaderProgram.pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
            shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
        }


        //定义了我的模型视图矩阵和投影矩阵
        var mvMatrix;
        var pMatrix;

        //把我们新设置的模型视图投影矩阵传给顶点着色器中的uniform变量
        function setMatrixUniforms() {
            gl.uniformMatrix4fv(shaderProgram.pMatrixUniform, false, pMatrix.toArray());
            gl.uniformMatrix4fv(shaderProgram.mvMatrixUniform, false, mvMatrix.toArray());
        }


        //定义我的三角形和矩形缓冲区
        var triangleVertexPositionBuffer;
        var squareVertexPositionBuffer;

        //缓冲区的初始化
        function initBuffers() {
            //1.新建三角形顶点缓冲区对象
            triangleVertexPositionBuffer = gl.createBuffer();
            //2.绑定目标对象到缓冲区
            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
            ];
            //3.缓冲区对象中写入数据
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);

            //计算顶点数组的大小和顶点个数
            triangleVertexPositionBuffer.itemSize = 3;
            triangleVertexPositionBuffer.numItems = 3;

            //1.新建矩形顶点缓冲区对象
            squareVertexPositionBuffer = gl.createBuffer();
            //2.绑定目标对象到缓冲区
            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
            ];
            //3.向缓冲区对象中写入数据
            gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
            //计算矩形顶点数组每一项数据的大小,和顶点个数(有四个不同的顶点位置,每个顶点由3个数字组成)
            squareVertexPositionBuffer.itemSize = 3;
            squareVertexPositionBuffer.numItems = 4;
        }


        //绘制我的场景(三角形和矩形)
        function drawScene() {
            //设置视口大小
            gl.viewport(0, 0, gl.viewportWidth, gl.viewportHeight);
            //清空颜色缓存和深度缓存
            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

            //建立一个透视投影(视场角,视口比例,最近,最远距离)
            pMatrix = okMat4Proj(45, gl.viewportWidth / gl.viewportHeight, 0.1, 100.0);


            //设置我的模型视图矩阵为平移矩阵
            mvMatrix = okMat4Trans(-1.5, 0.0, -7.0);
            //绑定三角形顶点数据到缓冲区对象
            gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
            gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
            //告诉WEBGL当前使用的模型视图投影矩阵
            setMatrixUniforms();
            //开始绘制三角形(从第0个位置开始,绘制numItems个顶点)
            gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);

            //开始绘制矩形
            mvMatrix = okMat4Trans(1.5, 0.0, -7.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() {
            //获取canvas元素
            var canvas = document.getElementById("lesson01-canvas");

            //初始化WEBGL上下文信息
            initGL(canvas);

            //初始化着色器
            initShaders();

            //出事阿虎缓冲区
            initBuffers();

            //指定清空画布的颜色,开启隐藏面消除的功能
            gl.clearColor(0.0, 0.0, 0.0, 1.0);
            gl.enable(gl.DEPTH_TEST);

            //开始绘制我的场景
            drawScene();
        }


    </script>


</head>

    <body onload="webGLStart();">
        <canvas id="lesson01-canvas" style="border: none;" width="500" height="500"></canvas>
    </body>

</html>
相关文章
|
7月前
|
Web App开发 前端开发 JavaScript
WebGL:开始学习 / 理解 WebGL / WebGL 需要掌握哪些知识 / 应用领域 / 前端值得学WebGL吗
WebGL:开始学习 / 理解 WebGL / WebGL 需要掌握哪些知识 / 应用领域 / 前端值得学WebGL吗
125 0
|
22天前
|
移动开发 前端开发 JavaScript
游戏开发技术- 请谈谈WebGL与Canvas的区别,以及在什么情况下更适合使用WebGL。
WebGL和Canvas都是网页游戏开发的关键技术。Canvas是2D绘图API,适合初学者和简单的2D游戏,而WebGL是基于OpenGL的3D渲染标准,用于复杂3D图形和游戏,提供GPU硬件加速。当涉及3D渲染、高级视觉效果或高性能需求时,WebGL是更好的选择。对于轻量级2D应用,Canvas就足够了。某些游戏引擎支持两者自动切换,以实现最佳性能和兼容性。
|
6月前
|
存储 缓存 前端开发
WebGL简介
WebGL简介
76 0
WebGL简介
|
8月前
|
Web App开发 测试技术 API
WebGpu VS WebGL
首先是Web 和 WebGPU 上的图形简史.如果您还没有阅读,请阅读 - 这篇文章在很大程度上是从那篇文章开始的。我将介绍WebGPU在实践中与WebGL的比较,我在Web游戏引擎Construct中添加WebGPU支持时学到的东西,以及它对未来的意义。
141 0
|
移动开发 前端开发 JavaScript
什么是 WebGL?
什么是 WebGL?
190 0
|
移动开发 JavaScript 前端开发
webgl入门指南(一)
本文适合对图形感兴趣的小伙伴阅读。
webgl入门指南(一)
|
前端开发 JavaScript 异构计算
WebGL基础笔记
WebGL基础笔记
158 0
|
编解码 数据可视化 图形学
webgl系列之对光栅化的理解
前言 周末没事的学习了光栅化进一步理解, 从底层去学习,遇到问题才会从容不迫, 并同时把这些知识分享给大家, 如果大家没时间看视频的话,废话不多说, 直接开始吧, 这里先做一个概念的铺垫在3D即将渲染到我们屏幕当中来的时候。而接下来我们要做的是把这个标准立方体绘制到屏幕上,这样才能最终被我们所看见。 不清楚的同学看下这篇文章吧 可视化入门跳转到坐标系转换那里 我们简单看下这张图: 图片 变换过程 而光栅化的过程发生在哪里 ,其实 就是物体通过MVP变换,把摄像机观测的空间压缩成了一个标准立方体。然后将标准的立方体【-,1,】绘制到屏幕上的这些过程 图片 转换 在做这步操作之前,我们首
webgl系列之对光栅化的理解
|
数据格式
WebGL2系列之不可变纹理
WebGL2系列之不可变纹理
|
JavaScript 物联网 开发者
WebGL的3D框架比较 ThingJS 和 Three.js
随着flash的没落,浏览器的原生能力的兴起。在3D方面WebGL不管从功能还是性能方面都在逐渐加强。2D应用变为3D应用的需求也越来越强烈。 win10的画图板支持3D图片,2d工具photoshop也开始逐步集成了3D工具。
4560 0