WebGL编程指南 - 入门续

相关内容:在attribute变量传递参数的基础上,通过JavaScript获取鼠标事件的坐标,再经过坐标转换传递给attribute变量;Web颜色缓冲区每次绘制之后都会重置
相关函数:JavaScript鼠标事件onmousedown/onmouseup/onclick

html代码还是老一套

js代码:

// ClickedPoints.js
// 顶点着色器
var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  ' gl_Position = a_Position;\n' +
  ' gl_PointSize = 10.0;\n' +
  '}\n'
// 片元着色器
var FSHADER_SOURCE =
  'void main() {\n' +
  ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + // 设置颜色
  '}\n'
// 主函数
function main() {
  // 获取<canvas>元素
  let canvas = document.getElementById('webgl')
  // 获取WebGL绘图上下文
  let gl = getWebGLContext(canvas)
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL')
    return
  }
  // 初始化着色器
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to initialize shaders')
    return
  }
  // 获取a_Position变量的存储位置
  let a_Position = gl.getAttribLocation(gl.program, 'a_Position')
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position')
  }
  // 注册鼠标点击事件响应函数
  canvas.onmousedown = function (ev) {
    // console.log(ev)
    click(ev, gl, canvas, a_Position)
  }
  // 设置背景色
  gl.clearColor(0.0, 0.0, 0.0, 1.0)
  // 清空绘图区域
  gl.clear(gl.COLOR_BUFFER_BIT)
}
var g_points = [] // 鼠标点击位置数组
function click(ev, gl, canvas, a_Position) {
  let x = ev.clientX // 鼠标点击处的x坐标
  let y = ev.clientY // 鼠标点击处的y坐标
  let rect = ev.target.getBoundingClientRect() //cnavas边界坐标
  // 坐标转换
  x = (x - rect.left - canvas.width / 2) / (canvas.width / 2)
  y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2)
  // 将坐标存储到g_points数组中
  g_points.push(x)
  g_points.push(y)

  // 清空绘图区
  gl.clear(gl.COLOR_BUFFER_BIT)
  // 绘制数组中的点
  let len = g_points.length
  for (let i = 0; i < len; i += 2) {
    // 将点的位置传递到变量中a_Position
    gl.vertexAttrib3f(a_Position, g_points[i], g_points[i + 1], 0.0)
    // 绘制点
    gl.drawArrays(gl.POINTS, 0, 1)
  }
}

此处将x和y坐标通过JavaScript自带的鼠标点击事件来获取,通过坐标转换传递到着色器中。

注册事件响应函数:

// 注册鼠标点击事件响应函数
  canvas.onmousedown = function (ev) {
    // console.log(ev)
    click(ev, gl, canvas, a_Position)
  }

此处用ev作为函数的形参接收,ev中挂载了许多关于这一事件的属性,包括触发对象(target)、坐标等,不同事件传递的事件对象不同

改变点的颜色与uniform变量(动态设置片元着色器)

相关内容:JavaScript设置点的颜色;JavaScript传递点的颜色给片元着色器(通过uniform变量)
相关函数:gl.getUniformLocation(), gl.uniform4f()

  • 在片元着色器中准备 uniform 变量
  • 用这个 uniform 变量向 gl_FragColor 赋值
  • 将颜色数据从 JavaScript 传给 uniform 变量

根据位置不同显示不同地颜色

// ClickedPoints.js
// 顶点着色器
var VSHADER_SOURCE =
  'attribute vec4 a_Position;\n' +
  'void main() {\n' +
  ' gl_Position = a_Position;\n' +
  ' gl_PointSize = 10.0;\n' +
  '}\n'
// 片元着色器
var FSHADER_SOURCE =
  'precision mediump float;\n' +
  'uniform vec4 u_FragColor;\n' +
  'void main() {\n' +
  ' gl_FragColor = u_FragColor;\n' + // 设置颜色
  '}\n'
