1 概述
在进行标准的二维纹理映射处理时,一次把一幅纹理图像应用到一个多边形上。多重纹理允许应用几个纹理,在纹理操作管线中把它们逐个应用到同一个多边形上,多重纹理存在一系列的纹理单元,每个纹理单元执行单独的纹理操作,并把它的结果传递给下一个纹理单元,直到所有纹理单元的操作完成为止,最终显示处理后的效果。
多重纹理映射非常广泛,它能实现一些高级的渲染技巧,如光照、贴花、合成和细节纹理等,在OSG 中实现三维纹理主要有以下几个步骤:
(1)指定用户几何体的纹理坐标。
(2)创建多个纹理属性对象并保存纹理多个图形数据。
(3)为StateSet设置合适的纹理属性和模式。
看起来和二维纹理映射的区别不大,简单地说就是多个二维纹理映射的叠加。但这里需要注意的是,对于不同的纹理属性对象需要指定不同的纹理单元及纹理坐标,否则就不会启用该纹理单元,或者该纹理单元会被覆盖。
2 多重纹理映射示例
多重纹理映射示例的代码如程序清单所示。
#include <osgViewer/Viewer>
#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/Image>
#include <osg/TexGen>
#include <osg/TexEnv>
#include <osg/StateSet>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <osgUtil/Optimizer>
#include <iostream>
#include "utility.h"
int main()
{
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();
osg::ref_ptr<osg::Group> root = new osg::Group();
osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(GetCurrentPath() + "Data\\cow.osg");
// 读取贴图文件
osg::ref_ptr<osg::Image> image = osgDB::readImageFile(GetCurrentPath() + "Data\\fengjing\\2.jpg");
if (image.get())
{
// 创建二维纹理
osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
texture->setImage(image.get());
// 设置自动生成坐标
osg::ref_ptr<osg::TexGen> texgen = new osg::TexGen;
texgen->setMode(osg::TexGen::SPHERE_MAP);
// 设置纹理环境,模式为blend
osg::ref_ptr<osg::TexEnv> texenv = new osg::TexEnv;
texenv->setMode(osg::TexEnv::BLEND);
// 设置BLEND操作颜色
texenv->setColor(osg::Vec4(0.6f, 0.6f, 0.6f, 0.0f));
// 启用单元1自动生成纹理坐标,并使用纹理
osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;
stateset->setTextureAttributeAndModes(1, texture.get(), osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(1, texgen.get(), osg::StateAttribute::ON);
// 设置纹理环境
stateset->setTextureAttribute(1, texenv.get());
// 设置纹理状态
node->setStateSet(stateset.get());
}
root->addChild(node.get());
// 优化场景数据
osgUtil::Optimizer optimzer;
optimzer.optimize(root.get());
setWindowSize(viewer.get(), 600, 600, "MultiTexture");
viewer->setSceneData(root.get());
viewer->realize();
viewer->run();
return 0;
}
纹理图片
效果图
动态效果图