[wxwidgets3.1.2, opengl] A hen and egg problem

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
sarah.miller
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Jun 17, 2019 4:29 pm

[wxwidgets3.1.2, opengl] A hen and egg problem

Post by sarah.miller » Mon Jun 17, 2019 5:08 pm

Hi.

I've got an opengl application where I manually create an opengl context (I'm able to get an opengl 4.2 context on my machine). I'd like to use wxwidgets to add some gui elements to e.g. toggle render modes and to generally make debugging easier.
Unfortunably, I've got some problems creating an openGL context in wxwidgets.

I'm on win7 using mingw (x64 by TDM).

I've successfully compiled wxwidgets (3.1.2) from source, using

Code: Select all

mingw32-make.exe -f makefile.gcc MONOLITHIC=0 SHARED=1 UNICODE=1 USE_OPENGL=1 BUILD=release
mingw32-make.exe -f makefile.gcc MONOLITHIC=0 SHARED=1 UNICODE=1 USE_OPENGL=1 BUILD=debug
I can compile & run the opengl samples.

I've created a wxwidgets project in code::blocks IDE (using wxsmith as form editor).
I've added the wxwidget _gl lib/dll to the compiler/linker options. I'm also linking opengl32.

I've subclassed wxglCanvas (similar to the pyramid sample) and added that to my wxFrame (resp. to the layout of my frame).

When I compile & run, I get an error about some assert triggered on "tempcontext" inside wxglcanvas - e.g. there's something going wrong with the wxglcontext that is created automatically within the constructor of the wxglcanvas, but I'm unable to determine what exactly is going wrong.

