Hi Chris,

I think that

the use of FBO in place of pbuffer,

and use of async read pixels see my message
https://www.mail-archive.com/[email protected]/msg50831.html
could improve speed a bit in your case.

Regards
Sergey


On Fri, Aug 22, 2014 at 11:55 AM, Chris Hidden <[email protected]> wrote:

> Ok, with your pushes in the right direction I have finally managed to get
> this working!  :D. Its not very performance friendly but that I can
> optimize later.
>
> Ill break it down so that people who are looking to do somethings similar
> can see what I did and suggest betters ways of doing it if they want :D.
>
> The first step is to take a look at dhpowares code.  His open GL layered
> window example is the basis for a lot of what I did.
> http://www.dhpoware.com/demos/glLayeredWindows.html
>
> Dhpoware defines a bunch of constants to help set up the OpenGL and OpenGL
> Extensions in his code.  A lot of these we don't need however as OSG takes
> care of a lot of this for us.  We also don't need the methods:
>
>
> Code:
>
> InitChekerPatternTexture();
> InitGLExtensions();
> InitPBuffer();
> InitGL();
>
>
>
>
> These methods do things that OSG takes care of for us.  We can also remove
> the Struct called Vertex and the Vertex object g_cube as we are using our
> own models.
>
> I changed the Image struct to Scene instead of image just to make things
> easier for myself.  The struct itself remains the same:
>
>
> Code:
>
> typedef struct
> {
>         int                     width;
>         int                     height;
>         int                     pitch;
>         HDC                     hdc;
>         HBITMAP         hBitmap;
>         BITMAPINFO      info;
>         BYTE            *pPixels;
> } Scene;
>
>
>
>
> I also added a few global variables to make things easier while I was
> trying to figure this out:
>
>
> Code:
>
> /**
> *       Handle to the current Instance
> */
> HINSTANCE               g_hInst;
> /**
>  *      Screen Horizontal x
>  */
> int sLeft;
> /**
> *       Screen Vertical y
> */
> int sTop;
> /**
> *       Width of the screen
> */
> int sWidth;
> /**
> *       Height of the screen
> */
> int sHeight;
>
> /**
>  *      Viewer for the OSG engine
>  */
> osg::ref_ptr<osgViewer::Viewer>         g_viewer;
> /**
> *       Image for the off screen pbuffer for the osg Scene
> */
> osg::ref_ptr<osg::Image>                        g_image;
> /**
> *       OSG camera object for our scene
> */
> osg::ref_ptr<osg::Camera>                       g_camera;
>
>
>
>
>
> With WinMain we establish the layered window as shown in the example
> except I use sTop, sLeft, sWidth and sHeight to set the createWindow
> x,y,width and height attriubutes:
>
>
> Code:
>
> g_hWnd = CreateWindowEx(
>                 WS_EX_LAYERED | WS_EX_TOPMOST,  // 32 bit value declaring
> the extended window style
>                 wcl.lpszClassName,                              // Null
> terminated string.  Class name.
>                 _T("GL Layered Window Demo"),   // Null terminated
> string.  Window Name.
>                 WS_POPUP,                                               //
> 32 but value declaring the style of the window.
>                 sLeft,                                                  //
> int x pos of window
>                 sTop,                                                   //
> int y pos of window.
>                 sWidth,                                                 //
> int width of window
>                 sHeight,                                                //
> int height of window.
>                 0,
>       // HWND handle to parent window, 0 if none.
>                 0,
>       // HMENU handle to menu
>                 wcl.hInstance,                                  //
> HINSTANCE handle to the instance of the module.
>                 0);
>
>
>
>
> Then I built a small method to set the full screen:
>
>
> Code:
>
> void SetToFullScreen()
> {
>         RECT desktop;
>
>         const HWND hDesk = GetDesktopWindow();
>         GetWindowRect(hDesk, &desktop);
>
>         sLeft   = desktop.left;
>         sTop    = desktop.top;
>         sWidth  = desktop.right         - sLeft;
>         sHeight = desktop.bottom        - sTop;
> }
>
>
>
>
> Now that the window is full screen and the layered window is established
> we need to set up the WindowProc method to handle messages:
>
>
> Code:
>
> LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
> lParam)
> {
>         static TCHAR szBuffer[32] = { 0 };
>
>         switch (msg)
>         {
>         case WM_CREATE:
>                 initOSG(hWnd);
>                 return 0;
>
>         case WM_DESTROY:
>                 PostQuitMessage(0);
>                 return 0;
>
>         case WM_KEYDOWN:
>                 if (wParam == VK_ESCAPE)
>                 {
>                         SendMessage(hWnd, WM_CLOSE, 0, 0);
>                         return 0;
>                 }
>                 break;
>
>         default:
>                 break;
>         }
>
>         return DefWindowProc(hWnd, msg, wParam, lParam);
> }
>
>
>
>
> This looks a bit different as I didn't need the timer functionality any
> more and in WM_CREATE I used the function initOSG to init the OSG engine.
>
> I also took away the functionality to move around the window as its
> unnecessary in full screen.
>
> initOSG builds off of the forum post that Sergey so kindly provided me:
>
>
> >
> > see discussion here http://forum.openscenegraph.org/viewtopic.php?t=7202
> >
>
>
>
> Code:
>
> void initOSG(HWND &hWnd)
> {
>         osg::ref_ptr<osg::Referenced> windata = new
> osgViewer::GraphicsWindowWin32::WindowData(hWnd);
>
>         g_viewer = new osgViewer::Viewer();
>         g_camera = new osg::Camera;
>         g_camera = g_viewer->getCamera();
>
>         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new
> osg::GraphicsContext::Traits;
>
>         initOSGTraits(*traits, windata);
>
>         osg::ref_ptr<osg::GraphicsContext> gc =
> osg::GraphicsContext::createGraphicsContext(traits.get());
>
>         g_camera->setGraphicsContext                            (gc);
>         g_camera->setDrawBuffer
>  (GL_FRONT);
>         g_camera->setProjectionMatrixAsPerspective      (30.0f,
> (double)traits->width / (double)traits->height, 1.0, 1000.0);
>         g_camera->setViewport
>  (new osg::Viewport(0, 0, traits->width, traits->height));
>         g_viewer->setSceneData
> (osgDB::readNodeFile("cessna.osg"));
>         g_camera->setClearColor
>  (osg::Vec4f(0, 0, 0, 0));
>
>         g_viewer->setCameraManipulator(new osgGA::TrackballManipulator);
>         g_image = new osg::Image(); // Needed to establish off screen
> rendering.
>
>         g_viewer->setRunMaxFrameRate(30);
> }
>
>
>
>
> I also like to split my code up a lot so I establish the traits in a
> separate method.  Its important here to set the pbuffer to true. As well as
> the alpha if you want the background to be completely transparent.
>
>
> Code:
>
> void initOSGTraits(osg::GraphicsContext::Traits &traits,
> osg::ref_ptr<osg::Referenced> &windata)
> {
>         traits.x                                        = sWidth        /
> 2;
>         traits.y                                        = sHeight       /
> 2;
>         traits.width                            = sWidth;
>         traits.height                           = sHeight;
>         traits.windowDecoration         = false;
>         traits.doubleBuffer                     = true;
>         traits.pbuffer                          = true;
>         traits.alpha                            = true;
>         traits.inheritedWindowData      = windata;
> }
>
>
>
>
> Now to DrawFrame() which gets called every time we move through the
> message loop in WinMain where WM_QUIT is not true.
>
> Here is the bit that got it all working for me.  First we need to call
> attach on our camera to link the image to the scene.  Or I think thats how
> it works anyways. Im still quite new to OSG.  Then we realize and draw our
> frame.
>
> Now I use dhpoweras CopyPBufferToImage method to create an offscreen
> render of our frame:
>
>
> Code:
>
> void CopyPBufferToImage()
> {
>
>         g_image->readPixels(0, 0, sWidth, sHeight, GL_BGRA_EXT,
> GL_UNSIGNED_BYTE);
>
>
>         for (int i = 0; i < g_image->t(); ++i)
>         {
>                 memcpy(&g_scene.pPixels[g_scene.pitch * i],
>                         &g_image->data()[((sHeight - 1) - i) * (sWidth *
> 4)],
>                         sWidth * 4);
>         }
>
>
> }
>
>
>
>
> I took out everything from this method except for the loop that handles
> copying over the image from the pbuffer to the scene struct we have
> declared earlier.  This way it does exactly what dhpoware did except that
> we use OSG to handle readPixels.  So instead of passing in a byte array we
> use osg::IMAGE data property to get the byte array.  And memcpy it to our
> struct.  Notice here that I don't use a threading method as we want
> everything to exist in the same thread as the layered window so that we can
> actually access our image and copy it to the current window context.
>
> Dhpowares redrawLayeredWindow() and ImagePreMultAlpha take care of the
> nitty gritty redrawing process that I don't fully fuly understand yet.
>
> And voila!  Full screen with a model and no background!  Very awesome.
> Now I need to fix a LOT of performance issues as this takes a crap ton of
> resources, but this is the basic idea anyways.   Don't forget to include
> the osg headers you need and process.h.
>
> PLEASE FEEL FREE to criticize the shit out my methods. I want to make this
> as performance low and well written as possible.  Like I said, I just
> started using OSG 2 weeks ago so Im stil learning.
>
> Cheers![/code]
>
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=60738#60738
>
>
>
>
>
> _______________________________________________
> 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

Reply via email to