博客
关于我
OSG学习:OSG组成(二)——渲染状态和纹理映射
阅读量:796 次
发布时间:2023-02-26

本文共 5315 字,大约阅读时间需要 17 分钟。

OpenSceneGraph三维渲染引擎编程指南

一 概述

三维场景中的几何体通常由顶点组成,但要实现真实的渲染效果,需要对几何体进行渲染。OpenSceneGraph(OSG)通过场景树和渲染树的结合,提供了一个高效的三维渲染解决方案。通过纹理和光照的配合,可以屏蔽物体表面的粗糙不平现象,使场景呈现出接近真实的效果。

OSG几乎封装了OpenGL所有的渲染接口,包括光照、材质、纹理、Alpha测试、图像融合、面剔除、雾效、深度测试,以及顶点着色器(Vertex Shader)、几何着色器(Geometry Shader)和片元着色器(Fragment Shader)。

二 渲染树:渲染状态-渲染属性和渲染模式

渲染树是以StateSet和RenderLeaf为节点的一棵树。OSG采用包围体层次的形式来构建不同层次、不同功能的场景节点。每个节点都可以保存多种类型的渲染属性和模式,而父子节点之间则存在多种渲染状态的继承关系。

OSG将渲染状态分为两部分:属性(Attribute)和模式(Mode)。一个节点所赋予的多个渲染状态(包括各种属性和模式)称为一个渲染状态几何,用StateSet类来表示。

渲染属性控制渲染特性,如雾的颜色或Blend融合函数,而渲染模式则对应OpenGL的状态特性,通过glEnable()和glDisable()进行控制。渲染属性是渲染模式的属性变量,如灯光的颜色、强度、雾效的颜色等。

能够应用渲染状态集的对象不一定是场景中的节点Node,也可以是绘制对象Drawable。如果一个叶节点Geode包含多个几何形体,那么这个叶节点和每一个几何体都可以拥有自己的渲染属性和模式结合,创造出如底部被云雾笼罩,顶部有阳光照耀的房屋等效果。

OSG为每个状态属性定义了不同的类,所有的属性类均继承自osg::StateAttribute,它是一个无法直接实例化的虚基类。

OSG将所有的属性和模式分为纹理(texture)和非纹理(non-texture)两大部分。由于纹理属性需要特别为多重纹理设置纹理单元,OSG为纹理属性的设置提供了不同的接口。

三 设置渲染属性和渲染模式

设置渲染属性:修改属性类的实例化,用osg::StateSet::setAttribute()将其关联到StateSet。

实现面剔除(face culling)的属性,以下代码用到了位屏蔽技术:

// 获取变量geom的State指针
osg::StateSet *state = geom->getOrCreateStateSet();
// 创建并添加CullFace属性类
osg::CullFace *cf = new osg::CullFace(osg::CullFace::BACK);
state->setAttribute(cf);

设置渲染模式:使用osg::StateSet::setMode()设置允许或禁止某种模式。

例如,打开雾效模式的许可:

// 获取一个State实例
osg::StateSet *state = geom->getOrCreateStateSet();
// 允许这个State的雾效模式
state->setMode(GL_FOG, osg::StateAttribute::ON);

设置渲染属性和模式:使用osg::StateSet::setAttributeAndMode()方法。

设置渲染属性和模式的继承:当设置节点的渲染状态后,其子节点会继承当前状态,而若子节点对该渲染状态设置了不同的属性参数,为了允许用户根据场景图形中任意位置的渲染属性和模式需求单独改变原有的状态继承特性,OSG提供了几种枚举形式:

  • osg::StateAttribute::OVERRIDE:所有子节点都将继承这一属性或模式,子节点对其更改无效。
  • osg::StateAttribute::PROTECTED:设置了这一属性的子节点的渲染属性或模式不会受到父节点的影响。
  • osg::StateAttribute::INHERIT:强制子节点继承父节点的渲染状态,自己本身的渲染状态被解除。

四 纹理映射

