WebGL 实践篇(五)三维图形的绘制及矩阵变换、正射投影

2023-11-18

一 三维“F”的绘制

1.着色器

按照上一篇提到的矩阵变换,我们可以直接在顶点着色器中加入相应的矩阵变换,这样就可以简化着色器代码,通过变量传入矩阵的值也便于之后矩阵变换的修改。

三维图形的绘制相比于二维图形只在参数类型上有一些变化(注意vec4以及mat4):

  <script id="vertex-shader-3D" type="x-shader/x-vertex">
    attribute vec4 a_position;

    uniform mat4 u_matrix;

    void main(){
      gl_Position = u_matrix * a_position;
    }
  </script>
  <script id="fragment-shader-3D" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 u_color;

    void main(){
      gl_FragColor = u_color;
    }
  </script>

2.绘制信息(主要是位置坐标点)

 如上图,我们可以看出要绘制的三维图形”F"所需要的矩形面总共有16个,而每个矩形面需要2个三角形。

function setGeometry(gl) {
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        // left column front
        0, 0, 0,
        30, 0, 0,
        0, 150, 0,
        0, 150, 0,
        30, 0, 0,
        30, 150, 0,

        // top rung front
        30, 0, 0,
        100, 0, 0,
        30, 30, 0,
        30, 30, 0,
        100, 0, 0,
        100, 30, 0,

        // middle rung front
        30, 60, 0,
        67, 60, 0,
        30, 90, 0,
        30, 90, 0,
        67, 60, 0,
        67, 90, 0,

        // left column back
        0, 0, 30,
        30, 0, 30,
        0, 150, 30,
        0, 150, 30,
        30, 0, 30,
        30, 150, 30,

        // top rung back
        30, 0, 30,
        100, 0, 30,
        30, 30, 30,
        30, 30, 30,
        100, 0, 30,
        100, 30, 30,

        // middle rung back
        30, 60, 30,
        67, 60, 30,
        30, 90, 30,
        30, 90, 30,
        67, 60, 30,
        67, 90, 30,

        // top
        0, 0, 0,
        100, 0, 0,
        100, 0, 30,
        0, 0, 0,
        100, 0, 30,
        0, 0, 30,

        // top rung right
        100, 0, 0,
        100, 30, 0,
        100, 30, 30,
        100, 0, 0,
        100, 30, 30,
        100, 0, 30,

        // under top rung
        30, 30, 0,
        30, 30, 30,
        100, 30, 30,
        30, 30, 0,
        100, 30, 30,
        100, 30, 0,

        // between top rung and middle
        30, 30, 0,
        30, 30, 30,
        30, 60, 30,
        30, 30, 0,
        30, 60, 30,
        30, 60, 0,

        // top of middle rung
        30, 60, 0,
        30, 60, 30,
        67, 60, 30,
        30, 60, 0,
        67, 60, 30,
        67, 60, 0,

        // right of middle rung
        67, 60, 0,
        67, 60, 30,
        67, 90, 30,
        67, 60, 0,
        67, 90, 30,
        67, 90, 0,

        // bottom of middle rung.
        30, 90, 0,
        30, 90, 30,
        67, 90, 30,
        30, 90, 0,
        67, 90, 30,
        67, 90, 0,

        // right of bottom
        30, 90, 0,
        30, 90, 30,
        30, 150, 30,
        30, 90, 0,
        30, 150, 30,
        30, 150, 0,

        // bottom
        0, 150, 0,
        0, 150, 30,
        30, 150, 30,
        0, 150, 0,
        30, 150, 30,
        30, 150, 0,

        // left side
        0, 0, 0,
        0, 0, 30,
        0, 150, 30,
        0, 0, 0,
        0, 150, 30,
        0, 150, 0
      ]), gl.STATIC_DRAW)
    }

