OpenSceneGraph Forum Forum Index OpenSceneGraph Forum
Official forum which mirrors the existent OSG mailing lists. Messages posted here are forwarded to the mailing list and vice versa.
 
   FAQFAQ    SearchSearch    MemberlistMemberlist    RulesRules    UsergroupsUsergroups    RegisterRegister 
 Mail2Forum SettingsMail2Forum Settings  ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
   AlbumAlbum  OpenSceneGraph IRC ChatOpenSceneGraph IRC Chat   SmartFeedSmartFeed 

How to resize when using PIXEL_BUFFER?


 
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General
View previous topic :: View next topic  
Author Message
greg_nhi1
Newbie


Joined: 26 Sep 2014
Posts: 5

PostPosted: Thu Feb 04, 2016 9:15 pm    Post subject:
How to resize when using PIXEL_BUFFER?
Reply with quote

Hi,

Our application (Windows x64) writes to a memory buffer rather than a window. The app using OSG runs as a hidden console app and streams the rendered images via named pipe to a client app. (Even if we weren't using a separate process for OSG we need to render using PIXEL_BUFFER since our app is WPF and doesn't provide a usable window handle.)

When I resize the display window I send a message to my processor so it can resize the OSG components. However, I cannot find a way to do this that works. I get the following results by trying different methods.

I've searched the sample code and forums and can't find anything (other than the methods I have tried based on sample code). Any help would be appreciated.


