doublemax wrote: ↑Thu Mar 21, 2019 5:11 pm
Can you try to create a minimal, compilable sample that shows the problem?
Since I have not solved it yet,
Put the previous code.
MyApp.h
Code: Select all
#pragma once
#include <wx/wxprec.h>
#include "MyFrame.h"
#include "GLContext.h"
class MyApp : public wxApp
{
public:
MyApp();
virtual bool OnInit() override;
virtual int OnExit() override;
GLContext& GetContext(wxGLCanvas* canvas);
private:
GLContext* glContext_;
};
wxDECLARE_APP(MyApp);
MyApp.cpp
Code: Select all
#include "MyApp.h"
wxIMPLEMENT_APP(MyApp);
MyApp::MyApp() :
glContext_(nullptr)
{}
bool MyApp::OnInit()
{
MyFrame *frame = new MyFrame();
frame->Show(true);
return true;
}
int MyApp::OnExit()
{
delete glContext_;
return wxApp::OnExit();
}
GLContext & MyApp::GetContext(wxGLCanvas* canvas)
{
if(!glContext_) glContext_ = new GLContext(canvas);
glContext_->SetCurrent(*canvas);
return *glContext_;
}
MyFrame.h
Code: Select all
#pragma once
#include <wx/wxprec.h>
class MyFrame : public wxFrame
{
public:
MyFrame();
};
MyFrame.cpp
Code: Select all
#include "MyFrame.h"
#include "Window.h"
#include "GLCanvas.h"
MyFrame::MyFrame() :
wxFrame(NULL, wxID_ANY, Window::kTitle, wxPoint(2200, 200), wxSize(Window::kWidth, Window::kHeight))
{
GLCanvas *glCanvas = new GLCanvas(this, wxSize(800, 500));
wxMenu *menuDisplay = new wxMenu;
wxMenu *menuSubDisplay = new wxMenu;
menuSubDisplay->AppendRadioItem(ItemID::kScaling_Radio25, "25%");
menuSubDisplay->AppendRadioItem(ItemID::kScaling_Radio50, "50%");
menuSubDisplay->AppendRadioItem(ItemID::kScaling_Radio100, "100%");
menuSubDisplay->AppendRadioItem(ItemID::kScaling_Radio200, "200%");
menuSubDisplay->AppendRadioItem(ItemID::kScaling_RadioWindow, "WindowSize")->Check(true);
menuDisplay->AppendSubMenu(menuSubDisplay, "&Scale");
wxMenuBar *menuBar = new wxMenuBar;
menuBar->Append(menuDisplay, "&Display");
SetMenuBar(menuBar);
CreateStatusBar();
SetStatusText("Welcome to wxWidgets!");
Bind(wxEVT_MENU, &GLCanvas::ScalingEvent, glCanvas, ItemID::kScaling_Radio25);
Bind(wxEVT_MENU, &GLCanvas::ScalingEvent, glCanvas, ItemID::kScaling_Radio50);
Bind(wxEVT_MENU, &GLCanvas::ScalingEvent, glCanvas, ItemID::kScaling_Radio100);
Bind(wxEVT_MENU, &GLCanvas::ScalingEvent, glCanvas, ItemID::kScaling_Radio200);
Bind(wxEVT_MENU, &GLCanvas::ScalingEvent, glCanvas, ItemID::kScaling_RadioWindow);
}
GLContext.h
Code: Select all
#pragma once
#include <wx/wxprec.h>
#include "wx/glcanvas.h"
class GLContext : public wxGLContext
{
public:
GLContext(wxGLCanvas* canvas);
~GLContext();
};
GLContext.cpp
Code: Select all
#include "GLContext.h"
GLContext::GLContext(wxGLCanvas * canvas) :
wxGLContext(canvas)
{
SetCurrent(*canvas);
}
GLContext::~GLContext()
{}
GLCanvas.h
Code: Select all
#pragma once
#include <wx/wxprec.h>
#include "wx/glcanvas.h"
class GLCanvas : public wxGLCanvas
{
public:
GLCanvas(wxWindow* parent, const wxSize& windowSize);
void ScalingEvent(wxCommandEvent& event);
private:
void OnPaint(wxPaintEvent& event);
void Draw();
void WindowSizeInitialize();
void ViewportMatrixInitialize();
void ProjectionMatrixInitialize();
void ModelViewMatrixInitialize();
float GetRaito();
private:
const wxSize kResolutionSize_;
const wxSize kHalfResolutionSize_;
enum CanvasType
{
kScaling25,
kScaling50,
kScaling100,
kScaling200,
kScalingWindow
};
CanvasType currentCanvasType;
};
GLCanvas.cpp
Code: Select all
#include "GLCanvas.h"
#include "GLContext.h"
#include "MyApp.h"
#include "Window.h"
GLCanvas::GLCanvas(wxWindow * parent, const wxSize & resolutionSize) :
wxGLCanvas(parent, wxID_ANY, nullptr, wxDefaultPosition, resolutionSize, wxBORDER_SIMPLE | wxNO_FULL_REPAINT_ON_RESIZE),
kResolutionSize_(resolutionSize),
kHalfResolutionSize_(resolutionSize.x / 2.0f, resolutionSize.y / 2.0f),
currentCanvasType(CanvasType::kScalingWindow)
{
GLContext& canvas = wxGetApp().GetContext(this);
Bind(wxEVT_PAINT, &GLCanvas::OnPaint, this);
wxBoxSizer *sizer1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sizer2 = new wxBoxSizer(wxHORIZONTAL);
sizer1->Add(this, 1, wxALIGN_CENTER);
sizer2->Add(sizer1, 1, wxALIGN_CENTER);
SetSizer(sizer2);
SetAutoLayout(true);
Center();
}
void GLCanvas::ScalingEvent(wxCommandEvent & event)
{
switch(event.GetId())
{
case ItemID::kScaling_Radio25:
currentCanvasType = CanvasType::kScaling25;
break;
case ItemID::kScaling_Radio50:
currentCanvasType = CanvasType::kScaling50;
break;
case ItemID::kScaling_Radio100:
currentCanvasType = CanvasType::kScaling100;
break;
case ItemID::kScaling_Radio200:
currentCanvasType = CanvasType::kScaling200;
break;
case ItemID::kScaling_RadioWindow:
currentCanvasType = CanvasType::kScalingWindow;
break;
}
Refresh();
Update();
Layout();
Center();
}
void GLCanvas::OnPaint(wxPaintEvent & event)
{
wxPaintDC dc(this);
Draw();
}
void GLCanvas::Draw()
{
WindowSizeInitialize();
ViewportMatrixInitialize();
ModelViewMatrixInitialize();
ProjectionMatrixInitialize();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_TRIANGLES);
glVertex2f(-100, 100);
glVertex2f(0, -100);
glVertex2i(100, 100);
glEnd();
glFlush();
SwapBuffers();
}
void GLCanvas::WindowSizeInitialize()
{
if(currentCanvasType == CanvasType::kScalingWindow)
{
wxSize parentSize = this->GetParent()->GetClientSize();
float parentAspect = (float)parentSize.x / parentSize.y;
float aspect = (float)kResolutionSize_.x / kResolutionSize_.y;
if(parentAspect < aspect)
{
//this->SetClientSize(wxSize(parentSize.x, (float)parentSize.x / aspect));
this->SetMinClientSize(wxSize(parentSize.x, (float)parentSize.x / aspect));
this->SetMaxClientSize(wxSize(parentSize.x, (float)parentSize.x / aspect));
}
else
{
//this->SetClientSize(wxSize((float)parentSize.y * aspect, parentSize.y));
this->SetMinClientSize(wxSize((float)parentSize.y * aspect, parentSize.y));
this->SetMaxClientSize(wxSize((float)parentSize.y * aspect, parentSize.y));
}
}
else
{
//this->SetClientSize(kResolutionSize_ * GetRaito());
this->SetMinClientSize(kResolutionSize_ * GetRaito());
this->SetMaxClientSize(kResolutionSize_ * GetRaito());
}
Center();
}
void GLCanvas::ViewportMatrixInitialize()
{
float raito = GetRaito();
glViewport(0, 0, kResolutionSize_.x * raito, kResolutionSize_.y * raito);
}
void GLCanvas::ProjectionMatrixInitialize()
{
float raito = GetRaito();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-kHalfResolutionSize_.x * raito, kHalfResolutionSize_.x * raito, kHalfResolutionSize_.y * raito, -kHalfResolutionSize_.y * raito, 0.0f, 1.0f);
}
void GLCanvas::ModelViewMatrixInitialize()
{
float raito = GetRaito();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
const wxSize parentSize = this->GetParent()->GetClientSize();
if(currentCanvasType != CanvasType::kScalingWindow)
{
float difference = kResolutionSize_.y * raito - parentSize.y;
if(difference < 0.0f) difference = 0.0f;
glTranslatef(0.0f, difference, 0.0f);
}
glScalef(raito, raito, raito);
}
float GLCanvas::GetRaito()
{
float raito = 0.0f;
switch(currentCanvasType)
{
case CanvasType::kScaling25:
raito = 0.25f;
break;
case CanvasType::kScaling50:
raito = 0.5f;
break;
case CanvasType::kScaling100:
raito = 1.0f;
break;
case CanvasType::kScaling200:
raito = 2.0f;
break;
case CanvasType::kScalingWindow:
raito = (float)this->GetSize().x / kResolutionSize_.x;
break;
}
return raito;
}