LiangliangNan / Easy3D

A lightweight, easy-to-use, and efficient C++ library for processing and rendering 3D data
GNU General Public License v3.0
1.37k stars 245 forks source link

WxWidgets support #136

Closed esuig closed 2 years ago

esuig commented 2 years ago

Hello,

I would like to setup a minimal working example for using Easy3D with wxWidgets. I think I have to use wxGLCanvas as element to display the graphic stuff. I analysed the examples for Qt and Imgui that are available in the Easy3D repository, but at the moment I'm not able to understand how to initialize context and link it to the wxGLCanvas in the specific case of wxWidgets. Could you please give me an hint or provide some lines of code? I can post my advancements here

LiangliangNan commented 2 years ago

I've added such an example in the dev branch. See here: https://github.com/LiangliangNan/Easy3D/tree/dev/tutorials/Tutorial_203_Viewer_wxWidgets

I haven't fully tested it yet (only on macOS). Let me know if you encounter any issues.

esuig commented 2 years ago

Hello, thank you very much for the example! I succeeded in building it (I'm on windows). I had a look into the code and I have a question: why have you redefined a new add_model function? I see that in the ImGui example you derive the viewer from the easy 3d viewer directly and you use the functions of the Viewer class (<easy3d/viewer/viewer.h>). This is related to another question: suppose I want to display a segment: I'll create an auto linedrawable = new easy3d::LinesDrawable("segment");, then add the vertexes, set color and so on. But at the end I have to display it and I would like to call viewer->add_drawable(line_drawable);, but I have no add_drawable and I'm not really sure I'm able to implement it, how could I do?

LiangliangNan commented 2 years ago

Hello, thank you very much for the example! I succeeded in building it (I'm on windows). I had a look into the code and I have a question: why have you redefined a new add_model function? I see that in the ImGui example you derive the viewer from the easy 3d viewer directly and you use the functions of the Viewer class (<easy3d/viewer/viewer.h>).

That is because the two viewers are based on completely different window frameworks.

This is related to another question: suppose I want to display a segment: I'll create an auto linedrawable = new easy3d::LinesDrawable("segment");, then add the vertexes, set color and so on. But at the end I have to display it and I would like to call viewer->add_drawable(line_drawable);, but I have no add_drawable and I'm not really sure I'm able to implement it, how could I do?

The current wxWidgets viewer is very limited, and it mainly demonstrates the OpenGL context and window/viewer creation, and some basic rendering. It can be easily extended by copying many functions from the default viewer (<easy3d/viewer/viewer.h>). I've just added the Viewer::add_drawable(...) to it. You can grab the new code and run it to check.

esuig commented 2 years ago

Ok, I checked the code and everything works perfectly. Thank you, I'll close the issue, since I think the example you provided is a complete and interesting starting point for the support of wxWidgets

LiangliangNan commented 2 years ago

@esuig Thank you! Today I got some time to test the code on Windows and encountered an issue. The program pops up a warning dialog "Couldn't create GL context" on startup even though everything is rendered fine. See below. I don't have much experience with wxWidgets, did you encounter the same issue, or do you have an idea how this could be fixed? image

esuig commented 2 years ago

In your code I found the following lines:

#ifndef __WXMAC__
        // An impossible context, just to test IsOk()
        ctxAttrs.PlatformDefaults().OGLVersion(99, 2).EndList();
        gl_contex_ = new wxGLContext(this, NULL, &ctxAttrs);

        if (!gl_contex_->IsOK()) {
            delete gl_contex_;  // Trying to set OpenGL 99.2 failed, as expected.
            ctxAttrs.Reset();
#endif //__WXMAC__
            ctxAttrs.PlatformDefaults().CoreProfile().OGLVersion(gl_major, gl_minor).EndList();
            gl_contex_ = new wxGLContext(this, NULL, &ctxAttrs);
#ifndef __WXMAC__
        }
#endif //__WXMAC__

The creation of the "impossible" context at the beginning of the lines I reported here is the cause of that message (so it is correct that the message pops up). I just replaced those lines with:

ctxAttrs.PlatformDefaults().CoreProfile().OGLVersion(gl_major, gl_minor).EndList();
gl_contex_ = new wxGLContext(this, NULL, &ctxAttrs);

I thought that was a test and you wanted to leave there for some reason, so I didn't think about that as an issue.

I think that is the reason, but please let me know if it works also for you.

LiangliangNan commented 2 years ago

Indeed. I completely ignored that piece of test code. Thank you again, and good luck with your research/development!