3.绘制并渲染

      webgl.useProgram(program);
      webgl.enableVertexAttribArray(positionAttributeLocation);
      webgl.bindBuffer(webgl.ARRAY_BUFFER, positionBuffer);
      webgl.vertexAttribPointer(positionAttributeLocation, 3, webgl.FLOAT, false, 0, 0);

      var matrix = m4.projection(webgl.canvas.clientWidth, webgl.canvas.clientHeight, 400);
      matrix = m4.translate(matrix, translations[0], translations[1], translations[2]);
      matrix = m4.xRotate(matrix, rotations[0]);
      matrix = m4.yRotate(matrix, rotations[1]);
      matrix = m4.zRotate(matrix, rotations[2]);
      matrix = m4.scale(matrix, scale[0], scale[1], scale[2]);

      webgl.uniformMatrix4fv(matrixUniformLocation, false, matrix);
      webgl.uniform4fv(colorUniformLocation, color);

      webgl.drawArrays(webgl.TRIANGLES, 0, 16 * 6);

注意:vertexAttribPointer的第二个参数为3是因为咱们的顶点坐标变成了3维,也就是在bufferData中设定的各面的顶点坐标(x,y,z),而w可以使用默认值1从而能够不传(因为顶点着色器中坐标的变量类型为vec4)。而对于drawArrays中的第三个参数是指总共要绘制多少个顶点,由于我们需要绘制16个矩形,每个矩形包含两个三角形,而每个三角形又包含3个顶点,因此总共需要绘制16*6个顶点。

结果如下:

 二 三维下的矩阵变换

1.屏幕像素空间与裁剪空间之间的关系 - 投影矩阵

在像素空间中,宽取值范围在0到width,高在0到height,深度在-depth/2 到 +depth/2。让我们对裁剪空间中的宽高深度根据投影矩阵进行拆解:

x' = 2/width * x - w,x' ∈ [-1,1]

y' = -2/height * y + w,y' ∈ [-1,1]

z' = 2/depth * w,z' ∈ [-1,1]

在二维当中,z的默认值为1;而在三维当中,w的默认值为1.

因此,反推回去,像素空间中的宽高以及深度也就一目了然了。在之后矩阵变换的传值当中会传一个与width相似的值给depth。

      projection: function (width, height, depth) {
        return [
          2 / width, 0, 0, 0,
          0, -2 / height, 0, 0,
          0, 0, 2 / depth, 0,
          -1, 1, 0, 1
        ]
      },

      translation: function (tx, ty, tz) {
        return [
          1, 0, 0, 0,
          0, 1, 0, 0,
          0, 0, 1, 0,
          tx, ty, tz, 1,
        ];
      },

      xRotation: function (angleInRadians) {
        var c = Math.cos(angleInRadians);
        var s = Math.sin(angleInRadians);

        return [
          1, 0, 0, 0,
          0, c, s, 0,
          0, -s, c, 0,
          0, 0, 0, 1,
        ];
      },

      yRotation: function (angleInRadians) {
        var c = Math.cos(angleInRadians);
        var s = Math.sin(angleInRadians);

        return [
          c, 0, -s, 0,
          0, 1, 0, 0,
          s, 0, c, 0,
          0, 0, 0, 1,
        ];
      },

      zRotation: function (angleInRadians) {
        var c = Math.cos(angleInRadians);
        var s = Math.sin(angleInRadians);

        return [
          c, s, 0, 0,
          -s, c, 0, 0,
          0, 0, 1, 0,
          0, 0, 0, 1,
        ];
      },

      scaling: function (sx, sy, sz) {
        return [
          sx, 0, 0, 0,
          0, sy, 0, 0,
          0, 0, sz, 0,
          0, 0, 0, 1,
        ];
      }

2. 旋转矩阵

二维图形绕着z轴做旋转就好了,而三维图形可以绕着三个轴分别进行旋转,其内里就是将其中一个轴作为旋转轴然后根据其他两个轴来计算旋转后的坐标,原理其实差不多,这里也就不赘述了。

绕z轴旋转:

        x' = x * cos + y * sin;

        y' = x*(-sin) + y * cos;

绕x轴旋转:

        y' = y * cos + z * sin;

        z' = y*(-sin) + z * cos;

绕y轴旋转:

        x' = x * cos + z * sin;

        z' = x * (-sin) + z * cos;

三 可变量的颜色属性

