In my GLUT program i have created two windows. when i try to close one window entire program shuts down. can anyone tell how to avoid it.
My code to create window is as follows
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(ww,wh);
window1 = glutCreateWindow("sample");
glutReshapeFunc(changeSize);
glutIdleFunc(renderScene);
glutDisplayFunc(renderScene);
window3 = glutCreateWindow("sample2");
glutReshapeFunc(changeSize);
glutDisplayFunc(renderScene2);
glutIdleFunc(renderScene2);
glutMouseFunc(mouse);
glutPostRedisplay();
glutMainLoop();
return 1;
}
I don't recall GLUT being able to close windows independently in the same thread, like that. As you only use a single glutMainLoop() call to get them going, thereby when the main loop is killed for one window, it's killed for all of them.
You could try creating the windows in their own Thread. That might work, but I'm not entirely sure.
Something else you could try, is to use GLFW instead, using GLFW, you need to create the main loop etc, yourself. Bottom line, that's much easier to use and it gives you a lot more control, over your OpenGL programs. Also if you don't already have it, you should get something like GLEW.
You've just left the capabilities of GLUT with this demand. But you're lucky: GLUT =/= OpenGL and there are many other frameworks that will satisfy your needs. How about you take a look at Qt, which offers you not only a runtime environment and a OpenGL widget, but also a large set of widgets to draw UI elements with.
Related
I want to create the opengGL context using freeglut. I will first decide the which context to by checking the supporting version using glew and some other parameters. I know for glew to work, it needs a opengl context. So I first create a context using glutCreateWindow, then check the supported version and then set the version required using the glutInitContextVersion() and destroy the previous window using glutDestroyWindow and recreate the new window by using glutCreateWindow. I get this error Freeglut error: ERROR: No display callback registered for window 1 (I checked 1 is ID for my previous window which I destroyed) . Following is my code
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100, 100);
glutInitWindowSize(900, 600);
int winID = glutCreateWindow("Rotating Cube"); //winID is 1 here
glewExperimental = GL_TRUE;
glewInit();
//I decide the context on some other parameters also except the supported version reported by glew.
//I have tested this with opengl 3.2 core profile as well.
//This is not working even if I forcefully set the opengl version to 2.0
if (glewIsSupported("GL_VERSION_3_1"))
{
glutInitContextVersion (3, 1);
glutInitContextFlags (GLUT_FORWARD_COMPATIBLE);
//glutInitContextVersion (3, 2);
//glutInitContextFlags (GLUT_CORE_PROFILE);
}
else if (glewIsSupported("GL_VERSION_2_0"))
{
glutInitContextVersion (2, 0);
}
glutDestroyWindow(winID);
winID = glutCreateWindow("Rotating Cube"); //winID is 2 here
glutSetWindow(winID);
glutDisplayFunc(RenderScene);
glutIdleFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(ProcessNormalKeys);
glutSpecialFunc(ProcessSpecialKeys);
glutMainLoop();
I think I need to do this as a openGL context is always required for glew to work. I already tried setting the display function on first window as well (though I know I am going to destroy it) but that also didn't work. I am setting the current window to new window and then calling the glutMainLoop. So I think this should work
According to answer by rhashimoto, I tried to put the destroy command at different positions
if (g_winID>=0)
{
glutDestroyWindow(g_winID);
g_winID = -1;
}
I put the destroy command at begining of reshape callback
ERROR: No display callback registered for window 1
The I put the destroy command at beginning of display function
ERROR: Function <glutSwapBuffers> called with no current window defined.
If I put this at end of Display callback, it does not give error but the displayed scene is not correct. Somethings are missing from the scene
So is there some specific callback function I need to put this display command? I dont think there is any destroy callback I can set. yes there is glutCloseFunc but I think that is meant to be called when window is being destroyed that is when glutDestroyWindow has been called on window
I think you can argue that this is a FreeGLUT bug, either in the implementation or the documentation. It looks like glutDestroyWindow() needs to be called from a GLUT callback to work properly.
glutDestroyWindow() mainly puts the window on a list to be destroyed, as well as clearing all callbacks (except a destroy callback). This is probably why setting the display function didn't work for you - it was removed when you called glutDestroyWindow().
Windows are actually destroyed at the end of each main loop. So on the first time through the loop, your window still exists. The fact that it has no display callback makes GLUT unhappy.
The best workaround is probably to arrange to call glutDestroyWindow() only via one of the GLUT callbacks. I don't know if this will make the window briefly flash on the screen. My guess is it won't, but it might depend on the platform.
My program works perfectly fine in a normal 3D with one buffer, it is coded with SFML window management.
I would like to add quad buffered stereo, therefore i changed my drawing code to the following :
glDrawBuffer(GL_BACK_LEFT);
camera->OnMouseMotion(sf::Vector2i(-1,0));
for (auto i = objects->cbegin(); i != objects->cend(); ++i)
(*i)->draw(camera);
glFlush();
glDrawBuffer(GL_BACK_RIGHT);
camera->OnMouseMotion(sf::Vector2i(2,0));
for (auto i = objects->cbegin(); i != objects->cend(); ++i)
(*i)->draw(camera);
glFlush();
camera->OnMouseMotion(sf::Vector2i(-1,0));
Notice that my camera changed are not perfectly right and i know i will have to change these, right now i am focusing on displaying an image just using quad buffered stereo. I noticed in all examples of programs using this stereo that they were initialising the window with something like this :
type = GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH | GLUT_STEREO;
glutInitDisplayMode(type);
Using SFML, such function isn't available, my questions are :
Can i use a low-level openGL function to achieve the same result ? Can i use another window managing library with SFML ? Should i forget SFML for my program and completly change it to another one ?
SFML doesn't have an initialisation function, it creates openGL context automatically, two things you can do :
Modify SFML sources you are using, and try to add somewhere in the window creation function your parameter
change your display library to create the openGL context, however you may or not keep SFML 2D drawing functions, i am not sure these are gonna work if you create your context with glut for example.
EDIT : after a small check, you cannot create a context with another library and still use SFML for drawing simple 2D forms, i am afraid you are forced to let SFML go.
I have reinstalled devcpp 4.9.9.2 on windows xp virtualbox and installed glut and glew.
My original program just used glut, and shows some spheres bouncing around a room. My problem is that once I add in the line
glGenFramebuffers(1, &myBuffer);
my program fails to run. It compiles just fine. But when I run it says "Ass1.exe has encountered a problem and needs to close. We are sorry for the inconvenience.".
If I comment out this line then it works just fine, with balls bouncing around. The glGenFramebuffers is at the bottom of my setup method.
Here is a link to my code. https://dl.dropboxusercontent.com/u/13330596/Exercise1.cpp
This is the code just before I now call glewInit();
// Initialize GLUT.
glutInit(&argc, argv);
// Set display mode with an RGB colour buffer, double buffering and a depth buffer..
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
// Set OpenGL window size
glutInitWindowSize(1000, 1000);
// Set position of OpenGL window upper-left corner
glutInitWindowPosition(100, 100);
// Create OpenGL window with title
glutCreateWindow("Dissertation");
glewInit();
You must call glewInit(); before you can use extended functionality. Probably you didn't so the functions pointers are still null pointer. glewInit must be called after a context has been created and bound. In the case of using GLUT this is right after glutCreateWindow(…);
I was expecting a Linux API similar to the Windows API. All I see on Google is references to Qt and GTK. I really don't need anything more than a simple window to draw on with OpenGL, so these libraries appear bloated for my use. What do Qt and GTK use to create windows under Linux? Is there nothing more low-level?
The X window system generally does the drawing - you then use a toolkit such as Qt or GTK on top of raw Xlib to provide event loops, drag and drop, starting apps on mouseclicks and all the other 'desktop' stuff
It's fairly easy to work directly with Xlib and opengl or if you just want to learn opengl the glut provides the framework you need to display a window, handle mouse/keyboard events and so on.
For OpenGL, the easiest way to do it is by using GLUT or SDL. Here's an approximate example using GLUT:
#include <GL/glut.h>
int main (int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow("My new window");
/* ... */
}
You really want to avoid using Xlib directly as it's extremely tedious to use. Furthermore, GLUT and SDL make it easier to port your OpenGL application to different platforms.
Updated answer for 2019. Unix like systems normally uses the X window system. You can work with it directly using Xlib this is the low level API. But you likely need a more welcoming and cross-platform solution. You can use:
OpenGL Utility Toolkit - GLUT
Simple and Fast Multimedia Library - SFML
Simple DirectMedia Layer - SDL
Graphics Library Framework - GLFW (my recommendation)
GLFW is written in C and has native support for Windows, macOS and many Unix-like systems using the X Window System, such as Linux and FreeBSD.
Once installed, create a window with :
#include <GLFW/glfw3.h>
.
. //Entry and glfwInit()
.
GLFWwindow* window = glfwCreateWindow(1000, 1000, "MyWindow", NULL, NULL);
glfwMakeContextCurrent(window);
Ax Martin said, X11 (or its fork XOrg these days) is the windowing system, but you can actually write X11 applications (i.e. clients) without using a toolkit, just using the X libraries. See here for documentation.
It is generally not the best idea to do so, as it is rather painful and will involve a lot of code for relatively simple applications to work as you expect them to.
I know this is an old post. But for people that have found this recently like me here is a useful diagram. It is just a matter of how far down do you want/need to go in abstraction; if you arent careful you'll end up trying to code in binary. XLib is a dependency for SFML and XLib has it's dependencies.
Diagram of GUI Layers
Assuming by simple window you mean the drawing should appear on the screen:
The Weston compositor uses EGLOutput/EGLDevice to display the composited Weston desktop or individual Wayland applications on a physical display device.
For drawing with other manufacturer's hardware studying GEM may give hints.
I am writing an OpenGL app using Qt, and it builds and runs fine on my desktop, but when I try running the exact same code on my laptop, it builds but does not output anything? Here is my main.cpp
#include <QtGui/QApplication>
#include <QtOpenGL/QGLWidget>
#include "GLWidget.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
GLWidget window;
window.resize(1050,700);
window.setFixedSize(1050, 700);
window.show();
return app.exec();
}
I do not want the user to be able to resize the window, hence the fixed size. If I set a breakpoint on the last line of main, it never reaches it on my laptop. I have stepped through the code and right after show() is called (which is just an inline function) the debugger finishes with code 0. I checked all the project build and run settings, they are the same on both machines.
My desktop has a 1920x1080 monitor, but my laptop is only 1366x768 could this have anything to do with it? Is there some sort of internal check going on under the hood in Qt that depends on my screens resolution? That is pretty much the only thing I can think of.
I do not want the user to be able to resize the window
May I ask why? May I presume you want the window to be a fixed size, because you want to use OpenGL to generate a image exactly this size? If so, then I must tell you, it will not work that way. OpenGL implementations will only render what will become visible on the screen (pixel ownership test). If parts of the window are not visible (and in your case this will be the case on the laptop) those pixels are simply not rendered. Reading out the framebuffer will leave those pixels undefined.
The proper way to tackle this problem is using either a PBuffer, or a Frame Buffer Object (FBO). FBOs are easier to use, but not as widely supported on Windows (Intel graphics on Windows have rather poor FBO support). FBOs are supported by all Linux OpenGL implementations (Mesa (also does Intel), ATI/AMD and NVidia). There are numerours FBO and PBuffer tutorials in the web.