Code Monkey home page Code Monkey logo

Comments (72)

asmwarrior avatar asmwarrior commented on June 10, 2024 1

Hi, I think you can follow this link:

https://github.com/lszl84/wx_opengl_tutorial/blob/main/src/main.cpp

This code should work under Linux, and is much simpler than the wx's opengl sample.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024 1

With the above changes, I can build the wx-sample3.cpp, and when running, it gives me correct window output, see below:

image

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024 1

Do you know if wxWidgets would also delete a wxGLContext which is a wxObject?

I just checked the wxwidgets' official opengl sample code and my own wxWidgets opengl application code, wxGLContext should be explicitly deleted by user in the destructor of the wxGLCanvas derived class.

EDIT

I think the current way is OK, because you are using std::unique_ptr<wxGLContext> glContext;

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024 1

Could you give this another test?

I just tried the recent wx-graph1.cpp, and it builds and runs correctly under my Windows 10 64bit with msys2's 64bit GCC (mingw64) and Code::Blocks.
Good work!

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024 1

One suggestion: You can mention the wxWidgets port in the main home page here, I see QT port is already mentioned:

https://github.com/ABRG-Models/morphologica/blob/main/README.md

Thanks.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024 1

By the way - I'll go through and unify the function naming in morph::wx::Canvas once we're happy with the design. setupVisualModels -> SetupVisualModels etc

I totally agree.

I come from wxwidgets world, and all functions there are something like SetupVisualModels.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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?

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

"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

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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

from morphologica.

ABRG-Models avatar ABRG-Models commented on June 10, 2024

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

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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);
 

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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?

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Okay. Do you have any interest in doing that?

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

Okay. Do you have any interest in doing that?

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

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

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.

Having #define OWNED_MODE 1 is ok in viswidget.h because that one has to be defined in any case. Could wrap it in #ifndef OWNED_MODE ... #endif though.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

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.

I have add the PR now, see here:
#156

from morphologica.

optseb avatar optseb commented on June 10, 2024

I've had a little hack around here, but I need to go a bit deeper with wxWidgets and the current design, so I've not been able to get it working on wxGTK yet. See https://github.com/ABRG-Models/morphologica/tree/issue/wxWidgets_154

from morphologica.

optseb avatar optseb commented on June 10, 2024

Thanks for the link - it'll be helpful. The difficulty is not so much figuring out the example code, it's more the architectural decisions about how to build a morph::Visual containing widget/canvas or even if that is the right choice with wxWidgets. I'll see if I can find some more time to devote to this soon.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Progress! See wx-example3.cpp:
https://github.com/ABRG-Models/morphologica/blob/issue/wxWidgets_154/examples/wx/wx-example3.cpp

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

wx-example3

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

I made a new include file called morph/wx/viswx.h which has both a morph::wx::Canvas and a morph::wx::Frame following the hello world example code you posted. I'm happy with the design now. I'll see if I can make a dynamic example, and will clean up the examples/wx folder before I merge this into main.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

Good work! Grad to see it shows a demo under Linux.

I looked at the code, and I see some issues, see below:

-                    this->canvas = new morph::wx::Canvas(this, vAttrs);
+                    this->canvas = std::make_unique<morph::wx::Canvas>(this, vAttrs);

I don't think you need a std::unique here, because Automatic Deletion of Child Windows.

So, the canvas is a child window, if the parent window get closed, it children will get deleted automatically. No memory leak.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

The name "DELETE" should be handled carefully.

I try to find which file defines this macro by adding such code:

