在 WebGL 中绘制许多形状

2023-11-21

我正在阅读教程here.

<script class = "WebGL">
var gl;
function initGL() {
  // Get A WebGL context
  var canvas = document.getElementById("canvas");
  gl = getWebGLContext(canvas);
  if (!gl) {
    return;
  }
}
var positionLocation;
var resolutionLocation;
var colorLocation;
var translationLocation;
var rotationLocation;
var translation = [50,50];
var rotation = [0, 1];
var angle = 0;
function initShaders() {
  // setup GLSL program
  vertexShader = createShaderFromScriptElement(gl, "2d-vertex-shader");
  fragmentShader = createShaderFromScriptElement(gl, "2d-fragment-shader");
  program = createProgram(gl, [vertexShader, fragmentShader]);
  gl.useProgram(program);

  // look up where the vertex data needs to go.
  positionLocation = gl.getAttribLocation(program, "a_position");

  // lookup uniforms
  resolutionLocation = gl.getUniformLocation(program, "u_resolution");
  colorLocation = gl.getUniformLocation(program, "u_color");
  translationLocation = gl.getUniformLocation(program, "u_translation");
    rotationLocation = gl.getUniformLocation(program, "u_rotation");

  // set the resolution
  gl.uniform2f(resolutionLocation, canvas.width, canvas.height);
}
function initBuffers() {
  // Create a buffer.
  var buffer = gl.createBuffer();
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
  gl.enableVertexAttribArray(positionLocation);
  gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

  // Set Geometry.
  setGeometry(gl);
}

function setColor(red, green, blue) {
    gl.uniform4f(colorLocation, red, green, blue, 1);
}
// Draw the scene.
function drawScene() {
    // Clear the canvas.
    gl.clear(gl.COLOR_BUFFER_BIT);

    // Set the translation.
    gl.uniform2fv(translationLocation, translation);
    // Set the rotation.
    gl.uniform2fv(rotationLocation, rotation);

    // Draw the geometry.
    gl.drawArrays(gl.TRIANGLES, 0, 6);
}


// Fill the buffer with the values that define a letter 'F'.
function setGeometry(gl) {
/*Assume size1 is declared*/
    var vertices = [
         -size1/2, -size1/2,
         -size1/2, size1/2,
         size1/2, size1/2,
         size1/2, size1/2,
         size1/2, -size1/2,
         -size1/2, -size1/2 ];
      gl.bufferData(
         gl.ARRAY_BUFFER,
         new Float32Array(vertices),
         gl.STATIC_DRAW);
}
function animate() {
    translation[0] += 0.01;
    translation[1] += 0.01;
    angle += 0.01;
    rotation[0] = Math.cos(angle);
    rotation[1] = Math.sin(angle);
}
function tick() {
    requestAnimFrame(tick);
    drawScene();
    animate();
}
function start() {

    initGL();
    initShaders();
    initBuffers();
    setColor(0.2, 0.5, 0.5);
    tick();
}

</script>

<!-- vertex shader -->
<script id="2d-vertex-shader" type="x-shader/x-vertex">
    attribute vec2 a_position;

    uniform vec2 u_resolution;
    uniform vec2 u_translation;
    uniform vec2 u_rotation;
    void main() {
        vec2 rotatedPosition = vec2(
        a_position.x * u_rotation.y + a_position.y * u_rotation.x,
        a_position.y * u_rotation.y - a_position.x * u_rotation.x);

       // Add in the translation.
       vec2 position = rotatedPosition + u_translation;

       // convert the position from pixels to 0.0 to 1.0
       vec2 zeroToOne = position / u_resolution;

       // convert from 0->1 to 0->2
       vec2 zeroToTwo = zeroToOne * 2.0;

       // convert from 0->2 to -1->+1 (clipspace)
       vec2 clipSpace = zeroToTwo - 1.0;

       gl_Position = vec4(clipSpace, 0, 1);
    }
