Browse Source

feature: webgl

xiongxt 1 year ago
parent
commit
d19c228b74
5 changed files with 242 additions and 24 deletions
  1. 10 5
      public/index.html
  2. 1 0
      src/components/navBar.vue
  3. 23 18
      src/router/index.js
  4. 206 0
      src/views/webgl/index.vue
  5. 2 1
      tsconfig.json

+ 10 - 5
public/index.html

@@ -1,17 +1,22 @@
 <!DOCTYPE html>
 <html lang="">
   <head>
-    <meta charset="utf-8">
-    <meta http-equiv="X-UA-Compatible" content="IE=edge">
-    <meta name="viewport" content="width=device-width,initial-scale=1.0">
-    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
+    <meta charset="utf-8" />
+    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
+    <link rel="icon" href="<%= BASE_URL %>favicon.ico" />
     <title><%= htmlWebpackPlugin.options.title %></title>
   </head>
   <body>
     <noscript>
-      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
+      <strong
+        >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
+        properly without JavaScript enabled. Please enable it to
+        continue.</strong
+      >
     </noscript>
     <div id="app"></div>
+    <script src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"></script>
     <!-- built files will be auto injected -->
   </body>
 </html>

+ 1 - 0
src/components/navBar.vue

@@ -4,6 +4,7 @@
       <h1>Ludash</h1>
     </div>
     <div class="menu">
+      <RouterLink to="/webgl">webgl</RouterLink>
       <RouterLink to="/flow">Flow</RouterLink>
       <RouterLink to="/install">安装</RouterLink>
       <RouterLink to="/sdk">SDK</RouterLink>

+ 23 - 18
src/router/index.js

@@ -1,6 +1,13 @@
 import { createRouter, createWebHashHistory } from "vue-router";
 import { defineComponent } from "vue";
 
+const DynamicComponent = defineComponent({
+  name: "DynamicComponent",
+  render() {
+    return <router-view></router-view>;
+  },
+});
+
 /**
  * @type {import("vue-router").RouteRecordRaw[]}
  */