1.着色器代码(利用varying变量将颜色值从顶点着色器到片段着色器):

  <script id="vertex-shader-3D" type="x-shader/x-vertex">
    attribute vec4 a_position;
    attribute vec4 a_color;

    uniform mat4 u_matrix;

    varying vec4 v_color;

    void main(){
      gl_Position = u_matrix * a_position;
      
      v_color = a_color;
    }
  </script>
  <script id="fragment-shader-3D" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_color;

    void main(){
      gl_FragColor = v_color;
    }
  </script>

2.设置渲染颜色(每个面设置不同的颜色以便区分,注意颜色使用的类型与坐标使用的类型不同):

    function setColors(gl) {
      gl.bufferData(gl.ARRAY_BUFFER, new Uint8Array([
        // left column front
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,

        // top rung front
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,

        // middle rung front
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,
        200, 70, 120,

        // left column back
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,

        // top rung back
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,

        // middle rung back
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,
        80, 70, 200,

        // top
        70, 200, 210,
        70, 200, 210,
        70, 200, 210,
        70, 200, 210,
        70, 200, 210,
        70, 200, 210,

        // top rung right
        200, 200, 70,
        200, 200, 70,
        200, 200, 70,
        200, 200, 70,
        200, 200, 70,
        200, 200, 70,

        // under top rung
        210, 100, 70,
        210, 100, 70,
        210, 100, 70,
        210, 100, 70,
        210, 100, 70,
        210, 100, 70,

        // between top rung and middle
        210, 160, 70,
        210, 160, 70,
        210, 160, 70,
        210, 160, 70,
        210, 160, 70,
        210, 160, 70,

        // top of middle rung
        70, 180, 210,
        70, 180, 210,
        70, 180, 210,
        70, 180, 210,
        70, 180, 210,
        70, 180, 210,

        // right of middle rung
        100, 70, 210,
        100, 70, 210,
        100, 70, 210,
        100, 70, 210,
        100, 70, 210,
        100, 70, 210,

        // bottom of middle rung.
        76, 210, 100,
        76, 210, 100,
        76, 210, 100,
        76, 210, 100,
        76, 210, 100,
        76, 210, 100,

        // right of bottom
        140, 210, 80,
        140, 210, 80,
        140, 210, 80,
        140, 210, 80,
        140, 210, 80,
        140, 210, 80,

        // bottom
        90, 130, 110,
        90, 130, 110,
        90, 130, 110,
        90, 130, 110,
        90, 130, 110,
        90, 130, 110,

        // left side
        160, 160, 220,
        160, 160, 220,
        160, 160, 220,
        160, 160, 220,
        160, 160, 220,
        160, 160, 220
      ]), gl.STATIC_DRAW);
    }

3.启用属性并传值

      webgl.enableVertexAttribArray(colorAttributeLocation);
      webgl.bindBuffer(webgl.ARRAY_BUFFER, colorBuffer);
      webgl.vertexAttribPointer(colorAttributeLocation, 3, webgl.UNSIGNED_BYTE, true, 0, 0);

注意:vertexAttribPointer的第三个参数webgl.UNSIGNED_BYTE和第四个参数true(规范化:即将取值范围设成0-1)

结果如下:

 四 正反面的绘制

1.WebGL中的正反面

WebGL中的三角形有正反面的概念,正面三角形的顶点顺序是逆时针方向,反面三角形的顶点顺序是顺时针方向。

 由上图可以看出,红色是正面,蓝色是背面。红色先绘制而蓝色后绘制的原因在于设置数据的顺序。

2.开启只绘制正面或反面

开启只绘制正面或者反面三角形(这行代码加载refreshDraw的函数里面):

      webgl.enable(webgl.CULL_FACE);

结果如下:

 三角形的正反面是根据着色器的最终计算结果来判定的,如果将X轴缩放-1,那么一个顺时针的三角形就会变成逆时针;如果将顺时针的三角形旋转180°,那么它就会变成逆时针的三角形(相当于按旋转轴进行翻转,原来面向你的面现在背向了你,可以拿张纸实操一下更容易理解)。

