Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 0
Adding basic image support for desktop mode#72
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
11df8c18e9baa40f1eb61d7bc3a478d5da33cf63eb1db6eaee77387c671725bbec985b22ed2d9128804c34a73bd55bb3d2d43dcd8File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +0,0 @@ | ||
| *.png | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,8 @@ | ||
| #ifndef __EMSCRIPTEN__ | ||
| #include <GLES3/gl3.h> | ||
| #endif | ||
| #include <queue> | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| #include <string> | ||
| #include <mutex> | ||
| #include <rpp/rpp.hpp> | ||
| @@ -8,6 +13,7 @@ | ||
| #include "shared.h" | ||
| #include "imgui_helpers.h" | ||
| #include "texture_helpers.h" | ||
| using json = nlohmann::json; | ||
| @@ -71,6 +77,12 @@ class ReactImgui { | ||
| std::unordered_map<int, std::vector<int>> m_hierarchy; | ||
| std::mutex m_hierarchy_mutex; | ||
| #ifndef __EMSCRIPTEN__ | ||
| std::unordered_map<int, GLuint> m_imageToTextureMap; | ||
| #endif | ||
| std::queue<ImageJob> m_imageJobs; | ||
| std::unordered_map<int, std::unique_ptr<char[]>> m_floatFormatChars; | ||
| ImGuiStyle m_appStyle; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -17,4 +17,9 @@ struct Texture { | ||
| int height; | ||
| }; | ||
| struct ImageJob { | ||
| int widgetId; | ||
| std::string url; | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| }; | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| #endif //TEXTURE_HELPERS_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,8 @@ | ||
| #include <optional> | ||
| #include "ada.h" | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| #include "mapgenerator.h" | ||
| #include "styled_widget.h" | ||
| #include "texture_helpers.h" | ||
| #include <nlohmann/json.hpp> | ||
| using fetchImageCallback = std::function<void(void*, size_t)>; | ||
| @@ -20,11 +20,13 @@ class Image final : public StyledWidget { | ||
| auto id = widgetDef["id"].template get<int>(); | ||
| auto url = widgetDef["url"].template get<std::string>(); | ||
| auto parsedUrl = ada::parse<ada::url>(url); | ||
| #ifdef __EMSCRIPTEN__ | ||
| auto parsedUrl = ada::parse<ada::url>(url); | ||
| if (!parsedUrl) { | ||
| throw std::invalid_argument("Invalid url supplied"); | ||
| } | ||
| #endif | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| std::optional<ImVec2> size; | ||
| @@ -57,12 +59,12 @@ class Image final : public StyledWidget { | ||
| void HandleInternalOp(const json& opDef) override; | ||
| void FetchImage(); | ||
| #ifdef __EMSCRIPTEN__ | ||
| void FetchImage(); | ||
| void HandleFetchImageSuccess(emscripten_fetch_t *fetch); | ||
| void HandleFetchImageFailure(emscripten_fetch_t *fetch); | ||
| #else | ||
| void QueueFetchImage(); | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| #endif | ||
| void Init(const json& elementDef) override { | ||
| @@ -71,6 +73,10 @@ class Image final : public StyledWidget { | ||
| YGNodeSetContext(m_layoutNode->m_node, this); | ||
| YGNodeSetMeasureFunc(m_layoutNode->m_node, Measure); | ||
| #ifdef __EMSCRIPTEN__ | ||
| FetchImage(); | ||
| #else | ||
| QueueFetchImage(); | ||
| #endif | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| #define _CRT_SECURE_NO_WARNINGS | ||
| #define STB_IMAGE_IMPLEMENTATION | ||
| #include "stb_image.h" | ||
| @@ -7,6 +8,7 @@ | ||
| #include <webgpu/webgpu.h> | ||
| #else | ||
| #include "imgui_impl_opengl3.h" | ||
| #include <GLES3/gl3.h> | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| #endif | ||
| #ifdef __EMSCRIPTEN__ | ||
| @@ -201,9 +203,11 @@ void ImGuiRenderer::InitGlfw() { | ||
| // This needs to be done explicitly later. | ||
| glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API); | ||
| #else | ||
| const char* glsl_version = "#version 130"; | ||
| const char* glsl_version = "#version 150"; | ||
| glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only | ||
| glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); | ||
| glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); | ||
| glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); | ||
| glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); | ||
| #endif | ||
| m_glfwWindow = glfwCreateWindow(m_window_width, m_window_height, m_glWindowTitle, nullptr, nullptr); | ||
| @@ -382,8 +386,44 @@ void ImGuiRenderer::SetCurrentContext() { | ||
| ImGui::SetCurrentContext(m_imGuiCtx); | ||
| } | ||
| #ifndef __EMSCRIPTEN__ | ||
| void ImGuiRenderer::HandleNextImageJob() { | ||
| auto& [widgetId, url] = m_reactImgui->m_imageJobs.front(); | ||
| auto pathToFile = std::format("{}/{}", m_assetsBasePath, url); | ||
| FILE* f = fopen(pathToFile.c_str(), "rb"); | ||
| if (f == NULL) { | ||
| printf("Unable to open file\n"); | ||
| return; | ||
| } | ||
| fseek(f, 0, SEEK_END); | ||
| size_t file_size = (size_t)ftell(f); | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| if (file_size == -1) { | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| printf("Unable to determine file size of image\n"); | ||
| } | ||
| fseek(f, 0, SEEK_SET); | ||
| void* file_data = IM_ALLOC(file_size); | ||
| fread(file_data, 1, file_size, f); | ||
| fclose(f); | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| m_reactImgui->m_imageToTextureMap[widgetId] = LoadTexture(file_data, file_size); | ||
| IM_FREE(file_data); | ||
| m_reactImgui->m_imageJobs.pop(); | ||
| }; | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| #endif | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| void ImGuiRenderer::BeginRenderLoop() { | ||
| // SetCurrentContext(); | ||
| SetUp(); | ||
| #ifdef __EMSCRIPTEN__ | ||
| LoadFontsFromDefs(); | ||
| @@ -399,8 +439,6 @@ void ImGuiRenderer::BeginRenderLoop() { | ||
| m_reactImgui->Init(this); | ||
| SetUp(); | ||
| // Main loop | ||
| #ifdef __EMSCRIPTEN__ | ||
| EMSCRIPTEN_MAINLOOP_BEGIN | ||
| @@ -412,24 +450,27 @@ void ImGuiRenderer::BeginRenderLoop() { | ||
| HandleScreenSizeChanged(); | ||
| // SetCurrentContext(); | ||
| #ifdef __EMSCRIPTEN__ | ||
| #ifdef __EMSCRIPTEN__ | ||
| ImGui_ImplWGPU_NewFrame(); | ||
| #else | ||
| #else | ||
| ImGui_ImplOpenGL3_NewFrame(); | ||
| #endif | ||
| #endif | ||
| ImGui_ImplGlfw_NewFrame(); | ||
| #ifndef __EMSCRIPTEN__ | ||
| if (!m_reactImgui->m_imageJobs.empty()) { | ||
| HandleNextImageJob(); | ||
| } | ||
| #endif | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| m_reactImgui->Render(m_window_width, m_window_height); | ||
| PerformRendering(); | ||
| #ifndef __EMSCRIPTEN__ | ||
| #ifndef __EMSCRIPTEN__ | ||
| glfwSwapBuffers(m_glfwWindow); | ||
| #endif | ||
| #endif | ||
| } | ||
| #ifdef __EMSCRIPTEN__ | ||
| EMSCRIPTEN_MAINLOOP_END; | ||
| @@ -557,13 +598,41 @@ bool ImGuiRenderer::LoadTexture(const void* data, const int numBytes, Texture* t | ||
| return true; | ||
| } | ||
| #else | ||
| bool LoadTexture(const void* data, const int numBytes, Texture* texture) { | ||
| return true; | ||
| GLuint ImGuiRenderer::LoadTexture(const void* data, int numBytes) { | ||
| int image_width = 0; | ||
| int image_height = 0; | ||
| unsigned char* image_data = stbi_load_from_memory((const unsigned char*)data, (int)numBytes, &image_width, &image_height, NULL, 4); | ||
| if (image_data == NULL) { | ||
| printf("Unable to load image from memory\n"); | ||
| return 0; | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| GLuint image_texture = 0; | ||
| glGenTextures(1, &image_texture); | ||
| glBindTexture(GL_TEXTURE_2D, image_texture); | ||
| // Setup filtering parameters for display | ||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
| // Upload pixels into texture | ||
| glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); | ||
| glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width, image_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data); | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| GLenum error = glGetError(); | ||
| if (error != GL_NO_ERROR) { | ||
| printf("OpenGL Error: %d\n", error); | ||
| return 0; | ||
| } | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| stbi_image_free(image_data); | ||
| return image_texture; | ||
andreamancuso marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| } | ||
| #endif | ||
| json ImGuiRenderer::GetAvailableFonts() { | ||
| // SetCurrentContext(); | ||
| ImGuiIO& io = m_imGuiCtx->IO; | ||
| json fonts = json::array(); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| #include <imgui.h> | ||
| #include <nlohmann/json.hpp> | ||
| #include "widget/checkbox.h" | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.