查看: 641|回复: 4

设置纹理时,孩子结点与父亲结点关系

[复制链接]

该用户从未签到

发表于 2014-6-19 15:36:28 | 显示全部楼层 |阅读模式
各位大哥:
当一个父节点(下挂多个孩子节点)的纹理设置为某张图片。
  每个孩子的纹理是这张图片的一部分还是 每个孩子的纹理就是一整张图片?

  编写了一个小程序测试,发现每个孩子的纹理就是一整张图片。
  如何使得每个孩子的纹理是这种图片的一部分。 是要设置每个孩子的纹理坐标吗?麻烦哪位大哥给点提示? 多谢。


代码如下,运行结果见附件,图1

  1. #include <osgViewer/Viewer>
  2. #include <osgViewer/ViewerEventHandlers>
  3. #include <osgViewer/api/win32/GraphicsWindowWin32>
  4. #include <osgGA/TrackballManipulator>
  5. #include <osgGA/KeySwitchMatrixManipulator>
  6. #include <osgGA/StateSetManipulator>
  7. #include <osgDB/DatabasePager>
  8. #include <osgDB/Registry>
  9. #include <osgDB/ReadFile>
  10. #include <osgDB/WriteFile>
  11. #include <osgUtil/Optimizer>
  12. #include <osgUtil/SmoothingVisitor>
  13. #include <osg/ShapeDrawable>
  14. #include <osg/Shape>
  15. #include <osg/MatrixTransform>
  16. #include <osg/Transform>
  17. #include <osg/PositionAttitudeTransform>
  18. #include <osg/StateSet>
  19. #include <osg/NodeVisitor>
  20. #include <osg/ImageSequence>
  21. #include <osg/ImageStream>
  22. #include <osg/ClipPlane>
  23. #include <osg/ClipNode>
  24. #include <iostream>
  25. #include<iomanip>
  26. #include<fstream>
  27. #include <vector>
  28. #include <cstring>
  29. #include <string>


  30. int main(int argc, char**argv){
  31.        
  32.         osg::TessellationHints* hints = new osg::TessellationHints;
  33.         hints->setDetailRatio(0.5f);
  34.         hints->setCreateBody(true);
  35.         //hints->setCreateBackFace(true); //必须去除这句话,否则贴图闪烁。
  36.         hints->setCreateBottom(false);
  37.         hints->setCreateTop(false);

  38.         float radius = 5.f;
  39.         float height = 8.f;

  40.         osg::ref_ptr<osg::PositionAttitudeTransform> group = new osg::PositionAttitudeTransform;
  41.         osg::ref_ptr<osg::Geode> genode = new osg::Geode;
  42.         osg::ref_ptr<osg::Geode> genode2 = new osg::Geode;
  43.         osg::ref_ptr<osg::ShapeDrawable> drawable = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0.0f,0.0f,0.0f),radius,height),hints);
  44.         osg::ref_ptr<osg::ShapeDrawable> drawable2 = new osg::ShapeDrawable(new osg::Cylinder(osg::Vec3(0.0f,0.0f,0.0f),radius,height),hints);
  45.         genode->addDrawable(drawable.get());        // geom.get() or gemo. both are ok.
  46.         genode2->addDrawable(drawable2.get());        // geom.get() or gemo. both are ok.

  47.         osg::ref_ptr<osg::MatrixTransform> tans = new osg::MatrixTransform;
  48.         tans->setMatrix(osg::Matrix::translate(0,0,height/2.0));
  49.         tans->addChild(genode.get());
  50.         osg::ref_ptr<osg::MatrixTransform> tans2 = new osg::MatrixTransform;
  51.         tans2->setMatrix(osg::Matrix::translate(0,0,-height/2.0));
  52.         tans2->addChild(genode2.get());
  53.         group->addChild(tans2);
  54.         group->addChild(tans);

  55.         osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
  56.         osg::ref_ptr<osg::Image> image = osgDB::readImageFile("land_shallow_topo_2048.jpg");
  57.        
  58.         texture->setImage(image);
  59.         texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
  60.         texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);       
  61.         texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
  62.         texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);

  63.         osg::StateSet* state = group->getOrCreateStateSet();
  64.         state->setMode( GL_LIGHTING, osg::StateAttribute::OFF |
  65.                 osg::StateAttribute::PROTECTED );
  66.         state->setTextureAttributeAndModes(0,texture.get());
  67.         osgViewer::Viewer viewer;
  68.         viewer.setSceneData(group.get());
  69.         viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
  70.         viewer.addEventHandler(new osgViewer::WindowSizeHandler);
  71.         return viewer.run();
  72. }