结果如下:

 3.修正坐标顺序(即修正朝向)

    function setGeometry(gl) {
      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
        // left column front
        0, 0, 0,
        0, 150, 0,
        30, 0, 0,
        0, 150, 0,
        30, 150, 0,
        30, 0, 0,

        // top rung front
        30, 0, 0,
        30, 30, 0,
        100, 0, 0,
        30, 30, 0,
        100, 30, 0,
        100, 0, 0,

        // middle rung front
        30, 60, 0,
        30, 90, 0,
        67, 60, 0,
        30, 90, 0,
        67, 90, 0,
        67, 60, 0,

        // left column back
        0, 0, 30,
        30, 0, 30,
        0, 150, 30,
        0, 150, 30,
        30, 0, 30,
        30, 150, 30,

        // top rung back
        30, 0, 30,
        100, 0, 30,
        30, 30, 30,
        30, 30, 30,
        100, 0, 30,
        100, 30, 30,

        // middle rung back
        30, 60, 30,
        67, 60, 30,
        30, 90, 30,
        30, 90, 30,
        67, 60, 30,
        67, 90, 30,

        // top
        0, 0, 0,
        100, 0, 0,
        100, 0, 30,
        0, 0, 0,
        100, 0, 30,
        0, 0, 30,

        // top rung right
        100, 0, 0,
        100, 30, 0,
        100, 30, 30,
        100, 0, 0,
        100, 30, 30,
        100, 0, 30,

        // under top rung
        30, 30, 0,
        30, 30, 30,
        100, 30, 30,
        30, 30, 0,
        100, 30, 30,
        100, 30, 0,

        // between top rung and middle
        30, 30, 0,
        30, 60, 30,
        30, 30, 30,
        30, 30, 0,
        30, 60, 0,
        30, 60, 30,

        // top of middle rung
        30, 60, 0,
        67, 60, 30,
        30, 60, 30,
        30, 60, 0,
        67, 60, 0,
        67, 60, 30,

        // right of middle rung
        67, 60, 0,
        67, 90, 30,
        67, 60, 30,
        67, 60, 0,
        67, 90, 0,
        67, 90, 30,

        // bottom of middle rung.
        30, 90, 0,
        30, 90, 30,
        67, 90, 30,
        30, 90, 0,
        67, 90, 30,
        67, 90, 0,

        // right of bottom
        30, 90, 0,
        30, 150, 30,
        30, 90, 30,
        30, 90, 0,
        30, 150, 0,
        30, 150, 30,

        // bottom
        0, 150, 0,
        0, 150, 30,
        30, 150, 30,
        0, 150, 0,
        30, 150, 30,
        30, 150, 0,

        // left side
        0, 0, 0,
        0, 0, 30,
        0, 150, 30,
        0, 0, 0,
        0, 150, 30,
        0, 150, 0
      ]), gl.STATIC_DRAW)
    }

结果如下:

4.开启深度缓冲(Z-Buffer)

由上图可以看出,呈现出来的“F”还是有些奇怪的,按常理来说有的矩形面应该会被前面的面遮挡住才对呀。这是因为我们还没有开启深度缓存,简单理解深度缓存就是为了遮挡后面元素(即深度值不大的元素)。

      webgl.clear(webgl.COLOR_BUFFER_BIT | webgl.DEPTH_BUFFER_BIT);

      webgl.enable(webgl.DEPTH_TEST);

注意:在开启深度缓冲之前要先清空深度缓冲噢~这个应该是相当于将Z值从裁剪空间([-1,1])转换到深度空间([0,1])。

结果如下(是不是正常多啦~): 

五 正射投影

上面的涉及到的投影矩阵就是我们常说的正射投影啦,只不过真正的正射投影的函数会更完善一些,涉及到各个方向(上下左右前后),通常用ortho或者相关的函数来进行调用。

比如,ortho(left,right,bottom,top,near,far){}

具体的可以参考你所使用的外部库里面对于正射投影函数的定义。

调用时每个参数可以这样设置(作为参考):

ortho(0,webgl.canvas.clientWidth,webgl.canvas.clientHeight,0,400,-400)

