morphologica icon indicating copy to clipboard operation
morphologica copied to clipboard

how to use this library under wxWidgets

Open asmwarrior opened this issue 1 year ago • 71 comments

Hi, I see this project can draw 3D objects under QT, that's great.

Is it possible to draw something under wxWidgets?

I know how to draw opengl 3D under wxWidgets, but I don't know how to incorporate with this library. (for example, here are the examples: https://github.com/asmwarrior/cb_projects_for_wxWidgets/tree/master/samples/opengl )

Any ideas?

Thanks.

asmwarrior avatar Dec 19 '23 14:12 asmwarrior

The OpenGL drawing code is morph::Visual (see morph/Visual.h). It operates in two 'modes'. In one, mode, which is how it was originally written, morph::Visual 'owns' a GLFW window, which provides the OpenGL context. In order to make it compatible with Qt, I had to make it possible for morph::Visual to be 'owned by' the Qt window, because Qt provides the OpenGL context. In Visual.h, you'll see some ifdefs to this effect.

So for wxWidgets, you'll need to decide which mode would be most appropriate. Does wxWidgets provide an OpenGL context like QtWidgets can?

sebjameswml avatar Dec 19 '23 16:12 sebjameswml

Thanks for the response. I will take some time to learn the code in morph/Visual.h.

In wxWidgets, there is a wxWidgets: wxGLCanvas Class Reference to show the 3D objects, also, there is a wxGLContext to works with the wxGLCanvas.

In my opinion, to draw something, I just need to prepare the VBO, VBA and the shader, and when in the OnPaint event handler, I just need to activate the VBA and shader, and call glDrawXXX like functions.

asmwarrior avatar Dec 20 '23 00:12 asmwarrior

"In my opinion, to draw something, I just need to prepare the VBO, VBA and the shader, and when in the OnPaint event handler, I just need to activate the VBA and shader, and call glDrawXXX like functions."

Exactly! And this is what morph::Visual does. It does this by having a collection of morph::VisualModel-derived objects and its render() method calls the render method of each VisualModel. Each VisualModel has vbo, vba and morph::Visual owns the shaders.

You can refer to viswidget also, which is my Qt way of using morph::Visual to draw in a Qt widget:

https://github.com/ABRG-Models/morphologica/blob/main/morph/qt/viswidget.h

sebjameswml avatar Dec 20 '23 09:12 sebjameswml

btw, I can't help much with code writing at the moment as I'm injured and can only type one-handed.

sebjameswml avatar Dec 20 '23 09:12 sebjameswml

btw, I can't help much with code writing at the moment as I'm injured and can only type one-handed.

Thanks for you help. I think it will take me some time to learn the code. Especially the QT related code.

I hope you will recover from the injury soon.

asmwarrior avatar Dec 20 '23 12:12 asmwarrior

Some good news, I can use this library under wxWidgets, and here is the screen shot:

image

I have add all the source files I use in my own branch, see my commit here

add the wxWidgets GUI support, also add wxWidgets sample code and Code::Blocks project file

Note I use the Code::Blocks as the project file(a cbp file), I'm not familiar with CMake.

asmwarrior avatar Dec 31 '23 13:12 asmwarrior

Well done! I'll see if I can get it to build myself. It should be easy enough to make a cmake lists file so that it works build as another example along with everything else.

sebjameswml avatar Dec 31 '23 20:12 sebjameswml

I have added some fixes in the main git branch in my fork, see here: https://github.com/asmwarrior/morphologica/tree/main

asmwarrior avatar Jan 01 '24 09:01 asmwarrior

Happy New Year! I made some progress this morning towards compiling your new wx program on Ubuntu 22.04 with wxGtk. I've just got to the point where I realise I need wx 3.1 whereas my Ubuntu packaged version of wx is 3.0.5. 3.0.5 doesn't have wxGLAttributes. I'll see if a more recent Ubuntu has wx 3.1, and use that, otherwise I'll see about compiling/installing wx from source.

sebjameswml avatar Jan 01 '24 10:01 sebjameswml

If I remember correctly, the wxGLCanvas has different constructor function prototype between wx 3.0.x and wx 3.2.

The later use wxGLAttributes, the former use some kinds of int *args.

But please note I think you don't need to upgrade to wx 3.1 in your Linux, the OpenGL profile mode(core profile) works under wx 3.0, you just need to modify you code to fit the wxGLCanvas constructor.