复制代码



图1

图1

该用户从未签到

发表于 2014-6-20 10:05:54 | 显示全部楼层
我介绍一个笨办法,修改osg ShapeDrawable的代码:
1. osg::TessellationHints 中增加float _minu; float _maxu;        float _minv;float _maxv; 用于记录该Shape占用的纹理坐标
2. 修改DrawShapeVisitor中的所有gl.TexCoord2f的值 1.0修改成_max, 0.0修改成_min, 0.5修改成(_max-min)/2.0,
    const float texCoordDelta = (_maxu - _minu)/(float)numSegments;
3. 在使用时,设置osg::TessellationHints对应的uv坐标值,就ok啦
效果如下:

效果

效果

该用户从未签到

发表于 2014-6-20 10:09:21 | 显示全部楼层
设置对应的纹理坐标比例

该用户从未签到

发表于 2014-6-20 10:11:32 | 显示全部楼层
不修改osg代码的话,需要重载osg:ShapeDrawable,仅供参考
  1. // Test.cpp : 定义控制台应用程序的入口点。
  2. //

  3. #include "stdafx.h"
  4. #include <osgViewer/Viewer>
  5. #include <osgViewer/ViewerEventHandlers>
  6. #include <osgViewer/api/win32/GraphicsWindowWin32>
  7. #include <osgGA/TrackballManipulator>
  8. #include <osgGA/KeySwitchMatrixManipulator>
  9. #include <osgGA/StateSetManipulator>
  10. #include <osgDB/DatabasePager>
  11. #include <osgDB/Registry>
  12. #include <osgDB/ReadFile>
  13. #include <osgDB/WriteFile>
  14. #include <osgUtil/Optimizer>
  15. #include <osgUtil/SmoothingVisitor>
  16. #include <osg/ShapeDrawable>
  17. #include <osg/Shape>
  18. #include <osg/MatrixTransform>
  19. #include <osg/Transform>
  20. #include <osg/PositionAttitudeTransform>
  21. #include <osg/StateSet>
  22. #include <osg/NodeVisitor>
  23. #include <osg/ImageSequence>
  24. #include <osg/ImageStream>
  25. #include <osg/ClipPlane>
  26. #include <osg/ClipNode>
  27. #include <iostream>
  28. #include<iomanip>
  29. #include<fstream>
  30. #include <vector>
  31. #include <cstring>
  32. #include <string>

  33. const unsigned int MIN_NUM_ROWS = 3;
  34. const unsigned int MIN_NUM_SEGMENTS = 5;
  35. class DrawShapeVisitor : public osg::ConstShapeVisitor
  36. {
  37. public:

  38.         DrawShapeVisitor(osg::State& state,const osg::TessellationHints* hints, float minu = 0.0f, float maxu = 1.0f, float minv = 0.0f, float maxv = 1.0f):
  39.           _state(state),
  40.                   _hints(hints),
  41.                   _minu(minu),
  42.                   _maxu(maxu),
  43.                   _minv(minv),
  44.                   _maxv(maxv)
  45.           {
  46. #if 0
  47.                   if (hints)
  48.                   {
  49.                           OSG_NOTICE<<"Warning: TessellationHints ignored in present osg::ShapeDrawable implementation."<<std::endl;
  50.                   }
  51. #endif
  52.           }

  53.           virtual void apply(const osg::Cylinder&);

  54.           osg::State&                      _state;
  55.           const osg::TessellationHints*    _hints;
  56.           float _minu;
  57.           float _maxu;
  58.           float _minv;
  59.           float _maxv;

  60. protected:

  61.         DrawShapeVisitor& operator = (const DrawShapeVisitor&) { return *this; }

  62.         enum SphereHalf { SphereTopHalf, SphereBottomHalf };

  63.         // helpers for apply( Cylinder | Sphere | Capsule )
  64.         void drawCylinderBody(unsigned int numSegments, float radius, float height);
  65. };


  66. void DrawShapeVisitor::drawCylinderBody(unsigned int numSegments, float radius, float height)
  67. {
  68.         const float angleDelta = 2.0f*osg::PI/(float)numSegments;
  69.         const float texCoordDelta = (_maxu - _minu)/(float)numSegments;

  70.         const float r = radius;
  71.         const float h = height;

  72.         float basez = -h*0.5f;
  73.         float topz = h*0.5f;

  74.         float angle = 0.0f;
  75.         float texCoord = _minu;

  76.         bool drawFrontFace = _hints ? _hints->getCreateFrontFace() : true;
  77.         bool drawBackFace = _hints ? _hints->getCreateBackFace() : false;

  78.         // The only difference between the font & back face loops is that the
  79.         //  normals are inverted and the order of the vertex pairs is reversed.
  80.         //  The code is mostly duplicated in order to hoist the back/front face
  81.         //  test out of the loop for efficiency

  82.         osg::GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();

  83.         gl.Begin(GL_QUAD_STRIP);

  84.         if (drawFrontFace) {

  85.                 for(unsigned int bodyi=0;
  86.                         bodyi<numSegments;
  87.                         ++bodyi,angle+=angleDelta,texCoord+=texCoordDelta)
  88.                 {
  89.                         float c = cosf(angle);
  90.                         float s = sinf(angle);

  91.                         gl.Normal3f(c,s,0.0f);

  92.                         gl.TexCoord2f(texCoord,_maxv);
  93.                         gl.Vertex3f(c*r,s*r,topz);

  94.                         gl.TexCoord2f(texCoord,_minv);
  95.                         gl.Vertex3f(c*r,s*r,basez);
  96.                 }

  97.                 // do last point by hand to ensure no round off errors.
  98.                 gl.Normal3f(1.0f,0.0f,0.0f);

  99.                 gl.TexCoord2f(_maxu,_maxv);
  100.                 gl.Vertex3f(r,0.0f,topz);

  101.                 gl.TexCoord2f(_maxu,_minv);
  102.                 gl.Vertex3f(r,0.0f,basez);
  103.         }

  104.         if (drawBackFace) {
  105.                 for(unsigned int bodyi=0;
  106.                         bodyi<numSegments;
  107.                         ++bodyi,angle+=angleDelta,texCoord+=texCoordDelta)
  108.                 {
  109.                         float c = cosf(angle);
  110.                         float s = sinf(angle);

  111.                         gl.Normal3f(-c,-s,0.0f);

  112.                         gl.TexCoord2f(texCoord,_minv);
  113.                         gl.Vertex3f(c*r,s*r,basez);

  114.                         gl.TexCoord2f(texCoord,_maxv);
  115.                         gl.Vertex3f(c*r,s*r,topz);
  116.                 }

  117.                 // do last point by hand to ensure no round off errors.
  118.                 gl.Normal3f(-1.0f,0.0f,0.0f);

  119.                 gl.TexCoord2f(_maxu,_minv);
  120.                 gl.Vertex3f(r,0.0f,basez);

  121.                 gl.TexCoord2f(_maxu,_maxv);
  122.                 gl.Vertex3f(r,0.0f,topz);
  123.         }

  124.         gl.End();
  125. }

  126. void DrawShapeVisitor::apply(const osg::Cylinder& cylinder)
  127. {
  128.         osg::GLBeginEndAdapter& gl = _state.getGLBeginEndAdapter();

  129.         gl.PushMatrix();

  130.         gl.Translated(cylinder.getCenter().x(),cylinder.getCenter().y(),cylinder.getCenter().z());

  131.         if (!cylinder.zeroRotation())
  132.         {
  133.                 osg::Matrixd rotation(cylinder.computeRotationMatrix());
  134.                 gl.MultMatrixd(rotation.ptr());
  135.         }

  136.         // evaluate hints
  137.         bool createBody = (_hints ? _hints->getCreateBody() : true);
  138.         bool createTop = (_hints ? _hints->getCreateTop() : true);
  139.         bool createBottom = (_hints ? _hints->getCreateBottom() : true);

  140.         unsigned int numSegments = 40;
  141.         float ratio = (_hints ? _hints->getDetailRatio() : 1.0f);
  142.         if (ratio > 0.0f && ratio != 1.0f) {
  143.                 numSegments = (unsigned int) (numSegments * ratio);
  144.                 if (numSegments < MIN_NUM_SEGMENTS)
  145.                         numSegments = MIN_NUM_SEGMENTS;
  146.         }


  147.         // cylinder body
  148.         if (createBody)
  149.                 drawCylinderBody(numSegments, cylinder.getRadius(), cylinder.getHeight());

  150.         float angleDelta = 2.0f*osg::PI/(float)numSegments;
  151.         float texCoordDelta = (_maxu-_minu)/(float)numSegments;
  152.         float halfU = (_maxu-_minu)/2.0f;
  153.         float halfV = (_maxv-_minv)/2.0f;

  154.         float r = cylinder.getRadius();
  155.         float h = cylinder.getHeight();

  156.         float basez = -h*0.5f;
  157.         float topz = h*0.5f;

  158.         float angle = 0.0f;
  159.         float texCoord = _minu;

  160.         // cylinder top
  161.         if (createTop) {
  162.                 gl.Begin(GL_TRIANGLE_FAN);

  163.                 gl.Normal3f(0.0f,0.0f,1.0f);
  164.                 gl.TexCoord2f(0.5f,0.5f);
  165.                 gl.Vertex3f(0.0f,0.0f,topz);

  166.                 angle = 0.0f;
  167.                 texCoord = 0.0f;
  168.                 for(unsigned int topi=0;
  169.                         topi<numSegments;
  170.                         ++topi,angle+=angleDelta,texCoord+=texCoordDelta)
  171.                 {
  172.                         float c = cosf(angle);
  173.                         float s = sinf(angle);

  174.                         gl.TexCoord2f(c*halfU+halfU,s*halfV+halfV);
  175.                         gl.Vertex3f(c*r,s*r,topz);
  176.                 }

  177.                 gl.TexCoord2f(_maxu,halfV);
  178.                 gl.Vertex3f(r,0.0f,topz);

  179.                 gl.End();
  180.         }

  181.         // cylinder bottom
  182.         if (createBottom)
  183.         {
  184.                 gl.Begin(GL_TRIANGLE_FAN);

  185.                 gl.Normal3f(0.0f,0.0f,-1.0f);
  186.                 gl.TexCoord2f(halfU,halfV);
  187.                 gl.Vertex3f(0.0f,0.0f,basez);

  188.                 angle = osg::PI*2.0f;
  189.                 texCoord = _maxu;
  190.                 for(unsigned int bottomi=0;
  191.                         bottomi<numSegments;
  192.                         ++bottomi,angle-=angleDelta,texCoord-=texCoordDelta)
  193.                 {
  194.                         float c = cosf(angle);
  195.                         float s = sinf(angle);

  196.                         gl.TexCoord2f(c*halfU+halfU,s*halfV+halfV);
  197.                         gl.Vertex3f(c*r,s*r,basez);
  198.                 }

  199.                 gl.TexCoord2f(_maxu,halfV);
  200.                 gl.Vertex3f(r,0.0f,basez);

  201.                 gl.End();
  202.         }

  203.         gl.PopMatrix();
  204. }

  205. class ShapeDrawableEx : public osg::ShapeDrawable
  206. {
  207. public:
  208.         ShapeDrawableEx() : _minu(0.0f), _maxu(1.0f), _minv(0.0f), _maxv(1.0f) {}
  209.         ShapeDrawableEx(osg::Shape* shape, osg::TessellationHints* hints=0)
  210.                 : osg::ShapeDrawable(shape, hints), _minu(0.0f), _maxu(1.0f), _minv(0.0f), _maxv(1.0f)
  211.         {}
  212.         ShapeDrawableEx(const ShapeDrawableEx& pg,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY)
  213.                 : osg::ShapeDrawable(pg, copyop), _minu(pg._minu), _maxu(pg._maxu), _minv(pg._minv), _maxv(pg._maxv)
  214.         {}

  215. public:
  216.         inline void setMinU(float v) { _minu=v; }
  217.         inline float getMinU() const { return _minu; }
  218.         inline void setMaxU(float v) { _maxu=v; }
  219.         inline float getMaxU() const { return _maxu; }
  220.         inline void setMinV(float v) { _minv=v; }
  221.         inline float getMinV() const { return _minv; }
  222.         inline void setMaxV(float v) { _maxv=v; }
  223.         inline float getMaxV() const { return _maxv; }

  224. public:
  225.         virtual void drawImplementation(osg::RenderInfo& renderInfo) const
  226.         {
  227.                 osg::State& state = *renderInfo.getState();
  228.                 osg::GLBeginEndAdapter& gl = state.getGLBeginEndAdapter();

  229.                 if (_shape.valid())
  230.                 {
  231.                         gl.Color4fv(_color.ptr());

  232.                         DrawShapeVisitor dsv(state,_tessellationHints.get(), _minu, _maxu, _minv, _maxv);

  233.                         _shape->accept(dsv);
  234.                 }
  235.         }

  236. protected:
  237.         float _minu;
  238.         float _maxu;
  239.         float _minv;
  240.         float _maxv;
  241. };

  242. int _tmain(int argc, _TCHAR* argv[])
  243. {
  244.         osg::TessellationHints* hints = new osg::TessellationHints;
  245.         hints->setDetailRatio(0.5f);
  246.         hints->setCreateBody(true);
  247.         //hints->setCreateBackFace(true); //必须去除这句话,否则贴图闪烁。
  248.         hints->setCreateBottom(false);
  249.         hints->setCreateTop(false);
  250.         hints->setCreateTextureCoords(true);

  251.         float radius = 5.f;
  252.         float height = 8.f;

  253.         osg::ref_ptr<osg::PositionAttitudeTransform> group = new osg::PositionAttitudeTransform;
  254.         osg::ref_ptr<osg::Geode> genode = new osg::Geode;
  255.         osg::ref_ptr<osg::Geode> genode2 = new osg::Geode;       
  256.         osg::ref_ptr<ShapeDrawableEx> drawable = new ShapeDrawableEx(new osg::Cylinder(osg::Vec3(0.0f,0.0f,0.0f),radius,height),hints);
  257.         drawable->setMinV(0.5f);        // 设置纹理坐标
  258.         osg::ref_ptr<ShapeDrawableEx> drawable2 = new ShapeDrawableEx(new osg::Cylinder(osg::Vec3(0.0f,0.0f,0.0f),radius,height),hints);
  259.         drawable2->setMaxV(0.5f);   // 设置纹理坐标
  260.         genode->addDrawable(drawable.get());        // geom.get() or gemo. both are ok.
  261.         genode2->addDrawable(drawable2.get());        // geom.get() or gemo. both are ok.

  262.         osg::ref_ptr<osg::MatrixTransform> tans = new osg::MatrixTransform;
  263.         tans->setMatrix(osg::Matrix::translate(0,0,height/2.0));
  264.         tans->addChild(genode.get());
  265.         osg::ref_ptr<osg::MatrixTransform> tans2 = new osg::MatrixTransform;
  266.         tans2->setMatrix(osg::Matrix::translate(0,0,-height/2.0));
  267.         tans2->addChild(genode2.get());
  268.         group->addChild(tans2);
  269.         group->addChild(tans);

  270.         osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;
  271.         osg::ref_ptr<osg::Image> image = osgDB::readImageFile("land_shallow_topo_2048.png");

  272.         texture->setImage(image);
  273.         texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR);
  274.         texture->setFilter(osg::Texture::MAG_FILTER,osg::Texture::LINEAR);        
  275.         texture->setWrap(osg::Texture::WRAP_S,osg::Texture::CLAMP_TO_EDGE);
  276.         texture->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);

  277.         osg::StateSet* state = group->getOrCreateStateSet();
  278.         state->setMode( GL_LIGHTING, osg::StateAttribute::OFF |
  279.                 osg::StateAttribute::PROTECTED );
  280.         state->setTextureAttributeAndModes(0,texture.get());
  281.         osgViewer::Viewer viewer;
  282.         viewer.setSceneData(group.get());
  283.         viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
  284.         viewer.addEventHandler(new osgViewer::WindowSizeHandler);
  285.         return viewer.run();
  286. }
复制代码

该用户从未签到

 楼主| 发表于 2014-6-21 16:40:31 | 显示全部楼层
xueyu200 发表于 2014-6-20 10:11
不修改osg代码的话,需要重载osg:ShapeDrawable,仅供参考

特别感谢你,你大大的好啊。
还特意写了代码帮测试,thank you  so so  so much.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

OSG中国官方论坛-有您OSG在中国才更好

网站简介:osgChina是国内首个三维相关技术开源社区,旨在为国内更多的技术开发人员提供最前沿的技术资讯,为更多的三维从业者提供一个学习、交流的技术平台。

联系我们

  • 工作时间:09:00--18:00
  • 反馈邮箱:1315785073@qq.com
快速回复 返回顶部 返回列表