发现了吗,就是我们上面提到过的像素空间的取值范围。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WebGL 实践篇(五)三维图形的绘制及矩阵变换、正射投影 的相关文章

  • 您可以将原始 WebGL 纹理与 Three.js 一起使用吗

    我有一个相当复杂的架构 我在 Three JS 中完成大部分工作 但我也有一个特殊的渲染器 可以直接渲染到原始 WebGL 纹理 是否可以在 Three js 纹理 中使用此 WebGL 纹理 看起来 Three JS 纹理类只是图像 视频
  • 如何在 UWP 上的 Xamarin.Forms WebView 中启用 WebGL?

    我是 Xamarin Forms 新手 尝试在 Windows 10 x64 v1803 计算机上使用 UWP 使用 WebView 但我不知道如何让它与 WebGL 一起使用 使用 WebGL 的网站要么显示一条消息 您的视频卡不支持 W
  • 片段着色器 - 确定整个(单色)图像的最小/最大值并使用它们进行进一步的像素操作

    我想正常化单色图像像素以这种方式最小值为黑色 最大值为白色 并且两者之间的值按比例分布 目前我在 canvas 中分两步完成 但我相信在 WebGL 中应该更快 我可以想象通过片段着色器操纵颜色 但我找不到任何有效的方法来 1 确定图像的实
  • 如何检测用户是否在浏览器中启用了全屏

    当用户在 Chrome 或 FireFox 中启用全屏时 是否会触发一些 JavaScript 事件 我有 WebGL 应用程序 画布宽度和高度设置为一定大小 当用户启用全屏时 我想调整其大小 如果没有这样的事件 我是否应该开始研究用画布填
  • 未捕获的类型错误:无法解析模块说明符“三/示例/jsm/loaders/GLTFLoader.js”

    我很难理解为什么我的程序由于这个错误而崩溃 未捕获的类型错误 无法解析模块说明符 三 示例 jsm loaders GLTFLoader js 相对引用必须以 或 开头 我正在尝试使我的 html 文件与我创建的 serial js 文件进
  • 将 webGL html 转换为 SVG

    我正在使用 R 以及 Misc3d 和 rpanel 库 在 webGL 中创建 3D 图像 然后我需要通过 Latex 将图像嵌入到 PDF 中 3D 图像渲染良好并且看起来很棒 但我想我需要将 webGL HTML 文件转换为 SVG
  • 以到最近边缘的距离为函数的着色矩形会在对角线上产生奇怪的结果

    I m trying to color a rectangle in ShaderToy GLSL in function of each pixel s distance to the nearest rectangle edge How
  • Three.js中是否有一个容器类型对象来转换一组孩子?

    Three js 中是否有一个容器或节点对象 可以将多个网格添加为子对象 以便它们可以一起转换 一个不可见的容器 允许对组中的所有子对象执行转换 thanks Example http mrdoob github com three js
  • 在 Fabric.js 中真正旋转等边三角形的中心

    使用 Fabric js 我无法真正围绕其中心点旋转三角形 或者至少我认为应该是中心点 我创建了一个jsFiddle http jsfiddle net UW8Be 这表明 三角形很简单 我用了originX center 原点Y 也是如此
  • 深度图三.js

    Three js中有没有办法获取深度图 我感兴趣的是制作类似于 Kinect 为给定场景制作的东西 我遇到了一种不使用颜色和雾来模仿这一点的黑客方法 但这并不理想 因为它会使用两个不同的场景并且会因光照而变化 我认为执行此操作的另一种方法是
  • 如何在 Ubuntu 的 headless chrome 中启用 WebGL?

    如何在 Ubuntu 14 的 headless chrome 中启用 webgl 或安装 webgl 我尝试安装 libosmesa6 但这没有帮助 有人可以指出我正确的方向吗 我想使用 webgl 来处理无头 chrome 和 sele
  • VS CODE 中的 WEBGL 自动完成

    我有一个学校项目 我需要使用 WEBGL 但是在没有自动补全的情况下编写所有代码是相当困难的 我没有找到合适的扩展名 你有想法吗 为了让 Visual Studio 代码能够自动完成 它需要知道变量的类型 例如 如果你有这个 const g
  • 上传统一块的正确顺序是什么?

    在示例页面中https www lighthouse3d com tutorials glsl tutorial uniform b locks https www lighthouse3d com tutorials glsl tutor
  • 在每一帧上更新整个 VBO 是绘制许多变化的独特三角形的最有效方法吗?

    答复我之前的问题 https stackoverflow com questions 24592099 drawing many unique triangles with a single draw call for better per
  • 三.js环境光意想不到的效果

    在下面的代码中 我渲染了一些立方体并使用点光源和环境光照亮它们 然而 当设置为 0xffffff 时 AmbientLight 会将侧面的颜色更改为白色 无论其指定的颜色如何 奇怪的是 点光源按预期工作 我怎样才能使环境光表现得像点光 因为
  • 使用文件 API 将资源加载到 Three.js 中

    我想创建导入 3D 模型以在浏览器中查看的功能 方法是使用File API http www html5rocks com en tutorials file dndfiles Three js 加载器在我托管的文件上运行良好 我的理解是加
  • WebGL 如何设置深度缓冲区中的值?

    在 OpenGL 中 深度缓冲区值是根据场景的近剪裁平面和远剪裁平面计算的 参考 从深度缓冲区获取真实的 z 值 https stackoverflow com questions 6652253 getting the true z va
  • 使用矩阵变换 Three.js 场景图

    我正在尝试将文件中的场景加载到 Three js 中 自定义格式 不是 Three js 支持的格式 这种特殊格式描述了一个场景图 其中树中的每个节点都有一个指定为 4x4 矩阵的变换 将其推送到 Three js 的过程如下所示 Yeah
  • 与整数纹理进行 Alpha 混合以进行对象拾取

    问题描述 你好 在我们的 WebGL 应用程序中 我们正在绘制许多 甚至数十万 形状 并且我们想要发现当前鼠标位于哪个形状 我正在寻找一种有效的方法 Details 形状定义为有符号距离函数 https en wikipedia org w
  • 如何检查 webgl(two.js) 的客户端性能

    我有一个使用 Three JS 的图形项目 现在我想自动检查客户端 GPU 性能并计算可以在应用程序中加载多少元素 我想到了诸如 GPU 基准测试之类的东西 看一眼stats js https github com mrdoob stats