// 主函数
function main() {
  // 获取<canvas>元素
  let canvas = document.getElementById('webgl')
  // 获取WebGL绘图上下文
  let gl = getWebGLContext(canvas)
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL')
    return
  }
  // 初始化着色器
  if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
    console.log('Failed to initialize shaders')
    return
  }
  // 获取a_Position变量的存储位置
  let a_Position = gl.getAttribLocation(gl.program, 'a_Position')
  if (a_Position < 0) {
    console.log('Failed to get the storage location of a_Position')
  }
  //获取u_FragColor 变量的存储位置
  let u_FragColor = gl.getUniformLocation(gl.program,'u_FragColor');
  if(u_FragColor < 0) {
    console.log('Failed to get the storage location of u_FragColor');
  }
  // 注册鼠标点击事件响应函数
  canvas.onmousedown = function (ev) {
    // console.log(ev)
    click(ev, gl, canvas, a_Position,u_FragColor);
  }
  // 设置背景色
  gl.clearColor(0.0, 0.0, 0.0, 1.0)
  // 清空绘图区域
  gl.clear(gl.COLOR_BUFFER_BIT)
}
var g_points = [] // 鼠标点击位置数组
var g_colors = [];// 存储点颜色的数组
function click(ev, gl, canvas, a_Position,u_FragColor) {
  let x = ev.clientX // 鼠标点击处的x坐标
  let y = ev.clientY // 鼠标点击处的y坐标
  let rect = ev.target.getBoundingClientRect() //cnavas边界坐标
  // 坐标转换
  x = (x - rect.left - canvas.width / 2) / (canvas.width / 2)
  y = (canvas.height / 2 - (y - rect.top)) / (canvas.height / 2)
  // 将坐标存储到g_points数组中
  g_points.push(x)
  g_points.push(y)

// 将点的颜色存储到g_colors中
if (x >= 0.0 && y >= 0.0) {
    // 第一象限
    g_colors.push([1.0, 0.0, 0.0, 1.0]) // 红色
  } else if (x < 0.0 && y < 0.0) {
    // 第三象限
    g_colors.push([0.0, 0.0, 1.0, 1.0]) // 绿色
  } else {
    // 其他
    g_colors.push([1.0, 1.0, 1.0, 1.0]) // 白色
  }

  // 清空绘图区
  gl.clear(gl.COLOR_BUFFER_BIT)
  // 绘制数组中的点
  let len = g_points.length
  for (let i = 0; i < len; i += 2) {
    let rgba = g_colors[i/2];
    // 将点的位置传递到变量中a_Position
    gl.vertexAttrib3f(a_Position, g_points[i], g_points[i + 1], 0.0);
    gl.uniform4fv(u_FragColor,rgba);
    // 绘制点
    gl.drawArrays(gl.POINTS, 0, 1)
  }
}

uniform 变量

// 片元着色器
var FSHADER_SOURCE =
  'precision mediump float;\n' +
  'uniform vec4 u_FragColor;\n' + // uniform变量
  'void main() {\n' +
  ' gl_FragColor = u_FragColor;\n' +
  '}\n'
  • uniform变量的声明遵循与attribute变量相同的格式<存储限定符><类型><变量名>

获取uniform变量的存储地址

  // 获取u_FragColor变量的存储位置
  let u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
  if (!u_FragColor) {
    console.log('Failed to get the storage location of u_FragColor')
  }

指定变量不存在时,返回的是null而不是-1。所以在检查的时候,需要用’!‘(取反)操作符而不是’<0’

向 uniform 变量赋值

参考:【《WebGL编程指南》读书笔记】_webgl 编程指南笔记-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

0基础学java之Day09(下午完整版)

六、数组 概念&#xff1a; 1.数组是引用数据类型 2.数组中的数据叫做元素 3.元素都有标号叫做索引/下标 4.下标从0开始 5.数组一旦初始化成功&#xff0c;长度不可变&#xff08;意味着数组没有添加和删除&#xff09; 6.数组中的元素在内存中是挨在一起的 声明&#xff1a; 数…

