Hi Glen,
I just did this like a week ago, was facing the same challenge. There are
few options: One is to make C# wrappers with SWIG, I spent good time on
this supported somewhat from the community, but at the end did not
succeeded.
The other is to wrap some functions into unmanaged dll, where you
initialize the viewer by a given handle (HWND). Then in C# you call this
function and provide the HWND. Some snippets here, not going to provide the
whole source code since it is rather complicated:
This is the function that is exported from a dll, creates the Viewer based
on a given handle (HWND) and start the rendering thread:
extern "C" __declspec(dllexport) int __stdcall InitControl(HWND window)
{
// Lookup for this control, it might be already in use
MapViewersIterator itr = g_Viewers.find(window);
if (itr != g_Viewers.end())
{
return -1;
}
// Local Variable to hold window size data
RECT rect;
// Create the viewer for this window
g_Viewers[window] = new osgViewer::Viewer();
// Get the current window size
::GetWindowRect(window, &rect);
// Init the GraphicsContext Traits
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new
osg::GraphicsContext::Traits;
// Init the Windata Variable that holds the handle for the Window to
display OSG in.
osg::ref_ptr<osg::Referenced> windata = new
osgViewer::GraphicsWindowWin32::WindowData(window);
// Setup the traits parameters
traits->x = 0;
traits->y = 0;
traits->width = rect.right - rect.left;
traits->height = rect.bottom - rect.top;
traits->windowDecoration = false;
traits->doubleBuffer = true;
traits->sharedContext = 0;
traits->setInheritedWindowPixelFormat = true;
traits->inheritedWindowData = windata;
// Create the Graphics Context
osg::GraphicsContext* gc =
osg::GraphicsContext::createGraphicsContext(traits.get());
// Init a new Camera (Master for this View)
osg::ref_ptr<osg::Camera> camera = new osg::Camera;
// Assign Graphics Context to the Camera
camera->setGraphicsContext(gc);
// Set the viewport for the Camera
camera->setViewport(new osg::Viewport(traits->x, traits->y,
traits->width, traits->height));
// Set projection matrix and camera attribtues
camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
camera->setClearColor(osg::Vec4f(0.2f, 0.2f, 0.4f, 1.0f));
camera->setProjectionMatrixAsPerspective(30.0f,
static_cast<double>(traits->width)/static_cast<double>(traits->height),
1.0, 1000.0);
// Add the Camera to the Viewer
g_Viewers[window]->setCamera(camera.get());
// Setup the geometry for this control
g_Viewers[window]->setSceneData( createHUD(osg::Vec2(0,traits->height/2.f),
osg::Vec2(traits->width,traits->height), window) );
// Realize the Viewer
g_Viewers[window]->realize();
// Start the rendring thread and save it as user data for later clearance
osg::ref_ptr< RenderingThread > renderer = new RenderingThread(
g_Viewers[window] );
renderer->startThread();
g_Viewers[window]->getCamera()->setUserData( renderer.get() );
return 0;
}
This is the rendering thread class. Only do frames in a loop. Other option
is to have it on your C# side, to have another exported function like
DoFrame(), and use timer or C# thread to do the rendering loop:
class RenderingThread : public OpenThreads::Thread, public osg::Referenced
{
public:
RenderingThread(osgViewer::Viewer* viewer)
: m_Viewer(viewer)
, m_Running(false)
{
}
virtual void run()
{
m_Running = true;
while (m_Running)
{
m_Viewer->frame();
}
cancel();
}
void setIsRunning( bool running )
{
m_Running = running;
}
protected:
osg::ref_ptr<osgViewer::Viewer> m_Viewer;
bool m_Running;
};
And finaly the C# side. You create control ot get the HWND of the .NET
Form. In my case I have a picture control and I have the viewer running it
it's client's area:
[DllImport("MyOSG.dll")]
static extern int InitControl(Int32 hwnd);
.....
this.pictureBox1.Location = new System.Drawing.Point(30, 71);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(225, 105);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
InitControl(hdl = this.pictureBox1.Handle.ToInt32());
It is tricky but doable. Took some time to figured it out. If you got stuck
ping me, I might be able to give more hints
Cheers,
Nick
On Thu, Jun 19, 2014 at 8:11 AM, 龚来恩 <[email protected]> wrote:
> Hi Everyone,
>
> I want to develop an 3D application based on OSG. Is it possible that I
> use C# language to develop UI, and OSG presentation function is invoke by
> C#. If it is feasible, please give me an source code example.
>
>
>
> Glen
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
>
>
--
trajce nikolov nick
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org