#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();
}
osg tree
最新推荐文章于 2022-11-30 18:19:33 发布