本文共 5315 字,大约阅读时间需要 17 分钟。
三维场景中的几何体通常由顶点组成,但要实现真实的渲染效果,需要对几何体进行渲染。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纹理、压缩纹理和立方纹理等。
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):获取一个已设置的纹理相关的渲染属性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对象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():获取纹理图像数目Texture2D():默认构造函数Texture2D(Image *image):构造函数,以一个2D纹理的图片源作为输入参数void setImage(Image *image):设置2D纹理的输入图片源对象void setTextureWidth(int width):设置2D纹理图像的大小void setTextureHeight(int height):设置2D纹理图像的大小转载地址:http://vkvfk.baihongyu.com/