zoukankan      html  css  js  c++  java
  • 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();
    }
  • 相关阅读:
    mysql索引
    springboot mybatis 后台框架平台 shiro 权限 集成代码生成器
    java 企业网站源码模版 有前后台 springmvc SSM 生成静态化
    java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis
    activiti工作流的web流程设计器整合视频教程 SSM和独立部署
    .Net Core中的ObjectPool
    文件操作、流相关类梳理
    .Net Core中的配置文件源码解析
    .Net Core中依赖注入服务使用总结
    消息中间件RabbitMQ(一)
  • 原文地址:https://www.cnblogs.com/airduce/p/9783837.html
Copyright © 2011-2022 走看看