Skip to content

Commit f88cf0d

Browse files
committed
Updated NetImgui Server's OpenGl version to work with latest changes
Also applied some changes to the sokol version, but that one need a sokol library update to dear imgui 1.92 to work.
1 parent e986632 commit f88cf0d

File tree

5 files changed

+146
-175
lines changed

5 files changed

+146
-175
lines changed

Code/ServerApp/Source/GlfwGL3/NetImguiServer_App_GlfwGL3.cpp

Lines changed: 78 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,18 @@
3838

3939
// Dear ImGui: standalone example application for GLFW + OpenGL 3, using programmable pipeline
4040
// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.)
41-
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
42-
// Read online: https://github.com/ocornut/imgui/tree/master/docs
41+
42+
// Learn about Dear ImGui:
43+
// - FAQ https://dearimgui.com/faq
44+
// - Getting Started https://dearimgui.com/getting-started
45+
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
46+
// - Introduction, links and more at the top of imgui.cpp
4347

4448
#include "imgui.h"
4549
#include "imgui_impl_glfw.h"
4650
#include "imgui_impl_opengl3.h"
4751
#include <stdio.h>
52+
#define GL_SILENCE_DEPRECATION
4853
#if defined(IMGUI_IMPL_OPENGL_ES2)
4954
#include <GLES2/gl2.h>
5055
#endif
@@ -57,25 +62,36 @@
5762
#pragma comment(lib, "legacy_stdio_definitions")
5863
#endif
5964

65+
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
66+
#ifdef __EMSCRIPTEN__
67+
#include "../libs/emscripten/emscripten_mainloop_stub.h"
68+
#endif
69+
6070
static void glfw_error_callback(int error, const char* description)
6171
{
62-
fprintf(stderr, "Glfw Error %d: %s\n", error, description);
72+
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
6373
}
6474

65-
int main(int argc, char **argv)
75+
// Main code
76+
int main(int argc, char **argv) // @SAMPLE_EDIT (added parameters names so we can use them)
6677
{
67-
// Setup window
6878
glfwSetErrorCallback(glfw_error_callback);
6979
if (!glfwInit())
7080
return 1;
7181

7282
// Decide GL+GLSL versions
7383
#if defined(IMGUI_IMPL_OPENGL_ES2)
74-
// GL ES 2.0 + GLSL 100
84+
// GL ES 2.0 + GLSL 100 (WebGL 1.0)
7585
const char* glsl_version = "#version 100";
7686
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
7787
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
7888
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
89+
#elif defined(IMGUI_IMPL_OPENGL_ES3)
90+
// GL ES 3.0 + GLSL 300 es (WebGL 2.0)
91+
const char* glsl_version = "#version 300 es";
92+
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
93+
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
94+
glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API);
7995
#elif defined(__APPLE__)
8096
// GL 3.2 + GLSL 150
8197
const char* glsl_version = "#version 150";
@@ -93,30 +109,38 @@ int main(int argc, char **argv)
93109
#endif
94110

95111
// Create window with graphics context
96-
GLFWwindow* window = glfwCreateWindow(1280, 720, "NetImgui Server", NULL, NULL); // @SAMPLE_EDIT (changed name)
97-
if (window == NULL)
112+
float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only
113+
GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "NetImgui Server", nullptr, nullptr); // @SAMPLE_EDIT (changed name)
114+
if (window == nullptr)
98115
return 1;
99116
glfwMakeContextCurrent(window);
100117
glfwSwapInterval(1); // Enable vsync
101118

102-
103119
// Setup Dear ImGui context
104120
IMGUI_CHECKVERSION();
105121
ImGui::CreateContext();
106122
ImGuiIO& io = ImGui::GetIO(); (void)io;
107-
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
108-
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
109-
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
110-
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
123+
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
124+
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
125+
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
126+
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows
111127
//io.ConfigViewportsNoAutoMerge = true;
112128
//io.ConfigViewportsNoTaskBarIcon = true;
113129

114130
// Setup Dear ImGui style
115131
ImGui::StyleColorsDark();
116-
//ImGui::StyleColorsClassic();
132+
//ImGui::StyleColorsLight();
117133

