├── .gitmodules ├── src ├── app │ ├── example │ │ ├── opengl_example │ │ │ ├── ProggyClean.ttf │ │ │ ├── glfw │ │ │ │ ├── lib-msvc100 │ │ │ │ │ └── glfw3.lib │ │ │ │ ├── lib-msvc110 │ │ │ │ │ └── glfw3.lib │ │ │ │ ├── COPYING.txt │ │ │ │ └── include │ │ │ │ │ └── GLFW │ │ │ │ │ └── glfw3native.h │ │ │ ├── opengl_example_without_deps.xcodeproj │ │ │ │ ├── project.xcworkspace │ │ │ │ │ └── contents.xcworkspacedata │ │ │ │ └── project.pbxproj │ │ │ ├── Info.plist │ │ │ ├── opengl_example_vs2013.vcxproj │ │ │ ├── opengl_example_without_deps.vcxproj │ │ │ ├── opengl_example_vs2013_without_deps.vcxproj │ │ │ ├── main.cpp │ │ │ └── main.mm │ │ ├── remote_example_vs2013.sln │ │ ├── remote_example_vs2010_without_deps.sln │ │ ├── remote_example_vs2013_without_deps.sln │ │ ├── README.md │ │ └── main.cpp │ ├── webby │ │ ├── webby_unix.h │ │ ├── webby_win32.h │ │ ├── LICENSE │ │ ├── README.md │ │ └── webby.h │ ├── lz4 │ │ ├── LICENSE │ │ ├── lz4frame_static.h │ │ ├── xxhash.h │ │ ├── lz4hc.h │ │ ├── lz4frame.h │ │ └── lz4.h │ ├── imgui_remote_webby.h │ └── imgui_remote.h └── client │ ├── imgui │ ├── detector.js │ └── main.css │ └── imgui.html ├── .gitignore ├── LICENSE └── README.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/app/imgui"] 2 | path = src/app/imgui 3 | url = https://github.com/ocornut/imgui.git 4 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/ProggyClean.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordiRos/remoteimgui/HEAD/src/app/example/opengl_example/ProggyClean.ttf -------------------------------------------------------------------------------- /src/app/example/opengl_example/glfw/lib-msvc100/glfw3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordiRos/remoteimgui/HEAD/src/app/example/opengl_example/glfw/lib-msvc100/glfw3.lib -------------------------------------------------------------------------------- /src/app/example/opengl_example/glfw/lib-msvc110/glfw3.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JordiRos/remoteimgui/HEAD/src/app/example/opengl_example/glfw/lib-msvc110/glfw3.lib -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.obj 2 | *.log 3 | *.tlog 4 | *.idb 5 | *.pdb 6 | *.sdf 7 | *.filters 8 | *.suo 9 | *.exe 10 | *.ilk 11 | *.ini 12 | *.opensdf 13 | *xcuserdata* 14 | *.xccheckout 15 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/opengl_example_without_deps.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/app/webby/webby_unix.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | typedef int webby_socket_t; 10 | typedef socklen_t webby_socklen_t; 11 | 12 | #define WB_ALIGN(x) __attribute__((aligned(x))) 13 | #define WB_INVALID_SOCKET (-1) 14 | 15 | static int wb_socket_error(void) 16 | { 17 | return errno; 18 | } 19 | 20 | static int wb_valid_socket(webby_socket_t socket) 21 | { 22 | return socket > 0; 23 | } 24 | 25 | static void wb_close_socket(webby_socket_t socket) 26 | { 27 | close(socket); 28 | } 29 | 30 | static int wb_is_blocking_error(int error) 31 | { 32 | return EAGAIN == error; 33 | } 34 | 35 | static int wb_set_blocking(webby_socket_t socket, int blocking) 36 | { 37 | int flags = fcntl(socket, F_GETFL); 38 | if (blocking) 39 | return fcntl(socket, F_SETFL, flags & ~O_NONBLOCK); 40 | else 41 | return fcntl(socket, F_SETFL, flags | O_NONBLOCK); 42 | } 43 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/glfw/COPYING.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2002-2006 Marcus Geelnard 2 | Copyright (c) 2006-2010 Camilla Berglund 3 | 4 | This software is provided 'as-is', without any express or implied 5 | warranty. In no event will the authors be held liable for any damages 6 | arising from the use of this software. 7 | 8 | Permission is granted to anyone to use this software for any purpose, 9 | including commercial applications, and to alter it and redistribute it 10 | freely, subject to the following restrictions: 11 | 12 | 1. The origin of this software must not be misrepresented; you must not 13 | claim that you wrote the original software. If you use this software 14 | in a product, an acknowledgment in the product documentation would 15 | be appreciated but is not required. 16 | 17 | 2. Altered source versions must be plainly marked as such, and must not 18 | be misrepresented as being the original software. 19 | 20 | 3. This notice may not be removed or altered from any source 21 | distribution. 22 | 23 | -------------------------------------------------------------------------------- /src/app/example/remote_example_vs2013.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl_example", "opengl_example\opengl_example_vs2013.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32 16 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32 17 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/app/example/remote_example_vs2010_without_deps.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl_example_without_deps", "opengl_example\opengl_example_without_deps.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32 16 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32 17 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /src/app/example/remote_example_vs2013_without_deps.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opengl_example_vs2013_without_deps", "opengl_example\opengl_example_vs2013_without_deps.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Debug|Win32.Build.0 = Debug|Win32 16 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.ActiveCfg = Release|Win32 17 | {9CDA7840-B7A5-496D-A527-E95571496D18}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jordi Ros 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.imgui.$(PRODUCT_NAME:rfc1034identifier) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 IMGUI. All rights reserved. 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/app/webby/webby_win32.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | 4 | typedef SOCKET webby_socket_t; 5 | 6 | #if defined(__GNUC__) 7 | #define WB_ALIGN(x) __attribute__((aligned(x))) 8 | #else 9 | #define WB_ALIGN(x) __declspec(align(x)) 10 | #endif 11 | 12 | #define WB_INVALID_SOCKET INVALID_SOCKET 13 | #define snprintf _snprintf 14 | 15 | typedef int webby_socklen_t; 16 | 17 | static int wb_socket_error(void) 18 | { 19 | return WSAGetLastError(); 20 | } 21 | 22 | #if !defined(__GNUC__) 23 | static int strcasecmp(const char *a, const char *b) 24 | { 25 | return _stricmp(a, b); 26 | } 27 | 28 | static int strncasecmp(const char *a, const char *b, size_t len) 29 | { 30 | return _strnicmp(a, b, len); 31 | } 32 | #endif 33 | 34 | static int wb_set_blocking(webby_socket_t socket, int blocking) 35 | { 36 | u_long val = !blocking; 37 | return ioctlsocket(socket, FIONBIO, &val); 38 | } 39 | 40 | static int wb_valid_socket(webby_socket_t socket) 41 | { 42 | return INVALID_SOCKET != socket; 43 | } 44 | 45 | static void wb_close_socket(webby_socket_t socket) 46 | { 47 | closesocket(socket); 48 | } 49 | 50 | static int wb_is_blocking_error(int error) 51 | { 52 | return WSAEWOULDBLOCK == error; 53 | } 54 | -------------------------------------------------------------------------------- /src/app/lz4/LICENSE: -------------------------------------------------------------------------------- 1 | LZ4 Library 2 | Copyright (c) 2011-2016, Yann Collet 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or 13 | other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /src/app/webby/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012, Andreas Fredriksson 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | -------------------------------------------------------------------------------- /src/client/imgui/detector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author mr.doob / http://mrdoob.com/ 4 | */ 5 | 6 | var Detector = { 7 | 8 | canvas: !! window.CanvasRenderingContext2D, 9 | webgl: ( function () { try { var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); } catch( e ) { return false; } } )(), 10 | workers: !! window.Worker, 11 | fileapi: window.File && window.FileReader && window.FileList && window.Blob, 12 | 13 | getWebGLErrorMessage: function () { 14 | 15 | var element = document.createElement( 'div' ); 16 | element.id = 'webgl-error-message'; 17 | element.style.fontFamily = 'monospace'; 18 | element.style.fontSize = '13px'; 19 | element.style.fontWeight = 'normal'; 20 | element.style.textAlign = 'center'; 21 | element.style.background = '#fff'; 22 | element.style.color = '#000'; 23 | element.style.padding = '1.5em'; 24 | element.style.width = '400px'; 25 | element.style.margin = '5em auto 0'; 26 | 27 | if ( ! this.webgl ) { 28 | 29 | element.innerHTML = window.WebGLRenderingContext ? [ 30 | 'Your graphics card does not seem to support WebGL.
', 31 | 'Find out how to get it here.' 32 | ].join( '\n' ) : [ 33 | 'Your browser does not seem to support WebGL.
', 34 | 'Find out how to get it here.' 35 | ].join( '\n' ); 36 | 37 | } 38 | 39 | return element; 40 | 41 | }, 42 | 43 | addGetWebGLMessage: function ( parameters ) { 44 | 45 | var parent, id, element; 46 | 47 | parameters = parameters || {}; 48 | 49 | parent = parameters.parent !== undefined ? parameters.parent : document.body; 50 | id = parameters.id !== undefined ? parameters.id : 'oldie'; 51 | 52 | element = Detector.getWebGLErrorMessage(); 53 | element.id = id; 54 | 55 | parent.appendChild( element ); 56 | 57 | } 58 | 59 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Remote ImGui 2 | ============ 3 | 4 | Remote ImGui is an extension for https://github.com/ocornut/imgui (currently 1.3), sending output and receiving input from a target client in another device running an HTML5/WebGL/WebSockets(v13) application. 5 | You will view all ImGui output from host app, but can also set a bigger virtual canvas and drag windows around. Use Ctrl+LeftMouse on web client to move around it. 6 | Client also sends input from mouse/keyboard, allowing interaction with host app. 7 | 8 | * Using Chrome works out of the box; on Firefox you have to toggle `network.websocket.allowInsecureFromHTTPS` in `about:config` to `true` 9 | 10 | 11 | Setup Host 12 | ========== 13 | 14 | *#include "../imgui_remote.h"* 15 | 16 | - RemoteInit to initialize: *void ImGui::RemoteInit(bind_address, bind_port, vcanvas_width, vcanvas_height);* 17 | - RemoteUpdate on update to pump network code: *void ImGui::RemoteUpdate();* 18 | - RemoteDraw on render to send render data to client: *void ImGui::RemoteDraw(cmd_lists, cmd_lists_count);* 19 | - RemoteShutdown to terminate: *void ImGui::RemoteShutdown();* 20 | - RemoteGetInput to get input from remote: *bool ImGui::RemoteGetInput(input);* 21 | 22 | Check app/example for a working example (ImGui 1.3 included). 23 | 24 | * RemoteInput might conflict with your actual app input, you will have to decide which one is focused and decide what input send to ImGui. 25 | 26 | **Dependencies** 27 | 28 | LZ4 - https://code.google.com/p/lz4/ 29 | 30 | Modified Webby - https://github.com/deplinenoise/webby 31 | 32 | I've used Webby for the WebSocketServer connection. It supports Win32 + Unix, but it should be easy to add other platforms. I included Webby on the repo as I added a function to allow sending WebSocket packets in a single frame. 33 | 34 | 35 | Setup Client 36 | ============ 37 | 38 | Double click index.html, add your host address and click connect. You can also create an autoconnect index.html bookmark with *index.html?host=address* 39 | 40 | **Dependencies** 41 | 42 | ThreeJS - *https://github.com/mrdoob/three.js* 43 | 44 | Dat.Gui - *https://github.com/dataarts/dat.gui* 45 | 46 | Modified LZ4.js - *https://github.com/ukyo/lz4.js* 47 | 48 | 49 | ToDo 50 | ============ 51 | 52 | - Web client tested on iOS / Android + WebGL, but input is not handled 53 | -------------------------------------------------------------------------------- /src/client/imgui/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | overflow : hidden; 3 | padding : 0; 4 | margin : 0; 5 | 6 | color : #222; 7 | background-color: #333; 8 | } 9 | .form-style-6{ 10 | font: 100% Arial, Helvetica, sans-serif; 11 | max-width: 300px; 12 | margin: 10px auto; 13 | padding: 16px; 14 | background: #F7F7F7; 15 | } 16 | .form-style-6 h1{ 17 | background: #409FC1; 18 | padding: 15px 0; 19 | font-size: 100%; 20 | font-weight: 100; 21 | text-align: center; 22 | color: #fff; 23 | margin: -16px -16px 16px -16px; 24 | } 25 | .form-style-6 input[type="text"], 26 | .form-style-6 input[type="date"], 27 | .form-style-6 input[type="datetime"], 28 | .form-style-6 input[type="email"], 29 | .form-style-6 input[type="number"], 30 | .form-style-6 input[type="search"], 31 | .form-style-6 input[type="time"], 32 | .form-style-6 input[type="url"], 33 | .form-style-6 textarea, 34 | .form-style-6 select 35 | { 36 | -webkit-transition: all 0.30s ease-in-out; 37 | -moz-transition: all 0.30s ease-in-out; 38 | -ms-transition: all 0.30s ease-in-out; 39 | -o-transition: all 0.30s ease-in-out; 40 | outline: none; 41 | box-sizing: border-box; 42 | -webkit-box-sizing: border-box; 43 | -moz-box-sizing: border-box; 44 | width: 100%; 45 | background: #fff; 46 | margin-bottom: 4%; 47 | border: 1px solid #ccc; 48 | padding: 2%; 49 | color: #555; 50 | text-align: center; 51 | font: 100% Arial, Helvetica, sans-serif; 52 | } 53 | .form-style-6 input[type="text"]:focus, 54 | .form-style-6 input[type="date"]:focus, 55 | .form-style-6 input[type="datetime"]:focus, 56 | .form-style-6 input[type="email"]:focus, 57 | .form-style-6 input[type="number"]:focus, 58 | .form-style-6 input[type="search"]:focus, 59 | .form-style-6 input[type="time"]:focus, 60 | .form-style-6 input[type="url"]:focus, 61 | .form-style-6 textarea:focus, 62 | .form-style-6 select:focus 63 | { 64 | box-shadow: 0 0 5px #409FC1; 65 | padding: 3%; 66 | border: 1px solid #409FC1; 67 | } 68 | .button{ 69 | box-sizing: border-box; 70 | -webkit-box-sizing: border-box; 71 | -moz-box-sizing: border-box; 72 | width: 100%; 73 | padding: 3%; 74 | background: #409FC1; 75 | border-bottom: 2px solid #3080AF; 76 | border-top-style: none; 77 | border-right-style: none; 78 | border-left-style: none; 79 | color: #fff; 80 | } 81 | .form-style-6 input[type="submit"]:hover, 82 | .form-style-6 input[type="button"]:hover{ 83 | background: #2EBC99; 84 | } 85 | #imgui { 86 | margin-top: 10px; 87 | color: #444; 88 | font: 75% Arial, Helvetica, sans-serif; 89 | } -------------------------------------------------------------------------------- /src/client/imgui.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Remote ImGui 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 24 | 25 | 26 | 27 |
28 |

Remote ImGui

29 | 30 | 31 |

