Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2017
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.41 KB | None | 0 0
  1. /* OpenSceneGraph example, osgdrawinstanced.
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  13. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  14. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  15. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  16. * THE SOFTWARE.
  17. */
  18. //
  19. // This code is copyright (c) 2008 Skew Matrix Software LLC. You may use
  20. // the code under the licensing terms described above.
  21. //
  22.  
  23. #include <osgDB/ReadFile>
  24. #include <osgViewer/Viewer>
  25. #include <osg/Geometry>
  26. #include <osg/Texture2D>
  27. #include <osgEarth/Random>
  28. #include <osgViewer/ViewerEventHandlers>
  29. #include <osgGA/TrackballManipulator>
  30. #include <osg/Point>
  31.  
  32. #include <osgDB/WriteFile>
  33.  
  34. #include <iostream>
  35.  
  36. #define TEXTURE_DIM 2048
  37.  
  38.  
  39. struct NotifyCameraPostDrawCallback : public osg::Camera::DrawCallback
  40. {
  41. NotifyCameraPostDrawCallback(const std::string& message):
  42. _message(message)
  43. {
  44. }
  45.  
  46. virtual void operator () (osg::RenderInfo& renderInfo) const
  47. {
  48. OE_NOTICE << _message << std::endl;
  49. }
  50.  
  51. std::string _message;
  52. };
  53.  
  54. void
  55. createDAIGeometry( osg::Geometry& geom, int nInstances=1 )
  56. {
  57. osg::Vec3Array* v = new osg::Vec3Array;
  58. v->resize( 1 );
  59. geom.setVertexArray( v );
  60.  
  61. // Geometry for a single quad.
  62. (*v)[ 0 ] = osg::Vec3( 0.0, 0.0, 0.0 );
  63.  
  64. // Use the DrawArraysInstanced PrimitiveSet and tell it to draw 1024 instances.
  65. geom.addPrimitiveSet( new osg::DrawArrays( GL_POINTS, 0, 1, nInstances ) );
  66.  
  67. geom.setInitialBound(osg::BoundingBox(osg::Vec3(-5000.0, -5000.0, -5000.0), osg::Vec3(5000.0, 5000.0, 5000.0)));
  68.  
  69. }
  70.  
  71. osg::Texture2D* createPositionTexture()
  72. {
  73. osgEarth::Random random;
  74.  
  75. osg::Image* positionImage = new osg::Image;
  76. positionImage->allocateImage(TEXTURE_DIM,TEXTURE_DIM,1, GL_RGBA, GL_FLOAT);
  77. positionImage->setInternalTextureFormat(GL_RGBA32F_ARB);
  78. GLfloat* ptr = reinterpret_cast<GLfloat*>( positionImage->data() );
  79.  
  80.  
  81. for (unsigned int i = 0; i < TEXTURE_DIM * TEXTURE_DIM; i++)
  82. {
  83. /*
  84. float x = -500.0 + random.next() * 1000.0;
  85. float y = -500.0 + random.next() * 1000.0;
  86. float z = -500.0 + random.next() * 1000.0;
  87. */
  88.  
  89. // Start in the center and eminate out.
  90. float x = 0.0;
  91. float y = 0.0;
  92. float z = 0.0;
  93.  
  94. //OSG_NOTICE << x << ", " << y << ", " << z << std::endl;
  95.  
  96. *ptr++ = x;
  97. *ptr++ = y;
  98. *ptr++ = z;
  99. // Random life
  100. *ptr++ = random.next();
  101. }
  102.  
  103. osg::Texture2D* tex = new osg::Texture2D( positionImage );
  104. tex->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT);
  105. tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST );
  106. tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST );
  107. return tex;
  108. }
  109.  
  110. osg::Texture2D* createDirectionTexture()
  111. {
  112. osgEarth::Random random;
  113.  
  114. osg::Image* positionDirection = new osg::Image;
  115. positionDirection->allocateImage(TEXTURE_DIM,TEXTURE_DIM,1, GL_RGBA, GL_FLOAT);
  116. positionDirection->setInternalTextureFormat(GL_RGBA32F_ARB);
  117. GLfloat* ptr = reinterpret_cast<GLfloat*>( positionDirection->data() );
  118.  
  119. float minTheta = 0.0;
  120. float maxTheta = 0.5f*osg::PI_4;
  121. float minPhi = 0.0;
  122. float maxPhi = 2*osg::PI;
  123.  
  124. for (unsigned int i = 0; i < TEXTURE_DIM * TEXTURE_DIM; i++)
  125. {
  126. // Initial velocity
  127. float velocity = random.next() * 50.0;
  128.  
  129. // Circle
  130. //float x = -0.5 + random.next();
  131. //float y = -0.5 + random.next();
  132. //float z = -0.5 + random.next();
  133.  
  134. /*
  135. float x = random.next();
  136. float y = random.next();
  137. float z = random.next();
  138. */
  139.  
  140.  
  141. float theta = minTheta + (maxTheta - minTheta) * random.next();
  142. float phi = minPhi + (maxPhi - minPhi) * random.next();
  143.  
  144. float x = velocity * sinf(theta) * cosf(phi);
  145. float y = velocity * sinf(theta) * sinf(phi);
  146. float z = velocity * cosf(theta);
  147.  
  148. // Initial velocity
  149. float acceleration = random.next() * 100.0;
  150.  
  151. osg::Vec3 dir(x, y, z);
  152.  
  153. *ptr++ = dir.x();
  154. *ptr++ = dir.y();
  155. *ptr++ = dir.z();
  156. *ptr++ = acceleration;
  157. }
  158.  
  159. osg::Texture2D* tex = new osg::Texture2D( positionDirection );
  160. tex->setInternalFormatMode(osg::Texture::USE_IMAGE_DATA_FORMAT);
  161. tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST );
  162. tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST );
  163. return tex;
  164. }
  165.  
  166.  
  167. osg::Node* makeQuad(int width, int height, const osg::Vec4& color)
  168. {
  169. osg::Geometry *geometry = new osg::Geometry;
  170. osg::Vec3Array* verts = new osg::Vec3Array();
  171. verts->push_back(osg::Vec3(0,0,0));
  172. verts->push_back(osg::Vec3(width, 0, 0));
  173. verts->push_back(osg::Vec3(width,height,0));
  174. verts->push_back(osg::Vec3(0, height, 0));
  175. geometry->setVertexArray(verts);
  176. osg::Vec4Array* colors = new osg::Vec4Array();
  177. colors->push_back(color);
  178. geometry->setColorArray(colors);
  179. geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
  180. geometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, verts->size()));
  181. osg::Geode* geode = new osg::Geode;
  182. geode->addDrawable(geometry);
  183. return geode;
  184. }
  185.  
  186.  
  187. std::string computeVert =
  188. "void main() \n"
  189. "{ \n"
  190. " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
  191. "} \n";
  192.  
  193. std::string computeFrag =
  194. "uniform sampler2D texturePosition; \n"
  195. "uniform sampler2D textureVelocity; \n"
  196. "uniform float osg_DeltaSimulationTime; \n"
  197. "uniform float osg_SimulationTime; \n"
  198. "uniform vec2 resolution;\n"
  199.  
  200. "uniform vec3 gravity;\n"
  201.  
  202. // Generate a pseudo-random value in the specified range:
  203. "float\n"
  204. "oe_random(float minValue, float maxValue, vec2 co)\n"
  205. "{\n"
  206. " float t = fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);\n"
  207. " return minValue + t*(maxValue-minValue);\n"
  208. "}\n"
  209.  
  210.  
  211. "void main() \n"
  212. "{ \n"
  213. " vec2 uv = gl_FragCoord.xy / resolution.xy;\n"
  214.  
  215. " vec4 positionInfo = texture2D( texturePosition, uv );\n"
  216. " vec4 velocityInfo = texture2D( textureVelocity, uv );\n"
  217.  
  218. " vec3 position = positionInfo.xyz;\n"
  219. " float life = positionInfo.w;\n"
  220. " vec3 velocity = velocityInfo.xyz;\n"
  221.  
  222. // Apply various forces to compute a new velocity
  223.  
  224. // Gravity
  225. //" velocity = velocity + vec3(0.0, 0.0, -9.8) * osg_DeltaSimulationTime;\n"
  226. " velocity = velocity + gravity * osg_DeltaSimulationTime;\n"
  227.  
  228. // Compute the new position based on the velocity
  229. " position = position + velocity * osg_DeltaSimulationTime;\n"
  230.  
  231. // Compute the new velocity based on the acceleration
  232. //" velocity = velocity + acceleration * osg_DeltaSimulationTime;\n"
  233.  
  234. " life -= osg_DeltaSimulationTime / 20.0f;\n"
  235. // Reset particle
  236. " if (life < 0.0) {\n"
  237. " life = oe_random(0.0, 1.0, vec2(position.x, position.y));\n"
  238. " float initialVelocity = oe_random(50.0, 250.0, vec2(position.y, position.z));\n"
  239. " float x = oe_random(-0.5, 0.5, vec2(position.x, position.y));\n"
  240. " float y = oe_random(-0.5, 0.5, vec2(position.y, position.x));\n"
  241. " float z = 1.0;//oe_random(-0.5, 0.5, vec2(position.x, position.z));\n"
  242. " velocity = initialVelocity * normalize(vec3(x, y, z));\n"
  243. " position = vec3(0.0, 0.0, 0.0);\n"
  244. " }\n"
  245.  
  246.  
  247. // Write out the new position
  248. //" gl_FragColor = vec4(position, life);\n"
  249. //" gl_FragColor = vec4(position, velocity);\n"
  250. " gl_FragData[0] = vec4(position, life);\n"
  251. " gl_FragData[1] = vec4(velocity, 1.0);\n"
  252. "} \n";
  253.  
  254.  
  255. // Helper node that will run a fragment shader, taking one texture as input and writing to another texture.
  256. // And then it flips on each frame to use the previous input.
  257. class ComputeNode : public osg::Group
  258. {
  259. public:
  260. ComputeNode():
  261. _size(TEXTURE_DIM)
  262. {
  263. _inputPosition = createPositionTexture();
  264. _outputPosition = createPositionTexture();
  265. _velocityInput = createDirectionTexture();
  266. _velocityOutput = createDirectionTexture();
  267.  
  268. buildCamera();
  269. }
  270.  
  271. osg::StateSet* createStateSet()
  272. {
  273. osg::Program* program = new osg::Program;
  274. program->addShader(new osg::Shader(osg::Shader::VERTEX, computeVert));
  275. program->addShader(new osg::Shader(osg::Shader::FRAGMENT, computeFrag));
  276. osg::StateSet* ss = new osg::StateSet;
  277. ss->setAttributeAndModes(program);
  278.  
  279. ss->addUniform(new osg::Uniform("texturePosition", 0 ));
  280. ss->addUniform(new osg::Uniform("textureVelocity", 1 ));
  281.  
  282. ss->addUniform(new osg::Uniform( "resolution", osg::Vec2f(_size, _size)));
  283.  
  284. // Use the input texture as texture 0
  285. ss->setTextureAttributeAndModes(0, _inputPosition.get(), osg::StateAttribute::ON);
  286. ss->setTextureAttributeAndModes(1, _velocityInput.get(), osg::StateAttribute::ON);
  287.  
  288. return ss;
  289. }
  290.  
  291. osg::Camera* createRTTCamera()
  292. {
  293. osg::Camera* camera = new osg::Camera;
  294.  
  295. camera->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  296.  
  297. // set view
  298. camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
  299.  
  300. // set viewport
  301. camera->setViewport(0,0, _size, _size );
  302.  
  303. // set the camera to render before the main camera.
  304. camera->setRenderOrder(osg::Camera::PRE_RENDER);
  305.  
  306. // tell the camera to use OpenGL frame buffer object where supported.
  307. camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
  308.  
  309. // set up projection.
  310. camera->setProjectionMatrixAsOrtho2D(0.0, _size, 0.0, _size);
  311. camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
  312.  
  313. // Make a full screen quad
  314. _quad = makeQuad(_size, _size, osg::Vec4(1,1,1,1));
  315. _quad->setCullingActive(false);
  316. _quad->setStateSet(createStateSet());
  317. camera->addChild( _quad );
  318.  
  319. return camera;
  320. }
  321.  
  322. void buildCamera()
  323. {
  324. if (_camera.valid())
  325. {
  326. removeChild(_camera.get());
  327. }
  328. _camera = createRTTCamera();
  329. // Use the color buffer.
  330. //_camera->attach( osg::Camera::COLOR_BUFFER, _outputPosition, 0, 0, false );
  331. _camera->attach( osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), _outputPosition);
  332. _camera->attach( osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER1), _velocityOutput);
  333. addChild(_camera.get());
  334. }
  335.  
  336. void swap()
  337. {
  338. // Swap the positions
  339. osg::ref_ptr< osg::Texture2D > tmp = _inputPosition.get();
  340. _inputPosition = _outputPosition.get();
  341. _outputPosition = tmp.get();
  342.  
  343. // Swap the velocities
  344. tmp = _velocityInput.get();
  345. _velocityInput = _velocityOutput.get();
  346. _velocityOutput = tmp.get();
  347.  
  348. buildCamera();
  349. }
  350.  
  351. osg::ref_ptr< osg::Texture2D > _inputPosition;
  352. osg::ref_ptr< osg::Texture2D > _outputPosition;
  353. osg::ref_ptr< osg::Texture2D > _velocityInput;
  354. osg::ref_ptr< osg::Texture2D > _velocityOutput;
  355. osg::ref_ptr< osg::Camera > _camera;
  356. osg::ref_ptr<osg::Node> _quad;
  357.  
  358. unsigned int _size;
  359. };
  360.  
  361.  
  362. osg::Node* createBase(const osg::Vec3& center,float radius)
  363. {
  364. int numTilesX = 10;
  365. int numTilesY = 10;
  366.  
  367. float width = 2*radius;
  368. float height = 2*radius;
  369.  
  370. osg::Vec3 v000(center - osg::Vec3(width*0.5f,height*0.5f,0.0f));
  371. osg::Vec3 dx(osg::Vec3(width/((float)numTilesX),0.0,0.0f));
  372. osg::Vec3 dy(osg::Vec3(0.0f,height/((float)numTilesY),0.0f));
  373.  
  374. // fill in vertices for grid, note numTilesX+1 * numTilesY+1...
  375. osg::Vec3Array* coords = new osg::Vec3Array;
  376. int iy;
  377. for(iy=0;iy<=numTilesY;++iy)
  378. {
  379. for(int ix=0;ix<=numTilesX;++ix)
  380. {
  381. coords->push_back(v000+dx*(float)ix+dy*(float)iy);
  382. }
  383. }
  384.  
  385. //Just two colours - black and white.
  386. osg::Vec4Array* colors = new osg::Vec4Array;
  387. colors->push_back(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); // white
  388. colors->push_back(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); // black
  389.  
  390. osg::ref_ptr<osg::DrawElementsUShort> whitePrimitives = new osg::DrawElementsUShort(GL_QUADS);
  391. osg::ref_ptr<osg::DrawElementsUShort> blackPrimitives = new osg::DrawElementsUShort(GL_QUADS);
  392.  
  393. int numIndicesPerRow=numTilesX+1;
  394. for(iy=0;iy<numTilesY;++iy)
  395. {
  396. for(int ix=0;ix<numTilesX;++ix)
  397. {
  398. osg::DrawElementsUShort* primitives = ((iy+ix)%2==0) ? whitePrimitives.get() : blackPrimitives.get();
  399. primitives->push_back(ix +(iy+1)*numIndicesPerRow);
  400. primitives->push_back(ix +iy*numIndicesPerRow);
  401. primitives->push_back((ix+1)+iy*numIndicesPerRow);
  402. primitives->push_back((ix+1)+(iy+1)*numIndicesPerRow);
  403. }
  404. }
  405.  
  406. // set up a single normal
  407. osg::Vec3Array* normals = new osg::Vec3Array;
  408. normals->push_back(osg::Vec3(0.0f,0.0f,1.0f));
  409.  
  410. osg::Geometry* geom = new osg::Geometry;
  411. geom->setVertexArray(coords);
  412.  
  413. geom->setColorArray(colors, osg::Array::BIND_PER_PRIMITIVE_SET);
  414.  
  415. geom->setNormalArray(normals, osg::Array::BIND_OVERALL);
  416.  
  417. geom->addPrimitiveSet(whitePrimitives.get());
  418. geom->addPrimitiveSet(blackPrimitives.get());
  419.  
  420. osg::Geode* geode = new osg::Geode;
  421. geode->addDrawable(geom);
  422.  
  423. return geode;
  424. }
  425.  
  426.  
  427. osg::StateSet*
  428. createStateSet()
  429. {
  430. osg::ref_ptr< osg::StateSet > ss = new osg::StateSet;
  431.  
  432. // Create a vertex program that references the gl_InstanceID to
  433. // render each instance uniquely. gl_InstanceID will be in the range
  434. // 0 to numInstances-1 (1023 in our case).
  435. std::string vertexSource =
  436. "uniform sampler2D positionSampler; \n"
  437. "uniform float osg_SimulationTime; \n"
  438. "uniform mat4 osg_ViewMatrixInverse;\n"
  439. "uniform mat4 osg_ViewMatrix;\n"
  440.  
  441. "uniform vec2 resolution;\n"
  442.  
  443. "void main() \n"
  444. "{ \n"
  445. "mat4 modelView = gl_ModelViewMatrix;\n"
  446.  
  447. "mat4 modelMatrix = gl_ModelViewMatrix * osg_ViewMatrixInverse;"
  448.  
  449. // Using the instance ID, generate "texture coords" for this instance.
  450. "vec2 tC; \n"
  451. "float r = float(gl_InstanceID) / resolution.x; \n"
  452. "tC.s = fract( r ); tC.t = floor( r ) / resolution.y; \n"
  453.  
  454. // Use the (scaled) tex coord to translate the position of the vertices.
  455. "vec4 posInfo = texture2D( positionSampler, tC );\n"
  456. "float life = posInfo.w;\n"
  457. "vec4 pos = gl_Vertex + vec4(posInfo.xyz, 0.0);\n"
  458.  
  459. // Always red
  460. //"gl_FrontColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
  461. //"vec3 color = mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 0.0), clamp(velocity / 200.0, 0.0, 1.0));\n"
  462. "float alpha = clamp(life, 0.0, 1.0);\n"
  463. "vec3 color = mix(vec3(1.0, 0.0, 0.0), vec3(1.0, 1.0, 0.0), alpha);\n"
  464. "gl_FrontColor = vec4(color, alpha);\n"
  465.  
  466.  
  467. //"gl_Position = gl_ProjectionMatrix * (pos + vec4(modelView[3].xyz, 0));\n"
  468. "gl_Position = gl_ModelViewProjectionMatrix * pos; \n"
  469. //"gl_Position = gl_ProjectionMatrix * modelView * pos;\n"
  470. "} \n";
  471.  
  472. std::string fragSource =
  473.  
  474. "void main() \n"
  475. "{ \n"
  476. " gl_FragColor = gl_Color;\n"
  477. "} \n";
  478.  
  479.  
  480. osg::ref_ptr< osg::Program > program = new osg::Program();
  481. program->addShader( new osg::Shader(osg::Shader::VERTEX, vertexSource ));
  482. program->addShader(new osg::Shader(osg::Shader::FRAGMENT, fragSource));
  483.  
  484. ss->setAttribute( program.get(),
  485. osg::StateAttribute::ON | osg::StateAttribute::PROTECTED );
  486.  
  487. osg::ref_ptr< osg::Uniform > positionUniform =
  488. new osg::Uniform( "positionSampler", 0 );
  489. ss->addUniform( positionUniform.get() );
  490.  
  491. ss->addUniform(new osg::Uniform( "resolution", osg::Vec2f(TEXTURE_DIM, TEXTURE_DIM)));
  492.  
  493. return( ss.release() );
  494. }
  495.  
  496.  
  497. struct GravityHandler : public osgGA::GUIEventHandler
  498. {
  499. GravityHandler(osg::Uniform* uniform):
  500. _uniform(uniform)
  501. {
  502. }
  503.  
  504. bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa)
  505. {
  506. if (ea.getEventType() == ea.KEYDOWN)
  507. {
  508. if (ea.getKey() == '+')
  509. {
  510. osg::Vec3 value;
  511. _uniform->get(value);
  512. value += osg::Vec3(0,0,1);
  513. _uniform->set(value);
  514. return true;
  515. }
  516. else if (ea.getKey() == '-')
  517. {
  518. osg::Vec3 value;
  519. _uniform->get(value);
  520. value -= osg::Vec3(0,0,1);
  521. _uniform->set(value);
  522. return true;
  523. }
  524. }
  525. return false;
  526. }
  527.  
  528. osg::Uniform* _uniform;
  529. };
  530.  
  531.  
  532.  
  533. int main( int argc, char **argv )
  534. {
  535. osg::ArgumentParser arguments(&argc, argv);
  536.  
  537. osg::Group* root = new osg::Group;
  538.  
  539. root->addChild(createBase(osg::Vec3(0,0,-1000.0), 5000.0));
  540.  
  541. // Add a compute node.
  542. ComputeNode* computeNode = new ComputeNode();
  543. root->addChild(computeNode);
  544.  
  545. // Make a scene graph consisting of a single Geode, containing
  546. // a single Geometry, and a single PrimitiveSet.
  547. osg::ref_ptr< osg::Geode > geode = new osg::Geode;
  548.  
  549. osg::ref_ptr< osg::Geometry > geom = new osg::Geometry;
  550. // Configure the Geometry for use with EXT_draw_arrays:
  551. // DL off and buffer objects on.
  552. geom->setUseDisplayList( false );
  553. geom->setUseVertexBufferObjects( true );
  554.  
  555. createDAIGeometry( *geom, TEXTURE_DIM*TEXTURE_DIM );
  556. geode->addDrawable( geom.get() );
  557. geom->setCullingActive(false);
  558. geode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
  559. geode->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
  560.  
  561. // Create a StateSet to render the instanced Geometry.
  562. osg::ref_ptr< osg::StateSet > ss = createStateSet();
  563.  
  564. // Attatch the output of the compute node as the texture to feed the positions on the instanced geometry.
  565. ss->setTextureAttributeAndModes(0, computeNode->_outputPosition.get(), osg::StateAttribute::ON);
  566.  
  567. geode->setStateSet( ss.get() );
  568.  
  569. geode->getOrCreateStateSet()->setAttributeAndModes(new osg::Point(2.0));
  570. geode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON);
  571.  
  572. root->addChild(geode);
  573.  
  574. osgViewer::Viewer viewer(arguments);
  575. viewer.addEventHandler(new osgViewer::StatsHandler);
  576. viewer.setSceneData( root );
  577.  
  578. viewer.setCameraManipulator(new osgGA::TrackballManipulator());
  579.  
  580. osg::Uniform* gravity = new osg::Uniform("gravity", osg::Vec3(0.0, 0.0, -9.8));
  581. computeNode->getOrCreateStateSet()->addUniform(gravity);
  582.  
  583. viewer.addEventHandler(new GravityHandler(gravity));
  584.  
  585.  
  586. double prevSimulationTime = viewer.getFrameStamp()->getSimulationTime();
  587.  
  588. osgEarth::Random rand;
  589.  
  590. while (!viewer.done())
  591. {
  592. viewer.frame();
  593.  
  594. computeNode->swap();
  595. // Attatch the output of the compute node as the texture to feed the positions on the instanced geometry.
  596. ss->setTextureAttributeAndModes(0, computeNode->_outputPosition.get(), osg::StateAttribute::ON);
  597. }
  598. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement