OSG之二维纹理数据

191 阅读2分钟

1 概述

纹理数据,在大多数应用程序中,纹理数据都是从外部导入的图像文件。当没有必要导入图像时,可以生成一幅纹理数据贴图。这里使用从外部导入的纹理数据图形的方法。

2 纹理读取

读取图像需要使用一个新类——osg::Image。 osg::Image 继承自 osg::Object 类,继承关系图如下图所示。

osg::Image继承关系图

2.PNG

下面的代码将实现如何读取图像:

osg::ref_ptr<osg::Image> image = new osg::Image; 
image->setFileName("tree.rgb");

在读取一个图像后,需要创建一个纹理对象来关联图像。osg::Texture2D属于osg::StateAttribute的派生类,用于管理OpenGL纹理对象,而Image用于管理图像像素数据。如果要使用2D图像文件作为纹理映射的图形,只要将文件名赋给 Image 对象并将 Image 关联到 Texture2D 即可。

osg::Texture2D 继承自 osg::Texture,继承关系图如下图所示。

osg::Texture2D继承关系图

3.PNG

下面的代码将实现将图像关联到 2D 纹理对象上:

//将图像关联到 Texture2D 对象
osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
tex->setlmage( image.get());

在关联图像以后,可以直接关联到渲染状态。值得注意的是:大量使用纹理贴图的程序往往需要实现更紧凑的内存管理。Image 类继承自 Referenced 类,而 Texture2D 内部保存了一个指向 Image 的ref—ptr—指针。在第一次渲染时, OSG创建了用于保存图像数据的OpenGL纹理对象,其结果是产生了两个纹理图像的副本,一个是 Image 对象,另一个由OpenGL 拥有。

简单的单环境(single—context)场景渲染中,读者可以通过设置Texture2D解除对Image的引用来降低内存损耗。如果当前引用Image对象的只有Texture2D对象,那么OSG将释放Image及其内存空间。下面的代码演示了设置Texture2D解除对 Image 引用的方法:

//创建OpenGL纹理对象后,释放内部的ref_ptr<Image>,删除 Image图像
tex->setUnRefImageDataAfterApply( true);

默认情况下, Texture2D不会自动释放对Image的引用。在多环境(multi—context)场景渲染中,这是一种期望行为,前提是纹理对象并没有在各环境中共享。