Skip to content

Commit 3d06617

Browse files
committed
fix(render): make canvas/UI DPI-aware
1 parent cf0d37f commit 3d06617

File tree

6 files changed

+48
-31
lines changed

6 files changed

+48
-31
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ Utilities:
6161
+ [ ] Video recording
6262
+ [ ] Custom uniforms
6363
+ [ ] Custom meshes
64+
+ [ ] Anti aliasing
6465

6566
Contributions are welcome!
6667

shadertoy/Backend.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,7 @@ class Pipeline {
104104
virtual std::vector<FrameBuffer*> createCubeMapFrameBuffer() = 0;
105105
virtual void addPass(const std::string& src, NodeType type, std::vector<DoubleBufferedFB> target,
106106
std::vector<Channel> channels) = 0;
107-
virtual void render(ImVec2 frameBufferSize, ImVec2 clipMin, ImVec2 clipMax, ImVec2 base, ImVec2 size,
108-
const ShaderToyUniform& uniform) = 0;
107+
virtual void render(ImVec2 frameBufferSize, ImVec2 clipMin, ImVec2 clipMax, ImVec2 size, const ShaderToyUniform& uniform) = 0;
109108
virtual TextureId createDynamicTexture(uint32_t width, uint32_t height, std::function<void(uint32_t*)> update) = 0;
110109
};
111110

shadertoy/NodeEditor/PipelineEditor.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "shadertoy/SuppressWarningPush.hpp"
2424

2525
#include <fmt/format.h>
26+
#include <hello_imgui/dpi_aware.h>
2627
#include <hello_imgui/hello_imgui.h>
2728
#include <hello_imgui/image_from_asset.h>
2829
#include <httplib.h>
@@ -32,6 +33,8 @@
3233
#include <nlohmann/json.hpp>
3334
#include <stb_image.h>
3435

36+
using HelloImGui::EmToVec2;
37+
3538
#include "shadertoy/SuppressWarningPop.hpp"
3639

3740
SHADERTOY_NAMESPACE_BEGIN
@@ -266,7 +269,7 @@ static void drawPinIcon(const EditorPin& pin, const bool connected, const int al
266269
break;
267270
}
268271

269-
ax::Widgets::icon(ImVec2(24, 24), iconType, connected, color, ImColor(32, 32, 32, alpha));
272+
ax::Widgets::icon(EmToVec2(1, 1), iconType, connected, color, ImColor(32, 32, 32, alpha));
270273
}
271274