asmwarrior avatar Jan 01 '24 11:01 asmwarrior

See this link OpenGL 4.0 in wxwidgets 3.0.4 - wxWidgets Discussion Forum as a reference.

asmwarrior avatar Jan 01 '24 12:01 asmwarrior

Ubuntu 23 has wx 3.2, so I'll work with that- I have a laptop with this version of the OS on it

ABRG-Models avatar Jan 01 '24 12:01 ABRG-Models

It compiles with cmake and wxgtk 3.2. But at runtime: image

sebjameswml avatar Jan 01 '24 12:01 sebjameswml

Perhaps with wxgtk there needs to be a window show/draw command early on?

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

It compiles with cmake and wxgtk 3.2. But at runtime: image

I understand the reason of the alert, you need to only set the context to active on a showed window under Linux. Under Windows, this is not need.

So, you may look at the wxWidgets' opengl sample:

https://github.com/wxWidgets/wxWidgets/blob/master/samples/opengl/pyramid/pyramid.cpp

I think the idea is to first check the window is shown(IsShown return true), then you can active the context.

asmwarrior avatar Jan 01 '24 13:01 asmwarrior

I made these changes in main-wx.cpp to make it compile on linux within the existing cmake build process

diff --git a/examples/wx/main-wx.cpp b/examples/wx/main-wx.cpp
index 0b568e2..219ff4c 100644
--- a/examples/wx/main-wx.cpp
+++ b/examples/wx/main-wx.cpp
@@ -1,11 +1,12 @@
-#define OWNED_MODE
-#define USE_GLEW
-
-#include <gl/glew.h>
+#ifdef USE_GLEW
+# include <gl/glew.h>
+#endif
 #include <wx/glcanvas.h>
 #include <wx/wx.h>
 
-// Note sure why the DELETE macro got conflict with this library
+// Note sure why the DELETE macro got conflict with this library. Seb: Possibly because of
+// morph::key::DELETE. DELETE must be defined in wx somewhere and conflicts with morph::key::DELETE?
+// Not sure of best fix, but leave this for now.
 #ifdef DELETE
     #undef DELETE
 #endif // DELETE
@@ -14,10 +15,6 @@
 #include <morph/GraphVisual.h>
 #include <morph/vvec.h>
 
