From 9b34a4de685ad50703f2082952e7070753bef67a Mon Sep 17 00:00:00 2001 From: drug007 Date: Sun, 21 Jan 2024 04:02:45 +0300 Subject: [PATCH] Add support for 4K --- examples/sdl/source/app.d | 32 ++++++++++++++++++++++++++++---- source/nanogui/glcanvas.d | 5 +++-- source/nanogui/screen.d | 11 ++++++++--- source/nanogui/sdlapp.d | 4 ++-- source/nanogui/sdlbackend.d | 10 +++++----- 5 files changed, 46 insertions(+), 16 deletions(-) diff --git a/examples/sdl/source/app.d b/examples/sdl/source/app.d index d7a0d221..c7de993d 100644 --- a/examples/sdl/source/app.d +++ b/examples/sdl/source/app.d @@ -1,6 +1,7 @@ module examples.sdl; import std.datetime : Clock; +import std.getopt : defaultGetoptPrinter, getopt; import arsd.nanovega; import nanogui.sdlbackend : SdlBackend; import nanogui.widget : Widget; @@ -179,9 +180,9 @@ class MyGui : SdlBackend Label lblCpuUsage; ProcessCPUWatcher cpuWatcher; - this(int w, int h, string title) + this(int w, int h, string title, int scale) { - super(w, h, title); + super(w, h, title, scale); } override void onVisibleForTheFirstTime() @@ -551,8 +552,29 @@ union Payload } alias Item = TaggedAlgebraic!Payload; -void main () { - auto gui = new MyGui(1000, 800, "Nanogui using SDL2 backend"); +int main (string[] args) +{ + int scale = 1; + + auto helpInformation = getopt( + args, + "scale", "Scale, 2 for 4K monitors and 1 for the rest", &scale, + ); + + if (helpInformation.helpWanted) + { + defaultGetoptPrinter("Usage:", helpInformation.options); + return 0; + } + + if (scale != 1 && scale != 2) + { + import std; + stderr.writeln("Scale can be 1 or 2 only"); + return 1; + } + + auto gui = new MyGui(1000, 800, "Nanogui using SDL2 backend", scale); gui.onBeforeLoopStart = () { import std.datetime : SysTime, seconds, Clock; static SysTime prevStdTime; @@ -566,4 +588,6 @@ void main () { } }; gui.run(); + + return 0; } diff --git a/source/nanogui/glcanvas.d b/source/nanogui/glcanvas.d index 8f154a24..ad10d509 100644 --- a/source/nanogui/glcanvas.d +++ b/source/nanogui/glcanvas.d @@ -86,13 +86,14 @@ public: if (mDrawBorder) drawWidgetBorder(ctx); + const scale = screen.scale; // TODO PERFORMANCE it can be expensive operation auto mImage = glCreateImageFromOpenGLTexture(ctx, mColorBuf.handle, width, height, NVGImageFlag.NoDelete); assert(mImage.valid); auto mPaint = ctx.imagePattern( mPos.x + 1, mPos.y + 1.0f, - mSize.x - 2, - mSize.y - 2, + mSize.x/scale - 2, + mSize.y/scale - 2, 0, mImage); diff --git a/source/nanogui/screen.d b/source/nanogui/screen.d index 90d925f4..9bc13ee2 100644 --- a/source/nanogui/screen.d +++ b/source/nanogui/screen.d @@ -14,7 +14,7 @@ class Screen : Widget { import nanogui.window : Window; - this(int w, int h, long timestamp) + this(int w, int h, long timestamp, int scale) { super(null); size = vec2i(w, h); @@ -23,6 +23,7 @@ class Screen : Widget mCursor = Cursor.Arrow; mPixelRatio = 1.0; mClearEnabled = true; + mScale = scale; } auto currTime() const { return mTimestamp; } @@ -38,6 +39,8 @@ class Screen : Widget } } + auto scale() const { return mScale; } + auto lastInteraction() { return mLastInteraction; } override void draw(ref NanoContext ctx) @@ -72,11 +75,11 @@ class Screen : Widget // draw the rest if (mClearEnabled) { - glViewport(0, 0, size.x, size.y); + glViewport(0, 0, size.x*mScale, size.y*mScale); glClearColor(0., 0., 0., 0); glClear(glNVGClearFlags); // use NanoVega API to get flags for OpenGL call } - ctx.beginFrame(size.x, size.y); // begin rendering + ctx.beginFrame(size.x, size.y, mScale); // begin rendering scope(exit) { if (ctx.inFrame) @@ -450,4 +453,6 @@ protected: void delegate(Vector2i) mResizeCallback; Array!GLCanvas mGLCanvases; bool mClearEnabled; + /// Integer scale for 4K support + int mScale; } diff --git a/source/nanogui/sdlapp.d b/source/nanogui/sdlapp.d index 7f46156b..b7ed2e82 100644 --- a/source/nanogui/sdlapp.d +++ b/source/nanogui/sdlapp.d @@ -12,7 +12,7 @@ class SdlApp { alias Event = SDL_Event; - this(int w, int h, string title) + this(int w, int h, string title, int scale = 1) { /* Avoid locale-related number parsing issues */ version(Windows) {} @@ -66,7 +66,7 @@ class SdlApp // create an OpenGL-enabled SDL window window = new SDL2Window(_sdl2, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, - width, height, + width * scale, height * scale, SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN ); window.setTitle(title); diff --git a/source/nanogui/sdlbackend.d b/source/nanogui/sdlbackend.d index 4e09fdd1..daaa196d 100644 --- a/source/nanogui/sdlbackend.d +++ b/source/nanogui/sdlbackend.d @@ -16,9 +16,9 @@ import nanogui.sdlapp : SdlApp; class SdlBackend : Screen { - this(int w, int h, string title) + this(int w, int h, string title, int scale) { - _sdlApp = new SdlApp(w, h, title); + _sdlApp = new SdlApp(w, h, title, scale); _sdlApp.onBeforeLoopStart = () { @@ -77,8 +77,8 @@ class SdlBackend : Screen _sdlApp.invalidate; - ctx.mouse.x = event.motion.x; - ctx.mouse.y = event.motion.y; + ctx.mouse.x = event.motion.x/scale; + ctx.mouse.y = event.motion.y/scale; if (event.motion.state & SDL_BUTTON_LMASK) btn = MouseButton.Left; @@ -168,7 +168,7 @@ class SdlBackend : Screen mCursorSet[Cursor.HResize] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZEWE); mCursorSet[Cursor.VResize] = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_SIZENS); - super(w, h, Clock.currTime.stdTime); + super(w, h, Clock.currTime.stdTime, scale); theme = new Theme(ctx); }