WebGL系列教程三(使用缓冲区绘制三角形)

目录

  • 1 前言
  • 2 缓冲区介绍
  • 3 声明顶点的位置和颜色
  • 4 回忆Shader的初始化
  • 5 开始缓冲区的逻辑
    • 5.1 声明顶点坐标
    • 5.2 创建并绑定缓冲区
    • 5.3 获取顶点着色器中的变量
    • 5.4 使变量从缓冲区取值
    • 5.5 绘制
    • 5.6 完整代码
  • 6 总结

1 前言

  上一篇中我们介绍了WebGL的环境搭建及Shader的初始化,并绘制了一个点,这一篇我们来绘制一个三角形,并介绍缓冲区的使用方法。

2 缓冲区介绍

  缓冲区就是一块存储数据的区域,为了方便我们一次性把所需的数据都传给WebGL,而不是每次都去传。这次我们的流程和上一篇的操作流程基本是一致的,唯一不同的在于绘制时使用缓冲区的数据绘制三角形,我们还是将整个流程梳理一下:

  1. 创建着色器对象
  2. 获取着色器对象的源代码
  3. 绑定着色器的源
  4. 编译着色器
  5. 创建并关联项目
  6. 创建并绑定缓冲区
  7. 读取缓冲区数据并绘制三角形

  最后就我们要的三角形是这样的,颜色是红色:
在这里插入图片描述

3 声明顶点的位置和颜色

  这一块的代码并没有什么特别之处,只是去掉了声明点的那一句代码gl_PointSize = 10.0;,因为这次我们不再需要绘制点了,其他的保持原样。

 <script id="vertex-shader" type="x-shader/x-vertex">//声明一个点,vec2表示2维向量attribute vec2 aPos;void main(){//点的位置,将vec2补齐为vec4gl_Position = vec4(aPos,0.0,1.0);}</script><script id="fragment-shader" type="x-shader/x-fragment">precision highp float;void main(){//点的颜色,rgba形式,红色gl_FragColor = vec4(1.0,0.0,0.0,1.0);}</script>

4 回忆Shader的初始化

  这一块的代码我们在上一篇已经介绍过了,这里不再细说,全部一次性给出,由于我们之后的每一篇博文都有这个操作,因此,这块的代码可以封装为一个函数重复调用,之后的博文也将不再列出。

 const canvas = document.getElementById("canvas");const gl = canvas.getContext("webgl");//创建着色器对象let vertexShader = gl.createShader(gl.VERTEX_SHADER);let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);//获取着色器对象的源let vertexSource = document.getElementById("vertex-shader").innerText;let fragmentSource = document.getElementById("fragment-shader").innerText;//绑定着色器的源gl.shaderSource(vertexShader,vertexSource);gl.shaderSource(fragmentShader,fragmentSource);//编译着色器gl.compileShader(vertexShader);gl.compileShader(fragmentShader);console.log(gl.getShaderInfoLog(vertexShader));//创建并关联项目let program = gl.createProgram();gl.attachShader(program,vertexShader);gl.attachShader(program,fragmentShader);gl.linkProgram(program);gl.useProgram(program);

5 开始缓冲区的逻辑

5.1 声明顶点坐标

const vertices = new Float32Array([-0.5,0.0,0.0,1.0,0.5,0.0,
]);

5.2 创建并绑定缓冲区

gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);

5.3 获取顶点着色器中的变量

let aPos = gl.getAttribLocation(program,"aPos");

5.4 使变量从缓冲区取值

//指定aPos如何读取缓冲区  两个值表示一个坐标,float类型,不使用归一化,2个值所占的字节长度,从偏移0倍字节开始读取
gl.vertexAttribPointer(aPos,2,gl.FLOAT,false,2*Float32Array.BYTES_PER_ELEMENT,0);
//允许aPos变量从缓冲区取值
gl.enableVertexAttribArray(aPos);

什么是归一化?
  举个例子,假设我们的数据范围是从0-10,变为0-1的过程,就叫归一化。那怎么变为0-1呢?很简单,将每个值都除以10就可以了。这里我们不使用归一化,意味着不允许WebGL修改我们的数据。

5.5 绘制

//绘制三角形,从零好索引开始,绘制三个点
gl.drawArrays(gl.TRIANGLES,0,3);