-// Include the header for morph::wx::viswidget
-#include "morph/wx/viswidget.h"
-
-
 // Define the custom frame class
 class MyFrame : public wxFrame
 {
@@ -27,7 +24,10 @@ public:
         wxGLAttributes vAttrs;
         // Defaults should be accepted
         vAttrs.PlatformDefaults().Defaults().EndList();
-        bool accepted = wxGLCanvas::IsDisplaySupported(vAttrs) ;
+        bool accepted = wxGLCanvas::IsDisplaySupported(vAttrs);
+        if (!accepted) {
+            std::cout << "Warning: wxGLCAnvas::IsDisplaySupported returned false\n";
+        }
         // Create the viswidget as a child of the frame
         widget = new morph::wx::viswidget(this, vAttrs);
 

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

I made these changes in main-wx.cpp to make it compile on linux within the existing cmake build process

diff --git a/examples/wx/main-wx.cpp b/examples/wx/main-wx.cpp
index 0b568e2..219ff4c 100644
--- a/examples/wx/main-wx.cpp
+++ b/examples/wx/main-wx.cpp
@@ -1,11 +1,12 @@
-#define OWNED_MODE
-#define USE_GLEW
-
-#include <gl/glew.h>
+#ifdef USE_GLEW
+# include <gl/glew.h>
+#endif
 #include <wx/glcanvas.h>
 #include <wx/wx.h>
 
-// Note sure why the DELETE macro got conflict with this library
+// Note sure why the DELETE macro got conflict with this library. Seb: Possibly because of
+// morph::key::DELETE. DELETE must be defined in wx somewhere and conflicts with morph::key::DELETE?
+// Not sure of best fix, but leave this for now.
 #ifdef DELETE
     #undef DELETE
 #endif // DELETE
@@ -14,10 +15,6 @@
 #include <morph/GraphVisual.h>
 #include <morph/vvec.h>
 
-// Include the header for morph::wx::viswidget
-#include "morph/wx/viswidget.h"
-
-
 // Define the custom frame class
 class MyFrame : public wxFrame
 {
@@ -27,7 +24,10 @@ public:
         wxGLAttributes vAttrs;
         // Defaults should be accepted
         vAttrs.PlatformDefaults().Defaults().EndList();
-        bool accepted = wxGLCanvas::IsDisplaySupported(vAttrs) ;
+        bool accepted = wxGLCanvas::IsDisplaySupported(vAttrs);
+        if (!accepted) {
+            std::cout << "Warning: wxGLCAnvas::IsDisplaySupported returned false\n";
+        }
         // Create the viswidget as a child of the frame
         widget = new morph::wx::viswidget(this, vAttrs);
 

I think you can commit all your changes to your main git branch(or you can have a test git branch), and I will merge or rebase my forked git branch for testing on msys2.

asmwarrior avatar Jan 01 '24 13:01 asmwarrior

I took out definitions of OWNED_MODE which is defined in your wx/viswidget.h file and USE_GLEW, which should be passed to the compiler as -DUSE_GLEW if required.

I added a use of the bool accepted because I compile morphologica with all the warnings treated as errors.

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

Ok, how about this - you do a pull request for what you have now. I'll then make these changes and commit back and you can test with MSYS2.

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

And we can figure out the issue

It compiles with cmake and wxgtk 3.2. But at runtime: image

I understand the reason of the alert, you need to only set the context to active on a showed window under Linux. Under Windows, this is not need.

So, you may look at the wxWidgets' opengl sample:

https://github.com/wxWidgets/wxWidgets/blob/master/samples/opengl/pyramid/pyramid.cpp

I think the idea is to first check the window is shown(IsShown return true), then you can active the context.

Ok - thanks for the pointers.

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

I took out definitions of OWNED_MODE which is defined in your wx/viswidget.h file and USE_GLEW, which should be passed to the compiler as -DUSE_GLEW if required.

I added a use of the bool accepted because I compile morphologica with all the warnings treated as errors.

I think all the #define in the wx/viswidget.h can be removed, because I can define a macro inside the Code::Blocks cbp file.

asmwarrior avatar Jan 01 '24 13:01 asmwarrior

Ok, how about this - you do a pull request for what you have now. I'll then make these changes and commit back and you can test with MSYS2.

The problem here is: I am using Code::Blocks cbp file for building, and some of the include search path in the cbp file is hard-coded, so in my pull request, do I need add the cbp file?

asmwarrior avatar Jan 01 '24 13:01 asmwarrior

It compiles with cmake and wxgtk 3.2. But at runtime: image

I understand the reason of the alert, you need to only set the context to active on a showed window under Linux. Under Windows, this is not need.

So, you may look at the wxWidgets' opengl sample:

https://github.com/wxWidgets/wxWidgets/blob/master/samples/opengl/pyramid/pyramid.cpp

I think the idea is to first check the window is shown(IsShown return true), then you can active the context.

So the problem is that we have SetCurrent() in the wx::viswidget constructor, which can't be called until the frame is shown, but the frame can't be shown until the constructor has been called. Catch 22.

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

So that context setup code will have to come out of the constructor and be called after viswidget has been created.

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

So that context setup code will have to come out of the constructor and be called after viswidget has been created.

Yes, that's the correct way to set the context to active.

See this FAQ:

FAQ: wxWidgets and OpenGL - wxWidgets Discussion Forum

Especially in the section: Q. About setting a context as "current". And Multi-threading.

asmwarrior avatar Jan 01 '24 13:01 asmwarrior

Okay. Do you have any interest in doing that?

sebjameswml avatar Jan 01 '24 13:01 sebjameswml

Okay. Do you have any interest in doing that?

I do not have a Linux system, so I can't do the code test.

asmwarrior avatar Jan 01 '24 14:01 asmwarrior

Okay, no problem. I'll see what I can do about modifying the design of wx::viswidget

sebjameswml avatar Jan 01 '24 14:01 sebjameswml

Could you open a pull request on your fork of morphologica?

sebjameswml avatar Jan 01 '24 15:01 sebjameswml

Ok, how about this - you do a pull request for what you have now. I'll then make these changes and commit back and you can test with MSYS2.

The problem here is: I am using Code::Blocks cbp file for building, and some of the include search path in the cbp file is hard-coded, so in my pull request, do I need add the cbp file?

Sorry - I hadn't seen this message. We could add your example in 'standalone_examples' along with the cbp file to demonstrate/record how do compile it this way. For now, I don't mind at all if you just leave that file in place and include it in the pull request.

sebjameswml avatar Jan 01 '24 16:01 sebjameswml