Commit MetaInfo

Revisãob9c6e714470f63cd3006c5c8c8f663415bb0b893 (tree)
Hora2020-02-26 06:40:53
AutorDavid Ludwig <dludwig@pobo...>
CommiterDavid Ludwig

Mensagem de Log

added initial, work-in-progress, support for Emscripten

Mudança Sumário

Diff

diff -r fa3f19865261 -r b9c6e714470f CMakeLists.txt
--- a/CMakeLists.txt Tue Feb 25 14:48:34 2020 -0500
+++ b/CMakeLists.txt Tue Feb 25 16:40:53 2020 -0500
@@ -16,11 +16,29 @@
1616 # target_include_directories(SDL-test-panel PRIVATE ${SDL2_INCLUDE_DIRS})
1717 # target_link_libraries(SDL-test-panel ${SDL2_LIBRARIES})
1818 set_property(TARGET SDL-test-panel PROPERTY CXX_STANDARD 20)
19+if (EMSCRIPTEN)
20+ set_target_properties(SDL-test-panel PROPERTIES
21+ OUTPUT_NAME "sdl-test-panel-emscripten"
22+ )
23+ target_include_directories(SDL-test-panel PRIVATE
24+ "${CMAKE_CURRENT_LIST_DIR}/../installed-emscripten/include/SDL2"
25+ )
26+ target_link_directories(SDL-test-panel PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../installed-emscripten/lib")
27+else()
28+ target_include_directories(SDL-test-panel PRIVATE
29+ "${CMAKE_CURRENT_LIST_DIR}/../include/SDL2"
30+ )
31+ target_link_directories(SDL-test-panel PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../lib")
32+endif()
1933 target_include_directories(SDL-test-panel PRIVATE
20- "${CMAKE_CURRENT_LIST_DIR}/../include/SDL2"
2134 "${CMAKE_CURRENT_LIST_DIR}/../imgui"
2235 "${CMAKE_CURRENT_LIST_DIR}/../imgui/examples"
2336 "${CMAKE_CURRENT_LIST_DIR}/../imgui_sdl"
2437 )
25-target_link_directories(SDL-test-panel PRIVATE "${CMAKE_CURRENT_LIST_DIR}/../lib")
38+
2639 target_link_libraries(SDL-test-panel "$<IF:$<CONFIG:Debug>,SDL2d,SDL2>")
40+
41+add_custom_command(
42+ TARGET SDL-test-panel
43+ POST_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different "${CMAKE_CURRENT_LIST_DIR}/sdl-test-panel-emscripten.*" $<TARGET_FILE_DIR:SDL-test-panel>
44+)
diff -r fa3f19865261 -r b9c6e714470f main.cpp
--- a/main.cpp Tue Feb 25 14:48:34 2020 -0500
+++ b/main.cpp Tue Feb 25 16:40:53 2020 -0500
@@ -30,6 +30,10 @@
3030 #include "imgui_sdl.h"
3131 #include "imgui_internal.h"
3232
33+#if defined(EMSCRIPTEN)
34+#include "emscripten.h"
35+#endif
36+
3337 extern bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
3438
3539 void ImGui_TextGUID(SDL_JoystickGUID guid)
@@ -477,6 +481,95 @@
477481 ImGui::EndChild();
478482 }
479483
484+static bool isRunning = true;
485+static SDL_Renderer * renderer = nullptr;
486+
487+void Tick()
488+{
489+ // Process user-input events
490+ ImGuiIO & io = ImGui::GetIO();
491+ int wheel = 0;
492+ SDL_Event e;
493+ while (SDL_PollEvent(&e)) {
494+ switch (e.type) {
495+ case SDL_QUIT:
496+ isRunning = false;
497+ break;
498+ case SDL_WINDOWEVENT:
499+ if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
500+ {
501+ io.DisplaySize.x = static_cast<float>(e.window.data1);
502+ io.DisplaySize.y = static_cast<float>(e.window.data2);
503+ }
504+ break;
505+ case SDL_MOUSEWHEEL:
506+ wheel = e.wheel.y;
507+ break;
508+#if DEV_DAVIDL
509+ case SDL_JOYBUTTONDOWN:
510+ printf("SDL_JOYBUTTONDOWN\n");
511+ break;
512+ case SDL_JOYBUTTONUP:
513+ printf("SDL_JOYBUTTONUP\n");
514+ break;
515+ case SDL_JOYDEVICEADDED:
516+ printf("SDL_JOYDEVICEADDED\n");
517+ break;
518+ case SDL_JOYDEVICEREMOVED:
519+ printf("SDL_JOYDEVICEREMOVED\n");
520+ break;
521+
522+#endif
523+ default:
524+ ImGui_ImplSDL2_ProcessEvent(&e);
525+ break;
526+ }
527+ }
528+
529+ // Record time-advancement
530+ static Uint64 g_Time = 0;
531+ static const Uint64 frequency = SDL_GetPerformanceFrequency();
532+ const Uint64 current_time = SDL_GetPerformanceCounter();
533+ io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f);
534+ g_Time = current_time;
535+
536+ // Update mouse inputs
537+ int mouseX, mouseY;
538+ const int buttons = SDL_GetMouseState(&mouseX, &mouseY);
539+ io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
540+ io.MouseDown[0] = buttons & SDL_BUTTON(SDL_BUTTON_LEFT);
541+ io.MouseDown[1] = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT);
542+ io.MouseWheel = static_cast<float>(wheel);
543+
544+ // Tell ImGui that we're ready to draw a new frame
545+ ImGui::NewFrame();
546+
547+ // Layout this frame's ImGui
548+ static bool show_window_imgui_demo = false;
549+ static bool show_window_joysticks = true;
550+ if (ImGui::BeginMainMenuBar()) {
551+ if (ImGui::BeginMenu("View")) {
552+ ImGui::MenuItem("ImGui Demo Window...", NULL, &show_window_imgui_demo);
553+ ImGui::MenuItem("Joysticks...", NULL, &show_window_joysticks);
554+ ImGui::EndMenu();
555+ }
556+ ImGui::EndMainMenuBar();
557+ }
558+ if (show_window_imgui_demo) {
559+ ImGui::ShowDemoWindow();
560+ }
561+ if (show_window_joysticks) {
562+ ShowJoystickMainWindow();
563+ }
564+
565+ // Tell ImGui + SDL that we're done drawing, for now
566+ SDL_SetRenderDrawColor(renderer, 114, 144, 154, 255);
567+ SDL_RenderClear(renderer);
568+ ImGui::Render();
569+ ImGuiSDL::Render(ImGui::GetDrawData());
570+ SDL_RenderPresent(renderer);
571+}
572+
480573 int main()
481574 {
482575 // Initialize SDL and ImGui
@@ -492,7 +585,7 @@
492585 #endif
493586 sysWindowWidth, sysWindowHeight,
494587 SDL_WINDOW_RESIZABLE);
495- SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
588+ renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
496589 ImGui::CreateContext();
497590 ImGuiSDL::Initialize(renderer, sysWindowWidth, sysWindowHeight);
498591 SDL_Texture * texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_TARGET, 100, 100);
@@ -512,91 +605,13 @@
512605 #endif
513606
514607 // Loop indefinitely while processing events and drawing content
515- bool isRunning = true;
608+#if defined(__EMSCRIPTEN__)
609+ emscripten_set_main_loop(Tick, 0, 1);
610+#else
516611 while (isRunning) {
517- // Process user-input events
518- ImGuiIO & io = ImGui::GetIO();
519- int wheel = 0;
520- SDL_Event e;
521- while (SDL_PollEvent(&e)) {
522- switch (e.type) {
523- case SDL_QUIT:
524- isRunning = false;
525- break;
526- case SDL_WINDOWEVENT:
527- if (e.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
528- {
529- io.DisplaySize.x = static_cast<float>(e.window.data1);
530- io.DisplaySize.y = static_cast<float>(e.window.data2);
531- }
532- break;
533- case SDL_MOUSEWHEEL:
534- wheel = e.wheel.y;
535- break;
536-#if DEV_DAVIDL
537- case SDL_JOYBUTTONDOWN:
538- printf("SDL_JOYBUTTONDOWN\n");
539- break;
540- case SDL_JOYBUTTONUP:
541- printf("SDL_JOYBUTTONUP\n");
542- break;
543- case SDL_JOYDEVICEADDED:
544- printf("SDL_JOYDEVICEADDED\n");
545- break;
546- case SDL_JOYDEVICEREMOVED:
547- printf("SDL_JOYDEVICEREMOVED\n");
548- break;
549-
612+ Tick();
613+ }
550614 #endif
551- default:
552- ImGui_ImplSDL2_ProcessEvent(&e);
553- break;
554- }
555- }
556-
557- // Record time-advancement
558- static Uint64 g_Time = 0;
559- static const Uint64 frequency = SDL_GetPerformanceFrequency();
560- const Uint64 current_time = SDL_GetPerformanceCounter();
561- io.DeltaTime = g_Time > 0 ? (float)((double)(current_time - g_Time) / frequency) : (float)(1.0f / 60.0f);
562- g_Time = current_time;
563-
564- // Update mouse inputs
565- int mouseX, mouseY;
566- const int buttons = SDL_GetMouseState(&mouseX, &mouseY);
567- io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
568- io.MouseDown[0] = buttons & SDL_BUTTON(SDL_BUTTON_LEFT);
569- io.MouseDown[1] = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT);
570- io.MouseWheel = static_cast<float>(wheel);
571-
572- // Tell ImGui that we're ready to draw a new frame
573- ImGui::NewFrame();
574-
575- // Layout this frame's ImGui
576- static bool show_window_imgui_demo = false;
577- static bool show_window_joysticks = true;
578- if (ImGui::BeginMainMenuBar()) {
579- if (ImGui::BeginMenu("View")) {
580- ImGui::MenuItem("ImGui Demo Window...", NULL, &show_window_imgui_demo);
581- ImGui::MenuItem("Joysticks...", NULL, &show_window_joysticks);
582- ImGui::EndMenu();
583- }
584- ImGui::EndMainMenuBar();
585- }
586- if (show_window_imgui_demo) {
587- ImGui::ShowDemoWindow();
588- }
589- if (show_window_joysticks) {
590- ShowJoystickMainWindow();
591- }
592-
593- // Tell ImGui + SDL that we're done drawing, for now
594- SDL_SetRenderDrawColor(renderer, 114, 144, 154, 255);
595- SDL_RenderClear(renderer);
596- ImGui::Render();
597- ImGuiSDL::Render(ImGui::GetDrawData());
598- SDL_RenderPresent(renderer);
599- }
600615
601616 // Cleanup
602617 ImGuiSDL::Deinitialize();
diff -r fa3f19865261 -r b9c6e714470f sdl-test-panel-emscripten.css
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sdl-test-panel-emscripten.css Tue Feb 25 16:40:53 2020 -0500
@@ -0,0 +1,179 @@
1+
2+:root {
3+ --canvas-scaling-factor: 1.0;
4+}
5+
6+body {
7+ background-color: black;
8+}
9+
10+.circle {
11+ position: absolute;
12+ width: 100px;
13+ height: 100px;
14+ border-radius: 50%;
15+ background-color: #dddddd;
16+ -webkit-transform: scale(1, 1);
17+ transform: scale(1, 1);
18+}
19+
20+.circle.circle_pulse {
21+ -webkit-animation-timing-function: ease;
22+ animation-timing-function: ease;
23+ -webkit-animation: circle_pulse 2s infinite;
24+ animation: circle_pulse 2s infinite;
25+ background-color: #ffffff;
26+}
27+
28+.circle_svg {
29+ fill: #333333;
30+ stroke: #333333;
31+ stroke-linejoin: round;
32+ stroke-width: 5;
33+ transition: all 0.3s;
34+}
35+
36+.circle_svg:hover {
37+ /* cursor: pointer; */
38+ fill: #000000;
39+ stroke: #000000;
40+ -webkit-transform: scale(1.2, 1.2);
41+ transform: scale(1.2, 1.2);
42+}
43+
44+@-webkit-keyframes circle_pulse {
45+ 0% {
46+ -webkit-transform: scale(1, 1);
47+ transform: scale(1, 1);
48+ }
49+ 25% {
50+ -webkit-transform: scale(1, 1);
51+ transform: scale(1, 1);
52+ }
53+ 50% {
54+ -webkit-transform: scale(1.2, 1.2);
55+ transform: scale(1.2, 1.2);
56+ }
57+ 100% {
58+ -webkit-transform: scale(1, 1);
59+ transform: scale(1, 1);
60+ }
61+}
62+
63+@keyframes circle_pulse {
64+ 0% {
65+ -webkit-transform: scale(1, 1);
66+ transform: scale(1, 1);
67+ }
68+ 25% {
69+ -webkit-transform: scale(1, 1);
70+ transform: scale(1, 1);
71+ }
72+ 50% {
73+ -webkit-transform: scale(1.2, 1.2);
74+ transform: scale(1.2, 1.2);
75+ }
76+ 100% {
77+ -webkit-transform: scale(1, 1);
78+ transform: scale(1, 1);
79+ }
80+}
81+
82+.content_window {
83+ position: absolute;
84+ top: 50%;
85+ left: 50%;
86+ transform: translate(-50%, -50%) scale(var(--canvas-scaling-factor));
87+ width: 1100px;
88+ height: 520px;
89+ /* display over the HUD */
90+ z-index: 2;
91+}
92+
93+.coverer {
94+ position: absolute;
95+ top: 0;
96+ left: 0;
97+ right: 0;
98+ bottom: 0;
99+ display: flex;
100+ align-items: center;
101+ justify-content: center;
102+ cursor: pointer;
103+ background-color: darkblue;
104+ border-color: darkgrey;
105+ border-width: 1px;
106+ border-style: solid;
107+}
108+
109+canvas.emscripten {
110+ image-rendering: -moz-crisp-edges;
111+ image-rendering: -webkit-crisp-edges;
112+ image-rendering: pixelated;
113+ image-rendering: crisp-edges;
114+ background-color: black;
115+ /* the canvas *must not* have any border or padding, or mouse coords will be wrong */
116+ border: 0px none;
117+}
118+
119+#hud {
120+ position: absolute;
121+ top: 0;
122+ left: 0;
123+ right: 0;
124+ width: 100%;
125+ /* height: 100px; */
126+ z-index: 1;
127+ /* background-color: green; */
128+ color: white;
129+ padding: 4px;
130+}
131+
132+.hudButton {
133+ /* position: absolute; */
134+ position: relative;
135+ right: 8px;
136+ background-color: #ffffff;
137+ padding: 8px;
138+ border-radius: 8px;
139+ /* right: 0; */
140+ float: right;
141+ /* box-shadow: 4px 4px gray; */
142+}
143+
144+.hudIcon {
145+ display: block;
146+ margin: auto;
147+ width: 24px;
148+ height: 24px;
149+ padding: 8px;
150+}
151+
152+.hudText {
153+ display: block;
154+ color: black;
155+ font-family: Sans-serif;
156+ /* text-transform: uppercase; */
157+}
158+
159+.loader {
160+ border: 16px solid #00000033;
161+ border-top: 16px solid #ffffff;
162+ border-radius: 50%;
163+ width: 100px;
164+ height: 100px;
165+ animation: spin 2s linear infinite;
166+}
167+
168+@keyframes spin {
169+ 0% { transform: rotate(0deg); }
170+ 100% { transform: rotate(360deg); }
171+}
172+
173+#click_to_start {
174+ /* visibility: visible; */
175+}
176+
177+#waiting_to_start {
178+ visibility: hidden;
179+}
diff -r fa3f19865261 -r b9c6e714470f sdl-test-panel-emscripten.html
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sdl-test-panel-emscripten.html Tue Feb 25 16:40:53 2020 -0500
@@ -0,0 +1,160 @@
1+<!DOCTYPE html>
2+<html>
3+
4+<head>
5+ <meta name="viewport" content="width=device-width, initial-scale=1">
6+ <!-- <script type="text/javascript" src="/live.js"></script> -->
7+ <!-- <script type="text/javascript" src="http://livejs.com/live.js"></script> -->
8+ <link rel="stylesheet" type="text/css" href="sdl-test-panel-emscripten.css">
9+
10+ <!-- HACK: use 'as="fetch" crossorigin', rather than just 'as="script"',
11+ to suppress preload-related warnings in Chrome -->
12+ <link rel="preload" href="sdl-test-panel-emscripten.js" as="fetch" crossorigin>
13+ <link rel="preload" href="sdl-test-panel-emscripten.wasm" as="fetch" crossorigin>
14+ <!-- <link rel="preload" href="sdl-test-panel-emscripten.data" as="fetch" crossorigin> -->
15+</head>
16+
17+<body>
18+ <div id="hud">
19+ <div class="hudButton" onclick="toggleFullscreen()">
20+ <svg class="hudIcon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
21+ <path d="M24 9h-2v-7h-7v-2h9v9zm-9 15v-2h7v-7h2v9h-9zm-15-9h2v7h7v2h-9v-9zm9-15v2h-7v7h-2v-9h9z"/>
22+ </svg>
23+ <div class="hudText">Fullscreen</div>
24+ </div>
25+ <!-- <span>Scaling: <span id="hudScalingFactor"></span>X</span> -->
26+ <!-- <button onclick="hideCover()">Hide Cover</button>
27+ <button onclick="startXHR()">Start XHR</button>
28+ <button onclick="execMainCode()">Exec Main Code</button> -->
29+ </div>
30+ <canvas class="content_window emscripten" id="canvas" width="1100" height="520" oncontextmenu="event.preventDefault()"></canvas>
31+ <div id="cover" class="content_window" onclick="userStarted()">
32+ <div id="click_to_start" class="coverer">
33+ <div class="circle circle_pulse"></div>
34+ <div class="circle">
35+ <svg class="circle_svg" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
36+ <polygon points="40,30 65,50 40,70"></polygon>
37+ </svg>
38+ </div>
39+ </div>
40+ <div id="waiting_to_start" class="coverer">
41+ <div class="loader"></div>
42+ </div>
43+ </div>
44+ <script type="text/javascript">
45+ Module = {
46+ printErr: function (text) {
47+ if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
48+ console.error(text);
49+ },
50+ canvas: (function () {
51+ var canvas = document.getElementById('canvas');
52+
53+ // As a default initial behavior, pop up an alert when webgl context is lost. To make your
54+ // application robust, you may want to override this behavior before shipping!
55+ // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
56+ canvas.addEventListener("webglcontextlost", function (e) {
57+ alert('WebGL context lost. You will need to reload the page.');
58+ e.preventDefault();
59+ }, false);
60+
61+ return canvas;
62+ })(),
63+ };
64+
65+ var MainCode = null;
66+ var InteractionStarted = false;
67+
68+ function toggleFullscreen() {
69+ var elem = document.documentElement;
70+ if (!document.fullscreenElement) {
71+ elem.requestFullscreen().catch(err => {
72+ alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
73+ });
74+ } else {
75+ document.exitFullscreen();
76+ }
77+ }
78+
79+ function startXHR() {
80+ // console.log("XHR CREATION");
81+ var xhr = new XMLHttpRequest();
82+ xhr.open("GET", "sdl-test-panel-emscripten.js");
83+ xhr.onload = function(e) {
84+ if (xhr.readyState === 4) {
85+ if (xhr.status === 200) {
86+ // setTimeout(function () {
87+ // console.log("XHR SUCCESS");
88+ MainCode = xhr.responseText;
89+ advanceUIState();
90+ // }, 4000); // ONLY USE FOR TESTING!
91+ } else {
92+ console.error("XHR HTTP ERROR:", xhr.statusText);
93+ }
94+ }
95+ };
96+ xhr.onerror = function(e) {
97+ console.error("XHR GENERIC ERROR:", xhr.statusText);
98+ };
99+ xhr.send(null);
100+ }
101+
102+ function advanceUIState() {
103+ if (!InteractionStarted) {
104+ // keep showing '#cover'
105+ } else if (MainCode == null) {
106+ document.getElementById("waiting_to_start").style.setProperty("visibility", "visible");
107+ document.getElementById("click_to_start").style.setProperty("display", "none");
108+ // keep showing '#waiting_to_start'
109+ } else {
110+ // hide the cover
111+ document.getElementById("cover").style.setProperty("display", "none");
112+ execMainCode();
113+ }
114+ }
115+
116+ function userStarted() {
117+ InteractionStarted = true;
118+ advanceUIState();
119+ }
120+
121+ function execMainCode() {
122+ if (MainCode == null) {
123+ console.error("Cannot execute MainCode, which has not been fully-loaded")
124+ return;
125+ }
126+
127+ // We will invoke main() ourselves (via emscripten_main(),
128+ // a function of ours and not Emscripten's), after an
129+ // asynchronous load of save-data.
130+ // Module.noInitialRun = true;
131+ // Module.postRun = function () { // This gets called regardless of noInitialRun=true
132+ // Module.ccall('emscripten_main');
133+ // }
134+
135+ const execMainCode = new Function('Module', MainCode);
136+ execMainCode(Module);
137+ }
138+
139+ function handleResize() {
140+ var canvas = document.getElementById("canvas");
141+ const scaleMaxX = Math.floor(window.innerWidth / canvas.width);
142+ const scaleMaxY = Math.floor(window.innerHeight / canvas.height);
143+ const scale = Math.max(1, Math.min(scaleMaxX, scaleMaxY));
144+ // console.log("handleResize", scale, "<--", scaleMaxX, scaleMaxY);
145+ document.documentElement.style.setProperty("--canvas-scaling-factor", scale);
146+ var hudScalingFactor = document.getElementById("hudScalingFactor");
147+ if (hudScalingFactor) {
148+ hudScalingFactor.textContent = scale;
149+ }
150+ }
151+
152+ window.addEventListener('load', handleResize);
153+ window.addEventListener('resize', handleResize);
154+ window.addEventListener("load", startXHR);
155+
156+ // drawDebugCanvas();
157+ </script>
158+</body>
159+
160+</html>
\ No newline at end of file
Show on old repository browser