热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[WebGL入门]十二,模型数据和顶点属性

顶点中的属性是由程序员来自由添加的,需要的VBO的个数就是添加的属性个数。顶点属性的各个数据,使用纯粹的一维数组,当然,数组的元素个数要根据想要绘制的顶点个数来定义。生成VBO的时候,首先要把缓存绑定到WebGL,然后相应的数据,要转换为相应的类型,然后使用指定的常量来写入数据。而为了避免预想之外的错误发生,数据写入结

注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中如果有我的额外说明,我会加上[lufy:],另外,鄙人webgl研究还不够深入,一些专业词语,如果翻译有误,欢迎大家指正。


顶点属性的意思

上次的文章中,介绍了一下从着色器的生成,编译,到程序对象的生成和着色器的连接。这次,简单的说一下模型数据的定义和顶点属性的处理。另外,介绍一下根据模型数据生成VBO的方法。
VBO的使用要比生成难理解一些,但是不要担心,后面会慢慢说明。
接下来看一下顶点属性。
顶点属性,说的简单点,就是顶点包含的各种元素。WebGL中,顶点至少要包含的元素是位置情报,这个之前已经说过很多遍了。
顶点是三维空间中的任意一个点,所以一定要有位置情报,如果没有位置情报,则无法在三维空间中定义这个点,因为每个点都不一样,所以位置情报是必须的。lufy:感觉好罗嗦啊,作者是为了强调吧,可是真的好罗嗦啊,好罗嗦啊,啰嗦啊,嗦啊,啊.....
但是,顶点里还有可能包含其他属性,举个例子来说的话,比如顶点的颜色等等。根据顶点的颜色属性,来对多边形进行着色,或者透明等各种各样的处理。
另外的,还有顶点的法线,纹理坐标等相关的情报,这些都可以在顶点属性中自由的定义。DirectX中根据所谓的顶点格式来实现这些,但是在WebGL中顶点的各种属性都可以定义在顶点属性中。

顶点属性和VBO既然顶点属性是可以自由定义的,那么具体应该如何来实现呢?
看过以前的文章的话,应该知道顶点属性的个数和生成VBO的个数是一致的,如果顶点中有三个属性,那么就需要三个VBO,因为顶点属性必须通过VBO来传给顶点着色器。VBO也叫做顶点缓存,和它的名字一样,就是将顶点相关的情报缓存起来。顶点属性和VBO一对一进行分配,然后传给顶点着色器。
为了生成VBO,首先准备好和顶点个数相对应的矩阵,这里用的就是普通的Javascript数组,当然Array对象也可以,但是不可以使用关联数组,要使用一维数组。
举个例子,由三个顶点定义多边形的时候,写成下面这样。

>保存模型数据的数组的例子

var vertex_position = [
    // X,   Y,   Z
     0.0, 1.0, 0.0,
     1.0, 0.0, 0.0,
    -1.0, 0.0, 0.0
];
为了让大家看的更容易些,中间加了换行,可以看到这是一个一维数组,包含有9个元素,三个顶点都分别包含了X,Y,Z的坐标,顶点数x要素的数,就是3x3=9,所以数组中元素的个数是9。

VBO的生成用矩阵准备好顶点数据之后,就可以使用这个矩阵来生成VBO了,生成VBO的时候使用WebGL的createBuffer函数,这个函数就是用来生成缓存的。但是这个函数并不是用来直接生成VBO的,它只是生成了一个缓存对象,根据它里面保存的内容不同,用途也是不用的。
要操作缓存,首先必须跟WebGL进行绑定,就是说,要向“缓存”这个“光盘”中写入数据的时候,必须连接到WebGL这个“光驱”上。
绑定了缓存之后,使用bufferData函数来向缓存中写入数据,把这些处理写成一个函数,就是下面这样。

>生成VBO的函数

function create_vbo(data){
    // 生成缓存对象
    var vbo = gl.createBuffer();
    
    // 绑定缓存
    gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
    
    // 向缓存中写入数据
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(data), gl.STATIC_DRAW);
    
    // 将绑定的缓存设为无效
    gl.bindBuffer(gl.ARRAY_BUFFER, null);
    
    // 返回生成的VBO
    return vbo;
}
这个函数,接受一个矩阵作为参数,最后返回生成的VBO。首先使用createBuffer生成缓存对象,接着绑定缓存,然后写入数据。
绑定缓存的时候使用bindBuffer函数,这个函数有两个参数,第一个参数是缓存的类型,第二个参数是指定缓存对象。将第一个参数指定为gl.ARRAY_BUFFER就可以生成VBO。
另外,bufferData函数的第二个参数中出现的Float32Array对象,是Javascript的类型数组,和一般的Array对象类似,是处理浮点型小数的时候使用的数组对象。3D世界里小数的精确度非常重要,所以使用类型数组来传递数据。而第三个参数中的gl.STATIC_DRAW这个常量,定义了这个缓存中内容的更新频率。VBO的话,模型数据基本上就是直接这么反复用,所以使用这个常量。
可以绑定WebGL的缓存,一次只能绑定一个,所以要操作其他的缓存的时候,必须要绑定相应的缓存。所以在函数的最后,再次使用bindBuffer函数,设定第二个参数为null,来将上次的绑定无效化,这是为了防止WebGL中的缓存一致保留,而出现和预想不一致的情况。