118-
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
134+
// Setup scaling
119135
ImGuiStyle& style = ImGui::GetStyle();
136+
style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again)
137+
style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose)
138+
#if GLFW_VERSION_MAJOR >= 3 && GLFW_VERSION_MINOR >= 3
139+
io.ConfigDpiScaleFonts = true; // [Experimental] Automatically overwrite style.FontScaleDpi in Begin() when Monitor DPI changes. This will scale fonts but _NOT_ scale sizes/padding for now.
140+
io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes.
141+
#endif
142+
143+
// When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
120144
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
121145
{
122146
style.WindowRounding = 0.0f;
@@ -125,22 +149,27 @@ int main(int argc, char **argv)
125149

126150
// Setup Platform/Renderer backends
127151
ImGui_ImplGlfw_InitForOpenGL(window, true);
152+
#ifdef __EMSCRIPTEN__
153+
ImGui_ImplGlfw_InstallEmscriptenCallbacks(window, "#canvas");
154+
#endif
128155
ImGui_ImplOpenGL3_Init(glsl_version);
129156

130157
// Load Fonts
131158
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
132159
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
133-
// - If the file cannot be loaded, the function will return NULL. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
134-
// - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
160+
// - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit).
161+
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
135162
// - Read 'docs/FONTS.md' for more instructions and details.
136163
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
164+
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details.
165+
//style.FontSizeBase = 20.0f;
137166
//io.Fonts->AddFontDefault();
138-
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
139-
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
140-
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
141-
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/ProggyTiny.ttf", 10.0f);
142-
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese());
143-
//IM_ASSERT(font != NULL);
167+
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf");
168+
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf");
169+
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf");
170+
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf");
171+
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf");
172+
//IM_ASSERT(font != nullptr);
144173

145174
// Our state
146175
bool show_demo_window = true;
@@ -160,20 +189,34 @@ int main(int argc, char **argv)
160189
cmdArgs.pop_back();
161190
}
162191

163-
bool ok = NetImguiServer::App::Startup(cmdArgs.c_str());
164-
while (ok && !glfwWindowShouldClose(window))
192+
bool netImguiInitOk = NetImguiServer::App::Startup(cmdArgs.c_str());
165193
//=========================================================================================
194+
195+
#ifdef __EMSCRIPTEN__
196+
// For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.
197+
// You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
198+
io.IniFilename = nullptr;
199+
EMSCRIPTEN_MAINLOOP_BEGIN
200+
#else
201+
while (!glfwWindowShouldClose(window))
202+
#endif
166203
{
204+
if( !netImguiInitOk ) break; // @SAMPLE_EDIT (immediately exit if init failed)
205+
167206
// Poll and handle events (inputs, window resize, etc.)
168207
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
169-
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
170-
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
208+
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
209+
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
171210
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
172211
glfwPollEvents();
173-
174-
NetImguiServer::App::Update(); // @SAMPLE_EDIT (Request each client to update their drawing content )
212+
if (glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0)
213+
{
214+
ImGui_ImplGlfw_Sleep(10);
215+
continue;
216+
}
175217

176218
// Start the Dear ImGui frame
219+
NetImguiServer::App::Update(); // @SAMPLE_EDIT (Request each client to update their drawing content )
177220
ImGui_ImplOpenGL3_NewFrame();
178221
ImGui_ImplGlfw_NewFrame();
179222
ImGui::NewFrame();
@@ -188,7 +231,7 @@ int main(int argc, char **argv)
188231
if (show_demo_window)
189232
ImGui::ShowDemoWindow(&show_demo_window);
190233

191-
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to created a named window.
234+
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window.
192235
{
193236
static float f = 0.0f;
194237
static int counter = 0;
@@ -207,7 +250,7 @@ int main(int argc, char **argv)
207250
ImGui::SameLine();
208251
ImGui::Text("counter = %d", counter);
209252

210-
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate);
253+
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
211254
ImGui::End();
212255
}
213256

@@ -231,7 +274,7 @@ int main(int argc, char **argv)
231274
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
232275
glClear(GL_COLOR_BUFFER_BIT);
233276
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
234-
277+
235278
// Update and Render additional Platform Windows
236279
// (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere.
237280
// For this specific demo app we could also call glfwMakeContextCurrent(window) directly)
@@ -245,6 +288,9 @@ int main(int argc, char **argv)
245288