大功告成,看一下效果:
在这里插入图片描述

5.6 完整代码

//声明顶点坐标
const vertices = new Float32Array([-0.5,0.0,0.0,1.0,0.5,0.0,
]);
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);
let aPos = gl.getAttribLocation(program,"aPos");let length = Float32Array.BYTES_PER_ELEMENT;//数组中单个元素的字节长度
//指定aPos如何读取缓冲区  两个值表示一个坐标,float类型,不使用归一化,2个值所占的字节长度,从偏移0倍字节开始读取
gl.vertexAttribPointer(aPos,2,gl.FLOAT,false,2*length,0);
gl.enableVertexAttribArray(aPos);
//绘制三角形,从零号索引开始,绘制三个点
gl.drawArrays(gl.TRIANGLES,0,3);

6 总结

  本篇中,我们首先回忆了Shader的初始化过程,然后介绍了如何使用缓冲区进行三角形的绘制,并详细介绍了如何从缓冲区进行取值,及各个参数的含义,下一篇我们讲如何将三角形变为彩色的,回见~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/423101.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webpack - 五大核心概念和基本配置(打包一个简单HTML页面)

// 五大核心概念 1. entry&#xff08;入口&#xff09; 指示Webpack从哪个文件开始打包2. output&#xff08;输出&#xff09; 指示Webpack打包完的文件输出到哪里去&#xff0c;如何命名等3. loader&#xff08;加载器&#xff09; webpack本身只能处理js&#xff0c;json等…

51单片机快速入门之定时器和计数器

51单片机快速入门之定时器 断开外部输入 晶振振荡 假设为 12MHz 12分频之后,为1MHz 当其从0-65536 时,需要65536μs 微秒 也就是65.536ms 毫秒 溢出(值>65536 时)>中断>执行中断操作 假设需要1ms后产生溢出,则需要设置初始值为64536 此时定时器会从 64536 开始计…

xss-labs-master通关教程

一.level1 先来进行一下代码审计 <?php ini_set("display_errors", 0);//关闭错误显示 $str $_GET["name"]; //接受URL来的get形式的name传参 echo "<h2 aligncenter>欢迎用户".$str."</h2>";//在网页输出&#x…

引领AI PC浪潮,Arm人工智能创新应用大赛火热报名中

AI PC&#xff0c;即搭载人工智能技术的个人电脑&#xff0c;正成为个人电脑市场的新宠儿。而正在如火如荼进行中的 Arm人工智能创新应用大赛&#xff0c;则为敏锐的开发者探索 AI PC 应用开发掘金之路提供了平台。 点击报名 挑战10万奖金池 AI PC 增长强劲&#xff0c;年出货…

【Hadoop|HDFS篇】HDFS的读写流程

1. HDFS的写流程 1.1 剖析文件的写入 副本存储节点的选择问题&#xff1a; 第一个副本在Client所在的节点上&#xff0c;如果客户端在集群外&#xff0c;随机选一个。第二个副本在另一个机架的随机一个节点上。第三个副本在第二个副本所在的机架的随机节点上。 2. HDFS的写流…

2024CCPC网络预选赛

vp链接&#xff1a;Dashboard - The 2024 CCPC Online Contest - Codeforces B. 军训 II 序列 a 从小到大排列或者从大到小排列时&#xff0c;不整齐度是最小的。方案数是所有相同数字的个数的排列数的乘积。如果首尾的数字不同的话&#xff0c;还要再乘个 2。 #include <…

Social Network Influence Maximization Based on Graph Attention Mechanisms

摘要 社交网络中的关键节点对整个网络具有重要的影响力&#xff0c;而社交网络中的一些节点可能位于网络的中心&#xff0c;而另一些节点则可能位于网络的边缘&#xff0c;传统的影响力最大化算法忽略了这种不平衡。通过忽略位于网络边缘但连接到中心的节点来导致信息的传播。为…