diff --git a/morph/keys.h b/morph/keys.h
index 0fadf3c..afb744f 100644
--- a/morph/keys.h
+++ b/morph/keys.h
@@ -71,6 +71,9 @@ namespace morph {
         static constexpr int TAB              =  258;
         static constexpr int BACKSPACE        =  259;
         static constexpr int INSERT           =  260;
+#if defined (DELETE)
+        #define DELETE XXXXXXX
+#endif // defined
         static constexpr int DELETE           =  261;
         static constexpr int RIGHT            =  262;
         static constexpr int LEFT             =  263;

Now, I got such message when compiling.

In file included from F:/code/morphologica/morph/Visual.h:48,
                 from F:/code/morphologica/morph/wx/viswx.h:19,
                 from F:\code\morphologica\examples\wx\wx-example3.cpp:8:
F:/code/morphologica/morph/keys.h:75: warning: "DELETE" redefined
   75 |         #define DELETE XXXXXXX
      | 
In file included from F:/msys2/mingw64/include/minwindef.h:163,
                 from F:/msys2/mingw64/include/windef.h:9,
                 from F:/msys2/mingw64/include/windows.h:69,
                 from F:/msys2/mingw64/include/winsock2.h:23,
                 from E:/code/wxWidgets-3.2.4/include/wx/msw/wrapwin.h:46,
                 from E:/code/wxWidgets-3.2.4/include/wx/msw/init.h:27,
                 from E:/code/wxWidgets-3.2.4/include/wx/init.h:58,
                 from E:/code/wxWidgets-3.2.4/include/wx/app.h:23,
                 from E:/code/wxWidgets-3.2.4/include/wx/wx.h:25,
                 from F:\code\morphologica\examples\wx\wx-example3.cpp:1:
F:/msys2/mingw64/include/winnt.h:3009: note: this is the location of the previous definition
 3009 | #define DELETE (__MSABI_LONG(0x00010000))

So, it is defined in winnt.h.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

Also, to build the wx-wxample3.cpp, I have to change the json search file path

diff --git a/morph/Visual.h b/morph/Visual.h
index 83cfb29..ca49c4e 100644
--- a/morph/Visual.h
+++ b/morph/Visual.h
@@ -48,7 +48,7 @@
 #include <morph/keys.h>
 
 #include <morph/VisualResources.h>
-#include <morph/nlohmann/json.hpp>
+#include <nlohmann/json.hpp>
 #include <morph/CoordArrows.h>
 #include <morph/Quaternion.h>
 #include <morph/TransformMatrix.h>

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

The name "DELETE" should be handled carefully.

This is interesting. morph::key::DELETE in morph/keys.h is defined as a constexpr int inside a struct.

I tried to mess things up by adding the line

#define DELETE

at the start of wx-example3.cpp

and sure enough:

[seb@minimonster 11:40:04 build]$ make wx-example3
[  0%] Building CXX object examples/wx/CMakeFiles/wx-example3.dir/wx-example3.cpp.o
In file included from /home/seb/models/morphologica/morph/Visual.h:48,
                 from /home/seb/models/morphologica/morph/wx/viswx.h:19,
                 from /home/seb/models/morphologica/examples/wx/wx-example3.cpp:10:
/home/seb/models/morphologica/morph/keys.h:74:47: error: expected unqualified-id before ‘=’ token
   74 |         static constexpr int DELETE           =  261;
      |                                               ^
compilation terminated due to -Wfatal-errors.
make[3]: *** [examples/wx/CMakeFiles/wx-example3.dir/build.make:76: examples/wx/CMakeFiles/wx-example3.dir/wx-example3.cpp.o] Error 1
make[2]: *** [CMakeFiles/Makefile2:4780: examples/wx/CMakeFiles/wx-example3.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:4787: examples/wx/CMakeFiles/wx-example3.dir/rule] Error 2
make: *** [Makefile:2194: wx-example3] Error 2

So the problem is that the token DELETE has been defined either in your system in winnt.h or in my test example, at the start of the .cpp file.

It indicates the good C/C++ practice of using all caps only for definitions and using lower/mixed case for variable names.

The reason I used caps was to match the names in the GLFW system.

I'm going to think about what's the best solution for this. It could be to rename the keys to be all lower case. It could simply be to rename DELETE, which is causing the problem to something like DELETE_KEY. It could also be a test like you suggest.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Also, to build the wx-wxample3.cpp, I have to change the json search file path

diff --git a/morph/Visual.h b/morph/Visual.h
index 83cfb29..ca49c4e 100644
--- a/morph/Visual.h
+++ b/morph/Visual.h
@@ -48,7 +48,7 @@
 #include <morph/keys.h>
 
 #include <morph/VisualResources.h>
-#include <morph/nlohmann/json.hpp>
+#include <nlohmann/json.hpp>
 #include <morph/CoordArrows.h>
 #include <morph/Quaternion.h>
 #include <morph/TransformMatrix.h>

Ah, yes, I recently moved nlohmann/json out of morph and into the include directory, because it is third party code.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Good work! Grad to see it shows a demo under Linux.

I looked at the code, and I see some issues, see below:

-                    this->canvas = new morph::wx::Canvas(this, vAttrs);
+                    this->canvas = std::make_unique<morph::wx::Canvas>(this, vAttrs);

I don't think you need a std::unique here, because Automatic Deletion of Child Windows.

So, the canvas is a child window, if the parent window get closed, it children will get deleted automatically. No memory leak.

Okay, I will trust to wxWidgets memory management for the canvas.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Good work! Grad to see it shows a demo under Linux.
I looked at the code, and I see some issues, see below:

-                    this->canvas = new morph::wx::Canvas(this, vAttrs);
+                    this->canvas = std::make_unique<morph::wx::Canvas>(this, vAttrs);

I don't think you need a std::unique here, because Automatic Deletion of Child Windows.
So, the canvas is a child window, if the parent window get closed, it children will get deleted automatically. No memory leak.

Okay, I will trust to wxWidgets memory management for the canvas.

Do you know if wxWidgets would also delete a wxGLContext which is a wxObject?

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Okay, I believe I've addressed all the issues discussed, apart from whether or not to allow morph::wx::Canvas::glContext to be deallocated by the wxWidgets library on program exit. Could you give this another test?

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

I've merged the wx stuff into main now. I did plan to make a couple of additional wx examples before closing this issue though.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

OK, good work!
I will test it as soon as I can.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

I see you have add the wx port in the homepage, good!

// Your application-specific frame, deriving from morph::wx:Frame. In this frame, I'll set up VisualModels
class MyFrame : public morph::wx::Frame
{
public:
    MyFrame(const wxString &title) : morph::wx::Frame(title)
    {

I see this code in the wx-graph6.cpp file.

But from my point of view, I'm not satisfied with this code, because I think the MyFrame is a pure user class, this could have many many user's own children window, and sometimes, this MyFrame could be generated by some GUI tool, so it should not be derived from a customized morph::wx::Frame.

What I expect is a derived class from the wxWidgets: wxGLCanvas Class Reference.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

I think MyFrame is a pure user class, which is why it is in the example .cpp file wx-graph6.cpp

Take a look in viswx.h. You see that I had to extend BOTH wxGLCanvas and wxFrame.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

The content of morph::wx::Frame is quite limited. You could just put that code directly in MyFrame I guess.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

The content of morph::wx::Frame is quite limited. You could just put that code directly in MyFrame I guess.

Yes. I see:

        // morph::wx::Frame is to be extended. Note that a default GL version of 4.1 is given here.
        template <int glver = morph::gl::version_4_1>
        class Frame : public wxFrame
        {
        public:
            Frame(const wxString &title)
                : wxFrame(nullptr, wxID_ANY, title, wxDefaultPosition, wxDefaultSize)
            {
                wxGLAttributes vAttrs;
                vAttrs.PlatformDefaults().Defaults().EndList();
                if (wxGLCanvas::IsDisplaySupported(vAttrs)) {
                    // canvas becomes a child of this wxFrame which is responsible for deallocation
                    this->canvas = new morph::wx::Canvas<glver>(this, vAttrs);
                    this->canvas->SetMinSize (FromDIP (wxSize(640, 480)));
                } else {
                    throw std::runtime_error ("wxGLCanvas::IsDisplaySupported(vAttrs) returned false");
                }
            }

        protected:
            // A morph::wx::Frame contains a morph::wx::Canvas
            morph::wx::Canvas<glver>* canvas;
        };

Can the above code be put in the constructor of the morph::wx::Canvas?
I see the code just set the wxGLAttributes, and pass it to the constructor of the morph::wx::Canvas. If a user need some new feature of the wxGLAttributes, he can create its own class derived from the morph::wx::Canvas.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Unofrtunately, that's definitely not possible. It has to do with the order in which you create stuff. The frame has to exist first (esp. with wxWidgets on Linux). The frame has to own a canvas. The canvas creates a context in its constructor. The OpenGL 'model construction' code has to run after frame->Show() - in wx-graph1.cpp that's the call to frame->SetupVisualModels(), which is a morphologica-specific call that has to have been added to MyFrame.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

Unofrtunately, that's definitely not possible. It has to do with the order in which you create stuff. The frame has to exist first (esp. with wxWidgets on Linux). The frame has to own a canvas. The canvas creates a context in its constructor. The OpenGL 'model construction' code has to run after frame->Show() - in wx-graph1.cpp that's the call to frame->SetupVisualModels(), which is a morphologica-specific call that has to have been added to MyFrame.

Thanks for the response.

I see this:

bool MyApp::OnInit()
{
if (!wxApp::OnInit()) { return false; }
MyFrame *frame = new MyFrame("Hello OpenGL");
frame->Show(true);
frame->setupVisualModels(); // After calling Show()
return true;
}

From my point of view, function call statement SetupVisualModels() can be put in a event handler of the wxGLCanvas.

Such as put the function call to the below event handler:

Bind (wxEVT_SIZE, &morph::wx::Canvas<glver>::OnSize, this);

You can looked at the code here: lszl84/wx_opengl_tutorial
When the frame->Show() get called, it is expected that all the child window will receive the OnSize event, so it is the good place to initialize the OpenGL context and the VisuaModels.

If the user what to use its own SetupVisualModels() function, we can make this function a virtual function, and user has to define its own implementation.

The point here is, keep all the changes inside the wxGLCanvas or morph::wx::Canvas<glver>, because a wxGLCanvas can put inside any other wx related windows, such as wxFrame, wxDialog, wxAuiNotebook. If you keep changes inside a single class, it will be very easy to move a wxGLCanvas from here and there.

That's my point.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

I've tried the idea of bringing the canvas setup code into the user's MyFrame class. This removes the need for a morph::wx::Frame class. It adds some additional boilerplate lines of code into the user's MyFrame class.

I haven't placed setupVisualModels into a MyCanvas class (deriving from morph::wx::Canvas) because I prefer the idea that the user only has to specialize one class (MyFrame) and not two classes (MyFrame and MyCanvas).

You'll find this simple change in a dev branch: https://github.com/ABRG-Models/morphologica/tree/dev/remove_morph_wx_frame

See commit de8cc65

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

I do see your point about being able to place a canvas into multiple wx things (wxDialog, etc)

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

This commit: a87cd28 moves setupVisualModels into a MyCanvas class. Seems ok.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Lastly, commit 685759a calls setupVisualModels from within the OnSize event.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

Lastly, commit 685759a calls setupVisualModels from within the OnSize event.

Nice work, I will test the changes in this weekend.

Now, I'm thinking how to show an image or texture on a plane.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Oh my, now you want textures!

This is already done in the morph::VisualTextModel, which computes quads for each glyph that it will render and then applies a texture for the glyph to the quad. VisualTextModel has its own shaders, which are slightly different from the 'graphics only' shaders that I use for all of the regular VisualModels.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

By the way - I'll go through and unify the function naming in morph::wx::Canvas once we're happy with the design. setupVisualModels -> SetupVisualModels etc

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

I'm testing the branch https://github.com/ABRG-Models/morphologica/tree/dev/remove_morph_wx_frame, and it works fine.

About you mentioned morph::VisualTextModel, it looks like this is only for text characters, but for me, I would like to draw a bitmap, which may be slightly different. For example, I have a function z=f(x,y), I would like to create a surface, and the surface(mesh) has some texture on it, so I need to cover the surface with the bitmap.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Early on I decided not to use textures to indicate surfaces in morphologica. Instead, I create all the vertices for the triangles that make up the surface and colour each index from a colour map so that we get a nice surface plot, as you'll find in many of the examples, including the convolve program:

https://github.com/ABRG-Models/morphologica/tree/main/examples#convolvecpp

That uses a morph::HexGridVisual (and its underlying morph::HexGrid) to display a surface as hexagons, each of which is drawn with 6 OpenGL triangles.

You might think this would be inefficient, but it works just fine on most modern hardware (in fact, I got that program to run on Raspberry Pi recently).

The beauty of this method is that you can use the z axis in the scene's 3D universe to plot the magnitude of your data and the colour attribute of the vertex to indicate the same (or even a different) value.

Do you think you really need to apply textures to surfaces as you would if you were drawing objects only for their visual appearance (as you would in a game, for example)?

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

Do you think you really need to apply textures to surfaces as you would if you were drawing objects only for their visual appearance (as you would in a game, for example)?

I can understand your thought. Adding many features to the morphologica library may be hard to maintain. Is it possible to open or expose some interface of the opengl scene, so the user can add it's own VBO,VAO or Customized Shader to render its own object in the scene? For example, I have a 3D .obj file, I need to load this file to the scene.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

You could consider writing a new equivalent to VisualModel - a kind of "FreeFormVisualModel". This could have its own shader, including a user-supplied shader option and you could add however many vaos and vbos you wanted. The FreeFormVisualModel could fit into the morph::Visual framework, without interfering with VisualModel. I'd be happy to consider a pull request of such a new class.

from morphologica.

asmwarrior avatar asmwarrior commented on June 10, 2024

You could consider writing a new equivalent to VisualModel - a kind of "FreeFormVisualModel". This could have its own shader, including a user-supplied shader option and you could add however many vaos and vbos you wanted. The FreeFormVisualModel could fit into the morph::Visual framework, without interfering with VisualModel. I'd be happy to consider a pull request of such a new class.

OK, this is a good idea, I will do that later. For me, the first thing I would like to finish is to draw some 3D points(or trajectories) in a 3D spaces, and show the grid like 3D axies. Several applications need such feature such as target object tracking.

from morphologica.

sebjameswml avatar sebjameswml commented on June 10, 2024

Closing this issue on the assumption that @asmwarrior now knows how to use this library under wxWidgets (or has decided it doesn't meet their needs).

from morphologica.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.