总结顶点中的属性是由程序员来自由添加的,需要的VBO的个数就是添加的属性个数。
顶点属性的各个数据,使用纯粹的一维数组,当然,数组的元素个数要根据想要绘制的顶点个数来定义。
生成VBO的时候,首先要把缓存绑定到WebGL,然后相应的数据,要转换为相应的类型,然后使用指定的常量来写入数据。而为了避免预想之外的错误发生,数据写入结束之后,要将WebGL中绑定的缓存无效化。
这样,一连串的处理之后,模型数据就可以被顶点着色器利用了。下一回以后,说一下将VBO传给着色器的步骤,首先先把VBO的准备部分好好理解一下吧。


下次,说一下如何准备坐标变换矩阵。


转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend


推荐阅读
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • SQLite 动态创建多个表的需求在网络上有不少讨论,但很少有详细的解决方案。本文将介绍如何在 Qt 环境中使用 QString 类轻松实现 SQLite 表的动态创建,并提供详细的步骤和示例代码。 ... [详细]
  • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
    本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
  • 阅读本文大约需要3分钟。微信8.0版本的发布带来了许多令人振奋的新功能,如烟花特效和改进的悬浮窗,引发了用户的热烈反响。 ... [详细]
  • 深入理解Java泛型:JDK 5的新特性
    本文详细介绍了Java泛型的概念及其在JDK 5中的应用,通过具体代码示例解释了泛型的引入、作用和优势。同时,探讨了泛型类、泛型方法和泛型接口的实现,并深入讲解了通配符的使用。 ... [详细]
  • 作为一名程序员,从大学步入职场后,常常感受到一种难以言喻的空虚感。这种感觉或许源于对生活的不满、职业发展的瓶颈,或是日常琐事带来的压力。本文将深入探讨这种复杂的情感,并尝试寻找解决之道。 ... [详细]
  • 深入解析:阿里实战 SpringCloud 微服务架构与应用
    本文将详细介绍 SpringCloud 在微服务架构中的应用,涵盖入门、实战和案例分析。通过丰富的代码示例和实际项目经验,帮助读者全面掌握 SpringCloud 的核心技术和最佳实践。 ... [详细]
  • 并发编程:深入理解设计原理与优化
    本文探讨了并发编程中的关键设计原则,特别是Java内存模型(JMM)的happens-before规则及其对多线程编程的影响。文章详细介绍了DCL双重检查锁定模式的问题及解决方案,并总结了不同处理器和内存模型之间的关系,旨在为程序员提供更深入的理解和最佳实践。 ... [详细]
  • 本文深入探讨了C++对象模型中的一些细节问题,特别是虚拟继承和析构函数的处理。通过具体代码示例和详细分析,揭示了书中某些观点的不足之处,并提供了更合理的解释。 ... [详细]
  • 随着网络安全威胁的不断演变,电子邮件系统成为攻击者频繁利用的目标。本文详细探讨了电子邮件系统中的常见漏洞及其潜在风险,并提供了专业的防护建议。 ... [详细]
  • 在 Angular Google Maps 中实现图片嵌入信息窗口的功能,可以通过使用 `@agm/core` 库来实现。该库提供了丰富的 API 和组件,使得开发者可以轻松地在地图上的信息窗口中嵌入图片。本文将详细介绍如何配置和使用这些组件,以实现动态加载和显示图片的功能。此外,还将探讨一些常见的问题和解决方案,帮助开发者更好地集成这一功能。 ... [详细]
  • 在TypeScript中,我定义了一个名为 `Employee` 的接口,其中包含 `id` 和 `name` 属性。为了使这些属性可选为空,可以通过使用 `| null` 或 `| undefined` 来扩展其类型定义。例如,`id: number | null` 表示 `id` 可以是数字或空值。这种类型的灵活性在处理不确定的数据时非常有用,可以提高代码的健壮性和可维护性。 ... [详细]
  • 我有一个包含多个URL的数组。首先,需要同步获取数组中的第一个和第二个URL,当其中任意一个请求完成时,再继续处理第三个URL。这种按序获取的方式可以确保数据的正确性和完整性,避免因并发请求导致的数据混乱。 ... [详细]
  • 本文探讨了如何在 Google Sheets 中通过自定义函数实现 AJAX 调用。具体介绍了编写脚本的方法,以便在电子表格中发起 AJAX 请求,从而实现数据的动态获取与更新。这种方法不仅简化了数据处理流程,还提高了工作效率。 ... [详细]
  • MyJGUI 0.7.3:强大的MySQL管理工具最新版发布
    MyJGUI 0.7.3 是一款基于 Java 的 MySQL 数据库管理工具的最新版本。此更新引入了新的键盘快捷键,并对用户界面进行了多项改进,提升了用户体验和操作效率。此外,该版本还优化了性能,增强了稳定性和安全性,为数据库管理员提供了更加便捷和高效的管理工具。 ... [详细]
author-avatar
mobiledu2502915447
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有