【WebGL系列-01】获取WebGL上下文

这篇具有很好参考价值的文章主要介绍了【WebGL系列-01】获取WebGL上下文。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

获取WebGL上下文

获取上下文

WebGL上下文是从<canvas>标签中获取到的,通过canvas对象的getContext()函数可以获取WebGLRenderingContext

跟据参数的不同,getContext()函数可以获取不同种类的渲染上下文。

接口

canvas.getContext(contextType: String, contextAttributes ?: Object)

  • contextType:

    • '2d':建立一个CanvasRenderingContext2D二维渲染上下文
    • 'webgl''experimental-webgl':创建一个WebGLRenderingContext三维上下文对象,只在实现WebGL1的浏览器上可用
    • 'webgl2''experimental-webgl2':创建一个WebGL2RenderingContext三维渲染上下文对象,只在实现WebGL2的浏览器上可用
    • 'bitmaprenderer':创建一个只提供将canvas内容替换为指定ImageBitmap功能的ImageBitmapRenderingContext
  • contextAttributes:

    • contextType2d时:

      • alpha:boolean,表明canvas包含一个alpha通道。如果设置为false,浏览器默认canvas背景总是不透明的,可加速绘制透明物体
      • willReadFrequently (Gecko only):boolean,表示是否有重复读取计划。经常使用getImageData()会导致软件使用2D canvas并节省内存,适用于存在属性gfx.canvas.willReadFrequently的环境
      • storage (Blink only):string,表示使用哪种方式存储,默认为"presistent"持久性存储
    • 当使用webgl上下文时:

      • alpha:boolean,表明canvas包含一个alpha缓冲区
      • antialias:boolean,表明是否开启抗锯齿
      • depth:boolean,表明绘制缓冲区包含一个深度至少为16位的缓冲区
      • failIfMajorPerformanceCaveat:表明在一个系统性能低的环境是否创建该上下文的boolean值
      • powerPreference:指示浏览器在运行webgl上下文时使用相应的GPU电源配置,可能的值有
        • "default":默认,自动选择
        • "high-performance":高性能模式
        • "low-power":节能模式
      • premultipliedAlpha:boolean,表明排版引擎将假设绘制缓冲区包含预混合alpha通道
      • preserveDrawingBuffer:boolean,如果为true,缓冲区将不会被清除,会保存袭来,直到被清除或被覆盖
      • stencil:boolean,表明绘制缓冲区包含一个深度至少为8为的模板缓冲区

当要获取一个上下文对象的contextAttributes时,可以使用接口context.getContextAttributes()来获取

返回值

  • CanvasRenderingContext2D:当ContextType"2d"
  • WebGLRenderingContext:当ContextType"webgl""experimental-webgl"
  • WebGL2RenderingContext:当ContextType"webgl2""experimental-webgl2"
  • ImageBitmapRenderingContext:当ContextType"bitmaprenderer"

获取上下文事件

canvas获取上下文会触发以下事件:

  • contextlost (experimental):当获取的CanvasRenderingContext2D上下文丢失时会触发
  • contextrestored (experimental):在用户代理恢复CanvasRenderingContext2D时会触发
  • webglcontextcreatingerror:在用户无法创建WebGLRenderingContext上下文时触发
  • webglcontextlost:在用户代理检测到绘制缓冲关联的WebGLRenderingContext上下文丢失时会触发
    - webglcontextrestored:在用户代理恢复WebGLRenderingContext对象的绘制缓冲时会触发

WebGL获取上下文函数的封装

基于以上接口及属性,我们可以封装一个如下的接口(此接口仿照Threejs的初始化方法):文章来源地址https://www.toymoban.com/news/detail-599488.html

function defaultValue(value, default) {
  return value !== undefined ? value : default;
}

function createCanvasElement() {
  const canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
  canvas.display = "block";
  return canvas;
}

function onContextLost(event) {
  event.preventDefault();
  console.log("WebGL context lost.");
  // TODO 上下文丢失后的处理
}

function onContextRestore(event) {
  console.log("WebGL context restored.");
  // 用户代理上下文对象恢复后,触发的事件
  // 例如,重新创建创建属性对象、材质、纹理、几何、渲染列表等
}

function getContext(parameters) {
  const _canvas     = defaultValue(parameters.canvas, createCanvasElement()),
        _context    = defaultValue(parameters.context, null),
        _depth      = defaultValue(parameters.depth, true),
        _stencil    = defaultValue(parameters.stencil, true),
        _antialias  = defaultValue(parameters.antialias, false),
        _premultipliedAlpha = defaultValue(parameters.premultipliedAlpha, true),
        _preserveDrawingBuffer = defaultValue(parameters.preserveDrawingBuffer, false),
        _failIfMajorPerformanceCaveat = defaultValue(parameters.failIfMajorPerformanceCaveat, false),
        _powerPreference = defaultValue(parameters.powerPreference, 'default');
  
  let _alpha;
  if (parameters.context) {
    _alpha = _context.getContextAttributes().alpha;
  } else {
    _alpha = parameters.alpha !== undefined ? parameters.alpha : false;
  }

  let _gl = _context;
  // 准备上下文参数
  const contextAttributes = {
    alpha: _alpha,
    depth: _depth,
    stencil: _stencil,
    antialias: _antialias,
    premultipliedAlpha: _premultipliedAlpha,
    preserveDrawingBuffer: _preserveDrawingBuffer,
    failIfMajorPerformanceCaveat: _failIfMajorPerformanceCaveat,
    powerPreference: _powerPreference
  };
  // 绑定事件,由于我们手动控制上下文的创建过程,此处不绑定webglcontextcreatingerror事件,而是在出现错误时手动处理
  _canvas.addEventListener('webglcontextlost', onContextLost, false);
  _canvas.addEventListener('webglcontextrestore', onContextRestore, false);
  // _canvas.addEventlistener('webglcontextcreatingerror', null, false);

  function getWebGLContext(contextNames, contextAttributes) {
    for (let i = 0; i < contextnames.length; ++i) {
      const contextName = contextNames[ i ];
      const context = _canvas.getContext( contextName, contextAttributes );
      if ( context !== null ) return context;
    }
    return null;
  }

  // 如果当前没有上下文环境,则从下面的参数中查找
  if (_gl === null) {
    const contextNames = [ 'webgl2', 'webgl', 'experimental-webgl2', 'experimental-webgl' ];
    _gl = getWebGLContext(contextNames, contextAttributes);
    // 此处再进行一次判断,如果contextAttributes参数中有参数有问题,会造成上下文创建失败
    // 如果不加参数创建上下文依然失败,那说明无法创建上下文
    if (_gl === null) {
      _gl = getWebGLContext(contextNames);
      if (_gl) {
        // 不带参数创建上下文成功,说明参数有问题
        throw new Error("Error creating WebGL context with your selected attributes.");
      } else {
        // 不带参数也无法创建上下文,说明无法创建上下文
        throw new Error("Error creating WebGL context");
      }
    }
  }

  return { canvas: _canvas, context: _gl };
}

