├── .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 |
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 | [](https://travis-ci.org/ocornut/imgui)
4 | [](https://scan.coverity.com/projects/4720)
5 |
6 | [](http://www.patreon.com/imgui) [](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 | 
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 | 
49 | 
50 | 
51 | 
52 | 
53 | 
54 | 
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 | 
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 | 
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 | [](http://www.patreon.com/imgui) [](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 |
--------------------------------------------------------------------------------