随机推荐

  • RocketMQ-源码解读与调试

    源码环境搭建 源码拉取 RocketMQ的官方Git仓库地址 GitHub apache rocketmq Mirror of Apache RocketMQ 可以用git把项目clone下来或者直接下载代码包 也可以到RocketMQ的官
  • Java设计模式-结构型设计模式-适配器模式

    Java设计模式 结构型设计模式 适配器模式 从这一专栏开始将学习设计模式 上课学习和自己总结归纳的笔记将总结出来供大家参考 参考书籍 设计模式就该这样学 其他文章 Java设计模式 UML类图 Java设计模式 七大架构设计原则 开闭原则
  • 机器学习NLP参考文章

    本站整理了一些NLP的入门资料参考 建议初学者看看 需要复制链接在浏览器里打开 1 通过kaggle比赛学习机器学习文本分类方法https zhuanlan zhihu com p 34899693 utm medium social ut
  • 宋浩高等数学笔记(八)向量代数与空间解析几何

    本章知识点并不难理解 但是公式与名词属于非常多 记忆时需重点对待
  • Java GUI编程——在线聊天室

    引言 综合应用Java的GUI编程和网络编程 实现一个能够支持多组用户同时使用的聊天室软件 该聊天室具有比较友好的GUI界面 并使用C S模式 支持多个用户同时使用 用户可以自己选择加入或者创建房间 和房间内的其他用户互发信息 文字和图片
  • Web前端的优点有什么?为什么前端可以这么火?

    今天小编要跟大家分享的文章是关于web前端的优点有哪些 为什么Web前端可以这么火 相信小伙伴们对Web前端并不陌生 那么你知道Web前端的有点都有哪些吗 下面就让我们一起来看一看吧 HTML5是唯一一个通吃PC Mac iPhone iP
  • oracle两个日期的月份间隔,Oracle 计算两个日期间隔的天数、月数和年数

    在Oracle中计算两个日期间隔的天数 月数和年数 一 天数 在Oracle中 两个日期直接相减 便可以得到天数 1 select to date 08 06 2015 mm dd yyyy to date 07 01 2015 mm dd
  • 三招搞定你的ubuntu安全问题

    本篇主要介绍以下三个部分 反病毒引擎clamav的安装和使用 ubuntu ufw限制访问地址 ubuntu用户连接失败锁定指定时间 反病毒引擎clamav的安装和使用 简介 ClamAV是一款开源的反病毒引擎 用于检测病毒 特洛伊木马 恶
  • IT行业里的热门技术和项目分享

    随着科技的发展 IT行业中涌现出了很多热门技术 其中最具代表性的包括人工智能和机器学习 云计算和云原生技术 大数据和数据分析 容器化技术和Kubernetes 前端框架和组件库等 此外 也有一些热门IT技术项目备受关注 比如Apache K
  • jdk报错

    Syntax error annotations are only available if source level is 1 5 or greater解决方法 原创 2016年07月18日 14 13 39 ul class artic
  • Java内存分配全面浅析

    本文将由浅入深详细介绍Java内存分配的原理 以帮助新手更轻松的学习Java 这类文章网上有很多 但大多比较零碎 本文从认知过程角度出发 将带给读者一个系统的介绍 进入正题前首先要知道的是Java程序运行在JVM Java VirtualM
  • 多维随机变量及其分布(四):

    一 二维随机变量及其分布函数 1 二维随机变量 设随机变量 Z X Y 则有 Z X Y 一个随机变量是有两个随机变量决定的 2 联合分布函数的基本性质 单调性 F x y 分别对x 或y是单调不减的 即 对任意固定的y 当 x1 lt x
  • 【SPI】STM32 SPI 双机通信,SPI从机模式使用

    文章目录 一 SPI主机配置 二 SPI从机配置 三 双机通信 1 轮询 中断 低速 2 轮询 DMA 低速 3 DMA DMA 高速 4 开启CRC校验 自选 四 遇到的问题 1 高速使用时 程序卡死 或者数据出错 已解决 2 数据莫名其
  • html制作日程安排,在线日程安排怎样做?日程表在线制作工具

    在线日程安排怎样做 日程表在线制作工具 在线日程安排怎样做 每日仅有二十四小时 可在一天我们要做的事却太多 每日忙的晕头转向 身心俱疲 这可咋办啊 戴尔 麦康基说过 计划的订制比计划本身更为重要 因此可见 订制好每日的行程安排是不可或缺的
  • 详述String类的equals方法

    详述String类的equals方法 1 两个String类的对象采取直接赋值 ublic class Test public static void main String args String name1 Tom String nam
  • java基础语法之面向对象

    面向对象 面向对象是一种编程思想 与之对应的是面向过程 区别 面向过程 POP 强调的是功能 面向对象 OOP 强调的是带有具体功能的对象 面向对象的优点 提高代码复用性 降低代码间的耦合度 提升代码维护性 三大特征 封装 继承 多态 一
  • 六种黑客入侵手机的常见方式

    六种黑客入侵手机的常见方式 在移动网络科技高速发展的今天 我们每个人的手机都有可能成为黑客攻击的对象 下面为大家介绍6种黑客入侵手机的常见方式 希望能够帮助大家避免手机被不对象攻击 1 网络钓鱼攻击 网络钓鱼攻击非常普遍 那是因为它们非常有
  • 磁盘空间重分配

    root localhost df h Filesystem Size Used Avail Use Mounted on dev mapper VolGroup lv root 50G 47G 16M 100 lv root满了 tmpf
  • pageHelper的使用与源码分析

    文章目录 一 使用步骤 二 分页原理 1 统计总数 2 源码分析 三 总结 pageHelper作为Mybatis最好用的分页插件 自然受到极大多数人的追捧 而这里想要尽量阐述清楚pageHelper的具体使用步骤 实现的背后原理 以及与原
  • WebGL 实践篇(五)三维图形的绘制及矩阵变换、正射投影

    一 三维 F 的绘制 1 着色器 按照上一篇提到的矩阵变换 我们可以直接在顶点着色器中加入相应的矩阵变换 这样就可以简化着色器代码 通过变量传入矩阵的值也便于之后矩阵变换的修改 三维图形的绘制相比于二维图形只在参数类型上有一些变化 注意ve