I was working with a project that reads a data file, performs some calculations, and show results on standard output. Later i wanted to give a 3D graphical view to the results, so I made a new OpenGL project that shows data as 3D object.
Now the problem is, I can not figure out a way to integrate these two independent projects, because the main() in my OpenGL project goes in a non terminating glutMainLoop() loop, and I am unable to figure out where to put the loop in main() of my first project !
/**** Proj1 ****/
int main()
{
while(ESC key not pressed)
{
// read data file
// do some processing
// show results on standard output
}
}
/**** Proj2 ****/
int main()
{
glutInit(&argc, argv);
Init();
glutDisplayFunc(Display);
glutKeyboardFunc(Keyboard);
glutMouseFunc(Mouse);
glutIdleFunc(Idle);
glutMainLoop();
}
Least mixing of codes between Proj1 & Proj2 is requested.
Is it possible to do something like:
/**** Proj1 ****/
#include <filesFromProj2>
int main()
{
while(ESC key not pressed)
{
// read data file
// do some processing
proj2.showResult(result) // how to do this ?
}
}
The most simple solution would be to ditch GLUT and use a OpenGL windowing framework that lets you implement the event loop. GLFW would be the immediate choice. Then instead of having an opaque glutMainLoop that never returns you instead call glfwPollEvents beside your your stdio processing.
GLUT decouples your event handling code from your display code. It feels strange if you're used to the paradigm where you have full control over the loop, but it's not really hard to deal with. Basically, you need to maintain a state that your glutDisplayFunc will react to, and update that state in your glutKeyboardFunc. So in pseudocode (it seems like you have the C++ down):
displayFunc:
if state.showProj1
proj1.showResult
else if state.showProj2
proj2.showResult
keyboardFunc
if keyPressed(esc)
state.showProj1 = false
state.showProj2 = true
glutPostRedisplay()
Ok, so that is some pretty naive code there, but it should get the idea of how to make changes to your state in response to user input which in turn affects what you are rendering.
As mentioned in the previous answer, if you want explicit control of the program loop (as opposed to the event-based paradigm), you have some good options in GLFW and SDL, but of course there will be some ramp-up with those since GLUT does things in a pretty different way.
Found a solution so answering it myself for everyone's reference:
I desperately needed a workaround without having to change my existing glut base code into GLFW and SDF etc.
Digging more on internet I found that freeglut supports a function glutMainLoopEvent() that "causes freeglut to process one iteration’s worth of events in its event loop. This allows the application to control its own event loop and still use the freeglut windowing system."
Also, freeglut supported all the functions of glut (or atleast supported all the glut functions used in my prog). So,i didn't have to change my glut base code.
The pseudo-code for the workaround is as below. I welcome your comments.
#include <gl/freeglut.h>
#include <filesFromProj2>
int main()
{
glutInit(&argc, argv);
Init();
glutDisplayFunc(Display);
glutKeyboardFunc(Keyboard);
glutMouseFunc(Mouse);
glutIdleFunc(Idle);
// glutMainLoop(); // Do not use this
while(ESC key not pressed)
{
// read data file
// do some processing
proj2.showresults(results)
glutMainLoopEvent(); // One iteration only
Display(); // Call the func used with glutDisplayFunc()
}
glutLeaveMainLoop();
}
I also thought that multi-threading, may also solve this problem. One thread for glutMainLoop() and another for data processing !!
Related
I went throught suggested "questions" about my problem. However neither does not solve it.
I program two windows. The second window is opening from first window. I need active the both windows, however to start the first window(MainWindow) I use:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.setWindowModality(Qt::NonModal);
return a.exec();
}
As was mentioned, the second window is started from pushButton, which is situated in first window(MainWindow) by same way.
void MainWindow::on_pushButton_2_clicked()
{
Graphics gr;
gr.setWindowModality(Qt::NonModal);
gr.exec();
}
I changed modality to NonModal,however the problem is without change. The Non-Modal mean:"The window is not modal and does not block input to other windows." <- from documentation
By documentation is recommended to avoid used .exec(). The alternatives are .show() and open(), which i tried. After the modification, the second window is shut down immediately after opening. after open immediately shut down.
Do you have any idea, how to solve that?
Graphics gr; defines a local variable, so the object is destructed as soon as it goes out of scope (at the end of your function).
In Qt, the typical approach is to work with pointers to Qt widgets (and, more generally, QObjects), but have a parent for each – the parent will clean it up.
Try this instead:
auto gr = new Graphics(this);
gr->setWindowModality(Qt::NonModal); // this is the default, no need for this call
gr->show();
This way the window will survive until your main window is destructed. In Qt there is also a mechanism for widgets/objects to self-destruct:
this->deleteLater();
So for example if you want to close and cleanup gr you can use that mechanism (you could also store gr as a member and call gr->deleteLater().
I'm trying to make an OpenGL program on Windows. Since the main exe file was getting bigger and bigger, I decided to split it into DLLs. And this is how my problem is started.
For ImGui functions, I created a class. Here is render() function of my class:
cout << "render" << endl;
imgui_newFrame();
{
ImGui::SetNextWindowSize(ImVec2(30, 30), ImGuiSetCond_FirstUseEver);
ImGui::Begin("Test", &show_another_window);
ImGui::Button("Test Window");
ImGui::End();
}
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
ImGui::Render();
Before calling render() function in my class, I initiate ImGui in another function in my class with this:
if (!imgui_init(glfw_window)) {
return false;
}
And here is my main glfw loop:
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glfwPollEvents();
MyMyGuiClass.render(); //here i ask my class to render imgui
glfwSwapBuffers(window);
}
With this code I am able to make ImGui clear window color (glClearColor function works and my console prints "render")
But it doesn't show anything else.
By the way, here is the command working perfectly when I run it.
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glfwPollEvents();
imgui_newFrame();
{
ImGui::SetNextWindowSize(ImVec2(30, 30), ImGuiSetCond_FirstUseEver);
ImGui::Begin("", &show_another_window);
ImGui::Button("Test Window");
ImGui::End();
}
glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w);
ImGui::Render();
glfwSwapBuffers(window);
}
I'm using VS2017 and my compiler doesn't show any warnings or errors when i compile this. Also I tried to make my class' functions static, and I got nothing.
So simply, is ImGui not able to render when called from inside a class?
The problem you're running into is that ImGui maintains a global state and that this state has to be kept somewhere. ImGui keeps it around in a module-local global symbol.
Note the "module-local" here! It means that every DLL (and the main EXE) gets its very own copy of that state. So doing things with ImGui in DLL "A" (or EXE "1" for that matter) will operate on its very own instance of ImGui state.
There is a solution to this, by making that pesky ImGui global state shared across DLLs. How to share data between DLLs is described in MSDN here https://msdn.microsoft.com/en-us/library/h90dkhs0(v=vs.90).aspx – as for the details in ImGui itself. It mostly boils down to the ImGuiContext that's being used. For now this is a module-local global variable, but the ImGui devs plan on making it explicit-per call and user managed eventually.
Comment from the ImGui code:
// Default context storage + current context pointer. Implicitely used by all
// ImGui functions. Always assumed to be != NULL. Change to a different context
// by calling ImGui::SetCurrentContext() ImGui is currently not thread-safe
// because of this variable. If you want thread-safety to allow N threads to
// access N different contexts, you might work around it by: - Having multiple
// instances of the ImGui code compiled inside different namespace
// (easiest/safest, if you have a finite number of contexts) - or: Changing
// this variable to be TLS. You may #define GImGui in imconfig.h for further
// custom hackery. Future development aim to make this context pointer explicit
// to all calls. Also read https://github.com/ocornut/imgui/issues/586
In c++, we are used to see that opengl is installed in main function.Such as-
int main(int argv,char **argc){
glutInit(&argv,argc);
glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB|GLUT_DEPTH);
..............................
}
But without this main function,how can we declare opengl in other sub functions?
Such as-
int main(){
...........}
int installopengl(int argv,char **argc){
glutInit(&argv,argc);
glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB|GLUT_DEPTH);
..............................
}
Maybe I misunderstood - why cant you directly call the function like below ?
int main(int argv,char **argc) {
installopengl(argv, argc);
...........
}
int installopengl(int argv,char **argc) {
glutInit(&argv,argc);
glutInitDisplayMode(GLUT_DOUBLE| GLUT_RGB|GLUT_DEPTH);
..............................
}
Please get your terminology right. OpenGL is not installed in a program. It get's initialized.
Also the pattern you quoted is GLUT initialization. GLUT is not OpenGL, but a simple windowing framework, that creates a OpenGL context for you to use to draw to the window. But there are several other frameworks as well.
Then you seem to completely misunderstand what the main function does. main is the program entry point, the very first function that gets called in a process after the runtime environment has been set up. main can call any function, and you can simply call a dedicated framework initialization there. If it needs parameters from main you simply pass them along.
While it is defiantly not recommended, you can always do this:
int i = 0;
glutInit(&i, NULL);
The issue with doing it this way is that you won't be able to pass any information to the glut library from the command line.
I am creating an application using SDL2 & OpenGL, and it worked fine on 3 different computers. But on another computer (an updated arch linux), it doesn't, and it crashes with this error:
OpenGL context already created
So my question is: How do I check if the OpenGL context has already been created? And then, if it is already created, how do I get a handle for it?
If I can't do this, how do I bypass this issue?
SDL2 does not in fact create an OpenGL context without you asking to make one. However, if you ask it to create an OpenGL context when OpenGL doesn't work at all, SDL2 likes to, erm, freestyle a bit. (The actual reason is that it does a bad job in error checking, so if X fails to create an OpenGL context, it assumes that it's because a context was already created)
So, to answer the third question ("how do I bypass this issue"), you have to fix OpenGL before attempting to use it. Figures, right?
To answer the first and second, well, no API call that I know of... but you can do it a slightly different way:
SDL_Window* window = NULL;
SDL_GLContext* context = NULL; // NOTE: This is a pointer!
...
int main(int argc, char** argv) {
// Stuff here, initialize 'window'
*context = SDL_GL_CreateContext(window);
// More stuff here
if (context) {
// context is initialized!! yay!
}
return 2; // Just to confuse people a bit =P
}
I am brand new to c++ so I apologize if this is a stupid question but I can't seem to find the answer to it.
I have been using Processing for a while now and would like to start using c++ because I heard it is faster and a program I made is too long/dense for Processing to run at a reasonable speed.
In Processing there is a setup void which runs once and then the draw void which runs continuously after that. This is what I am used to and I need it to make remake a program in c++ (a chess AI).
Is there a way to get int main to run continuously? If not can I have it call a function that will run continuously?
Also is there a way to make a window pop up when you run the program which you can draw geometry to? (I will need to make pieces that can be manipulated by a mouse ideally)
I'm using Xcode by the way
main() should typically do your setup and then start the main message-processing loop provided by your toolkit. The message processing loop will run continuously until the user requests your application to quit (or you ask the toolkit to shut down your app).
Your toolkit will call your draw function whenever your window needs to be painted. It will call other functions when user input such as keypresses or mouse clicks happen.
For example, if you were using the GLUT toolkit (for OpenGL, a very popular drawing API supported on Mac, Windows, Linux, and many mobile devices), your main function might look like this (complete tutorial here):
void main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_SINGLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow("My First openGL Program");
glutDisplayFunc(render);
glutMainLoop();
}
For Cocoa, the OSX native API, it might look like this (more information and links here):
#import <Cocoa/Cocoa.h>
int main(int argc, const char** argv)
{
return NSApplicationMain(argc, argv);
}
May I suggest that instead of asking very rudimentary questions like this on StackOverflow, you go and invest your time reading one of the thousands of introductory C++ tutorials that are scattered all over the web.
After a couple of hours of reading you'll find that questions like this are answered faster via a Google search.
Good luck with your learning.
You should not try to get main() to run continuously.
You may instead do something like this:
int main() {
while (true) {
//call functions here
}
return 1;
}
In C++, each function is defined by it's call and it's return. For example:
void foo()
{
cout << "hello world!";
return;
}
int main()
{
foo();
return 0;
}
When foo() is called, it runs until the return statement. If we want foo to run for some indeterminate amount of time, we could, for example:
void foo()
{
bool isExiting = false;
char input;
while( isExiting != true )
{
cout << "Exit? ";
cin >> input;
if ( input == 'y' )
{
isExiting = true;
}
return;
}
}
int main()
{
foo();
return 0;
}
This is a kind of ugly example - using cin to a char and whatnot - but it gets the idea across. The while loop will run forever and the innards of it (well, it's logic, anyway) could be replaced with whatever your program needed to do.
Make sense?
There are plenty of options as far as graphics libraries go; you can use SDL, GLUT/OpenGL, DirectX, even good ol' Win32. However, for someone who is relatively new to things as rudimentary as while loops, I suggest that you stay off the C++ for a while, as there are many peculiarities that might prove to be enormous roadblocks. If you really need every ounce of speed, I recommend that you make a DLL with your time-critical algorithms and use it in conjunction with a simpler language that supports DLL's, and provides a relatively developer-friendly interface. Game Maker comes immediately to mind, although I'm sure there are many options out there.
Best of luck.
I'd recommend having a look at Cinder or OpenFrameworks as a neat transition from Processing.org - especially if you're planning on doing multimedia applications (which, if you were using Processing, is likely)
They both provide a very similar layer to that of Processing, and will ease your journey somewhat.
You could also implement your own basic framework on top of SDL if you feel up to it.
As a more general answer to your question, the main() function is basically the same as the setup() function in Processing.org - with the main distinction being that it has to call a (user-provided) draw() function or equivalent.
So a rudimentary equivalent would be:
bool quit = FALSE;
void setup() {
// initialise the screen and so forth
}
void draw() {
// perform some drawing and update tasks
}
int main(int argc, char *argv[]) {
setup();
while (!quit) {
draw();
}
shutdown();
return 0;
}
NB: the above will probably compile, but it would do nothing except loop and potentially bog up your machine since it's not connected to any graphics library and is getting no user input to modify the quit boolean.
finally, I'll quote a section from the Cinder faq:
I’m experienced with Processing, but I
think I’m ready to try something new.
Is Cinder right for me?
Very possibly.
First though, be sure you really need
to move on to Cinder. Have you already
experimented with using an external
IDE like Eclipse? Are you using native
OpenGL calls instead of PGraphics?
What about experimenting with Toxi’s
excellent libraries? You’ll learn some
things that will make an eventual
transition to Cinder much easier, and
as much as we’re into C++, it’s easy
to underestimate how far Processing
can take you. All that said, don’t let
us talk you out of this either — if
you’re excited about learning Cinder,
we’re excited to have you, and we bet
you’ll find it’s easier to get started
than you might imagine.