On top of that the documentation is kind of confusing on this topic: "Notice that versions of wxWidgets previous to 2.9 used to implicitly create a wxGLContext inside wxGLCanvas itself. This is still supported in the current version but is deprecated now and will be removed in the future, please update your code to create the rendering contexts explicitly." (https://docs.wxwidgets.org/trunk/classw ... anvas.html) - so, If that internal openglcontext was actually removed like the documentation says, I could create my own context w/attributes like opengl version?

I'm neither seeing a way to pass contextattributes into the wxglcanvas, nor a way to tell the canvas to not autogenerate a context, nor a way to pass a manually created context to the canvas (or vice versa).

So, how can I create an wxglcanvas and use a context with specific opengl context attributes, e.g. opengl version 4.2 and core profile?



PS: Searching for a solution, I came across http://www.lighthouse3d.com/2012/07/wor ... wx-wigets/ but unlike suggested, I'd rather not modify the library code.

User avatar
doublemax
Moderator
Moderator
Posts: 14314
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by doublemax » Mon Jun 17, 2019 6:58 pm

You already mentioned the "pyramid" sample. Doesn't that show how to use modern OpenGL contexts?
Use the source, Luke!

Mick P.
Earned some good credits
Earned some good credits
Posts: 123
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by Mick P. » Wed Jun 19, 2019 1:13 pm

I think wxGLContext is separate from wxGLCanvas. I think you're confusing it with some dinky little helper objects that were added later.

Look in the examples, you will see that they manage a wxGLContext object separate from their canvases, since those things are logically separate; although it is pretty confusing because they also bind the contexts to windows at the same time as making them current on the thread. OpenGL is kind of a mess. You just have to grin and bear it sometimes.

Off-topic: But there is a major problem with the canvas module, in that there is no way to deselect contexts. That should be added. But someone will have to make a big effort to do that if so. The OpenGL part of wxWidgets is very underdeveloped. It needs more developers and eyeballs on it. It needs a killer app to get it out of the demo stage. It might even be wiser to not use it if possible. By going native. There are lots of design limitations.

sarah.miller
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Jun 17, 2019 4:29 pm

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by sarah.miller » Thu Jun 20, 2019 8:07 pm

doublemax wrote:
Mon Jun 17, 2019 6:58 pm
You already mentioned the "pyramid" sample. Doesn't that show how to use modern OpenGL contexts?
The pyramid sample does indeed show how to use modern OpenGL contexts. It could be more verbose though.

What I'm trying to do is get a simple opengl program working (just clears the screen with a blue clearcolor and swaps buffers).
So I create a wxglcanvas and then an wxglcontext but the problem I'm facing is that the internal context created by the canvas triggers an assert and I've got no clue as to what goes wrong.

I'll have to see If I can't find some time this weekend to study the pyramid sample more closely.
Mick P. wrote:
Wed Jun 19, 2019 1:13 pm
I think wxGLContext is separate from wxGLCanvas. I think you're confusing it with some dinky little helper objects that were added later.
I'm talking about the following two classes:
https://docs.wxwidgets.org/3.0/classwx_g_l_canvas.html
https://docs.wxwidgets.org/3.0/classwx_g_l_context.html
Mick P. wrote:
Wed Jun 19, 2019 1:13 pm
Look in the examples, you will see that they manage a wxGLContext object separate from their canvases, since those things are logically separate; although it is pretty confusing because they also bind the contexts to windows at the same time as making them current on the thread.
Unfortunably, only the pyramid sample is relevant for me, since I intend to use an opengl core context > v3.3 (and the other samples only deal with legacy opengl, e.g. < v3.3). But I will examine that sample more closely.
Mick P. wrote:
Wed Jun 19, 2019 1:13 pm
OpenGL is kind of a mess. You just have to grin and bear it sometimes.
Well, compared to the effort I've put into trying to get a simple wxwidgets + opengl program running, manually creating an opengl context in a native window was easy. ymmv

User avatar
doublemax
Moderator
Moderator
Posts: 14314
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by doublemax » Thu Jun 20, 2019 8:21 pm

So I create a wxglcanvas and then an wxglcontext but the problem I'm facing is that the internal context created by the canvas triggers an assert
If it's an assert, you should also get an assert message telling you what's wrong. If it was a crash, please build a debug version and post the call stack/backtrace.

Unfortunately using modern OpenGL requires a huge amount of boilerplate initialization code. Maybe for a start you should just copy the "pyramid" sample and put your render code in "oglstuff.cpp", myOGLManager::Render().
Use the source, Luke!

williamjcm
In need of some credit
In need of some credit
Posts: 4
Joined: Mon Oct 06, 2014 3:29 pm

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by williamjcm » Fri Jun 21, 2019 7:51 am

I once contributed a wxWidgets-based bootstrap project to Magnum (a graphics middleware with an OpenGL wrapping layer), which you can find on GitHub, in the "base-wxwidgets" branch of the "mosra/magnum-bootstrap" repo. It has a wx3.1 code path, which you could take a look at.

I didn't add any configuration for the context itself, but here's what I use in another wx3.1 project of mine (and it happens to "Just Work™"):

Code: Select all

wxGLAttributes attributes;
attributes.PlatformDefaults().BufferSize(24).MinRGBA(8, 8, 8, 0).Depth(24).Stencil(0).DoubleBuffer().EndList();
_glCanvas = new wxGLCanvas(this, attributes, wxID_ANY, wxDefaultPosition, wxSize(1024, 576));

wxGLContextAttrs context_attributes;

context_attributes.PlatformDefaults()
                  .CoreProfile()
                  .ForwardCompatible()
                  .OGLVersion(3, 3)
                  .EndList();

_wxGlContext.emplace(_glCanvas, nullptr, &context_attributes);
_wxGlContext->SetCurrent(*_glCanvas);
I hope this'll help you get started with wxWidgets and OpenGL.
I'm French, so, sorry if I make English mistakes.

Current environment as of 16/08/2019:
  • GCC 9.1.0 (Arch Linux; I use the equivalent MinGW-w64 on MSYS2 on Windows)
  • wxWidgets 3.1.2

Mick P.
Earned some good credits
Earned some good credits
Posts: 123
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by Mick P. » Fri Jun 21, 2019 12:24 pm

sarah.miller wrote:
Thu Jun 20, 2019 8:07 pm
So I create a wxglcanvas and then an wxglcontext but the problem I'm facing is that the internal context created by the canvas triggers an assert and I've got no clue as to what goes wrong.
Sorry, I think I misread. I thought maybe you had confused these (https://docs.wxwidgets.org/trunk/classw ... _base.html) classes for the context one.

Going back I see you are trying to bypass wxWidget's to make your own context without wxGLContext? If so, then you would want to avoid wxGLCanvas too?

If you get something working I'm curious myself, since I have a feeling wxGLCanvas will prove ultimately not up to supporting a serious application in its present state.


P.S. I read you ARE using wxGLCanvas. In that case I would suggest not using it. In which case you need to find another way to use OpenGL to draw on the window. The temporary context is probably a bootstrapping context that is needed to ask the system what OpenGL capabilities it has.

Manolo
Can't get richer than this
Can't get richer than this
Posts: 704
Joined: Mon Apr 30, 2012 11:07 pm

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by Manolo » Fri Jun 21, 2019 8:07 pm

I get an error about some assert triggered on "tempcontext" inside wxglcanvas
If you look inside msw/glcanvas.cpp this is a temporary context used internally to get a pointer to wglCreateContextAttribsARB needed for OpenGL > 2.1
Having a error there means there's something wrong and weird with your environment. Mmmmmm... do you have another context and set is as current for that window? Even so... if you have linked with opengl32 this error should never happen.

Don't confuse this temporary context with the "persistent" context that wx2.8 may have create by default. If you have disabled wx2.8 compatibility then the only way to have a context is creating one like in the pyramid sample (i.e. by using wxGLContext)

Also, don't confuse display attributes with context attributes. Read the wx docs (https://docs.wxwidgets.org/trunk/group_ ... s__gl.html) to learn about them, and some OGL tutorial to understand them :D . The OGL specifications are really hard, delay reading them until you feel confortable with OGL stuff.
Notice that this "attributes" thing have changed in wx3.1. And if you want a Core Profile or OGL>2.1 then you need wx3.1 (well, there was some OGL version selection introduced in wx3.0.y, I don't remember the "y").
Mick P.
Off-topic: But there is a major problem with the canvas module, in that there is no way to deselect contexts.
True. But it isn't a "major problem". And can easily done:

Code: Select all

#ifdefined __WIN__
    wglMakeCurrent(NULL, NULL);
#elif __UNIX__
   MakeCurrent(None, NULL);
#else
.....
But the point here is "why do you need it?" It may be used in a sub-optimal case where two threads want to render in the same window.

Mick P.
I read you ARE using wxGLCanvas. In that case I would suggest not using it.
I suggest the opposite. Using wx3.1 OGL features is much much easier than dealing with OS API. Take a look at glcanvas.cpp for several targets to see the required steps to go, that you can avoid just by using wx.

Finally, @doublemax told it clear: "Unfortunately using modern OpenGL requires a huge amount of boilerplate initialization code"
Which means you must deal with function pointers to gl functions, retrieved from the graphics driver; and with matricex maths. More at viewtopic.php?f=27&t=45552

Mick P.
Earned some good credits
Earned some good credits
Posts: 123
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by Mick P. » Fri Jun 21, 2019 8:58 pm

Manolo wrote:
Fri Jun 21, 2019 8:07 pm
I suggest the opposite. Using wx3.1 OGL features is much much easier than dealing with OS API. Take a look at glcanvas.cpp for several targets to see the required steps to go, that you can avoid just by using wx.
Well I hope you realize (I didn't at first) sarah.miller is specifically NOT using wxGLContext. So, it makes sense to not use wxGLCanvas either. In any case, that's what I was responding to.
Last edited by Mick P. on Sat Jun 22, 2019 9:26 am, edited 2 times in total.

Manolo
Can't get richer than this
Can't get richer than this
Posts: 704
Joined: Mon Apr 30, 2012 11:07 pm

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by Manolo » Sat Jun 22, 2019 12:00 am

Mick P:
...they are expressly NOT using wxGLContext. Therefor, it seems logical to also not use wxGLCanvas...
Please, stop adding confusion. The OP has problems with 'creating a openGL context in wxWidgets', and some people (like me) are trying to help.

To use OpenGL you need:
1) Create a window. There are some old possibility of doing OGL without a window (e.g. PixelBuffer), but for modern OGL you better use a window.
2) Define the attributes for that window. In MSW parlance they are encapsulated in a "pixelformat", in Linux/X11 a "config"; and ask the OS for a "pixelformat" that meet your requirements.
3) Create a gl-context. Modern OGL (> 2.1) allows some attributes.
4) Bind the context to a thread ("Set current").
There are plenty of info in the web. For example https://www.khronos.org/opengl/wiki/Getting_Started and https://www.khronos.org/opengl/wiki/Cre ... text_(WGL).

