WebGL——osg框架学习三
今天继续来Draw绘制的osg模块的学习,昨天我们学习的是StateBin渲染状态树节点类,今天我们来继续学习下一个Draw的基础类DrawableEntity渲染对象实体类。这个类和Drawable和绘制对象关系是并列的,DrawableEntity同样有自己的DrawEntityActor。但是要注意的是,DrawableEntity和Drawable的功能是完全不同的,Drawable是绘制对象,包含geometry,transform,stateBin等几何属性空间属性和状态树属性;DrawableEntity则是管理render渲染实体的,和将要绘制的对象有着天壤之别。我们今天研究的是渲染管理模块,先理清概念。
接下来老办法,鲫鱼继续带大家看看DrawableEntity的构造函数,看看DrawableEntity的私有属性有哪些。先贴出DrawableEntity构造函数的代码,由于采用的是require(module)方式引入依赖模块,所以鲫鱼将DrawableEntity依赖的类也一起截出来,但在本文不加讨论,以后会逐一介绍。
- /*
- 渲染实体的可绘制对象
- */
- let Drawable = require('./Drawable');
- let StateBin = require('./StateBin');
- let DrawableEntity = function (actor) {
- Drawable.call(this, actor);
- this._renderEntity = undefined;//关联的渲染实体
- this._material = undefined;//原本的颜色状态
- };
我们看到,DrawableEntity依赖Drawable可绘制对象类,依赖StateBin状态树节点类。前文已经讨论过这两个类,这里不再叙述。我们还是来看DrawableEntity的属性,this._renderEntity渲染实体属性;this._material初始颜色属性。我们接下来继续看看DrawableEntity的成员函数。
- reset: function () {
- Drawable.prototype.reset.call(this);
- this._renderEntity = undefined;
- //this._radius = 0;
- },
重置函数,重构原型对象中的reset函数,将私有成员this._renderEntity置空。
- setRenderEntity: function (entity) {
- this._renderEntity = entity;
- },
设置渲染对象,设置私有成员this._renderEntity渲染实体。
- getRenderEntity: function () {
- return this._renderEntity;
- },
获取渲染对象。
- setMaterial: function (s) {
- this._material = s;
- },
设置材质。
- getMaterial: function () {
- return this._material;
- },
获取材质属性。
- valid: function () {
- // if(this._frameNumber === Drawable.FrameNumber){//已经绘制过,不再处理
- // return false;
- // }
- //是否后面的不需再判断了
- if (!this._renderEntity.isShown()) {//隐藏的直接跳过
- return false;
- }
- if (this._drawActor.getBaseCamera().isBoundingBoxCulled(this.getBoundingBox())) {
- return false;
- }
- return true;
- },
这个就类似Drawable了,valid成员函数用来判断render渲染对象是否需要被绘制,这里排除了2种不需要绘制的情况,第一种是标记为隐藏的渲染对象;第二种被剔除的则是包围盒不在相机可视棱台范围内的可渲染对象,简单来说就是不在当前视口范围内的渲染对象。剩下的都是符合渲染条件的renderEntity,通过valid校验。我们继续看下一个函数。
- isTransparent: function () {
- let result = false;
- let hasmaterial = false;
- //this._stateBin不能变
- this._statebin.removeChildren();
- this._curStatebin = this._statebin;
- if (this._renderEntity !== undefined) {//有关联的渲染实体,渲染实体的状态优先级最高
- let statesets = this._renderEntity.getStateSets();
- let size = statesets.size;
- if (size !== 0) {
- statesets.forEach((stateset) => {
- if (stateset) {
- let mat = stateset.getMaterialAttribute();//一般不存在多个Material的情况,逻辑上避免,如果存在使用最后一个
- if (mat) {//如果有Material,当前this._material就不再考虑
- hasmaterial = true;
- result = mat.isTransparent();
- }
- this._curStatebin = this._curStatebin.addStateSetChild(stateset);
- }
- });
- }
- }
- //当前材质状态
- if (this._material) {
- if (!hasmaterial) {
- this._curStatebin = this._curStatebin.addStateSetChild(this._material);
- let mat = this._material.getMaterialAttribute();
- if (mat) {
- result = mat.isTransparent();
- }
- }
- }
- return result;
- },
该函数是用来判断当前渲染对象是否为透明的材质对象。由于webgl和opengl中对透明材质的处理很特殊,要按照深度排序由远到近依次绘制而且我们都是在非透明材质绘制完成后才绘制透明材质,否则材质混合会出问题,所以我们在管理renderEntity时一定要判断渲染对象是否透明。这当中还要对当前渲染对象的StateSet状态优先级进行排序,其中判断材质是否透明的函数是Material的成员函数,这个api是this._material.getMaterialAttribute().isTransparent()。我们再来看最后一个函数。
- draw: function (glstate, preDrawable) {//重载
- //先接受状态,再渲染几何
- let curStatebin = this._curStatebin;
- let curStateset = curStatebin.getStateSet();//当前的状态
- let curStatebinParent = curStatebin.getParent();//父节点
- //let curStatesetParent = undefined;//父节点的状态
- //if(curStatebinParent){//自从加了总根节点后,这个情况不存在了吧!
- //let curStatesetParent = curStatebinParent.getStateSet();//父节点的状态
- //}
- if (preDrawable !== undefined) {
- let preStatebin = preDrawable.getCurrentStateBin();
- let preStateset = preStatebin.getStateSet();
- let preStatebinParent = preStatebin.getParent();
- //let preStatesetParent = undefined;
- //if(preStatebinParent){//自从加了总根节点后,这个情况不存在了吧!
- //let preStatesetParent = preStatebinParent.getStateSet();//父节点的状态
- //}
- //RenderEntity下的状态随时会变,在isTransparent中会实时更新StateBin
- //所以每次StateBin的结果可能都是临时创建的没有可比性,还是比较stateset靠谱点
- if (preStatebinParent !== curStatebinParent) {//A
- StateBin.moveStateBin(glstate, preStatebinParent, curStatebinParent);
- glstate.applyStateSet(curStateset);
- } else if (preStateset !== curStateset) {//B
- glstate.applyStateSet(curStateset);
- } else {
- // we call apply but actually we dont need
- // except if the stateSetStack changed.
- // for example if insert/remove StateSet has been used
- // if (glstate._stateSetStackChanged(idLastDraw, lastStateSetStackSize )) {
- // glstate.applyStateSet(curStateset);
- // }
- }
- }
- else {//如果preLeaf为空,第一个绘制的几何,状态遍历到根节点全部push到GLState中
- StateBin.moveStateBin(glstate, undefined, curStatebinParent);
- glstate.applyStateSet(curStateset);
- }
- //state._setStateSetsDrawID( ++idLastDraw );
- //lastStateSetStackSize = state.getStateSetStackSize();
- //this.drawGeometry(glstate);
- let camera = this._drawActor.getBaseCamera();
- glstate.applyModelMatrix(this._transform, camera.getModelViewMatrix(), camera.getProjectionMatrix());
- this._geometry.draw(glstate);
- //return true;
- //_stateBin新添加的儿子要删除,不影响下一帧的绘制
- //this._statebin.removeChildren();
- //this._curStatebin = undefined;//千万不要重置。。每帧绘制时的Drawable会取前一个的状态
- //this._frameNumber = Drawable.FrameNumber;//已经绘制过,不再绘制
- },
绘制函数draw。这个绘制draw就是用glstate来绘制当前渲染对象。
好了,以上就是DrawableEntity渲染对象的管理操作类的所有成员属性和成员函数的介绍。我们又了解了osg的DrawableEntity的构造,再接再厉,下一篇鲫鱼带领大家继续学习DrawEntityActor类。今天先到这里,下周再见。本文系原创,如需引用,请注明出处:https://www.cnblogs.com/ccentry/p/10227152.html
WebGL——osg框架学习三的更多相关文章
- WebGL——osg框架学习一
从今天开始,我们开始正式的学习osg框架,今天我们学习的是osg的渲染模块,我们来看一下代码结构. 所有DrawXXX的js模块都是渲染的模块,我们逐一来简单介绍一下,第一个Drawable.js,这 ...
- WebGL——osg框架学习四
这篇我们接着来看一下DrawEntityActor类,我们来看看这个继承DrawActor的类到底做了什么事.我们之前学习了Drawable对应的DrawActor,那么我们类比的来看Drawable ...
- Struts2框架学习(三) 数据处理
Struts2框架学习(三) 数据处理 Struts2框架框架使用OGNL语言和值栈技术实现数据的流转处理. 值栈就相当于一个容器,用来存放数据,而OGNL是一种快速查询数据的语言. 值栈:Value ...
- Android 学习笔记之AndBase框架学习(三) 使用封装好的函数完成Http请求..
PS:踏踏实实走好每一步... 学习内容: 1.使用AndBase框架实现无参Http Get请求... 2.使用AndBase框架实现有参Http Post请求... 3.使用AndBase框架实现 ...
- python flask框架学习(三)——豆瓣微信小程序案例(二)整理封装block,模板的继承
我们所要实现的效果: 点击电影的更多,跳转到更多的电影页面:点击电视剧的更多,跳转到更多的电视剧页面. 三个页面的风格相同,可以设置一个模板,三个页面都继承这个模板 1.在指定模板之前,把css放在一 ...
- django 基础框架学习 (三)
Django框架基础-03数据库新增数据 1.save⽅法 >>> from datetime import date >>> f ...
- Struts2框架学习(三)——配置详解
一.struts.xml配置 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts ...
- Hibernate框架学习(三)——实体规则、对象状态、一级缓存
一.Hibernate中的实体规则 1.实体类创建的注意事项 1)持久化类提供无参数构造,因为在Hibernate的底层需要使用反射生成类的实例. 2)成员变量私有,提供公有的get和set方法,需提 ...
- spring框架学习(三)——AOP( 面向切面编程)
AOP 即 Aspect Oriented Program 面向切面编程 首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能. 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务 ...
随机推荐
- Linux常用命令笔记总结(待补充)
问题实际场景:遇到告警磁盘利用率不足,检查根目录下各文件大小 Linux查看磁盘利用率 df –h 查找磁盘占用情况 find / -size +100M 从根目录往下找大于100M大小的文件 du ...
- 简单的dp加贪心
题目链接:传送门 这个题目让我纠结了好久,之后恍然大悟是求最长的递减序列,并加上贪心的算法,如果有大于两个的发射系统,应该判断使导弹的高度与此时个个发射系统的高度比较,选取高度差最小的去执行这次的拦截 ...
- Alpha 冲刺报告(9/10)
Alpha 冲刺报告(9/10) 队名:洛基小队 峻雄(组长) 已完成:角色属性功能的测试版 明日计划:准备α版本的ppt 剩余任务:尽量完成角色属性功能 困难:缺乏编程经验,很难自己独立完成编写,只 ...
- CR与LF
CR与LF CR(carriage return),中文名称"回车":LF(line feed),中文名称"换行".无论是初学编程的小白还是入行十年的资深,总会 ...
- 【转】说说Android中的style和theme
最近在做软件从2.3到4.0的改变的一些工作,其中涉及了一些style和theme相关的东西.上网上查了一些东西,这个一并说说.关于android中style和theme的基本使用,这里就不再赘述了, ...
- jQuery内容横向拖拽滚动
如果有业务需求:使用横向滚动,而又不想用滚动条,可以使用横向拖拽滚动,主要是利用元素的scrollLeft特性: 废话不多说直接上代码: css: .box{ width:100%; height:3 ...
- springboot整合mybatis将sql打印到日志
在前台请求数据的时候,sql语句一直都是打印到控制台的,有一个想法就是想让它打印到日志里,该如何做呢? 见下面的mybatis配置文件: <?xml version="1.0" ...
- vmvare安装系统提示vmci.sys 版本不正确解决方法
无法获取vmci驱动程序版本:参数不正确解决 无法获取vmci驱动程序版本:参数不正确. 驱动程序vmci.sys版本不正确. 解决办法: 1,创建好虚拟机之后,别打开电源,然后到建好的虚拟机文件夹里 ...
- 基于AppDomain的"插件式"开发
很多时候,我们都想使用(开发)USB式(热插拔)的应用,例如,开发一个WinForm应用,并且这个WinForm应用能允许开发人员定制扩展插件,又例如,我们可能维护着一个WinService管理系统, ...
- 解决:在pom.xml处理添加testng依赖之外,需对testng进行关联
问题描述:当maven项目中下载了testng包,在调用后,执行maven test,未执行testng.xml中指定的测试类. 解决:在pom.xml处理添加testng依赖之外,需对testng进 ...