数据结构与算法 - 树 #数的概念 #二叉树 #堆 - 堆的实现/堆排序/TOP-K问题

文章目录 前言 一、树 (一)、概念 1、树的定义 (二)、树的定义 1、树为什么是递归定义的&#xff1f; 2、如何定义树(如何表达一棵树) 解决方案一&#xff1a;假设我们得知该树的度 解决方案二&#xff1a;顺序表 解决方案三&#xff1a;左孩子右兄弟表示法 二、二叉…

人工智能是否会取代人类的工作吗? 就业方向该如何抉择

人工智能是否会取代人类的工作一直是备受关注的话题。目前来看&#xff0c;人工智能在某些方面确实展现出了强大的能力&#xff0c;但要说完全取代人类还不太可能。 一、人工智能的优势 高效处理大量数据 人工智能可以快速处理和分析海量数据&#xff0c;例如在金融领域进行风…

linux------缓冲区与C库的原理

前言 一、缓冲区 缓冲区的作用是提高效率&#xff0c;因为将数据写入到设备&#xff0c;是需要调用系统接口的&#xff0c;如果每次写入缓冲区的数据就调用一次系统调用&#xff0c;涉及到系统调用这时操作系统就会介入&#xff0c;用户态转为内核态&#xff0c;这个过程需要时…

解决PyCharm 2023 Python Packages列表为空

原因是因为没有设置镜像源 展开 > 之后&#xff0c;这里 点击齿轮 添加一个阿里云的源 最后还需要点击刷新 可以选择下面的任意一个国内镜像源&#xff1a; 清华&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 阿里云&#xff1a;http://mirrors.aliyun.com/…

Vue3 集成Monaco Editor编辑器

Vue3 集成Monaco Editor编辑器 1. 安装依赖2. 使用3. 效果 Monaco Editor &#xff08;官方链接 https://microsoft.github.io/monaco-editor/&#xff09;是一个由微软开发的功能强大的在线代码编辑器&#xff0c;被广泛应用于各种 Web 开发场景中。以下是对 Monaco Editor 的…

微深节能 料场堆取料无人操作系统 格雷母线

微深节能的料场堆取料无人操作系统采用了格雷母线定位系统&#xff0c;这是一种高精度位移检测技术&#xff0c;用于提升料场作业的自动化水平和精确性。该系统通过精准定位和自动化控制&#xff0c;大幅减少了人工操作中的误差和延误&#xff0c;提高了作业效率和精确性。格雷…

Jenkins入门(二):流水线方式部署多模块Springboot项目

目录 一、环境准备 1. 搭建配置Jenkins (在上一篇基础上进行) 2. 安装mysql 3. 安装redis 4. 配置docker-componse 5. 启动docker-componse 二、脚本准备 1. Jenkinsfile 2. deploy.sh 3. Dockerfile 三、Jenkins流水线配置 新增版本号参数 流水线选择代码里面的Je…

Python酷库之旅-第三方库Pandas(158)

目录 一、用法精讲 721、pandas.Timedelta.round方法 721-1、语法 721-2、参数 721-3、功能 721-4、返回值 721-5、说明 721-6、用法 721-6-1、数据准备 721-6-2、代码示例 721-6-3、结果输出 722、pandas.Timedelta.to_pytimedelta方法 722-1、语法 722-2、参数…

农作物苹果叶片病虫害识别数据集

农作物苹果叶片病虫害识别数据集 一、引言 农作物病虫害是影响农业生产的重要因素之一&#xff0c;其中苹果作为广泛种植的水果品种&#xff0c;其叶片病虫害问题尤为突出。为了有效应对苹果叶片病虫害&#xff0c;提高苹果产量和品质&#xff0c;农业科研机构和学者不断开展…