Since wx 3.1 wxWidgets offers what is needed:
Steps 1) and 2) are easily achieved by wxGLCanvas and wxGLAttributes.
Steps 3) and 4) are easily achieved by wxGLContext and wxGLContextAttrs.
With wx3.0 you can also have OGL working, but only for OGL <= 2.1.

Of course you can by-pass wx and do all OGL setup on your own, as you seem to suggest. But the point is the opposite. And why would do it the hard way? Specially if you're coding for several platforms.

Mick P.
Earned some good credits
Earned some good credits
Posts: 123
Joined: Thu Jun 06, 2019 3:41 am
Contact:

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by Mick P. » Sat Jun 22, 2019 9:27 am

Manolo wrote:
Sat Jun 22, 2019 12:00 am
Please, stop adding confusion. The OP has problems with 'creating a openGL context in wxWidgets', and some people (like me) are trying to help.
Yeah, I was trying to help [-X

sarah.miller
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Jun 17, 2019 4:29 pm

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by sarah.miller » Sun Jun 23, 2019 5:42 pm

Sorry about the confusion.

I've looked at the pyramid sample again and didn't notice much difference compared to my own code.

I am indeed using a custom class derived from wxGLCanvas, which holds a wxGLContext as a member variable (which is initially a nullptr and gets initialized within the constructor).
The pyramid sample takes a similar route - there, a 'MyGLWidget' is used as a custom class derived from wxglcanvas.


Compile & linking calls according to build log:

Code: Select all

x86_64-w64-mingw32-c++.exe -Wall -std=c++14 -pipe -mthreads -mwindows -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DwxUSE_UNICODE -DwxUSE_GLCANVAS -std=c++14 -g -Wall -std=c++14 -m64 -g -II:\libs\wxWidgets-3.1.2\include -II:\libs\wxWidgets-3.1.2\lib\gcc_dll\mswu -IwxCanvas -c G:\project\wxCanvas\mycanvas.cpp -o obj\Debug\wxCanvas\mycanvas.o
x86_64-w64-mingw32-g++.exe -LI:\libs\wxWidgets-3.1.2\lib\gcc_dll -o bin\Debug\project.exe  obj\Debug\wxCanvas\mycanvas.o obj\Debug\wxprojectApp.o obj\Debug\wxprojectMain.o obj\Debug\resource.res -mthreads -m64  -lwxmsw31ud_core -lwxbase31ud -lwxmsw31ud_gl -lwxpngd -lwxzlibd -lopengl32 -lglu32 -lgdi32
I hope I'm not missing some lib or include.


The assert I'm getting is:

Code: Select all

../src/msw/glcanvas.cpp (596): assert ""tempContext"" failed in wxGLContext(): wglCreateContext failed!

Below is the constructor of my custom class:

Code: Select all

// ctor
mycanvas::mycanvas(wxFrame* parent, wxGLAttributes args) : wxGLCanvas(parent, args, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE, _T("ID_mycanvas"), wxNullPalette)
{
    // version of openGL
    m_glVersionMajor = 4;
    m_glVersionMinor = 2;

    // context attributes - available in wxwidgets version 3.1.0 or higher
    wxGLContextAttrs ctxAttrs;
    ctxAttrs.PlatformDefaults().CoreProfile().OGLVersion(m_glVersionMajor, m_glVersionMinor).ForwardCompatible().DebugCtx().EndList();
    ctxAttrs.SetNeedsARB(true);

    // create & set context
    m_context = new wxGLContext(this, nullptr, &ctxAttrs);

    // valid context?
    if(!m_context->IsOK())
    {
        // tell user to upgrade graphics card or something
        wxMessageBox("This sample needs an OpenGL " + std::to_string(m_glVersionMajor) + "." + std::to_string(m_glVersionMinor) + " capable driver.\nThe app will end now.",
                     "OpenGL version error", wxOK | wxICON_INFORMATION, this);
        // TODO: exit
    }

    // To avoid flashing on MSW (according to wxwidgets wiki)
    SetBackgroundStyle(wxBG_STYLE_CUSTOM);
}
My debugger (wingdb) stops at the line "m_context = new wxGLContext(this, nullptr, &ctxAttrs);", e.g. during context initialization.
Initialization with only "patformdefaults" as attribute also does not work.

What am I doing wrong?


PS: I've got all kinds of opengl rendering code ready to go (in another program) btw - I'm mostly looking at wxwidgets for handling context initialisation and input handling on multiple platforms & for adding a debugging menu.

edit/PPS: This is my rendering function (only clears screen for now):

Code: Select all

// rendering
void mycanvas::render( wxPaintEvent& evt )
{
    // do not render if we are invisible or hidden
    if(!IsShown()) return;

    // do not render when context is not available
    if(!m_context) return;

    // make our context current and grab the device
    wxGLCanvas::SetCurrent(*m_context);
    wxPaintDC(this);

    // clear color and depth buffer
    glClearColor(0.4f, 0.6f, 0.9f, 0.0f);
    glClearDepth(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST); // Enables Depth Testing
    glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

    // rendering code goes here - TODO: renderer classes
    // TODO: render something meaningful

    // finally: swap buffers to show current frame
    SwapBuffers();
}
edit2/PPPS: Just realized I should probably also show how I init the glcanvas in my mainwindow:

Code: Select all

wxGLAttributes canvasAttributes;
    canvasAttributes.PlatformDefaults().Defaults().RGBA().DoubleBuffer().Depth(24).Stencil(8).EndList();

    // test attrs
    if(!wxGLCanvas::IsDisplaySupported(canvasAttributes))
    {
        wxMessageBox("Sorry, the set of wxGLAttributes is not supported on this system.\nThe app will end now.",
                     "wxGLAttributes error", wxOK | wxICON_INFORMATION, this);
    }

    //canvasAttributes.SetNeedsARB(true);
    canvas = new mycanvas(this, canvasAttributes);

User avatar
doublemax
Moderator
Moderator
Posts: 14314
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by doublemax » Sun Jun 23, 2019 6:30 pm

I assume the unmodified pyramid sample works for you?

If i use your initialization code, including the same wxGLAttributes and wxGLContextAttrs into the pyramid sample, it still works for me.

Either try to create a complete, compilable sample that produces the assert, or try to move your code over to the pyramid sample step by step until the assert happens.
Use the source, Luke!

Manolo
Can't get richer than this
Can't get richer than this
Posts: 704
Joined: Mon Apr 30, 2012 11:07 pm

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by Manolo » Mon Jun 24, 2019 4:04 pm

If the pyramid sample works for you I guess your issue is related to libraries linked. To find how pyramid gets compiled add >buildlog.txt >2&1 at the end of your command line (x86_64-w64-mingw32-c++.exe -f makefile.gcc...). Then, "buildlog.txt" will show the included dirs and linked libs.

It seems you use very few libraries from Windows (lacks kernel32, user32, etc). And be aware that with MinGW the order or libs is important. See this post viewtopic.php?f=19&t=45239&p=187600&hil ... es#p187600 for a working environment.

Some less important points:
** Linking with "glu" is not needed, since you want a OGL Core Profile and glu only is valid for OGL not-core.
** SetNeedsARB() is used internally by wx. It's only user-needed if you add some new context attribute not handled by wx yet.
** GL_PERSPECTIVE_CORRECTION_HINT is not valid for glHint in Core Profile.

sarah.miller
In need of some credit
In need of some credit
Posts: 5
Joined: Mon Jun 17, 2019 4:29 pm

Re: [wxwidgets3.1.2, opengl] A hen and egg problem

Post by sarah.miller » Mon Jun 24, 2019 7:57 pm

doublemax wrote:
Sun Jun 23, 2019 6:30 pm
I assume the unmodified pyramid sample works for you?
Yes, the unmodified pyramid sample compiles and runs without problems. Looking at the about dialog, I'm getting an opengl 3.2 context in the pyramid sample.

Creating an MWE will take a while though.
Manolo wrote:
Mon Jun 24, 2019 4:04 pm
To find how pyramid gets compiled add >buildlog.txt >2&1 at the end of your command line
That gives me

Code: Select all

g++ -c -o gcc_mswuddll\pyramid_pyramid.o -g -O0 -mthreads  -DHAVE_W32API_H -D__WXMSW__       -D_UNICODE -I.\..\..\..\lib\gcc_dll\mswud -I.\..\..\..\include  -W -Wall -I. -DWXUSINGDLL -I.\..\..\..\samples -DNOPCH   -Wno-ctor-dtor-privacy   -MTgcc_mswuddll\pyramid_pyramid.o -MFgcc_mswuddll\pyramid_pyramid.o.d -MD -MP pyramid.cpp
g++ -o gcc_mswuddll\pyramid.exe gcc_mswuddll\pyramid_sample_rc.o gcc_mswuddll\pyramid_pyramid.o gcc_mswuddll\pyramid_oglstuff.o gcc_mswuddll\pyramid_mathstuff.o gcc_mswuddll\pyramid_oglpfuncs.o  -g -mthreads -L.\..\..\..\lib\gcc_dll -Wl,--subsystem,windows -mwindows    -lwxmsw31ud_gl -lopengl32 -lglu32 -lwxmsw31ud_core  -lwxbase31ud    -lwxtiffd -lwxjpegd -lwxpngd   -lwxzlibd -lwxregexud -lwxexpatd   -lkernel32 -luser32 -lgdi32 -lcomdlg32 -lwinspool -lwinmm -lshell32 -lshlwapi -lcomctl32 -lole32 -loleaut32 -luuid -lrpcrt4 -ladvapi32 -lversion -lwsock32 -lwininet -loleacc -luxtheme
Manolo wrote:
Mon Jun 24, 2019 4:04 pm
It seems you use very few libraries from Windows (lacks kernel32, user32, etc). And be aware that with MinGW the order or libs is important. See this post viewtopic.php?f=19&t=45239&p=187600&hil ... es#p187600 for a working environment.
I'll need some time to digest that. I'll report back when I've checked my lib order.

Post Reply