PDA

View Full Version : Segmentation Fault Opengl used within a Class



Loderunner
01-23-2010, 11:46 PM
So I'm designing an intelligent ground vehicle as part of my senior design project and I'm running into a Segmentation fault.

Basically we are running a multi-threaded C++ application that calls things like opencv and ncurses in addition to opengl.

Now my part of all this is the creation of a mapping software using opengl.

When I run this code independently it works fine, but when I integrate into the main code it gets the segfault.

The only part I have in main.cc is:

glutInit(&argc, argv); //initialize glut
glutCreateWindow("2D map"); //window title
glutDisplayFunc(drawScene);
I had to declare drawScene as a global function because I kept getting an error when I called glutDisplayFunc within the mapping class.

In mapping.cc I have:
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400, 400); //set mapping window size
glutInitWindowPosition(600,1); //set screen location
glutSolidSphere(.025,15,15); //radius, slices,stacks
glutMainLoop();

and I get a seg-fault..... I have no idea why this is happening. Just this basic sphere image is giving me an error. I have tried to put the glutInit conditions in main() as well as the drawScene() function to no avail. I am really out of a ideas and any help would be greatly appreciated!

Alfonse Reinheart
01-24-2010, 01:54 AM
Basically we are running a multi-threaded C++ application that calls things like opencv and ncurses in addition to opengl.

OpenGL contexts are thread-specific. So if you're in a different thread, you have to make the context current in that thread to be able to render.

Since you're using GLUT, I assume that it is creating a context and making it current in the thread you call "glutCreateWindow" in. You must make sure that all OpenGL calls are made from the same thread.

Since you're using GLUT, I'd suggest not making any OpenGL calls unless they are made in the context of the displayFunc.



glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(400, 400); //set mapping window size
glutInitWindowPosition(600,1); //set screen location
glutSolidSphere(.025,15,15); //radius, slices,stacks
glutMainLoop();


This code looks highly suspect. I'm not familiar with GLUT, so I can only guess.

The first 3 functions look very much like the kind of things you should set before creating the window, not after. I'm guessing that "glutSolidSphere" actually renders a sphere, so it is not something that should be called before creating the window. And I'm not sure, but "glutMainLoop" looks suspiciously like something that will call the display function.

Loderunner
01-24-2010, 11:19 AM
I would love to put all of the opengl data in one thread, however when I call say glutDisplayFunc(drawScene) or even glutDisplayFunc(mapping::drawScene) I receive an error message stating:
Error: argument of type `void (mapping::)()' does not match `void (*)()'
I also tried adding :
glutInit(&argc, argv); //initialize glut
glutCreateWindow("2D map"); //window title
glutDisplayFunc(drawScene);
into mapping.cc's constructor, but got a segmentation fault for that. I managed to pass argc and argv to glutInit by creating a function that receives those variables from main.cc

Alfonse Reinheart
01-24-2010, 12:56 PM
Error: argument of type `void (mapping::)()' does not match `void (*)()'

That's because member pointers are not the same type as regular function pointers. You need to either use a static member or a non-member function.

Loderunner
01-24-2010, 01:39 PM
so declaring drawScene as:
static void mapping::drawScene()
should make it glutDisplayFunc(drawScene) work?

Alfonse Reinheart
01-24-2010, 06:38 PM
should make it glutDisplayFunc(drawScene) work?

It should make it compile.

marshats
01-25-2010, 08:05 AM
An alternative to static class member declarations is seen in the pseudo code using the Singleton code paradigm here (http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=264866#Post2648 66)

Loderunner
01-25-2010, 11:05 AM
Yea, i cant seem to define it as a static void function:
static void mapping::drawScene() {}
gives the error :
mapping.cc:104: error: cannot declare member function ‘static void mapping::drawScene()’ to have static linkage

I have it defined as so in mapping.h:
static void drawScene();

Loderunner
01-26-2010, 12:38 PM
Is it even possible to have all the main glut initialize commands from a function other than main?
eg:
class member called Run()
can it contain:

glutInit(&argc, argv);
glutCreateWindow("2D map");
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(400, 400);
?

Loderunner
01-26-2010, 12:57 PM
would this solve my problems?
http://www.stetten.com/george/glutmaster/glutmaster.html

marshats
01-27-2010, 07:18 AM
Is it even possible to have all the main glut initialize commands from a function other than main?


The issue is one of creating a valid openGL context in which you can issue gl* commands. You can call glut initialization functions (glutInit, glutCreateWindow, etc) anywhere you like but they represent a sort-of "constructor" to borrow a C++ term. They are not strictly constructors but they are REQUIRED to be run first and once. Once you have run those you have "constructed" a valid openGL context so you can start to issue gl* commands (like glClear, glTranslate, etc). If you try to issue gl* commands before openGL context is created you will get errors and even probably segmentation faults. So to answer your question, yes you can call these commands outside main but they must be BEFORE you start issuing gl* commands.

A good analogy would be to make a "Singleton" glut wrapper class. This exposes some underlying information about the openGL state machine -- because openGL is not thread safe and you can only issue glCommands from the same thread as the openGL context was created. You create context and issue commands form that same context's thread.

Note by gl* commands I mean glClear etc (not glut* commands like glutInit etc).

ps I noticed above one of your code snippets


glutSolidSphere(.025,15,15); //radius, slices,stacks
glutMainLoop();

A caveat also to be aware of is that calling some gl* commands before entering glutMainLoop will cause problems -- I don't know the full list but you should limit yourself to openGL state functions before glutMainLoop and avoid actual vertex pushing commands like glutSolidSphere before calling glutMainLoop. I wouldn't be suprised if you get a seg fault if you called glutSolidSphere before entering the glutMainLoop.

Loderunner
01-28-2010, 12:29 PM
anyone?