32 | Remote ImGui 33 |
34 | 35 |
36 | 37 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /src/app/lz4/lz4frame_static.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 auto-framing library 3 | Header File for static linking only 4 | Copyright (C) 2011-2015, Yann Collet. 5 | 6 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other materials provided with the 17 | distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | You can contact the author at : 32 | - LZ4 source repository : http://code.google.com/p/lz4/ 33 | - LZ4 source mirror : https://github.com/Cyan4973/lz4 34 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 35 | */ 36 | 37 | #pragma once 38 | 39 | #if defined (__cplusplus) 40 | extern "C" { 41 | #endif 42 | 43 | /* lz4frame_static.h should be used solely in the context of static linking. 44 | * */ 45 | 46 | 47 | /************************************** 48 | * Error management 49 | * ************************************/ 50 | #define LZ4F_LIST_ERRORS(ITEM) \ 51 | ITEM(OK_NoError) ITEM(ERROR_GENERIC) \ 52 | ITEM(ERROR_maxBlockSize_invalid) ITEM(ERROR_blockMode_invalid) ITEM(ERROR_contentChecksumFlag_invalid) \ 53 | ITEM(ERROR_compressionLevel_invalid) \ 54 | ITEM(ERROR_allocation_failed) \ 55 | ITEM(ERROR_srcSize_tooLarge) ITEM(ERROR_dstMaxSize_tooSmall) \ 56 | ITEM(ERROR_decompressionFailed) \ 57 | ITEM(ERROR_checksum_invalid) \ 58 | ITEM(ERROR_maxCode) 59 | 60 | #define LZ4F_GENERATE_ENUM(ENUM) ENUM, 61 | typedef enum { LZ4F_LIST_ERRORS(LZ4F_GENERATE_ENUM) } LZ4F_errorCodes; /* enum is exposed, to handle specific errors; compare function result to -enum value */ 62 | 63 | 64 | /************************************** 65 | Includes 66 | **************************************/ 67 | #include "lz4frame.h" 68 | 69 | 70 | #if defined (__cplusplus) 71 | } 72 | #endif 73 | -------------------------------------------------------------------------------- /src/app/webby/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Webby - A simple web server for game debugging # 3 | 4 | Webby is a web server intended for debugging tools inside a game or other 5 | program with a continously running main loop. It's intended to be used when 6 | all you need is something tiny and performance isn't a key concern. 7 | 8 | ## Features ## 9 | 10 | - No dynamic memory allocations -- server memory is completely fixed 11 | - No threading, all I/O and serving happens on the calling thread 12 | - Supports socket keep-alives 13 | - Supports the 100-Continue scheme for file uploading 14 | - Basic support for WebSockets is available. 15 | 16 | Because request/response I/O is synchronous on the calling thread, performance 17 | will suffer when you are serving data. For the use-cases Webby is intended for, 18 | this is fine. You can still run Webby in a background thread at your 19 | discretion if this is a problem. 20 | 21 | ## Usage ## 22 | 23 | - Fill in a `WebbyServerConfig` structure 24 | - Compute the memory requirements by calling `WebbyServerMemoryNeeded()` 25 | - Allocate memory (or just use a static char array..) 26 | - Initialize the server by calling `WebbyServerInit()` 27 | - Every game frame, call `WebbyServerUpdate()` 28 | - Handle requests in your dispatch function 29 | - When it's time to shut down, call `WebbyServerShutdown()` 30 | 31 | ## WebSocket Usage ## 32 | 33 | - Provide the `WEBBY_SERVER_WEBSOCKETS` flag at init time 34 | - In your `ws_connect` handler, decide to allow the upgrade request. 35 | - When the connection is established, your `ws_connected` handler is called. At this point, you can start sending WebSocket frames over the connection (and you can get incoming frames as well). 36 | - As frames come in, your `ws_frame` handler will be called. Webby doesn't try to merge frames together when the data is split into fragments, so you can be getting one binary/text frame followed by any number of continuation frames. It's up to your handler to make sense of the data and build a buffer as appropriate. The rationale is that otherwise Webby would need a lot more buffer space. To read the frame data, look at the payload size and then call `WebbyRead` to get at the data. Be careful to not read more than what is stated, or you will screw up the protocol. 37 | - To send WebSocket data, call `WebbyBeginSocketFrame`, passing in the type of frame (typically `WEBBY_WS_OP_TEXT_FRAME` or `WEBBY_WS_OP_BINARY_FRAME`). Then write an arbitrary amount of data using `WebbyWrite`. When you're done, call `WebbyEndSocketFrame`. Webby currently emits one WebSocket (continuation) frame for each `WebbyWrite` call (again, to reduce buffering overhead), so try to write big chunks if you can. 38 | - When a connection is closed, you will get a call to your `ws_closed` handler. 39 | 40 | ## Request handling ## 41 | 42 | When you configure the server, you give it a function pointer to your 43 | dispatcher. The dispatcher is called by Webby when a request has been fully 44 | read into memory and is ready for processing. The socket the request came in on 45 | has then been switched to blocking mode, and you're free to read any request 46 | data using `WebbyRead()` (if present, check `content_length`) and then write 47 | your response. 48 | 49 | There are two ways to generate a response; explicit size or chunked. 50 | 51 | ### When you know the size of the data ### 52 | 53 | When you know in advance how big the response is going to be, you should pass 54 | that size in bytes to `WebbyBeginResponse()` (it will be sent as the 55 | Content-Length header). You then call `WebbyWrite()` to push that data out, and 56 | finally `WebbyEndResponse()` to finalize the response and prepare the socket 57 | for a new request. 58 | 59 | ### When the response size is dynamic ### 60 | 61 | Sometimes you want to generate an arbitrary amount of text in the response, and 62 | you don't know how much that will be. Rather than buffering everything in RAM, 63 | you can use chunked encoding. First call `WebbyBeginResponse()` as normal, but 64 | pass it -1 for the content length. This triggers sending the 65 | `Transfer-Encoding: chunked` header. You then call `WebbyWrite()` or 66 | `WebbyPrintf()` as desired until the response is complete. When you're done, 67 | call `WebbyEndResponse()` to finish up. 68 | 69 | ## Limitations ## 70 | 71 | - There is not much error checking. 72 | 73 | ## Author ## 74 | 75 | Webby was written by Andreas Fredriksson (@deplinenoise on Twitter). 76 | 77 | ## License ## 78 | 79 | Webby is available under the BSD license. See the file `LICENSE`. 80 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/opengl_example_vs2013.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {9CDA7840-B7A5-496D-A527-E95571496D18} 15 | opengl_example 16 | opengl_example_vs2013 17 | 18 | 19 | 20 | Application 21 | true 22 | MultiByte 23 | v120 24 | 25 | 26 | Application 27 | false 28 | true 29 | MultiByte 30 | v120 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Level3 46 | Disabled 47 | $(ProjectDir)\glfw\include;%(AdditionalIncludeDirectories) 48 | 49 | 50 | true 51 | $(ProjectDir)\glfw\lib-msvc100;%(AdditionalLibraryDirectories) 52 | opengl32.lib;imm32.lib;glfw3.lib;ws2_32.lib;%(AdditionalDependencies) 53 | NotSet 54 | 55 | 56 | 57 | 58 | Level3 59 | MaxSpeed 60 | true 61 | true 62 | $(ProjectDir)\glfw\include;%(AdditionalIncludeDirectories) 63 | 64 | 65 | true 66 | true 67 | true 68 | $(ProjectDir)\glfw\lib-msvc100;%(AdditionalLibraryDirectories) 69 | opengl32.lib;imm32.lib;glfw3.lib;ws2_32.lib;%(AdditionalDependencies) 70 | NotSet 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /src/app/imgui_remote_webby.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Remote ImGui https://github.com/JordiRos/remoteimgui 3 | // Uses 4 | // ImGui https://github.com/ocornut/imgui 1.3 5 | // Webby https://github.com/deplinenoise/webby 6 | // LZ4 https://code.google.com/p/lz4/ 7 | //----------------------------------------------------------------------------- 8 | 9 | #include "webby/webby.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _WIN32 17 | #include 18 | #endif 19 | 20 | #ifdef __APPLE__ 21 | #include 22 | #endif 23 | 24 | struct IWebSocketServer; 25 | 26 | IWebSocketServer *s_WebSocketServer; 27 | 28 | static void onLog( const char* text ); 29 | static int onDispatch( struct WebbyConnection *connection ); 30 | static int onConnect( struct WebbyConnection *connection ); 31 | static void onConnected( struct WebbyConnection *connection ); 32 | static void onDisconnected( struct WebbyConnection *connection ); 33 | static int onFrame( struct WebbyConnection *connection, const struct WebbyWsFrame *frame ); 34 | 35 | struct IWebSocketServer 36 | { 37 | enum OpCode // based on websocket connection opcodes 38 | { 39 | Continuation = 0, 40 | Text = 1, 41 | Binary = 2, 42 | Disconnect = 8, 43 | Ping = 9, 44 | Pong = 10, 45 | }; 46 | 47 | void *Memory; 48 | int MemorySize; 49 | struct WebbyServer *Server; 50 | struct WebbyServerConfig ServerConfig; 51 | struct WebbyConnection *Client; 52 | 53 | int Init( const char *local_address, int local_port ) 54 | { 55 | s_WebSocketServer = this; 56 | 57 | #if defined(_WIN32) 58 | { 59 | WORD wsa_version = MAKEWORD( 2, 2 ); 60 | WSADATA wsa_data; 61 | if ( 0 != WSAStartup( wsa_version, &wsa_data ) ) 62 | return -1; 63 | } 64 | #endif 65 | 66 | memset( &ServerConfig, 0, sizeof ServerConfig ); 67 | ServerConfig.bind_address = local_address; 68 | ServerConfig.listening_port = (unsigned short) ( local_port ); 69 | ServerConfig.flags = WEBBY_SERVER_WEBSOCKETS; 70 | ServerConfig.connection_max = 1; 71 | ServerConfig.request_buffer_size = 2048; 72 | ServerConfig.io_buffer_size = 8192; 73 | ServerConfig.dispatch = &onDispatch; 74 | ServerConfig.log = &onLog; 75 | ServerConfig.ws_connect = &onConnect; 76 | ServerConfig.ws_connected = &onConnected; 77 | ServerConfig.ws_closed = &onDisconnected; 78 | ServerConfig.ws_frame = &onFrame; 79 | 80 | MemorySize = WebbyServerMemoryNeeded( &ServerConfig ); 81 | Memory = malloc( MemorySize ); 82 | Server = WebbyServerInit( &ServerConfig, Memory, MemorySize ); 83 | Client = NULL; 84 | if ( !Server ) 85 | return -2; 86 | 87 | return 0; 88 | } 89 | 90 | void Update() 91 | { 92 | if ( Server ) 93 | WebbyServerUpdate( Server ); 94 | } 95 | 96 | void Shutdown() 97 | { 98 | if ( Server ) 99 | { 100 | WebbyServerShutdown( Server ); 101 | free( Memory ); 102 | } 103 | 104 | #if defined(_WIN32) 105 | WSACleanup(); 106 | #endif 107 | } 108 | 109 | void WsOnConnected( struct WebbyConnection *connection ) 110 | { 111 | Client = connection; 112 | } 113 | 114 | void WsOnDisconnected( struct WebbyConnection * /*connection*/ ) 115 | { 116 | Client = NULL; 117 | OnMessage( Disconnect, NULL, 0 ); 118 | } 119 | 120 | int WsOnFrame( struct WebbyConnection *connection, const struct WebbyWsFrame *frame ) 121 | { 122 | // printf("WebSocket frame incoming\n"); 123 | // printf(" Frame OpCode: %d\n", frame->opcode); 124 | // printf(" Final frame?: %s\n", (frame->flags & WEBBY_WSF_FIN) ? "yes" : "no"); 125 | // printf(" Masked? : %s\n", (frame->flags & WEBBY_WSF_MASKED) ? "yes" : "no"); 126 | // printf(" Data Length : %d\n", (int) frame->payload_length); 127 | 128 | Vector buffer( frame->payload_length + 1 ); 129 | WebbyRead( connection, &buffer[ 0 ], frame->payload_length ); 130 | buffer[ frame->payload_length ] = 0; 131 | // if(!strstr((char*)&buffer[0],"ImMouseMove")) 132 | // printf(" Data : %s\n", &buffer[0]); 133 | 134 | OnMessage( (OpCode) frame->opcode, &buffer[ 0 ], frame->payload_length ); 135 | 136 | return 0; 137 | } 138 | 139 | virtual void OnMessage( OpCode /*opcode*/, const void * /*data*/, int /*size*/ ) { } 140 | virtual void OnError() { } 141 | 142 | virtual void SendText( const void *data, int size ) 143 | { 144 | if ( Client ) 145 | { 146 | WebbySendFrame( Client, WEBBY_WS_OP_TEXT_FRAME, data, size ); 147 | } 148 | } 149 | 150 | virtual void SendBinary( const void *data, int size ) 151 | { 152 | if ( Client ) 153 | { 154 | WebbySendFrame( Client, WEBBY_WS_OP_BINARY_FRAME, data, size ); 155 | } 156 | } 157 | }; 158 | 159 | 160 | static void onLog( const char* /*text*/ ) 161 | { 162 | //printf("[WsOnLog] %s\n", text); 163 | } 164 | 165 | static int onDispatch( struct WebbyConnection * /*connection*/ ) 166 | { 167 | //printf("[WsOnDispatch] %s\n", connection->request.uri); 168 | return 1; 169 | } 170 | 171 | static int onConnect( struct WebbyConnection * /*connection*/ ) 172 | { 173 | //printf("[WsOnConnect] %s\n", connection->request.uri); 174 | return 0; 175 | } 176 | 177 | static void onConnected( struct WebbyConnection *connection ) 178 | { 179 | //printf("[WsOnConnected]\n"); 180 | s_WebSocketServer->WsOnConnected( connection ); 181 | } 182 | 183 | static void onDisconnected( struct WebbyConnection *connection ) 184 | { 185 | //printf("[WsOnDisconnected]\n"); 186 | s_WebSocketServer->WsOnDisconnected( connection ); 187 | } 188 | 189 | static int onFrame( struct WebbyConnection *connection, const struct WebbyWsFrame *frame ) 190 | { 191 | //printf("[WsOnFrame]\n"); 192 | return s_WebSocketServer->WsOnFrame( connection, frame ); 193 | } 194 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/opengl_example_without_deps.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {9CDA7840-B7A5-496D-A527-E95571496D18} 15 | opengl_example 16 | opengl_example_vs2010_without_deps 17 | 18 | 19 | 20 | Application 21 | true 22 | MultiByte 23 | 24 | 25 | Application 26 | false 27 | true 28 | MultiByte 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | $(ProjectDir)$(Configuration)\ 42 | $(ProjectDir)$(Configuration)\ 43 | 44 | 45 | $(ProjectDir)$(Configuration)\ 46 | $(ProjectDir)$(Configuration)\ 47 | 48 | 49 | 50 | Level3 51 | Disabled 52 | 53 | 54 | 55 | 56 | true 57 | 58 | 59 | opengl32.lib;%(AdditionalDependencies) 60 | Windows 61 | 62 | 63 | 64 | 65 | 66 | 67 | Level3 68 | MaxSpeed 69 | true 70 | true 71 | 72 | 73 | 74 | 75 | true 76 | true 77 | true 78 | 79 | 80 | opengl32.lib;%(AdditionalDependencies) 81 | Windows 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/app/lz4/xxhash.h: -------------------------------------------------------------------------------- 1 | /* 2 | xxHash - Extremely Fast Hash algorithm 3 | Header File 4 | Copyright (C) 2012-2014, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - xxHash source repository : http://code.google.com/p/xxhash/ 32 | */ 33 | 34 | /* Notice extracted from xxHash homepage : 35 | 36 | xxHash is an extremely fast Hash algorithm, running at RAM speed limits. 37 | It also successfully passes all tests from the SMHasher suite. 38 | 39 | Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz) 40 | 41 | Name Speed Q.Score Author 42 | xxHash 5.4 GB/s 10 43 | CrapWow 3.2 GB/s 2 Andrew 44 | MumurHash 3a 2.7 GB/s 10 Austin Appleby 45 | SpookyHash 2.0 GB/s 10 Bob Jenkins 46 | SBox 1.4 GB/s 9 Bret Mulvey 47 | Lookup3 1.2 GB/s 9 Bob Jenkins 48 | SuperFastHash 1.2 GB/s 1 Paul Hsieh 49 | CityHash64 1.05 GB/s 10 Pike & Alakuijala 50 | FNV 0.55 GB/s 5 Fowler, Noll, Vo 51 | CRC32 0.43 GB/s 9 52 | MD5-32 0.33 GB/s 10 Ronald L. Rivest 53 | SHA1-32 0.28 GB/s 10 54 | 55 | Q.Score is a measure of quality of the hash function. 56 | It depends on successfully passing SMHasher test set. 57 | 10 is a perfect score. 58 | */ 59 | 60 | #pragma once 61 | 62 | #if defined (__cplusplus) 63 | extern "C" { 64 | #endif 65 | 66 | 67 | /***************************** 68 | Includes 69 | *****************************/ 70 | #include /* size_t */ 71 | 72 | 73 | /***************************** 74 | Type 75 | *****************************/ 76 | typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode; 77 | 78 | 79 | 80 | /***************************** 81 | Simple Hash Functions 82 | *****************************/ 83 | 84 | unsigned int XXH32 (const void* input, size_t length, unsigned seed); 85 | unsigned long long XXH64 (const void* input, size_t length, unsigned long long seed); 86 | 87 | /* 88 | XXH32() : 89 | Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input". 90 | The memory between input & input+length must be valid (allocated and read-accessible). 91 | "seed" can be used to alter the result predictably. 92 | This function successfully passes all SMHasher tests. 93 | Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s 94 | XXH64() : 95 | Calculate the 64-bits hash of sequence of length "len" stored at memory address "input". 96 | */ 97 | 98 | 99 | 100 | /***************************** 101 | Advanced Hash Functions 102 | *****************************/ 103 | typedef struct { long long ll[ 6]; } XXH32_state_t; 104 | typedef struct { long long ll[11]; } XXH64_state_t; 105 | 106 | /* 107 | These structures allow static allocation of XXH states. 108 | States must then be initialized using XXHnn_reset() before first use. 109 | 110 | If you prefer dynamic allocation, please refer to functions below. 111 | */ 112 | 113 | XXH32_state_t* XXH32_createState(void); 114 | XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr); 115 | 116 | XXH64_state_t* XXH64_createState(void); 117 | XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr); 118 | 119 | /* 120 | These functions create and release memory for XXH state. 121 | States must then be initialized using XXHnn_reset() before first use. 122 | */ 123 | 124 | 125 | XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned seed); 126 | XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length); 127 | unsigned int XXH32_digest (const XXH32_state_t* statePtr); 128 | 129 | XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed); 130 | XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length); 131 | unsigned long long XXH64_digest (const XXH64_state_t* statePtr); 132 | 133 | /* 134 | These functions calculate the xxHash of an input provided in multiple smaller packets, 135 | as opposed to an input provided as a single block. 136 | 137 | XXH state space must first be allocated, using either static or dynamic method provided above. 138 | 139 | Start a new hash by initializing state with a seed, using XXHnn_reset(). 140 | 141 | Then, feed the hash state by calling XXHnn_update() as many times as necessary. 142 | Obviously, input must be valid, meaning allocated and read accessible. 143 | The function returns an error code, with 0 meaning OK, and any other value meaning there is an error. 144 | 145 | Finally, you can produce a hash anytime, by using XXHnn_digest(). 146 | This function returns the final nn-bits hash. 147 | You can nonetheless continue feeding the hash state with more input, 148 | and therefore get some new hashes, by calling again XXHnn_digest(). 149 | 150 | When you are done, don't forget to free XXH state space, using typically XXHnn_freeState(). 151 | */ 152 | 153 | 154 | #if defined (__cplusplus) 155 | } 156 | #endif 157 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/glfw/include/GLFW/glfw3native.h: -------------------------------------------------------------------------------- 1 | /************************************************************************* 2 | * GLFW 3.0 - www.glfw.org 3 | * A library for OpenGL, window and input 4 | *------------------------------------------------------------------------ 5 | * Copyright (c) 2002-2006 Marcus Geelnard 6 | * Copyright (c) 2006-2010 Camilla Berglund 7 | * 8 | * This software is provided 'as-is', without any express or implied 9 | * warranty. In no event will the authors be held liable for any damages 10 | * arising from the use of this software. 11 | * 12 | * Permission is granted to anyone to use this software for any purpose, 13 | * including commercial applications, and to alter it and redistribute it 14 | * freely, subject to the following restrictions: 15 | * 16 | * 1. The origin of this software must not be misrepresented; you must not 17 | * claim that you wrote the original software. If you use this software 18 | * in a product, an acknowledgment in the product documentation would 19 | * be appreciated but is not required. 20 | * 21 | * 2. Altered source versions must be plainly marked as such, and must not 22 | * be misrepresented as being the original software. 23 | * 24 | * 3. This notice may not be removed or altered from any source 25 | * distribution. 26 | * 27 | *************************************************************************/ 28 | 29 | #ifndef _glfw3_native_h_ 30 | #define _glfw3_native_h_ 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | 37 | /************************************************************************* 38 | * Doxygen documentation 39 | *************************************************************************/ 40 | 41 | /*! @defgroup native Native access 42 | * 43 | * **By using the native API, you assert that you know what you're doing and 44 | * how to fix problems caused by using it. If you don't, you shouldn't be 45 | * using it.** 46 | * 47 | * Before the inclusion of @ref glfw3native.h, you must define exactly one 48 | * window API macro and exactly one context API macro. Failure to do this 49 | * will cause a compile-time error. 50 | * 51 | * The available window API macros are: 52 | * * `GLFW_EXPOSE_NATIVE_WIN32` 53 | * * `GLFW_EXPOSE_NATIVE_COCOA` 54 | * * `GLFW_EXPOSE_NATIVE_X11` 55 | * 56 | * The available context API macros are: 57 | * * `GLFW_EXPOSE_NATIVE_WGL` 58 | * * `GLFW_EXPOSE_NATIVE_NSGL` 59 | * * `GLFW_EXPOSE_NATIVE_GLX` 60 | * * `GLFW_EXPOSE_NATIVE_EGL` 61 | * 62 | * These macros select which of the native access functions that are declared 63 | * and which platform-specific headers to include. It is then up your (by 64 | * definition platform-specific) code to handle which of these should be 65 | * defined. 66 | */ 67 | 68 | 69 | /************************************************************************* 70 | * System headers and types 71 | *************************************************************************/ 72 | 73 | #if defined(GLFW_EXPOSE_NATIVE_WIN32) 74 | #include 75 | #elif defined(GLFW_EXPOSE_NATIVE_COCOA) 76 | #if defined(__OBJC__) 77 | #import 78 | #else 79 | typedef void* id; 80 | #endif 81 | #elif defined(GLFW_EXPOSE_NATIVE_X11) 82 | #include 83 | #else 84 | #error "No window API specified" 85 | #endif 86 | 87 | #if defined(GLFW_EXPOSE_NATIVE_WGL) 88 | /* WGL is declared by windows.h */ 89 | #elif defined(GLFW_EXPOSE_NATIVE_NSGL) 90 | /* NSGL is declared by Cocoa.h */ 91 | #elif defined(GLFW_EXPOSE_NATIVE_GLX) 92 | #include 93 | #elif defined(GLFW_EXPOSE_NATIVE_EGL) 94 | #include 95 | #else 96 | #error "No context API specified" 97 | #endif 98 | 99 | 100 | /************************************************************************* 101 | * Functions 102 | *************************************************************************/ 103 | 104 | #if defined(GLFW_EXPOSE_NATIVE_WIN32) 105 | /*! @brief Returns the `HWND` of the specified window. 106 | * @return The `HWND` of the specified window. 107 | * @ingroup native 108 | */ 109 | GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window); 110 | #endif 111 | 112 | #if defined(GLFW_EXPOSE_NATIVE_WGL) 113 | /*! @brief Returns the `HGLRC` of the specified window. 114 | * @return The `HGLRC` of the specified window. 115 | * @ingroup native 116 | */ 117 | GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window); 118 | #endif 119 | 120 | #if defined(GLFW_EXPOSE_NATIVE_COCOA) 121 | /*! @brief Returns the `NSWindow` of the specified window. 122 | * @return The `NSWindow` of the specified window. 123 | * @ingroup native 124 | */ 125 | GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window); 126 | #endif 127 | 128 | #if defined(GLFW_EXPOSE_NATIVE_NSGL) 129 | /*! @brief Returns the `NSOpenGLContext` of the specified window. 130 | * @return The `NSOpenGLContext` of the specified window. 131 | * @ingroup native 132 | */ 133 | GLFWAPI id glfwGetNSGLContext(GLFWwindow* window); 134 | #endif 135 | 136 | #if defined(GLFW_EXPOSE_NATIVE_X11) 137 | /*! @brief Returns the `Display` used by GLFW. 138 | * @return The `Display` used by GLFW. 139 | * @ingroup native 140 | */ 141 | GLFWAPI Display* glfwGetX11Display(void); 142 | /*! @brief Returns the `Window` of the specified window. 143 | * @return The `Window` of the specified window. 144 | * @ingroup native 145 | */ 146 | GLFWAPI Window glfwGetX11Window(GLFWwindow* window); 147 | #endif 148 | 149 | #if defined(GLFW_EXPOSE_NATIVE_GLX) 150 | /*! @brief Returns the `GLXContext` of the specified window. 151 | * @return The `GLXContext` of the specified window. 152 | * @ingroup native 153 | */ 154 | GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window); 155 | #endif 156 | 157 | #if defined(GLFW_EXPOSE_NATIVE_EGL) 158 | /*! @brief Returns the `EGLDisplay` used by GLFW. 159 | * @return The `EGLDisplay` used by GLFW. 160 | * @ingroup native 161 | */ 162 | GLFWAPI EGLDisplay glfwGetEGLDisplay(void); 163 | /*! @brief Returns the `EGLContext` of the specified window. 164 | * @return The `EGLContext` of the specified window. 165 | * @ingroup native 166 | */ 167 | GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window); 168 | /*! @brief Returns the `EGLSurface` of the specified window. 169 | * @return The `EGLSurface` of the specified window. 170 | * @ingroup native 171 | */ 172 | GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); 173 | #endif 174 | 175 | #ifdef __cplusplus 176 | } 177 | #endif 178 | 179 | #endif /* _glfw3_native_h_ */ 180 | 181 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/opengl_example_vs2013_without_deps.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {9CDA7840-B7A5-496D-A527-E95571496D18} 15 | opengl_example 16 | opengl_example_vs2013_without_deps 17 | 18 | 19 | 20 | Application 21 | true 22 | MultiByte 23 | v120 24 | 25 | 26 | Application 27 | false 28 | true 29 | MultiByte 30 | v120 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | $(ProjectDir)$(Configuration)\ 44 | $(ProjectDir)$(Configuration)\ 45 | 46 | 47 | $(ProjectDir)$(Configuration)\ 48 | $(ProjectDir)$(Configuration)\ 49 | 50 | 51 | 52 | Level3 53 | Disabled 54 | 55 | 56 | 57 | 58 | true 59 | 60 | 61 | opengl32.lib;%(AdditionalDependencies) 62 | Windows 63 | 64 | 65 | 66 | 67 | 68 | 69 | Level3 70 | MaxSpeed 71 | true 72 | true 73 | 74 | 75 | 76 | 77 | true 78 | true 79 | true 80 | 81 | 82 | opengl32.lib;%(AdditionalDependencies) 83 | Windows 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /src/app/webby/webby.h: -------------------------------------------------------------------------------- 1 | #ifndef WEBBY_H 2 | #define WEBBY_H 3 | 4 | #include 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /* 11 | Webby - A tiny little web server for game debugging. 12 | */ 13 | 14 | /* Server initialization flags */ 15 | enum 16 | { 17 | WEBBY_SERVER_LOG_DEBUG = 1 << 0, 18 | WEBBY_SERVER_WEBSOCKETS = 1 << 1 19 | }; 20 | 21 | /* Hard limits */ 22 | enum 23 | { 24 | WEBBY_MAX_HEADERS = 64 25 | }; 26 | 27 | struct WebbyServer; 28 | 29 | /* A HTTP header */ 30 | struct WebbyHeader 31 | { 32 | const char *name; 33 | const char *value; 34 | }; 35 | 36 | /* A HTTP request. */ 37 | struct WebbyRequest 38 | { 39 | /* The method of the request, e.g. "GET", "POST" and so on */ 40 | const char *method; 41 | /* The URI that was used. */ 42 | const char *uri; 43 | /* The HTTP version that used. */ 44 | const char *http_version; 45 | /* The query parameters passed in the URL, or NULL if none were passed. */ 46 | const char *query_params; 47 | /* The number of bytes of request body that are available via WebbyRead() */ 48 | int content_length; 49 | /* The number of headers */ 50 | int header_count; 51 | /* Request headers */ 52 | struct WebbyHeader headers[WEBBY_MAX_HEADERS]; 53 | }; 54 | 55 | /* Connection state, as published to the serving callback. */ 56 | struct WebbyConnection 57 | { 58 | /* The request being served. Read-only. */ 59 | struct WebbyRequest request; 60 | 61 | /* User data. Read-write. Webby doesn't care about this. */ 62 | void *user_data; 63 | }; 64 | 65 | enum 66 | { 67 | WEBBY_WS_OP_CONTINUATION = 0, 68 | WEBBY_WS_OP_TEXT_FRAME = 1, 69 | WEBBY_WS_OP_BINARY_FRAME = 2, 70 | WEBBY_WS_OP_CLOSE = 8, 71 | WEBBY_WS_OP_PING = 9, 72 | WEBBY_WS_OP_PONG = 10 73 | }; 74 | 75 | enum 76 | { 77 | WEBBY_WSF_FIN = 1 << 0, 78 | WEBBY_WSF_MASKED = 1 << 1 79 | }; 80 | 81 | struct WebbyWsFrame 82 | { 83 | unsigned char flags; 84 | unsigned char opcode; 85 | unsigned char header_size; 86 | unsigned char padding_; 87 | unsigned char mask_key[4]; 88 | int payload_length; 89 | }; 90 | 91 | /* Configuration data required for starting a server. */ 92 | struct WebbyServerConfig 93 | { 94 | /* The bind address. Must be a textual IP address. */ 95 | const char *bind_address; 96 | 97 | /* The port to listen to. */ 98 | unsigned short listening_port; 99 | 100 | /* Flags. Right now WEBBY_SERVER_LOG_DEBUG is the only valid flag. */ 101 | unsigned int flags; 102 | 103 | /* Maximum number of simultaneous connections. */ 104 | int connection_max; 105 | 106 | /* The size of the request buffer. This must be big enough to contain all 107 | * headers and the request line sent by the client. 2-4k is a good size for 108 | * this buffer. */ 109 | int request_buffer_size; 110 | 111 | /* The size of the I/O buffer, used when writing the reponse. 4k is a good 112 | * choice for this buffer.*/ 113 | int io_buffer_size; 114 | 115 | /* Optional callback function that receives debug log text (without 116 | * newlines). */ 117 | void (*log)(const char *msg); 118 | 119 | /* Request dispatcher function. This function is called when the request 120 | * structure is ready. 121 | * 122 | * If you decide to handle the request, call WebbyBeginResponse(), 123 | * WebbyWrite() and WebbyEndResponse() and then return 0. Otherwise, return a 124 | * non-zero value to have Webby send back a 404 response. 125 | */ 126 | int (*dispatch)(struct WebbyConnection *connection); 127 | 128 | /* 129 | * WebSocket connection dispatcher. Called when an incoming request wants to 130 | * update to a WebSocket connection. 131 | * 132 | * Return 0 to allow the connection. 133 | * Return 1 to ignore the connection. 134 | */ 135 | int (*ws_connect)(struct WebbyConnection *connection); 136 | 137 | /* 138 | * Called when a WebSocket connection has been established. 139 | */ 140 | void (*ws_connected)(struct WebbyConnection *connection); 141 | 142 | /* 143 | * Called when a WebSocket connection has been closed. 144 | */ 145 | void (*ws_closed)(struct WebbyConnection *connection); 146 | 147 | /* 148 | * Called when a WebSocket data frame is incoming. 149 | * 150 | * Call WebbyRead() to read the payload data. 151 | * 152 | * Return non-zero to close the connection. 153 | */ 154 | int (*ws_frame)(struct WebbyConnection *connection, const struct WebbyWsFrame *frame); 155 | }; 156 | 157 | /* Returns the amount of memory needed for the specified config. */ 158 | int 159 | WebbyServerMemoryNeeded(const struct WebbyServerConfig *config); 160 | 161 | /* Initialize a server in the specified memory space. Size must be big enough, 162 | * as determined by WebbyServerMemoryNeeded(). The memory block must be aligned 163 | * to at least 8 bytes. 164 | */ 165 | struct WebbyServer* 166 | WebbyServerInit(struct WebbyServerConfig *config, void *memory, size_t memory_size); 167 | 168 | /* Update the server. Call frequently (at least once per frame). */ 169 | void 170 | WebbyServerUpdate(struct WebbyServer *srv); 171 | 172 | /* Shutdown the server and close all sockets. */ 173 | void 174 | WebbyServerShutdown(struct WebbyServer *srv); 175 | 176 | /* 177 | * Begin a response. 178 | * 179 | * status_code - The HTTP status code to send. Normally 200 180 | * content_length - size in bytes you intend to write, or -1 for chunked encoding 181 | * headers - Array of HTTP headers to transmit (can be NULL if header_count ==0) 182 | * header_count - Number of headers in the array. 183 | * 184 | * Returns zero on success, non-zero on error. 185 | */ 186 | int 187 | WebbyBeginResponse( 188 | struct WebbyConnection *conn, 189 | int status_code, 190 | int content_length, 191 | const struct WebbyHeader headers[], 192 | int header_count); 193 | 194 | /* 195 | * Finish a response. 196 | * 197 | * When you're done writing the response body, call this function. It makes 198 | * sure that chunked encoding is terminated correctly and that the connection 199 | * is set up for reuse. 200 | */ 201 | void 202 | WebbyEndResponse(struct WebbyConnection *conn); 203 | 204 | /* 205 | * Read data from the request body. Only read what the client has provided (via 206 | * the content_length) parameter, or you will end up blocking forever. 207 | */ 208 | int WebbyRead(struct WebbyConnection *conn, void *ptr, size_t len); 209 | 210 | /* 211 | * Write response data to the connection. If you're not using chunked encoding, 212 | * be careful not to send more than the specified content length. You can call 213 | * this function multiple times as long as the total number of bytes matches up 214 | * with the content length. 215 | */ 216 | int WebbyWrite(struct WebbyConnection *conn, const void *ptr, size_t len); 217 | 218 | /* 219 | * Convenience function to do formatted printing to a response. Only useful 220 | * when chunked encoding is being used. 221 | */ 222 | int WebbyPrintf(struct WebbyConnection *conn, const char *fmt, ...); 223 | 224 | /* 225 | * Convenience function to find a header in a request. Returns the value of the 226 | * specified header, or NULL if it was not present. 227 | */ 228 | const char *WebbyFindHeader(struct WebbyConnection *conn, const char *name); 229 | 230 | /* Helper function to look up a query parameter given a URL encoded string. 231 | 232 | Returns the size of the returned data, or -1 if the query var wasn't found. 233 | */ 234 | int WebbyFindQueryVar(const char *query_params, const char *name, char *buffer, size_t buffer_size); 235 | 236 | /* Begin an outgoing websocket frame */ 237 | int 238 | WebbyBeginSocketFrame(struct WebbyConnection *conn, int websocket_opcode); 239 | 240 | /* End an outgoing websocket frame */ 241 | int 242 | WebbyEndSocketFrame(struct WebbyConnection *conn); 243 | 244 | int 245 | WebbySendFrame(struct WebbyConnection *conn_pub, int opcode, const void *ptr, size_t len); 246 | 247 | #ifdef __cplusplus 248 | } 249 | #endif 250 | 251 | #endif 252 | -------------------------------------------------------------------------------- /src/app/lz4/lz4hc.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 HC - High Compression Mode of LZ4 3 | Header File 4 | Copyright (C) 2011-2014, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - LZ4 homepage : http://fastcompression.blogspot.com/p/lz4.html 32 | - LZ4 source repository : http://code.google.com/p/lz4/ 33 | */ 34 | #pragma once 35 | 36 | 37 | #if defined (__cplusplus) 38 | extern "C" { 39 | #endif 40 | 41 | 42 | int LZ4_compressHC (const char* source, char* dest, int inputSize); 43 | /* 44 | LZ4_compressHC : 45 | return : the number of bytes in compressed buffer dest 46 | or 0 if compression fails. 47 | note : destination buffer must be already allocated. 48 | To avoid any problem, size it to handle worst cases situations (input data not compressible) 49 | Worst case size evaluation is provided by function LZ4_compressBound() (see "lz4.h") 50 | */ 51 | 52 | int LZ4_compressHC_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize); 53 | /* 54 | LZ4_compress_limitedOutput() : 55 | Compress 'inputSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. 56 | If it cannot achieve it, compression will stop, and result of the function will be zero. 57 | This function never writes outside of provided output buffer. 58 | 59 | inputSize : Max supported value is 1 GB 60 | maxOutputSize : is maximum allowed size into the destination buffer (which must be already allocated) 61 | return : the number of output bytes written in buffer 'dest' 62 | or 0 if compression fails. 63 | */ 64 | 65 | 66 | int LZ4_compressHC2 (const char* source, char* dest, int inputSize, int compressionLevel); 67 | int LZ4_compressHC2_limitedOutput (const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); 68 | /* 69 | Same functions as above, but with programmable 'compressionLevel'. 70 | Recommended values are between 4 and 9, although any value between 0 and 16 will work. 71 | 'compressionLevel'==0 means use default 'compressionLevel' value. 72 | Values above 16 behave the same as 16. 73 | Equivalent variants exist for all other compression functions below. 74 | */ 75 | 76 | /* Note : 77 | Decompression functions are provided within LZ4 source code (see "lz4.h") (BSD license) 78 | */ 79 | 80 | 81 | /************************************** 82 | Using an external allocation 83 | **************************************/ 84 | int LZ4_sizeofStateHC(void); 85 | int LZ4_compressHC_withStateHC (void* state, const char* source, char* dest, int inputSize); 86 | int LZ4_compressHC_limitedOutput_withStateHC (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); 87 | 88 | int LZ4_compressHC2_withStateHC (void* state, const char* source, char* dest, int inputSize, int compressionLevel); 89 | int LZ4_compressHC2_limitedOutput_withStateHC(void* state, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); 90 | 91 | /* 92 | These functions are provided should you prefer to allocate memory for compression tables with your own allocation methods. 93 | To know how much memory must be allocated for the compression tables, use : 94 | int LZ4_sizeofStateHC(); 95 | 96 | Note that tables must be aligned for pointer (32 or 64 bits), otherwise compression will fail (return code 0). 97 | 98 | The allocated memory can be provided to the compression functions using 'void* state' parameter. 99 | LZ4_compress_withStateHC() and LZ4_compress_limitedOutput_withStateHC() are equivalent to previously described functions. 100 | They just use the externally allocated memory for state instead of allocating their own (on stack, or on heap). 101 | */ 102 | 103 | 104 | 105 | /************************************** 106 | Experimental Streaming Functions 107 | **************************************/ 108 | #define LZ4_STREAMHCSIZE_U64 32774 109 | #define LZ4_STREAMHCSIZE (LZ4_STREAMHCSIZE_U64 * sizeof(unsigned long long)) 110 | typedef struct { unsigned long long table[LZ4_STREAMHCSIZE_U64]; } LZ4_streamHC_t; 111 | /* 112 | LZ4_streamHC_t 113 | This structure allows static allocation of LZ4 HC streaming state. 114 | State must then be initialized using LZ4_resetStreamHC() before first use. 115 | 116 | Static allocation should only be used with statically linked library. 117 | If you want to use LZ4 as a DLL, please use construction functions below, which are more future-proof. 118 | */ 119 | 120 | 121 | LZ4_streamHC_t* LZ4_createStreamHC(void); 122 | int LZ4_freeStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr); 123 | /* 124 | These functions create and release memory for LZ4 HC streaming state. 125 | Newly created states are already initialized. 126 | Existing state space can be re-used anytime using LZ4_resetStreamHC(). 127 | If you use LZ4 as a DLL, please use these functions instead of direct struct allocation, 128 | to avoid size mismatch between different versions. 129 | */ 130 | 131 | void LZ4_resetStreamHC (LZ4_streamHC_t* LZ4_streamHCPtr, int compressionLevel); 132 | int LZ4_loadDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, const char* dictionary, int dictSize); 133 | 134 | int LZ4_compressHC_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize); 135 | int LZ4_compressHC_limitedOutput_continue (LZ4_streamHC_t* LZ4_streamHCPtr, const char* source, char* dest, int inputSize, int maxOutputSize); 136 | 137 | int LZ4_saveDictHC (LZ4_streamHC_t* LZ4_streamHCPtr, char* safeBuffer, int maxDictSize); 138 | 139 | /* 140 | These functions compress data in successive blocks of any size, using previous blocks as dictionary. 141 | One key assumption is that each previous block will remain read-accessible while compressing next block. 142 | 143 | Before starting compression, state must be properly initialized, using LZ4_resetStreamHC(). 144 | A first "fictional block" can then be designated as initial dictionary, using LZ4_loadDictHC() (Optional). 145 | 146 | Then, use LZ4_compressHC_continue() or LZ4_compressHC_limitedOutput_continue() to compress each successive block. 147 | They work like usual LZ4_compressHC() or LZ4_compressHC_limitedOutput(), but use previous memory blocks to improve compression. 148 | Previous memory blocks (including initial dictionary when present) must remain accessible and unmodified during compression. 149 | 150 | If, for any reason, previous data block can't be preserved in memory during next compression block, 151 | you must save it to a safer memory space, 152 | using LZ4_saveDictHC(). 153 | */ 154 | 155 | 156 | 157 | /************************************** 158 | * Deprecated Streaming Functions 159 | * ************************************/ 160 | /* Note : these streaming functions follows the older model, and should no longer be used */ 161 | void* LZ4_createHC (const char* inputBuffer); 162 | char* LZ4_slideInputBufferHC (void* LZ4HC_Data); 163 | int LZ4_freeHC (void* LZ4HC_Data); 164 | 165 | int LZ4_compressHC2_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int compressionLevel); 166 | int LZ4_compressHC2_limitedOutput_continue (void* LZ4HC_Data, const char* source, char* dest, int inputSize, int maxOutputSize, int compressionLevel); 167 | 168 | int LZ4_sizeofStreamStateHC(void); 169 | int LZ4_resetStreamStateHC(void* state, const char* inputBuffer); 170 | 171 | 172 | #if defined (__cplusplus) 173 | } 174 | #endif 175 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/main.cpp: -------------------------------------------------------------------------------- 1 | // ImGui - standalone example application for OpenGL 2, using fixed pipeline 2 | 3 | #ifdef _MSC_VER 4 | #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen 5 | #endif 6 | #ifdef __clang__ 7 | #pragma clang diagnostic ignored "-Wunused-function" // warning: unused function 8 | #endif 9 | 10 | #include "../imgui.h" 11 | #include "../../imgui_remote.h" 12 | #include 13 | 14 | // Glfw/Glew 15 | #define GLEW_STATIC 16 | #include 17 | #include 18 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 19 | 20 | static GLFWwindow* window; 21 | static bool mousePressed[2] = { false, false }; 22 | 23 | // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) 24 | // If text or lines are blurry when integrating ImGui in your engine: 25 | // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) 26 | static void ImImpl_RenderDrawLists(ImDrawList** const cmd_lists, int cmd_lists_count) 27 | { 28 | ImGui::RemoteDraw(cmd_lists, cmd_lists_count); 29 | 30 | if (cmd_lists_count == 0) 31 | return; 32 | 33 | // We are using the OpenGL fixed pipeline to make the example code simpler to read! 34 | // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. 35 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. 36 | glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); 37 | glEnable(GL_BLEND); 38 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 39 | glDisable(GL_CULL_FACE); 40 | glDisable(GL_DEPTH_TEST); 41 | glEnable(GL_SCISSOR_TEST); 42 | glEnableClientState(GL_VERTEX_ARRAY); 43 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 44 | glEnableClientState(GL_COLOR_ARRAY); 45 | glEnable(GL_TEXTURE_2D); 46 | 47 | // Setup orthographic projection matrix 48 | const float width = ImGui::GetIO().DisplaySize.x; 49 | const float height = ImGui::GetIO().DisplaySize.y; 50 | glMatrixMode(GL_PROJECTION); 51 | glPushMatrix(); 52 | glLoadIdentity(); 53 | glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f); 54 | glMatrixMode(GL_MODELVIEW); 55 | glPushMatrix(); 56 | glLoadIdentity(); 57 | 58 | // Render command lists 59 | for (int n = 0; n < cmd_lists_count; n++) 60 | { 61 | const ImDrawList* cmd_list = cmd_lists[n]; 62 | const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->vtx_buffer.front(); 63 | glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); 64 | glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); 65 | glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); 66 | 67 | int vtx_offset = 0; 68 | for (size_t cmd_i = 0; cmd_i < cmd_list->commands.size(); cmd_i++) 69 | { 70 | const ImDrawCmd* pcmd = &cmd_list->commands[cmd_i]; 71 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->texture_id); 72 | glScissor((int)pcmd->clip_rect.x, (int)(height - pcmd->clip_rect.w), (int)(pcmd->clip_rect.z - pcmd->clip_rect.x), (int)(pcmd->clip_rect.w - pcmd->clip_rect.y)); 73 | glDrawArrays(GL_TRIANGLES, vtx_offset, pcmd->vtx_count); 74 | vtx_offset += pcmd->vtx_count; 75 | } 76 | } 77 | 78 | // Restore modified state 79 | glDisableClientState(GL_COLOR_ARRAY); 80 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); 81 | glDisableClientState(GL_VERTEX_ARRAY); 82 | glMatrixMode(GL_MODELVIEW); 83 | glPopMatrix(); 84 | glMatrixMode(GL_PROJECTION); 85 | glPopMatrix(); 86 | glPopAttrib(); 87 | } 88 | 89 | // NB: ImGui already provide OS clipboard support for Windows so this isn't needed if you are using Windows only. 90 | static const char* ImImpl_GetClipboardTextFn() 91 | { 92 | return glfwGetClipboardString(window); 93 | } 94 | 95 | static void ImImpl_SetClipboardTextFn(const char* text) 96 | { 97 | glfwSetClipboardString(window, text); 98 | } 99 | 100 | // GLFW callbacks to get events 101 | static void glfw_error_callback(int error, const char* description) 102 | { 103 | fputs(description, stderr); 104 | } 105 | 106 | static void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods) 107 | { 108 | if (action == GLFW_PRESS && button >= 0 && button < 2) 109 | mousePressed[button] = true; 110 | } 111 | 112 | static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset) 113 | { 114 | ImGuiIO& io = ImGui::GetIO(); 115 | io.MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. 116 | } 117 | 118 | static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 119 | { 120 | ImGuiIO& io = ImGui::GetIO(); 121 | if (action == GLFW_PRESS) 122 | io.KeysDown[key] = true; 123 | if (action == GLFW_RELEASE) 124 | io.KeysDown[key] = false; 125 | io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0; 126 | io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0; 127 | } 128 | 129 | static void glfw_char_callback(GLFWwindow* window, unsigned int c) 130 | { 131 | if (c > 0 && c < 0x10000) 132 | ImGui::GetIO().AddInputCharacter((unsigned short)c); 133 | } 134 | 135 | void InitGL() 136 | { 137 | glfwSetErrorCallback(glfw_error_callback); 138 | if (!glfwInit()) 139 | exit(1); 140 | 141 | window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); 142 | glfwMakeContextCurrent(window); 143 | glfwSetKeyCallback(window, glfw_key_callback); 144 | glfwSetMouseButtonCallback(window, glfw_mouse_button_callback); 145 | glfwSetScrollCallback(window, glfw_scroll_callback); 146 | glfwSetCharCallback(window, glfw_char_callback); 147 | 148 | glewInit(); 149 | } 150 | 151 | void LoadFontsTexture() 152 | { 153 | ImGuiIO& io = ImGui::GetIO(); 154 | //ImFont* my_font1 = io.Fonts->AddFontDefault(); 155 | //ImFont* my_font2 = io.Fonts->AddFontFromFileTTF("extra_fonts/Karla-Regular.ttf", 15.0f); 156 | //ImFont* my_font3 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyClean.ttf", 13.0f); my_font3->DisplayOffset.y += 1; 157 | //ImFont* my_font4 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyTiny.ttf", 10.0f); my_font4->DisplayOffset.y += 1; 158 | //ImFont* my_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 20.0f, io.Fonts->GetGlyphRangesJapanese()); 159 | 160 | unsigned char* pixels; 161 | int width, height; 162 | io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); 163 | 164 | GLuint tex_id; 165 | glGenTextures(1, &tex_id); 166 | glBindTexture(GL_TEXTURE_2D, tex_id); 167 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 168 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 169 | glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); 170 | 171 | // Store our identifier 172 | io.Fonts->TexID = (void *)(intptr_t)tex_id; 173 | } 174 | 175 | void InitImGui() 176 | { 177 | ImGuiIO& io = ImGui::GetIO(); 178 | io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable) 179 | io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 180 | io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; 181 | io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; 182 | io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; 183 | io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; 184 | io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; 185 | io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; 186 | io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; 187 | io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; 188 | io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; 189 | io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; 190 | io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; 191 | io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; 192 | io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; 193 | io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; 194 | io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; 195 | io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; 196 | 197 | io.RenderDrawListsFn = ImImpl_RenderDrawLists; 198 | io.SetClipboardTextFn = ImImpl_SetClipboardTextFn; 199 | io.GetClipboardTextFn = ImImpl_GetClipboardTextFn; 200 | 201 | LoadFontsTexture(); 202 | 203 | ImGui::RemoteInit("127.0.0.1", 7002, 8192, 8192); 204 | } 205 | 206 | void UpdateImGui() 207 | { 208 | ImGuiIO& io = ImGui::GetIO(); 209 | 210 | // Setup resolution (every frame to accommodate for window resizing) 211 | int w, h; 212 | int display_w, display_h; 213 | glfwGetWindowSize(window, &w, &h); 214 | glfwGetFramebufferSize(window, &display_w, &display_h); 215 | io.DisplaySize = ImVec2((float)display_w, (float)display_h); // Display size, in pixels. For clamping windows positions. 216 | 217 | // Setup time step 218 | static double time = 0.0f; 219 | const double current_time = glfwGetTime(); 220 | io.DeltaTime = (float)(current_time - time); 221 | time = current_time; 222 | 223 | ImGui::RemoteUpdate(); 224 | 225 | ImGui::RemoteInput input; 226 | if (ImGui::RemoteGetInput(input)) 227 | { 228 | ImGuiIO& io = ImGui::GetIO(); 229 | for (int i = 0; i < 256; i++) 230 | io.KeysDown[i] = input.KeysDown[i]; 231 | io.KeyCtrl = input.KeyCtrl; 232 | io.KeyShift = input.KeyShift; 233 | io.MousePos = input.MousePos; 234 | io.MouseDown[0] = (input.MouseButtons & 1); 235 | io.MouseDown[1] = (input.MouseButtons & 2) != 0; 236 | io.MouseWheel = (float)input.MouseWheel; 237 | } 238 | else 239 | { 240 | // Setup inputs 241 | // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) 242 | double mouse_x, mouse_y; 243 | glfwGetCursorPos(window, &mouse_x, &mouse_y); 244 | mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels 245 | mouse_y *= (float)display_h / h; 246 | io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) 247 | io.MouseDown[0] = mousePressed[0] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. 248 | io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0; 249 | } 250 | 251 | // Start the frame 252 | ImGui::NewFrame(); 253 | } 254 | 255 | // Application code 256 | int main(int argc, char** argv) 257 | { 258 | InitGL(); 259 | InitImGui(); 260 | 261 | bool show_test_window = true; 262 | bool show_another_window = false; 263 | ImVec4 clear_col = ImColor(114, 144, 154); 264 | 265 | while (!glfwWindowShouldClose(window)) 266 | { 267 | ImGuiIO& io = ImGui::GetIO(); 268 | mousePressed[0] = mousePressed[1] = false; 269 | glfwPollEvents(); 270 | UpdateImGui(); 271 | 272 | // 1. Show a simple window 273 | // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" 274 | { 275 | static float f; 276 | ImGui::Text("Hello, world!"); 277 | ImGui::SliderFloat("float", &f, 0.0f, 1.0f); 278 | ImGui::ColorEdit3("clear color", (float*)&clear_col); 279 | if (ImGui::Button("Test Window")) show_test_window ^= 1; 280 | if (ImGui::Button("Another Window")) show_another_window ^= 1; 281 | 282 | // Calculate and show frame rate 283 | static float ms_per_frame[120] = { 0 }; 284 | static int ms_per_frame_idx = 0; 285 | static float ms_per_frame_accum = 0.0f; 286 | ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx]; 287 | ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f; 288 | ms_per_frame_accum += ms_per_frame[ms_per_frame_idx]; 289 | ms_per_frame_idx = (ms_per_frame_idx + 1) % 120; 290 | const float ms_per_frame_avg = ms_per_frame_accum / 120; 291 | ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg); 292 | } 293 | 294 | // 2. Show another simple window, this time using an explicit Begin/End pair 295 | if (show_another_window) 296 | { 297 | ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); 298 | ImGui::Text("Hello"); 299 | ImGui::End(); 300 | } 301 | 302 | // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() 303 | if (show_test_window) 304 | { 305 | ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCondition_FirstUseEver); 306 | ImGui::ShowTestWindow(&show_test_window); 307 | } 308 | 309 | // Rendering 310 | glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); 311 | glClearColor(clear_col.x, clear_col.y, clear_col.z, clear_col.w); 312 | glClear(GL_COLOR_BUFFER_BIT); 313 | ImGui::Render(); 314 | glfwSwapBuffers(window); 315 | } 316 | 317 | // Cleanup 318 | ImGui::Shutdown(); 319 | glfwTerminate(); 320 | 321 | return 0; 322 | } 323 | -------------------------------------------------------------------------------- /src/app/example/README.md: -------------------------------------------------------------------------------- 1 | ImGui 2 | ===== 3 | [![Build Status](https://travis-ci.org/ocornut/imgui.svg?branch=master)](https://travis-ci.org/ocornut/imgui) 4 | [![Coverity Status](https://scan.coverity.com/projects/4720/badge.svg)](https://scan.coverity.com/projects/4720) 5 | 6 | [![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) 7 | 8 | ImGui is a bloat-free graphical user interface library for C++. It outputs vertex buffers that you can render in your 3D-pipeline enabled application. It is portable, renderer agnostic and self-contained (no external dependencies). It is based on an "immediate mode" graphical user interface paradigm which enables you to build user interfaces with ease. 9 | 10 | ImGui is designed to enable fast iteration and empower programmers to create content creation tools and visualization/debug tools (as opposed to UI for the average end-user). It favors simplicity and productivity toward this goal, and thus lacks certain features normally found in more high-level libraries. 11 | 12 | ImGui is particularly suited to integration in realtime 3D applications, fullscreen applications, embedded applications, games, or any applications on consoles platforms where operating system features are non-standard. 13 | 14 | ImGui is self-contained within a few files that you can easily copy and compile into your application/engine: 15 | 16 | - imgui.cpp 17 | - imgui.h 18 | - imgui_demo.cpp 19 | - imgui_draw.cpp 20 | - imgui_internal.h 21 | - imconfig.h (empty by default, user-editable) 22 | - stb_rect_pack.h 23 | - stb_textedit.h 24 | - stb_truetype.h 25 | 26 | No specific build process is required. You can add the .cpp files to your project or #include them from an existing file. 27 | 28 | Your code passes mouse/keyboard inputs and settings to ImGui (see example applications for more details). After ImGui is setup, you can use it like in this example: 29 | 30 | ![screenshot of sample code alongside its output with ImGui](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/code_sample_01.png) 31 | 32 | ImGui outputs vertex buffers and simple command-lists that you can render in your application. Because it doesn't know or touch graphics state directly, you can call ImGui commands anywhere in your code (e.g. in the middle of a running algorithm, or in the middle of your own rendering process). Refer to the sample applications in the examples/ folder for instructions on how to integrate ImGui with your existing codebase. 33 | 34 | ImGui allows you create elaborate tools as well as very short-lived ones. On the extreme side of short-liveness: using the Edit&Continue feature of modern compilers you can add a few widgets to tweaks variables while your application is running, and remove the code a minute later! ImGui is not just for tweaking values. You can use it to trace a running algorithm by just emitting text commands. You can use it along with your own reflection data to browse your dataset live. You can use it to expose the internals of a subsystem in your engine, to create a logger, an inspection tool, a profiler, a debugger, etc. 35 | 36 | Some of the features supported in some way by ImGui: window management (ordering, moving, resizing, collapsing, persistent settings), button, slider, dragging value, checkbox, radio button, text input (with selection, clipboard support, and standard keyboard controls), multiline text input, filtering text input, tree nodes, collapsing header, word-wrapping, utf-8 text, images, selectable items, vertical and horizontal scrolling, sub-window with independant scrolling/clipping, ttf font loading, basic styling, logging any ui output into text data (clipboard/tty/file), hovering, tooltips, popup windows, modal windows, menu bars, menu items, context menus, combo boxes, list box, plotting lines and histograms, resizable columns, keyboard tabbing, dragging, simple drawing api (anti-aliased, with stroking, convex fill), and low-level primitives to create custom widgets. 37 | 38 | Demo 39 | ---- 40 | 41 | You should be able to build the examples from sources (tested on Windows/Mac/Linux). If you don't, let me know! If you want to have a quick look at the features of ImGui, you can download Windows binaries of the demo app here. 42 | - [imgui-demo-binaries-20150716.zip](http://www.miracleworld.net/imgui/binaries/imgui-demo-binaries-20150716.zip) (Windows binaries, ImGui 1.43 WIP 2015/07/16, 4 executables, 475 KB) 43 | 44 | 45 | Gallery 46 | ------- 47 | 48 | ![screenshot 1](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_01.png) 49 | ![screenshot 2](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_02.png) 50 | ![screenshot 3](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/test_window_03.png) 51 | ![screenshot 5](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v140/test_window_05_menus.png) 52 | ![screenshot 4](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/skinning_sample_02.png) 53 | ![screenshot 6](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v143/examples_04.png) 54 | ![screenshot 7](https://cloud.githubusercontent.com/assets/8225057/7903336/96f0fb7c-07d0-11e5-95d6-41c6a1595e5a.png) 55 | 56 | ImGui can load TTF fonts. UTF-8 is supported for text display and input. Here using Arial Unicode font to display Japanese. Initialize custom font with: 57 | ``` 58 | ImGuiIO& io = ImGui::GetIO(); 59 | io.Fonts->AddFontFromFileTTF("ArialUni.ttf", 18.0f, NULL, io.Fonts->GetGlyphRangesJapanese()); 60 | ``` 61 | For Microsoft IME, pass your HWND to enable IME positioning: 62 | ``` 63 | io.ImeWindowHandle = my_hwnd; 64 | ``` 65 | ![Japanese screenshot](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/code_sample_01_jp.png) 66 | 67 | References 68 | ---------- 69 | 70 | The Immediate Mode GUI paradigm may at first appear unusual to some users. This is mainly because "Retained Mode" GUIs have been so widespread and predominant. The following links can give you a better understanding about how Immediate Mode GUIs works. 71 | - [Johannes 'johno' Norneby's article](http://www.johno.se/book/imgui.html). 72 | - [A presentation by Rickard Gustafsson and Johannes Algelind](http://www.cse.chalmers.se/edu/year/2011/course/TDA361/Advanced%20Computer%20Graphics/IMGUI.pdf). 73 | - [Jari Komppa's tutorial on building an ImGui library](http://iki.fi/sol/imgui/). 74 | - [Casey Muratori's original video that popularized the concept](https://mollyrocket.com/861). 75 | 76 | Frequently Asked Question 77 | ------------------------- 78 | 79 | Where is the documentation? 80 | 81 | - The documentation is at the top of imgui.cpp + effectively imgui.h. 82 | - Example code is in imgui_demo.cpp and particularly the ImGui::ShowTestWindow() function. It covers most features of ImGui so you can read the code and call the function itself to see its output. 83 | - Standalone example applications using e.g. OpenGL/DirectX are provided in the examples/ folder. 84 | - It obviously needs better documentation! Consider helping or becoming a [Patron](http://www.patreon.com/imgui) to promote this effort. 85 | 86 | How do you use ImGui on a platform that may not have a mouse or keyboard? 87 | 88 | I recommend using [Synergy](http://synergy-project.org) ([sources](https://github.com/synergy/synergy)). In particular, the _src/micro/uSynergy.c_ file contains a small client that you can use on any platform to connect to your host PC. You can seamlessly use your PC input devices from a video game console or a tablet. ImGui allows to increase the hit box of widgets (via the _TouchPadding_ setting) to accomodate a little for the lack of precision of touch inputs, but it is recommended you use a mouse to allow optimising for screen real-estate. 89 | 90 | I integrated ImGui in my engine and the text or lines are blurry.. 91 | 92 | In your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f). 93 | 94 | Can you create elaborate/serious tools with ImGui? 95 | 96 | Yes. I have written data browsers, debuggers, profilers and all sort of non-trivial tools with the library. In my experience the simplicity of the API is very empowering. Your UI runs close to your live data. Make the tools always-on and everybody in the team will be inclined to create new tools (as opposed to more "offline" UI toolkits where only a fraction of your team effectively creates tools). 97 | 98 | ImGui is very programmer centric and the immediate-mode GUI paradigm might requires a bit of adaptation before you can realize its full potential. Many programmers have unfortunately been taught by their environment to make unnecessarily complicated things. ImGui is about making things that are simple, efficient and powerful. 99 | 100 | Is ImGui fast? 101 | 102 | Down to the fundation of its visual design, ImGui is engineered to be fairly performant both in term of CPU and GPU usage. Running elaborate code and creating elaborate UI will of course have a cost but ImGui aims to minimize it. 103 | 104 | Mileage may vary but the following screenshot can give you a rough idea of the cost of running and rendering UI code (In the case of a trivial demo application like this one, your driver/os setup are likely to be the bottleneck. Testing performance as part of a real application is recommended). 105 | 106 | ![performance screenshot](https://raw.githubusercontent.com/wiki/ocornut/imgui/web/v138/performance_01.png) 107 | 108 | This is showing framerate for the full application loop on my 2011 iMac running Windows 7, OpenGL, AMD Radeon HD 6700M with an optimized executable. In contrast, librairies featuring higher-quality rendering and layouting techniques may have a higher resources footprint. 109 | 110 | If you intend to display large lists of items (say, 1000+) it can be beneficial for your code to perform clipping manually - using helpers such as ImGuiListClipper - in order to avoid submitting them to ImGui in the first place. Even though ImGui will discard your clipped items it still needs to calculate their size and that overhead will add up if you have thousands of items. If you can handle clipping and height positionning yourself then browsing a list with millions of items isn't a problem. 111 | 112 | Can you reskin the look of ImGui? 113 | 114 | You can alter the look of the interface to some degree: changing colors, sizes, padding, rounding, fonts. However, as ImGui is designed and optimised to create debug tools, the amount of skinning you can apply is limited. There is only so much you can stray away from the default look and feel of the interface. 115 | 116 | Why using C++ (as opposed to C)? 117 | 118 | ImGui takes advantage of a few C++ features for convenience but nothing anywhere Boost-insanity/quagmire. In particular, function overloading and default parameters are used to make the API easier to use and code more terse. Doing so I believe the API is sitting on a sweet spot and giving up on those features would make the API more cumbersome. Other features such as namespace, constructors and templates (in the case of the ImVector<> class) are also relied on as a convenience but could be removed. 119 | 120 | Shall someone really need to use ImGui from another language, there is an unofficial but reasonably maintained [c-api for ImGui](https://github.com/Extrawurst/cimgui) by Stephan Dilly. I would suggest using your target language functionality to try replicating the function overloading and default parameters used in C++ else the API may be harder to use. It was really designed with C++ in mind and may not make the same amount of sense with another language. 121 | 122 | Donate 123 | ------ 124 | 125 | Can I donate to support the development of ImGui? 126 | 127 | [![Patreon](https://cloud.githubusercontent.com/assets/8225057/5990484/70413560-a9ab-11e4-8942-1a63607c0b00.png)](http://www.patreon.com/imgui) [![PayPal](https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5Q73FPZ9C526U) 128 | 129 | I'm currently an independant developer and your contributions are very meaningful to me. I have setup an [**ImGui Patreon page**](http://www.patreon.com/imgui) if you want to donate and enable me to spend more time improving the library. If your company uses ImGui please consider making a contribution. One-off donations are also greatly appreciated (PayPal link above). I am also available for hire to work on or with ImGui. Thanks! 130 | 131 | Credits 132 | ------- 133 | 134 | Developed by [Omar Cornut](http://www.miracleworld.net) and every direct or indirect contributors to the GitHub. The early version of this library was developed with the support of [Media Molecule](http://www.mediamolecule.com) and first used internally on the game [Tearaway](http://tearaway.mediamolecule.com). 135 | 136 | Embeds [ProggyClean.ttf](http://upperbounds.net) font by Tristan Grimmer (MIT license). 137 | 138 | Embeds [stb_textedit.h, stb_truetype.h, stb_rectpack.h](https://github.com/nothings/stb/) by Sean Barrett (public domain). 139 | 140 | Inspiration, feedback, and testing for early versions: Casey Muratori, Atman Binstock, Mikko Mononen, Emmanuel Briney, Stefan Kamoda, Anton Mikhailov, Matt Willis. And everybody posting feedback, questions and patches on the GitHub. 141 | 142 | ImGui development is financially supported on [**Patreon**](http://www.patreon.com/imgui). 143 | 144 | Special supporters: 145 | - Jetha Chan, Wild Sheep Studio, Pastagames, Mārtiņš Možeiko, Daniel Collin, Stefano Cristiano. 146 | 147 | And: 148 | - Michel Courtine, César Leblic, Dale Kim, Alex Evans, Rui Figueira, Paul Patrashcu, Jerome Lanquetot, Ctrl Alt Ninja, Paul Fleming, Neil Henning, Stephan Dilly, Neil Blakey-Milner, Aleksei. 149 | 150 | And other supporters; thanks! 151 | 152 | License 153 | ------- 154 | 155 | ImGui is licensed under the MIT License, see LICENSE for more information. 156 | -------------------------------------------------------------------------------- /src/app/lz4/lz4frame.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 auto-framing library 3 | Header File 4 | Copyright (C) 2011-2015, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - LZ4 source repository : http://code.google.com/p/lz4/ 32 | - LZ4 source mirror : https://github.com/Cyan4973/lz4 33 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 34 | */ 35 | 36 | /* LZ4F is a stand-alone API to create LZ4-compressed frames 37 | * fully conformant to specification v1.4.1. 38 | * All related operations, including memory management, are handled by the library. 39 | * You don't need lz4.h when using lz4frame.h. 40 | * */ 41 | 42 | #pragma once 43 | 44 | #if defined (__cplusplus) 45 | extern "C" { 46 | #endif 47 | 48 | /************************************** 49 | Includes 50 | **************************************/ 51 | #include /* size_t */ 52 | 53 | 54 | /************************************** 55 | * Error management 56 | * ************************************/ 57 | typedef size_t LZ4F_errorCode_t; 58 | 59 | unsigned LZ4F_isError(LZ4F_errorCode_t code); 60 | const char* LZ4F_getErrorName(LZ4F_errorCode_t code); /* return error code string; useful for debugging */ 61 | 62 | 63 | /************************************** 64 | * Frame compression types 65 | * ************************************/ 66 | typedef enum { LZ4F_default=0, max64KB=4, max256KB=5, max1MB=6, max4MB=7 } blockSizeID_t; 67 | typedef enum { blockLinked=0, blockIndependent} blockMode_t; 68 | typedef enum { noContentChecksum=0, contentChecksumEnabled } contentChecksum_t; 69 | 70 | typedef struct { 71 | blockSizeID_t blockSizeID; /* max64KB, max256KB, max1MB, max4MB ; 0 == default */ 72 | blockMode_t blockMode; /* blockLinked, blockIndependent ; 0 == default */ 73 | contentChecksum_t contentChecksumFlag; /* noContentChecksum, contentChecksumEnabled ; 0 == default */ 74 | unsigned reserved[5]; 75 | } LZ4F_frameInfo_t; 76 | 77 | typedef struct { 78 | LZ4F_frameInfo_t frameInfo; 79 | unsigned compressionLevel; /* 0 == default (fast mode); values above 16 count as 16 */ 80 | unsigned autoFlush; /* 1 == always flush : reduce need for tmp buffer */ 81 | unsigned reserved[4]; 82 | } LZ4F_preferences_t; 83 | 84 | 85 | /*********************************** 86 | * Simple compression function 87 | * *********************************/ 88 | size_t LZ4F_compressFrameBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr); 89 | 90 | size_t LZ4F_compressFrame(void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_preferences_t* preferencesPtr); 91 | /* LZ4F_compressFrame() 92 | * Compress an entire srcBuffer into a valid LZ4 frame, as defined by specification v1.4.1. 93 | * The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case. 94 | * You can get the minimum value of dstMaxSize by using LZ4F_compressFrameBound() 95 | * If this condition is not respected, LZ4F_compressFrame() will fail (result is an errorCode) 96 | * The LZ4F_preferences_t structure is optional : you can provide NULL as argument. All preferences will be set to default. 97 | * The result of the function is the number of bytes written into dstBuffer. 98 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 99 | */ 100 | 101 | 102 | 103 | /********************************** 104 | * Advanced compression functions 105 | * ********************************/ 106 | typedef void* LZ4F_compressionContext_t; 107 | 108 | typedef struct { 109 | unsigned stableSrc; /* 1 == src content will remain available on future calls to LZ4F_compress(); avoid saving src content within tmp buffer as future dictionary */ 110 | unsigned reserved[3]; 111 | } LZ4F_compressOptions_t; 112 | 113 | /* Resource Management */ 114 | 115 | #define LZ4F_VERSION 100 116 | LZ4F_errorCode_t LZ4F_createCompressionContext(LZ4F_compressionContext_t* LZ4F_compressionContextPtr, unsigned version); 117 | LZ4F_errorCode_t LZ4F_freeCompressionContext(LZ4F_compressionContext_t LZ4F_compressionContext); 118 | /* LZ4F_createCompressionContext() : 119 | * The first thing to do is to create a compressionContext object, which will be used in all compression operations. 120 | * This is achieved using LZ4F_createCompressionContext(), which takes as argument a version and an LZ4F_preferences_t structure. 121 | * The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries. 122 | * The function will provide a pointer to a fully allocated LZ4F_compressionContext_t object. 123 | * If the result LZ4F_errorCode_t is not zero, there was an error during context creation. 124 | * Object can release its memory using LZ4F_freeCompressionContext(); 125 | */ 126 | 127 | 128 | /* Compression */ 129 | 130 | size_t LZ4F_compressBegin(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_preferences_t* preferencesPtr); 131 | /* LZ4F_compressBegin() : 132 | * will write the frame header into dstBuffer. 133 | * dstBuffer must be large enough to accommodate a header (dstMaxSize). Maximum header size is 19 bytes. 134 | * The LZ4F_preferences_t structure is optional : you can provide NULL as argument, all preferences will then be set to default. 135 | * The result of the function is the number of bytes written into dstBuffer for the header 136 | * or an error code (can be tested using LZ4F_isError()) 137 | */ 138 | 139 | size_t LZ4F_compressBound(size_t srcSize, const LZ4F_preferences_t* preferencesPtr); 140 | /* LZ4F_compressBound() : 141 | * Provides the minimum size of Dst buffer given srcSize to handle worst case situations. 142 | * preferencesPtr is optional : you can provide NULL as argument, all preferences will then be set to default. 143 | * Note that different preferences will produce in different results. 144 | */ 145 | 146 | size_t LZ4F_compressUpdate(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const void* srcBuffer, size_t srcSize, const LZ4F_compressOptions_t* compressOptionsPtr); 147 | /* LZ4F_compressUpdate() 148 | * LZ4F_compressUpdate() can be called repetitively to compress as much data as necessary. 149 | * The most important rule is that dstBuffer MUST be large enough (dstMaxSize) to ensure compression completion even in worst case. 150 | * If this condition is not respected, LZ4F_compress() will fail (result is an errorCode) 151 | * You can get the minimum value of dstMaxSize by using LZ4F_compressBound() 152 | * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. 153 | * The result of the function is the number of bytes written into dstBuffer : it can be zero, meaning input data was just buffered. 154 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 155 | */ 156 | 157 | size_t LZ4F_flush(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* compressOptionsPtr); 158 | /* LZ4F_flush() 159 | * Should you need to create compressed data immediately, without waiting for a block to be filled, 160 | * you can call LZ4_flush(), which will immediately compress any remaining data buffered within compressionContext. 161 | * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. 162 | * The result of the function is the number of bytes written into dstBuffer 163 | * (it can be zero, this means there was no data left within compressionContext) 164 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 165 | */ 166 | 167 | size_t LZ4F_compressEnd(LZ4F_compressionContext_t compressionContext, void* dstBuffer, size_t dstMaxSize, const LZ4F_compressOptions_t* compressOptionsPtr); 168 | /* LZ4F_compressEnd() 169 | * When you want to properly finish the compressed frame, just call LZ4F_compressEnd(). 170 | * It will flush whatever data remained within compressionContext (like LZ4_flush()) 171 | * but also properly finalize the frame, with an endMark and a checksum. 172 | * The result of the function is the number of bytes written into dstBuffer (necessarily >= 4 (endMark size)) 173 | * The function outputs an error code if it fails (can be tested using LZ4F_isError()) 174 | * The LZ4F_compressOptions_t structure is optional : you can provide NULL as argument. 175 | * compressionContext can then be used again, starting with LZ4F_compressBegin(). 176 | */ 177 | 178 | 179 | /*********************************** 180 | * Decompression functions 181 | * *********************************/ 182 | 183 | typedef void* LZ4F_decompressionContext_t; 184 | 185 | typedef struct { 186 | unsigned stableDst; /* guarantee that decompressed data will still be there on next function calls (avoid storage into tmp buffers) */ 187 | unsigned reserved[3]; 188 | } LZ4F_decompressOptions_t; 189 | 190 | 191 | /* Resource management */ 192 | 193 | LZ4F_errorCode_t LZ4F_createDecompressionContext(LZ4F_decompressionContext_t* ctxPtr, unsigned version); 194 | LZ4F_errorCode_t LZ4F_freeDecompressionContext(LZ4F_decompressionContext_t ctx); 195 | /* LZ4F_createDecompressionContext() : 196 | * The first thing to do is to create a decompressionContext object, which will be used in all decompression operations. 197 | * This is achieved using LZ4F_createDecompressionContext(). 198 | * The version provided MUST be LZ4F_VERSION. It is intended to track potential version differences between different binaries. 199 | * The function will provide a pointer to a fully allocated and initialized LZ4F_decompressionContext_t object. 200 | * If the result LZ4F_errorCode_t is not OK_NoError, there was an error during context creation. 201 | * Object can release its memory using LZ4F_freeDecompressionContext(); 202 | */ 203 | 204 | 205 | /* Decompression */ 206 | 207 | size_t LZ4F_getFrameInfo(LZ4F_decompressionContext_t ctx, 208 | LZ4F_frameInfo_t* frameInfoPtr, 209 | const void* srcBuffer, size_t* srcSizePtr); 210 | /* LZ4F_getFrameInfo() 211 | * This function decodes frame header information, such as blockSize. 212 | * It is optional : you could start by calling directly LZ4F_decompress() instead. 213 | * The objective is to extract header information without starting decompression, typically for allocation purposes. 214 | * LZ4F_getFrameInfo() can also be used *after* starting decompression, on a valid LZ4F_decompressionContext_t. 215 | * The number of bytes read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value). 216 | * You are expected to resume decompression from where it stopped (srcBuffer + *srcSizePtr) 217 | * The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for next call, 218 | * or an error code which can be tested using LZ4F_isError(). 219 | */ 220 | 221 | size_t LZ4F_decompress(LZ4F_decompressionContext_t ctx, 222 | void* dstBuffer, size_t* dstSizePtr, 223 | const void* srcBuffer, size_t* srcSizePtr, 224 | const LZ4F_decompressOptions_t* optionsPtr); 225 | /* LZ4F_decompress() 226 | * Call this function repetitively to regenerate data compressed within srcBuffer. 227 | * The function will attempt to decode *srcSizePtr bytes from srcBuffer, into dstBuffer of maximum size *dstSizePtr. 228 | * 229 | * The number of bytes regenerated into dstBuffer will be provided within *dstSizePtr (necessarily <= original value). 230 | * 231 | * The number of bytes read from srcBuffer will be provided within *srcSizePtr (necessarily <= original value). 232 | * If number of bytes read is < number of bytes provided, then decompression operation is not completed. 233 | * It typically happens when dstBuffer is not large enough to contain all decoded data. 234 | * LZ4F_decompress() must be called again, starting from where it stopped (srcBuffer + *srcSizePtr) 235 | * The function will check this condition, and refuse to continue if it is not respected. 236 | * 237 | * dstBuffer is supposed to be flushed between each call to the function, since its content will be overwritten. 238 | * dst arguments can be changed at will with each consecutive call to the function. 239 | * 240 | * The function result is an hint of how many srcSize bytes LZ4F_decompress() expects for next call. 241 | * Schematically, it's the size of the current (or remaining) compressed block + header of next block. 242 | * Respecting the hint provides some boost to performance, since it does skip intermediate buffers. 243 | * This is just a hint, you can always provide any srcSize you want. 244 | * When a frame is fully decoded, the function result will be 0. (no more data expected) 245 | * If decompression failed, function result is an error code, which can be tested using LZ4F_isError(). 246 | */ 247 | 248 | 249 | 250 | #if defined (__cplusplus) 251 | } 252 | #endif 253 | -------------------------------------------------------------------------------- /src/app/lz4/lz4.h: -------------------------------------------------------------------------------- 1 | /* 2 | LZ4 - Fast LZ compression algorithm 3 | Header File 4 | Copyright (C) 2011-2014, Yann Collet. 5 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are 9 | met: 10 | 11 | * Redistributions of source code must retain the above copyright 12 | notice, this list of conditions and the following disclaimer. 13 | * Redistributions in binary form must reproduce the above 14 | copyright notice, this list of conditions and the following disclaimer 15 | in the documentation and/or other materials provided with the 16 | distribution. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | You can contact the author at : 31 | - LZ4 source repository : http://code.google.com/p/lz4/ 32 | - LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c 33 | */ 34 | #pragma once 35 | 36 | #if defined (__cplusplus) 37 | extern "C" { 38 | #endif 39 | 40 | /* 41 | * lz4.h provides raw compression format functions, for optimal performance and integration into programs. 42 | * If you need to generate data using an inter-operable format (respecting the framing specification), 43 | * please use lz4frame.h instead. 44 | */ 45 | 46 | /************************************** 47 | Version 48 | **************************************/ 49 | #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ 50 | #define LZ4_VERSION_MINOR 5 /* for new (non-breaking) interface capabilities */ 51 | #define LZ4_VERSION_RELEASE 0 /* for tweaks, bug-fixes, or development */ 52 | #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) 53 | int LZ4_versionNumber (void); 54 | 55 | /************************************** 56 | Tuning parameter 57 | **************************************/ 58 | /* 59 | * LZ4_MEMORY_USAGE : 60 | * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 61 | * Increasing memory usage improves compression ratio 62 | * Reduced memory usage can improve speed, due to cache effect 63 | * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache 64 | */ 65 | #define LZ4_MEMORY_USAGE 14 66 | 67 | 68 | /************************************** 69 | Simple Functions 70 | **************************************/ 71 | 72 | int LZ4_compress (const char* source, char* dest, int sourceSize); 73 | int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize); 74 | 75 | /* 76 | LZ4_compress() : 77 | Compresses 'sourceSize' bytes from 'source' into 'dest'. 78 | Destination buffer must be already allocated, 79 | and must be sized to handle worst cases situations (input data not compressible) 80 | Worst case size evaluation is provided by function LZ4_compressBound() 81 | inputSize : Max supported value is LZ4_MAX_INPUT_SIZE 82 | return : the number of bytes written in buffer dest 83 | or 0 if the compression fails 84 | 85 | LZ4_decompress_safe() : 86 | compressedSize : is obviously the source size 87 | maxDecompressedSize : is the size of the destination buffer, which must be already allocated. 88 | return : the number of bytes decompressed into the destination buffer (necessarily <= maxDecompressedSize) 89 | If the destination buffer is not large enough, decoding will stop and output an error code (<0). 90 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 91 | This function is protected against buffer overflow exploits, 92 | and never writes outside of output buffer, nor reads outside of input buffer. 93 | It is also protected against malicious data packets. 94 | */ 95 | 96 | 97 | /************************************** 98 | Advanced Functions 99 | **************************************/ 100 | #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ 101 | #define LZ4_COMPRESSBOUND(isize) ((unsigned int)(isize) > (unsigned int)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) 102 | 103 | /* 104 | LZ4_compressBound() : 105 | Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) 106 | This function is primarily useful for memory allocation purposes (output buffer size). 107 | Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). 108 | 109 | isize : is the input size. Max supported value is LZ4_MAX_INPUT_SIZE 110 | return : maximum output size in a "worst case" scenario 111 | or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) 112 | */ 113 | int LZ4_compressBound(int isize); 114 | 115 | 116 | /* 117 | LZ4_compress_limitedOutput() : 118 | Compress 'sourceSize' bytes from 'source' into an output buffer 'dest' of maximum size 'maxOutputSize'. 119 | If it cannot achieve it, compression will stop, and result of the function will be zero. 120 | This saves time and memory on detecting non-compressible (or barely compressible) data. 121 | This function never writes outside of provided output buffer. 122 | 123 | sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE 124 | maxOutputSize : is the size of the destination buffer (which must be already allocated) 125 | return : the number of bytes written in buffer 'dest' 126 | or 0 if compression fails 127 | */ 128 | int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); 129 | 130 | 131 | /* 132 | LZ4_compress_withState() : 133 | Same compression functions, but using an externally allocated memory space to store compression state. 134 | Use LZ4_sizeofState() to know how much memory must be allocated, 135 | and then, provide it as 'void* state' to compression functions. 136 | */ 137 | int LZ4_sizeofState(void); 138 | int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); 139 | int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); 140 | 141 | 142 | /* 143 | LZ4_decompress_fast() : 144 | originalSize : is the original and therefore uncompressed size 145 | return : the number of bytes read from the source buffer (in other words, the compressed size) 146 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 147 | Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes. 148 | note : This function fully respect memory boundaries for properly formed compressed data. 149 | It is a bit faster than LZ4_decompress_safe(). 150 | However, it does not provide any protection against intentionally modified data stream (malicious input). 151 | Use this function in trusted environment only (data to decode comes from a trusted source). 152 | */ 153 | int LZ4_decompress_fast (const char* source, char* dest, int originalSize); 154 | 155 | 156 | /* 157 | LZ4_decompress_safe_partial() : 158 | This function decompress a compressed block of size 'compressedSize' at position 'source' 159 | into destination buffer 'dest' of size 'maxDecompressedSize'. 160 | The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached, 161 | reducing decompression time. 162 | return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize) 163 | Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller. 164 | Always control how many bytes were decoded. 165 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 166 | This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets 167 | */ 168 | int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize); 169 | 170 | 171 | /*********************************************** 172 | Streaming Compression Functions 173 | ***********************************************/ 174 | 175 | #define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4) 176 | #define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long)) 177 | /* 178 | * LZ4_stream_t 179 | * information structure to track an LZ4 stream. 180 | * important : init this structure content before first use ! 181 | * note : only allocated directly the structure if you are statically linking LZ4 182 | * If you are using liblz4 as a DLL, please use below construction methods instead. 183 | */ 184 | typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t; 185 | 186 | /* 187 | * LZ4_resetStream 188 | * Use this function to init an allocated LZ4_stream_t structure 189 | */ 190 | void LZ4_resetStream (LZ4_stream_t* LZ4_streamPtr); 191 | 192 | /* 193 | * LZ4_createStream will allocate and initialize an LZ4_stream_t structure 194 | * LZ4_freeStream releases its memory. 195 | * In the context of a DLL (liblz4), please use these methods rather than the static struct. 196 | * They are more future proof, in case of a change of LZ4_stream_t size. 197 | */ 198 | LZ4_stream_t* LZ4_createStream(void); 199 | int LZ4_freeStream (LZ4_stream_t* LZ4_streamPtr); 200 | 201 | /* 202 | * LZ4_loadDict 203 | * Use this function to load a static dictionary into LZ4_stream. 204 | * Any previous data will be forgotten, only 'dictionary' will remain in memory. 205 | * Loading a size of 0 is allowed. 206 | * Return : dictionary size, in bytes (necessarily <= 64 KB) 207 | */ 208 | int LZ4_loadDict (LZ4_stream_t* LZ4_streamPtr, const char* dictionary, int dictSize); 209 | 210 | /* 211 | * LZ4_compress_continue 212 | * Compress data block 'source', using blocks compressed before as dictionary to improve compression ratio 213 | * Previous data blocks are assumed to still be present at their previous location. 214 | */ 215 | int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); 216 | 217 | /* 218 | * LZ4_compress_limitedOutput_continue 219 | * Same as before, but also specify a maximum target compressed size (maxOutputSize) 220 | * If objective cannot be met, compression exits, and returns a zero. 221 | */ 222 | int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); 223 | 224 | /* 225 | * LZ4_saveDict 226 | * If previously compressed data block is not guaranteed to remain available at its memory location 227 | * save it into a safer place (char* safeBuffer) 228 | * Note : you don't need to call LZ4_loadDict() afterwards, 229 | * dictionary is immediately usable, you can therefore call again LZ4_compress_continue() 230 | * Return : dictionary size in bytes, or 0 if error 231 | * Note : any dictSize > 64 KB will be interpreted as 64KB. 232 | */ 233 | int LZ4_saveDict (LZ4_stream_t* LZ4_streamPtr, char* safeBuffer, int dictSize); 234 | 235 | 236 | /************************************************ 237 | Streaming Decompression Functions 238 | ************************************************/ 239 | 240 | #define LZ4_STREAMDECODESIZE_U64 4 241 | #define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) 242 | typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t; 243 | /* 244 | * LZ4_streamDecode_t 245 | * information structure to track an LZ4 stream. 246 | * init this structure content using LZ4_setStreamDecode or memset() before first use ! 247 | * 248 | * In the context of a DLL (liblz4) please prefer usage of construction methods below. 249 | * They are more future proof, in case of a change of LZ4_streamDecode_t size in the future. 250 | * LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure 251 | * LZ4_freeStreamDecode releases its memory. 252 | */ 253 | LZ4_streamDecode_t* LZ4_createStreamDecode(void); 254 | int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); 255 | 256 | /* 257 | * LZ4_setStreamDecode 258 | * Use this function to instruct where to find the dictionary. 259 | * Setting a size of 0 is allowed (same effect as reset). 260 | * Return : 1 if OK, 0 if error 261 | */ 262 | int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); 263 | 264 | /* 265 | *_continue() : 266 | These decoding functions allow decompression of multiple blocks in "streaming" mode. 267 | Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB) 268 | If this condition is not possible, save the relevant part of decoded data into a safe buffer, 269 | and indicate where is its new address using LZ4_setStreamDecode() 270 | */ 271 | int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize); 272 | int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize); 273 | 274 | 275 | /* 276 | Advanced decoding functions : 277 | *_usingDict() : 278 | These decoding functions work the same as 279 | a combination of LZ4_setDictDecode() followed by LZ4_decompress_x_continue() 280 | They are stand-alone and don't use nor update an LZ4_streamDecode_t structure. 281 | */ 282 | int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize); 283 | int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize); 284 | 285 | 286 | 287 | /************************************** 288 | Obsolete Functions 289 | **************************************/ 290 | /* 291 | Obsolete decompression functions 292 | These function names are deprecated and should no longer be used. 293 | They are only provided here for compatibility with older user programs. 294 | - LZ4_uncompress is the same as LZ4_decompress_fast 295 | - LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe 296 | These function prototypes are now disabled; uncomment them if you really need them. 297 | It is highly recommended to stop using these functions and migrate to newer ones */ 298 | /* int LZ4_uncompress (const char* source, char* dest, int outputSize); */ 299 | /* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */ 300 | 301 | 302 | /* Obsolete streaming functions; use new streaming interface whenever possible */ 303 | void* LZ4_create (const char* inputBuffer); 304 | int LZ4_sizeofStreamState(void); 305 | int LZ4_resetStreamState(void* state, const char* inputBuffer); 306 | char* LZ4_slideInputBuffer (void* state); 307 | 308 | /* Obsolete streaming decoding functions */ 309 | int LZ4_decompress_safe_withPrefix64k (const char* source, char* dest, int compressedSize, int maxOutputSize); 310 | int LZ4_decompress_fast_withPrefix64k (const char* source, char* dest, int originalSize); 311 | 312 | 313 | #if defined (__cplusplus) 314 | } 315 | #endif 316 | -------------------------------------------------------------------------------- /src/app/example/main.cpp: -------------------------------------------------------------------------------- 1 | // ImGui - standalone example application for OpenGL 2, using fixed pipeline 2 | 3 | #ifdef _MSC_VER 4 | #pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen 5 | #endif 6 | #ifdef __clang__ 7 | #pragma clang diagnostic ignored "-Wunused-function" // warning: unused function 8 | #endif 9 | 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef _WIN32 17 | #include 18 | #endif 19 | 20 | #ifdef __APPLE__ 21 | #include 22 | #endif 23 | #include "../imgui/imgui.h" 24 | #include 25 | 26 | // @RemoteImgui begin 27 | #include "../imgui_remote.h" 28 | #define VCANVAS_WIDTH 8192 29 | #define VCANVAS_HEIGHT 8192 30 | // @RemoteImgui end 31 | 32 | // Glfw/Glew 33 | #include 34 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 35 | 36 | static GLFWwindow* window; 37 | static bool mousePressed[2] = { false, false }; 38 | 39 | // This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure) 40 | // If text or lines are blurry when integrating ImGui in your engine: 41 | // - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f) 42 | static void ImImpl_RenderDrawLists(ImDrawData* draw_data) 43 | { 44 | // @RemoteImgui begin 45 | ImGui::RemoteDraw(draw_data->CmdLists, draw_data->CmdListsCount); 46 | // @RemoteImgui end 47 | 48 | if (draw_data->CmdListsCount == 0) 49 | return; 50 | 51 | // We are using the OpenGL fixed pipeline to make the example code simpler to read! 52 | // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. 53 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. 54 | glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); 55 | glEnable(GL_BLEND); 56 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 57 | glDisable(GL_CULL_FACE); 58 | glDisable(GL_DEPTH_TEST); 59 | glEnable(GL_SCISSOR_TEST); 60 | glEnableClientState(GL_VERTEX_ARRAY); 61 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 62 | glEnableClientState(GL_COLOR_ARRAY); 63 | glEnable(GL_TEXTURE_2D); 64 | 65 | // Setup orthographic projection matrix 66 | int display_w, display_h; 67 | glfwGetFramebufferSize(window, &display_w, &display_h); 68 | const float width = (float)display_w; 69 | const float height = (float)display_h; 70 | 71 | glMatrixMode(GL_PROJECTION); 72 | glPushMatrix(); 73 | glLoadIdentity(); 74 | glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f); 75 | glMatrixMode(GL_MODELVIEW); 76 | glPushMatrix(); 77 | glLoadIdentity(); 78 | // Render command lists 79 | 80 | for (int n = 0; n < draw_data->CmdListsCount; n++) 81 | { 82 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 83 | const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); 84 | const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); 85 | glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); 86 | glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); 87 | glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); 88 | 89 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) 90 | { 91 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 92 | if (pcmd->UserCallback) 93 | { 94 | pcmd->UserCallback(cmd_list, pcmd); 95 | } 96 | else 97 | { 98 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); 99 | glScissor((int)pcmd->ClipRect.x, (int)(height - pcmd->ClipRect.w), (int)(pcmd->ClipRect.z - pcmd->ClipRect.x), (int)(pcmd->ClipRect.w - pcmd->ClipRect.y)); 100 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer); 101 | } 102 | idx_buffer += pcmd->ElemCount; 103 | } 104 | } 105 | 106 | // Restore modified state 107 | glDisableClientState(GL_COLOR_ARRAY); 108 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); 109 | glDisableClientState(GL_VERTEX_ARRAY); 110 | glMatrixMode(GL_MODELVIEW); 111 | glPopMatrix(); 112 | glMatrixMode(GL_PROJECTION); 113 | glPopMatrix(); 114 | glPopAttrib(); 115 | } 116 | 117 | // NB: ImGui already provide OS clipboard support for Windows so this isn't needed if you are using Windows only. 118 | static const char* ImImpl_GetClipboardTextFn() 119 | { 120 | return glfwGetClipboardString(window); 121 | } 122 | 123 | static void ImImpl_SetClipboardTextFn(const char* text) 124 | { 125 | glfwSetClipboardString(window, text); 126 | } 127 | 128 | // GLFW callbacks to get events 129 | static void glfw_error_callback(int error, const char* description) 130 | { 131 | fputs(description, stderr); 132 | } 133 | 134 | static void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods) 135 | { 136 | if (action == GLFW_PRESS && button >= 0 && button < 2) 137 | mousePressed[button] = true; 138 | } 139 | 140 | static void glfw_scroll_callback(GLFWwindow* window, double xoffset, double yoffset) 141 | { 142 | ImGuiIO& io = ImGui::GetIO(); 143 | io.MouseWheel += (float)yoffset; // Use fractional mouse wheel, 1.0 unit 5 lines. 144 | } 145 | 146 | static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 147 | { 148 | ImGuiIO& io = ImGui::GetIO(); 149 | if (action == GLFW_PRESS) 150 | io.KeysDown[key] = true; 151 | if (action == GLFW_RELEASE) 152 | io.KeysDown[key] = false; 153 | io.KeyCtrl = (mods & GLFW_MOD_CONTROL) != 0; 154 | io.KeyShift = (mods & GLFW_MOD_SHIFT) != 0; 155 | } 156 | 157 | static void glfw_char_callback(GLFWwindow* window, unsigned int c) 158 | { 159 | if (c > 0 && c < 0x10000) 160 | ImGui::GetIO().AddInputCharacter((unsigned short)c); 161 | } 162 | 163 | void InitGL() 164 | { 165 | glfwSetErrorCallback(glfw_error_callback); 166 | if (!glfwInit()) 167 | exit(1); 168 | 169 | window = glfwCreateWindow(1280, 720, "ImGui OpenGL2 example", NULL, NULL); 170 | glfwMakeContextCurrent(window); 171 | glfwSetKeyCallback(window, glfw_key_callback); 172 | glfwSetMouseButtonCallback(window, glfw_mouse_button_callback); 173 | glfwSetScrollCallback(window, glfw_scroll_callback); 174 | glfwSetCharCallback(window, glfw_char_callback); 175 | 176 | } 177 | 178 | void LoadFontsTexture() 179 | { 180 | ImGuiIO& io = ImGui::GetIO(); 181 | //ImFont* my_font1 = io.Fonts->AddFontDefault(); 182 | //ImFont* my_font2 = io.Fonts->AddFontFromFileTTF("extra_fonts/Karla-Regular.ttf", 15.0f); 183 | //ImFont* my_font3 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyClean.ttf", 13.0f); my_font3->DisplayOffset.y += 1; 184 | //ImFont* my_font4 = io.Fonts->AddFontFromFileTTF("extra_fonts/ProggyTiny.ttf", 10.0f); my_font4->DisplayOffset.y += 1; 185 | //ImFont* my_font5 = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 20.0f, io.Fonts->GetGlyphRangesJapanese()); 186 | 187 | unsigned char* pixels; 188 | int width, height; 189 | io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); 190 | 191 | GLuint tex_id; 192 | glGenTextures(1, &tex_id); 193 | glBindTexture(GL_TEXTURE_2D, tex_id); 194 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 195 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 196 | glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); 197 | 198 | // Store our identifier 199 | io.Fonts->TexID = (void *)(intptr_t)tex_id; 200 | } 201 | 202 | void InitImGui() 203 | { 204 | ImGuiIO& io = ImGui::GetIO(); 205 | io.DeltaTime = 1.0f/60.0f; // Time elapsed since last frame, in seconds (in this sample app we'll override this every frame because our time step is variable) 206 | io.KeyMap[ImGuiKey_Tab] = GLFW_KEY_TAB; // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 207 | io.KeyMap[ImGuiKey_LeftArrow] = GLFW_KEY_LEFT; 208 | io.KeyMap[ImGuiKey_RightArrow] = GLFW_KEY_RIGHT; 209 | io.KeyMap[ImGuiKey_UpArrow] = GLFW_KEY_UP; 210 | io.KeyMap[ImGuiKey_DownArrow] = GLFW_KEY_DOWN; 211 | io.KeyMap[ImGuiKey_Home] = GLFW_KEY_HOME; 212 | io.KeyMap[ImGuiKey_End] = GLFW_KEY_END; 213 | io.KeyMap[ImGuiKey_Delete] = GLFW_KEY_DELETE; 214 | io.KeyMap[ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE; 215 | io.KeyMap[ImGuiKey_Enter] = GLFW_KEY_ENTER; 216 | io.KeyMap[ImGuiKey_Escape] = GLFW_KEY_ESCAPE; 217 | io.KeyMap[ImGuiKey_A] = GLFW_KEY_A; 218 | io.KeyMap[ImGuiKey_C] = GLFW_KEY_C; 219 | io.KeyMap[ImGuiKey_V] = GLFW_KEY_V; 220 | io.KeyMap[ImGuiKey_X] = GLFW_KEY_X; 221 | io.KeyMap[ImGuiKey_Y] = GLFW_KEY_Y; 222 | io.KeyMap[ImGuiKey_Z] = GLFW_KEY_Z; 223 | 224 | io.RenderDrawListsFn = ImImpl_RenderDrawLists; 225 | io.SetClipboardTextFn = ImImpl_SetClipboardTextFn; 226 | io.GetClipboardTextFn = ImImpl_GetClipboardTextFn; 227 | 228 | LoadFontsTexture(); 229 | 230 | // @RemoteImgui begin 231 | ImGui::RemoteInit("0.0.0.0", 7002); // local host, local port 232 | //ImGui::GetStyle().WindowRounding = 0.f; // no rounding uses less bandwidth 233 | io.DisplaySize = ImVec2((float)VCANVAS_WIDTH, (float)VCANVAS_HEIGHT); 234 | // @RemoteImgui end 235 | } 236 | 237 | void UpdateImGui() 238 | { 239 | ImGuiIO& io = ImGui::GetIO(); 240 | 241 | // Setup resolution (every frame to accommodate for window resizing) 242 | int w, h; 243 | int display_w, display_h; 244 | glfwGetWindowSize(window, &w, &h); 245 | glfwGetFramebufferSize(window, &display_w, &display_h); 246 | 247 | // Setup time step 248 | static double time = 0.0f; 249 | const double current_time = glfwGetTime(); 250 | io.DeltaTime = (float)(current_time - time); 251 | time = current_time; 252 | 253 | // @RemoteImgui begin 254 | ImGui::RemoteUpdate(); 255 | ImGui::RemoteInput input; 256 | if (ImGui::RemoteGetInput(input)) 257 | { 258 | ImGuiIO& io = ImGui::GetIO(); 259 | for (int i = 0; i < 256; i++) 260 | io.KeysDown[i] = input.KeysDown[i]; 261 | io.KeyCtrl = input.KeyCtrl; 262 | io.KeyShift = input.KeyShift; 263 | io.MousePos = input.MousePos; 264 | io.MouseDown[0] = (input.MouseButtons & 1); 265 | io.MouseDown[1] = (input.MouseButtons & 2) != 0; 266 | io.MouseWheel += input.MouseWheelDelta; 267 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 268 | io.KeyMap[ImGuiKey_Tab] = ImGuiKey_Tab; 269 | io.KeyMap[ImGuiKey_LeftArrow] = ImGuiKey_LeftArrow; 270 | io.KeyMap[ImGuiKey_RightArrow] = ImGuiKey_RightArrow; 271 | io.KeyMap[ImGuiKey_UpArrow] = ImGuiKey_UpArrow; 272 | io.KeyMap[ImGuiKey_DownArrow] = ImGuiKey_DownArrow; 273 | io.KeyMap[ImGuiKey_Home] = ImGuiKey_Home; 274 | io.KeyMap[ImGuiKey_End] = ImGuiKey_End; 275 | io.KeyMap[ImGuiKey_Delete] = ImGuiKey_Delete; 276 | io.KeyMap[ImGuiKey_Backspace] = ImGuiKey_Backspace; 277 | io.KeyMap[ImGuiKey_Enter] = 13; 278 | io.KeyMap[ImGuiKey_Escape] = 27; 279 | io.KeyMap[ImGuiKey_A] = 'a'; 280 | io.KeyMap[ImGuiKey_C] = 'c'; 281 | io.KeyMap[ImGuiKey_V] = 'v'; 282 | io.KeyMap[ImGuiKey_X] = 'x'; 283 | io.KeyMap[ImGuiKey_Y] = 'y'; 284 | io.KeyMap[ImGuiKey_Z] = 'z'; 285 | } 286 | else 287 | // @RemoteImgui end 288 | { 289 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 290 | io.KeyMap[ImGuiKey_Tab] = 9; 291 | io.KeyMap[ImGuiKey_LeftArrow] = ImGuiKey_LeftArrow; 292 | io.KeyMap[ImGuiKey_RightArrow] = ImGuiKey_RightArrow; 293 | io.KeyMap[ImGuiKey_UpArrow] = ImGuiKey_UpArrow; 294 | io.KeyMap[ImGuiKey_DownArrow] = ImGuiKey_DownArrow; 295 | io.KeyMap[ImGuiKey_Home] = ImGuiKey_Home; 296 | io.KeyMap[ImGuiKey_End] = ImGuiKey_End; 297 | io.KeyMap[ImGuiKey_Delete] = ImGuiKey_Delete; 298 | io.KeyMap[ImGuiKey_Backspace] = 127; 299 | io.KeyMap[ImGuiKey_Enter] = 13; 300 | io.KeyMap[ImGuiKey_Escape] = 27; 301 | io.KeyMap[ImGuiKey_A] = 'a'; 302 | io.KeyMap[ImGuiKey_C] = 'c'; 303 | io.KeyMap[ImGuiKey_V] = 'v'; 304 | io.KeyMap[ImGuiKey_X] = 'x'; 305 | io.KeyMap[ImGuiKey_Y] = 'y'; 306 | io.KeyMap[ImGuiKey_Z] = 'z'; 307 | 308 | // Setup inputs 309 | // (we already got mouse wheel, keyboard keys & characters from glfw callbacks polled in glfwPollEvents()) 310 | double mouse_x, mouse_y; 311 | glfwGetCursorPos(window, &mouse_x, &mouse_y); 312 | mouse_x *= (float)display_w / w; // Convert mouse coordinates to pixels 313 | mouse_y *= (float)display_h / h; 314 | io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) 315 | io.MouseDown[0] = mousePressed[0] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) != 0; // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. 316 | io.MouseDown[1] = mousePressed[1] || glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_RIGHT) != 0; 317 | } 318 | 319 | // Start the frame 320 | ImGui::NewFrame(); 321 | } 322 | 323 | // Application code 324 | int main(int argc, char** argv) 325 | { 326 | InitGL(); 327 | InitImGui(); 328 | 329 | bool show_test_window = true; 330 | bool show_another_window = false; 331 | ImVec4 clear_col = ImColor(114, 144, 154); 332 | 333 | while (!glfwWindowShouldClose(window)) 334 | { 335 | ImGuiIO& io = ImGui::GetIO(); 336 | mousePressed[0] = mousePressed[1] = false; 337 | glfwPollEvents(); 338 | UpdateImGui(); 339 | 340 | // 1. Show a simple window 341 | // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" 342 | { 343 | static float f; 344 | ImGui::Text("Hello, world!"); 345 | ImGui::SliderFloat("float", &f, 0.0f, 1.0f); 346 | ImGui::ColorEdit3("clear color", (float*)&clear_col); 347 | if (ImGui::Button("Test Window")) show_test_window ^= 1; 348 | if (ImGui::Button("Another Window")) show_another_window ^= 1; 349 | 350 | // Calculate and show frame rate 351 | static float ms_per_frame[120] = { 0 }; 352 | static int ms_per_frame_idx = 0; 353 | static float ms_per_frame_accum = 0.0f; 354 | ms_per_frame_accum -= ms_per_frame[ms_per_frame_idx]; 355 | ms_per_frame[ms_per_frame_idx] = ImGui::GetIO().DeltaTime * 1000.0f; 356 | ms_per_frame_accum += ms_per_frame[ms_per_frame_idx]; 357 | ms_per_frame_idx = (ms_per_frame_idx + 1) % 120; 358 | const float ms_per_frame_avg = ms_per_frame_accum / 120; 359 | ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", ms_per_frame_avg, 1000.0f / ms_per_frame_avg); 360 | } 361 | 362 | // 2. Show another simple window, this time using an explicit Begin/End pair 363 | if (show_another_window) 364 | { 365 | ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); 366 | ImGui::Text("Hello"); 367 | ImGui::End(); 368 | } 369 | 370 | // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() 371 | if (show_test_window) 372 | { 373 | ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); 374 | ImGui::ShowTestWindow(&show_test_window); 375 | } 376 | 377 | int display_w, display_h; 378 | glfwGetFramebufferSize(window, &display_w, &display_h); 379 | 380 | // Rendering 381 | glViewport(0, 0, display_w, display_h); 382 | glClearColor(clear_col.x, clear_col.y, clear_col.z, clear_col.w); 383 | glClear(GL_COLOR_BUFFER_BIT); 384 | ImGui::Render(); 385 | glfwSwapBuffers(window); 386 | } 387 | 388 | // Cleanup 389 | ImGui::Shutdown(); 390 | glfwTerminate(); 391 | 392 | return 0; 393 | } 394 | -------------------------------------------------------------------------------- /src/app/imgui_remote.h: -------------------------------------------------------------------------------- 1 | //----------------------------------------------------------------------------- 2 | // Remote ImGui https://github.com/JordiRos/remoteimgui 3 | // Uses 4 | // ImGui https://github.com/ocornut/imgui 1.3 5 | // Webby https://github.com/deplinenoise/webby 6 | // LZ4 https://code.google.com/p/lz4/ 7 | //----------------------------------------------------------------------------- 8 | 9 | #include "lz4/lz4.h" 10 | #include 11 | 12 | #define IMGUI_REMOTE_KEY_FRAME 60 // send keyframe every 30 frames 13 | #define IMGUI_REMOTE_INPUT_FRAMES 60 // input valid during 120 frames 14 | 15 | namespace ImGui { 16 | 17 | //------------------ 18 | // ImGuiRemoteInput 19 | // - a structure to store input received from remote imgui, so you can use it on your whole app (keys, mouse) or just in imgui engine 20 | // - use GetImGuiRemoteInput to read input data safely (valid for IMGUI_REMOTE_INPUT_FRAMES) 21 | //------------------ 22 | struct RemoteInput 23 | { 24 | ImVec2 MousePos; 25 | int MouseButtons; 26 | float MouseWheelDelta; 27 | bool KeyCtrl; 28 | bool KeyShift; 29 | bool KeysDown[ 256 ]; 30 | }; 31 | 32 | //------------------ 33 | // IWebSocketServer 34 | // - WebSocketServer interface 35 | //------------------ 36 | /* 37 | struct IWebSocketServer 38 | { 39 | enum OpCode 40 | { 41 | Text, 42 | Binary, 43 | Disconnect, 44 | Ping, 45 | Pong 46 | }; 47 | void Init(const char *bind_address, int port); 48 | void Shutdown(); 49 | void SendText(const void *data, int size); 50 | void SendBinary(const void *data, int size); 51 | virtual void OnMessage(OpCode opcode, const void *data, int size) { } 52 | virtual void OnError() { } 53 | }; 54 | */ 55 | 56 | template class Vector 57 | { 58 | private: 59 | T * Items; 60 | unsigned int Size; 61 | unsigned int Capacity; 62 | public: 63 | Vector() 64 | : Items( NULL ) 65 | , Size( 0 ) 66 | , Capacity( 0 ) 67 | { 68 | reserve( 16 ); 69 | } 70 | Vector( unsigned int initialCapacity ) 71 | : Items( NULL ) 72 | , Size( 0 ) 73 | , Capacity( 0 ) 74 | { 75 | reserve( initialCapacity ); 76 | } 77 | ~Vector() 78 | { 79 | if ( Items ) 80 | { 81 | ImGui::MemFree( Items ); 82 | Items = nullptr; 83 | } 84 | } 85 | void push_back( T item ) 86 | { 87 | if ( Size >= Capacity ) 88 | { 89 | reserve( Capacity * 2 ); 90 | } 91 | Items[ Size++ ] = item; 92 | } 93 | void clear() 94 | { 95 | Size = 0; 96 | } 97 | void reserve( const unsigned int newCapacity ) 98 | { 99 | if ( newCapacity <= Capacity ) 100 | { 101 | return; 102 | } 103 | T * newItems = (T*) ImGui::MemAlloc( newCapacity * sizeof( T ) ); 104 | if ( Items ) 105 | { 106 | memcpy( newItems, Items, Capacity * sizeof( T ) ); 107 | ImGui::MemFree( Items ); 108 | } 109 | 110 | Items = newItems; 111 | Capacity = newCapacity; 112 | } 113 | const unsigned int size() 114 | { 115 | return Size; 116 | } 117 | T & operator[]( unsigned int index ) 118 | { 119 | return Items[ index ]; 120 | } 121 | }; 122 | 123 | #include "imgui_remote_webby.h" 124 | 125 | //------------------ 126 | // WebSocketServer 127 | // - ImGui web socket server connection 128 | //------------------ 129 | struct WebSocketServer : public IWebSocketServer 130 | { 131 | bool ClientActive; 132 | int Frame; 133 | int FrameReceived; 134 | int PrevPacketSize; 135 | bool IsKeyFrame; 136 | bool ForceKeyFrame; 137 | Vector Packet; 138 | Vector PrevPacket; 139 | RemoteInput Input; 140 | bool Supports32BitIndexBuffers; 141 | 142 | WebSocketServer() 143 | { 144 | ClientActive = false; 145 | Frame = 0; 146 | FrameReceived = 0; 147 | IsKeyFrame = false; 148 | PrevPacketSize = 0; 149 | Supports32BitIndexBuffers = false; 150 | } 151 | inline bool mapRemoteKey( int* remoteKey, bool isCtrlPressed ) 152 | { 153 | if ( *remoteKey == 37 ) 154 | *remoteKey = ImGuiKey_LeftArrow; 155 | else if ( *remoteKey == 40 ) 156 | *remoteKey = ImGuiKey_DownArrow; 157 | else if ( *remoteKey == 38 ) 158 | *remoteKey = ImGuiKey_UpArrow; 159 | else if ( *remoteKey == 39 ) 160 | *remoteKey = ImGuiKey_RightArrow; 161 | else if ( *remoteKey == 46 ) 162 | *remoteKey = ImGuiKey_Delete; 163 | else if ( *remoteKey == 9 ) 164 | *remoteKey = ImGuiKey_Tab; 165 | else if ( *remoteKey == 8 ) 166 | *remoteKey = ImGuiKey_Backspace; 167 | else if ( *remoteKey == 65 && isCtrlPressed ) 168 | *remoteKey = 'a'; 169 | else if ( *remoteKey == 67 && isCtrlPressed ) 170 | *remoteKey = 'c'; 171 | else if ( *remoteKey == 86 && isCtrlPressed ) 172 | *remoteKey = 'v'; 173 | else if ( *remoteKey == 88 && isCtrlPressed ) 174 | *remoteKey = 'x'; 175 | else 176 | return true; 177 | 178 | return false; 179 | } 180 | virtual void OnMessage( OpCode opcode, const void *data, int /*size*/ ) 181 | { 182 | switch ( opcode ) 183 | { 184 | // Text message 185 | case WebSocketServer::Text: 186 | if ( !ClientActive ) 187 | { 188 | if ( strstr( (char *) data, "ImInit" ) ) 189 | { 190 | // The browser lets us know if it can do 32-bit indexbuffers 191 | int supports32bitIB = 0; 192 | if ( sscanf( (char *) data, "ImInit;IB32=%d", &supports32bitIB ) == 1 ) 193 | { 194 | Supports32BitIndexBuffers = ( supports32bitIB != 0 ); 195 | } 196 | ClientActive = true; 197 | ForceKeyFrame = true; 198 | // Send confirmation with the indexbuffer size we negotiated 199 | // (This is for backwards compatibility, where if we don't send this header, 200 | // a newer client won't increase the element size) 201 | char sz[ 32 ]; 202 | snprintf( sz, 32, "ImInit;IB32=%d", Supports32BitIndexBuffers ? 1 : 0 ); 203 | SendText( sz, strlen( sz ) ); 204 | // Send font texture 205 | unsigned char* pixels; 206 | int width, height; 207 | ImGui::GetIO().Fonts->GetTexDataAsAlpha8( &pixels, &width, &height ); 208 | PreparePacketTexFont( pixels, width, height ); 209 | SendPacket(); 210 | } 211 | } 212 | else if ( strstr( (char *) data, "ImMouseMove" ) ) 213 | { 214 | int x, y, mouse_left, mouse_right; 215 | if ( sscanf( (char *) data, "ImMouseMove=%d,%d,%d,%d", &x, &y, &mouse_left, &mouse_right ) == 4 ) 216 | { 217 | FrameReceived = Frame; 218 | Input.MousePos.x = (float) x; 219 | Input.MousePos.y = (float) y; 220 | Input.MouseButtons = mouse_left | ( mouse_right << 1 ); 221 | } 222 | } 223 | else if ( strstr( (char *) data, "ImMousePress" ) ) 224 | { 225 | int l, r; 226 | if ( sscanf( (char *) data, "ImMousePress=%d,%d", &l, &r ) == 2 ) 227 | { 228 | FrameReceived = Frame; 229 | Input.MouseButtons = l | ( r << 1 ); 230 | } 231 | } 232 | else if ( strstr( (char *) data, "ImMouseWheelDelta" ) ) 233 | { 234 | float mouseWheelDelta; 235 | if ( sscanf( (char *) data, "ImMouseWheelDelta=%f", &mouseWheelDelta ) == 1 ) 236 | { 237 | FrameReceived = Frame; 238 | Input.MouseWheelDelta = mouseWheelDelta *0.01f; 239 | } 240 | } 241 | else if ( strstr( (char *) data, "ImKeyDown" ) ) 242 | { 243 | int key, shift, ctrl; 244 | if ( sscanf( (char *) data, "ImKeyDown=%d,%d,%d", &key, &shift, &ctrl ) == 3 ) 245 | { 246 | //update key states 247 | FrameReceived = Frame; 248 | Input.KeyShift = shift > 0; 249 | Input.KeyCtrl = ctrl > 0; 250 | mapRemoteKey( &key, Input.KeyCtrl ); 251 | Input.KeysDown[ key ] = true; 252 | } 253 | } 254 | else if ( strstr( (char *) data, "ImKeyUp" ) ) 255 | { 256 | int key; 257 | if ( sscanf( (char *) data, "ImKeyUp=%d", &key ) == 1 ) 258 | { 259 | //update key states 260 | FrameReceived = Frame; 261 | Input.KeysDown[ key ] = false; 262 | Input.KeyShift = false; 263 | Input.KeyCtrl = false; 264 | } 265 | } 266 | else if ( strstr( (char *) data, "ImKeyPress" ) ) 267 | { 268 | unsigned int key; 269 | if ( sscanf( (char *) data, "ImKeyPress=%d", &key ) == 1 ) 270 | ImGui::GetIO().AddInputCharacter( ImWchar( key ) ); 271 | } 272 | else if ( strstr( (char *) data, "ImClipboard=" ) ) 273 | { 274 | char *clipboard = &( (char *) data )[ strlen( "ImClipboard=" ) ]; 275 | ImGui::GetIO().SetClipboardTextFn( clipboard ); 276 | } 277 | break; 278 | // Binary message 279 | case WebSocketServer::Binary: 280 | //printf("ImGui client: Binary message received (%d bytes)\n", size); 281 | break; 282 | // Disconnect 283 | case WebSocketServer::Disconnect: 284 | printf( "ImGui client: DISCONNECT\n" ); 285 | ClientActive = false; 286 | break; 287 | // Ping 288 | case WebSocketServer::Ping: 289 | printf( "ImGui client: PING\n" ); 290 | break; 291 | // Pong 292 | case WebSocketServer::Pong: 293 | printf( "ImGui client: PONG\n" ); 294 | break; 295 | default: 296 | assert( 0 ); 297 | break; 298 | } 299 | } 300 | 301 | #pragma pack(1) 302 | struct Cmd 303 | { 304 | int elemCount; 305 | float clip_rect[ 4 ]; 306 | void Set( const ImDrawCmd &draw_cmd ) 307 | { 308 | elemCount = draw_cmd.ElemCount; 309 | clip_rect[ 0 ] = draw_cmd.ClipRect.x; 310 | clip_rect[ 1 ] = draw_cmd.ClipRect.y; 311 | clip_rect[ 2 ] = draw_cmd.ClipRect.z; 312 | clip_rect[ 3 ] = draw_cmd.ClipRect.w; 313 | //printf("DrawCmd: %d ( %.2f, %.2f, %.2f, %.2f )\n", vtx_count, clip_rect[0], clip_rect[1], clip_rect[2], clip_rect[3]); 314 | } 315 | }; 316 | struct Vtx 317 | { 318 | short x, y; // 16 short 319 | short u, v; // 16 fixed point 320 | unsigned char r, g, b, a; // 8*4 321 | void Set( const ImDrawVert &vtx ) 322 | { 323 | x = (short) ( vtx.pos.x ); 324 | y = (short) ( vtx.pos.y ); 325 | u = (short) ( vtx.uv.x * 32767.f ); 326 | v = (short) ( vtx.uv.y * 32767.f ); 327 | r = ( vtx.col >> 0 ) & 0xff; 328 | g = ( vtx.col >> 8 ) & 0xff; 329 | b = ( vtx.col >> 16 ) & 0xff; 330 | a = ( vtx.col >> 24 ) & 0xff; 331 | } 332 | }; 333 | struct Idx32 334 | { 335 | unsigned int idx; 336 | 337 | void Set( ImDrawIdx _idx ) 338 | { 339 | idx = _idx; 340 | } 341 | }; 342 | struct Idx16 343 | { 344 | unsigned short idx; 345 | 346 | void Set( ImDrawIdx _idx ) 347 | { 348 | assert( _idx <= 0xFFFF ); 349 | idx = (unsigned short) _idx; 350 | } 351 | }; 352 | 353 | #pragma pack() 354 | 355 | void Write( unsigned char c ) { Packet.push_back( c ); } 356 | void Write( unsigned int i ) 357 | { 358 | if ( IsKeyFrame ) 359 | Write( &i, sizeof( unsigned int ) ); 360 | else 361 | WriteDiff( &i, sizeof( unsigned int ) ); 362 | } 363 | void Write( Cmd const &cmd ) 364 | { 365 | if ( IsKeyFrame ) 366 | Write( (void *) &cmd, sizeof( Cmd ) ); 367 | else 368 | WriteDiff( (void *) &cmd, sizeof( Cmd ) ); 369 | } 370 | void Write( Vtx const &vtx ) 371 | { 372 | if ( IsKeyFrame ) 373 | Write( (void *) &vtx, sizeof( Vtx ) ); 374 | else 375 | WriteDiff( (void *) &vtx, sizeof( Vtx ) ); 376 | } 377 | void Write( Idx16 const &idx ) 378 | { 379 | if ( IsKeyFrame ) 380 | Write( (void *) &idx, sizeof( Idx16 ) ); 381 | else 382 | WriteDiff( (void *) &idx, sizeof( Idx16 ) ); 383 | } 384 | void Write( Idx32 const &idx ) 385 | { 386 | if ( IsKeyFrame ) 387 | Write( (void *) &idx, sizeof( Idx32 ) ); 388 | else 389 | WriteDiff( (void *) &idx, sizeof( Idx32 ) ); 390 | } 391 | 392 | void Write( const void *data, int size ) 393 | { 394 | unsigned char *src = (unsigned char *) data; 395 | for ( int i = 0; i < size; i++ ) 396 | { 397 | int pos = (int) Packet.size(); 398 | Write( src[ i ] ); 399 | PrevPacket[ pos ] = src[ i ]; 400 | } 401 | } 402 | void WriteDiff( const void *data, int size ) 403 | { 404 | unsigned char *src = (unsigned char *) data; 405 | for ( int i = 0; i < size; i++ ) 406 | { 407 | int pos = (int) Packet.size(); 408 | Write( (unsigned char) ( src[ i ] - ( pos < PrevPacketSize ? PrevPacket[ pos ] : 0 ) ) ); 409 | PrevPacket[ pos ] = src[ i ]; 410 | } 411 | } 412 | 413 | void SendPacket() 414 | { 415 | static int buffer[ 65536 ]; 416 | unsigned int * bufferU32 = ( unsigned int * )buffer; 417 | int originalSize = ( int )Packet.size(); 418 | int size = originalSize; 419 | int offset = 0; 420 | const unsigned int magicHeaderStart = 0xDEADDA7A; // Incomplete packet 421 | const unsigned int magicHeaderEnd = 0xBAADFEED; // Final packet 422 | do 423 | { 424 | int csize = LZ4_compress_limitedOutput( ( char * )&Packet[ offset ], ( char * )( buffer + 3 ), size, 65536 * sizeof( int ) - 12 ); 425 | if ( csize == 0 ) 426 | { 427 | // If packet fails to compress, halve the data and try again 428 | size /= 2; 429 | continue; 430 | } 431 | // If this is the final packet, mark it as final and finish 432 | bool isFinalPacket = offset + size == originalSize; 433 | bufferU32[ 0 ] = isFinalPacket ? magicHeaderEnd : magicHeaderStart; // Our LZ4 header magic number (used in custom lz4.js to decompress) 434 | bufferU32[ 1 ] = size; 435 | bufferU32[ 2 ] = csize; 436 | SendBinary( buffer, csize + 12 ); 437 | if ( isFinalPacket ) 438 | { 439 | break; 440 | } 441 | // Otherwise, try to compress the rest in one go 442 | offset += size; 443 | size = originalSize - offset; 444 | } while ( true ); 445 | //printf("ImWebSocket SendPacket: %s %d / %d (%.2f%%)\n", IsKeyFrame ? "(KEY)" : "", size, csize, (float)csize * 100.f / size); 446 | PrevPacketSize = size; 447 | } 448 | 449 | void PreparePacket( unsigned char data_type, unsigned int data_size ) 450 | { 451 | unsigned int size = sizeof( unsigned char ) + data_size; 452 | Packet.clear(); 453 | Packet.reserve( size ); 454 | PrevPacket.reserve( size ); 455 | while ( size > PrevPacket.size() ) 456 | PrevPacket.push_back( 0 ); 457 | Write( data_type ); 458 | } 459 | 460 | // packet types 461 | enum { TEX_FONT = 255, FRAME_KEY = 254, FRAME_DIFF = 253 }; 462 | 463 | void PreparePacketTexFont( const void *data, unsigned int w, unsigned int h ) 464 | { 465 | IsKeyFrame = true; 466 | PreparePacket( TEX_FONT, sizeof( unsigned int ) * 2 + w*h ); 467 | Write( w ); 468 | Write( h ); 469 | Write( data, w*h ); 470 | ForceKeyFrame = true; 471 | } 472 | 473 | void PreparePacketFrame( unsigned int size )//unsigned int cmd_count, unsigned int vtx_count, unsigned int idx_count) 474 | { 475 | IsKeyFrame = ( Frame%IMGUI_REMOTE_KEY_FRAME ) == 0 || ForceKeyFrame; 476 | PreparePacket( (unsigned char) ( IsKeyFrame ? FRAME_KEY : FRAME_DIFF ), size ); 477 | //printf("ImWebSocket PreparePacket: cmd_count = %i, vtx_count = %i ( %lu bytes )\n", cmd_count, vtx_count, sizeof(unsigned int) + sizeof(unsigned int) + cmd_count * sizeof(Cmd) + vtx_count * sizeof(Vtx)); 478 | ForceKeyFrame = false; 479 | } 480 | }; 481 | 482 | 483 | static WebSocketServer GServer; 484 | 485 | 486 | //------------------ 487 | // RemoteGetInput 488 | // - get input received from remote safely (valid for 30 frames) 489 | //------------------ 490 | bool RemoteGetInput( RemoteInput & input ) 491 | { 492 | bool res = false; 493 | if ( GServer.ClientActive ) 494 | { 495 | 496 | if ( GServer.Frame - GServer.FrameReceived < IMGUI_REMOTE_INPUT_FRAMES ) 497 | { 498 | input = GServer.Input; 499 | res = true; 500 | } 501 | } 502 | memset( GServer.Input.KeysDown, 0, 256 * sizeof( bool ) ); 503 | GServer.Input.KeyCtrl = false; 504 | GServer.Input.KeyShift = false; 505 | GServer.Input.MouseWheelDelta = 0; 506 | return res; 507 | } 508 | 509 | 510 | //------------------ 511 | // RemoteInit 512 | // - initialize RemoteImGui on top of your ImGui 513 | //------------------ 514 | void RemoteInit( const char *local_address, int local_port ) 515 | { 516 | GServer.Init( local_address, local_port ); 517 | } 518 | 519 | 520 | //------------------ 521 | // RemoteShutdown 522 | // - shutdown RemoteImGui 523 | //------------------ 524 | void RemoteShutdown() 525 | { 526 | GServer.Shutdown(); 527 | } 528 | 529 | 530 | //------------------ 531 | // RemoteUpdate 532 | // - update RemoteImGui stuff 533 | //------------------ 534 | void RemoteUpdate() 535 | { 536 | GServer.Frame++; 537 | GServer.Update(); 538 | } 539 | 540 | 541 | //------------------ 542 | // RemoteDraw 543 | // - send draw list commands to connected client 544 | //------------------ 545 | void RemoteDraw( ImDrawList** const cmd_lists, int cmd_lists_count ) 546 | { 547 | if ( GServer.ClientActive ) 548 | { 549 | static int sendframe = 0; 550 | if ( sendframe++ < 2 ) // every 2 frames, @TWEAK 551 | { 552 | return; 553 | } 554 | sendframe = 0; 555 | 556 | unsigned int totalSize = sizeof( unsigned int ); // cmd_lists_count 557 | for ( int n = 0; n < cmd_lists_count; n++ ) 558 | { 559 | const ImDrawList* cmd_list = cmd_lists[ n ]; 560 | int cmd_count = cmd_list->CmdBuffer.size(); 561 | int vtx_count = cmd_list->VtxBuffer.size(); 562 | int idx_count = cmd_list->IdxBuffer.size(); 563 | totalSize += 3 * sizeof( unsigned int ); //cmd_count, vtx_count and idx_count 564 | totalSize += cmd_count * sizeof( WebSocketServer::Cmd ) + vtx_count * sizeof( WebSocketServer::Vtx ); 565 | totalSize += GServer.Supports32BitIndexBuffers ? ( idx_count * sizeof( WebSocketServer::Idx32 ) ) : ( idx_count * sizeof( WebSocketServer::Idx16 ) ); 566 | } 567 | 568 | GServer.PreparePacketFrame( totalSize ); 569 | GServer.Write( (unsigned int) cmd_lists_count ); 570 | 571 | for ( int n = 0; n < cmd_lists_count; n++ ) 572 | { 573 | const ImDrawList* cmd_list = cmd_lists[ n ]; 574 | const ImDrawVert * vtx_src = cmd_list->VtxBuffer.begin(); 575 | const ImDrawIdx * idx_src = cmd_list->IdxBuffer.begin(); 576 | unsigned int cmd_count = cmd_list->CmdBuffer.size(); 577 | unsigned int vtx_count = cmd_list->VtxBuffer.size(); 578 | unsigned int idx_count = cmd_list->IdxBuffer.size(); 579 | GServer.Write( cmd_count ); 580 | GServer.Write( vtx_count ); 581 | GServer.Write( idx_count ); 582 | // Send 583 | // Add all drawcmds 584 | WebSocketServer::Cmd cmd; 585 | const ImDrawCmd* pcmd_end = cmd_list->CmdBuffer.end(); 586 | for ( const ImDrawCmd* pcmd = cmd_list->CmdBuffer.begin(); pcmd != pcmd_end; pcmd++ ) 587 | { 588 | cmd.Set( *pcmd ); 589 | GServer.Write( cmd ); 590 | } 591 | // Add all vtx 592 | WebSocketServer::Vtx vtx; 593 | int vtx_remaining = vtx_count; 594 | while ( vtx_remaining-- > 0 ) 595 | { 596 | vtx.Set( *vtx_src++ ); 597 | GServer.Write( vtx ); 598 | } 599 | 600 | // Add all idx 601 | if ( GServer.Supports32BitIndexBuffers ) 602 | { 603 | WebSocketServer::Idx32 idx; 604 | 605 | int idx_remaining = idx_count; 606 | while ( idx_remaining-- > 0 ) 607 | { 608 | idx.Set( *idx_src++ ); 609 | GServer.Write( idx ); 610 | } 611 | } 612 | else 613 | { 614 | WebSocketServer::Idx16 idx; 615 | 616 | int idx_remaining = idx_count; 617 | while ( idx_remaining-- > 0 ) 618 | { 619 | idx.Set( *idx_src++ ); 620 | GServer.Write( idx ); 621 | } 622 | } 623 | 624 | } 625 | // Send 626 | GServer.SendPacket(); 627 | } 628 | } 629 | 630 | 631 | } // namespace 632 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/opengl_example_without_deps.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 7B0131231B9D93F500380F75 /* imgui.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B0130E31B9D93F500380F75 /* imgui.cpp */; }; 11 | 7B0131241B9D93F500380F75 /* imgui_demo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B0130E51B9D93F500380F75 /* imgui_demo.cpp */; }; 12 | 7B0131251B9D93F500380F75 /* imgui_draw.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B0130E61B9D93F500380F75 /* imgui_draw.cpp */; }; 13 | 7B01313C1B9D9BA100380F75 /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = 7B01312C1B9D9BA100380F75 /* lz4.c */; }; 14 | 7B01313D1B9D9BA100380F75 /* lz4frame.c in Sources */ = {isa = PBXBuildFile; fileRef = 7B01312E1B9D9BA100380F75 /* lz4frame.c */; }; 15 | 7B01313E1B9D9BA100380F75 /* lz4hc.c in Sources */ = {isa = PBXBuildFile; fileRef = 7B0131311B9D9BA100380F75 /* lz4hc.c */; }; 16 | 7B01313F1B9D9BA100380F75 /* xxhash.c in Sources */ = {isa = PBXBuildFile; fileRef = 7B0131331B9D9BA100380F75 /* xxhash.c */; }; 17 | 7B0131421B9D9BA100380F75 /* webby.c in Sources */ = {isa = PBXBuildFile; fileRef = 7B0131381B9D9BA100380F75 /* webby.c */; }; 18 | 7B0131461B9DB51900380F75 /* imgui.js in Resources */ = {isa = PBXBuildFile; fileRef = 7B0131451B9DB51900380F75 /* imgui.js */; }; 19 | 7B0131481B9DC59E00380F75 /* imgui.html in Resources */ = {isa = PBXBuildFile; fileRef = 7B0131471B9DC59E00380F75 /* imgui.html */; }; 20 | 7BDE201C1A9235A500766EFE /* main.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7B2310BB1A92342C0028144F /* main.mm */; }; 21 | 7BDE201D1A9235AB00766EFE /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B2310BD1A9234540028144F /* OpenGL.framework */; }; 22 | 7BDE201E1A9235B000766EFE /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B2310BF1A92345A0028144F /* Cocoa.framework */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 7B0130E21B9D93F500380F75 /* imconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imconfig.h; sourceTree = ""; }; 27 | 7B0130E31B9D93F500380F75 /* imgui.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui.cpp; sourceTree = ""; }; 28 | 7B0130E41B9D93F500380F75 /* imgui.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui.h; sourceTree = ""; }; 29 | 7B0130E51B9D93F500380F75 /* imgui_demo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_demo.cpp; sourceTree = ""; }; 30 | 7B0130E61B9D93F500380F75 /* imgui_draw.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = imgui_draw.cpp; sourceTree = ""; }; 31 | 7B0130E71B9D93F500380F75 /* imgui_internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = imgui_internal.h; sourceTree = ""; }; 32 | 7B0130E81B9D93F500380F75 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 33 | 7B0130E91B9D93F500380F75 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 34 | 7B0130EA1B9D93F500380F75 /* stb_rect_pack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_rect_pack.h; sourceTree = ""; }; 35 | 7B0130EB1B9D93F500380F75 /* stb_textedit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_textedit.h; sourceTree = ""; }; 36 | 7B0130EC1B9D93F500380F75 /* stb_truetype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stb_truetype.h; sourceTree = ""; }; 37 | 7B01312C1B9D9BA100380F75 /* lz4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lz4.c; sourceTree = ""; }; 38 | 7B01312D1B9D9BA100380F75 /* lz4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4.h; sourceTree = ""; }; 39 | 7B01312E1B9D9BA100380F75 /* lz4frame.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lz4frame.c; sourceTree = ""; }; 40 | 7B01312F1B9D9BA100380F75 /* lz4frame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4frame.h; sourceTree = ""; }; 41 | 7B0131301B9D9BA100380F75 /* lz4frame_static.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4frame_static.h; sourceTree = ""; }; 42 | 7B0131311B9D9BA100380F75 /* lz4hc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lz4hc.c; sourceTree = ""; }; 43 | 7B0131321B9D9BA100380F75 /* lz4hc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4hc.h; sourceTree = ""; }; 44 | 7B0131331B9D9BA100380F75 /* xxhash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xxhash.c; sourceTree = ""; }; 45 | 7B0131341B9D9BA100380F75 /* xxhash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xxhash.h; sourceTree = ""; }; 46 | 7B0131361B9D9BA100380F75 /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; 47 | 7B0131371B9D9BA100380F75 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 48 | 7B0131381B9D9BA100380F75 /* webby.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = webby.c; sourceTree = ""; }; 49 | 7B0131391B9D9BA100380F75 /* webby.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = webby.h; sourceTree = ""; }; 50 | 7B01313A1B9D9BA100380F75 /* webby_unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = webby_unix.h; sourceTree = ""; }; 51 | 7B01313B1B9D9BA100380F75 /* webby_win32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = webby_win32.h; sourceTree = ""; }; 52 | 7B0131431B9DB31200380F75 /* imgui_remote_webby.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_remote_webby.h; path = ../../imgui_remote_webby.h; sourceTree = ""; }; 53 | 7B0131441B9DB31200380F75 /* imgui_remote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = imgui_remote.h; path = ../../imgui_remote.h; sourceTree = ""; }; 54 | 7B0131451B9DB51900380F75 /* imgui.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = imgui.js; path = ../../../client/imgui.js; sourceTree = ""; }; 55 | 7B0131471B9DC59E00380F75 /* imgui.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = imgui.html; path = ../../../client/imgui.html; sourceTree = ""; }; 56 | 7B2310BA1A92342C0028144F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 7B2310BB1A92342C0028144F /* main.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = main.mm; sourceTree = ""; }; 58 | 7B2310BD1A9234540028144F /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; 59 | 7B2310BF1A92345A0028144F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 60 | 7BDE1FFB1A92357F00766EFE /* opengl_sample_without_deps.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = opengl_sample_without_deps.app; sourceTree = BUILT_PRODUCTS_DIR; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | 7BDE1FF81A92357F00766EFE /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 7BDE201E1A9235B000766EFE /* Cocoa.framework in Frameworks */, 69 | 7BDE201D1A9235AB00766EFE /* OpenGL.framework in Frameworks */, 70 | ); 71 | runOnlyForDeploymentPostprocessing = 0; 72 | }; 73 | /* End PBXFrameworksBuildPhase section */ 74 | 75 | /* Begin PBXGroup section */ 76 | 7B0130831B9D93F500380F75 /* imgui */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 7B0130E21B9D93F500380F75 /* imconfig.h */, 80 | 7B0130E31B9D93F500380F75 /* imgui.cpp */, 81 | 7B0130E41B9D93F500380F75 /* imgui.h */, 82 | 7B0130E51B9D93F500380F75 /* imgui_demo.cpp */, 83 | 7B0130E61B9D93F500380F75 /* imgui_draw.cpp */, 84 | 7B0130E71B9D93F500380F75 /* imgui_internal.h */, 85 | 7B0130E81B9D93F500380F75 /* LICENSE */, 86 | 7B0130E91B9D93F500380F75 /* README.md */, 87 | 7B0130EA1B9D93F500380F75 /* stb_rect_pack.h */, 88 | 7B0130EB1B9D93F500380F75 /* stb_textedit.h */, 89 | 7B0130EC1B9D93F500380F75 /* stb_truetype.h */, 90 | ); 91 | name = imgui; 92 | path = ../../imgui; 93 | sourceTree = ""; 94 | }; 95 | 7B01312B1B9D9BA100380F75 /* lz4 */ = { 96 | isa = PBXGroup; 97 | children = ( 98 | 7B01312C1B9D9BA100380F75 /* lz4.c */, 99 | 7B01312D1B9D9BA100380F75 /* lz4.h */, 100 | 7B01312E1B9D9BA100380F75 /* lz4frame.c */, 101 | 7B01312F1B9D9BA100380F75 /* lz4frame.h */, 102 | 7B0131301B9D9BA100380F75 /* lz4frame_static.h */, 103 | 7B0131311B9D9BA100380F75 /* lz4hc.c */, 104 | 7B0131321B9D9BA100380F75 /* lz4hc.h */, 105 | 7B0131331B9D9BA100380F75 /* xxhash.c */, 106 | 7B0131341B9D9BA100380F75 /* xxhash.h */, 107 | ); 108 | name = lz4; 109 | path = ../../lz4; 110 | sourceTree = ""; 111 | }; 112 | 7B0131351B9D9BA100380F75 /* webby */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 7B0131361B9D9BA100380F75 /* LICENSE */, 116 | 7B0131371B9D9BA100380F75 /* README.md */, 117 | 7B0131381B9D9BA100380F75 /* webby.c */, 118 | 7B0131391B9D9BA100380F75 /* webby.h */, 119 | 7B01313A1B9D9BA100380F75 /* webby_unix.h */, 120 | 7B01313B1B9D9BA100380F75 /* webby_win32.h */, 121 | ); 122 | name = webby; 123 | path = ../../webby; 124 | sourceTree = ""; 125 | }; 126 | 7BE9E7FA1A9233C7009BE5BF = { 127 | isa = PBXGroup; 128 | children = ( 129 | 7B0131471B9DC59E00380F75 /* imgui.html */, 130 | 7B0131451B9DB51900380F75 /* imgui.js */, 131 | 7B01312B1B9D9BA100380F75 /* lz4 */, 132 | 7B0131351B9D9BA100380F75 /* webby */, 133 | 7B0130831B9D93F500380F75 /* imgui */, 134 | 7B2310BF1A92345A0028144F /* Cocoa.framework */, 135 | 7B2310BD1A9234540028144F /* OpenGL.framework */, 136 | 7B2310BA1A92342C0028144F /* Info.plist */, 137 | 7B2310BB1A92342C0028144F /* main.mm */, 138 | 7B0131431B9DB31200380F75 /* imgui_remote_webby.h */, 139 | 7B0131441B9DB31200380F75 /* imgui_remote.h */, 140 | 7BE9E8041A9233C7009BE5BF /* Products */, 141 | ); 142 | sourceTree = ""; 143 | }; 144 | 7BE9E8041A9233C7009BE5BF /* Products */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | 7BDE1FFB1A92357F00766EFE /* opengl_sample_without_deps.app */, 148 | ); 149 | name = Products; 150 | sourceTree = ""; 151 | }; 152 | /* End PBXGroup section */ 153 | 154 | /* Begin PBXNativeTarget section */ 155 | 7BDE1FFA1A92357F00766EFE /* opengl_sample_without_deps */ = { 156 | isa = PBXNativeTarget; 157 | buildConfigurationList = 7BDE20151A92357F00766EFE /* Build configuration list for PBXNativeTarget "opengl_sample_without_deps" */; 158 | buildPhases = ( 159 | 7BDE1FF71A92357F00766EFE /* Sources */, 160 | 7BDE1FF81A92357F00766EFE /* Frameworks */, 161 | 7BDE1FF91A92357F00766EFE /* Resources */, 162 | ); 163 | buildRules = ( 164 | ); 165 | dependencies = ( 166 | ); 167 | name = opengl_sample_without_deps; 168 | productName = opengl_sample; 169 | productReference = 7BDE1FFB1A92357F00766EFE /* opengl_sample_without_deps.app */; 170 | productType = "com.apple.product-type.application"; 171 | }; 172 | /* End PBXNativeTarget section */ 173 | 174 | /* Begin PBXProject section */ 175 | 7BE9E7FB1A9233C7009BE5BF /* Project object */ = { 176 | isa = PBXProject; 177 | attributes = { 178 | LastUpgradeCheck = 0640; 179 | ORGANIZATIONNAME = "Stefano Cristiano"; 180 | TargetAttributes = { 181 | 7BDE1FFA1A92357F00766EFE = { 182 | CreatedOnToolsVersion = 6.1.1; 183 | }; 184 | }; 185 | }; 186 | buildConfigurationList = 7BE9E7FE1A9233C7009BE5BF /* Build configuration list for PBXProject "opengl_example_without_deps" */; 187 | compatibilityVersion = "Xcode 3.2"; 188 | developmentRegion = English; 189 | hasScannedForEncodings = 0; 190 | knownRegions = ( 191 | en, 192 | Base, 193 | ); 194 | mainGroup = 7BE9E7FA1A9233C7009BE5BF; 195 | productRefGroup = 7BE9E8041A9233C7009BE5BF /* Products */; 196 | projectDirPath = ""; 197 | projectRoot = ""; 198 | targets = ( 199 | 7BDE1FFA1A92357F00766EFE /* opengl_sample_without_deps */, 200 | ); 201 | }; 202 | /* End PBXProject section */ 203 | 204 | /* Begin PBXResourcesBuildPhase section */ 205 | 7BDE1FF91A92357F00766EFE /* Resources */ = { 206 | isa = PBXResourcesBuildPhase; 207 | buildActionMask = 2147483647; 208 | files = ( 209 | 7B0131481B9DC59E00380F75 /* imgui.html in Resources */, 210 | 7B0131461B9DB51900380F75 /* imgui.js in Resources */, 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | /* End PBXResourcesBuildPhase section */ 215 | 216 | /* Begin PBXSourcesBuildPhase section */ 217 | 7BDE1FF71A92357F00766EFE /* Sources */ = { 218 | isa = PBXSourcesBuildPhase; 219 | buildActionMask = 2147483647; 220 | files = ( 221 | 7B01313D1B9D9BA100380F75 /* lz4frame.c in Sources */, 222 | 7B0131251B9D93F500380F75 /* imgui_draw.cpp in Sources */, 223 | 7BDE201C1A9235A500766EFE /* main.mm in Sources */, 224 | 7B0131231B9D93F500380F75 /* imgui.cpp in Sources */, 225 | 7B0131241B9D93F500380F75 /* imgui_demo.cpp in Sources */, 226 | 7B0131421B9D9BA100380F75 /* webby.c in Sources */, 227 | 7B01313F1B9D9BA100380F75 /* xxhash.c in Sources */, 228 | 7B01313C1B9D9BA100380F75 /* lz4.c in Sources */, 229 | 7B01313E1B9D9BA100380F75 /* lz4hc.c in Sources */, 230 | ); 231 | runOnlyForDeploymentPostprocessing = 0; 232 | }; 233 | /* End PBXSourcesBuildPhase section */ 234 | 235 | /* Begin XCBuildConfiguration section */ 236 | 7BDE20161A92357F00766EFE /* Debug */ = { 237 | isa = XCBuildConfiguration; 238 | buildSettings = { 239 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 240 | CLANG_ENABLE_OBJC_ARC = NO; 241 | CODE_SIGN_IDENTITY = "-"; 242 | COMBINE_HIDPI_IMAGES = YES; 243 | GCC_PREPROCESSOR_DEFINITIONS = ( 244 | "DEBUG=1", 245 | "$(inherited)", 246 | ); 247 | INFOPLIST_FILE = Info.plist; 248 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 249 | LIBRARY_SEARCH_PATHS = ( 250 | "$(inherited)", 251 | "/Users/stefano/Developer/Opensource/remoteimgui-pagghiu/src/app/imgui/examples/libs/glfw/lib-vc2010-32", 252 | "/Users/stefano/Developer/Opensource/remoteimgui-pagghiu/src/app/imgui/examples/libs/glfw/lib-vc2010-64", 253 | ); 254 | PRODUCT_NAME = "$(TARGET_NAME)"; 255 | }; 256 | name = Debug; 257 | }; 258 | 7BDE20171A92357F00766EFE /* Release */ = { 259 | isa = XCBuildConfiguration; 260 | buildSettings = { 261 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 262 | CLANG_ENABLE_OBJC_ARC = NO; 263 | CODE_SIGN_IDENTITY = "-"; 264 | COMBINE_HIDPI_IMAGES = YES; 265 | INFOPLIST_FILE = Info.plist; 266 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 267 | LIBRARY_SEARCH_PATHS = ( 268 | "$(inherited)", 269 | "/Users/stefano/Developer/Opensource/remoteimgui-pagghiu/src/app/imgui/examples/libs/glfw/lib-vc2010-32", 270 | "/Users/stefano/Developer/Opensource/remoteimgui-pagghiu/src/app/imgui/examples/libs/glfw/lib-vc2010-64", 271 | ); 272 | PRODUCT_NAME = "$(TARGET_NAME)"; 273 | }; 274 | name = Release; 275 | }; 276 | 7BE9E8081A9233C7009BE5BF /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ALWAYS_SEARCH_USER_PATHS = NO; 280 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 281 | CLANG_CXX_LIBRARY = "libc++"; 282 | CLANG_ENABLE_MODULES = YES; 283 | CLANG_ENABLE_OBJC_ARC = NO; 284 | CLANG_WARN_BOOL_CONVERSION = YES; 285 | CLANG_WARN_CONSTANT_CONVERSION = YES; 286 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 287 | CLANG_WARN_EMPTY_BODY = YES; 288 | CLANG_WARN_ENUM_CONVERSION = YES; 289 | CLANG_WARN_INT_CONVERSION = YES; 290 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 291 | CLANG_WARN_UNREACHABLE_CODE = YES; 292 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 293 | COPY_PHASE_STRIP = NO; 294 | ENABLE_STRICT_OBJC_MSGSEND = YES; 295 | GCC_C_LANGUAGE_STANDARD = gnu99; 296 | GCC_DYNAMIC_NO_PIC = NO; 297 | GCC_OPTIMIZATION_LEVEL = 0; 298 | GCC_PREPROCESSOR_DEFINITIONS = ( 299 | "DEBUG=1", 300 | "$(inherited)", 301 | ); 302 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 303 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 304 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 305 | GCC_WARN_UNDECLARED_SELECTOR = YES; 306 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 307 | GCC_WARN_UNUSED_FUNCTION = YES; 308 | GCC_WARN_UNUSED_VARIABLE = YES; 309 | MACOSX_DEPLOYMENT_TARGET = 10.7; 310 | MTL_ENABLE_DEBUG_INFO = YES; 311 | ONLY_ACTIVE_ARCH = YES; 312 | SDKROOT = macosx; 313 | }; 314 | name = Debug; 315 | }; 316 | 7BE9E8091A9233C7009BE5BF /* Release */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | ALWAYS_SEARCH_USER_PATHS = NO; 320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 321 | CLANG_CXX_LIBRARY = "libc++"; 322 | CLANG_ENABLE_MODULES = YES; 323 | CLANG_ENABLE_OBJC_ARC = NO; 324 | CLANG_WARN_BOOL_CONVERSION = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 327 | CLANG_WARN_EMPTY_BODY = YES; 328 | CLANG_WARN_ENUM_CONVERSION = YES; 329 | CLANG_WARN_INT_CONVERSION = YES; 330 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 331 | CLANG_WARN_UNREACHABLE_CODE = YES; 332 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 333 | COPY_PHASE_STRIP = YES; 334 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 335 | ENABLE_NS_ASSERTIONS = NO; 336 | ENABLE_STRICT_OBJC_MSGSEND = YES; 337 | GCC_C_LANGUAGE_STANDARD = gnu99; 338 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 339 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 340 | GCC_WARN_UNDECLARED_SELECTOR = YES; 341 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 342 | GCC_WARN_UNUSED_FUNCTION = YES; 343 | GCC_WARN_UNUSED_VARIABLE = YES; 344 | MACOSX_DEPLOYMENT_TARGET = 10.7; 345 | MTL_ENABLE_DEBUG_INFO = NO; 346 | ONLY_ACTIVE_ARCH = YES; 347 | SDKROOT = macosx; 348 | }; 349 | name = Release; 350 | }; 351 | /* End XCBuildConfiguration section */ 352 | 353 | /* Begin XCConfigurationList section */ 354 | 7BDE20151A92357F00766EFE /* Build configuration list for PBXNativeTarget "opengl_sample_without_deps" */ = { 355 | isa = XCConfigurationList; 356 | buildConfigurations = ( 357 | 7BDE20161A92357F00766EFE /* Debug */, 358 | 7BDE20171A92357F00766EFE /* Release */, 359 | ); 360 | defaultConfigurationIsVisible = 0; 361 | defaultConfigurationName = Release; 362 | }; 363 | 7BE9E7FE1A9233C7009BE5BF /* Build configuration list for PBXProject "opengl_example_without_deps" */ = { 364 | isa = XCConfigurationList; 365 | buildConfigurations = ( 366 | 7BE9E8081A9233C7009BE5BF /* Debug */, 367 | 7BE9E8091A9233C7009BE5BF /* Release */, 368 | ); 369 | defaultConfigurationIsVisible = 0; 370 | defaultConfigurationName = Release; 371 | }; 372 | /* End XCConfigurationList section */ 373 | }; 374 | rootObject = 7BE9E7FB1A9233C7009BE5BF /* Project object */; 375 | } 376 | -------------------------------------------------------------------------------- /src/app/example/opengl_example/main.mm: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #include "../../imgui/imgui.h" 5 | // @RemoteImgui begin 6 | #include "../../imgui_remote.h" 7 | #define VCANVAS_WIDTH 8192 8 | #define VCANVAS_HEIGHT 8192 9 | // @RemoteImgui end 10 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 11 | static float highDpiScale = 1.0; 12 | static bool g_mousePressed[2] = { false, false }; 13 | static float g_mouseCoords[2] {0,0}; 14 | static clock_t g_lastClock; 15 | static unsigned int g_windowWidth, g_windowHeight; 16 | static unsigned int g_backingWidth, g_backingHeight; 17 | 18 | void ImImpl_RenderDrawLists(ImDrawData* draw_data) 19 | { 20 | // @RemoteImgui begin 21 | ImGui::RemoteDraw(draw_data->CmdLists, draw_data->CmdListsCount); 22 | // @RemoteImgui end 23 | 24 | // We are using the OpenGL fixed pipeline to make the example code simpler to read! 25 | // A probable faster way to render would be to collate all vertices from all cmd_lists into a single vertex buffer. 26 | // Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers. 27 | glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT); 28 | glEnable(GL_BLEND); 29 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 30 | glDisable(GL_CULL_FACE); 31 | glDisable(GL_DEPTH_TEST); 32 | glEnable(GL_SCISSOR_TEST); 33 | glEnableClientState(GL_VERTEX_ARRAY); 34 | glEnableClientState(GL_TEXTURE_COORD_ARRAY); 35 | glEnableClientState(GL_COLOR_ARRAY); 36 | glEnable(GL_TEXTURE_2D); 37 | //glUseProgram(0); // You may want this if using this code in an OpenGL 3+ context 38 | 39 | // Setup orthographic projection matrix 40 | const float width = g_windowWidth; 41 | const float height = g_windowHeight; 42 | glMatrixMode(GL_PROJECTION); 43 | glPushMatrix(); 44 | glLoadIdentity(); 45 | glOrtho(0.0f, width, height, 0.0f, -1.0f, +1.0f); 46 | glMatrixMode(GL_MODELVIEW); 47 | glPushMatrix(); 48 | glLoadIdentity(); 49 | 50 | // Render command lists 51 | #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) 52 | for (int n = 0; n < draw_data->CmdListsCount; n++) 53 | { 54 | const ImDrawList* cmd_list = draw_data->CmdLists[n]; 55 | const unsigned char* vtx_buffer = (const unsigned char*)&cmd_list->VtxBuffer.front(); 56 | const ImDrawIdx* idx_buffer = &cmd_list->IdxBuffer.front(); 57 | glVertexPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, pos))); 58 | glTexCoordPointer(2, GL_FLOAT, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, uv))); 59 | glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(ImDrawVert), (void*)(vtx_buffer + OFFSETOF(ImDrawVert, col))); 60 | 61 | for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.size(); cmd_i++) 62 | { 63 | const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; 64 | if (pcmd->UserCallback) 65 | { 66 | pcmd->UserCallback(cmd_list, pcmd); 67 | } 68 | else 69 | { 70 | glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->TextureId); 71 | glScissor((GLint)(pcmd->ClipRect.x*highDpiScale), 72 | (GLint)((height - pcmd->ClipRect.w)*highDpiScale), 73 | (GLint)((pcmd->ClipRect.z - pcmd->ClipRect.x)*highDpiScale), 74 | (GLint)((pcmd->ClipRect.w - pcmd->ClipRect.y)*highDpiScale)); 75 | 76 | glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, GL_UNSIGNED_SHORT, idx_buffer); 77 | } 78 | idx_buffer += pcmd->ElemCount; 79 | } 80 | } 81 | #undef OFFSETOF 82 | 83 | // Restore modified state 84 | glDisableClientState(GL_COLOR_ARRAY); 85 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); 86 | glDisableClientState(GL_VERTEX_ARRAY); 87 | glBindTexture(GL_TEXTURE_2D, 0); 88 | glMatrixMode(GL_MODELVIEW); 89 | glPopMatrix(); 90 | glMatrixMode(GL_PROJECTION); 91 | glPopMatrix(); 92 | glPopAttrib(); 93 | } 94 | 95 | void LoadFontsTexture() 96 | { 97 | ImGuiIO& io = ImGui::GetIO(); 98 | unsigned char* pixels; 99 | int width, height; 100 | io.Fonts->GetTexDataAsAlpha8(&pixels, &width, &height); 101 | 102 | GLuint tex_id; 103 | glGenTextures(1, &tex_id); 104 | glBindTexture(GL_TEXTURE_2D, tex_id); 105 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 106 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 107 | glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, pixels); 108 | 109 | // Store our identifier 110 | io.Fonts->TexID = (void *)(intptr_t)tex_id; 111 | } 112 | 113 | void IMGUIExample_InitImGui() 114 | { 115 | ImGuiIO& io = ImGui::GetIO(); 116 | // Time elapsed since last frame, in seconds 117 | // (in this sample app we'll override this every frame because our time step is variable) 118 | 119 | 120 | io.DeltaTime = 1.0f/60.0f; 121 | 122 | io.RenderDrawListsFn = ImImpl_RenderDrawLists; 123 | 124 | LoadFontsTexture(); 125 | // @RemoteImgui begin 126 | ImGui::RemoteInit("0.0.0.0", 7002); // local host, local port 127 | //ImGui::GetStyle().WindowRounding = 0.f; // no rounding uses less bandwidth 128 | io.DisplaySize = ImVec2((float)VCANVAS_WIDTH, (float)VCANVAS_HEIGHT); 129 | // @RemoteImgui end 130 | } 131 | 132 | void IMGUIExample_Draw(double elapsedMilliseconds) 133 | { 134 | ImGuiIO& io = ImGui::GetIO(); 135 | // Setup resolution (every frame to accommodate for window resizing) 136 | int w,h; 137 | int display_w, display_h; 138 | display_w = g_backingWidth; 139 | display_h = g_backingHeight; 140 | w = g_windowWidth; 141 | h = g_windowHeight; 142 | highDpiScale = g_backingWidth / g_windowWidth; 143 | // Display size, in pixels. For clamping windows positions. 144 | //io.DisplaySize = ImVec2((float)g_windowWidth, (float)g_windowHeight); 145 | io.DisplaySize = ImVec2((float)VCANVAS_WIDTH, (float)VCANVAS_HEIGHT); 146 | io.DeltaTime = elapsedMilliseconds/100.0; //convert in seconds 147 | // @RemoteImgui begin 148 | ImGui::RemoteUpdate(); 149 | ImGui::RemoteInput input; 150 | if (ImGui::RemoteGetInput(input)) 151 | { 152 | for (int i = 0; i < 256; i++) 153 | io.KeysDown[i] = input.KeysDown[i]; 154 | io.KeyCtrl = input.KeyCtrl; 155 | io.KeyShift = input.KeyShift; 156 | io.MousePos = input.MousePos; 157 | g_mouseCoords[0] = io.MousePos.x; 158 | g_mouseCoords[1] = io.MousePos.y; 159 | io.MouseDown[0] = (input.MouseButtons & 1); 160 | io.MouseDown[1] = (input.MouseButtons & 2) != 0; 161 | io.MouseWheel += input.MouseWheelDelta / highDpiScale; 162 | 163 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 164 | io.KeyMap[ImGuiKey_Tab] = ImGuiKey_Tab; 165 | io.KeyMap[ImGuiKey_LeftArrow] = ImGuiKey_LeftArrow; 166 | io.KeyMap[ImGuiKey_RightArrow] = ImGuiKey_RightArrow; 167 | io.KeyMap[ImGuiKey_UpArrow] = ImGuiKey_UpArrow; 168 | io.KeyMap[ImGuiKey_DownArrow] = ImGuiKey_DownArrow; 169 | io.KeyMap[ImGuiKey_Home] = ImGuiKey_Home; 170 | io.KeyMap[ImGuiKey_End] = ImGuiKey_End; 171 | io.KeyMap[ImGuiKey_Delete] = ImGuiKey_Delete; 172 | io.KeyMap[ImGuiKey_Backspace] = ImGuiKey_Backspace; 173 | io.KeyMap[ImGuiKey_Enter] = 13; 174 | io.KeyMap[ImGuiKey_Escape] = 27; 175 | io.KeyMap[ImGuiKey_A] = 'a'; 176 | io.KeyMap[ImGuiKey_C] = 'c'; 177 | io.KeyMap[ImGuiKey_V] = 'v'; 178 | io.KeyMap[ImGuiKey_X] = 'x'; 179 | io.KeyMap[ImGuiKey_Y] = 'y'; 180 | io.KeyMap[ImGuiKey_Z] = 'z'; 181 | } 182 | else // @RemoteImgui end 183 | { 184 | // Setup inputs 185 | double mouse_x = 0, mouse_y = 0; 186 | mouse_x = g_mouseCoords[0]; 187 | mouse_y = g_mouseCoords[1]; 188 | // Mouse position, in pixels (set to -1,-1 if no mouse / on another screen, etc.) 189 | io.MousePos = ImVec2((float)mouse_x, (float)mouse_y); 190 | io.MouseDown[0] = g_mousePressed[0]; 191 | 192 | // If a mouse press event came, always pass it as "mouse held this frame", 193 | // so we don't miss click-release events that are shorter than 1 frame. 194 | 195 | io.MouseDown[1] = g_mousePressed[1]; 196 | 197 | // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array. 198 | io.KeyMap[ImGuiKey_Tab] = 9; 199 | io.KeyMap[ImGuiKey_LeftArrow] = ImGuiKey_LeftArrow; 200 | io.KeyMap[ImGuiKey_RightArrow] = ImGuiKey_RightArrow; 201 | io.KeyMap[ImGuiKey_UpArrow] = ImGuiKey_UpArrow; 202 | io.KeyMap[ImGuiKey_DownArrow] = ImGuiKey_DownArrow; 203 | io.KeyMap[ImGuiKey_Home] = ImGuiKey_Home; 204 | io.KeyMap[ImGuiKey_End] = ImGuiKey_End; 205 | io.KeyMap[ImGuiKey_Delete] = ImGuiKey_Delete; 206 | io.KeyMap[ImGuiKey_Backspace] = 127; 207 | io.KeyMap[ImGuiKey_Enter] = 13; 208 | io.KeyMap[ImGuiKey_Escape] = 27; 209 | io.KeyMap[ImGuiKey_A] = 'a'; 210 | io.KeyMap[ImGuiKey_C] = 'c'; 211 | io.KeyMap[ImGuiKey_V] = 'v'; 212 | io.KeyMap[ImGuiKey_X] = 'x'; 213 | io.KeyMap[ImGuiKey_Y] = 'y'; 214 | io.KeyMap[ImGuiKey_Z] = 'z'; 215 | } 216 | // Start the frame 217 | ImGui::NewFrame(); 218 | static bool show_test_window = true; 219 | static bool show_another_window = false; 220 | static ImVec4 clear_col = ImColor(114, 144, 154); 221 | 222 | // 1. Show a simple window 223 | // Tip: if we don't call ImGui::Begin()/ImGui::End() the widgets appears in a window automatically called "Debug" 224 | { 225 | static float f; 226 | ImGui::Text("Hello, world!"); 227 | ImGui::SliderFloat("float", &f, 0.0f, 1.0f); 228 | ImGui::ColorEdit3("clear color", (float*)&clear_col); 229 | if (ImGui::Button("Test Window")) show_test_window ^= 1; 230 | if (ImGui::Button("Another Window")) show_another_window ^= 1; 231 | ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); 232 | ImGui::Text("Mouse X=%.1f, Y=%.1f", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); 233 | } 234 | 235 | // 2. Show another simple window, this time using an explicit Begin/End pair 236 | if (show_another_window) 237 | { 238 | ImGui::Begin("Another Window", &show_another_window, ImVec2(200,100)); 239 | ImGui::Text("Hello"); 240 | ImGui::End(); 241 | } 242 | 243 | // 3. Show the ImGui test window. Most of the sample code is in ImGui::ShowTestWindow() 244 | if (show_test_window) 245 | { 246 | ImGui::SetNextWindowPos(ImVec2(650, 20), ImGuiSetCond_FirstUseEver); 247 | ImGui::ShowTestWindow(&show_test_window); 248 | } 249 | 250 | // Rendering 251 | GLsizei width = (GLsizei)(g_backingWidth); 252 | GLsizei height = (GLsizei)(g_backingHeight); 253 | glViewport(0, 0, width, height); 254 | glClearColor(clear_col.x, clear_col.y, clear_col.z, clear_col.w); 255 | glClear(GL_COLOR_BUFFER_BIT); 256 | ImGui::Render(); 257 | } 258 | 259 | //------------------------------------------------------------------ 260 | // IMGUIExampleView 261 | //------------------------------------------------------------------ 262 | 263 | @interface IMGUIExampleView : NSOpenGLView 264 | { 265 | NSTimer *animationTimer; 266 | } 267 | @end 268 | 269 | @implementation IMGUIExampleView 270 | 271 | -(void)animationTimerFired:(NSTimer*)timer 272 | { 273 | [self setNeedsDisplay:YES]; 274 | } 275 | 276 | -(id)initWithFrame:(NSRect)frameRect pixelFormat:(NSOpenGLPixelFormat *)format 277 | { 278 | self = [super initWithFrame:frameRect pixelFormat:format]; 279 | if (self) 280 | { 281 | g_lastClock = clock(); 282 | } 283 | return(self); 284 | } 285 | 286 | - (void)prepareOpenGL 287 | { 288 | [super prepareOpenGL]; 289 | 290 | #ifndef DEBUG 291 | GLint swapInterval = 1; 292 | [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; 293 | if (swapInterval == 0) 294 | { 295 | NSLog(@"Error: Cannot set swap interval."); 296 | } 297 | #endif 298 | } 299 | 300 | - (void)drawView 301 | { 302 | clock_t thisclock = clock(); 303 | unsigned long clock_delay = thisclock - g_lastClock; 304 | double milliseconds = clock_delay * 1000.0f / CLOCKS_PER_SEC; 305 | 306 | IMGUIExample_Draw(milliseconds); 307 | 308 | g_lastClock = thisclock; 309 | 310 | [[self openGLContext] flushBuffer]; 311 | 312 | if (!animationTimer) 313 | { 314 | animationTimer = [[NSTimer scheduledTimerWithTimeInterval:0.017 target:self selector:@selector(animationTimerFired:) userInfo:nil repeats:YES] retain]; 315 | } 316 | } 317 | 318 | -(void)setViewportRect:(NSRect)bounds 319 | { 320 | glViewport(0, 0, bounds.size.width, bounds.size.height); 321 | g_windowWidth = bounds.size.width; 322 | g_windowHeight = bounds.size.height; 323 | 324 | if (g_windowHeight == 0) 325 | { 326 | g_windowHeight = 1; 327 | } 328 | 329 | 330 | //ImGui::GetIO().DisplaySize = ImVec2((float)bounds.size.width, (float)bounds.size.height); 331 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 332 | if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) 333 | { 334 | NSRect backing = [self convertRectToBacking:bounds]; 335 | g_backingWidth = backing.size.width; 336 | g_backingHeight= backing.size.height; 337 | if (g_backingHeight == 0) 338 | { 339 | g_backingHeight = g_windowHeight * 2; 340 | } 341 | } 342 | else 343 | #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ 344 | { 345 | g_backingWidth = g_windowWidth; 346 | g_backingHeight= g_windowHeight; 347 | } 348 | } 349 | 350 | -(void)reshape 351 | { 352 | [self setViewportRect:self.bounds]; 353 | [[self openGLContext] update]; 354 | [self drawView]; 355 | } 356 | 357 | -(void)drawRect:(NSRect)bounds 358 | { 359 | [self drawView]; 360 | } 361 | 362 | #pragma mark - 363 | 364 | -(BOOL)acceptsFirstResponder 365 | { 366 | return(YES); 367 | } 368 | 369 | -(BOOL)becomeFirstResponder 370 | { 371 | return(YES); 372 | } 373 | 374 | -(BOOL)resignFirstResponder 375 | { 376 | return(YES); 377 | } 378 | 379 | // Flips coordinate system upside down on Y 380 | -(BOOL)isFlipped 381 | { 382 | return(YES); 383 | } 384 | 385 | #pragma mark Mouse and Key Events. 386 | 387 | static bool mapKeymap(int* keymap) 388 | { 389 | if(*keymap == NSUpArrowFunctionKey) 390 | *keymap = ImGuiKey_UpArrow; 391 | else if(*keymap == NSDownArrowFunctionKey) 392 | *keymap = ImGuiKey_DownArrow; 393 | else if(*keymap == NSLeftArrowFunctionKey) 394 | *keymap = ImGuiKey_LeftArrow; 395 | else if(*keymap == NSRightArrowFunctionKey) 396 | *keymap = ImGuiKey_RightArrow; 397 | else if(*keymap == NSHomeFunctionKey) 398 | *keymap = ImGuiKey_Home; 399 | else if(*keymap == NSEndFunctionKey) 400 | *keymap = ImGuiKey_End; 401 | else if(*keymap == NSDeleteFunctionKey) 402 | *keymap = ImGuiKey_Delete; 403 | else if(*keymap == 25) // SHIFT + TAB 404 | *keymap = 9; // TAB 405 | else 406 | return true; 407 | 408 | return false; 409 | } 410 | 411 | static void resetKeys() 412 | { 413 | ImGuiIO& io = ImGui::GetIO(); 414 | io.KeysDown[io.KeyMap[ImGuiKey_A]] = false; 415 | io.KeysDown[io.KeyMap[ImGuiKey_C]] = false; 416 | io.KeysDown[io.KeyMap[ImGuiKey_V]] = false; 417 | io.KeysDown[io.KeyMap[ImGuiKey_X]] = false; 418 | io.KeysDown[io.KeyMap[ImGuiKey_Y]] = false; 419 | io.KeysDown[io.KeyMap[ImGuiKey_Z]] = false; 420 | io.KeysDown[io.KeyMap[ImGuiKey_LeftArrow]] = false; 421 | io.KeysDown[io.KeyMap[ImGuiKey_RightArrow]] = false; 422 | io.KeysDown[io.KeyMap[ImGuiKey_Tab]] = false; 423 | io.KeysDown[io.KeyMap[ImGuiKey_UpArrow]] = false; 424 | io.KeysDown[io.KeyMap[ImGuiKey_DownArrow]] = false; 425 | io.KeysDown[io.KeyMap[ImGuiKey_Tab]] = false; 426 | } 427 | 428 | -(void)keyUp:(NSEvent *)theEvent 429 | { 430 | NSString *str = [theEvent characters]; 431 | ImGuiIO& io = ImGui::GetIO(); 432 | int len = (int)[str length]; 433 | for(int i = 0; i < len; i++) 434 | { 435 | int keymap = [str characterAtIndex:i]; 436 | mapKeymap(&keymap); 437 | if(keymap < 512) 438 | { 439 | io.KeysDown[keymap] = false; 440 | } 441 | } 442 | } 443 | 444 | -(void)keyDown:(NSEvent *)theEvent 445 | { 446 | NSString *str = [theEvent characters]; 447 | ImGuiIO& io = ImGui::GetIO(); 448 | int len = (int)[str length]; 449 | for(int i = 0; i < len; i++) 450 | { 451 | int keymap = [str characterAtIndex:i]; 452 | if(mapKeymap(&keymap) && !io.KeyCtrl) 453 | io.AddInputCharacter(keymap); 454 | if(keymap < 512) 455 | { 456 | if(io.KeyCtrl) 457 | { 458 | // we must reset in case we're pressing a sequence 459 | // of special keys while keeping the command pressed 460 | resetKeys(); 461 | } 462 | io.KeysDown[keymap] = true; 463 | } 464 | } 465 | } 466 | 467 | - (void)flagsChanged:(NSEvent *)event 468 | { 469 | unsigned int flags; 470 | flags = [event modifierFlags] & NSDeviceIndependentModifierFlagsMask; 471 | ImGuiIO& io = ImGui::GetIO(); 472 | bool wasKeyShift= io.KeyShift; 473 | bool wasKeyCtrl = io.KeyCtrl; 474 | io.KeyShift = flags & NSShiftKeyMask; 475 | io.KeyCtrl = flags & NSCommandKeyMask; 476 | bool keyShiftReleased = wasKeyShift && !io.KeyShift; 477 | bool keyCtrlReleased = wasKeyCtrl && !io.KeyCtrl; 478 | if(keyShiftReleased || keyCtrlReleased) 479 | { 480 | // we must reset them as we will not receive any 481 | // keyUp event if they where pressed during shift or command 482 | resetKeys(); 483 | } 484 | } 485 | 486 | -(void)mouseDown:(NSEvent *)theEvent 487 | { 488 | int button = (int)[theEvent buttonNumber]; 489 | g_mousePressed[button] = true; 490 | } 491 | 492 | -(void)mouseUp:(NSEvent *)theEvent 493 | { 494 | int button = (int)[theEvent buttonNumber]; 495 | g_mousePressed[button] = false; 496 | } 497 | 498 | -(void)mouseMoved:(NSEvent *)theEvent 499 | { 500 | NSWindow *mainWindow = [self window]; 501 | NSPoint mousePosition = [mainWindow mouseLocationOutsideOfEventStream]; 502 | mousePosition = [self convertPoint:mousePosition fromView:nil]; 503 | g_mouseCoords[0] = mousePosition.x; 504 | g_mouseCoords[1] = mousePosition.y - 1.0f; 505 | } 506 | 507 | -(void)mouseDragged:(NSEvent *)theEvent 508 | { 509 | NSWindow *mainWindow = [self window]; 510 | NSPoint mousePosition = [mainWindow mouseLocationOutsideOfEventStream]; 511 | mousePosition = [self convertPoint:mousePosition fromView:nil]; 512 | g_mouseCoords[0] = mousePosition.x; 513 | g_mouseCoords[1] = mousePosition.y - 1.0f; 514 | } 515 | 516 | - (void)scrollWheel:(NSEvent *)event 517 | { 518 | double deltaX, deltaY; 519 | 520 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 521 | if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) 522 | { 523 | deltaX = [event scrollingDeltaX]; 524 | deltaY = [event scrollingDeltaY]; 525 | 526 | if ([event hasPreciseScrollingDeltas]) 527 | { 528 | deltaX *= 0.1; 529 | deltaY *= 0.1; 530 | } 531 | } 532 | else 533 | #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ 534 | { 535 | deltaX = [event deltaX]; 536 | deltaY = [event deltaY]; 537 | } 538 | 539 | if (fabs(deltaX) > 0.0 || fabs(deltaY) > 0.0) 540 | { 541 | ImGuiIO& io = ImGui::GetIO(); 542 | io.MouseWheel += deltaY * 0.05f; 543 | } 544 | } 545 | 546 | -(void)dealloc 547 | { 548 | [animationTimer release]; 549 | [super dealloc]; 550 | } 551 | 552 | @end 553 | 554 | //------------------------------------------------------------------ 555 | // IMGUIExampleAppDelegate 556 | //------------------------------------------------------------------ 557 | @interface IMGUIExampleAppDelegate : NSObject 558 | 559 | @property (nonatomic, readonly) NSWindow *window; 560 | 561 | @end 562 | 563 | @implementation IMGUIExampleAppDelegate 564 | 565 | @synthesize window = _window; 566 | 567 | - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication 568 | { 569 | return YES; 570 | } 571 | 572 | - (NSWindow*)window 573 | { 574 | if (_window != nil) 575 | return(_window); 576 | 577 | NSRect viewRect = NSMakeRect(100.0, 100.0, 1300.0, 800.0); 578 | 579 | _window = [[NSWindow alloc] initWithContentRect:viewRect styleMask:NSTitledWindowMask|NSMiniaturizableWindowMask|NSResizableWindowMask|NSClosableWindowMask backing:NSBackingStoreBuffered defer:YES]; 580 | [_window setTitle:@"IMGUI OSX Sample"]; 581 | [_window setOpaque:YES]; 582 | 583 | [_window makeKeyAndOrderFront:NSApp]; 584 | 585 | return(_window); 586 | } 587 | 588 | - (void)setupMenu 589 | { 590 | NSMenu *mainMenuBar; 591 | NSMenu *appMenu; 592 | NSMenuItem *menuItem; 593 | 594 | mainMenuBar = [[NSMenu alloc] init]; 595 | 596 | appMenu = [[NSMenu alloc] initWithTitle:@"IMGUI OSX Sample"]; 597 | menuItem = [appMenu addItemWithTitle:@"Quit IMGUI OSX Sample" action:@selector(terminate:) keyEquivalent:@"q"]; 598 | [menuItem setKeyEquivalentModifierMask:NSCommandKeyMask]; 599 | 600 | menuItem = [[NSMenuItem alloc] init]; 601 | [menuItem setSubmenu:appMenu]; 602 | 603 | [mainMenuBar addItem:menuItem]; 604 | 605 | [appMenu release]; 606 | [NSApp setMainMenu:mainMenuBar]; 607 | } 608 | 609 | - (void)dealloc 610 | { 611 | [_window dealloc]; 612 | [super dealloc]; 613 | } 614 | 615 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 616 | [self setupMenu]; 617 | 618 | NSOpenGLPixelFormatAttribute attrs[] = 619 | { 620 | NSOpenGLPFADoubleBuffer, 621 | NSOpenGLPFADepthSize, 32, 622 | 0 623 | }; 624 | 625 | NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; 626 | IMGUIExampleView *view = [[IMGUIExampleView alloc] initWithFrame:self.window.frame pixelFormat:format]; 627 | [format release]; 628 | #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 629 | if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) 630 | [view setWantsBestResolutionOpenGLSurface:YES]; 631 | #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ 632 | 633 | [self.window setContentView:view]; 634 | 635 | if ([view openGLContext] == nil) 636 | { 637 | NSLog(@"No OpenGL Context!"); 638 | } 639 | IMGUIExample_InitImGui(); 640 | // This is needed to accept mouse move events 641 | [self.window setAcceptsMouseMovedEvents:YES]; 642 | // This is needed to accept mouse events before clicking on the window 643 | [self.window makeFirstResponder:view]; 644 | } 645 | 646 | @end 647 | 648 | //------------------------------------------------------------------ 649 | // main 650 | //------------------------------------------------------------------ 651 | 652 | int main(int argc, const char * argv[]) 653 | { 654 | [[NSAutoreleasePool alloc] init]; 655 | NSApp = [NSApplication sharedApplication]; 656 | 657 | IMGUIExampleAppDelegate *delegate = [[IMGUIExampleAppDelegate alloc] init]; 658 | 659 | [[NSApplication sharedApplication] setDelegate:delegate]; 660 | [NSApp run]; 661 | return NSApplicationMain(argc, argv); 662 | } 663 | --------------------------------------------------------------------------------