From cf300cd3d39f33a5296e2e301a66825ad71080ff Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Thu, 3 Sep 2026 14:46:36 +0100
Subject: [PATCH 1/9] gitignore
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index 2f86d111..14e14126 100644
--- a/.gitignore
+++ b/.gitignore
@@ -85,3 +85,4 @@ examples/xdg-shell.o
# stb image headerss
stb_image_write.h
stb_image.h
+/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets/x64/Debug
From 8bd9005c2d94518bea9505b3d13ca8eaf118aadb Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Sun, 6 Sep 2026 15:10:50 +0100
Subject: [PATCH 2/9] gitignore for wx
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index 14e14126..a89c4adc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -86,3 +86,4 @@ examples/xdg-shell.o
stb_image_write.h
stb_image.h
/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets/x64/Debug
+/dev/msvc/olcPGE3_wxWidgets/x64/Debug
From a2ea453c53be3d9942a62587917768b56e3714c2 Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Sun, 6 Sep 2026 15:11:09 +0100
Subject: [PATCH 3/9] added basic infrastructure, not functioning yet but
compiles
---
dev/msvc/olcPGE3.sln | 10 +
dev/msvc/olcPGE3.vcxproj | 9 +
dev/msvc/olcPGE3.vcxproj.filters | 24 +-
dev/msvc/olcPGE3_wxWidgets/cApp.cpp | 19 ++
dev/msvc/olcPGE3_wxWidgets/cApp.h | 12 +
dev/msvc/olcPGE3_wxWidgets/cMain.cpp | 61 +++++
dev/msvc/olcPGE3_wxWidgets/cMain.h | 43 ++++
.../olcPGE3_wxWidgets.vcxproj | 161 ++++++++++++
.../olcPGE3_wxWidgets.vcxproj.filters | 36 +++
dev/msvc/olcPGE3_wxWidgets/wx_pge3.cpp | 3 +
dev/src/api_opengl.h | 5 +
dev/src/config.h | 3 +
dev/src/core.cpp | 4 +
dev/src/font.cpp | 4 +
dev/src/font.h | 12 +
dev/src/gpu_opengl33.cpp | 6 +
dev/src/host_wxwidgets.cpp | 124 ++++++++++
dev/src/host_wxwidgets.h | 86 +++++++
dev/src/sh_template.h | 25 +-
olcPixelGameEngine3.h | 231 +++++++++++++++++-
20 files changed, 862 insertions(+), 16 deletions(-)
create mode 100644 dev/msvc/olcPGE3_wxWidgets/cApp.cpp
create mode 100644 dev/msvc/olcPGE3_wxWidgets/cApp.h
create mode 100644 dev/msvc/olcPGE3_wxWidgets/cMain.cpp
create mode 100644 dev/msvc/olcPGE3_wxWidgets/cMain.h
create mode 100644 dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj
create mode 100644 dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj.filters
create mode 100644 dev/msvc/olcPGE3_wxWidgets/wx_pge3.cpp
create mode 100644 dev/src/host_wxwidgets.cpp
create mode 100644 dev/src/host_wxwidgets.h
diff --git a/dev/msvc/olcPGE3.sln b/dev/msvc/olcPGE3.sln
index 33b66c2e..b18666d0 100644
--- a/dev/msvc/olcPGE3.sln
+++ b/dev/msvc/olcPGE3.sln
@@ -7,6 +7,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "olcPGE3", "olcPGE3.vcxproj"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "olcPGE3_BuildSH", "olcPGE3_BuildSH\olcPGE3_BuildSH.vcxproj", "{227300C2-9BC8-4E66-95FC-334A009D449B}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "olcPGE3_wxWidgets", "olcPGE3_wxWidgets\olcPGE3_wxWidgets.vcxproj", "{B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@@ -31,6 +33,14 @@ Global
{227300C2-9BC8-4E66-95FC-334A009D449B}.Release|x64.Build.0 = Release|x64
{227300C2-9BC8-4E66-95FC-334A009D449B}.Release|x86.ActiveCfg = Release|Win32
{227300C2-9BC8-4E66-95FC-334A009D449B}.Release|x86.Build.0 = Release|Win32
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Debug|x64.ActiveCfg = Debug|x64
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Debug|x64.Build.0 = Debug|x64
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Debug|x86.ActiveCfg = Debug|Win32
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Debug|x86.Build.0 = Debug|Win32
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Release|x64.ActiveCfg = Release|x64
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Release|x64.Build.0 = Release|x64
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Release|x86.ActiveCfg = Release|Win32
+ {B87BDA1C-BB21-486C-BEB1-7C33AF2442C0}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/dev/msvc/olcPGE3.vcxproj b/dev/msvc/olcPGE3.vcxproj
index 598c8157..e3e0dd0d 100644
--- a/dev/msvc/olcPGE3.vcxproj
+++ b/dev/msvc/olcPGE3.vcxproj
@@ -234,6 +234,10 @@
true
+
+ true
+ true
+
@@ -258,6 +262,7 @@
true
true
+
@@ -315,6 +320,10 @@
true
+
+ true
+ true
+
diff --git a/dev/msvc/olcPGE3.vcxproj.filters b/dev/msvc/olcPGE3.vcxproj.filters
index 2323331a..254b087f 100644
--- a/dev/msvc/olcPGE3.vcxproj.filters
+++ b/dev/msvc/olcPGE3.vcxproj.filters
@@ -49,6 +49,9 @@
{76f094ac-5176-4402-9395-6187374c5d64}
+
+ {eb0bb606-e8b0-419b-b621-b61633c50add}
+
@@ -144,9 +147,6 @@
Header Files
-
- Hosts
-
GPUs
@@ -171,15 +171,24 @@
Hardware
-
- Hosts
-
Header Files
Utilities
+
+ Header Files
+
+
+ Header Files
+
+
+ Hosts
+
+
+ Hosts\wxWidgets Specific
+
@@ -257,6 +266,9 @@
Hardware
+
+ Hosts\wxWidgets Specific
+
diff --git a/dev/msvc/olcPGE3_wxWidgets/cApp.cpp b/dev/msvc/olcPGE3_wxWidgets/cApp.cpp
new file mode 100644
index 00000000..eebc29a1
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/cApp.cpp
@@ -0,0 +1,19 @@
+#include "cApp.h"
+#include "cMain.h"
+
+
+
+wxIMPLEMENT_APP(cApp);
+
+bool cApp::OnInit()
+{
+ if (!wxApp::OnInit())
+ return false;
+
+ cMain* pMain = new cMain();
+ pMain->Show(true);
+ SetTopWindow(pMain);
+
+ return true;
+}
+
diff --git a/dev/msvc/olcPGE3_wxWidgets/cApp.h b/dev/msvc/olcPGE3_wxWidgets/cApp.h
new file mode 100644
index 00000000..7752604e
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/cApp.h
@@ -0,0 +1,12 @@
+#pragma once
+
+#include
+
+class cApp : public wxApp
+{
+public:
+ virtual bool OnInit() override;
+};
+
+wxDECLARE_APP(cApp);
+
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.cpp b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
new file mode 100644
index 00000000..dae55ec1
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
@@ -0,0 +1,61 @@
+#include "cMain.h"
+
+// === BallPanel ===
+
+BallPanel::BallPanel(wxWindow* pParent, olc::wx::PGE3Core* core) : olc::wx::PGE3Panel(pParent, core)
+{
+
+}
+
+
+// === MouseFollowPanel ===
+//
+//MouseFollowPanel::MouseFollowPanel(wxWindow* pParent) : olc::wx::wxOLCPGE3Panel(pParent, { 160, 120 }, { 4, 4 })
+//{
+// sAppName = "wxWidgets Mouse Demo";
+//}
+//
+//bool MouseFollowPanel::OnUserCreate()
+//{
+// return true;
+//}
+//
+//bool MouseFollowPanel::OnUserUpdate(float fElapsedTime)
+//{
+// olc_IgnoreUnused(fElapsedTime);
+// auto& draw = GetDraw();
+// draw.Clear(olc::Colour::DARK_GREEN);
+// draw.FilledCircle(GetMouse().GetPosition(), 6.0f, olc::Colour::RED);
+// draw.String({ 4, 4 }, "Move mouse here", olc::Colour::WHITE);
+// return true;
+//}
+
+// === cMain ===
+
+cMain::cMain()
+ : wxFrame(nullptr, wxID_ANY, "olcPGE3 wxWidgets", wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE)
+{
+ wxPanel* pRoot = new wxPanel(this);
+ wxBoxSizer* pSizer = new wxBoxSizer(wxHORIZONTAL);
+
+ m_pBall = new BallPanel(pRoot);
+ //m_pMouse = new MouseFollowPanel(pRoot);
+
+ pSizer->Add(m_pBall, 1, wxEXPAND | wxALL, 8);
+ //pSizer->Add(m_pMouse, 1, wxEXPAND | wxALL, 8);
+ pRoot->SetSizer(pSizer);
+
+ // Drive redraws via a timer, since "only cause a redraw when the
+ // panel is refreshed" means the application - not the engine - is
+ // responsible for frame pacing.
+ m_timer.Bind(wxEVT_TIMER, &cMain::OnTick, this);
+ m_timer.Start(1000 / 60); // ~60 FPS
+}
+
+void cMain::OnTick(wxTimerEvent& event)
+{
+ olc_IgnoreUnused(event);
+ m_pBall->Refresh(false);
+ //m_pMouse->Refresh(false);
+}
+
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.h b/dev/msvc/olcPGE3_wxWidgets/cMain.h
new file mode 100644
index 00000000..06cd1628
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.h
@@ -0,0 +1,43 @@
+#pragma once
+
+#define OLC_USE_WXWIDGETS
+#include "..\..\..\olcPixelGameEngine3.h"
+
+
+
+
+// A simple bouncing-ball panel
+class BallPanel : public olc::wx::PGE3Panel
+{
+public:
+ BallPanel(wxWindow* pParent, olc::wx::PGE3Core* core = nullptr);
+
+private:
+ olc::vf2d vPos;
+ olc::vf2d vVel;
+};
+
+// A simple mouse-follow panel to demonstrate independent input per-panel
+//class MouseFollowPanel : public olc::wx::wxOLCPGE3Panel
+//{
+//public:
+// MouseFollowPanel(wxWindow* pParent);
+//
+// bool OnUserCreate() override;
+// bool OnUserUpdate(float fElapsedTime) override;
+//};
+
+class cMain : public wxFrame
+{
+public:
+ cMain();
+
+private:
+ void OnTick(wxTimerEvent& event);
+
+private:
+ BallPanel* m_pBall = nullptr;
+ //MouseFollowPanel* m_pMouse = nullptr;
+ wxTimer m_timer;
+};
+
diff --git a/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj b/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj
new file mode 100644
index 00000000..7e76d0e7
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj
@@ -0,0 +1,161 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 18.0
+ Win32Proj
+ {b87bda1c-bb21-486c-beb1-7c33af2442c0}
+ olcPGE3wxWidgets
+ 10.0
+
+
+
+ Application
+ true
+ v145
+ Unicode
+
+
+ Application
+ false
+ v145
+ true
+ Unicode
+
+
+ Application
+ true
+ v145
+ Unicode
+
+
+ Application
+ false
+ v145
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ E:\sdks\wx333\include;E:\sdks\wx333\include\msvc;$(IncludePath)
+ E:\sdks\wx333\lib\vc_x64_lib;$(LibraryPath)
+
+
+ E:\sdks\wx333\include;E:\sdks\wx333\include\msvc;$(VC_IncludePath);$(WindowsSDK_IncludePath);
+ E:\sdks\wx333\lib\vc_x64_lib;$(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64)
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+
+
+ Console
+ true
+
+
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+
+
+ Console
+ true
+
+
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+
+
+ Windows
+ true
+
+
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp20
+
+
+ Windows
+ true
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj.filters b/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj.filters
new file mode 100644
index 00000000..d26e64c3
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj.filters
@@ -0,0 +1,36 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
\ No newline at end of file
diff --git a/dev/msvc/olcPGE3_wxWidgets/wx_pge3.cpp b/dev/msvc/olcPGE3_wxWidgets/wx_pge3.cpp
new file mode 100644
index 00000000..d268e00a
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/wx_pge3.cpp
@@ -0,0 +1,3 @@
+#define OLC_USE_WXWIDGETS
+#define OLC_PGE3_APPLICATION
+#include "..\..\..\olcPixelGameEngine3.h"
\ No newline at end of file
diff --git a/dev/src/api_opengl.h b/dev/src/api_opengl.h
index 4ba39a28..c6c120ac 100644
--- a/dev/src/api_opengl.h
+++ b/dev/src/api_opengl.h
@@ -86,6 +86,11 @@
#define OGL_LOAD(t) reinterpret_cast(eglGetProcAddress(#t))
#endif
+#if OLC_HOST == OLC_HOST_WXWIDGETS
+
+
+#endif
+
#if !defined(CALLSTYLE)
#define CALLSTYLE
#endif
diff --git a/dev/src/config.h b/dev/src/config.h
index 60136e88..fb23c038 100644
--- a/dev/src/config.h
+++ b/dev/src/config.h
@@ -35,6 +35,7 @@
#define OLC_HOST_ANDROID 7
#define OLC_HOST_IOS 8
+
#if !defined(OLC_HOST)
#if defined(_WIN32)
#define OLC_HOST OLC_HOST_WINDOWS
@@ -123,6 +124,7 @@
#define OLC_IMAGELOADER OLC_IMAGELOADER_NDK_IMAGEDECODER
#define OLC_IMAGELOADER_CLASS ImageLoader_NDKImageDecoder
#endif
+
#endif
// We wait until after the platform specific image loader is selected
@@ -199,4 +201,5 @@ inline constexpr void olc_IgnoreUnused(Args&&...) noexcept {}
#define OLC_FRIENDLY_HOST Host_Android
#endif
+
//! END CONFIGURATION
diff --git a/dev/src/core.cpp b/dev/src/core.cpp
index 8b39c45a..19da9c92 100644
--- a/dev/src/core.cpp
+++ b/dev/src/core.cpp
@@ -37,6 +37,10 @@
#include "host_android.h"
#endif
+#if OLC_HOST == OLC_HOST_WXWIDGETS
+#include "host_wxwidgets.h"
+#endif
+
#if OLC_IMAGELOADER == OLC_IMAGELOADER_WINGDI
#include "imload_wingdi.h"
#endif
diff --git a/dev/src/font.cpp b/dev/src/font.cpp
index be13d212..7660be8c 100644
--- a/dev/src/font.cpp
+++ b/dev/src/font.cpp
@@ -7,7 +7,11 @@ namespace olc
{
namespace pgeguts
{
+#if defined(OLC_USE_WXWIDGETS)
+ void CreateClassicFont(olc::wx::PGE3Core* pge)
+#else
void CreateClassicFont(olc::PGEWindow* pge)
+#endif
{
std::string data =
"?Q`0001oOch0o01o@F40o000000000"
diff --git a/dev/src/font.h b/dev/src/font.h
index 6bb29762..9a03bc0d 100644
--- a/dev/src/font.h
+++ b/dev/src/font.h
@@ -21,7 +21,15 @@
#if !defined(PGE_FONT_DECLARED)
namespace olc
{
+#if defined(OLC_USE_WXWIDGETS)
+ namespace wx
+ {
+ class PGE3Core;
+ }
+#else
class PGEWindow;
+#endif
+
struct FontGlyph
{
@@ -64,7 +72,11 @@ namespace olc
namespace pgeguts
{
// Create the classic PGE font
+#if defined(OLC_USE_WXWIDGETS)
+ void CreateClassicFont(olc::wx::PGE3Core* pge);
+#else
void CreateClassicFont(olc::PGEWindow* pge);
+#endif
}
}
diff --git a/dev/src/gpu_opengl33.cpp b/dev/src/gpu_opengl33.cpp
index 66bc14bc..4341ced8 100644
--- a/dev/src/gpu_opengl33.cpp
+++ b/dev/src/gpu_opengl33.cpp
@@ -374,6 +374,12 @@ void main()
lastError = RendererError::FailedToCreateRenderContext;
return false;
}
+#endif
+
+#if OLC_HOST == OLC_HOST_WXWIDGETS
+
+
+
#endif
// Can't load OpenGL API until context is loaded
diff --git a/dev/src/host_wxwidgets.cpp b/dev/src/host_wxwidgets.cpp
new file mode 100644
index 00000000..ff2f9d39
--- /dev/null
+++ b/dev/src/host_wxwidgets.cpp
@@ -0,0 +1,124 @@
+#include "host_wxwidgets.h"
+
+
+//! START IMPLEMENTATION
+namespace olc::wx
+{
+ PGE3Core::PGE3Core(wxWindow* parent)
+ {
+ }
+
+ PGE3Core::~PGE3Core()
+ {
+ }
+
+ bool PGE3Core::CreateImage(olc::Image& image, const olc::vi2d& size, const ImageConfig& cfg)
+ {
+ // Create CPU Image
+ if (!image.CreateNoGPU(size, cfg))
+ return false;
+
+ // Create GPU Image
+ auto id = pRenderer->CreateTexture(image.Size(), cfg);
+ if (id == 0)
+ {
+ image.CreateNoGPU({ 0,0 });
+ return false;
+ }
+
+ // Associate CPU object with GPU Resource
+ image.SetGPUID(id);
+ return true;
+ }
+
+ bool PGE3Core::CreateImageFromFile(olc::Image& image, const std::string& sFileName, const ImageConfig& cfg)
+ {
+ if (pImageLoader->CreateImageFromFile(image, sFileName))
+ {
+ // Image has loaded ok, and populated into pixel vector
+ //
+ // Create GPU Image
+ auto id = pRenderer->CreateTexture(image.Size(), cfg);
+ if (id == 0)
+ {
+ image.CreateNoGPU({ 0,0 });
+ return false;
+ }
+
+ // Associate CPU object with GPU Resource
+ image.SetGPUID(id);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool PGE3Core::CreateImageFromMemory(olc::Image& image, const uint8_t* data, const size_t bytes, const ImageConfig& cfg)
+ {
+ if (pImageLoader->CreateImageFromMemory(image, data, bytes))
+ {
+ // Image has loaded ok, and populated into pixel vector
+ //
+ // Create GPU Image
+ auto id = pRenderer->CreateTexture(image.Size(), cfg);
+ if (id == 0)
+ {
+ image.CreateNoGPU({ 0,0 });
+ return false;
+ }
+
+ // Associate CPU object with GPU Resource
+ image.SetGPUID(id);
+ return true;
+ }
+
+ std::cout << "Create From Memory Failed\n";
+ return false;
+ }
+
+ bool PGE3Core::WriteImageToFile(const olc::Image& image, const std::string& sFileName)
+ {
+ olc_IgnoreUnused(image, sFileName);
+ return false;
+ }
+
+ void PGE3Core::DestroyImage(olc::Image& image)
+ {
+ // If image has gpu resource, remove it
+ if (image.GetGPUID() != 0)
+ {
+ pRenderer->DeleteTexture(uint32_t(image.GetGPUID()));
+ image.SetGPUID(0);
+ }
+
+ // Free any cpu memory associated with image
+ image.CreateNoGPU({ 0,0 });
+ }
+
+ PGE3Panel::PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core)
+ {
+ }
+
+ PGE3Panel::~PGE3Panel()
+ {
+ }
+
+ void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
+ {
+ }
+
+ void PGE3Panel::OnPreRender()
+ {
+ }
+
+ void PGE3Panel::OnRender()
+ {
+ }
+
+ void PGE3Panel::OnPostRender()
+ {
+ }
+
+
+}
+//! END IMPLEMENTATION
diff --git a/dev/src/host_wxwidgets.h b/dev/src/host_wxwidgets.h
new file mode 100644
index 00000000..e9de3c99
--- /dev/null
+++ b/dev/src/host_wxwidgets.h
@@ -0,0 +1,86 @@
+#pragma once
+#include "core.h"
+
+//! START STDHEADER GLOBAL
+#include
+#include
+#include
+//! END STDHEADER
+
+//! START CUSTOMHEADER
+#include "pixel.h"
+#include "vector2d.h"
+#include "vector4d.h"
+#include "matrix3d.h"
+#include "matrix4d.h"
+#include "transform2d.h"
+#include "image.h"
+#include "imload_iface.h"
+#include "gpu_iface.h"
+//! END CUSTOMHEADER
+
+//! START WXWIDGETS_CONFIG
+#include
+#include
+//! END WXWIDGETS_CONFIG
+
+//! START DECLARATION
+// Not really an olc::Host, but some stand alone components that wxWidgets
+// can use and get a PGE3 like rendering and user experience
+namespace olc::wx
+{
+ class PGE3Core
+ {
+ public:
+ PGE3Core(wxWindow* parent);
+ virtual ~PGE3Core();
+
+ // Create an image resource
+ bool CreateImage(olc::Image& image, const olc::vi2d& size, const ImageConfig& cfg = olc::ImageConfig());
+ // Create an image resource based on an image file asset on disk
+ bool CreateImageFromFile(olc::Image& image, const std::string& sFileName, const ImageConfig& cfg = olc::ImageConfig());
+ // Create an image resource based on an image file asset in memory
+ bool CreateImageFromMemory(olc::Image& image, const uint8_t* data, const size_t bytes, const ImageConfig& cfg = olc::ImageConfig());
+ // Store an image as a file asset on disk
+ bool WriteImageToFile(const olc::Image& image, const std::string& sFileName);
+ // Store an image as a file asset in memory
+ //bool WriteImageToMemory(const olc::Image& image, std::vector bytes, const std::string& sFileName);
+ // Destroy an image
+ void DestroyImage(olc::Image& image);
+
+
+
+ private: // wxWidgets Specific
+ wxGLContext* m_glContext = nullptr;
+
+ private: // Global PGE3 Components (excluding host)
+ std::unique_ptr pRenderer;
+ std::unique_ptr pImageLoader;
+ };
+
+ class PGE3Panel : public wxGLCanvas
+ {
+ public:
+ PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core = nullptr);
+ virtual ~PGE3Panel();
+
+ protected: // Local PGE3 Components
+ olc::Draw draw;
+
+ private:
+ // Same core is loaded across all panels in application
+ static olc::wx::PGE3Core* m_pCore;
+ olc::Image imgPrimary;
+
+
+ private: // wxWidgets Overrides
+ void Event_OnPaint(wxPaintEvent& evt);
+
+
+ protected: // User Overrides
+ virtual void OnPreRender();
+ virtual void OnRender();
+ virtual void OnPostRender();
+ };
+}
+//! END DECLARATION
diff --git a/dev/src/sh_template.h b/dev/src/sh_template.h
index 21767228..106bd1ff 100644
--- a/dev/src/sh_template.h
+++ b/dev/src/sh_template.h
@@ -147,6 +147,7 @@
//! GRAB hw_touch.h DECLARATION
+#if OLC_HOST != OLC_HOST_WXWIDGETS
//! GRAB window.h DECLARATION
//! GRAB host_iface.h DECLARATION
@@ -154,14 +155,14 @@
//! GRAB extension.h DECLARATION
//! GRAB core.h DECLARATION
+#endif
-
-
+#if !defined(OLC_USE_WXWIDGETS)
#if OLC_HOST == OLC_HOST_NONE
//! GRAB host_none.h NOHOST_CONFIG
@@ -209,6 +210,13 @@
//! GRAB host_android.h DECLARATION
#endif
+#else
+//! GRAB host_wxwidgets.h WXWIDGETS_CONFIG
+
+//! GRAB host_wxwidgets.h DECLARATION
+#endif
+
+
#if OLC_GPU == OLC_GPU_NONE
//! GRAB gpu_none.h DECLARATION
#endif
@@ -246,6 +254,9 @@
#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_HOST_IMPLEMENTED)
+
+#if !defined(OLC_USE_WXWIDGETS)
+
#if OLC_HOST == OLC_HOST_NONE
//! GRAB host_none.cpp IMPLEMENTATION
#endif
@@ -253,11 +264,11 @@
#if OLC_HOST == OLC_HOST_WINDOWS
//! GRAB host_win_winapi.cpp IMPLEMENTATION
#endif
+
#if OLC_HOST == OLC_HOST_MACOS
//! GRAB host_apple_macos.cpp IMPLEMENTATION
//! GRAB api_macos.cpp IMPLEMENTATION
-
#endif
#if OLC_HOST == OLC_HOST_LINUX_X11
@@ -276,6 +287,10 @@
//! GRAB host_android.cpp IMPLEMENTATION
#endif
+#else // Using wxWidgets
+//! GRAB host_wxwidgets.cpp IMPLEMENTATION
+#endif
+
#define PGE_HOST_IMPLEMENTED 1
#endif
@@ -300,7 +315,7 @@
#define PGE_DRAW_IMPLEMENTED 1
#endif
-#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_CORE_IMPLEMENTED)
+#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_CORE_IMPLEMENTED) && !defined(OLC_USE_WXWIDGETS)
//! GRAB core.cpp IMPLEMENTATION
#define PGE_CORE_IMPLEMENTED 1
#endif
@@ -330,7 +345,7 @@
#define PGE_HW_TOUCH_IMPLEMENTED 1
#endif
-#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_WINDOW_IMPLEMENTED)
+#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_WINDOW_IMPLEMENTED) && !defined(OLC_USE_WXWIDGETS)
//! GRAB window.cpp IMPLEMENTATION
#define PGE_WINDOW_IMPLEMENTED 1
#endif
diff --git a/olcPixelGameEngine3.h b/olcPixelGameEngine3.h
index a8a4da8b..b2652912 100644
--- a/olcPixelGameEngine3.h
+++ b/olcPixelGameEngine3.h
@@ -175,6 +175,7 @@
#define OLC_HOST_ANDROID 7
#define OLC_HOST_IOS 8
+
#if !defined(OLC_HOST)
#if defined(_WIN32)
#define OLC_HOST OLC_HOST_WINDOWS
@@ -263,6 +264,7 @@
#define OLC_IMAGELOADER OLC_IMAGELOADER_NDK_IMAGEDECODER
#define OLC_IMAGELOADER_CLASS ImageLoader_NDKImageDecoder
#endif
+
#endif
// We wait until after the platform specific image loader is selected
@@ -340,6 +342,7 @@ inline constexpr void olc_IgnoreUnused(Args&&...) noexcept {}
#endif
+
#if !defined(PGE_PIXEL_DECLARED)
#if OLC_HOST == OLC_HOST_MACOS
#pragma clang diagnostic push
@@ -2414,7 +2417,15 @@ namespace olc
#if !defined(PGE_FONT_DECLARED)
namespace olc
{
+#if defined(OLC_USE_WXWIDGETS)
+ namespace wx
+ {
+ class PGE3Core;
+ }
+#else
class PGEWindow;
+#endif
+
struct FontGlyph
{
@@ -2457,7 +2468,11 @@ namespace olc
namespace pgeguts
{
// Create the classic PGE font
+#if defined(OLC_USE_WXWIDGETS)
+ void CreateClassicFont(olc::wx::PGE3Core* pge);
+#else
void CreateClassicFont(olc::PGEWindow* pge);
+#endif
}
}
@@ -3872,6 +3887,7 @@ namespace olc
#define PGE_HW_TOUCH_DECLARED 1
#endif
+#if OLC_HOST != OLC_HOST_WXWIDGETS
#if !defined(PGE_WINDOW_DECLARED)
namespace olc
{
@@ -4361,14 +4377,14 @@ namespace olc
}
#define PGE_CORE_DECLARED 1
#endif
+#endif
-
-
+#if !defined(OLC_USE_WXWIDGETS)
#if OLC_HOST == OLC_HOST_NONE
@@ -6617,6 +6633,71 @@ namespace olc::host
}
#endif
+#else
+#include
+#include
+
+// Not really an olc::Host, but some stand alone components that wxWidgets
+// can use and get a PGE3 like rendering and user experience
+namespace olc::wx
+{
+ class PGE3Core
+ {
+ public:
+ PGE3Core(wxWindow* parent);
+ virtual ~PGE3Core();
+
+ // Create an image resource
+ bool CreateImage(olc::Image& image, const olc::vi2d& size, const ImageConfig& cfg = olc::ImageConfig());
+ // Create an image resource based on an image file asset on disk
+ bool CreateImageFromFile(olc::Image& image, const std::string& sFileName, const ImageConfig& cfg = olc::ImageConfig());
+ // Create an image resource based on an image file asset in memory
+ bool CreateImageFromMemory(olc::Image& image, const uint8_t* data, const size_t bytes, const ImageConfig& cfg = olc::ImageConfig());
+ // Store an image as a file asset on disk
+ bool WriteImageToFile(const olc::Image& image, const std::string& sFileName);
+ // Store an image as a file asset in memory
+ //bool WriteImageToMemory(const olc::Image& image, std::vector bytes, const std::string& sFileName);
+ // Destroy an image
+ void DestroyImage(olc::Image& image);
+
+
+
+ private: // wxWidgets Specific
+ wxGLContext* m_glContext = nullptr;
+
+ private: // Global PGE3 Components (excluding host)
+ std::unique_ptr pRenderer;
+ std::unique_ptr pImageLoader;
+ };
+
+ class PGE3Panel : public wxGLCanvas
+ {
+ public:
+ PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core = nullptr);
+ virtual ~PGE3Panel();
+
+ protected: // Local PGE3 Components
+ olc::Draw draw;
+
+ private:
+ // Same core is loaded across all panels in application
+ static olc::wx::PGE3Core* m_pCore;
+ olc::Image imgPrimary;
+
+
+ private: // wxWidgets Overrides
+ void Event_OnPaint(wxPaintEvent& evt);
+
+
+ protected: // User Overrides
+ virtual void OnPreRender();
+ virtual void OnRender();
+ virtual void OnPostRender();
+ };
+}
+#endif
+
+
#if OLC_GPU == OLC_GPU_NONE
#if !defined(PGE_RENDERER_NONE_DECLARED)
@@ -6764,6 +6845,11 @@ namespace olc::gpu
#define OGL_LOAD(t) reinterpret_cast(eglGetProcAddress(#t))
#endif
+#if OLC_HOST == OLC_HOST_WXWIDGETS
+
+
+#endif
+
#if !defined(CALLSTYLE)
#define CALLSTYLE
#endif
@@ -7346,6 +7432,9 @@ namespace olc::imload
#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_HOST_IMPLEMENTED)
+
+#if !defined(OLC_USE_WXWIDGETS)
+
#if OLC_HOST == OLC_HOST_NONE
namespace olc::host
{
@@ -8310,6 +8399,7 @@ namespace olc::host
};
#endif
+
#if OLC_HOST == OLC_HOST_MACOS
namespace olc::host {
@@ -12074,7 +12164,6 @@ extern "C" {
} // extern "C"
-
#endif
#if OLC_HOST == OLC_HOST_LINUX_X11
@@ -15288,6 +15377,128 @@ void android_main(struct android_app* app)
}
#endif
+#else // Using wxWidgets
+namespace olc::wx
+{
+ PGE3Core::PGE3Core(wxWindow* parent)
+ {
+ }
+
+ PGE3Core::~PGE3Core()
+ {
+ }
+
+ bool PGE3Core::CreateImage(olc::Image& image, const olc::vi2d& size, const ImageConfig& cfg)
+ {
+ // Create CPU Image
+ if (!image.CreateNoGPU(size, cfg))
+ return false;
+
+ // Create GPU Image
+ auto id = pRenderer->CreateTexture(image.Size(), cfg);
+ if (id == 0)
+ {
+ image.CreateNoGPU({ 0,0 });
+ return false;
+ }
+
+ // Associate CPU object with GPU Resource
+ image.SetGPUID(id);
+ return true;
+ }
+
+ bool PGE3Core::CreateImageFromFile(olc::Image& image, const std::string& sFileName, const ImageConfig& cfg)
+ {
+ if (pImageLoader->CreateImageFromFile(image, sFileName))
+ {
+ // Image has loaded ok, and populated into pixel vector
+ //
+ // Create GPU Image
+ auto id = pRenderer->CreateTexture(image.Size(), cfg);
+ if (id == 0)
+ {
+ image.CreateNoGPU({ 0,0 });
+ return false;
+ }
+
+ // Associate CPU object with GPU Resource
+ image.SetGPUID(id);
+ return true;
+ }
+
+ return false;
+ }
+
+ bool PGE3Core::CreateImageFromMemory(olc::Image& image, const uint8_t* data, const size_t bytes, const ImageConfig& cfg)
+ {
+ if (pImageLoader->CreateImageFromMemory(image, data, bytes))
+ {
+ // Image has loaded ok, and populated into pixel vector
+ //
+ // Create GPU Image
+ auto id = pRenderer->CreateTexture(image.Size(), cfg);
+ if (id == 0)
+ {
+ image.CreateNoGPU({ 0,0 });
+ return false;
+ }
+
+ // Associate CPU object with GPU Resource
+ image.SetGPUID(id);
+ return true;
+ }
+
+ std::cout << "Create From Memory Failed\n";
+ return false;
+ }
+
+ bool PGE3Core::WriteImageToFile(const olc::Image& image, const std::string& sFileName)
+ {
+ olc_IgnoreUnused(image, sFileName);
+ return false;
+ }
+
+ void PGE3Core::DestroyImage(olc::Image& image)
+ {
+ // If image has gpu resource, remove it
+ if (image.GetGPUID() != 0)
+ {
+ pRenderer->DeleteTexture(uint32_t(image.GetGPUID()));
+ image.SetGPUID(0);
+ }
+
+ // Free any cpu memory associated with image
+ image.CreateNoGPU({ 0,0 });
+ }
+
+ PGE3Panel::PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core)
+ {
+ }
+
+ PGE3Panel::~PGE3Panel()
+ {
+ }
+
+ void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
+ {
+ }
+
+ void PGE3Panel::OnPreRender()
+ {
+ }
+
+ void PGE3Panel::OnRender()
+ {
+ }
+
+ void PGE3Panel::OnPostRender()
+ {
+ }
+
+
+}
+#endif
+
#define PGE_HOST_IMPLEMENTED 1
#endif
@@ -16411,6 +16622,12 @@ void main()
lastError = RendererError::FailedToCreateRenderContext;
return false;
}
+#endif
+
+#if OLC_HOST == OLC_HOST_WXWIDGETS
+
+
+
#endif
// Can't load OpenGL API until context is loaded
@@ -19240,7 +19457,7 @@ const ImageBatch& olc::Draw::ImageRect(olc::ImageBatch& batch, olc::ImageRegion
#define PGE_DRAW_IMPLEMENTED 1
#endif
-#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_CORE_IMPLEMENTED)
+#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_CORE_IMPLEMENTED) && !defined(OLC_USE_WXWIDGETS)
namespace olc
{
PGEWindow::PGEWindow() : Window(), draw()
@@ -20012,7 +20229,11 @@ namespace olc
{
namespace pgeguts
{
+#if defined(OLC_USE_WXWIDGETS)
+ void CreateClassicFont(olc::wx::PGE3Core* pge)
+#else
void CreateClassicFont(olc::PGEWindow* pge)
+#endif
{
std::string data =
"?Q`0001oOch0o01o@F40o000000000"
@@ -20472,7 +20693,7 @@ namespace olc::hw
#define PGE_HW_TOUCH_IMPLEMENTED 1
#endif
-#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_WINDOW_IMPLEMENTED)
+#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_WINDOW_IMPLEMENTED) && !defined(OLC_USE_WXWIDGETS)
namespace olc
{
Window::Window()
From 77375073fc926bcc27d94f90221c36f7ebf04c31 Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Sun, 6 Sep 2026 19:44:37 +0100
Subject: [PATCH 4/9] Basic bare bones implementation at least gets renderer up
and running and things drawing
---
dev/msvc/olcPGE3_wxWidgets/cMain.cpp | 51 +++----
dev/msvc/olcPGE3_wxWidgets/cMain.h | 24 +---
dev/msvc/olcPGE3_wxWidgets/make_pge3.bat | 4 +
.../olcPGE3_wxWidgets.vcxproj | 6 +
dev/src/gpu_opengl33.cpp | 9 +-
dev/src/host_wxwidgets.cpp | 111 ++++++++++++++-
dev/src/host_wxwidgets.h | 14 +-
olcPixelGameEngine3.h | 134 +++++++++++++++---
8 files changed, 268 insertions(+), 85 deletions(-)
create mode 100644 dev/msvc/olcPGE3_wxWidgets/make_pge3.bat
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.cpp b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
index dae55ec1..6db97736 100644
--- a/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
@@ -1,61 +1,44 @@
#include "cMain.h"
-// === BallPanel ===
-BallPanel::BallPanel(wxWindow* pParent, olc::wx::PGE3Core* core) : olc::wx::PGE3Panel(pParent, core)
+BallPanel::BallPanel(wxWindow* pParent) : olc::wx::PGE3Panel(pParent)
{
}
+void BallPanel::OnRender()
+{
+ draw.Line({ 0,0 }, olc::Colour::BLUE, { 256, 240 }, olc::Colour::RED);
+
+ draw.StringProp({ 10, 2 }, "olc::PixelGameEngine\nin\nwxWidgets!", olc::Colour::WHITE);
+}
+
+
+
-// === MouseFollowPanel ===
-//
-//MouseFollowPanel::MouseFollowPanel(wxWindow* pParent) : olc::wx::wxOLCPGE3Panel(pParent, { 160, 120 }, { 4, 4 })
-//{
-// sAppName = "wxWidgets Mouse Demo";
-//}
-//
-//bool MouseFollowPanel::OnUserCreate()
-//{
-// return true;
-//}
-//
-//bool MouseFollowPanel::OnUserUpdate(float fElapsedTime)
-//{
-// olc_IgnoreUnused(fElapsedTime);
-// auto& draw = GetDraw();
-// draw.Clear(olc::Colour::DARK_GREEN);
-// draw.FilledCircle(GetMouse().GetPosition(), 6.0f, olc::Colour::RED);
-// draw.String({ 4, 4 }, "Move mouse here", olc::Colour::WHITE);
-// return true;
-//}
-
-// === cMain ===
cMain::cMain()
: wxFrame(nullptr, wxID_ANY, "olcPGE3 wxWidgets", wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE)
{
+
wxPanel* pRoot = new wxPanel(this);
wxBoxSizer* pSizer = new wxBoxSizer(wxHORIZONTAL);
- m_pBall = new BallPanel(pRoot);
- //m_pMouse = new MouseFollowPanel(pRoot);
+ m_pBall1 = new BallPanel(pRoot);
+ pSizer->Add(m_pBall1, 1, wxEXPAND | wxALL, 8);
+ m_pBall2 = new BallPanel(pRoot);
+ pSizer->Add(m_pBall2, 1, wxEXPAND | wxALL, 8);
- pSizer->Add(m_pBall, 1, wxEXPAND | wxALL, 8);
- //pSizer->Add(m_pMouse, 1, wxEXPAND | wxALL, 8);
pRoot->SetSizer(pSizer);
- // Drive redraws via a timer, since "only cause a redraw when the
- // panel is refreshed" means the application - not the engine - is
- // responsible for frame pacing.
m_timer.Bind(wxEVT_TIMER, &cMain::OnTick, this);
- m_timer.Start(1000 / 60); // ~60 FPS
+ m_timer.Start(1000 / 60);
}
void cMain::OnTick(wxTimerEvent& event)
{
olc_IgnoreUnused(event);
- m_pBall->Refresh(false);
+ //m_pBall->Refresh(false);
//m_pMouse->Refresh(false);
}
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.h b/dev/msvc/olcPGE3_wxWidgets/cMain.h
index 06cd1628..4b556aab 100644
--- a/dev/msvc/olcPGE3_wxWidgets/cMain.h
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.h
@@ -3,30 +3,19 @@
#define OLC_USE_WXWIDGETS
#include "..\..\..\olcPixelGameEngine3.h"
-
-
-
-// A simple bouncing-ball panel
class BallPanel : public olc::wx::PGE3Panel
{
public:
- BallPanel(wxWindow* pParent, olc::wx::PGE3Core* core = nullptr);
+ BallPanel(wxWindow* pParent);
+
+protected:
+ void OnRender() override;
private:
olc::vf2d vPos;
olc::vf2d vVel;
};
-// A simple mouse-follow panel to demonstrate independent input per-panel
-//class MouseFollowPanel : public olc::wx::wxOLCPGE3Panel
-//{
-//public:
-// MouseFollowPanel(wxWindow* pParent);
-//
-// bool OnUserCreate() override;
-// bool OnUserUpdate(float fElapsedTime) override;
-//};
-
class cMain : public wxFrame
{
public:
@@ -35,9 +24,10 @@ class cMain : public wxFrame
private:
void OnTick(wxTimerEvent& event);
+
private:
- BallPanel* m_pBall = nullptr;
- //MouseFollowPanel* m_pMouse = nullptr;
+ BallPanel* m_pBall1 = nullptr;
+ BallPanel* m_pBall2 = nullptr;
wxTimer m_timer;
};
diff --git a/dev/msvc/olcPGE3_wxWidgets/make_pge3.bat b/dev/msvc/olcPGE3_wxWidgets/make_pge3.bat
new file mode 100644
index 00000000..10a5794a
--- /dev/null
+++ b/dev/msvc/olcPGE3_wxWidgets/make_pge3.bat
@@ -0,0 +1,4 @@
+@echo on
+cd ..\..\src
+..\..\..\olcGimmeHead\msvc\x64\debug\gimme-head.exe sh_template.h ..\..\olcPixelGameEngine3.h
+rem copy ..\msvc\olcPGE3_BuildSH\olcPixelGameEngine3.h ..\..\olcPixelGameEngine3.h
\ No newline at end of file
diff --git a/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj b/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj
index 7e76d0e7..7fc506ec 100644
--- a/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj
+++ b/dev/msvc/olcPGE3_wxWidgets/olcPGE3_wxWidgets.vcxproj
@@ -127,6 +127,9 @@
true
+
+ $(ProjectDir)make_pge3.bat
+
@@ -145,6 +148,9 @@
true
+
+ $(ProjectDir)make_pge3.bat
+
diff --git a/dev/src/gpu_opengl33.cpp b/dev/src/gpu_opengl33.cpp
index 4341ced8..2c1c197e 100644
--- a/dev/src/gpu_opengl33.cpp
+++ b/dev/src/gpu_opengl33.cpp
@@ -243,7 +243,8 @@ void main()
config = cfg;
-
+#if !defined(OLC_USE_WXWIDGETS)
+
#if OLC_HOST == OLC_HOST_WINDOWS
// Create OpenGL Device Context
if (!PrepareWindowTarget(os_win_id))
@@ -376,11 +377,9 @@ void main()
}
#endif
-#if OLC_HOST == OLC_HOST_WXWIDGETS
-
+#else // wxWidgets specific
-
-#endif
+#endif // wxWidgets
// Can't load OpenGL API until context is loaded
auto& gl = olc::apis::opengl::gl::Get();
diff --git a/dev/src/host_wxwidgets.cpp b/dev/src/host_wxwidgets.cpp
index ff2f9d39..0513e218 100644
--- a/dev/src/host_wxwidgets.cpp
+++ b/dev/src/host_wxwidgets.cpp
@@ -4,12 +4,34 @@
//! START IMPLEMENTATION
namespace olc::wx
{
- PGE3Core::PGE3Core(wxWindow* parent)
+ PGE3Core::PGE3Core(wxWindow* parent) : wxGLCanvas(parent, -1, nullptr)
{
+ // Create a wxWidgets "glContext" targeting OpenGL 3.3
+ wxGLContextAttrs ctxAttrs;
+ ctxAttrs.CoreProfile().OGLVersion(3, 3).EndList();
+ m_glContext = new wxGLContext(this, NULL, &ctxAttrs);
+ SetCurrent(*m_glContext);
+
+
+ // Create all the vital parts of PGE
+ pImageLoader = std::make_unique();
+
+ // Create the renderer
+ olc::gpu::RendererConfig cfgRenderer;
+ pRenderer = std::make_unique();
+ pRenderer->CreateDevice({ this }, cfgRenderer);
+
+ // Load the font
+ olc::pgeguts::CreateClassicFont(this);
+
+ // wxWidgets should hide this pseudo-canvas. It was only
+ // needed to get the context
+ this->Hide();
}
PGE3Core::~PGE3Core()
{
+ delete m_glContext;
}
bool PGE3Core::CreateImage(olc::Image& image, const olc::vi2d& size, const ImageConfig& cfg)
@@ -95,30 +117,105 @@ namespace olc::wx
image.CreateNoGPU({ 0,0 });
}
- PGE3Panel::PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core)
+ wxGLContext* PGE3Core::get() const
{
+ return m_glContext;
}
- PGE3Panel::~PGE3Panel()
+ olc::gpu::Renderer* PGE3Core::GetRenderer()
{
+ return pRenderer.get();
}
- void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
+ olc::imload::ImageLoader* PGE3Core::GetImageLoader()
+ {
+ return pImageLoader.get();
+ }
+
+
+
+ olc::wx::PGE3Core* PGE3Panel::m_pCore = nullptr;
+
+
+
+ PGE3Panel::PGE3Panel(wxWindow* parent) : wxGLCanvas(parent, -1, nullptr)
+ {
+ if (m_pCore == nullptr)
+ {
+ // Create a static PGE3Core
+ m_pCore = new PGE3Core(this);
+ }
+
+ // Set the context via wxWidgets
+ SetCurrent(*m_pCore->get());
+
+ // Associate this instance of draw with the renderer
+ draw.SetGPU(m_pCore->GetRenderer());
+
+ // Create the default draw target
+ m_pCore->CreateImage(imgPrimary, { 256, 240 });
+
+ // Call "OnUserCreate()" before any other drawing can occur
+ ResetDrawState();
+ OnCreate();
+
+ Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
+ }
+
+ PGE3Panel::~PGE3Panel()
{
+
}
- void PGE3Panel::OnPreRender()
+ void PGE3Panel::ResetDrawState()
{
+ // Set the context via wxWidgets
+ SetCurrent(*m_pCore->get());
+ m_pCore->GetRenderer()->ApplyDefaultShader();
+ draw.SetTarget(imgPrimary);
+ draw.WorldReset();
+ draw.SetBlendMode(olc::BlendMode::Alpha);
+ draw.SetCullMode(olc::CullMode::None);
}
- void PGE3Panel::OnRender()
+ void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
{
+ // Configure WX to render this window
+ wxPaintDC(this);
+
+ // Perform actual render
+ ResetDrawState();
+ OnRender();
+ draw.ProcessGPUTasks();
+
+ // Present image to screen in location of panel
+ m_pCore->GetRenderer()->AssignTextureTarget(0, 0);
+
+ olc::vf2d vViewPos = { 0,0 };
+ olc::vf2d vViewSize = { float(GetSize().x), float(GetSize().y) };
+
+ // Present final composite
+ m_pCore->GetRenderer()->SetViewport(vViewPos, vViewSize);
+ m_pCore->GetRenderer()->ClearViewport(olc::Colour::RED, true, true);
+ draw.SetBlendMode(olc::BlendMode::Alpha);
+ draw.SetCullMode(olc::CullMode::None);
+ draw.ImageRect(imgPrimary.flipV(), { 0.0,0.0 }, vViewSize);
+ draw.ProcessGPUTasks();
+
+ // Update Window's primary surface - via wxWidgets
+ SwapBuffers();
}
- void PGE3Panel::OnPostRender()
+
+ void PGE3Panel::OnCreate()
{
+ // Overriden by user
}
+ void PGE3Panel::OnRender()
+ {
+ // Overriden by user
+ }
}
//! END IMPLEMENTATION
diff --git a/dev/src/host_wxwidgets.h b/dev/src/host_wxwidgets.h
index e9de3c99..75fcaa83 100644
--- a/dev/src/host_wxwidgets.h
+++ b/dev/src/host_wxwidgets.h
@@ -29,7 +29,7 @@
// can use and get a PGE3 like rendering and user experience
namespace olc::wx
{
- class PGE3Core
+ class PGE3Core : public wxGLCanvas
{
public:
PGE3Core(wxWindow* parent);
@@ -48,7 +48,10 @@ namespace olc::wx
// Destroy an image
void DestroyImage(olc::Image& image);
-
+ public:
+ wxGLContext* get() const;
+ olc::gpu::Renderer* GetRenderer();
+ olc::imload::ImageLoader* GetImageLoader();
private: // wxWidgets Specific
wxGLContext* m_glContext = nullptr;
@@ -61,9 +64,11 @@ namespace olc::wx
class PGE3Panel : public wxGLCanvas
{
public:
- PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core = nullptr);
+ PGE3Panel(wxWindow* parent);
virtual ~PGE3Panel();
+ void ResetDrawState();
+
protected: // Local PGE3 Components
olc::Draw draw;
@@ -78,9 +83,8 @@ namespace olc::wx
protected: // User Overrides
- virtual void OnPreRender();
+ virtual void OnCreate();
virtual void OnRender();
- virtual void OnPostRender();
};
}
//! END DECLARATION
diff --git a/olcPixelGameEngine3.h b/olcPixelGameEngine3.h
index b2652912..6dace0ec 100644
--- a/olcPixelGameEngine3.h
+++ b/olcPixelGameEngine3.h
@@ -6641,7 +6641,7 @@ namespace olc::host
// can use and get a PGE3 like rendering and user experience
namespace olc::wx
{
- class PGE3Core
+ class PGE3Core : public wxGLCanvas
{
public:
PGE3Core(wxWindow* parent);
@@ -6660,7 +6660,10 @@ namespace olc::wx
// Destroy an image
void DestroyImage(olc::Image& image);
-
+ public:
+ wxGLContext* get() const;
+ olc::gpu::Renderer* GetRenderer();
+ olc::imload::ImageLoader* GetImageLoader();
private: // wxWidgets Specific
wxGLContext* m_glContext = nullptr;
@@ -6673,9 +6676,11 @@ namespace olc::wx
class PGE3Panel : public wxGLCanvas
{
public:
- PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core = nullptr);
+ PGE3Panel(wxWindow* parent);
virtual ~PGE3Panel();
+ void ResetDrawState();
+
protected: // Local PGE3 Components
olc::Draw draw;
@@ -6690,9 +6695,8 @@ namespace olc::wx
protected: // User Overrides
- virtual void OnPreRender();
+ virtual void OnCreate();
virtual void OnRender();
- virtual void OnPostRender();
};
}
#endif
@@ -15380,12 +15384,34 @@ void android_main(struct android_app* app)
#else // Using wxWidgets
namespace olc::wx
{
- PGE3Core::PGE3Core(wxWindow* parent)
+ PGE3Core::PGE3Core(wxWindow* parent) : wxGLCanvas(parent, -1, nullptr)
{
+ // Create a wxWidgets "glContext" targeting OpenGL 3.3
+ wxGLContextAttrs ctxAttrs;
+ ctxAttrs.CoreProfile().OGLVersion(3, 3).EndList();
+ m_glContext = new wxGLContext(this, NULL, &ctxAttrs);
+ SetCurrent(*m_glContext);
+
+
+ // Create all the vital parts of PGE
+ pImageLoader = std::make_unique();
+
+ // Create the renderer
+ olc::gpu::RendererConfig cfgRenderer;
+ pRenderer = std::make_unique();
+ pRenderer->CreateDevice({ this }, cfgRenderer);
+
+ // Load the font
+ olc::pgeguts::CreateClassicFont(this);
+
+ // wxWidgets should hide this pseudo-canvas. It was only
+ // needed to get the context
+ this->Hide();
}
PGE3Core::~PGE3Core()
{
+ delete m_glContext;
}
bool PGE3Core::CreateImage(olc::Image& image, const olc::vi2d& size, const ImageConfig& cfg)
@@ -15471,31 +15497,106 @@ namespace olc::wx
image.CreateNoGPU({ 0,0 });
}
- PGE3Panel::PGE3Panel(wxWindow* parent, olc::wx::PGE3Core* core)
+ wxGLContext* PGE3Core::get() const
{
+ return m_glContext;
}
- PGE3Panel::~PGE3Panel()
+ olc::gpu::Renderer* PGE3Core::GetRenderer()
{
+ return pRenderer.get();
}
- void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
+ olc::imload::ImageLoader* PGE3Core::GetImageLoader()
{
+ return pImageLoader.get();
}
- void PGE3Panel::OnPreRender()
+
+
+ olc::wx::PGE3Core* PGE3Panel::m_pCore = nullptr;
+
+
+
+ PGE3Panel::PGE3Panel(wxWindow* parent) : wxGLCanvas(parent, -1, nullptr)
{
+ if (m_pCore == nullptr)
+ {
+ // Create a static PGE3Core
+ m_pCore = new PGE3Core(this);
+ }
+
+ // Set the context via wxWidgets
+ SetCurrent(*m_pCore->get());
+
+ // Associate this instance of draw with the renderer
+ draw.SetGPU(m_pCore->GetRenderer());
+
+ // Create the default draw target
+ m_pCore->CreateImage(imgPrimary, { 256, 240 });
+
+ // Call "OnUserCreate()" before any other drawing can occur
+ ResetDrawState();
+ OnCreate();
+
+ Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
}
- void PGE3Panel::OnRender()
+ PGE3Panel::~PGE3Panel()
+ {
+
+ }
+
+ void PGE3Panel::ResetDrawState()
{
+ // Set the context via wxWidgets
+ SetCurrent(*m_pCore->get());
+ m_pCore->GetRenderer()->ApplyDefaultShader();
+ draw.SetTarget(imgPrimary);
+ draw.WorldReset();
+ draw.SetBlendMode(olc::BlendMode::Alpha);
+ draw.SetCullMode(olc::CullMode::None);
}
- void PGE3Panel::OnPostRender()
+ void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
{
+ // Configure WX to render this window
+ wxPaintDC(this);
+
+ // Perform actual render
+ ResetDrawState();
+ OnRender();
+ draw.ProcessGPUTasks();
+
+ // Present image to screen in location of panel
+ m_pCore->GetRenderer()->AssignTextureTarget(0, 0);
+
+ olc::vf2d vViewPos = { 0,0 };
+ olc::vf2d vViewSize = { float(GetSize().x), float(GetSize().y) };
+
+ // Present final composite
+ m_pCore->GetRenderer()->SetViewport(vViewPos, vViewSize);
+ m_pCore->GetRenderer()->ClearViewport(olc::Colour::RED, true, true);
+ draw.SetBlendMode(olc::BlendMode::Alpha);
+ draw.SetCullMode(olc::CullMode::None);
+ draw.ImageRect(imgPrimary.flipV(), { 0.0,0.0 }, vViewSize);
+ draw.ProcessGPUTasks();
+
+ // Update Window's primary surface - via wxWidgets
+ SwapBuffers();
}
+ void PGE3Panel::OnCreate()
+ {
+ // Overriden by user
+ }
+
+ void PGE3Panel::OnRender()
+ {
+ // Overriden by user
+ }
+
}
#endif
@@ -16491,7 +16592,8 @@ void main()
config = cfg;
-
+#if !defined(OLC_USE_WXWIDGETS)
+
#if OLC_HOST == OLC_HOST_WINDOWS
// Create OpenGL Device Context
if (!PrepareWindowTarget(os_win_id))
@@ -16624,11 +16726,9 @@ void main()
}
#endif
-#if OLC_HOST == OLC_HOST_WXWIDGETS
+#else // wxWidgets specific
-
-
-#endif
+#endif // wxWidgets
// Can't load OpenGL API until context is loaded
auto& gl = olc::apis::opengl::gl::Get();
From fada10d4dea09fd04b1e4c34205d2a5194ffb5e8 Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Sun, 6 Sep 2026 21:38:09 +0100
Subject: [PATCH 5/9] Added user choice over real size windows or not, ie does
a panel retain a fixed drawn resolution or adapts as sized by surrounding
gui. Also made demo more compelling
---
dev/msvc/olcPGE3_wxWidgets/cMain.cpp | 83 +++++++++++++++++++++++++---
dev/msvc/olcPGE3_wxWidgets/cMain.h | 24 ++++++--
dev/src/gpu_opengl33.cpp | 8 +++
dev/src/host_wxwidgets.cpp | 48 +++++++++++++++-
dev/src/host_wxwidgets.h | 10 +++-
dev/src/image.cpp | 1 +
olcPixelGameEngine3.h | 67 ++++++++++++++++++++--
7 files changed, 220 insertions(+), 21 deletions(-)
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.cpp b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
index 6db97736..fd0592e0 100644
--- a/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
@@ -1,15 +1,14 @@
#include "cMain.h"
-BallPanel::BallPanel(wxWindow* pParent) : olc::wx::PGE3Panel(pParent)
+ExamplePanel1::ExamplePanel1(wxWindow* pParent) : olc::wx::PGE3Panel(pParent)
{
}
-void BallPanel::OnRender()
+void ExamplePanel1::OnRender()
{
draw.Line({ 0,0 }, olc::Colour::BLUE, { 256, 240 }, olc::Colour::RED);
-
draw.StringProp({ 10, 2 }, "olc::PixelGameEngine\nin\nwxWidgets!", olc::Colour::WHITE);
}
@@ -17,6 +16,59 @@ void BallPanel::OnRender()
+
+ExamplePanel2::ExamplePanel2(wxWindow* pParent) : olc::wx::PGE3Panel(pParent)
+{
+
+}
+
+ExamplePanel2::ExamplePanel2(wxWindow* pParent, const olc::vi2d& vFixedSize) : olc::wx::PGE3Panel(pParent, vFixedSize)
+{
+
+}
+
+void ExamplePanel2::OnCreate()
+{
+
+ vPos = { 100,100 };
+ vVel = olc::vf2d(100.0f, 1.0f).cart();
+}
+
+void ExamplePanel2::OnRender()
+{
+ draw.Clear(olc::Colour::VERY_DARK_BLUE);
+ draw.FilledCircle(vPos.round(), 10, olc::Colour::WHITE);
+}
+
+void ExamplePanel2::OnUpdate(const float fElapsedTime)
+{
+ vPos += vVel * fElapsedTime;
+
+ if (vPos.x - 10 <= 0)
+ {
+ vPos.x = 10;
+ vVel.x *= -1;
+ }
+ if (vPos.y - 10 <= 0)
+ {
+ vPos.y = 10;
+ vVel.y *= -1;
+ }
+ if (vPos.x + 10 >= draw.GetTargetSize().x)
+ {
+ vPos.x = draw.GetTargetSize().x - 10;
+ vVel.x *= -1;
+ }
+
+ if (vPos.y + 10 >= draw.GetTargetSize().y)
+ {
+ vPos.y = draw.GetTargetSize().y - 10;
+ vVel.y *= -1;
+ }
+}
+
+
+
cMain::cMain()
: wxFrame(nullptr, wxID_ANY, "olcPGE3 wxWidgets", wxDefaultPosition, wxSize(800, 600), wxDEFAULT_FRAME_STYLE)
{
@@ -24,10 +76,16 @@ cMain::cMain()
wxPanel* pRoot = new wxPanel(this);
wxBoxSizer* pSizer = new wxBoxSizer(wxHORIZONTAL);
- m_pBall1 = new BallPanel(pRoot);
- pSizer->Add(m_pBall1, 1, wxEXPAND | wxALL, 8);
- m_pBall2 = new BallPanel(pRoot);
- pSizer->Add(m_pBall2, 1, wxEXPAND | wxALL, 8);
+ m_pPanel1 = new ExamplePanel1(pRoot);
+ pSizer->Add(m_pPanel1, 1, wxEXPAND | wxALL, 8);
+
+ m_pPanel2 = new ExamplePanel2(pRoot);
+ m_pPanel2->OnCreate();
+ pSizer->Add(m_pPanel2, 1, wxEXPAND | wxALL, 8);
+
+ m_pPanel3 = new ExamplePanel2(pRoot, { 128,128 });
+ m_pPanel3->OnCreate();
+ pSizer->Add(m_pPanel3, 1, wxEXPAND | wxALL, 8);
pRoot->SetSizer(pSizer);
@@ -38,7 +96,14 @@ cMain::cMain()
void cMain::OnTick(wxTimerEvent& event)
{
olc_IgnoreUnused(event);
- //m_pBall->Refresh(false);
- //m_pMouse->Refresh(false);
+ m_pPanel1->OnUpdate(1.0f / 60.0f);
+ m_pPanel1->Refresh(false);
+
+ m_pPanel2->OnUpdate(1.0f / 60.0f);
+ m_pPanel2->Refresh(false);
+
+ m_pPanel3->OnUpdate(1.0f / 60.0f);
+ m_pPanel3->Refresh(false);
}
+
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.h b/dev/msvc/olcPGE3_wxWidgets/cMain.h
index 4b556aab..7a08d595 100644
--- a/dev/msvc/olcPGE3_wxWidgets/cMain.h
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.h
@@ -3,14 +3,29 @@
#define OLC_USE_WXWIDGETS
#include "..\..\..\olcPixelGameEngine3.h"
-class BallPanel : public olc::wx::PGE3Panel
+class ExamplePanel1 : public olc::wx::PGE3Panel
{
public:
- BallPanel(wxWindow* pParent);
+ ExamplePanel1(wxWindow* pParent);
protected:
void OnRender() override;
+};
+
+
+class ExamplePanel2 : public olc::wx::PGE3Panel
+{
+public:
+ ExamplePanel2(wxWindow* pParent);
+ ExamplePanel2(wxWindow* pParent, const olc::vi2d& vFixedSize);
+
+public:
+ void OnUpdate(const float fElapsedTime) override;
+ void OnCreate() override;
+protected:
+ void OnRender() override;
+
private:
olc::vf2d vPos;
olc::vf2d vVel;
@@ -26,8 +41,9 @@ class cMain : public wxFrame
private:
- BallPanel* m_pBall1 = nullptr;
- BallPanel* m_pBall2 = nullptr;
+ ExamplePanel1* m_pPanel1 = nullptr;
+ ExamplePanel2* m_pPanel2 = nullptr;
+ ExamplePanel2* m_pPanel3 = nullptr;
wxTimer m_timer;
};
diff --git a/dev/src/gpu_opengl33.cpp b/dev/src/gpu_opengl33.cpp
index 2c1c197e..5aea8131 100644
--- a/dev/src/gpu_opengl33.cpp
+++ b/dev/src/gpu_opengl33.cpp
@@ -791,6 +791,14 @@ void main()
gl.glDeleteRenderbuffers(1, &rboId);
mapTextureToRenderbuffer.erase(texid);
}
+
+ mapTextureSizes.erase(texid);
+
+ if (nCurrentTextureSource == texid)
+ nCurrentTextureSource = 0;
+
+ if (nCurrentTextureTarget == texid)
+ nCurrentTextureTarget = 0;
return true;
}
diff --git a/dev/src/host_wxwidgets.cpp b/dev/src/host_wxwidgets.cpp
index 0513e218..c2ac7135 100644
--- a/dev/src/host_wxwidgets.cpp
+++ b/dev/src/host_wxwidgets.cpp
@@ -153,13 +153,37 @@ namespace olc::wx
draw.SetGPU(m_pCore->GetRenderer());
// Create the default draw target
+ bFixedSize = false;
m_pCore->CreateImage(imgPrimary, { 256, 240 });
-
- // Call "OnUserCreate()" before any other drawing can occur
+
ResetDrawState();
- OnCreate();
Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
+ Connect(wxEVT_SIZE, wxSizeEventHandler(olc::wx::PGE3Panel::Event_OnResize));
+ }
+
+ PGE3Panel::PGE3Panel(wxWindow* parent, const olc::vi2d& vFixedSize) : wxGLCanvas(parent, -1, nullptr)
+ {
+ if (m_pCore == nullptr)
+ {
+ // Create a static PGE3Core
+ m_pCore = new PGE3Core(this);
+ }
+
+ // Set the context via wxWidgets
+ SetCurrent(*m_pCore->get());
+
+ // Associate this instance of draw with the renderer
+ draw.SetGPU(m_pCore->GetRenderer());
+
+ // Create the default draw target
+ vFixedSizeImage = vFixedSize;
+ bFixedSize = true;
+ m_pCore->CreateImage(imgPrimary, vFixedSize);
+
+ ResetDrawState();
+
+ Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
}
PGE3Panel::~PGE3Panel()
@@ -206,12 +230,30 @@ namespace olc::wx
SwapBuffers();
}
+ void PGE3Panel::Event_OnResize(wxSizeEvent& evt)
+ {
+ if (!bFixedSize)
+ {
+ // Resize Target Image
+ SetCurrent(*m_pCore->get());
+ m_pCore->DestroyImage(imgPrimary);
+ m_pCore->CreateImage(imgPrimary, { evt.GetSize().x, evt.GetSize().y });
+ }
+
+ Refresh(true);
+ evt.Skip(true);
+ }
void PGE3Panel::OnCreate()
{
// Overriden by user
}
+ void PGE3Panel::OnUpdate(const float fElapsedTime)
+ {
+ // Overriden by user
+ }
+
void PGE3Panel::OnRender()
{
// Overriden by user
diff --git a/dev/src/host_wxwidgets.h b/dev/src/host_wxwidgets.h
index 75fcaa83..eb3fdf3c 100644
--- a/dev/src/host_wxwidgets.h
+++ b/dev/src/host_wxwidgets.h
@@ -65,6 +65,7 @@ namespace olc::wx
{
public:
PGE3Panel(wxWindow* parent);
+ PGE3Panel(wxWindow* parent, const olc::vi2d& vFixedSize);
virtual ~PGE3Panel();
void ResetDrawState();
@@ -77,14 +78,21 @@ namespace olc::wx
static olc::wx::PGE3Core* m_pCore;
olc::Image imgPrimary;
+ bool bFixedSize = false;
+ olc::vi2d vFixedSizeImage;
+
private: // wxWidgets Overrides
void Event_OnPaint(wxPaintEvent& evt);
+ void Event_OnResize(wxSizeEvent& evt);
protected: // User Overrides
+ virtual void OnRender(); // Called via wxWidgets ->Refresh()
+
+ public:
virtual void OnCreate();
- virtual void OnRender();
+ virtual void OnUpdate(const float fElapsedTime);
};
}
//! END DECLARATION
diff --git a/dev/src/image.cpp b/dev/src/image.cpp
index beadcc5e..cdaffcb0 100644
--- a/dev/src/image.cpp
+++ b/dev/src/image.cpp
@@ -16,6 +16,7 @@ namespace olc
dimensions = size;
config = cfg;
pixels.resize(dimensions.area(), olc::Colour::TANGERINE);
+ BindCPU();
return true;
}
diff --git a/olcPixelGameEngine3.h b/olcPixelGameEngine3.h
index 6dace0ec..30e83895 100644
--- a/olcPixelGameEngine3.h
+++ b/olcPixelGameEngine3.h
@@ -6677,6 +6677,7 @@ namespace olc::wx
{
public:
PGE3Panel(wxWindow* parent);
+ PGE3Panel(wxWindow* parent, const olc::vi2d& vFixedSize);
virtual ~PGE3Panel();
void ResetDrawState();
@@ -6689,14 +6690,21 @@ namespace olc::wx
static olc::wx::PGE3Core* m_pCore;
olc::Image imgPrimary;
+ bool bFixedSize = false;
+ olc::vi2d vFixedSizeImage;
+
private: // wxWidgets Overrides
void Event_OnPaint(wxPaintEvent& evt);
+ void Event_OnResize(wxSizeEvent& evt);
protected: // User Overrides
+ virtual void OnRender(); // Called via wxWidgets ->Refresh()
+
+ public:
virtual void OnCreate();
- virtual void OnRender();
+ virtual void OnUpdate(const float fElapsedTime);
};
}
#endif
@@ -15533,13 +15541,37 @@ namespace olc::wx
draw.SetGPU(m_pCore->GetRenderer());
// Create the default draw target
+ bFixedSize = false;
m_pCore->CreateImage(imgPrimary, { 256, 240 });
-
- // Call "OnUserCreate()" before any other drawing can occur
+
ResetDrawState();
- OnCreate();
Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
+ Connect(wxEVT_SIZE, wxSizeEventHandler(olc::wx::PGE3Panel::Event_OnResize));
+ }
+
+ PGE3Panel::PGE3Panel(wxWindow* parent, const olc::vi2d& vFixedSize) : wxGLCanvas(parent, -1, nullptr)
+ {
+ if (m_pCore == nullptr)
+ {
+ // Create a static PGE3Core
+ m_pCore = new PGE3Core(this);
+ }
+
+ // Set the context via wxWidgets
+ SetCurrent(*m_pCore->get());
+
+ // Associate this instance of draw with the renderer
+ draw.SetGPU(m_pCore->GetRenderer());
+
+ // Create the default draw target
+ vFixedSizeImage = vFixedSize;
+ bFixedSize = true;
+ m_pCore->CreateImage(imgPrimary, vFixedSize);
+
+ ResetDrawState();
+
+ Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
}
PGE3Panel::~PGE3Panel()
@@ -15586,12 +15618,30 @@ namespace olc::wx
SwapBuffers();
}
+ void PGE3Panel::Event_OnResize(wxSizeEvent& evt)
+ {
+ if (!bFixedSize)
+ {
+ // Resize Target Image
+ SetCurrent(*m_pCore->get());
+ m_pCore->DestroyImage(imgPrimary);
+ m_pCore->CreateImage(imgPrimary, { evt.GetSize().x, evt.GetSize().y });
+ }
+
+ Refresh(true);
+ evt.Skip(true);
+ }
void PGE3Panel::OnCreate()
{
// Overriden by user
}
+ void PGE3Panel::OnUpdate(const float fElapsedTime)
+ {
+ // Overriden by user
+ }
+
void PGE3Panel::OnRender()
{
// Overriden by user
@@ -17140,6 +17190,14 @@ void main()
gl.glDeleteRenderbuffers(1, &rboId);
mapTextureToRenderbuffer.erase(texid);
}
+
+ mapTextureSizes.erase(texid);
+
+ if (nCurrentTextureSource == texid)
+ nCurrentTextureSource = 0;
+
+ if (nCurrentTextureTarget == texid)
+ nCurrentTextureTarget = 0;
return true;
}
@@ -20224,6 +20282,7 @@ namespace olc
dimensions = size;
config = cfg;
pixels.resize(dimensions.area(), olc::Colour::TANGERINE);
+ BindCPU();
return true;
}
From 611612a26382678fa82103d115efc197ab5fb933 Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Sun, 6 Sep 2026 22:05:18 +0100
Subject: [PATCH 6/9] [wxWidgets] Added mouse functionality to PGE3Panel
---
dev/msvc/olcPGE3_wxWidgets/cMain.cpp | 26 ++++++-
dev/msvc/olcPGE3_wxWidgets/cMain.h | 8 ++
dev/src/host_wxwidgets.cpp | 83 ++++++++++++++++++--
dev/src/host_wxwidgets.h | 26 ++++++-
olcPixelGameEngine3.h | 109 ++++++++++++++++++++++++---
5 files changed, 228 insertions(+), 24 deletions(-)
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.cpp b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
index fd0592e0..17accab3 100644
--- a/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.cpp
@@ -3,15 +3,28 @@
ExamplePanel1::ExamplePanel1(wxWindow* pParent) : olc::wx::PGE3Panel(pParent)
{
-
+ vLineStart = { 0,0 };
+ vLineStop = { 256, 240 };
}
void ExamplePanel1::OnRender()
{
- draw.Line({ 0,0 }, olc::Colour::BLUE, { 256, 240 }, olc::Colour::RED);
+ draw.Line(vLineStart, olc::Colour::BLUE, vLineStop, olc::Colour::RED);
draw.StringProp({ 10, 2 }, "olc::PixelGameEngine\nin\nwxWidgets!", olc::Colour::WHITE);
}
+void ExamplePanel1::OnMouseLeftDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl)
+{
+ vLineStart = vWorldPos;
+ Refresh();
+}
+
+void ExamplePanel1::OnMouseRightDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl)
+{
+ vLineStop = vWorldPos;
+ Refresh();
+}
+
@@ -40,6 +53,11 @@ void ExamplePanel2::OnRender()
draw.FilledCircle(vPos.round(), 10, olc::Colour::WHITE);
}
+void ExamplePanel2::OnMouseMiddleDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl)
+{
+ vPos = vWorldPos;
+}
+
void ExamplePanel2::OnUpdate(const float fElapsedTime)
{
vPos += vVel * fElapsedTime;
@@ -96,8 +114,8 @@ cMain::cMain()
void cMain::OnTick(wxTimerEvent& event)
{
olc_IgnoreUnused(event);
- m_pPanel1->OnUpdate(1.0f / 60.0f);
- m_pPanel1->Refresh(false);
+ //m_pPanel1->OnUpdate(1.0f / 60.0f);
+ //m_pPanel1->Refresh(false);
m_pPanel2->OnUpdate(1.0f / 60.0f);
m_pPanel2->Refresh(false);
diff --git a/dev/msvc/olcPGE3_wxWidgets/cMain.h b/dev/msvc/olcPGE3_wxWidgets/cMain.h
index 7a08d595..263d9773 100644
--- a/dev/msvc/olcPGE3_wxWidgets/cMain.h
+++ b/dev/msvc/olcPGE3_wxWidgets/cMain.h
@@ -11,6 +11,12 @@ class ExamplePanel1 : public olc::wx::PGE3Panel
protected:
void OnRender() override;
+ void OnMouseLeftDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) override;
+ void OnMouseRightDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) override;
+
+private:
+ olc::vf2d vLineStart;
+ olc::vf2d vLineStop;
};
@@ -25,6 +31,8 @@ class ExamplePanel2 : public olc::wx::PGE3Panel
void OnCreate() override;
protected:
void OnRender() override;
+ void OnMouseMiddleDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) override;
+
private:
olc::vf2d vPos;
diff --git a/dev/src/host_wxwidgets.cpp b/dev/src/host_wxwidgets.cpp
index c2ac7135..65854481 100644
--- a/dev/src/host_wxwidgets.cpp
+++ b/dev/src/host_wxwidgets.cpp
@@ -160,6 +160,14 @@ namespace olc::wx
Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
Connect(wxEVT_SIZE, wxSizeEventHandler(olc::wx::PGE3Panel::Event_OnResize));
+ Connect(wxEVT_MOTION, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMove));
+ Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleDown));
+ Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleUp));
+ Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseWheel));
+ Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftDown));
+ Connect(wxEVT_LEFT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftUp));
+ Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightDown));
+ Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightUp));
}
PGE3Panel::PGE3Panel(wxWindow* parent, const olc::vi2d& vFixedSize) : wxGLCanvas(parent, -1, nullptr)
@@ -184,11 +192,28 @@ namespace olc::wx
ResetDrawState();
Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
+ Connect(wxEVT_MOTION, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMove));
+ Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleDown));
+ Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleUp));
+ Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseWheel));
+ Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftDown));
+ Connect(wxEVT_LEFT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftUp));
+ Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightDown));
+ Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightUp));
}
PGE3Panel::~PGE3Panel()
{
-
+ Disconnect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
+ Disconnect(wxEVT_SIZE, wxSizeEventHandler(olc::wx::PGE3Panel::Event_OnResize));
+ Disconnect(wxEVT_MOTION, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMove));
+ Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleDown));
+ Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleUp));
+ Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseWheel));
+ Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftDown));
+ Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftUp));
+ Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightDown));
+ Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightUp));
}
void PGE3Panel::ResetDrawState()
@@ -202,6 +227,8 @@ namespace olc::wx
draw.SetCullMode(olc::CullMode::None);
}
+
+
void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
{
// Configure WX to render this window
@@ -244,19 +271,61 @@ namespace olc::wx
evt.Skip(true);
}
- void PGE3Panel::OnCreate()
+ olc::vf2d PGE3Panel::ScaleMouse(wxMouseEvent& evt)
+ {
+ olc::vf2d vScreenPos = olc::vf2d(float(evt.GetX()), float(evt.GetY()));
+
+ if (bFixedSize)
+ vScreenPos = vScreenPos / olc::vf2d(GetSize().x, GetSize().y) * vFixedSizeImage;
+
+ return vScreenPos;
+ }
+
+ void PGE3Panel::Event_OnMouseLeftUp(wxMouseEvent& evt)
+ {
+ OnMouseLeftUp(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseLeftDown(wxMouseEvent& evt)
+ {
+ OnMouseLeftDown(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseRightUp(wxMouseEvent& evt)
+ {
+ OnMouseRightUp(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseRightDown(wxMouseEvent& evt)
+ {
+ OnMouseRightDown(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseMiddleUp(wxMouseEvent& evt)
+ {
+ OnMouseMiddleUp(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseMiddleDown(wxMouseEvent& evt)
{
- // Overriden by user
+ OnMouseMiddleDown(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
}
- void PGE3Panel::OnUpdate(const float fElapsedTime)
+ void PGE3Panel::Event_OnMouseMove(wxMouseEvent& evt)
{
- // Overriden by user
+ OnMouseMove(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
}
- void PGE3Panel::OnRender()
+ void PGE3Panel::Event_OnMouseWheel(wxMouseEvent& evt)
{
- // Overriden by user
+ evt.Skip();
}
}
diff --git a/dev/src/host_wxwidgets.h b/dev/src/host_wxwidgets.h
index eb3fdf3c..16490ca0 100644
--- a/dev/src/host_wxwidgets.h
+++ b/dev/src/host_wxwidgets.h
@@ -81,18 +81,38 @@ namespace olc::wx
bool bFixedSize = false;
olc::vi2d vFixedSizeImage;
+ olc::vf2d ScaleMouse(wxMouseEvent& evt);
+
private: // wxWidgets Overrides
void Event_OnPaint(wxPaintEvent& evt);
void Event_OnResize(wxSizeEvent& evt);
+ void Event_OnMouseLeftUp(wxMouseEvent& evt);
+ void Event_OnMouseLeftDown(wxMouseEvent& evt);
+ void Event_OnMouseRightUp(wxMouseEvent& evt);
+ void Event_OnMouseRightDown(wxMouseEvent& evt);
+ void Event_OnMouseMiddleUp(wxMouseEvent& evt);
+ void Event_OnMouseMiddleDown(wxMouseEvent& evt);
+ void Event_OnMouseMove(wxMouseEvent& evt);
+ void Event_OnMouseWheel(wxMouseEvent& evt);
protected: // User Overrides
- virtual void OnRender(); // Called via wxWidgets ->Refresh()
+ virtual void OnRender() {}; // Called via wxWidgets ->Refresh()
public:
- virtual void OnCreate();
- virtual void OnUpdate(const float fElapsedTime);
+ virtual void OnCreate() {};
+ virtual void OnUpdate(const float fElapsedTime) {};
+
+ // Mouse Handlers
+ virtual void OnMouseMiddleUp(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseMiddleDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseLeftUp(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseLeftDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseRightUp(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseRightDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseMove(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseWheel(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
};
}
//! END DECLARATION
diff --git a/olcPixelGameEngine3.h b/olcPixelGameEngine3.h
index 30e83895..583f9e5b 100644
--- a/olcPixelGameEngine3.h
+++ b/olcPixelGameEngine3.h
@@ -6693,18 +6693,38 @@ namespace olc::wx
bool bFixedSize = false;
olc::vi2d vFixedSizeImage;
+ olc::vf2d ScaleMouse(wxMouseEvent& evt);
+
private: // wxWidgets Overrides
void Event_OnPaint(wxPaintEvent& evt);
void Event_OnResize(wxSizeEvent& evt);
+ void Event_OnMouseLeftUp(wxMouseEvent& evt);
+ void Event_OnMouseLeftDown(wxMouseEvent& evt);
+ void Event_OnMouseRightUp(wxMouseEvent& evt);
+ void Event_OnMouseRightDown(wxMouseEvent& evt);
+ void Event_OnMouseMiddleUp(wxMouseEvent& evt);
+ void Event_OnMouseMiddleDown(wxMouseEvent& evt);
+ void Event_OnMouseMove(wxMouseEvent& evt);
+ void Event_OnMouseWheel(wxMouseEvent& evt);
protected: // User Overrides
- virtual void OnRender(); // Called via wxWidgets ->Refresh()
+ virtual void OnRender() {}; // Called via wxWidgets ->Refresh()
public:
- virtual void OnCreate();
- virtual void OnUpdate(const float fElapsedTime);
+ virtual void OnCreate() {};
+ virtual void OnUpdate(const float fElapsedTime) {};
+
+ // Mouse Handlers
+ virtual void OnMouseMiddleUp(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseMiddleDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseLeftUp(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseLeftDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseRightUp(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseRightDown(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseMove(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
+ virtual void OnMouseWheel(const olc::vf2d& vWorldPos, const bool bShift, const bool bControl) {};
};
}
#endif
@@ -15548,6 +15568,14 @@ namespace olc::wx
Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
Connect(wxEVT_SIZE, wxSizeEventHandler(olc::wx::PGE3Panel::Event_OnResize));
+ Connect(wxEVT_MOTION, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMove));
+ Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleDown));
+ Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleUp));
+ Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseWheel));
+ Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftDown));
+ Connect(wxEVT_LEFT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftUp));
+ Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightDown));
+ Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightUp));
}
PGE3Panel::PGE3Panel(wxWindow* parent, const olc::vi2d& vFixedSize) : wxGLCanvas(parent, -1, nullptr)
@@ -15572,11 +15600,28 @@ namespace olc::wx
ResetDrawState();
Connect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
+ Connect(wxEVT_MOTION, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMove));
+ Connect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleDown));
+ Connect(wxEVT_MIDDLE_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleUp));
+ Connect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseWheel));
+ Connect(wxEVT_LEFT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftDown));
+ Connect(wxEVT_LEFT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftUp));
+ Connect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightDown));
+ Connect(wxEVT_RIGHT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightUp));
}
PGE3Panel::~PGE3Panel()
{
-
+ Disconnect(wxEVT_PAINT, wxPaintEventHandler(olc::wx::PGE3Panel::Event_OnPaint));
+ Disconnect(wxEVT_SIZE, wxSizeEventHandler(olc::wx::PGE3Panel::Event_OnResize));
+ Disconnect(wxEVT_MOTION, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMove));
+ Disconnect(wxEVT_MIDDLE_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleDown));
+ Disconnect(wxEVT_MIDDLE_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseMiddleUp));
+ Disconnect(wxEVT_MOUSEWHEEL, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseWheel));
+ Disconnect(wxEVT_LEFT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftDown));
+ Disconnect(wxEVT_LEFT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseLeftUp));
+ Disconnect(wxEVT_RIGHT_DOWN, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightDown));
+ Disconnect(wxEVT_RIGHT_UP, wxMouseEventHandler(olc::wx::PGE3Panel::Event_OnMouseRightUp));
}
void PGE3Panel::ResetDrawState()
@@ -15590,6 +15635,8 @@ namespace olc::wx
draw.SetCullMode(olc::CullMode::None);
}
+
+
void PGE3Panel::Event_OnPaint(wxPaintEvent& evt)
{
// Configure WX to render this window
@@ -15632,19 +15679,61 @@ namespace olc::wx
evt.Skip(true);
}
- void PGE3Panel::OnCreate()
+ olc::vf2d PGE3Panel::ScaleMouse(wxMouseEvent& evt)
+ {
+ olc::vf2d vScreenPos = olc::vf2d(float(evt.GetX()), float(evt.GetY()));
+
+ if (bFixedSize)
+ vScreenPos = vScreenPos / olc::vf2d(GetSize().x, GetSize().y) * vFixedSizeImage;
+
+ return vScreenPos;
+ }
+
+ void PGE3Panel::Event_OnMouseLeftUp(wxMouseEvent& evt)
+ {
+ OnMouseLeftUp(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseLeftDown(wxMouseEvent& evt)
+ {
+ OnMouseLeftDown(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseRightUp(wxMouseEvent& evt)
+ {
+ OnMouseRightUp(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseRightDown(wxMouseEvent& evt)
+ {
+ OnMouseRightDown(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseMiddleUp(wxMouseEvent& evt)
+ {
+ OnMouseMiddleUp(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
+ }
+
+ void PGE3Panel::Event_OnMouseMiddleDown(wxMouseEvent& evt)
{
- // Overriden by user
+ OnMouseMiddleDown(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
}
- void PGE3Panel::OnUpdate(const float fElapsedTime)
+ void PGE3Panel::Event_OnMouseMove(wxMouseEvent& evt)
{
- // Overriden by user
+ OnMouseMove(draw.ScreenToWorld(ScaleMouse(evt)), evt.ShiftDown(), evt.ControlDown());
+ evt.Skip();
}
- void PGE3Panel::OnRender()
+ void PGE3Panel::Event_OnMouseWheel(wxMouseEvent& evt)
{
- // Overriden by user
+ evt.Skip();
}
}
From c3051af82baecfd2879255a03573f523eb993f2d Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Mon, 7 Sep 2026 20:38:13 +0100
Subject: [PATCH 7/9] some olc::Image tweaks
---
dev/src/image.cpp | 12 +++++-------
dev/src/image.h | 7 +++++++
olcPixelGameEngine3.h | 19 ++++++++++++-------
3 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/dev/src/image.cpp b/dev/src/image.cpp
index cdaffcb0..4c480376 100644
--- a/dev/src/image.cpp
+++ b/dev/src/image.cpp
@@ -3,13 +3,6 @@
//! START IMPLEMENTATION
namespace olc
{
- /*Image::Image(const olc::vi2d& size, const ImageConfig& cfg)
- {
- }
-
- Image::~Image()
- {
- }*/
bool Image::CreateNoGPU(const olc::vi2d& size, const ImageConfig& cfg)
{
@@ -79,6 +72,11 @@ namespace olc
return onCPU;
}
+ olc::ImageRegion Image::all()
+ {
+ return olc::ImageRegion(*this);
+ }
+
olc::ImageRegion Image::region(const olc::vf2d pos, const olc::vf2d& size)
{
return region(pos, { pos.x + size.x, pos.y }, { pos.x, pos.y + size.y }, pos + size);
diff --git a/dev/src/image.h b/dev/src/image.h
index cab7215b..6cd93c2a 100644
--- a/dev/src/image.h
+++ b/dev/src/image.h
@@ -45,6 +45,12 @@ namespace olc
Image() = default;
virtual ~Image() = default;
+ // Prevent copying & accidental duplication
+ Image(const Image&) = delete;
+ Image& operator=(const Image&) = delete;
+ Image(Image&&) = default;
+ Image& operator=(Image&&) = default;
+
public:
// Creates nothing but an array of pixels in system memory. Normal users
// should never need to call this method. If you want to construct an
@@ -77,6 +83,7 @@ namespace olc
bool BoundToCPU() const;
public:
+ olc::ImageRegion all();
olc::ImageRegion region(const olc::vf2d pos, const olc::vf2d& size);
olc::ImageRegion region(const olc::vf2d& vTL, const olc::vf2d& vTR, const olc::vf2d& vBL, const olc::vf2d& vBR);
olc::ImageRegion flipV();
diff --git a/olcPixelGameEngine3.h b/olcPixelGameEngine3.h
index 583f9e5b..62cfef42 100644
--- a/olcPixelGameEngine3.h
+++ b/olcPixelGameEngine3.h
@@ -2270,6 +2270,12 @@ namespace olc
Image() = default;
virtual ~Image() = default;
+ // Prevent copying & accidental duplication
+ Image(const Image&) = delete;
+ Image& operator=(const Image&) = delete;
+ Image(Image&&) = default;
+ Image& operator=(Image&&) = default;
+
public:
// Creates nothing but an array of pixels in system memory. Normal users
// should never need to call this method. If you want to construct an
@@ -2302,6 +2308,7 @@ namespace olc
bool BoundToCPU() const;
public:
+ olc::ImageRegion all();
olc::ImageRegion region(const olc::vf2d pos, const olc::vf2d& size);
olc::ImageRegion region(const olc::vf2d& vTL, const olc::vf2d& vTR, const olc::vf2d& vBL, const olc::vf2d& vBR);
olc::ImageRegion flipV();
@@ -20358,13 +20365,6 @@ namespace olc
#if defined(OLC_PGE3_APPLICATION) && !defined(PGE_IMAGE_IMPLEMENTED)
namespace olc
{
- /*Image::Image(const olc::vi2d& size, const ImageConfig& cfg)
- {
- }
-
- Image::~Image()
- {
- }*/
bool Image::CreateNoGPU(const olc::vi2d& size, const ImageConfig& cfg)
{
@@ -20434,6 +20434,11 @@ namespace olc
return onCPU;
}
+ olc::ImageRegion Image::all()
+ {
+ return olc::ImageRegion(*this);
+ }
+
olc::ImageRegion Image::region(const olc::vf2d pos, const olc::vf2d& size)
{
return region(pos, { pos.x + size.x, pos.y }, { pos.x, pos.y + size.y }, pos + size);
From 843d069e40119b97a69ce5c00e49546b2923d7dc Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Sun, 13 Sep 2026 10:23:25 +0100
Subject: [PATCH 8/9] Added folder structure for extensions
---
dev/msvc/olcPGE3.vcxproj | 4 ++++
dev/msvc/olcPGE3.vcxproj.filters | 21 +++++++++++++++++++++
dev/src/sh_template.h | 5 +++++
extensions/README.md | 14 ++++++++++++++
extensions/miniaudio/README.md | 0
extensions/splashscreen/README.md | 0
utilities/README.md | 6 ++++++
7 files changed, 50 insertions(+)
create mode 100644 extensions/README.md
create mode 100644 extensions/miniaudio/README.md
create mode 100644 extensions/splashscreen/README.md
create mode 100644 utilities/README.md
diff --git a/dev/msvc/olcPGE3.vcxproj b/dev/msvc/olcPGE3.vcxproj
index e3e0dd0d..fcff341f 100644
--- a/dev/msvc/olcPGE3.vcxproj
+++ b/dev/msvc/olcPGE3.vcxproj
@@ -365,8 +365,12 @@
+
+
+
+
diff --git a/dev/msvc/olcPGE3.vcxproj.filters b/dev/msvc/olcPGE3.vcxproj.filters
index 254b087f..03573c37 100644
--- a/dev/msvc/olcPGE3.vcxproj.filters
+++ b/dev/msvc/olcPGE3.vcxproj.filters
@@ -52,6 +52,15 @@
{eb0bb606-e8b0-419b-b621-b61633c50add}
+
+ {12be6a62-5486-49fa-be63-b305888e2aca}
+
+
+ {6b6f0117-0e7e-4dc8-ad83-96525e679ff3}
+
+
+ {799e6b1b-18e3-48e9-9181-a7e139ebd5da}
+
@@ -277,6 +286,18 @@
Extras
+
+ Extensions
+
+
+ Extensions\MiniAudio
+
+
+ Extensions\SplashScreen
+
+
+ Utilities
+
diff --git a/dev/src/sh_template.h b/dev/src/sh_template.h
index 106bd1ff..c17379f5 100644
--- a/dev/src/sh_template.h
+++ b/dev/src/sh_template.h
@@ -93,6 +93,11 @@
"You know you don't have to use AI if you like coding right?" - javidx9
+ Identified Uses of AI
+ ~~~~~~~~~~~~~~~~~~~~~
+ 1) NxN Matrix Inversion - After 4 attempts at getting the sequencing right following
+ the wikipedia articles (VS Copilot)
+
Primary Contributors
~~~~~~~~~~~~~~~~~~~~
@javidx9 (aka David Barr, OneLoneCoder)
diff --git a/extensions/README.md b/extensions/README.md
new file mode 100644
index 00000000..6ae8e9f9
--- /dev/null
+++ b/extensions/README.md
@@ -0,0 +1,14 @@
+# Extensions
+In PGE3, an extension allows the easy addition of automated functionality or wrapping of 3rd party libraries. Extensions **ADD** features by hooking into the main system loop and being called by PGE3 at various points.
+
+Extensions live in the `olc::ext` namespace.
+
+For example, the SplashScreen extension simply requires the presence of an `olc::ext::SplashScreen` object, and PGE3 will take care of the sequencing and rendering, removing that burden from the user. More complicated extensions such as audio may comprise several files or indeed require the installation of additional libraries.
+
+Extension code should exist in a self-contained and self-named folder, along with a `README.md` detailing their use and installation requirements. No 3rd party code should be stored within the folder, and we expect the README to sufficiently inform the user how to acquire, configure and use any 3rd part libraries.
+
+Support for extensions is not guaranteed, as extension maintainers come and go, 3rd party libraries change over time and the requirements for the extension may disappear.
+
+If you have an extension idea or contribution, then please reach out via our Discord server.
+
+`TODO: Basic Extension Writing Guide`
\ No newline at end of file
diff --git a/extensions/miniaudio/README.md b/extensions/miniaudio/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/extensions/splashscreen/README.md b/extensions/splashscreen/README.md
new file mode 100644
index 00000000..e69de29b
diff --git a/utilities/README.md b/utilities/README.md
new file mode 100644
index 00000000..13def36b
--- /dev/null
+++ b/utilities/README.md
@@ -0,0 +1,6 @@
+# Utilities
+A Utility in PGE3 is a single header file, assistive set of data structures, classes and algorithms intended to simplify common procedures. For example, the Camera2D utility will transform a game world to the screen in various ways, and the QuadTree can partition 2D space for efficient search or rendering.
+
+The core PGE3 doesn't rely upon utilities meaning they are entirely optional, however utilities and extensions may rely upon other utilities.
+
+Documentation for a utility if not obvious, should be included within the utility file itself.
\ No newline at end of file
From 355f64fce48af0338c3eeac0976189dd7b34fd78 Mon Sep 17 00:00:00 2001
From: Javidx9 <25419386+OneLoneCoder@users.noreply.github.com>
Date: Sun, 13 Sep 2026 10:25:37 +0100
Subject: [PATCH 9/9] sh again...
---
olcPixelGameEngine3.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/olcPixelGameEngine3.h b/olcPixelGameEngine3.h
index 62cfef42..c2390020 100644
--- a/olcPixelGameEngine3.h
+++ b/olcPixelGameEngine3.h
@@ -93,6 +93,11 @@
"You know you don't have to use AI if you like coding right?" - javidx9
+ Identified Uses of AI
+ ~~~~~~~~~~~~~~~~~~~~~
+ 1) NxN Matrix Inversion - After 4 attempts at getting the sequencing right following
+ the wikipedia articles (VS Copilot)
+
Primary Contributors
~~~~~~~~~~~~~~~~~~~~
@javidx9 (aka David Barr, OneLoneCoder)