I am encountering issues with the rendering of wxWidgets
examples that make use of wxGLCanvas
, code that had worked correctly under possibly previous version of wxWidgets
and associated libraries, but which fails to render properly after resizing under the following set-up:
OS: Ubuntu 24.04, running under WSL1 on Windows 10
wxWidgets: libwxgtk3.2-dev:amd64 3.2.4+dfsg-4build1
toolchain:
$ g++ --version
g++ (Ubuntu 14.2.0-4ubuntu2~24.04) 14.2.0
wx-config:
$ wx-config --libs --cxxflags --gl-libs
-I/usr/local/lib/wx/include/gtk3-unicode-3.2 -I/usr/local/include/wx-3.2 -D_FILE_OFFSET_BITS=64 -DWXUSINGDLL -D__WXGTK__ -pthread
-lwx_gtk3u_gl-3.2
-L/usr/local/lib -pthread -lwx_gtk3u_xrc-3.2 -lwx_gtk3u_html-3.2 -lwx_gtk3u_qa-3.2 -lwx_gtk3u_core-3.2 -lwx_baseu_xml-3.2 -lwx_baseu_net-3.2 -lwx_baseu-3.2
Under this set-up, the following minimal reproduceable code (simplified from code example at ) fails in the way to be described below:
// file: main.h
#ifndef _glpane_
#define _glpane_
#include <wx/wx.h>
#include <wx/glcanvas.h>
class BasicGLPane : public wxGLCanvas
{
wxGLContext *m_context;
public:
BasicGLPane(wxFrame *parent, int *args);
virtual ~BasicGLPane();
int getWidth();
int getHeight();
void prepare3DViewport(int topleft_x, int topleft_y, int bottomright_x, int bottomright_y);
void prepare2DViewport(int topleft_x, int topleft_y, int bottomright_x, int bottomright_y);
void render(wxPaintEvent& evt);
void resized(wxSizeEvent& evt);
DECLARE_EVENT_TABLE()
};
#endif
// file: main.cpp
#include <wx/wx.h>
#include <wx/sizer.h>
#include <wx/glcanvas.h>
#include <GL/glu.h>
#include <GL/gl.h>
#include "main.h"
class MyApp: public wxApp
{
virtual bool OnInit();
wxFrame *frame;
BasicGLPane *glPane;
public:
};
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL);
frame = new wxFrame((wxFrame *)NULL,
-1,
wxT("Hello GL World"),
wxPoint(50,50),
wxSize(200,200));
int args[] = {WX_GL_RGBA, WX_GL_DOUBLEBUFFER, WX_GL_DEPTH_SIZE, 16, 0};
glPane = new BasicGLPane( (wxFrame *) frame, args);
sizer->Add(glPane, 1, wxEXPAND);
frame->SetSizer(sizer);
frame->SetAutoLayout(true);
frame->Show();
return true;
}
BEGIN_EVENT_TABLE(BasicGLPane, wxGLCanvas)
EVT_SIZE(BasicGLPane::resized)
EVT_PAINT(BasicGLPane::render)
END_EVENT_TABLE()
GLfloat v[8][3];
GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */
{0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
{4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
BasicGLPane::BasicGLPane(wxFrame *parent, int *args) :
wxGLCanvas(parent, wxID_ANY, args, wxDefaultPosition, wxDefaultSize,
wxFULL_REPAINT_ON_RESIZE)
{
m_context = new wxGLContext(this);
v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
// To avoid flashing on MSW
SetBackgroundStyle(wxBG_STYLE_CUSTOM);
}
BasicGLPane::~BasicGLPane()
{
delete m_context;
}
void BasicGLPane::resized(wxSizeEvent& evt)
{
Refresh();
}
void BasicGLPane::prepare3DViewport(int topleft_x,
int topleft_y,
int bottomright_x,
int bottomright_y)
{
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_COLOR_MATERIAL);
glViewport(topleft_x, topleft_y,
bottomright_x - topleft_x,
bottomright_y - topleft_y);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float ratio_w_h = (float)(bottomright_x - topleft_x) /
(float)(bottomright_y - topleft_y);
gluPerspective(45 , ratio_w_h, 0.1, 200);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
int BasicGLPane::getWidth()
{
return GetSize().x;
}
int BasicGLPane::getHeight()
{
return GetSize().y;
}
void BasicGLPane::render( wxPaintEvent& evt )
{
if(!IsShown()) return;
wxGLCanvas::SetCurrent(*m_context);
wxPaintDC(this); // NOLINT
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
prepare3DViewport(0,0,getWidth(), getHeight());
glLoadIdentity();
glColor4f(0,0,1,1);
glTranslatef(0,0,-5);
glRotatef(50.0f, 0.0f, 1.0f, 0.0f);
glColor4f(1, 0, 0, 1);
for (int i = 0; i < 6; i++)
{
glBegin(GL_LINE_STRIP);
glVertex3fv(&v[faces[i][0]][0]);
glVertex3fv(&v[faces[i][1]][0]);
glVertex3fv(&v[faces[i][2]][0]);
glVertex3fv(&v[faces[i][3]][0]);
glVertex3fv(&v[faces[i][0]][0]);
glEnd();
}
glFlush();
SwapBuffers();
}
build:
$ g++ main.cpp -o wx `wx-config --libs --cxxflags --gl-libs` -lX11 -lGL -lGLU
Expectations
The code should build and, on running the program, the rendering of the wxGLCanvas
should respond to resize events so that the wireframe cube (see below) maintains the same proportion to whichever is shortest of the canvas' width/height and rendering occurs across the full extent of the visible canvas.
On startup (meets expectations)
On horizontal resize (meets expectations)
On vertical resize (fails expectations)
Problem specifics
Debugging code (printf
, not included here) confirms that there is no issue with the wxGLCanvas
itself resizing in both directions with the resizing of the frame. Evidently, the viewport is appropriately adjusted on resizing in both directions and, if fully rendered, it is clear that the the vertical resize would have the wireframe cube rendered at the correct size/position. Vertical resizing, however, fails to extend the area over which the gl context renders, and this remains static according to whatever height the wxGLCanvas
was given at application startup.
I have attempted to research this issue extensively over some months and am yet to be able to discover where the issue lies. As noted, all such examples would have built and run correctly under a previous set-up which would have preceeded an upgrade from Ubuntu 22.04 to 24.04, and several reinstallation attempts of wxWidgets-3.2
. In the first place, therefore, it would be useful to have some confirmation as to whether this is an issue with wxWidgets-3.2
(reproduceable) or with my system set-up otherwise.
I would welcome any suggestion as to where I should be looking next for a solution of the above issue. At present, a number of semi-large projects are effectively broken by this issue.
Update
Following the suggestion by @VZ, I have myself installed a Debian distro under WSL1 and added the same wxWidgets
packages (plus dependencies) as per my Ubuntu set-up (except using gcc-12
) and can confirm that the code posted builds and runs without issues, as @VZ reported. The only difference between the two set-ups is, indeed, the GL drivers, with the successful Debian build showing:
$ glxinfo | grep "OpenGL version"
OpenGL version string: 4.5 (Compatibility Profile) Mesa 22.3.6
whereas the failing Ubuntu set-up has:
$ glxinfo | grep "OpenGL version"
OpenGL version string: 4.5 (Compatibility Profile) Mesa 25.0.1 - kisak-mesa PPA
So, it would seem that we are indeed looking at a driver issue here, and not any bug in wxWidgets-3.2
.