物体的纹理是可以根据用户视点的远近来自动调整和变化的,即纹理图像的细节层次(Mipmap);并且当纹理无法完全覆盖几何体的每一个顶点时,通过边界截取方式的调整,可以重复设置同一块纹理,或者将边界颜色应用到未覆盖的物体表面上。

OSG的纹理映射主要包括一维纹理、二维纹理、三维纹理、凹凸纹理、多重纹理、Mipmap纹理、压缩纹理和立方纹理等。

  • 二维纹理:应用最广泛的纹理类型,将二维矩形图像映射到三维物体上。要求图像的宽度和高度必须是2的幂次方,单位是纹素。如果图像不符合要求,则会自动重采样到符合要求,消耗时间和系统资源。
  • 一维纹理:将二维纹理的高度设为1,且顶部和底部不存在边框,可以视其为只在S方向上变化的一维纹理。因此也要求纹理宽度为2的幂次方。如一条彩色丝带,水银柱的升降等。其操作效率高于高度值为1的二维纹理。
  • 三维纹理:最常用于医学和地质,可以用来表达医学CT图像和岩层状态。理解为多层二维子纹理所构成的一个立方体,其中的每一个纹素此时称为一个体素。因此也要求纹理宽度、高度和深度为2的幂次方。会耗费大量的系统资源。
  • 二维纹理数组:一种较为特殊的纹理类型,与三维纹理的概念并无本质上的区别。主要用于OpenGL着色语言(GLSL)程序中二维纹理数组对象的表达。
  • 立方图纹理:主要用于反射贴图或环境贴图的表达,如对于场景中天空景象的渲染。使用六个二维图像来表达一个立方体的六个面,S/T/R坐标轴的原点为这个立方体的中心点。
  • 矩形纹理:OpenGL中的传统纹理类型限制了图像的尺寸必须是2的幂次方,而矩形纹理取消了这种限制,它支持任意尺寸的二维图像作为纹理。不受“2的幂次方”限制的图像称为NPOTS纹理(Non-power-of-two Sized),它避免了传统二维纹理对于任意尺寸图像的重采样过程,并且可以节省更多的系统空间,但NPOTS纹理不支持Mipmap的过滤,对于纹理边界截取方式的设置也只有GL_CLAMP/GL_CLAMP_TO_EDGE/GL_CLAMP_TO_BORDER三种。

五 节点方法

1、osg::StateSet类
  • StateSet():默认构造函数
  • int compare(const StateSet &rhs, bool):比较两个渲染状态集
  • ParentList getParents():获取渲染状态集的父对象
  • void setMode(StateAttribute::GLmode, StateAttribute::GLModeValue):启用或禁用一种渲染模式
  • StateAttribute::GLModeValue getMode(StateAttribute::GLMode):获取一种已设置的渲染模式
  • void setAttribute(StateAttribute *attribute, StateAttribute::OverrideValue):设置一个渲染属性,并设置其开关值
  • void setAttributeAndMode(StateAttribute *attribute, StateAttribute::GLModeValue):设置一个渲染属性,同时设置与之绑定的渲染模式
  • StateAttribute *getAttribute(StateAttribute::Type type, unsigned int member):获取一个已设置的渲染属性
  • void setTextureMode(unsigned int unit, StateAttribute::GLMode mode, StateAttribute::GLModeValue):启用或禁用纹理相关的渲染模式
  • StateAttribute::GLModeValue getTextureMode(unsigned int unit, StateAttribute::GLMode):获取一个已设置的纹理相关的渲染模式
  • void setTextureAttribute(unsigned int unit StateAttribute *attribute, StateAttribute::OverrideValue):设置一个纹理相关的渲染属性,并设置其开关值
  • void setTextureAttributeAndModes(unsigned int unit, StateAttribute *attribute, StateAttribute::GLModeValue):设置一个纹理相关的渲染属性,同时设置与之绑定的渲染模式
  • StateAttribute *getTextureAttribute(unsigned int unit, StateAttribute::Type type):获取一个已设置的纹理相关的渲染属性
