• osg渲染一个房子的四壁(有纹理)


     1 /* -*-c++-*- Copyright (C) 2009 Wang Rui <wangray84 at gmail dot com>
     2  * OpenSceneGraph Engine Book - Design and Implementation
     3  * How to create a geometric house
     4 */
     5 
     6 #include <osg/Texture2D>
     7 #include <osg/Geometry>
     8 #include <osg/Geode>
     9 #include <osgDB/ReadFile>
    10 #include <osgUtil/SmoothingVisitor>
    11 #include <osgViewer/Viewer>
    12 
    13 osg::Drawable* createHouseWall()
    14 {
    15     // House vertices
    16     osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
    17     //前面
    18     vertices->push_back( osg::Vec3( 0.0, 0.0, 4.0) );  // 0
    19     vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0) );  // 1
    20     vertices->push_back( osg::Vec3( 6.0, 0.0, 4.0) );  // 2
    21     vertices->push_back( osg::Vec3( 6.0, 0.0, 0.0) );  // 3
    22     //右面
    23     vertices->push_back( osg::Vec3( 6.0, 4.0, 4.0) );  // 4
    24     vertices->push_back( osg::Vec3( 6.0, 4.0, 0.0) );  // 5
    25     //后面
    26     vertices->push_back( osg::Vec3( 0.0, 4.0, 4.0) );  // 6
    27     vertices->push_back( osg::Vec3( 0.0, 4.0, 0.0) );  // 7
    28     //左面
    29     vertices->push_back( osg::Vec3( 0.0, 0.0, 4.0) );  // 8
    30     vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0) );  // 9
    31     
    32     // House normals
    33     osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array( 10 );
    34     //左前
    35     (*normals)[0].set(-1.0,1.0, 0.0 );
    36     (*normals)[1].set(-1.0,1.0, 0.0 );
    37     //右前
    38    // (*normals)[2].set( 1.0,-1.0, 0.0 );
    39    // (*normals)[3].set( 1.0,-1.0, 0.0 );
    40     //右后
    41     (*normals)[4].set( 1.0, 1.0, 0.0 );
    42     (*normals)[5].set( 1.0, 1.0, 0.0 );
    43     //左后
    44     //(*normals)[6].set(-1.0, 1.0, 0.0 );
    45     //(*normals)[7].set(-1.0, 1.0, 0.0 );
    46     //左前
    47     //(*normals)[8].set(-1.0,-1.0, 0.0 );
    48     //(*normals)[9].set(-1.0,-1.0, 0.0 );
    49     
    50     // House texture coordinates
    51     osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array( 10 );
    52     //前面的左0.3
    53     (*texcoords)[0].set( 0.0, 1.0 );
    54     (*texcoords)[1].set( 0.0, 0.0 );
    55     (*texcoords)[2].set( 0.3, 1.0 );
    56     (*texcoords)[3].set( 0.3, 0.0 );
    57 
    58     //右面0.2
    59     (*texcoords)[4].set( 0.5, 1.0 );
    60     (*texcoords)[5].set( 0.5, 0.0 );
    61 
    62     //后面0.3
    63     (*texcoords)[6].set( 0.8, 1.0 );
    64     (*texcoords)[7].set( 0.8, 0.0 );
    65     //左边0.2
    66     (*texcoords)[8].set( 1.0, 1.0 );
    67     (*texcoords)[9].set( 1.0, 0.0 );
    68     
    69     // Create wall geometry
    70     osg::ref_ptr<osg::Geometry> houseWall = new osg::Geometry;
    71     houseWall->setVertexArray( vertices.get() );
    72     houseWall->setTexCoordArray( 0, texcoords.get() );
    73     houseWall->setNormalArray( normals.get() );
    74     houseWall->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
    75     houseWall->addPrimitiveSet( new osg::DrawArrays(osg::DrawArrays::QUAD_STRIP, 0, 10) );
    76     
    77     houseWall->getOrCreateStateSet()->setTextureAttributeAndModes( 0,
    78         new osg::Texture2D(osgDB::readImageFile("C:\wall.png")) );
    79     return houseWall.release();
    80 }
    81 
    82 int main( int argc, char** argv )
    83 {
    84     osg::ref_ptr<osg::Geode> geode = new osg::Geode;
    85     geode->addDrawable( createHouseWall() );
    86    // geode->addDrawable( createHouseRoof() );
    87     
    88     osgViewer::Viewer viewer;
    89     viewer.setSceneData( geode.get() );
    90     return viewer.run();
    91 }

    所用的纹理:
      

    运行效果(为了观察法线对灯光的影响,注释掉30行到40行相应的代码。改掉左前的法线方向,其影响是房子的里面亮了,如下图):

      

    运行效果(没有纹理):

      

    带有环境光、散射光,指定光源位置,有多个纹理

    效果:

      

    代码实现:

    /* -*-c++-*- Copyright (C) 2009 Wang Rui <wangray84 at gmail dot com>
     * OpenSceneGraph Engine Book - Design and Implementation
     * How to create a geometric house
    */
    
    #include <osg/Texture2D>
    #include <osg/Geometry>
    #include <osg/Geode>
    #include <osgDB/ReadFile>
    #include <osgUtil/SmoothingVisitor>
    #include <osgViewer/Viewer>
    #include <osg/PositionAttitudeTransform>
    #include <osg/MatrixTransform>
    //回调函数,让其不断的旋转
    class RotateCallback : public osg::NodeCallback
    {
    public:
        RotateCallback() : _rotateZ(0.0) {}
    
        virtual void operator()( osg::Node* node, osg::NodeVisitor* nv )
        {
            osg::PositionAttitudeTransform* pat = dynamic_cast<osg::PositionAttitudeTransform*>( node );
            if ( pat )
            {
                osg::Quat quat( osg::DegreesToRadians(_rotateZ), osg::Z_AXIS );
                pat->setAttitude( quat );
                _rotateZ += 1.0;
            }
            traverse( node, nv );//访问器的下一个节点
        }
    
    protected:
        double _rotateZ;
    };
    //向场景中添加光源
    osg::ref_ptr<osg::Group> createLight(osg::ref_ptr<osg::Node> node)
    {
        osg::ref_ptr<osg::Group> lightRoot= new osg::Group();
        //lightRoot->addChild(node);
    
        //开启光照
        osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();
        stateset = lightRoot->getOrCreateStateSet();
        stateset->setMode(GL_LIGHTING,osg::StateAttribute::ON);
        stateset->setMode(GL_LIGHT0,osg::StateAttribute::ON);
    
        //创建一个Light对象
        osg::ref_ptr<osg::Light> light = new osg::Light();
        light->setLightNum(0);
        //设置方向
        light->setDirection(osg::Vec3(0.0f,1.0f,-1.0f));
        //设置位置
        light->setPosition(osg::Vec4(0,-10,8,1.0f));
        //设置环境光的颜色
        light->setAmbient(osg::Vec4(0.1f,0.1f,0.1f,1.0f));
        //设置散射光的颜色
        light->setDiffuse(osg::Vec4(1.0f,1.0f,1.0f,1.0f));
    
         ////设置恒衰减指数
         //light->setConstantAttenuation(1.0f);
         ////设置线形衰减指数
         //light->setLinearAttenuation(0.0f);
         ////设置二次方衰减指数
         //light->setQuadraticAttenuation(0.0f);
    
        //创建光源
        osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource();
        lightSource->setLight(light.get());
    
        lightRoot->addChild(lightSource.get());
    
        return lightRoot.get() ;
    }
    osg::Drawable* createHouseWall()
    {
        // House vertices
        osg::ref_ptr<osg::Vec3Array> vertices = new osg::Vec3Array;
        //前面
        vertices->push_back( osg::Vec3( 0.0, 0.0, 4.0) );  // 0
        vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0) );  // 1
        vertices->push_back( osg::Vec3( 4.0, 0.0, 4.0) );  // 2
        vertices->push_back( osg::Vec3( 4.0, 0.0, 0.0) );  // 3
        //右面
        vertices->push_back( osg::Vec3( 4.0, 4.0, 4.0) );  // 4
        vertices->push_back( osg::Vec3( 4.0, 4.0, 0.0) );  // 5
        //后面
        vertices->push_back( osg::Vec3( 0.0, 4.0, 4.0) );  // 6
        vertices->push_back( osg::Vec3( 0.0, 4.0, 0.0) );  // 7
        //左面
        vertices->push_back( osg::Vec3( 0.0, 0.0, 4.0) );  // 8
        vertices->push_back( osg::Vec3( 0.0, 0.0, 0.0) );  // 9
        
        // House normals
        osg::ref_ptr<osg::Vec3Array> normals = new osg::Vec3Array( 10 );
        //左前
        (*normals)[0].set(-1.0,-1.0, 0.0 );
        (*normals)[1].set(-1.0,-1.0, 0.0 );
        //右前
        (*normals)[2].set( 1.0,-1.0, 0.0 );
        (*normals)[3].set( 1.0,-1.0, 0.0 );
        //右后
        (*normals)[4].set( 1.0, 1.0, 0.0 );
        (*normals)[5].set( 1.0, 1.0, 0.0 );
        //左后
        (*normals)[6].set(-1.0, 1.0, 0.0 );
        (*normals)[7].set(-1.0, 1.0, 0.0 );
        //左前
        (*normals)[8].set(-1.0,-1.0, 0.0 );
        (*normals)[9].set(-1.0,-1.0, 0.0 );
        
        // House texture coordinates
        osg::ref_ptr<osg::Vec2Array> texcoords = new osg::Vec2Array( 10 );
        //前面的左0.3
        (*texcoords)[0].set( 0.0, 1.0 );
        (*texcoords)[1].set( 0.0, 0.0 );
        (*texcoords)[2].set( 1.0, 1.0 );
        (*texcoords)[3].set( 1.0, 0.0 );
    
        //右面0.2
        /*   (*texcoords)[4].set( 0.0, 1.0 );
        (*texcoords)[5].set( 0.0, 0.0 );
    
        //后面0.3
        (*texcoords)[6].set( 1.0, 1.0 );
        (*texcoords)[7].set( 1.0, 0.0 );
        //左边0.2
        (*texcoords)[8].set( 0.0, 1.0 );
        (*texcoords)[9].set( 0.0, 0.0 );*/
    
        // House texture coordinates
        osg::ref_ptr<osg::Vec2Array> texcoords2 = new osg::Vec2Array( 10 );
    
    
          //右面0.2
    
        (*texcoords2)[4].set( 0.0, 1.0 );
        (*texcoords2)[5].set( 0.0, 0.0 );
        
    
        //后面0.3
        (*texcoords2)[6].set( 1.0, 1.0 );
        (*texcoords2)[7].set( 1.0, 0.0 );
        //左边0.2
        (*texcoords2)[8].set( 0.0, 1.0 );
        (*texcoords2)[9].set( 0.0, 0.0 );
    
        
        // Create wall geometry
        osg::ref_ptr<osg::Geometry> houseWall = new osg::Geometry;
        houseWall->setVertexArray( vertices.get() );
        houseWall->setTexCoordArray( 0, texcoords.get() );
         houseWall->setTexCoordArray( 1, texcoords2.get() );
        houseWall->setNormalArray( normals.get() );
        houseWall->setNormalBinding( osg::Geometry::BIND_PER_VERTEX );
        houseWall->addPrimitiveSet( new osg::DrawArrays(osg::DrawArrays::QUAD_STRIP, 0, 10) );
        
        houseWall->getOrCreateStateSet()->setTextureAttributeAndModes( 0,new osg::Texture2D(osgDB::readImageFile("C:\22.jpg")) );
    
         houseWall->getOrCreateStateSet()->setTextureAttributeAndModes( 1,new osg::Texture2D(osgDB::readImageFile("C:\55.jpg")) );
    
        return houseWall.release();
    }
    
    int main( int argc, char** argv )
    {
    
        osg::Group *root = new osg::Group;
        osg::ref_ptr<osg::Geode> geode = new osg::Geode;
        geode->addDrawable( createHouseWall() );
        
    
        osg::ref_ptr<osg::PositionAttitudeTransform> pat = new osg::PositionAttitudeTransform;
        pat->addChild( geode );
        pat->setUpdateCallback( new RotateCallback );
    
        root->addChild(pat);
        root->addChild(createLight(geode.get()));
        osgViewer::Viewer viewer;
        viewer.setUpViewInWindow(20,20,400,400);
        viewer.setSceneData(root);
        return viewer.run();
    }
  • 相关阅读:
    开发进度1
    人月神话阅读笔记(1)
    仓库管理系统
    课程管理系统教程
    流与文件课后作业2加解密工作
    流与文件课后作业3
    今日学习时间记录
    Java字符串切片
    java_ 集合
    json基础教程|理解Json
  • 原文地址:https://www.cnblogs.com/airduce/p/9783837.html
Copyright © 2020-2023  润新知