{"id":652,"date":"2024-09-08T09:46:18","date_gmt":"2024-09-08T09:46:18","guid":{"rendered":"https:\/\/blog.vishnumuthu.com\/?p=652"},"modified":"2025-02-25T14:45:17","modified_gmt":"2025-02-25T14:45:17","slug":"simple-working-of-imgui-implot-and-udp-socket","status":"publish","type":"post","link":"https:\/\/blog.vishnumuthu.com\/index.php\/2024\/09\/08\/simple-working-of-imgui-implot-and-udp-socket\/","title":{"rendered":"Simple working of Imgui, Implot and UDP Socket"},"content":{"rendered":"\n<div class=\"wp-block-buttons alignwide is-content-justification-center is-layout-flex wp-container-core-buttons-is-layout-a89b3969 wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/blog.vishnumuthu.com\/index.php\/2024\/09\/08\/a-simple-understanding-of-qthread\/\">Previous post: A simple understanding of qthread<\/a><\/div>\n<\/div>\n\n\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>Simple working of Imgui, Implot and UDP Socket<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">The Example <a href=\"https:\/\/github.com\/vishnumuthu\/ImGUI_Implot_UDPSocket\"><strong>ImGUI_Implot_UDPSocket github link<\/strong><\/a>,\nCreate a simple working for ImGUI and Implot with VisualStudio 22 to show the working of UDP socket.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">* The example shows integrating Imgui with Implot with glfw.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">* The example shows UDP socket send and receive through winsock2.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">* The example shows the real time plot of value.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"468\" src=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_1-1024x468.png\" alt=\"\" class=\"wp-image-653\" srcset=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_1-1024x468.png 1024w, https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_1-300x137.png 300w, https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_1-768x351.png 768w, https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_1.png 1365w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Graph output:<\/figcaption><\/figure>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>ImGui (Immediate Mode GUI)<\/strong> is a lightweight, fast, and easy-to-integrate graphical user interface library designed primarily for real-time applications like game engines, simulations, and tools. Unlike traditional GUIs that store the state of widgets, ImGui works in &#8220;immediate mode,&#8221; where the UI is fully reconstructed every frame based on the current state. This makes it highly efficient and flexible for dynamic UIs, as developers can modify the interface directly in the render loop. ImGui is widely used for debugging interfaces, editor tools, and quick prototyping because of its simple API, minimal setup, and real-time responsiveness.<\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">A <strong>UDP socket<\/strong> is a communication endpoint that uses the User Datagram Protocol (UDP) for transmitting data over a network. Unlike TCP, UDP is a connectionless protocol, meaning it sends messages, called datagrams, without establishing a reliable connection between sender and receiver. This makes UDP lightweight and faster but less reliable, as it doesn&#8217;t guarantee delivery, ordering, or error-checking of packets. UDP sockets are commonly used in applications where speed is critical and occasional data loss is acceptable, such as in real-time video streaming, online gaming, or VoIP (Voice over IP).<\/p>\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>Sending Data Section<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Send Network part:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Network.h header file for C++ UDP\n\n#define _WINSOCK_DEPRECATED_NO_WARNINGS\n#include &lt;system_error&gt;\n#include &lt;string&gt;\n#include &lt;iostream&gt;\n#include &lt;winsock2.h&gt;\n\n#pragma once\n#pragma comment (lib, \"ws2_32\")\n\nclass WSASession\n{\npublic:\n    WSASession()\n    {\n        int ret = WSAStartup(MAKEWORD(2, 2), &amp;data);\n        if (ret != 0)\n            throw std::system_error(WSAGetLastError(), std::system_category(), \"WSAStartup Failed\");\n    }\n    ~WSASession()\n    {\n        WSACleanup();\n    }\n\nprivate:\n    WSAData data;\n};\n\nclass UDPSocket\n{\npublic:\n    UDPSocket()\n    {\n        sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);\n        if (sock == INVALID_SOCKET)\n            throw std::system_error(WSAGetLastError(), std::system_category(), \"Error opening socket\");\n    }\n    ~UDPSocket()\n    {\n        closesocket(sock);\n    }\n\n    void SendTo(const std::string&amp; address, unsigned short port, const char* buffer, int len, int flags = 0)\n    {\n        sockaddr_in add;\n        add.sin_family = AF_INET;\n        add.sin_addr.s_addr = inet_addr(address.c_str());\n        \/\/add.sin_addr.s_addr = inet_pton(AF_INET, \"127.0.0.1\", address.c_str());\n        add.sin_port = htons(port);\n        int ret = sendto(sock, buffer, len, flags, reinterpret_cast&lt;SOCKADDR*&gt;(&amp;add), sizeof(add));\n        if (ret &lt; 0)\n            throw std::system_error(WSAGetLastError(), std::system_category(), \"sendto failed\");\n    }\n    void SendTo(sockaddr_in&amp; address, const char* buffer, int len, int flags = 0)\n    {\n        int ret = sendto(sock, buffer, len, flags, reinterpret_cast&lt;SOCKADDR*&gt;(&amp;address), sizeof(address));\n        if (ret &lt; 0)\n            throw std::system_error(WSAGetLastError(), std::system_category(), \"sendto failed\");\n    }\n    sockaddr_in RecvFrom(char* buffer, int len, int flags = 0)\n    {\n        sockaddr_in from;\n        int size = sizeof(from);\n        int ret = recvfrom(sock, buffer, len, flags, reinterpret_cast&lt;SOCKADDR*&gt;(&amp;from), &amp;size);\n        if (ret &lt; 0)\n            throw std::system_error(WSAGetLastError(), std::system_category(), \"recvfrom failed\");\n\n        \/\/ make the buffer zero terminated\n        buffer&#91;ret] = 0;\n        return from;\n    }\n    void Bind(unsigned short port)\n    {\n        sockaddr_in add;\n        add.sin_family = AF_INET;\n        add.sin_addr.s_addr = htonl(INADDR_ANY);\n        add.sin_port = htons(port);\n\n        int ret = bind(sock, reinterpret_cast&lt;SOCKADDR*&gt;(&amp;add), sizeof(add));\n        if (ret &lt; 0)\n            throw std::system_error(WSAGetLastError(), std::system_category(), \"Bind failed\");\n    }\n\nprivate:\n    SOCKET sock;\n};\n<\/code><\/pre>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Sending Main part:<\/strong><\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:66.66%\">\n<pre class=\"wp-block-code\"><code>\/\/ C++ UDP Transmitter\n\n#include \"Network.h\"\n\n#include &lt;cstdlib&gt;\n#include &lt;ctime&gt;\n#include &lt;iostream&gt;\n\n#pragma once\n\nint main()\n{\n    std::string IP = \"127.0.0.1\";\n    int PORT = 8888;\n\n    try\n    {\n        WSASession Session;\n        UDPSocket Socket;\n        std::string data = \"hello world\";\n        char buffer&#91;100];\n\n        \/\/ create a clock and start timer\n        clock_t TimeZero = clock(); \/\/Start timer\n        std::cout &lt;&lt; \"Start time: \" &lt;&lt; TimeZero &lt;&lt; std::endl;\n\n        double deltaTime = 0;\n        double hz_value = 10;\n        double reset_time = 1000 \/ hz_value;\n\n        \/\/ generate random seed using time \n        srand(time(0));\n\n        while (1)\n        {\n\n            \/\/ get delta time in milliseconds\n            deltaTime = (clock() - TimeZero);\n\n            \/\/ compare if delta time is 2 or more seconds\n            if (deltaTime &gt; reset_time) {\n\n                struct tm newtime;\n                time_t now = time(0);\n                localtime_s(&amp;newtime, &amp;now);\n                \/\/std::cout &lt;&lt; \"Current local time : \" &lt;&lt; newtime.tm_hour &lt;&lt; \":\" &lt;&lt; newtime.tm_min &lt;&lt; \":\" &lt;&lt; newtime.tm_sec &lt;&lt;std::endl;\n\n                \/\/ generate new random number\n                int i = rand() % 100 + 1;\n                \/\/std::cout  &lt;&lt; \": New random : \" &lt;&lt; i &lt;&lt; \"\\n\";\n                data = std::to_string(newtime.tm_hour) +\":\" + std::to_string(newtime.tm_min) + \":\" + std::to_string(newtime.tm_sec) + \" \" + std::to_string(i);\n                std::cout &lt;&lt; data &lt;&lt; std::endl;\n                Socket.SendTo(IP, PORT, data.c_str(), data.size());\n\n                \/\/reset the clock timers\n                TimeZero = clock();\n            }\n        }\n    }\n    catch (std::exception&amp; ex)\n    {\n        std::cout &lt;&lt; ex.what();\n    }\n}\n<\/code><\/pre>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\" style=\"flex-basis:33.33%\">\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"344\" height=\"574\" src=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_2.png\" alt=\"\" class=\"wp-image-654\" srcset=\"https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_2.png 344w, https:\/\/blog.vishnumuthu.com\/wp-content\/uploads\/2024\/09\/imgui_2-180x300.png 180w\" sizes=\"auto, (max-width: 344px) 100vw, 344px\" \/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Explanation:<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">Here the UDP network socket is created using winsock2. Then a random value is generated with a time stamp of the system and sent through the created socket. <\/p>\n\n&nbsp;<p class=\"has-medium-font-size\"><strong>Receive Data Section:<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Receive Network part:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ Network.h\n#include &lt;iostream&gt;\n#include &lt;winsock2.h&gt;\n\/\/#include &lt;ws2tcpip.h&gt;\n\n#pragma comment(lib, \"ws2_32.lib\")\n\nclass UDPHandler {\nprivate:\n    SOCKET sockfd;\n    struct sockaddr_in serverAddr, clientAddr;\n    int addrLen;\n    char buffer&#91;1024];\n\npublic:\n    UDPHandler(int port) {\n        WSADATA wsaData;\n        if (WSAStartup(MAKEWORD(2, 2), &amp;wsaData) != 0) {\n            std::cerr &lt;&lt; \"WSAStartup failed\" &lt;&lt; std::endl;\n            exit(EXIT_FAILURE);\n        }\n\n        sockfd = socket(AF_INET, SOCK_DGRAM, 0);\n        if (sockfd == INVALID_SOCKET) {\n            std::cerr &lt;&lt; \"Socket creation failed\" &lt;&lt; std::endl;\n            WSACleanup();\n            exit(EXIT_FAILURE);\n        }\n\n        \/\/ Set socket options using setsockopt()\n        int timeout = 10; \/\/ 5 seconds\n        if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&amp;timeout, sizeof(timeout)) == SOCKET_ERROR) {\n            std::cerr &lt;&lt; \"setsockopt failed\" &lt;&lt; std::endl;\n            closesocket(sockfd);\n            WSACleanup();\n            exit(EXIT_FAILURE);\n        }\n\n        memset(&amp;serverAddr, 0, sizeof(serverAddr));\n        memset(&amp;clientAddr, 0, sizeof(clientAddr));\n\n        serverAddr.sin_family = AF_INET;\n        serverAddr.sin_addr.s_addr = INADDR_ANY;\n        serverAddr.sin_port = htons(port);\n\n        if (bind(sockfd, (struct sockaddr *)&amp;serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {\n            std::cerr &lt;&lt; \"Bind failed\" &lt;&lt; std::endl;\n            closesocket(sockfd);\n            WSACleanup();\n            exit(EXIT_FAILURE);\n        }\n\n        addrLen = sizeof(clientAddr);\n    }\n\n    std::string receiveData() {\n        int n = recvfrom(sockfd, buffer, 1024, 0, (struct sockaddr *)&amp;clientAddr, &amp;addrLen);\n        if (n == SOCKET_ERROR) {\n            std::cerr &lt;&lt; \"Receive failed\" &lt;&lt; std::endl;\n            return \"NILL\";\n        }\n        buffer&#91;n] = '\\0';\n        return std::string(buffer);\n    }\n\n    void sendData(const std::string &amp;data) {\n        sendto(sockfd, data.c_str(), data.length(), 0, (struct sockaddr *)&amp;clientAddr, addrLen);\n    }\n\n    ~UDPHandler() {\n        closesocket(sockfd);\n        WSACleanup();\n    }\n};\n<\/code><\/pre>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Receive Main part:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/main.cpp\nstd::vector&lt;std::string&gt; split(std::string s, std::string delimiter) {\n    size_t pos_start = 0, pos_end, delim_len = delimiter.length();\n    std::string token;\n    std::vector&lt;std::string&gt; res;\n\n    while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {\n        token = s.substr(pos_start, pos_end - pos_start);\n        pos_start = pos_end + delim_len;\n        res.push_back(token);\n    }\n\n    res.push_back(s.substr(pos_start));\n    return res;\n}\n\n    UDPHandler udpHandler(8888);  \/\/ Initialize UDPHandler with the desired port\n\n    \/\/ assign graph\n    static float xs1&#91;10000], ys1&#91;10000];\n    int gcount1 = 0;\n\n    \/\/ Main loop\n#ifdef __EMSCRIPTEN__\n    \/\/ For an Emscripten build we are disabling file-system access, so let's not attempt to do a fopen() of the imgui.ini file.\n    \/\/ You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.\n    io.IniFilename = nullptr;\n    EMSCRIPTEN_MAINLOOP_BEGIN\n#else\n    while (!glfwWindowShouldClose(window))\n#endif\n    {\n        glfwPollEvents();\n        if (glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0)\n        {\n            ImGui_ImplGlfw_Sleep(10);\n            continue;\n        }\n\n        \/\/ Start the Dear ImGui frame\n        ImGui_ImplOpenGL3_NewFrame();\n        ImGui_ImplGlfw_NewFrame();\n        ImGui::NewFrame();\n\n        {\n            static float f = 0.0f;\n            \/\/static int counter = 0;\n\n            ImGui::Begin(\"Main Window\");                          \/\/ Create a window called \"Hello, world!\" and append into it.\n\n            ImGui::Text(\"List of Graphs\");               \/\/ Display some text (you can use a format strings too)\n            ImGui::Checkbox(\"show graph\", &amp;show_graph);      \/\/ Edit bools storing our window open\/close state\n\n            ImGui::Text(\"Application average %.3f ms\/frame (%.1f FPS)\", 1000.0f \/ io.Framerate, io.Framerate);\n            ImGui::End();\n        }\n\n        \n        if(show_graph)\n        { \n            ImGui::Begin(\"graph\");\n\n            \/\/ Receive UDP data\n            std::string receivedData = udpHandler.receiveData();\n\n            \/\/ Process the data (for simplicity, we'll just print it here)\n            std::cout &lt;&lt; \"Received: \" &lt;&lt; receivedData &lt;&lt; std::endl;\n            std::string delimiter = \" \";\n            std::vector&lt;std::string&gt; v = split(receivedData, delimiter);\n\n            for (auto i : v) std::cout &lt;&lt; i &lt;&lt; std::endl;\n\n\n            if (v&#91;0] != \"NILL\")\n            {\n                xs1&#91;gcount1] = gcount1;\n                ys1&#91;gcount1] = std::stof(v&#91;1]);\n                gcount1++;\n\n            }\n            \n\n            if (ImPlot::BeginPlot(\"Line Plots\")) {\n                ImPlot::SetupAxes(\"x\", \"y\");\n                ImPlot::PlotLine(\"f(x)\", xs1, ys1, gcount1);\n                ImPlot::SetNextMarkerStyle(ImPlotMarker_Circle);\n                \/\/ImPlot::PlotLine(\"g(x)\", xs2, ys2, 20, ImPlotLineFlags_Segments);\n                ImPlot::EndPlot();\n            }\n\n            ImGui::End();\n        }\n  \n\n        \/\/ Rendering\n        ImGui::Render();\n        int display_w, display_h;\n        glfwGetFramebufferSize(window, &amp;display_w, &amp;display_h);\n        glViewport(0, 0, display_w, display_h);\n        glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);\n        glClear(GL_COLOR_BUFFER_BIT);\n        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());\n\n        glfwSwapBuffers(window);\n    }\n#ifdef __EMSCRIPTEN__\n    EMSCRIPTEN_MAINLOOP_END;\n#endif\n\n    \/\/ Cleanup\n    ImGui_ImplOpenGL3_Shutdown();\n    ImGui_ImplGlfw_Shutdown();\n    ImPlot::DestroyContext();\n    ImGui::DestroyContext();\n\n    glfwDestroyWindow(window);\n    glfwTerminate();\n\n    return 0;\n}\n<\/code><\/pre>\n\n\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\"><strong>Explanation:<\/strong><\/p>\n\n<p class=\"has-normal-font-size\" style=\"text-indent:.2in;\">Here the UDP network socket for receiving is created using winsock2. Then the data is extracted and send to the implot data. Once the data is received the graph is updated accordingly. <\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Simple working of Imgui, Implot and UDP Socket The Example ImGUI_Implot_UDPSocket github link, Create a simple working for ImGUI and Implot with VisualStudio 22 to show the working of UDP socket. * The example shows integrating Imgui with Implot with glfw. * The example shows UDP socket send and receive through winsock2. * The [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":660,"comment_status":"open","ping_status":"open","sticky":false,"template":"wp-custom-template-template-cpp","format":"standard","meta":{"footnotes":""},"categories":[133],"tags":[134,139,140,141],"class_list":["post-652","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cpp","tag-cpp","tag-imgui","tag-implot","tag-udp-socket"],"_links":{"self":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts\/652","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/comments?post=652"}],"version-history":[{"count":6,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts\/652\/revisions"}],"predecessor-version":[{"id":657,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/posts\/652\/revisions\/657"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/media\/660"}],"wp:attachment":[{"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/media?parent=652"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/categories?post=652"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.vishnumuthu.com\/index.php\/wp-json\/wp\/v2\/tags?post=652"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}