Actually, I can share it here. It was written for non-commercial purpose.
See attached
Nick
On Thu, Jun 19, 2014 at 9:57 AM, Trajce Nikolov NICK <
[email protected]> wrote:
> Hi Nikita,
>
> I have sample of that. Ping me on my email I can share my sample with you
>
> Nick
>
>
> On Thu, Jun 19, 2014 at 9:51 AM, Robert Osfield <[email protected]>
> wrote:
>
>> HI Nikita,
>>
>> The way to do overlays like this is to render using a Camera with an
>> orthographic projection that effectively creates a 2D view, then just
>> create the geometry your draw in the standard OSG way using Nodes,
>> Geometry and StateSet as you'd do with a 3D scene graph. The osghud
>> example shows various ways of creating this extra view. The OSG's
>> onscreen stats also has a frame rate profile chart that is similar to
>> what you'll need to show, have a look at
>> src/osgViewer/StatsHandler.cpp.
>>
>> Robert.
>>
>> On 19 June 2014 08:28, Nikita Petrov <[email protected]> wrote:
>> > Hi,
>> >
>> > I'm developing application with osgEarth. What I want to do now is a
>> plane flying in the sky and in the bottom of the screen I want to show
>> vertical profile of the flight H(t). I've tried to find something to draw
>> charts on overlay (HUD) in OSG, but found nothing! I don't believe that
>> there is no such basic thing in OSG.
>> > The question is how I should do it? What is the easiest way? I'm
>> working with 3D graphics only for several months, so I'm at the beginner
>> level. :)
>> >
>> > Thank you!
>> >
>> > Cheers,
>> > Nikita
>> >
>> > ------------------
>> > Read this topic online here:
>> > http://forum.openscenegraph.org/viewtopic.php?p=59808#59808
>> >
>> >
>> >
>> >
>> >
>> > _______________________________________________
>> > osg-users mailing list
>> > [email protected]
>> >
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>> _______________________________________________
>> osg-users mailing list
>> [email protected]
>> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>>
>
>
>
> --
> trajce nikolov nick
>
--
trajce nikolov nick
#include <Windows.h>
#include <osgUtil/Optimizer>
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>
#include <osgViewer/CompositeViewer>
#include <osgGA/TrackballManipulator>
#include <osg/Material>
#include <osg/Geode>
#include <osg/BlendFunc>
#include <osg/Depth>
#include <osg/PolygonOffset>
#include <osg/MatrixTransform>
#include <osg/Camera>
#include <osg/RenderInfo>
#include <osgDB/WriteFile>
#include <osgText/Text>
#define NORMALIZE_RANDOM_SIGNAL_Y 100
#define SIGNALS_PER_SECOND 250
class ThreadSignalDataPipe : public OpenThreads::Thread, public osg::Referenced
{
public:
ThreadSignalDataPipe(const osg::Vec4& window, unsigned int size = 300)
: OpenThreads::Thread()
, m_ThreadIsRunning(false)
, m_X(0.f)
, m_Size(size)
, m_Vertices( new osg::Vec3Array )
, m_Window(window)
{
for ( unsigned int i=0; i<m_Size; ++i )
{
m_Vertices->push_back(osg::Vec3(window.x()+m_X++,window.y(),0.f));
}
}
typedef std::vector<float> SignalData;
typedef std::vector<float>::iterator SignalDataIterator;
typedef std::vector<float>::const_iterator SignalDataConstIterator;
virtual void addData(const SignalData& data)
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(m_Mutex);
m_Data.clear();
m_Data.insert(m_Data.end(), data.begin(), data.end());
}
virtual void run()
{
m_ThreadIsRunning = true;
while (m_ThreadIsRunning)
{
{
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(m_Mutex);
if (m_Data.size())
{
float signal = m_Data.front();
m_Data.erase(m_Data.begin());
#if 0
m_Vertices->erase( m_Vertices->begin() );
m_Vertices->push_back( osg::Vec3(m_Window.x()+m_X++,m_Window.y()+signal,0.f) );
#else
(*m_Vertices)[(int)m_X] = osg::Vec3(m_Window.x()+m_X++,m_Window.y()+signal,0.f);
#endif
}
else
{
#if 0
m_Vertices->erase( m_Vertices->begin() );
m_Vertices->push_back( osg::Vec3(m_Window.x()+m_X++,m_Window.y(),0.f) );
#else
(*m_Vertices)[(int)m_X] = osg::Vec3(m_Window.x()+m_X++,m_Window.y(),0.f);
#endif
}
if (m_X >= m_Size)
{
m_X = 0.f;
}
}
OpenThreads::Thread::microSleep(100);
}
m_ThreadIsRunning = false;
cancel();
}
bool isRunning() const
{
return m_ThreadIsRunning;
}
void setIsRunning(bool running)
{
m_ThreadIsRunning = running;
}
osg::Vec3Array* getVertexArray() const
{
return m_Vertices.get();
}
float getSliderPosition() const
{
return m_X;
}
osg::Vec4 getWindow() const
{
return m_Window;
}
OpenThreads::Mutex& getMutex() const
{
return m_Mutex;
}
protected:
mutable OpenThreads::Mutex m_Mutex;
SignalData m_Data;
bool m_ThreadIsRunning;
float m_X;
unsigned int m_Size;
osg::ref_ptr< osg::Vec3Array > m_Vertices;
osg::Vec4 m_Window;
};
class DataGeneratorThread : public OpenThreads::Thread, public osg::Referenced
{
public:
DataGeneratorThread(unsigned int numOfSignalsPerChunk = SIGNALS_PER_SECOND)
: OpenThreads::Thread()
, osg::Referenced()
, m_ThreadIsRunning(false)
, m_NumOfSignalsPerChunk(numOfSignalsPerChunk)
{
}
virtual ~DataGeneratorThread()
{
DataPipesIterator itr = m_DataPipes.begin();
for ( ; itr != m_DataPipes.end(); ++itr )
{
(**itr).setIsRunning( false );
while ((**itr).isRunning());
OpenThreads::Thread::microSleep(100000);
}
m_DataPipes.clear();
}
typedef std::vector< osg::ref_ptr<ThreadSignalDataPipe> > DataPipes;
typedef std::vector< osg::ref_ptr<ThreadSignalDataPipe> >::iterator DataPipesIterator;
typedef std::vector< osg::ref_ptr<ThreadSignalDataPipe> >::const_iterator DataPipesConstIterator;
void addDataPipe( ThreadSignalDataPipe* dataPipe )
{
m_DataPipes.push_back( dataPipe );
}
virtual void run()
{
m_ThreadIsRunning = true;
while (m_ThreadIsRunning)
{
DataPipesIterator itr = m_DataPipes.begin();
for ( ; itr != m_DataPipes.end(); ++itr )
{
ThreadSignalDataPipe::SignalData chunk;
for ( unsigned int i=0; i<m_NumOfSignalsPerChunk; ++i )
{
#if 0
chunk.push_back( rand() % NORMALIZE_RANDOM_SIGNAL_Y );
#else
if (i==0)
{
chunk.push_back(0);
}
else
{
int sign = rand() % 2;
switch (sign)
{
case 0:
sign = -1;
break;
case 1:
sign = 1;
break;
}
chunk.push_back(chunk.at(chunk.size()-1)+sign*(rand() % NORMALIZE_RANDOM_SIGNAL_Y/5));
}
#endif
}
(**itr).addData( chunk );
}
OpenThreads::Thread::microSleep((1.f/SIGNALS_PER_SECOND)*1000000);
}
m_ThreadIsRunning = false;
cancel();
}
bool isRunning() const
{
return m_ThreadIsRunning;
}
void setIsRunning(bool running)
{
m_ThreadIsRunning = running;
}
protected:
bool m_ThreadIsRunning;
DataPipes m_DataPipes;
unsigned int m_NumOfSignalsPerChunk;
};
class GeometryUpdateCallback : public osg::Geometry::UpdateCallback
{
public:
GeometryUpdateCallback( ThreadSignalDataPipe* pipe )
: m_Pipe(pipe)
{
}
virtual void update(osg::NodeVisitor*, osg::Drawable* drawable)
{
osg::Geometry* geometry = dynamic_cast<osg::Geometry*>(drawable);
if (!geometry) return;
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(m_Pipe->getMutex());
float slider = m_Pipe->getSliderPosition();
osg::Vec3Array* vertices = new osg::Vec3Array;
vertices->insert( vertices->end(), m_Pipe->getVertexArray()->begin(), m_Pipe->getVertexArray()->end() );
vertices->push_back( osg::Vec3( m_Pipe->getWindow().x()+slider, m_Pipe->getWindow().y(), 0.f ) );
vertices->push_back( osg::Vec3( m_Pipe->getWindow().x()+slider, m_Pipe->getWindow().y()+150, 0.f ) );
geometry->setVertexArray(vertices);
geometry->removePrimitiveSet(0,2);
geometry->addPrimitiveSet( new osg::DrawArrays( GL_LINE_STRIP, 0, m_Pipe->getVertexArray()->size() ) );
geometry->addPrimitiveSet( new osg::DrawArrays( GL_LINES, m_Pipe->getVertexArray()->size(), 2 ) );
}
protected:
ThreadSignalDataPipe* m_Pipe;
};
osg::ref_ptr< DataGeneratorThread > dataGeneratorThread = 0;
osg::Geometry* createSignalControl( float x, float y, const osg::Vec4& color, unsigned int size )
{
ThreadSignalDataPipe* pipe = new ThreadSignalDataPipe(osg::Vec4(x,y,0,0),size);
pipe->startThread();
dataGeneratorThread->addDataPipe( pipe );
osg::Geometry* geometry = new osg::Geometry;
geometry->setVertexArray(pipe->getVertexArray());
geometry->addPrimitiveSet( new osg::DrawArrays( GL_LINE_STRIP, 0, pipe->getVertexArray()->size() ) );
geometry->addPrimitiveSet( new osg::DrawArrays( GL_LINES, pipe->getVertexArray()->size(), 2 ) );
geometry->setUseDisplayList( false );
geometry->setUseVertexBufferObjects( false );
geometry->setUpdateCallback( new GeometryUpdateCallback(pipe) );
osg::Vec4Array* colors = new osg::Vec4Array;
colors->push_back(color);
colors->push_back(osg::Vec4(0,0,0,1));
geometry->setColorArray(colors);
geometry->setColorBinding(osg::Geometry::BIND_PER_PRIMITIVE_SET);
return geometry;
}
osg::Camera* createHUD()
{
// create a camera to set up the projection and model view matrices, and the subgraph to draw in the HUD
osg::Camera* camera = new osg::Camera;
// set the projection matrix
camera->setProjectionMatrix(osg::Matrix::ortho2D(0,800,0,600));
// set the view matrix
camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
camera->setViewMatrix(osg::Matrix::identity());
// only clear the depth buffer
camera->setClearMask(GL_DEPTH_BUFFER_BIT);
// draw subgraph after main camera view.
camera->setRenderOrder(osg::Camera::POST_RENDER);
// we don't want the camera to grab event focus from the viewers main camera(s).
camera->setAllowEventFocus(false);
// add to this camera a subgraph to render
{
osg::Geode* geode = new osg::Geode();
// turn lighting off for the text and disable depth test to ensure it's always ontop.
osg::StateSet* stateset = geode->getOrCreateStateSet();
stateset->setMode(GL_LIGHTING,osg::StateAttribute::OFF);
dataGeneratorThread = new DataGeneratorThread;
{
geode->addDrawable( createSignalControl( 100, 100, osg::Vec4(1,0,0,1),300 ) );
geode->addDrawable( createSignalControl( 100, 300, osg::Vec4(1,0,1,1),300 ) );
geode->addDrawable( createSignalControl( 500, 300, osg::Vec4(0,0,1,1),200 ) );
geode->addDrawable( createSignalControl( 500, 100, osg::Vec4(0,1,0,1),200 ) );
geode->addDrawable( createSignalControl( 100, 500, osg::Vec4(0,1,1,1),300 ) );
geode->addDrawable( createSignalControl( 500, 500, osg::Vec4(1,1,0,1),200 ) );
}
camera->addChild(geode);
dataGeneratorThread->startThread();
}
return camera;
}
int main( int argc, char **argv )
{
// use an ArgumentParser object to manage the program arguments.
osg::ArgumentParser arguments(&argc,argv);
// read the scene from the list of file specified commandline args.
osg::ref_ptr<osg::Node> scene = new osg::Group;
{
// construct the viewer.
osgViewer::Viewer viewer;
viewer.setUpViewInWindow( 100, 100, 800, 600 );
osg::ref_ptr<osg::Group> group = new osg::Group;
// add the HUD subgraph.
if (scene.valid()) group->addChild(scene.get());
group->addChild(createHUD());
// set the scene to render
viewer.setSceneData(group.get());
// white color
viewer.getCamera()->setClearColor(osg::Vec4(1,1,1,1));
viewer.run();
dataGeneratorThread->setIsRunning( false );
while ( dataGeneratorThread->isRunning() );
dataGeneratorThread->microSleep(10000);
dataGeneratorThread = 0;
return 0;
}
}
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org