For reference (I'm using an earth view to check proportions and coordinates - I get the same results using a model):

The last image (SmallEarthEventQueue) was generated using this source code to resize.

double eventTime = m_nhiViewer->getEventQueue()->getTime();
m_nhiViewer->getEventQueue()->windowResize(0, 0, m_width, m_height, eventTime);


The next up (SmallEarth-NoProjChange) was generated using this source code to resize.

gc->resized(0, 0, m_width, m_height);

camera->resize(m_width, m_height, osg::Camera::ResizeMask::RESIZE_ATTACHMENTS | osg::Camera::ResizeMask::RESIZE_VIEWPORT);


The next up (SmallEarth-ProjChange) was generated using this source code.

osg::Camera * camera = m_nhiViewer->getCamera();
if (camera != nullptr)
{
osg::ref_ptr<osg::GraphicsContext> gc = camera->getGraphicsContext();
if (gc != nullptr)
{
osg::Matrixd origCamProjMatrix = camera->getProjectionMatrix();

gc->resized(0, 0, m_width, m_height);

double widthChangeRatio = double(m_width) / double(m_lastWidth);
double heightChangeRatio = double(m_height) / double(m_lastHeight);
double aspectRatioChange = widthChangeRatio / heightChangeRatio;

if (aspectRatioChange != 1.0)
{
switch (camera->getProjectionResizePolicy())
{
case(osg::Camera::HORIZONTAL) :
case(osg::Camera::VERTICAL) :
origCamProjMatrix *= osg::Matrix::scale(1.0 / aspectRatioChange, 1.0 / aspectRatioChange, 1.0);
origCamProjMatrix *= osg::Matrix::translate(-(1.0 - widthChangeRatio), -(1.0 - heightChangeRatio), 0.0);
break;

default:
break;
}
}

camera->resize(m_width, m_height, osg::Camera::ResizeMask::RESIZE_ATTACHMENTS | osg::Camera::ResizeMask::RESIZE_VIEWPORT);

camera->setProjectionMatrix(origCamProjMatrix);
}
}



...

Thank you!

Cheers,
Greg


Last edited by greg_nhi1 on Fri Feb 05, 2016 2:33 pm; edited 1 time in total
Back to top
View user's profile Send private message
greg_nhi1
Newbie


Joined: 26 Sep 2014
Posts: 5

PostPosted: Fri Feb 05, 2016 2:27 pm    Post subject:
Reply with quote

Hi,

Added source code for reference.
...

Thank you!

Cheers,
Greg
Back to top
View user's profile Send private message
greg_nhi1
Newbie


Joined: 26 Sep 2014
Posts: 5

PostPosted: Fri Feb 05, 2016 2:30 pm    Post subject:
Re: How to resize when using PIXEL_BUFFER?
Reply with quote

duplicate
Back to top
View user's profile Send private message
robertosfield
OSG Project Lead


Joined: 18 Mar 2009
Posts: 11311

PostPosted: Fri Feb 05, 2016 8:34 pm    Post subject:
How to resize when using PIXEL_BUFFER?
Reply with quote

Hi Greg,

I haven't attempted doing what you are doing before so can't answer
with specific solutions. General comments would be that Pixel Buffers
are essentially fixed size with no support for resizing.

To provide a something equivalent to resize functionality you could
allocate a new pixel buffer with the new size or create an oversized
pixel buffer at the start that you just use a viewport at the size you
wish to render at. Potentially you could use FrameBufferObjects
within a PixelBuffer so rather than rendering directly to the
PixelBuffer's frame buffer you render to one FBO and reallocate a FBO
when you need a resize. The advantage with use a FBO is that you
never need to destroy a graphics context and all the GL objects
associated with it, this means the costs will be much lower for
creating a new window size as creating/destoying a FBO will just
require re-allocation of it, all the rest of the GL objects like
textures, VBO's etc. can remain allocated.

Robert.


------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
greg_nhi1
Newbie


Joined: 26 Sep 2014
Posts: 5

PostPosted: Thu Feb 11, 2016 10:57 pm    Post subject:
Reply with quote

Hi,

Here's a follow-up. I have it about 95% working (finally!).

Here's my code to resize the pixel-buffer models.

Code:


osg::Camera * camera = m_nhiViewer->getCamera();
if (camera != nullptr)
{
   osg::ref_ptr<osg::GraphicsContext> gc = camera->getGraphicsContext();
   if (gc != nullptr)
   {
      if (gc->releaseContext())
      {
         gc->close(); // will release PixelBufferWin32 and resources

         // create new graphics context
         osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
         traits->x = 0;
         traits->y = 0;
         traits->width = m_width;
         traits->height = m_height;
         traits->red = 8;
         traits->green = 8;
         traits->blue = 8;
         traits->depth = 24;
         traits->pbuffer = true;
         traits->doubleBuffer = true;
         traits->readDISPLAY();
         traits->supportsResize = true;

         gc = osg::GraphicsContext::createGraphicsContext(traits.get());
         if (gc != nullptr)
         {
            gc->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
            gc->setClearColor(m_background);

            camera->setGraphicsContext(gc.get());

            osg::ref_ptr<osg::Image> image = nullptr;
            std::map<osg::Camera::BufferComponent, osg::Camera::Attachment> bam = camera->getBufferAttachmentMap();
            if (!bam.empty())
            {
               osg::Camera::BufferAttachmentMap::iterator iter = bam.find(osg::Camera::COLOR_BUFFER);
               if (iter != bam.end())
                  image = iter->second._image;
            }

            if (image != nullptr)
            {
               image->allocateImage(m_width, m_height, image->r(), image->getPixelFormat(), image->getDataType(), image->getPacking());
            }

            m_nhiViewer->realize();

            double widthChangeRatio = double(m_width) / double(m_lastWidth);
            double heightChangeRatio = double(m_height) / double(m_lastHeight);
            double aspectRatioChange = widthChangeRatio / heightChangeRatio;

            if (aspectRatioChange != 1.0)
            {
               switch (camera->getProjectionResizePolicy())
               {
                  case(osg::Camera::HORIZONTAL) :
                     camera->getProjectionMatrix() *= osg::Matrix::scale(1.0 / aspectRatioChange, 1.0, 1.0);
                     break;
                  case(osg::Camera::VERTICAL) :
                     camera->getProjectionMatrix() *= osg::Matrix::scale(1.0, aspectRatioChange, 1.0);
                     break;

                  default:
                     break;
               }
            }

            camera->setViewport(0, 0, m_width, m_height);

            double eventTime = m_nhiViewer->getEventQueue()->getTime();
            m_nhiViewer->getEventQueue()->windowResize(0, 0, m_width, m_height, eventTime);
         }
      }
   }
}



But the real problem was that when I set up the rendering when the model loaded, I specified

camera->setRenderTargetImplementation(osg::Camera::PIXEL_BUFFER);

That seemed to throw everything off. Now it is defaulting to FRAME_BUFFER and using traits->pbuffer = true; to set up the pixel buffering.

I still have one problem though. It works great with models (e.g. .flt) but when I resize an earth file it doesn't render properly. I also get an error 'invalid enumerant' after RenderBin::draw() in osgUtil RenderBin.cpp. The error value is 1280. The earth image looks as below after I resize it (or it comes up black). If I resize it again the globe is black.

Any additional help would be greatly appreciated.

...

Thank you!

Cheers,
Greg
Back to top
View user's profile Send private message
robertosfield
OSG Project Lead


Joined: 18 Mar 2009
Posts: 11311

PostPosted: Fri Feb 12, 2016 10:53 am    Post subject:
How to resize when using PIXEL_BUFFER?
Reply with quote

Hi Greg,

It's hard to know specifically what is wrong as I don't have any of
your code to test first hand. If you are re-creating the PixelBuffer
on each resize then I'd guess that there is an issue with the graphics
object handles being invalidated in some way. There are mechanisms in
the OSG for release graphics objects but perhaps you are bypassing
these or using an older version of the OSG that doesn't manage this
correctly.

In my previous email I suggested that the best approach is to using a
single PixelBuffer and then using a FrameBufferObject within this to
do the rendering to and copying from rather than the using the
PixelBuffer's frame buffer - this approach would allow you to avoid
the need to release and then recreating GL objects on each resize, the
only resource that would need to be reallocated with the FBO.

Robert.

On 11 February 2016 at 22:58, Greg Danaha <> wrote:
Quote:
Hi,

Here's a follow-up. I have it about 95% working (finally!).

Here's my code to resize the pixel-buffer models.


Code:


osg::Camera * camera = m_nhiViewer->getCamera();
if (camera != nullptr)
{
osg::ref_ptr<osg::GraphicsContext> gc = camera->getGraphicsContext();
if (gc != nullptr)
{
if (gc->releaseContext())
{
gc->close(); // will release PixelBufferWin32 and resources

// create new graphics context
osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;
traits->x = 0;
traits->y = 0;
traits->width = m_width;
traits->height = m_height;
traits->red = 8;
traits->green = 8;
traits->blue = 8;
traits->depth = 24;
traits->pbuffer = true;
traits->doubleBuffer = true;
traits->readDISPLAY();
traits->supportsResize = true;

gc = osg::GraphicsContext::createGraphicsContext(traits.get());
if (gc != nullptr)
{
gc->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
gc->setClearColor(m_background);

camera->setGraphicsContext(gc.get());

osg::ref_ptr<osg::Image> image = nullptr;
std::map<osg::Camera::BufferComponent, osg::Camera::Attachment> bam = camera->getBufferAttachmentMap();
if (!bam.empty())
{
osg::Camera::BufferAttachmentMap::iterator iter = bam.find(osg::Camera::COLOR_BUFFER);
if (iter != bam.end())
image = iter->second._image;
}

if (image != nullptr)
{
image->allocateImage(m_width, m_height, image->r(), image->getPixelFormat(), image->getDataType(),
image->getPacking());
}

m_nhiViewer->realize();

double widthChangeRatio = double(m_width) / double(m_lastWidth);
double heightChangeRatio = double(m_height) / double(m_lastHeight);
double aspectRatioChange = widthChangeRatio / heightChangeRatio;

if (aspectRatioChange != 1.0)
{
switch (camera->getProjectionResizePolicy())
{
case(osg::Camera::HORIZONTAL) :
camera->getProjectionMatrix() *= osg::Matrix::scale(1.0 / aspectRatioChange, 1.0, 1.0);
break;
case(osg::Camera::VERTICAL) :
camera->getProjectionMatrix() *= osg::Matrix::scale(1.0, aspectRatioChange, 1.0);
break;

default:
break;
}
}

camera->setViewport(0, 0, m_width, m_height);

double eventTime = m_nhiViewer->getEventQueue()->getTime();
m_nhiViewer->getEventQueue()->windowResize(0, 0, m_width, m_height, eventTime);
}
}
}
}





But the real problem was that when I set up the rendering when the model loaded, I specified

camera->setRenderTargetImplementation(osg::Camera::PIXEL_BUFFER);

That seemed to throw everything off. Now it is defaulting to FRAME_BUFFER and using traits->pbuffer = true; to set up the pixel buffering.

I still have one problem though. It works great with models (e.g. .flt) but when I resize an earth file it doesn't render properly. I also get an error 'invalid enumerant' after RenderBin::draw() in osgUtil RenderBin.cpp. The error value is 1280. The earth image looks as below after I resize it (or it comes up black). If I resize it again the globe is black.

Any additional help would be greatly appreciated.

...

Thank you!

Cheers,
Greg[/code]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=66275#66275








------------------
Post generated by Mail2Forum
Back to top
View user's profile Send private message
gkoulin
Newbie


Joined: 11 Dec 2017
Posts: 2

PostPosted: Tue Dec 12, 2017 11:25 am    Post subject:
How to resize when using PIXEL_BUFFER?
Reply with quote

Hi Robert,

I have come accross a similar issue. I am working on a GtkmmOsgViewer for gtkmm3. I have found this is to be quite challenging and was not able to use new Gtk::GLArea widget for this. Perhaps someone with better knowledge of OpenGL than myself could solve that problem. The code from examples/osgviewerGTK was useful however I decided to follow a slightly different approach.

I create pBuffer context and attach image to main camera. Then after each frame I redraw the image onto the cairo surface of the widget using cairo_image_surface_create_for_data() similar to osgPlugins/pdf/ReaderWriterPDF.cpp . So far I have been creating an oversized PixelBuffer and only using a subset of it, this avoids re-creating the context each time the widget is resized. I also have to set camera->RenderTargetImplementation(FRAME_BUFFER); as this is the only option that gives me image with transparency alpha values. The other implementations ignore alpha.

My problems are:

• I am unable to achieve multisampling of the image. I've tried setting traits->samples = 4; and also samples on camera->attach(COLOR_BUFFER, image, 4 /* samples */); . I have tried setting a scaled up viewport, for example scale = 4, and letting cairo downsample to achieve antialiasing. This is however very slow (in frame time) since CPU is used for this downsampling operation. How can I achieve multisampling for the attached image?

• I think your advice "using a single PixelBuffer and then using a FrameBufferObject within this to do the rendering to and copying from" is great. Could you please explain how to do this? Are there any specific considerations for multisampling?


Looking forward to your answer.

Cheers,
Giorge
Back to top
View user's profile Send private message
gkoulin
Newbie


Joined: 11 Dec 2017
Posts: 2

PostPosted: Wed Dec 13, 2017 10:29 pm    Post subject:
Reply with quote

Hi,

I was able to solve my problem, at last!!

I was curious to investigate the re-allocating FBO option Robert talked about. Basically by setting camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT); and making sure my image pixelFormat and internalTextureFormat are correct. Then whenever the widget is resized I reallocate the image and resize viewport etc. Also reallocate FBO with the following calls:

osgViewer::Renderer* renderer = (osgViewer::Renderer*)camera->getRenderer();
renderer->getSceneView(0)->getRenderStage()->setCameraRequiresSetUp(true);
renderer->getSceneView(0)->getRenderStage()->setFrameBufferObject(NULL);

I will share the new GtkmmOsgViewer for gtkmm3 on git soon.

Thank you!

Cheers,
Giorge
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    OpenSceneGraph Forum Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You cannot download files in this forum

Similar Topics
Topic Author Forum Replies Posted
No new posts Camera resize vs setViewport ravidavi General 3 Fri Feb 24, 2017 3:13 am View latest post
No new posts odd scene resize gambr General 5 Wed Sep 07, 2016 7:51 am View latest post
No new posts OSX/X11 graphics context not updating... ravidavi General 1 Mon Jun 27, 2016 9:17 pm View latest post
No new posts resize an osgWidget::Window gambr General 0 Thu Jun 25, 2015 2:57 pm View latest post
No new posts Resize Geometry in a HUD on Resize of... jlguitar287 General [forum] 2 Wed Dec 17, 2014 9:04 pm View latest post


Board Security Anti Bot Question MOD - phpBB MOD against Spam Bots
Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP