osg tree

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/artisans/article/details/78705365
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osg/Geometry>
#include <osg/Texture2D>

#include <osgDB/WriteFile>
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>

#include <osgGA/TrackballManipulator>
#include <osgGA/FlightManipulator>
#include <osgGA/DriveManipulator>
#include <osgGA/KeySwitchMatrixManipulator>
#include <osgGA/StateSetManipulator>
#include <osgGA/AnimationPathManipulator>
#include <osgGA/TerrainManipulator>
#include <osgGA/SphericalManipulator>
#include <iostream>
using namespace std;


class TreePrimitiveSetVisitor : osg::NodeVisitor
{
public:
    TreePrimitiveSetVisitor() : osg::NodeVisitor(NodeVisitor::TRAVERSE_ALL_CHILDREN)
    {
        _tree = osgDB::readNodeFile("tree.osg");
        _tree->accept(*this);
        addShader(_tree->getOrCreateStateSet());
    }


    void addShader(osg::StateSet* ss)
    {
        std::string vertexSource =
            //"#version 140\n"
            "varying vec2 texcoord;\n"
            "uniform int treeNum;\n"
            "uniform  int count;\n" //控制点的个数
            "uniform vec3 arr[4];\n"
            "void main() \n"
            "{ \n"
            "vec3 center;\n"
            "for(int i = 0; i < count; i++)\n"
            "{\n"
            "center += arr[i];\n"
            "}\n"
            "center /= count;"

            "vec2 TMP = vec2(fract(sin(gl_InstanceID)), fract(cos(gl_InstanceID)));"
            "if(TMP.x + TMP.y > 1.0) TMP = vec2(1, 1) - TMP;\n"
            "int index1 = gl_InstanceID / (treeNum / count);\n"
            "int index2 = index1 + 1;\n"
            "if(index2 >= count)\n"
            "{\n"
            "index1 = 0; index2 =  count - 1; "
            "}\n"
            "vec4 pos;\n"
            "vec3 ab = arr[index1] - center;\n"
            "vec3 ac = arr[index2] - center;\n"
            "vec3 PT = center + ab * TMP.x + ac * TMP.y;\n"
            "pos = gl_Vertex + vec4(PT, 1);\n"

            "pos = gl_Vertex +  vec4(arr[gl_InstanceID % 4], 1);\n"
            //"pos = gl_Vertex + vec4(1, 1, 1, 1);\n"

            //"int x = gl_InstanceID %  100; int y = gl_InstanceID / 100;"
            //"pos = gl_Vertex + x * vec4(10, 0, 0, 0) + y * vec4(0, 10, 0, 0); \n"

            "gl_Position = ( gl_ModelViewProjectionMatrix * pos); \n"
            "texcoord = gl_MultiTexCoord0.st;"
            "} \n";

        osg::ref_ptr< osg::Shader > vertexShader = new osg::Shader();
        vertexShader->setType(osg::Shader::VERTEX);
        vertexShader->setShaderSource(vertexSource);

        std::string fragSource =
            //"#version 140\n"
            "varying vec2 texcoord;\n"
            "uniform sampler2D baseTexture; \n"
            "void main()\n"
            "{\n"
            "   vec4 finalColor = texture2D( baseTexture, texcoord); \n"
            "   gl_FragColor = vec4(finalColor.rgba);\n"
            "}\n";

        osg::ref_ptr< osg::Shader > fragShader = new osg::Shader();
        fragShader->setType(osg::Shader::FRAGMENT);
        fragShader->setShaderSource(fragSource);

        {
            osg::ref_ptr<osg::Uniform> treeNum = new osg::Uniform("treeNum", 10000);
            ss->addUniform(treeNum);

            vector<osg::Vec3> arr;
            arr.push_back(osg::Vec3(-100, -100, 0));
            arr.push_back(osg::Vec3(10, 0, 0));
            arr.push_back(osg::Vec3(10, 10, 0));
            arr.push_back(osg::Vec3(0, 10, 0));

            osg::ref_ptr<osg::Uniform> count = new osg::Uniform("count", arr.size());
            ss->addUniform(count);

            osg::ref_ptr<osg::Uniform> TMP = new osg::Uniform(osg::Uniform::FLOAT_VEC3, "arr", arr.size());
            ss->addUniform(TMP);
        }

        osg::ref_ptr< osg::Program > program = new osg::Program();
        program->addShader(vertexShader.get());
        program->addShader(fragShader.get());

        ss->setAttribute(program.get(), osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE | osg::StateAttribute::PROTECTED);
        _tree->dirtyBound();
    }

    virtual void apply(osg::Geometry& geometry) override
    {
        cout << "geometry  " << geometry.getName() << endl;
        traverse(geometry);

        geometry.setUseDisplayList(false);
        geometry.setUseVertexBufferObjects(true);
        float minVal = -100;
        float maxVal = 100;
        osg::BoundingBox bb(minVal, minVal, minVal, maxVal, maxVal, maxVal);
        geometry.setInitialBound(bb);

        for (unsigned i = 0; i < geometry.getPrimitiveSetList().size(); i++)
        {
            osg::PrimitiveSet* ps = geometry.getPrimitiveSet(i);
            ps->setNumInstances(10000);
        }
    }

    virtual void apply(osg::Node& node) override
    {
        cout << "node   " << node.getName() << endl;
        traverse(node);
    }

public:
    osg::Node* _tree;
};



int main(int argc, char **argv)
{
    osg::ArgumentParser arguments(&argc, argv);

    TreePrimitiveSetVisitor tps;

    osgViewer::Viewer viewer(arguments);
    viewer.setSceneData(tps._tree);
    viewer.addEventHandler(new osgViewer::WindowSizeHandler);

    // add the stats handler
    viewer.addEventHandler(new osgViewer::StatsHandler);

    // add the help handler
    viewer.addEventHandler(new osgViewer::HelpHandler(arguments.getApplicationUsage()));

    // add the record camera path handler
    viewer.addEventHandler(new osgViewer::RecordCameraPathHandler);

    // add the LOD Scale handler
    viewer.addEventHandler(new osgViewer::LODScaleHandler);

    // add the screen capture handler
    viewer.addEventHandler(new osgViewer::ScreenCaptureHandler);
    viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));
    viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::COMPUTE_NEAR_USING_PRIMITIVES);
    //viewer.getCamera()->setNearFarRatio(0.0003f);
    viewer.getCamera()->setProjectionMatrixAsPerspective(60.0f, 1.33333, 0.01, 100000.0);

    osgDB::writeNodeFile(*tps._tree, "abc.osg");

    return viewer.run();
}

猜你喜欢

转载自blog.csdn.net/artisans/article/details/78705365