SoOffscreenRenderer.getBuffer returns nil -- Coin3D v4 SoQt 1.6 Fedora 29

182 views
Skip to first unread message

Michael Rilee

unread,
Feb 22, 2019, 11:07:33 PM2/22/19
to coin3d-discuss

I've moved my work to Fedora 29 from MacOS, where I was previously able to render scenes offscreen and then save to a file.

I had been doing this by creating a QImage from an SoOffscreenRenderer getBuffer, but have since also discovered SoOffscreenRenderer's file writing capabilities (via simage).

Presently, getBuffer from an SoOffscreenRenderer object returns nil, whereas the code on MacOS was successful. On Fedora I used hg to clone Coin3D and SoQt from bitbucket and then compiled via cmake.

Any directions on debugging this would be appreciated.

Regards,

Mike


Stewart M.

unread,
Feb 23, 2019, 9:43:32 AM2/23/19
to coin3d-...@googlegroups.com
Hello Mike,

My experience has been that getting offscreen rendering to work on Linux is tricky.  A common problem is not having indirect GLX contexts enabled on the X server, but that may or not be happening in your case.

Could you post a minimal example that demonstrates the problem?  (The file ./src/rendering/SoOffscreenRenderer.cpp has a complete example in the comments.)  There might be an environment variable you can set to get relevant debugging info.

Regards,

Stewart Milberger

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
--
You received this message because you are subscribed to the Google Groups "coin3d-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to coin3d-discus...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Stewart M.

unread,
Feb 23, 2019, 5:21:05 PM2/23/19
to coin3d-...@googlegroups.com
I also remembered that I had written a C++ class for the Clive project to do offscreen rendering with OSMesa (part of the Mesa OpenGL project)--which may be useful to look at as well:




‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

Michael Rilee

unread,
Feb 24, 2019, 4:39:39 PM2/24/19
to coin3d-discuss

Thanks, I pulled that example code out of the renderer (appended below). When I compile and run it I get the following output.

Writing 5 frames...

X Error of failed request:  BadValue (integer parameter out of range for operation)

  Major opcode of failed request:  150 (GLX)

  Minor opcode of failed request:  3 (X_GLXCreateContext)

  Value in failed request:  0x0

  Serial number of failed request:  25

  Current serial number in output stream:  28


I see GLX errors, so maybe indirect contexts aren't enabled as you suggest.

FWIW, I'm running Fedora 29 in a VMWare Fusion VM.

From src/renderingSoOffscreenRenderer.cpp:

#include <Inventor/SoDB.h>

#include <Inventor/SoOffscreenRenderer.h>

#include <Inventor/engines/SoInterpolateVec3f.h>

#include <Inventor/nodes/SoCube.h>

#include <Inventor/nodes/SoDirectionalLight.h>

#include <Inventor/nodes/SoPerspectiveCamera.h>

#include <Inventor/nodes/SoSeparator.h>


#include <iostream>


int main()

{

// Init Coin

SoDB::init();


// The root node

SoSeparator * root = new SoSeparator;

root->ref();


// It is mandatory to have at least one light for the offscreen renderer

SoDirectionalLight * light = new SoDirectionalLight;

root->addChild(light);


// It is mandatory to have at least one camera for the offscreen renderer

SoPerspectiveCamera * camera = new SoPerspectiveCamera;

SbRotation cameraRotation = SbRotation::identity();

cameraRotation *= SbRotation(SbVec3f(1, 0, 0), -0.4f);

cameraRotation *= SbRotation(SbVec3f(0, 1, 0), 0.4f);

camera->orientation = cameraRotation;

root->addChild(camera);


// Something to show... A box

SoCube * cube = new SoCube;

root->addChild(cube);


// Set up the two camera positions we want to move the camera between

SoInterpolateVec3f * interpolate = new SoInterpolateVec3f;

interpolate->input0 = SbVec3f(2, 2, 9);

interpolate->input1 = SbVec3f(2, 2, 5);

camera->position.connectFrom(&interpolate->output);


// Set up the offscreen renderer

SbViewportRegion vpRegion(400, 300);

SoOffscreenRenderer offscreenRenderer(vpRegion);


// How many frames to render for the video

int frames = 5;

std::cout << "Writing " << frames << " frames..." << std::endl;


for (int i = 0; i < frames; i++) {

// Update the camera position

interpolate->alpha = float(i) / (frames - 1);


// Render the scene

SbBool ok = offscreenRenderer.render(root);


// Save the image to disk

SbString filename = SbString("coinvideo-") + (i + 1) + ".jpg";

if (ok) {

offscreenRenderer.writeToFile(filename.getString(), "jpg");

} else {

std::cout << "Error saving image: " << filename.getString() << std::endl;

break;

}

}


std::cout << "Done!" << std::endl;


root->unref();

return 0;

Michael Rilee

unread,
Feb 24, 2019, 5:30:54 PM2/24/19
to coin3d-discuss

A brief update: I turned off Wayland by changing /etc/gdm/custom.conf and enabled indirect glx as described here and here. Now I'm back to a "silent" failure with output as follows.

Writing 5 frames...

Error saving image: coinvideo-1.jpg

Done!



Stewart M.

unread,
Feb 24, 2019, 8:53:08 PM2/24/19
to coin3d-...@googlegroups.com
I enabled indirect GLX and also got the "silent failure" you got.  I found the environment variable COIN_DEBUG_SOOFFSCREENRENDERER in the source.  If you set this to non-zero and run your program, what output do you get?

I got:

  Coin info in CoinOffscreenGLCanvas::getMaxTileSize(): cc_glglue_context_max_dimensions()==[0, 0]

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

Michael Rilee

unread,
Feb 24, 2019, 10:53:56 PM2/24/19
to coin3d-discuss
Yes, I get the same thing. offscreenRenderer.render(root) returns false and getBuffer returns nil, but these seem to result from the getMaxTileSize issue.

Stewart M.

unread,
Feb 25, 2019, 12:46:32 PM2/25/19
to coin3d-...@googlegroups.com
I got the sample code to work.  I setup the following environment variables:

export COIN_DEBUG_SOOFFSCREENRENDERER=1
export COIN_FULL_INDIRECT_RENDERING=1
export COIN_OFFSCREENRENDERER_MAX_TILESIZE=512
export COIN_OFFSCREENRENDERER_TILEHEIGHT=256
export COIN_OFFSCREENRENDERER_TILEWIDTH=256

I also had to modify the simage library to ignore the case of the file format in the "qimage_set_save_format" function (in file "./src/simage_qimage.cpp").  I'm running on Ubuntu 18.04 by the way.



‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

Michael Rilee

unread,
Feb 26, 2019, 6:02:47 PM2/26/19
to coin3d-discuss
Great! It's working for me now too. Though it looks like the cube in the first image is clipped.

Thanks!

Stewart M.

unread,
Feb 26, 2019, 7:41:47 PM2/26/19
to coin3d-...@googlegroups.com
My images aren't clipped (at least I don't think so):


‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

Michael Rilee

unread,
Feb 26, 2019, 10:56:05 PM2/26/19
to coin3d-discuss

My image isn't clipped, it looks like on the first frame a tile didn't render correctly.

https://postimg.cc/gallery/cx4hczao/

If I render the first frame twice (saving after the second), then it looks like yours.

The debug output starts with:

Writing 5 frames...

Coin info in CoinOffscreenGLCanvas::getMaxTileSize(): cc_glglue_context_max_dimensions()==[0, 0]

Coin info in CoinOffscreenGLCanvas::setWantedSize(): killing current context, (clamped) reqsize==[256, 256], previous size==[0, 0], resourcehog==FALSE

Coin info in CoinOffscreenGLCanvas::tryActivateGLContext(): Tried to create offscreen context of dimensions <256, 256> -- succeeded

Coin info in SoOffscreenRendererP::renderFromBase(): fullsize==<400, 300>, glsize==<256, 256>

Coin info in SoOffscreenRenderer::renderFromBase(): GL context GL_[RED|GREEN|BLUE|ALPHA]_BITS==[8, 8, 8, 8]

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <0, 0>: <0.000000, 0.000000> - <0.640000, 0.853333>

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <1, 0>: <0.640000, 0.000000> - <1.000000, 0.853333>

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <0, 1>: <0.000000, 0.853333> - <0.640000, 1.000000>

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <1, 1>: <0.640000, 0.853333> - <1.000000, 1.000000>

Render ok? 1

osv::getImage::buffer: 0x7f0a63048010

Coin info in SoOffscreenRendererP::renderFromBase(): fullsize==<400, 300>, glsize==<256, 256>

Coin info in SoOffscreenRenderer::renderFromBase(): GL context GL_[RED|GREEN|BLUE|ALPHA]_BITS==[8, 8, 8, 8]

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <0, 0>: <0.000000, 0.000000> - <0.640000, 0.853333>

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <1, 0>: <0.640000, 0.000000> - <1.000000, 0.853333>

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <0, 1>: <0.000000, 0.853333> - <0.640000, 1.000000>

Coin info in SoOffscreenRendererP::setCameraViewvolForTile(): narrowing for tile <1, 1>: <0.640000, 0.853333> - <1.000000, 1.000000>

Render ok? 1

osv::getImage::buffer: 0x7f0a63048010


And then repeats... At present it seems workable as long as I render the first one twice...



Stewart M.

unread,
Feb 27, 2019, 10:10:36 AM2/27/19
to coin3d-...@googlegroups.com
Like I said in my first email on this thread...offscreen rendering can be difficult to get working on Linux. :)   That's the main reason I started developing a class that used OSMesa.

‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐

Michael Rilee

unread,
Feb 27, 2019, 2:24:50 PM2/27/19
to coin3d-...@googlegroups.com
Indeed. I'm glad you mentioned OSMesa, I hadn't heard of it before. Is that class you're developing for Coin3D?

You received this message because you are subscribed to a topic in the Google Groups "coin3d-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/coin3d-discuss/eyb9jCIOkpA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to coin3d-discus...@googlegroups.com.

Stewart M.

unread,
Feb 27, 2019, 4:37:24 PM2/27/19
to coin3d-discuss
From OSMesa's web page (https://www.mesa3d.org/osmesa.html):

> OSMesa's off-screen interface is used for rendering into user-allocated memory without any sort of window system or operating system dependencies. That is, the GL_FRONT colorbuffer is actually a buffer in main memory, rather than a window on your display.

Since it SEEMS like "they" (I haven't figured out who) are intent on deprecating indirect GLX in Linux :), I started developing my own offscreen renderer (which is still a work in progress, and only supports simple image formats.)  My class, FileRenderer, should be usable with any OpenInventor 2.1 compatible library, including Coin.  The links to FileRenderer are in an earlier email in this thread.

One thing I thought I could do is document some of the stuff from this thread in the Coin repo someday.

Good luck!

Bastiaan Veelo

unread,
Feb 27, 2019, 4:43:14 PM2/27/19
to coin3d-...@googlegroups.com
On 27/02/2019 22:37, 'Stewart M.' via coin3d-discuss wrote:
> One thing I thought I could do is document some of the stuff from this
> thread in the Coin repo someday.

Certainly! We also have a wiki: https://bitbucket.org/Coin3D/coin/wiki/Home

Bastiaan.

Reply all
Reply to author
Forward
0 new messages