2、osg::StateAttribute类
  • StateAttribute():默认构造函数
  • unsigned int getMember():虚函数,用于获取属性的成员号
  • bool getModeUsage(StateAttribute::ModeUsage &):虚函数,用于获取与属性绑定的渲染模式
  • int compare(const StateAttribute &):虚函数,用于比较两个渲染属性
  • const ParentList &getParents():获取属性的父对象列表
  • void apply(State &):虚函数,应用这个渲染属性
  • void compileGLObjects(State &):虚函数,用于编译OpenGL对象
  • void releaseGLObjects(State *):虚函数,用于释放编译得到的OpenGL对象
3、osg::Texture类
  • Texture():默认构造函数
  • int getTextureWidth(): 获取纹理S方向宽度
  • int getTextureHeight(): 获取纹理T方向高度
  • int getTextureDepth(): 获取纹理R方向深度
  • void setBorderColor(const Vec4d &):设置纹理边界的颜色
  • const Vec4d &getBorderColor(): 获取纹理边界的颜色
  • void setBorderWidth(GLint):设置纹理边界的厚度
  • GLint getBorderWidth(): 获取纹理边界的厚度
  • void setWrap(WrapParameter which, WrapMode wrap):设置纹理滤波方式
  • WrapMode getWrap(WrapParameter which):获取纹理滤波方式
  • void setFilter(FilterParameter which, FilterMode filter):设置纹理的内部压缩方式
  • FilterMode getFilter(FilterParameter which):获取纹理的内部压缩方式
  • void setResizeNonPowerOfTwoHint(bool):设置纹理的自动转换到2的幂次方的提示
  • bool getResizeNonPowerOfTwoHint():获取纹理的自动转换到2的幂次方的提示
  • void setInternalFormatMode(InternalFormatMode):设置纹理内部格式
  • InternalFormatMode getInternalFormatMode():获取纹理内部格式
  • void setInternalFormat(Glint):设置纹理内部格式
  • GLenum getSourceFormat():获取纹理图象源的数据格式
  • void setSourceType(GLenum):设置纹理图象源的数据类型
  • void setImage(unsigned int face, Image *):设置某个面的纹理图像
  • Image *getImage(unsigned int face):获取已设置的纹理图像数目
  • unsigned int getNumImages():获取纹理图像数目
4、osg::Texture2D类
  • Texture2D():默认构造函数
  • Texture2D(Image *image):构造函数,以一个2D纹理的图片源作为输入参数
  • void setImage(Image *image):设置2D纹理的输入图片源对象
  • void setTextureWidth(int width):设置2D纹理图像的大小
  • void setTextureHeight(int height):设置2D纹理图像的大小

转载地址:http://vkvfk.baihongyu.com/

你可能感兴趣的文章
OpenResty(2):OpenResty开发环境搭建
查看>>
OpenResty(3):OpenResty快速入门之安装lua
查看>>
OpenResty(4):OpenResty快速入门
查看>>
OpenResty(5):Openresty 模板渲染
查看>>
OpenSessionInView模式
查看>>
openshift搭建Istio企业级实战
查看>>
OpenSLL
查看>>
OpenSSL 引入了新的治理模式和项目,来增强社区参与和决策
查看>>
openssl安装
查看>>
OpenStack 上部署 Kubernetes 方案对比
查看>>
Openstack 之 网络设置静态IP地址
查看>>
OpenStack 存储服务详解
查看>>
OpenStack 搭建私有云主机实战(附OpenStack实验环境)
查看>>
OpenStack 综合服务详解
查看>>
OpenStack 网络服务Neutron详解
查看>>
Openstack 网络管理企业级实战
查看>>
Openstack(两控制节点+四计算节点)-1
查看>>
openstack--memecache
查看>>
openstack-keystone安装权限报错问题
查看>>
openstack【Kilo】汇总:包括20英文文档、各个组件新增功能及Kilo版部署
查看>>