</script>
<!-- fragment shader -->
<script id="2d-fragment-shader" type="x-shader/x-fragment">
    precision mediump float;

    uniform vec4 u_color;

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

我的 1 个形状的 WebGL 程序的工作原理如下:

  1. 从 canvas 元素获取上下文 (gl)。
  2. 用我的对象的形状初始化缓冲区
  3. drawScene(): 打电话给gl.drawArrays()
  4. 如果有动画,更新函数,它会更新我的形状的角度、位置, 进而drawScene()同时在tick(),以便它被重复调用。

现在,当我需要超过 1 个形状时,我是否应该立即用许多对象填充单个缓冲区,然后使用它来稍后调用drawScene()一次绘制所有对象[OR]我应该重复打电话吗initBuffer and drawScene() from requestAnimFrame().


在伪代码中

在初始化时

  • 从 canvas 元素获取上下文 (gl)。
  • for each shader
    • 创建着色器
    • 查找属性和统一位置
  • for each shape
    • 使用形状初始化缓冲区
  • for each texture
    • 创建纹理和/或用数据填充它们。

抽奖时

  • for each shape
    • 如果最后使用的着色器与此形状调用所需的着色器不同gl.useProgram
    • For each attribute needed by shader
      • call gl.enableVertexAttribArray, gl.bindBuffer and gl.vertexAttribPointer对于形状所需的每个属性以及当前着色器的属性位置。
    • For each uniform needed by shader
      • call gl.uniformXXX使用当前着色器的位置与所需的值
    • call gl.drawArrays或者如果数据被索引称为gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferOfIndicesForCurrentShape)其次是gl.drawElements

常见优化

1)通常你不需要设置每件制服。例如,如果您使用以下命令绘制 10 个形状same着色器并且该着色器采用viewMatrix或cameraMatrix,viewMatrix制服或cameraMatrix制服很可能对于每个形状都是相同的,因此只需设置一次。

2) 您通常可以将呼叫转移至gl.enableVertexAttribArray到初始化时间。

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

在 WebGL 中绘制许多形状 的相关文章