246289
glfwSwapBuffers(window);
247290
}
291+
#ifdef __EMSCRIPTEN__
292+
EMSCRIPTEN_MAINLOOP_END;
293+
#endif
248294

249295
// Cleanup
250296
NetImguiServer::App::Shutdown(); // @SAMPLE_EDIT (Deallocate resources)

Code/ServerApp/Source/GlfwGL3/NetImguiServer_HAL_GL3.cpp

Lines changed: 25 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414

1515
namespace NetImguiServer { namespace App
1616
{
17+
18+
//=================================================================================================
19+
// HAL RENDER DRAW DATA
20+
//=================================================================================================
21+
void HAL_RenderDrawData(ImDrawData* pDrawData)
22+
{
23+
ImGui_ImplOpenGL3_RenderDrawData(pDrawData);
24+
}
25+
1726
//=================================================================================================
1827
// HAL RENDER DRAW DATA
1928
// The drawing of remote clients is handled normally by the standard rendering backend,
@@ -31,6 +40,7 @@ void HAL_RenderDrawData(RemoteClient::Client& client, ImDrawData* pDrawData)
3140
NetImgui::Internal::ScopedImguiContext scopedCtx(client.mpBGContext);
3241
ImGui::GetIO().BackendRendererUserData = mainBackend; // Re-appropriate the existing renderer backend, for this client rendeering
3342
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
43+
ImGui::GetIO().BackendRendererUserData = nullptr;
3444
}
3545
if (pDrawData)
3646
{
@@ -48,21 +58,21 @@ void HAL_RenderDrawData(RemoteClient::Client& client, ImDrawData* pDrawData)
4858
//=================================================================================================
4959
bool HAL_CreateRenderTarget(uint16_t Width, uint16_t Height, void*& pOutRT, ImTextureData& OutTexture)
5060
{
51-
HAL_DestroyRenderTarget(pOutRT, pOutTexture);
61+
HAL_DestroyRenderTarget(pOutRT, OutTexture);
5262

53-
GLuint pTextureView = 0u;
54-
glGenTextures(1, &pTextureView);
55-
glBindTexture(GL_TEXTURE_2D, pTextureView);
63+
GLuint TextureView = 0u;
64+
glGenTextures(1, &TextureView);
65+
glBindTexture(GL_TEXTURE_2D, TextureView);
5666
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
5767
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
5868
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
59-
69+
6070
GLuint pRenderTargetView = 0u;
6171
glGenFramebuffers(1, &pRenderTargetView);
6272
glBindFramebuffer(GL_FRAMEBUFFER, pRenderTargetView);
6373

6474
//Attach 2D texture to this FBO
65-
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, pTextureView, 0);
75+
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, TextureView, 0);
6676

6777
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
6878
bool bSuccess = status == GL_FRAMEBUFFER_COMPLETE;
@@ -73,7 +83,9 @@ bool HAL_CreateRenderTarget(uint16_t Width, uint16_t Height, void*& pOutRT, ImTe
7383

7484
if( bSuccess ){
7585
pOutRT = reinterpret_cast<void*>(static_cast<uint64_t>(pRenderTargetView));
76-
pOutTexture = reinterpret_cast<void*>(static_cast<uint64_t>(pTextureView));
86+
// Store identifiers
87+
OutTexture.SetTexID(static_cast<ImTextureID>(TextureView));
88+
OutTexture.SetStatus(ImTextureStatus_OK);
7789
return true;
7890
}
7991
return false;
@@ -91,70 +103,15 @@ void HAL_DestroyRenderTarget(void*& pOutRT, ImTextureData& OutTexture)
91103
pOutRT = nullptr;
92104
glDeleteFramebuffers(1, &pRT);
93105
}
94-
if(pOutTexture)
106+
if(OutTexture.Status != ImTextureStatus_Destroyed && OutTexture.GetTexID() != ImTextureID_Invalid)
95107
{
96-
GLuint pTexture = static_cast<GLuint>(reinterpret_cast<uint64_t>(pOutTexture));
97-
pOutTexture = nullptr;
98-
glDeleteTextures(1, &pTexture);
99-
}
100-
}
108+
GLuint ViewTexture = static_cast<GLuint>(OutTexture.GetTexID());
109+
glDeleteTextures(1, &ViewTexture);
101110