272275
bool PipelineEditor::canCreateLink(const EditorPin* startPin, const EditorPin* endPin) const {
@@ -365,7 +368,7 @@ void PipelineEditor::renderEditor() {
365368
} else
366369
ImGui::TextUnformatted(node->name.c_str());
367370
ImGui::Spring(1);
368-
ImGui::Dummy(ImVec2(0, 28));
371+
ImGui::Dummy(EmToVec2(0, 1.5));
369372
ImGui::Spring(0);
370373
builder.endHeader();
371374

@@ -555,7 +558,7 @@ void PipelineEditor::renderEditor() {
555558
mNewNodeLinkPin = nullptr;
556559
}
557560

558-
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(8, 8));
561+
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, EmToVec2(0.25, 0.25));
559562
if(ImGui::BeginPopup("Node Context Menu")) {
560563
const auto node = findNode(mContextNodeId);
561564
if(!node->rename && ImGui::MenuItem("Rename")) {
@@ -930,9 +933,8 @@ void PipelineEditor::render(ShaderToyContext& context) {
930933

931934
ed::SetCurrentEditor(mCtx);
932935
// toolbar
933-
if(mShouldBuildPipeline || ImGui::Button(ICON_FA_PLAY " Build")) {
934-
build(context);
935-
mShouldBuildPipeline = false;
936+
if(ImGui::Button(ICON_FA_PLAY " Build")) {
937+
mShouldBuildPipeline = true;
936938
}
937939
ImGui::SameLine();
938940
if(ImGui::Button("Zoom to context")) {
@@ -1007,6 +1009,11 @@ void PipelineEditor::render(ShaderToyContext& context) {
10071009
ImGui::EndTabBar();
10081010
}
10091011
ImGui::End();
1012+
1013+
if(mShouldBuildPipeline) {
1014+
build(context);
1015+
mShouldBuildPipeline = false;
1016+
}
10101017
}
10111018

10121019
PipelineEditor& PipelineEditor::get() {
@@ -1089,7 +1096,7 @@ bool EditorTexture::renderContent() {
10891096

10901097
if(textureId) {
10911098
// NOLINTNEXTLINE(performance-no-int-to-ptr)
1092-
ImGui::Image(reinterpret_cast<ImTextureID>(textureId->getTexture()), ImVec2{ 64, 64 }, ImVec2{ 0, 1 }, ImVec2{ 1, 0 });
1099+
ImGui::Image(reinterpret_cast<ImTextureID>(textureId->getTexture()), EmToVec2(3, 3), ImVec2{ 0, 1 }, ImVec2{ 1, 0 });
10931100
}
10941101
return updateTex;
10951102
}
@@ -1174,7 +1181,7 @@ void EditorLastFrame::renderPopup() {
11741181

11751182
if(editing && ImGui::BeginPopup("##popup_button")) {
11761183
lastFrame = nullptr;
1177-
ImGui::BeginChild("##popup_scroller", ImVec2(100, 100), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
1184+
ImGui::BeginChild("##popup_scroller", EmToVec2(4, 4), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
11781185
for(uint32_t idx = 0; idx < names.size(); ++idx) {
11791186
if(ImGui::Button(names[idx])) {
11801187
lastFrame = nodes[idx];

shadertoy/OpenGL.cpp

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -327,28 +327,33 @@ class RenderPass final {
327327
[[nodiscard]] NodeType getType() const noexcept {
328328
return mType;
329329
}
330-
void render(ImVec2 frameBufferSize, const ImVec2 clipMin, const ImVec2 clipMax, ImVec2 base, ImVec2 size,
330+
void render(const ImVec2 frameBufferSize, const ImVec2 clipMin, const ImVec2 clipMax, const ImVec2 canvasSize,
331331
const ShaderToyUniform& uniform, const GLuint vao, const GLuint vbo) {
332332
glDisable(GL_BLEND);
333333
constexpr ImVec2 cubeMapSize{ static_cast<float>(cubeMapRenderTargetSize), static_cast<float>(cubeMapRenderTargetSize) };
334+
const auto screenBase = clipMin;
335+
const auto screenSize = ImVec2{ clipMax.x - clipMin.x, clipMax.y - clipMin.y };
334336

335337
for(uint32_t idx = 0; idx < mBuffers.size(); ++idx) {
336338
const auto buffer = mBuffers[idx].get();
337-
339+
ImVec2 size, base, fbSize, uniformSize;
338340
if(buffer) {
339-
if(mType == NodeType::CubeMap) {
340-
size = cubeMapSize;
341-
}
341+
base = { 0, 0 };
342+
size = mType == NodeType::CubeMap ? cubeMapSize : screenSize;
343+
fbSize = size;
344+
uniformSize = mType == NodeType::CubeMap ? cubeMapSize : canvasSize;
342345
glViewport(0, 0, static_cast<GLsizei>(size.x), static_cast<GLsizei>(size.y));
343346
glDisable(GL_SCISSOR_TEST);
344347
buffer->bind(static_cast<uint32_t>(size.x), static_cast<uint32_t>(size.y));
345-
base = { 0, 0 };
346-
frameBufferSize = size;
347348
} else {
348349
glViewport(0, 0, static_cast<GLsizei>(frameBufferSize.x), static_cast<GLsizei>(frameBufferSize.y));
349350
glEnable(GL_SCISSOR_TEST);
350351
glScissor(static_cast<GLint>(clipMin.x), static_cast<GLint>(frameBufferSize.y - clipMax.y),
351352
static_cast<GLint>(clipMax.x - clipMin.x), static_cast<GLint>(clipMax.y - clipMin.y));
353+
base = screenBase;
354+
size = screenSize;
355+
fbSize = frameBufferSize;
356+
uniformSize = canvasSize;
352357
}
353358
glUseProgram(mProgram);
354359
// update vertex array
@@ -362,8 +367,8 @@ class RenderPass final {
362367
Vertex{ ImVec2{ base.x + size.x, base.y + size.y }, ImVec2{ size.x, 0.0 } }, // right-bottom
363368
};
364369
for(auto& [pos, coord] : vertices) {
365-
pos.x = pos.x / frameBufferSize.x * 2.0f - 1.0f;
366-
pos.y = 1.0f - pos.y / frameBufferSize.y * 2.0f;
370+
pos.x = pos.x / fbSize.x * 2.0f - 1.0f;
371+
pos.y = 1.0f - pos.y / fbSize.y * 2.0f;
367372
}
368373
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex), vertices.data(), GL_STREAM_DRAW);
369374
} else {
@@ -378,8 +383,8 @@ class RenderPass final {
378383
cubeMapVertexPos[cubeMapVertexIndex[idx][3]] }, // right-bottom
379384
};
380385
for(auto& [pos, coord, point] : vertices) {
381-
pos.x = pos.x / frameBufferSize.x * 2.0f - 1.0f;
382-
pos.y = 1.0f - pos.y / frameBufferSize.y * 2.0f;
386+
pos.x = pos.x / fbSize.x * 2.0f - 1.0f;
387+
pos.y = 1.0f - pos.y / fbSize.y * 2.0f;
383388
}
384389
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(VertexCubeMap), vertices.data(), GL_STREAM_DRAW);
385390
}
@@ -439,7 +444,7 @@ class RenderPass final {
439444

440445
// update uniform
441446
if(mLocationResolution != -1)
442-
glUniform3f(mLocationResolution, size.x, size.y, 0.0f);
447+
glUniform3f(mLocationResolution, uniformSize.x, uniformSize.y, 0.0f);
443448
if(mLocationTime != -1)
444449
glUniform1f(mLocationTime, uniform.time);
445450
if(mLocationTimeDelta != -1)
@@ -613,7 +618,7 @@ class OpenGLPipeline final : public Pipeline {
613618
mRenderPasses.push_back(std::make_unique<RenderPass>(src, type, std::move(target), std::move(channels)));
614619
}
615620

616-
void render(const ImVec2 frameBufferSize, const ImVec2 clipMin, const ImVec2 clipMax, const ImVec2 base, const ImVec2 size,
621+
void render(const ImVec2 frameBufferSize, const ImVec2 clipMin, const ImVec2 clipMax, ImVec2 size,
617622
const ShaderToyUniform& uniform) override {
618623
for(auto& [tex, data, update] : mDynamicTextures) {
619624
update(data.data());
@@ -624,7 +629,7 @@ class OpenGLPipeline final : public Pipeline {
624629
glBindTexture(GL_TEXTURE_2D, GL_NONE);
625630
}
626631
for(const auto& pass : mRenderPasses)
627-
pass->render(frameBufferSize, clipMin, clipMax, base, size, uniform,
632+
pass->render(frameBufferSize, clipMin, clipMax, size, uniform,
628633
pass->getType() == NodeType::Image ? mVAOImage : mVAOCubeMap, mVBO);
629634
}
630635

shadertoy/ShaderToyContext.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void ShaderToyContext::render(const ImVec2 base, const ImVec2 size, const std::o
101101
return;
102102
ctx->mBound = { clipMin.x, clipMin.y, clipMax.x, clipMax.y };
103103
ctx->mPipeline->render(
104-
fbSize, clipMin, clipMax, ctx->mBase - drawData->DisplayPos, ctx->mSize,
104+
fbSize, clipMin, clipMax, ctx->mSize,
105105
{ ctx->mTime, ctx->mTimeDelta, ctx->mFrameRate, ctx->mFrameCount, ctx->mMouse, ctx->mDate });
106106
},
107107
this);

shadertoy/shadertoy.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "shadertoy/SuppressWarningPush.hpp"
2121

2222
#include <fmt/format.h>
23+
#include <hello_imgui/dpi_aware.h>
2324
#include <hello_imgui/hello_imgui.h>
2425
#include <hello_imgui/hello_imgui_screenshot.h>
2526
#include <httplib.h>
@@ -40,6 +41,8 @@
4041
#include <Windows.h>
4142
#endif
4243

44+
using HelloImGui::EmToVec2;
45+
4346
#include "shadertoy/SuppressWarningPop.hpp"
4447

4548
SHADERTOY_NAMESPACE_BEGIN
@@ -230,7 +233,7 @@ static void showImportModal() {
230233
ImGui::SetNextItemWidth(ImGui::CalcTextSize("https://www.shadertoy.com/view/WWWWWWXXXX").x);
231234
ImGui::InputText("##Url", &url, ImGuiInputTextFlags_CharsNoBlank);
232235

233-
if(ImGui::Button("Import", ImVec2(120, 0))) {
236+
if(ImGui::Button("Import", EmToVec2(5, 0))) {
234237
try {
235238
PipelineEditor::get().loadFromShaderToy(url);
236239
} catch(const Error&) {
@@ -240,7 +243,7 @@ static void showImportModal() {
240243
}
241244
ImGui::SetItemDefaultFocus();
242245
ImGui::SameLine();
243-
if(ImGui::Button("Cancel", ImVec2(120, 0))) {
246+
if(ImGui::Button("Cancel", EmToVec2(5, 0))) {
244247
ImGui::CloseCurrentPopup();
245248
}
246249
ImGui::EndPopup();
@@ -286,7 +289,7 @@ static void showAboutModal() {
286289
ImGui::TextUnformatted(OpenSSL_version(OPENSSL_VERSION));
287290
}
288291

289-
if(ImGui::Button("Close", ImVec2(120, 0))) {
292+
if(ImGui::Button("Close", EmToVec2(5, 0))) {
290293
ImGui::CloseCurrentPopup();
291294
}
292295
ImGui::SetItemDefaultFocus();
@@ -347,9 +350,6 @@ int shaderToyMain(int argc, char** argv) {
347350
canvasWindow.label = "Canvas";
348351
canvasWindow.dockSpaceName = "LeftSpace";
349352
canvasWindow.GuiFunction = [&] {
350-
if(!__glewCreateProgram && glewInit() != GLEW_OK)
351-
reportFatalError("Failed to initialize glew");
352-
353353
if(!initialPipeline.empty()) {
354354
if(startsWith(initialPipeline, "https://")) {
355355
PipelineEditor::get().loadFromShaderToy(initialPipeline);
@@ -375,6 +375,11 @@ int shaderToyMain(int argc, char** argv) {
375375
editorWindow.GuiFunction = [&] { PipelineEditor::get().render(ctx); };
376376
runnerParams.dockingParams.dockableWindows = { canvasWindow, outputWindow, editorWindow };
377377

378+
// 8x MSAA
379+
runnerParams.callbacks.PostInit = [] {
380+
if(glewInit() != GLEW_OK)
381+
reportFatalError("Failed to initialize glew");
382+
};
378383
HelloImGui::Run(runnerParams);
379384
return 0;
380385
}

0 commit comments

Comments
 (0)