I'm using glutMouseFunc(mouseFunction); as a callback however I keep getting the Access violation reading location 0x000000b0 at this line glutMouseFunc(mouseFunction);
I'm not using any of the glutInit functions because they interfere with the program and they are not essential anyways.
Does anyone know why I'm getting this error when at this callback?
Here is my initialize function:
int Initialize()
{
/* Bunch of code here that is irrelevant to the problem.......*/
glutMouseFunc(mouseFunction); // Error occurs here.
}
And here is my mouseFunction:
void mouseFunction(int button, int state, int x, int y){
if(button==GLUT_MIDDLE_BUTTON && state==GLUT_DOWN)
{
printf("Pressed middle mouse button!");
}
}
I've noticed one thing though, there error does not occur when I call the mouseFunction() as a normal function call in my Initialize method however once I try to use the mouseFunction with glutMouseFunc(mouseFunction), than the error happens so I believe this is more of an error with glutMouseFunc.
I'm not using any of the glutInit functions because they interfere with the program and they are not essential anyways.
This is your problem. If you're going to use GLUT, use it correctly.
The glutInit() function is essential - part of what it does is initializing internal state within GLUT. As you've discovered, with this state not properly initialized, other parts of GLUT (such as mouse event handling!) may not work properly.
Given your comments to the other questions your problem is simply, that you call glutMouseFunc without a GLUT window. Trying to register GLUT event callbacks without proper initialization or without a GLUT window created will crash your program.
You also say "GLUT interferes" with your actual window. So why would you try to register a GLUT callback at all if you don't have a window that could actually receive the events for GLUT to dispatch?
You should use the mouse event handling of the window you've already got. And what are you using GLUT for then anyway? The whole purpose of GLUT is to create a window for you and do event management. If you don't use GLUT for that, then don't use GLUT at all.
If it's for the teapot, well, you can have that without GLUT as well.
Related
I'm trying to build an application that can spawn a window on a separate thread. Let me explain a simple version. My main creates an object that has a window, let's call this object a menu. From the menu you can select what to do, for example open up an image to a new window. This whole object, or the object's "game loop" needs to be on a separate thread so that I can still keep interacting with the menu. I also need to interact with the image viewer.
My question is, what is the proper way of doing this?
I haven't really used threads a lot before. But from what I understand I need to detach the thread to create a daemon thread.
I tried to play around with the thread to create this but I kept getting these errors:
Failed to activate the window's context
Failed to activate OpenGL context: The requested resource is in use.
I'm not certain what causes this, all objects, like my windows are different instances. The application will still run fine even with these errors.
My application is quite big so here's an extremely simplified version of the code I've tried.
int main()
{
Menu menu; // this spawns a window
menu.run(); // let's say for simplicity this doesn't do anything else other than
// create a new window (the image viewer)
}
...
void caller(Image_view *img_view)
{
img_view->run();
}
void Menu::run()
{
Image_view *img_view = new Image_view(); // This creates the window
this->thread = new std::thread(caller, img_view);
this->thread->detach();
while (1); // This is here to keep the application running,
// in a real application this method would look different.
// This whole thread call would be in an event handler instead,
// but for this example I tried to make it as simple as possible
}
...
void Image_view::run()
{
while (running)
{
update(); // Event handler and whatever
render(); // Renders the image and whatever
}
this->window->close();
}
I mostly want to know if I'm using the thread correctly or not in an application like this. Also if you have any insight as to what the error message means, explaining it would be greatly appreciated. I should also mention that I'm using SFML for rendering and creating the window instance.
The tutorials I found about the threads are always something extremely simple which doesn't involve any window or anything that could for example cause that error message. So I figured someone smarter here might know the proper use of the thread in my case.
Thanks in advance!
I'm using my own variant of a wxPanel which itself makes use of its own paint-method to draw a custom image m_image:
void wxImagePanel::OnPaint(wxPaintEvent & evt)
{
wxPaintDC dc(this);
dc.SetBackground(*wxWHITE_BRUSH);
dc.Clear();
dc.DrawBitmap(*m_image,6,4,false);
wxWindow::OnPaint(evt);
}
The final call to wxWindow::OnPaint(evt) is there to let wxWidgets draw some GUI-elements on top of that image.
This works and compiles well with Windows, but when trying to build this application with Linux (Ubuntu 22.04LTS), I get an error:
error: ‘OnPaint’ is not a member of ‘wxWindow’
335 | wxWindow::OnPaint(evt);
| ^~~~~~~
The same happens when I try wxPanel::OnPaint(evt).
So, how can it happen that this does not compile for Linux only? Can't OnPaint() be found in wxWindow?
You should never call the base class event handler directly and not only because it may not exist but because the event handling logic in wxWidgets is more complex, in general, than that. Instead, you should either process the event (which you will typically do for wxEVT_PAINT, it doesn't make much sense to paint the window yourself and then do something else) or not, and in the latter case you need to call evt.Skip() to let the event handling code know that it should keep processing the event.
Again, for wxEVT_PAINT events you almost never want to do this anyhow. But for some other events, e.g. focus ones, you almost always do need to call Skip().
I've created an application with Qt Creator (OS Ubuntu 13.04). One function creates a window and draws a graphic using GLUT library, picture is right. But when I try to close window and continue working with my program, it terminates. How can I avoid this?
There is the code of my function:
void plot(int argc, char**argv,.../*other arguments*/)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_ALPHA);
glutCreateWindow("Green Window");
//some code
//...
glutDisplayFunc( draw );
glutMainLoop();
}
Application output prints "... exited with code 0"
If you read e.g. this reference of glutMainLoop you will see that glutMainLoop never returns. That means it will call exit directly instead of returning.
If you're using Qt, then it's able to open windows containing OpenGL contexts, windows compatible with the rest of Qt and which you can close at will.
You might want to switch to freeglut which has implemented the function glutLeaveMainLoop(). As the documentation says:
The glutLeaveMainLoop function causes freeglut to stop its event loop.
Usage
void glutLeaveMainLoop ( void );
Description
The glutLeaveMainLoop function causes freeglut to stop the event loop. If the GLUT_ACTION_ON_WINDOW_CLOSE option has been set to GLUT_ACTION_CONTINUE_EXECUTION, control will return to the function which called glutMainLoop; otherwise the application will exit.
If the application has two nested calls to glutMainLoop and calls glutLeaveMainLoop, the behaviour of freeglut is undefined. It may leave only the inner nested loop or it may leave both loops. If the reader has a strong preference for one behaviour over the other he should contact the freeglut Programming Consortium and ask for the code to be fixed.
Changes From GLUT
GLUT does not include this function.
Source:
http://freeglut.sourceforge.net/docs/api.php
For FreeGlut. If You want to close only window which has created with GLUT. Look:
int handle = glutCreateWindow("Red square example");
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
No thanks.
I know that in order to write a GTK application, I write a bunch of code which describes what is put in the main window, then I call:
gtk_main();
Any code statements after this do not get executed.
Now let's suppose I'd like my GTK app to display something I wrote with glut, which itself contains a bunch of statements about what graphics need to be set etc. then ends with the statement:
glutMainLoop();
Anything after this is not executed.
So my problem is that either of these two statements prevents me from calling the other.
Is there a way to execute a glut main loop inside a GTK widget ?
Is there a way to write a code that could somehow simultaneously call both a GTK main loop and a glut main loop (but called from the main program and rendered in a separate X window, not within a widget)? I've got a feeling this could be done with "threads"...
You don't. There's generally no point to it.
GLUT is a library for creating and managing OpenGL windows. GTK already has an OpenGL window in it. If you're using GTK, then there's no point in using GLUT. It's like having two vector math libraries or something.
You are running the main loops. gtk_main() runs until gtk_quit() is called.
gtk_main() at GTK.org
Runs the main loop until gtk_main_quit() is called. You can nest calls to gtk_main(). In that case gtk_main_quit() will make the innermost invocation of the main loop return.
Also, glutMainLoop() works the same way, it processes GL events forever.
glutMainLoop() at OpenGL.org
glutMainLoop() enters the GLUT event processing loop. This routine should be called at most once in a GLUT program. Once called, this routine will never return. It will call as necessary any callbacks that have been registered.
So, you you wan't both of these things to execute at the same time (I think they might interfere with each other so you might get unexpected results) then you will need to call gtk_main_iteration() from inside glut.
gtk_main_iteration() at GTK.org
Runs a single iteration of the mainloop. If no events are waiting to be processed GTK+ will block until the next event is noticed. If you don't want to block look at gtk_main_iteration_do() or check if any events are pending with gtk_events_pending() first.
Now.. GLUT doesn't have an equivalent to gtk_main_iteration() so you are going to need to register GLUT callbacks.
You could register a callback with GLUT that runs gtk_main_iteration() using glutIdleFunc(void (*func)(void)) which will run a callback for every frame - glutIdleFunc()..
Or you could give a callback to glutTimerFunc(unsigned int msecs,
void (*func)(int value), value) to call and check the return value of gtk_main_iteration() every 200msec or so.
I'd probably experiment with both, glutIdleFunc() might not always get called regularly enough for good responsiveness.
It really is worth looking at driving GTK's GL support though.
I have a program that uses GLUT for its OpenGL rendering. Now I need it to be inside of a MFC project so that it can work with another program component.
I've followed this tutorial: http://www.codeguru.com/cpp/g-m/opengl/openfaq/article.php/c10975__1/Setting-Up-OpenGL-in-an-MFC-Control.htm
I am calling the function that was the GLUT display callback when the timer fires, but that's not working because the rendering depends on something that happens in the GLUT idle callback. I don't understand where I should call the GLUT idle callback in my MFC program. Is there a separate event handler I should make for it, and if so, which event? Or am I doing something else completely wrong? I'm fairly familiar with OpenGL but this is my first experience with MFC so I am probably erring on that side.
Thanks so much for your time; I really appreciate it!
I just browsed the tutorial you've linked to; on page two, something along the following lines can be found (I cleaned up the code a little bit):
void COpenGLControl::OnTimer(UINT nIDEvent)
{
if(nIDEvent==1)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
oglDrawScene();
// try to insert your idle function code here
SwapBuffers(hdc);
}
CWnd::OnTimer(nIDEvent);
}
So, basically this is the replacement for glutIdleFunc suggested by the tutorial. I'd simply try to insert the code called in your idle function before the call to SwapBuffers.
I hope that helps.