102-
//=================================================================================================
103-
// HAL CREATE TEXTURE
104-
// Receive info on a Texture to allocate. At the moment, 'Dear ImGui' default rendering backend
105-
// only support RGBA8 format, so first convert any input format to a RGBA8 that we can use
106-
//=================================================================================================
107-
bool HAL_CreateTexture(uint16_t Width, uint16_t Height, NetImgui::eTexFormat Format, const uint8_t* pPixelData, ServerTexture& OutTexture)
108-
{
109-
NetImguiServer::App::EnqueueHALTextureDestroy(OutTexture);
110-
111-
// Convert all incoming textures data to RGBA8
112-
uint32_t* pPixelDataAlloc = NetImgui::Internal::netImguiSizedNew<uint32_t>(Width*Height*4);
113-
if(Format == NetImgui::eTexFormat::kTexFmtA8)
114-
{
115-
for (int i = 0; i < Width * Height; ++i){
116-
pPixelDataAlloc[i] = 0x00FFFFFF | (static_cast<uint32_t>(pPixelData[i])<<24);
117-
}
118-
pPixelData = reinterpret_cast<const uint8_t*>(pPixelDataAlloc);
119-
}
120-
else if (Format == NetImgui::eTexFormat::kTexFmtRGBA8)
121-
{
122-
}
123-
else
124-
{
125-
// Unsupported format
126-
return false;
127-
}
128-
129-
GLint last_texture;
130-
glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture); // Save state
131-
132-
// Create new texture
133-
GLuint texture = 0u;
134-
glGenTextures(1, &texture);
135-
136-
//GLenum error = glGetError(); (void)error;
137-
if( texture != 0 ){
138-
glBindTexture(GL_TEXTURE_2D, texture);
139-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
140-
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
141-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, Width, Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pPixelData);
142-
OutTexture.mpHAL_Texture = reinterpret_cast<void*>(static_cast<uint64_t>(texture));
143-
glBindTexture(GL_TEXTURE_2D, last_texture); // Restore state
111+
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
112+
OutTexture.SetTexID(ImTextureID_Invalid);
113+
OutTexture.SetStatus(ImTextureStatus_Destroyed);
144114
}
145-
NetImgui::Internal::netImguiDeleteSafe(pPixelDataAlloc);
146-
return texture != 0;
147-
}
148-
149-
//=================================================================================================
150-
// HAL DESTROY TEXTURE
151-
// Free up allocated resources tried to a Texture
152-
//=================================================================================================
153-
void HAL_DestroyTexture(ServerTexture& OutTexture)
154-
{
155-
GLuint pTexture = static_cast<GLuint>(reinterpret_cast<uint64_t>(OutTexture.mpHAL_Texture));
156-
glDeleteTextures(1, &pTexture);
157-
memset(&OutTexture, 0, sizeof(OutTexture));
158115
}
159116

160117
}} //namespace NetImguiServer { namespace App

Code/ServerApp/Source/NetImguiServer_App.cpp

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,27 @@ void Shutdown()
6868
}
6969
}
7070

71-
ImGui::NewFrame(); ImGui::Render(); HAL_RenderDrawData(ImGui::GetDrawData()); // Allow Dear ImGui to delete the textures
72-
UpdateServerTextures(); // Finish removing them from Dear ImGui user textures and delete objects
73-
ImGui::NewFrame(); ImGui::Render(); // Update Dear ImGui texture list (so it doesn't have deleted items in it)
71+
// Allow Dear ImGui to delete the textures
72+
ImGui::NewFrame();
73+
ImGui::Render();
74+
HAL_RenderDrawData(ImGui::GetDrawData());
75+
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
76+
{
77+
ImGui::UpdatePlatformWindows();
78+
ImGui::RenderPlatformWindowsDefault();
79+
}
80+
81+
// Finish removing them from Dear ImGui user textures and delete objects
82+
UpdateServerTextures();
83+
84+
// Update Dear ImGui texture list (so it doesn't have deleted items in it)
85+
ImGui::NewFrame();
86+
ImGui::Render();
87+
if (ImGui::GetIO().ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
88+
{
89+
ImGui::UpdatePlatformWindows();
90+
ImGui::RenderPlatformWindowsDefault();
91+
}
7492

7593
// Remove deleted textures from clients
7694
for(uint32_t i(0); i<RemoteClient::Client::GetCountMax(); ++i)

0 commit comments

Comments
 (0)