服务端负载均衡和客户端负载

负载均衡分为服务端负载均衡和客户端负载均衡&#xff0c;图解&#xff1a; 客户端的负载均衡还需要从注册中心获取集群部署的服务地址&#xff0c;其中客户的负载均衡器定时读取注册中心的IP和端口&#xff0c;然后缓存起来&#xff0c;这样以后可以先判断缓存IP和端口是否可用…

Java基于SSM微信小程序物流仓库管理系统设计与实现(源码+lw+数据库+讲解等)

选题背景 随着社会的发展&#xff0c;社会的方方面面都在利用信息化时代的优势。互联网的优势和普及使得各种系统的开发成为必需。 本文以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;它主要是采用java语言技术和mysql数据库来完成对系统的设计。整个…

#数据结构(二)

栈和队列 一.栈的顺序存储结构 特点&#xff1a;先进后出 栈是一种只能在一端进行插入或删除操作的线性表。 表中允许插入删除操作的一端为栈顶&#xff08;top&#xff09;&#xff0c;表的另一端为栈底&#xff08;bottom&#xff09;&#xff0c; 1 结构体的定义 #incl…

10月18日

二次型矩阵要是对称矩阵 通解要带入特解 集体化 逆反思维 先定特解&#xff0c;再求通解 反函数...我谢谢你 依旧是原函数

Vision China 2024 | 移远通信以一体化的AI训练及部署能力,引领3C电子制造智能升级

10月14日&#xff0c;由机器视觉产业联盟(CMVU)主办的中国机器视觉展(Vision China)在深圳国际会展中心盛大开幕。作为全球领先的物联网整体解决方案供应商&#xff0c;移远通信应邀参加展会首日举办的“智造引领数质并进”3C电子制造自动化与数字化论坛。 论坛上&#xff0c;移…

立仪科技:光谱共焦传感器精准测量玻璃

光谱共焦测量技术作为一种创新的光学检测方法&#xff0c;近年来在工业领域引起了广泛关注。 它以其高精度、非接触式的特点&#xff0c;特别适用于透明或半透明材料如玻璃的厚度和表面形貌测量。 接下来&#xff0c;立仪科技小编将深入探讨光谱共焦技术在玻璃测量上的应用及其…

火山引擎数智平台 VeDI:A/B 实验互斥域流量分配体系上线

近日&#xff0c;火山引擎 A/B 测试平台(DataTester)完成了一次重要升级&#xff0c;推出互斥域流量分配体系&#xff0c;这一功能意味着企业在产品优化策略上有新的突破空间。此次升级的核心亮点是允许企业根据实际需求&#xff0c;灵活地将用户流量分割成多个独立的区块&…

探索 Jupyter 笔记本转换的无限可能:nbconvert 库的神秘面纱

文章目录 探索 Jupyter 笔记本转换的无限可能&#xff1a;nbconvert 库的神秘面纱背景&#xff1a;为何选择 nbconvert&#xff1f;库简介&#xff1a;nbconvert 是什么&#xff1f;安装指南&#xff1a;如何安装 nbconvert&#xff1f;函数用法&#xff1a;简单函数示例应用场…

简单概述Ton链开发路径

区块链开发领域发展迅速&#xff0c;各种平台为开发人员提供不同的生态系统。其中一个更有趣且越来越相关的区块链是TON&#xff08;开放网络&#xff09;区块链。TON 区块链最初由 Telegram 构思&#xff0c;旨在提供快速、安全且可扩展的去中心化应用程序 (dApp)。凭借其独特…

LangGraph - Hierarchical Agent Teams

本文翻译整理自 Hierarchical Agent Teams https://langchain-ai.github.io/langgraph/tutorials/multi_agent/hierarchical_agent_teams/ 文章目录 一、前言二、设置三、创建工具四、Helper Utilities五、定义代理 Team研究 Team文档写作Team 六、添加图层 一、前言 在前面的…