到了这里,关于【WebGL系列-01】获取WebGL上下文的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 安信可开发环境构建-基于Ai-WB2系列 和 Ai-M61 或 Ai-M62 (环境上下文切换)

    首先,对于Ai-WB2系列环境的构建官方文档已经讲的非常明白了,这里不做阐述 如下链接所示https://blog.csdn.net/Boantong_/article/details/128480919  本人亲自测试可行 ,请严格follow官方的steps。 另外需要注意的是,为了避免错误,尽量不要自己从GIT或者Gitee拉取项目。使用上述链接内,

    2024年02月08日
    浏览(29)
  • 超长上下文处理:基于Transformer上下文处理常见方法梳理

    原文链接:芝士AI吃鱼 目前已经采用多种方法来增加Transformer的上下文长度,主要侧重于缓解注意力计算的二次复杂度。 例如,Transformer-XL通过缓存先前的上下文,并允许随着层数的增加线性扩展上下文。Longformer采用了一种注意力机制,使得token稀疏地关注远距离的token,从而

    2024年02月13日
    浏览(40)
  • 无限上下文,多级内存管理!突破ChatGPT等大语言模型上下文限制

    目前,ChatGPT、Llama 2、文心一言等主流大语言模型,因技术架构的问题上下文输入一直受到限制,即便是Claude 最多只支持10万token输入,这对于解读上百页报告、书籍、论文来说非常不方便。 为了解决这一难题,加州伯克利分校受操作系统的内存管理机制启发,提出了MemGPT。

    2024年02月06日
    浏览(47)
  • 从零开始理解Linux中断架构(7)--- Linux执行上下文之中断上下文

            当前运行的loop是一条执行流,中断程序运行开启了另外一条执行流,从上一节得知这是三种跳转的第三类,这个是一个大跳转。对中断程序的基本要求就是 中断执行完毕后要恢复到原来执行的程序 ,除了时间流逝外,原来运行的程序应该毫无感知。        

    2024年02月11日
    浏览(51)
  • 〖大前端 - 基础入门三大核心之JS篇(51)〗- 面向对象之认识上下文与上下文规则

    说明:该文属于 大前端全栈架构白宝书专栏, 目前阶段免费 , 如需要项目实战或者是体系化资源,文末名片加V! 作者:哈哥撩编程,十余年工作经验, 从事过全栈研发、产品经理等工作,目前在公司担任研发部门CTO。 荣誉: 2022年度博客之星Top4、2023年度超级个体得主、谷

    2024年02月05日
    浏览(44)
  • 执行上下文

    通过var定义(声明)的变量--在定义语句之前就可以访问到 值为undefined 通过function声明的函数--在之前就可以直接调用 值为函数定义(对象) 全局代码 函数(局部)代码 在执行全局代码前将window确定为全局执行上下文 对全局数据进行预处理 var定义的全局变量--undefined--添加

    2023年04月20日
    浏览(36)
  • CPU上下文切换

    CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。 CPU 的上下文切换就可以分为几个不同的场景,也就是进程上下文切换、

    2024年02月14日
    浏览(28)
  • 【Spring | 应用上下文】

      本节介绍如何使用资源创建应用程序上下文,包括使用 XML 的快捷方式、如何使用通配符以及其他详细信息。   应用上下文构造函数(针对特定的应用上下文类型)通常将字符串或字符串数组作为资源的位置路径,例如构成上下文定义的 XML 文件。 示例如下    Clas

    2024年02月16日
    浏览(33)
  • js执行上下文

    创造执行上下文,是为了把变量声明给保存下来,在执行时,好找到变量用 看代码要分执行前(构建执行上下文)和执行时去看 执行上下文的组成 1、词法环境:[全局对象]、scope、outer 2、This Binding:提供this的访问 构建执行上下文 1、处理声明 2、检查重复定义 3、初步赋值

    2024年02月02日
    浏览(32)
  • 上下文切换性能篇

    现代操作系统都是多任务的分时操作系统,也就是说同时响应多个用户交互或同时支持多个任务处理,因为 CPU 的速度很快而用户交互的频率相比会低得多。所以例如在 Linux 中,可以支持远大于 CPU 数量的任务同时执行,对于单个 CPU 来说,其实任务并不是在同时执行,而是操

    2024年02月15日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包