@@ -15,12 +22,7 @@ const routes = [
   {
     path: "/install",
     name: "install",
-    component: defineComponent({
-      name: "DynamicComponent",
-      render() {
-        return <router-view></router-view>;
-      },
-    }),
+    component: DynamicComponent,
     children: [
       {
         path: "",
@@ -33,12 +35,7 @@ const routes = [
   {
     path: "/flow",
     name: "flow",
-    component: defineComponent({
-      name: "DynamicComponent",
-      render() {
-        return <router-view></router-view>;
-      },
-    }),
+    component: DynamicComponent,
     children: [
       {
         path: "",
@@ -48,15 +45,23 @@ const routes = [
       },
     ],
   },
+  {
+    path: "/webgl",
+    name: "webgl",
+    component: DynamicComponent,
+    children: [
+      {
+        path: "",
+        name: "webglIndex",
+        component: () =>
+          import(/* webpackChunkName: "webgl" */ "../views/webgl/index.vue"),
+      },
+    ],
+  },
   {
     path: "/sdk",
     name: "sdk",
-    component: defineComponent({
-      name: "DynamicComponent",
-      render() {
-        return <router-view></router-view>;
-      },
-    }),
+    component: DynamicComponent,
     children: [
       {
         path: "queue",

+ 206 - 0
src/views/webgl/index.vue

@@ -0,0 +1,206 @@
+<template>
+  <div>
+    <canvas ref="canvas" id="canvas" width="500" height="500" />
+    <component
+      :is="'script'"
+      src="https://webglfundamentals.org/webgl/resources/webgl-utils.js"
+    />
+  </div>
+</template>
+
+<script setup>
+import { onMounted, ref } from "vue";
+
+/**
+ * @type {import("vue").Ref<HTMLCanvasElement>}
+ */
+const canvas = ref();
+
+/**
+ * @param {WebGLRenderingContext} gl
+ * @param {number} type
+ * @param {string} source
+ */
+function createShader(gl, type, source) {
+  var shader = gl.createShader(type); // 创建着色器对象
+  gl.shaderSource(shader, source); // 提供数据源
+  gl.compileShader(shader); // 编译 -> 生成着色器
+  var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
+  if (success) {
+    return shader;
+  }
+
+  gl.deleteShader(shader);
+}
+
+/**
+ * @param {WebGLRenderingContext} gl
+ * @param {WebGLShader} vertexShader
+ * @param {WebGLShader} fragmentShader
+ */
+function createProgram(gl, vertexShader, fragmentShader) {
+  var program = gl.createProgram();
+  gl.attachShader(program, vertexShader);
+  gl.attachShader(program, fragmentShader);
+  gl.linkProgram(program);
+  var success = gl.getProgramParameter(program, gl.LINK_STATUS);
+  if (success) {
+    return program;
+  }
+
+  gl.deleteProgram(program);
+}
+
+// 返回 0 到 range 范围内的随机整数
+function randomInt(range) {
+  return Math.floor(Math.random() * range);
+}
+
+// 用参数生成矩形顶点并写进缓冲
+
+function setRectangle(gl, x, y, width, height) {
+  var x1 = x;
+  var x2 = x + width;
+  var y1 = y;
+  var y2 = y + height;
+
+  // 注意: gl.bufferData(gl.ARRAY_BUFFER, ...) 将会影响到
+  // 当前绑定点`ARRAY_BUFFER`的绑定缓冲
+  // 目前我们只有一个缓冲,如果我们有多个缓冲
+  // 我们需要先将所需缓冲绑定到`ARRAY_BUFFER`
+
+  gl.bufferData(
+    gl.ARRAY_BUFFER,
+    new Float32Array([x1, y1, x2, y1, x1, y2, x1, y2, x2, y1, x2, y2]),
+    gl.STATIC_DRAW
+  );
+}
+
+onMounted(() => {
+  const gl = canvas.value.getContext("webgl");
+
+  const vertexShader = createShader(
+    gl,
+    gl.VERTEX_SHADER,
+    `
+      // 一个属性变量,将会从缓冲中获取数据
+      attribute vec2 a_position;
+ 
+      uniform vec2 u_resolution;
+      varying vec4 v_color;
+    
+      void main() {
+        // 从像素坐标转换到 0.0 到 1.0
+        vec2 zeroToOne = a_position / u_resolution;
+    
+        // 再把 0->1 转换 0->2
+        vec2 zeroToTwo = zeroToOne * 2.0;
+    
+        // 把 0->2 转换到 -1->+1 (裁剪空间)
+        vec2 clipSpace = zeroToTwo - 1.0;
+    
+        // gl_Position = vec4(clipSpace, 0, 1);
+
+        gl_Position = vec4(clipSpace * vec2(1, -1), 0, 1);
+
+        v_color = gl_Position * 0.5 + 0.5;
+
+      }
+    `
+  );
+  const fragmentShader = createShader(
+    gl,
+    gl.FRAGMENT_SHADER,
+    `
+      // 片段着色器没有默认精度,所以我们需要设置一个精度
+      // mediump是一个不错的默认值,代表“medium precision”(中等精度)
+      precision mediump float;
+
+      uniform vec4 u_color;
+
+      varying vec4 v_color;
+
+      void main() {
+        // gl_FragColor = u_color;
+        gl_FragColor = u_color;
+      }
+    `
+  );
+  var program = createProgram(gl, vertexShader, fragmentShader);
+  var positionAttributeLocation = gl.getAttribLocation(program, "a_position");
+  var resolutionUniformLocation = gl.getUniformLocation(
+    program,
+    "u_resolution"
+  );
+
+  var positionBuffer = gl.createBuffer();
+  gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
+  // gl.bufferData(
+  //   gl.ARRAY_BUFFER,
+  //   new Float32Array([0, 0, 0, 0.5, 0.5, 0]),
+  //   gl.STATIC_DRAW
+  // );
+
+  gl.bufferData(
+    gl.ARRAY_BUFFER,
+    new Float32Array([0, 0, 0, 100, 100, 0, 500, 0, 500, 100, 400, 0]),
+    gl.STATIC_DRAW
+  );
+
+  gl.useProgram(program);
+  gl.enableVertexAttribArray(resolutionUniformLocation);
+  gl.uniform2f(resolutionUniformLocation, gl.canvas.width, gl.canvas.height);
+
+  window.webglUtils.resizeCanvasToDisplaySize(gl.canvas);
+  gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
+
+  gl.clearColor(0, 0, 0, 0);
+  gl.clear(gl.COLOR_BUFFER_BIT);
+
+  var size = 2; // 每次迭代运行提取两个单位数据
+  var type = gl.FLOAT; // 每个单位的数据类型是32位浮点型
+  var normalize = false; // 不需要归一化数据
+  var stride = 0; // 0 = 移动单位数量 * 每个单位占用内存(sizeof(type)) 每次迭代运行运动多少内存到下一个数据开始点
+  var offset = 0; // 从缓冲起始位置开始读取
+  gl.vertexAttribPointer(
+    resolutionUniformLocation,
+    size,
+    type,
+    normalize,
+    stride,
+    offset
+  );
+
+  var primitiveType = gl.TRIANGLES;
+  gl.drawArrays(primitiveType, 0, 100);
+
+  var colorUniformLocation = gl.getUniformLocation(program, "u_color");
+
+  // 绘制50个随机颜色矩形
+  for (var ii = 0; ii < 50; ++ii) {
+    // 创建一个随机矩形
+    // 并将写入位置缓冲
+    // 因为位置缓冲是我们绑定在
+    // `ARRAY_BUFFER`绑定点上的最后一个缓冲
+    setRectangle(
+      gl,
+      randomInt(300),
+      randomInt(300),
+      randomInt(300),
+      randomInt(300)
+    );
+
+    // 设置一个随机颜色
+    gl.uniform4f(
+      colorUniformLocation,
+      Math.random(),
+      Math.random(),
+      Math.random(),
+      1
+    );
+
+    // 绘制矩形
+    gl.drawArrays(gl.TRIANGLES, 0, 6);
+  }
+});
+</script>

+ 2 - 1
tsconfig.json

@@ -11,7 +11,8 @@
     "skipLibCheck": true, 
     "importHelpers": true,     
     "forceConsistentCasingInFileNames": true,
-    "noUnusedLocals": true,
+    "noUnusedLocals": false,
+    "noUnusedParameters": false,
     "allowJs": true,
     "paths": {
       "tslib" : ["node_modules/tslib/tslib.d.ts"],