Java项目: 基于SpringBoot+mybatis+maven医院管理系统(含源码+数据库+任务书+开题报告+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven医院管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

【LeetCode】每日一题 2024_9_13 预算内的最多机器人数目(滑动窗口、单调队列)

LeetCode 启动&#xff01; 每日一题的题解重新开始连载&#xff01; 题目&#xff1a;预算内的最多机器人数目 题目链接&#xff1a;2398. 预算内的最多机器人数目 题目描述 代码与解题思路 func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (an…

期权组合策略有什么风险?期权组合策略是什么?

今天期权懂带你了解期权组合策略有什么风险&#xff1f;期权组合策略是什么&#xff1f;期权组合策略是通过结合不同期权合约&#xff08;如看涨期权和看跌期权&#xff09;&#xff0c;以及标的资产&#xff08;如股票&#xff09;来实现特定投资目标的策略。 期权组合策略市…

改进大语言模型的最全方法!

这是一篇关于适应开源大语言模型&#xff08;LLMs&#xff09;的三部系列博客的第一篇。本文探讨将LLM适应领域数据的各种方法。 第二部分讨论如何确定微调&#xff08;fine-tuning&#xff09;是否适合您的用例。第三部分探讨策划良好训练数据集的一些经验法则。 0 引言 大…

【IP协议】IP协议报头结构(上)

IP 协议报头结构 4位版本 实际上只有两个取值 4 > IPv4&#xff08;主流&#xff09;6 > IPv6 IPv2&#xff0c;IPv5 在实际中是没有的&#xff0c;可能是理论上/实验室中存在 4位首部长度 IP 协议报头也是变长的&#xff0c;因为选项个数不确定&#xff0c;所以报头长…

突破瓶颈:Java并发编程的最佳实践与技巧,你了解了吗?

文章目录 1 什么是 Executor 和 ExecutorService &#xff1f;这两个接口有什么区别&#xff1f;2 java.util.concurrent 标准库中 ExecutorService 的可用实现是什么 &#xff1f;3 什么是 Java 内存模型&#xff08; JMM &#xff09;&#xff1f;描述下其目的和基本思想4 JM…

Spring扩展点系列-ApplicationContextAwareProcessor

文章目录 简介源码分析示例代码示例一&#xff1a;扩展点的执行顺序运行示例一 示例二&#xff1a;获取配置文件值配置文件application.properties内容定义工具类ConfigUtilcontroller测试调用运行示例二 示例三&#xff1a;实现ResourceLoaderAware读取文件ExtendResourceLoad…

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染&#xff1a;一项综述 文章目录 大规模语言模型的基准数据污染&#xff1a;一项综述摘要1 引言 摘要 大规模语言模型&#xff08;LLMs&…

css——网格布局

名词解释 div{$}*9tab键&#xff0c;快捷生成 记首字母gtc 网格布局&#xff1a;display: grid; grid-template-columns: 100px 100px 100px; grid-template-rows: 100px 100px 100px; &#xff08;父元素&#xff09; <!DOCTYPE html> <html lang&q…

如何构建适合企业需求的即时通讯与音视频通话私有化平台?

在数字化转型的浪潮中&#xff0c;企业对于内部沟通的需求日益复杂化和多元化。传统的沟通方式已难以满足高效协作、信息安全及个性化定制的需求。因此&#xff0c;“即时通讯音视频通话”集成的私有化部署软件应运而生&#xff0c;成为企业优化内部沟通、提升工作效率的得力助…

PN IO设备ET 200SP支持R1模式

IA博途V18除了支持性能大幅提升的V3.0版本S7-1500 CPU&#xff08;不包含S7-1517/18 CPU&#xff09;外&#xff0c;还支持我们一直期待的R1模式的PROFINET IO设备ET200SP&#xff01;这样使S7-1500H 冗余系统的PN IO设备配置更加灵活。 1. PN 设备接口模式 以前的S7-1500R/…

【重学 MySQL】二十七、七种 join 连接

【重学 MySQL】二十七、七种 join 连接 union 的使用UNION 的基本用法示例UNION ALL 的用法 七种 join 连接代码实现语法格式小结 union 的使用 UNION 在 SQL 中用于合并两个或多个 SELECT 语句的结果集&#xff0c;并默认去除重复的行。如果希望包含重复行&#xff0c;可以使…

jmeter之setUP、tearDown线程组

setUp线程组&#xff1a; 用于在执行常规线程组之前执行一些必要的操作 ------会在普通线程组执行前被触发 应用场景举例&#xff1a; A、测试数据库操作功能时&#xff0c;用于执行打开数据库连接操作 B、测试用户购物功能时&#xff0c;用于执行用户的注册、登录等操作 tea…