osg::TexGen在 OSG 开发中很多时候模型没有手动指定纹理坐标UV或者需要程序化、自动地给模型贴纹理如投影贴图、地形贴图、物体空间映射。这时就需要使用osg::TexGen——OSG 内置的自动纹理坐标生成器。本文从原理、类继承关系、核心模式、完整可运行代码四个维度彻底讲透osg::TexGen。什么是 osg::TexGenosg::TexGen是 OSG 中用于**自动生成纹理坐标UV**的渲染状态类。它的作用不需要手动设置纹理坐标GPU 根据顶点坐标自动计算 UV。它支持 4 种自动生成模式最常用的是OBJECT_LINEAR物体空间线性映射本文代码使用EYE_LINEAR视角空间线性映射SPHERE_MAP球形环境映射NORMAL_MAP法向映射类继承关系osg::Object所有OSG对象基类 └── osg::StateAttribute渲染状态属性基类 ├── osg::Texture 纹理基类 │ └── osg::Texture2D └── osg::TexGen 自动纹理坐标生成器重要结论TexGen和Texture是同级别的渲染状态它们可以绑定到同一个纹理单元一起工作都由StateSet统一管理TexGen 核心工作模式OBJECT_LINEAR本文代码使用的是OBJECT_LINEAR物体线性模式。原理根据模型自身的局部坐标系物体空间通过平面方程把 3D 顶点坐标 → 自动映射成 2D 纹理坐标。texgen-setMode(osg::TexGen::OBJECT_LINEAR);设置平面决定纹理映射方向texgen-setPlane(osg::TexGen::S,osg::Plane(0.0f,0.0f,1.0f,0.0f));texgen-setPlane(osg::TexGen::T,osg::Plane(1.0f,0.0f,0.0f,0.0f));S 方向 → 映射到 Z 轴T 方向 → 映射到 X 轴完整可运行代码#includeosgViewer/Viewer#includeosg/Node#includeosg/Geode#includeosg/Group#includeosg/Image#includeosg/TexGen#includeosg/Texture2D#includeosg/TexEnv#includeosg/StateSet#includeosg/Plane#includeosgDB/ReadFile#includeosgDB/WriteFile#includeosgUtil/Optimizer#includeiostream// 创建纹理与自动纹理坐标状态osg::ref_ptrosg::StateSetcreateTexture1DState(){// 读取纹理图片osg::ref_ptrosg::ImageimageosgDB::readImageFile(Images/primitives.gif);if(!image.valid()){std::cerr图片加载失败std::endl;returnnullptr;}// 创建2D纹理osg::ref_ptrosg::Texture2Dtexturenewosg::Texture2D();// 设置纹理环绕方式为重复texture-setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT);texture-setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT);// 设置滤波texture-setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);texture-setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST);// 设置图像texture-setImage(image.get());// // 核心自动纹理坐标生成// osg::ref_ptrosg::TexGentexgennewosg::TexGen();texgen-setMode(osg::TexGen::OBJECT_LINEAR);// 物体线性模式// 设置 S、T 生成平面texgen-setPlane(osg::TexGen::S,osg::Plane(0.0f,0.0f,1.0f,0.0f));texgen-setPlane(osg::TexGen::T,osg::Plane(1.0f,0.0f,0.0f,0.0f));// 创建状态集osg::ref_ptrosg::StateSetstatesetnewosg::StateSet();// 启用纹理OVERRIDE表示强制覆盖原有状态stateset-setTextureAttributeAndModes(0,texture,osg::StateAttribute::OVERRIDE);stateset-setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);// 启用自动纹理坐标stateset-setTextureAttributeAndModes(0,texgen,osg::StateAttribute::OVERRIDE);stateset-setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);stateset-setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);returnstateset;}intmain(){osg::ref_ptrosgViewer::ViewerviewernewosgViewer::Viewer();osg::ref_ptrosg::Grouprootnewosg::Group();// 加载模型cessna.osgosg::ref_ptrosg::NodenodeosgDB::readNodeFile(cessna.osg);if(!node.valid()){std::cout模型加载失败std::endl;return-1;}// 获取纹理状态osg::ref_ptrosg::StateSetstatesetcreateTexture1DState();node-setStateSet(stateset.get());root-addChild(node.get());// 优化场景osgUtil::Optimizer optimizer;optimizer.optimize(root.get());// 运行viewer-setSceneData(root.get());viewer-realize();viewer-run();return0;}代码核心解释1. 创建纹理设置环绕、过滤、图像。2. 创建 TexGentexgen-setMode(osg::TexGen::OBJECT_LINEAR);使用物体空间线性映射。3. 设置映射平面texgen-setPlane(osg::TexGen::S,osg::Plane(0,0,1,0));texgen-setPlane(osg::TexGen::T,osg::Plane(1,0,0,0));S 方向 → Z 轴T 方向 → X 轴4. 启用自动纹理坐标setTextureMode(0,GL_TEXTURE_GEN_S,ON);setTextureMode(0,GL_TEXTURE_GEN_T,ON);告诉 GPUS 和 T 坐标都自动生成5. OVERRIDE 标志强制覆盖模型自带纹理保证我们的贴图生效。总结osg::TexGen自动生成纹理坐标无需手动 UV继承关系继承自StateAttribute与Texture同级OBJECT_LINEAR根据物体空间坐标自动映射纹理使用方法与纹理绑定到同一纹理单元启用GL_TEXTURE_GEN_S/T
【OSG学习笔记】Day 29: TexGen(自动纹理坐标)
发布时间:2026/6/5 22:24:37
osg::TexGen在 OSG 开发中很多时候模型没有手动指定纹理坐标UV或者需要程序化、自动地给模型贴纹理如投影贴图、地形贴图、物体空间映射。这时就需要使用osg::TexGen——OSG 内置的自动纹理坐标生成器。本文从原理、类继承关系、核心模式、完整可运行代码四个维度彻底讲透osg::TexGen。什么是 osg::TexGenosg::TexGen是 OSG 中用于**自动生成纹理坐标UV**的渲染状态类。它的作用不需要手动设置纹理坐标GPU 根据顶点坐标自动计算 UV。它支持 4 种自动生成模式最常用的是OBJECT_LINEAR物体空间线性映射本文代码使用EYE_LINEAR视角空间线性映射SPHERE_MAP球形环境映射NORMAL_MAP法向映射类继承关系osg::Object所有OSG对象基类 └── osg::StateAttribute渲染状态属性基类 ├── osg::Texture 纹理基类 │ └── osg::Texture2D └── osg::TexGen 自动纹理坐标生成器重要结论TexGen和Texture是同级别的渲染状态它们可以绑定到同一个纹理单元一起工作都由StateSet统一管理TexGen 核心工作模式OBJECT_LINEAR本文代码使用的是OBJECT_LINEAR物体线性模式。原理根据模型自身的局部坐标系物体空间通过平面方程把 3D 顶点坐标 → 自动映射成 2D 纹理坐标。texgen-setMode(osg::TexGen::OBJECT_LINEAR);设置平面决定纹理映射方向texgen-setPlane(osg::TexGen::S,osg::Plane(0.0f,0.0f,1.0f,0.0f));texgen-setPlane(osg::TexGen::T,osg::Plane(1.0f,0.0f,0.0f,0.0f));S 方向 → 映射到 Z 轴T 方向 → 映射到 X 轴完整可运行代码#includeosgViewer/Viewer#includeosg/Node#includeosg/Geode#includeosg/Group#includeosg/Image#includeosg/TexGen#includeosg/Texture2D#includeosg/TexEnv#includeosg/StateSet#includeosg/Plane#includeosgDB/ReadFile#includeosgDB/WriteFile#includeosgUtil/Optimizer#includeiostream// 创建纹理与自动纹理坐标状态osg::ref_ptrosg::StateSetcreateTexture1DState(){// 读取纹理图片osg::ref_ptrosg::ImageimageosgDB::readImageFile(Images/primitives.gif);if(!image.valid()){std::cerr图片加载失败std::endl;returnnullptr;}// 创建2D纹理osg::ref_ptrosg::Texture2Dtexturenewosg::Texture2D();// 设置纹理环绕方式为重复texture-setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT);texture-setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT);// 设置滤波texture-setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);texture-setFilter(osg::Texture::MAG_FILTER,osg::Texture::NEAREST);// 设置图像texture-setImage(image.get());// // 核心自动纹理坐标生成// osg::ref_ptrosg::TexGentexgennewosg::TexGen();texgen-setMode(osg::TexGen::OBJECT_LINEAR);// 物体线性模式// 设置 S、T 生成平面texgen-setPlane(osg::TexGen::S,osg::Plane(0.0f,0.0f,1.0f,0.0f));texgen-setPlane(osg::TexGen::T,osg::Plane(1.0f,0.0f,0.0f,0.0f));// 创建状态集osg::ref_ptrosg::StateSetstatesetnewosg::StateSet();// 启用纹理OVERRIDE表示强制覆盖原有状态stateset-setTextureAttributeAndModes(0,texture,osg::StateAttribute::OVERRIDE);stateset-setTextureMode(0,GL_TEXTURE_2D,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);// 启用自动纹理坐标stateset-setTextureAttributeAndModes(0,texgen,osg::StateAttribute::OVERRIDE);stateset-setTextureMode(0,GL_TEXTURE_GEN_S,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);stateset-setTextureMode(0,GL_TEXTURE_GEN_T,osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);returnstateset;}intmain(){osg::ref_ptrosgViewer::ViewerviewernewosgViewer::Viewer();osg::ref_ptrosg::Grouprootnewosg::Group();// 加载模型cessna.osgosg::ref_ptrosg::NodenodeosgDB::readNodeFile(cessna.osg);if(!node.valid()){std::cout模型加载失败std::endl;return-1;}// 获取纹理状态osg::ref_ptrosg::StateSetstatesetcreateTexture1DState();node-setStateSet(stateset.get());root-addChild(node.get());// 优化场景osgUtil::Optimizer optimizer;optimizer.optimize(root.get());// 运行viewer-setSceneData(root.get());viewer-realize();viewer-run();return0;}代码核心解释1. 创建纹理设置环绕、过滤、图像。2. 创建 TexGentexgen-setMode(osg::TexGen::OBJECT_LINEAR);使用物体空间线性映射。3. 设置映射平面texgen-setPlane(osg::TexGen::S,osg::Plane(0,0,1,0));texgen-setPlane(osg::TexGen::T,osg::Plane(1,0,0,0));S 方向 → Z 轴T 方向 → X 轴4. 启用自动纹理坐标setTextureMode(0,GL_TEXTURE_GEN_S,ON);setTextureMode(0,GL_TEXTURE_GEN_T,ON);告诉 GPUS 和 T 坐标都自动生成5. OVERRIDE 标志强制覆盖模型自带纹理保证我们的贴图生效。总结osg::TexGen自动生成纹理坐标无需手动 UV继承关系继承自StateAttribute与Texture同级OBJECT_LINEAR根据物体空间坐标自动映射纹理使用方法与纹理绑定到同一纹理单元启用GL_TEXTURE_GEN_S/T