随机推荐

  • 如何为 IXmlSerialized 类型添加命名空间前缀

    我有以下类定义 XmlRoot ElementName person Namespace MyNamespace public class Person IXmlSerializable public string FirstName ge
  • 包安装错误 - 实体框架

    当我尝试创建 ADO NET 实体数据模型时发生错误 错误说 预安装的软件包引用了缺失的注册表 价值 找不到具有名称的注册表项 EntityFrameworkVisualStudio14Tools 下 软件 NuGet 存储库 我使用的是
  • 在后台启动 jenkins

    我正在使用 war 文件在我的服务器上运行 jenkins 他们说用 java jar jenkins war 来源 https wiki jenkins ci org display JENKINS Starting and Access
  • 什么 Maven 工件包含 javax.ws.rs.Path?

    我正在研究 Bill Burke 编写的 Restful Java with JAX RS 中的示例 我正在使用 intellij 并创建了一个 Maven 项目来制作 Hello World Web 服务 我理解 JAX RS 是一个规范
  • 如何对 Laravel 5.7“电子邮件验证”电子邮件发送进行排队

    Laravel 5 7 包含的 电子邮件验证 功能运行良好 但异步电子邮件发送 在用户注册或重新发送链接页面期间 并不理想 有没有办法通过队列发送电子邮件验证电子邮件 而无需在 Laravel 5 7 中重写整个电子邮件验证 没有内置的方法
  • 详细披露按下后注释详细信息?

    我有一个 MKMapView 注释对象 它有一个正确的标注附件详细信息披露按钮 当按下按钮时 我使用 addTarget action forControlEvent 调用一个选择器方法 该方法创建一个详细视图控制器并将其推送到视图堆栈上
  • 如何在 Visual C++ 中调试外部库 (OpenCV)?

    我正在用VC 2008开发一个项目 该项目使用 OpenCV 库 但我想这适用于任何其他库 我正在使用调试配置 链接器属性包括库 lib 的调试版本作为附加依赖项 在 工具 选项 下的 VC 目录中 我设置了包含目录 lib 目录以及库的源
  • hadoop - namenode上的连接被拒绝

    我在网上和stackoverflow上搜索了很长时间 但没有用 我已经在 2 节点集群设置中安装了 hadoop yarn 2 2 0 但出了问题 当我在主节点上使用 start dfs sh 和 start yarn sh 启动 hado
  • 使用新的 csproj 在 PDB 中嵌入 C# 源代码

    最近发布的 NET 工具似乎支持在 PDB 中嵌入 C 这应该会改善进入第三方等的体验 csc 我可以清楚地看到 embed 选项 将所有源文件嵌入到 PDB 中 但是 似乎没有任何方法可以在 csproj 中指定这一点 此外 似乎没有任何
  • Html2Canvas 调整大小

    我正在使用 html2canvas 来获取网页的屏幕截图并将其呈现为缩略图 好吧 400x300 不完全是缩略图 基于截图控制台代码 除了缩略图部分之外 一切都运行良好 如何将图像尺寸设置为 400x300 在 firebug 中 我将该属
  • 如何在 XSD 中添加条件验证:

    现有的 XSD 片段
  • 如何确保 WPF 数据绑定重构安全?

    因此 我正在完成我的第一个 WPF 项目 并且我很喜欢到目前为止所看到的内容 学习曲线比我预期的要多 但尽管如此 WPF 还是很酷的 然而 我在数据绑定概念上遇到了一些困难 我的一个具体问题是如何使我的数据绑定声明重构安全 考虑这个例子 p
  • 使用 fill 或 fill_ Between 绘制甜甜圈

    我想绘制一个甜甜圈 我的脚本是 import numpy as np import matplotlib pyplot as plt pi sin cos np pi np sin np cos r1 1 r2 2 theta np lin
  • 如何获得 .NET TreeView 的 Windows 原生外观?

    在 NET 中使用 TreeView 组件时 我看到了左侧树的外观 如何为我的 NET TreeView 获得正确的树外观 Windows Native Look 我特别想要得到的是 三角形 节点手柄和蓝色 气泡 选择方块 您需要 P In
  • 如果应用程序在 Google App Engine 上调用超过 10 个异步 URL 提取,会发生什么情况?

    阅读 Google App Engine文档异步 URL 获取 该应用程序最多可以同时运行 10 个 异步 URL 获取调用 如果应用程序一次调用超过 10 个异步提取 会发生什么情况 Google App Engine 是否会引发异常或只
  • 如何使用 PHP cURL 发布 JSON 数据?

    这是我的代码 url url to post data array first name gt First name last name gt last name email gt email protected addresses gt
  • 通过类型的大小写匹配,根据 SparkSQL 中的类型转换值

    Scala 中是否可以匹配参数类型 假设我有一个接收两个参数的函数 value and a type 我想使用模式匹配来进行类型转换 像这样的东西 datatype match case IntegerType gt return valu
  • 为什么 Cache-Control 属性在请求标头中发送(客户端到服务器)?

    阅读完有关Cache ControlHTTP 标头字段 据我了解 Cache ControlHTTP 响应标头 服务器到客户端 中的字段通过发送不同的值来指定中间代理服务器 客户端浏览器如何处理响应的指令Cache Control fiel
  • 如何找出可执行文件将加载哪些 dll?

    如果我有 Windows 可执行文件 如何找出它将加载哪些 dll 我只是谈论哪些将静态加载 而不是那些可能使用 LoadLibrary 之类的东西动态加载的 dumpbin是VC 自带的工具 要查看程序将导入哪些 DLL 打开视觉工作室
  • 在 WebGL 中绘制许多形状

    我正在阅读教程here