Cesium渲染模块之Buffer
1. 引言
Cesium是一款三维地球和地图可视化开源JavaScript库,使用WebGL来进行硬件加速图形,使用时不需要任何插件支持,基于Apache2.0许可的开源程序,可以免费用于商业和非商业用途
Cesium官网:Cesium: The Platform for 3D Geospatial
Cesium GitHub站点:CesiumGS/cesium: An open-source JavaScript library for world-class 3D globes and maps (github.com)
API文档:Index - Cesium Documentation
通过阅读源码,理清代码逻辑,有助于扩展与开发,笔者主要参考了以下两个系列的文章
渲染是前端可视化的核心,本文描述Cesium渲染模块的Buffer
2. WebGL中的Buffer
以下大致是一个最简的WebGL绘制代码:
<canvas id="canvas"></canvas>
<script>
const vertexSource = `
attribute vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
`
const fragmentSource = `
void main()
{
gl_FragColor = vec4(1.0, 0.5, 0.2, 1.0);
}
`
const canvas = document.getElementById('canvas');
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
const gl = canvas.getContext('webgl2');
if (!gl) {
alert('WebGL not supported');
}
const vertices = new Float32Array([
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0,
]);
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(0)
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentSource);
gl.compileShader(fragmentShader);
const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);
gl.clearColor(0.2, 0.3, 0.3, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(shaderProgram);
gl.drawArrays(gl.TRIANGLES, 0, 3);
</script>

其中,vbo是顶点缓冲对象(Vertex Buffer Objects, VBO),主要用来储存顶点数据:
const vertices = new Float32Array([
-0.5, -0.5, 0.0,
0.5, -0.5, 0.0,
0.0, 0.5, 0.0,
]);
const vbo = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
WebGLBuffer 接口属于 WebGL API 的一部分,表示一个不透明的缓冲区对象,储存诸如顶点或着色之类的数据
WebGLBuffer 对象没有定义任何自己的方法或属性,且内容不能被直接访问。当使用 WebGLBuffer 对象时, WebGLRenderingContext 下的这些方法会很有用:
WebGLRenderingContext.bindBuffer()WebGLRenderingContext.createBuffer()WebGLRenderingContext.deleteBuffer()WebGLRenderingContext.isBuffer()- 更详细的内容可以参考:WebGLBuffer - Web API 接口参考 | MDN (mozilla.org)
示例代码中:
createBuffer() 方法可创建并初始化一个用于储存顶点数据或着色数据的WebGLBuffer对象
bindBuffer(target, buffer) 方法将给定的WebGLBuffer绑定到目标,参数:
target
GLenum(en-US) 指定绑定点 (target)。可能的值:gl.ARRAY_BUFFER: 包含顶点属性的 Buffer,如顶点坐标,纹理坐标数据或顶点颜色数据。gl.ELEMENT_ARRAY_BUFFER: 用于元素索引的 Buffer
buffer
要绑定的
WebGLBuffer
bufferData(target, size, usage) 方法创建并初始化了 Buffer 对象的数据存储区,参数:
target
GLenum(en-US) 指定 Buffer 绑定点(目标)。可取以下值:gl.ARRAY_BUFFER: 包含顶点属性的 Buffer,如顶点坐标,纹理坐标数据或顶点颜色数据。gl.ELEMENT_ARRAY_BUFFER: 用于元素索引的 Buffer
size
GLsizeiptr(en-US) 设定 Buffer 对象的数据存储区大小
usage
GLenum(en-US) 指定数据存储区的使用方法。可取以下值:gl.STATIC_DRAW: 缓冲区的内容可能经常使用,而不会经常更改。内容被写入缓冲区,但不被读取。gl.DYNAMIC_DRAW: 缓冲区的内容可能经常被使用,并且经常更改。内容被写入缓冲区,但不被读取。gl.STREAM_DRAW: 缓冲区的内容可能不会经常使用。内容被写入缓冲区,但不被读取
以上大致就是WebGL中Buffer(VBO)的用法
3. Cesium中的Buffer
Cesium中,对WebGL的Buffer进行了封装:
function Buffer(options) {
const gl = options.context._gl;
gl.bindBuffer(bufferTarget, buffer);
gl.bufferData(bufferTarget, hasArray ? typedArray : sizeInBytes, usage);
gl.bindBuffer(bufferTarget, null);
}
Buffer.createVertexBuffer = function (options) {
return new Buffer({
context: options.context,
bufferTarget: WebGLConstants.ARRAY_BUFFER,
typedArray: options.typedArray,
sizeInBytes: options.sizeInBytes,
usage: options.usage,
});
};
Buffer.createIndexBuffer = function (options) {
const buffer = new Buffer({
// ...
});
return buffer;
};
Buffer类的构造函数只是一次简单的封装,Buffer.createVertexBuffer函数可以更为快速的构建Buffer,搜索源码就会发现大多也是使用Buffer.createVertexBuffer创建Buffer,比如GeoJsonLoader.js:
// ...
// Create GPU buffers
const positionBuffer = Buffer.createVertexBuffer({
typedArray: positionsTypedArray,
context: frameState.context,
usage: BufferUsage.STATIC_DRAW,
});
positionBuffer.vertexArrayDestroyable = false;
const featureIdBuffer = Buffer.createVertexBuffer({
typedArray: featureIdsTypedArray,
context: frameState.context,
usage: BufferUsage.STATIC_DRAW,
});
featureIdBuffer.vertexArrayDestroyable = false;
const indexBuffer = Buffer.createIndexBuffer({
typedArray: indicesTypedArray,
context: frameState.context,
usage: BufferUsage.STATIC_DRAW,
indexDatatype: indexDatatype,
});
indexBuffer.vertexArrayDestroyable = false;
// ...
使用Buffer.createVertexBuffer创建指定数据大小而数据未确定的VBO的例子:
// Example 1. Create a dynamic vertex buffer 16 bytes in size.
const buffer = Buffer.createVertexBuffer({
context : context,
sizeInBytes : 16,
usage : BufferUsage.DYNAMIC_DRAW
});
使用Buffer.createVertexBuffer创建数据确定的VBO的例子:
// Example 2. Create a dynamic vertex buffer from three floating-point values.
// The data copied to the vertex buffer is considered raw bytes until it is
// interpreted as vertices using a vertex array.
const positionBuffer = buffer.createVertexBuffer({
context : context,
typedArray : new Float32Array([0, 0, 0]),
usage : BufferUsage.STATIC_DRAW
});
使用Buffer.createIndexBuffer创建指定数据大小而数据未确定的IBO的例子:
// Example 1. Create a stream index buffer of unsigned shorts that is
// 16 bytes in size.
const buffer = Buffer.createIndexBuffer({
context : context,
sizeInBytes : 16,
usage : BufferUsage.STREAM_DRAW,
indexDatatype : IndexDatatype.UNSIGNED_SHORT
});
使用Buffer.createIndexBuffer创建数据确定的IBO的例子:
// Example 2. Create a static index buffer containing three unsigned shorts.
const buffer = Buffer.createIndexBuffer({
context : context,
typedArray : new Uint16Array([0, 1, 2]),
usage : BufferUsage.STATIC_DRAW,
indexDatatype : IndexDatatype.UNSIGNED_SHORT
});
此外,Buffer封装的函数有:
Buffer.prototype.copyFromArrayView = function (arrayView, offsetInBytes)
Buffer.prototype.copyFromBuffer = function (
readBuffer,
readOffset,
writeOffset,
sizeInBytes
)
Buffer.prototype.getBufferData = function (
arrayView,
sourceOffset,
destinationOffset,
length
)
Buffer.prototype.isDestroyed
Buffer.prototype.destroy
4. 参考资料
[1]Cesium原理篇:6 Renderer模块(1: Buffer) - fu*k - 博客园 (cnblogs.com)
[2]WebGLRenderingContext - Web API 接口参考 | MDN (mozilla.org)
[3]Cesium渲染模块之概述 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com)
Cesium渲染模块之Buffer的更多相关文章
- Cesium原理篇:6 Renderer模块(1: Buffer)
刚刚结束完地球切片的渲染调度后,打算介绍一下目前大家都很关注的3D Tiles方面的内容,但发现要讲3D Tiles,或者充分理解它,需要对DataSource,Primitive要有基础,而这要求对 ...
- Cesium原理篇:6 Renderer模块(1: Buffer)【转】
https://www.bbsmax.com/A/n2d9P1Q5Dv/ 刚刚结束完地球切片的渲染调度后,打算介绍一下目前大家都很关注的3D Tiles方面的内容,但发现要讲3D Tiles,或者充分 ...
- (原)Unreal渲染模块 管线 - 着色器(1)
@author: 白袍小道 转载悄悄说明下 随缘查看,施主开心就好 说明: 本篇继续Unreal搬山部分的渲染模块的Shader部分, 主要牵扯模块RenderCore, ShaderCore, RH ...
- (原)Unreal渲染模块 管线 - 程序和场景查询
@author: 白袍小道 查看随意,转载随缘 第一部分: 这里主要关心加速算法,和该阶段相关的UE模块的结构和组件的处理. What-HOW-Why-HOW-What(嘿嘿,老规矩) 1.渲 ...
- (原)Unreal渲染模块 源码和实例分析说明
@author:白袍小道 说明 1.由于小道就三境武夫而已,而UE渲染部分不仅管理挺大,而且牵扯技术和内容驳杂,所以才有这篇梳理. 2.尽量会按书籍和资料,源码,小模块的调试和搬山(就是敲键盘)..等 ...
- (原)Unreal 渲染模块 渲染流程
@author:白袍小道 浏览分享随缘,评论不喷亦可. 扯淡部分: 在temp中,乱七八糟的说了下大致的UE过程.下面我们还是稍微别那么任性,一步步来吧. UE渲染模块牵扯到场景遍历. ...
- (原)Unreal 渲染模块引言Temp
@author:白袍小道 引言 本文只在对Unreal渲染模块做一些详细的理解,务求能分析出个大概. 其中框架的思想和实现的过程,是非常值得学习和推敲一二的. 涉及资源系统,材 ...
- Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基础文件配置,Web框架的本质,服务器程序和应用程序(wsgiref服务端模块,jinja2模板渲染模块)的使用
Django---Http协议简述和原理,HTTP请求码,HTTP请求格式和响应格式(重点),Django的安装与使用,Django项目的创建和运行(cmd和pycharm两种模式),Django的基 ...
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
- drf框架 - 请求模块 | 渲染模块
Postman接口工具 官方 https://www.getpostman.com/ get请求,携带参数采用Paramspost等请求,提交数据包可以采用三种方式:form-date.urlenc ...
随机推荐
- 【大数据课程】高途课程实践-Day03:Scala实现商品实时销售统计
〇.概述 1.实现内容 使用Scala编写代码,通过Flink的Source.Sink以及时间语义实现实时销量展示 2.过程 (1)导包并下载依赖 (2)创建数据源数据表并写⼊数据 (3)在Mysql ...
- 【HBase】简介、结构、数据模型、快速入门部署、shell操作、架构原理、读写数据流程、数据刷写、压缩、分割、Phoenix、表的映射、与hive集成、优化
一.简介 1.定义 分布式.可扩展.支持海量数据存储的NoSQL数据库 2.数据模型 2.1逻辑结构 2.2物理存储结构 2.3数据模型介绍 Name Space:相当于数据库,包含很多张表 Regi ...
- SQLSERVER 的主键索引真的是物理有序吗?
一:背景 1. 讲故事 最近在看 SQL SERVER 2008 查询性能优化,书中说当一个表创建了聚集索引,那么表中的行会按照主键索引的顺序物理排列,这里有一个关键词叫:物理排列,如果不了解底层原理 ...
- Excelize 2.7.0 发布, 2023 年首个更新
Excelize 是 Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准.可以使用它来读取.写入由 Microsoft Exc ...
- [cocos2d-x]用getContentSize()返回的值用CCLOG打印必须用%f
今天写代码,又遇到了一个bug,开始还以为是我自己哪写错了,没想到竟然在这里出错? 而width和height的类型是float类型,为什么必须用%d打印?接着我查看了一下源码: 如果没理解错的话,C ...
- 04-Sed操作参数
1 Sed操作参数 1.1 s--替换 s表示替换(substitute)文件内的字符串. [address1],[address2]s/pattern/replacement/[flag] # s/ ...
- OpenMP 线程同步 Construct 实现原理以及源码分析(上)
OpenMP 线程同步 Construct 实现原理以及源码分析(上) 前言 在本篇文章当中主要给大家介绍在 OpenMP 当中使用的一些同步的 construct 的实现原理,如 master, s ...
- SSM进行Query
在查询之前,需要输入数据库字段的名称,s_id需要获取
- 【随笔记】Littlevgl 8.x 踩过的坑
在多线程并发使用的时候,总是在运行过程中莫名其妙的 crash,后面才意识到 LVGL 本身不支持并发,加了互斥锁解决了. 在引入矢量字库时(freetype),又有启动时会概率性 crash 的问题 ...
- ADC-单通道DMA到多通道DMA ADC采集修改事项
1. 使能通道IO,因为从单通道到多通道,需要添加规则转换通道数,故需要使能扫描模式,否则只能扫描第一个通道: 2. DMA模式配置需修改为循环传输模式,否则只转换一次: 3. 开启ADC规则转换通道 ...