Browse Source

Initial commit

master
alistair 9 months ago
commit
585f3e522c
  1. 178
      .clang-format
  2. 17
      .clang-tidy
  3. 115
      CMakeLists.txt
  4. 33
      cmake/CPM.cmake
  5. 60
      cmake/emscripten.cmake
  6. 8
      cmake/windows-cross-clang.cmake
  7. 13
      cmake/windows-cross-toolchain.cmake
  8. 32
      readme.md
  9. 64
      shell.emscripten.html
  10. 203
      source/main.cpp
  11. 54
      source/mainloop_stub.hpp

178
.clang-format

@ -0,0 +1,178 @@ @@ -0,0 +1,178 @@
---
Language: Cpp
# BasedOnStyle: Chromium
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveBitFields: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: DontAlign
AlignOperands: DontAlign
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortEnumsOnASingleLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: MultiLine
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterObjCDeclaration: false
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: true
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeBraces: Custom
# BreakBeforeInheritanceComma: true
BreakInheritanceList: BeforeComma
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: true
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: true
BreakStringLiterals: true
ColumnLimit: 80
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DeriveLineEnding: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Regroup
IncludeCategories:
# Standard library headers come before anything else
- Regex: '^<[a-z_]+>'
Priority: -1
- Regex: '^<.+\.h(pp)?>'
Priority: 1
- Regex: '^<.*'
Priority: 2
- Regex: '.*'
Priority: 3
IncludeIsMainRegex: ''
IncludeIsMainSourceRegex: ''
IndentCaseLabels: true
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: AfterHash
IndentExternBlock: NoIndent
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertTrailingCommas: Wrapped
JavaScriptQuotes: Double
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Never
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 200
PointerAlignment: Left
RawStringFormats:
- Language: Cpp
Delimiters:
- cc
- CC
- cpp
- Cpp
- CPP
- 'c++'
- 'C++'
CanonicalDelimiter: ''
BasedOnStyle: google
- Language: TextProto
Delimiters:
- pb
- PB
- proto
- PROTO
EnclosingFunctions:
- EqualsProto
- EquivToProto
- PARSE_PARTIAL_TEXT_PROTO
- PARSE_TEST_PROTO
- PARSE_TEXT_PROTO
- ParseTextOrDie
- ParseTextProtoOrDie
- ParseTestProto
- ParsePartialTestProto
CanonicalDelimiter: ''
BasedOnStyle: google
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatementsExceptForEachMacros
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: false
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false
Standard: Auto
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
...

17
.clang-tidy

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
---
# Enable ALL the things! Except not really
# misc-non-private-member-variables-in-classes: the options don't do anything
# modernize-use-nodiscard: too aggressive, attribute is situationally useful
Checks: "*,\
-google-readability-todo,\
-altera-*,\
-fuchsia-*,\
-modernize-*,\
fuchsia-multiple-inheritance,\
-llvm-header-guard,\
-llvm-include-order,\
-llvmlibc-*,\
-modernize-use-nodiscard,\
-misc-non-private-member-variables-in-classes"
WarningsAsErrors: ''
---

115
CMakeLists.txt

@ -0,0 +1,115 @@ @@ -0,0 +1,115 @@
cmake_minimum_required(VERSION 3.14)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
if(NOT compile-target)
#set(compile-target "-target x86_64-linux-gnu")
set(compile-target "")
else ()
message("using compile-target: " compile-target)
set(compile-target "-target compile-target")
endif()
set(BUILD_SHARED_LIBS OFF)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_C_FLAGS "CMAKE_C_FLAGS -g")
set(CMAKE_CXX_FLAGS "CMAKE_CXX_FLAGS -g -fpermissive -Wno-error ")
project(
chipgui
VERSION 0.1.0
DESCRIPTION "CHIP emulator visualiser"
HOMEPAGE_URL "https://example.com/"
LANGUAGES CXX
)
include(cmake/emscripten.cmake)
include(cmake/CPM.cmake)
include(FetchContent)
CPMAddPackage("gh:onqtam/doctest@2.4.9")
CPMAddPackage("gh:nlohmann/json@3.10.5")
CPMAddPackage("gh:ocornut/imgui#docking")
CPMAddPackage("gh:gabime/spdlog@1.8.2")
CPMAddPackage("gh:fmtlib/fmt#7.1.3")
FetchContent_Declare(SDL2
GIT_REPOSITORY https://github.com/libsdl-org/SDL
GIT_TAG release-2.26.4
OVERRIDE_FIND_PACKAGE
)
FetchContent_MakeAvailable(SDL2)
find_package(SDL2 REQUIRED)
# https://github.com/cpm-cmake/CPM.cmake/issues/368
add_library(imgui STATIC
imgui_SOURCE_DIR/imgui.cpp
imgui_SOURCE_DIR/imgui_demo.cpp # optionally comment this out
imgui_SOURCE_DIR/imgui_draw.cpp
imgui_SOURCE_DIR/imgui_widgets.cpp
imgui_SOURCE_DIR/imgui_tables.cpp
imgui_SOURCE_DIR/backends/imgui_impl_opengl3.cpp
imgui_SOURCE_DIR/backends/imgui_impl_sdl2.cpp
imgui_SOURCE_DIR/imgui_demo.cpp # optionally comment this out
)
target_include_directories(imgui PUBLIC imgui_SOURCE_DIR)
target_compile_definitions(imgui PUBLIC -DIMGUI_DISABLE_OBSOLETE_FUNCTIONS) # optional imgui setting
target_link_libraries(imgui PUBLIC SDL2::SDL2-static)
add_executable(main_exe source/main.cpp)
add_executable(main::exe ALIAS main_exe)
set(CMAKE_C_FLAGS_DEBUG
"CMAKE_C_FLAGS_DEBUG -Og -g -Werror -fsanitize=undefined -fsanitize=address -fsanitize=leak"
)
set(CMAKE_CXX_FLAGS_DEBUG
"CMAKE_CXX_FLAGS_DEBUG -Og -g -Werror -fsanitize=undefined -fsanitize=address -fsanitize=leak"
)
set(CMAKE_C_FLAGS_RELEASE "CMAKE_C_FLAGS_RELEASE -O2 -fstack-protector")
set(CMAKE_CXX_FLAGS_RELEASE "CMAKE_CXX_FLAGS_RELEASE -O2 -fstack-protector")
set_property(TARGET main_exe PROPERTY OUTPUT_NAME main)
target_compile_features(main_exe PRIVATE cxx_std_20)
if (EMSCRIPTEN)
hello_imgui_platform_customization(main_exe)
endif()
target_link_libraries(main_exe PRIVATE
fmt::fmt
SDL2::SDL2-static
spdlog
imgui
nlohmann_json::nlohmann_json
)
if (EMSCRIPTEN)
target_link_libraries(imgui PUBLIC SDL2::SDL2-static GLESv2)
endif()
if (LINUX)
target_link_libraries(imgui PUBLIC SDL2::SDL2-static OpenGL)
endif()
if (WIN32)
set(CMAKE_EXE_LINKER_FLAGS "-static -fstack-protector")
target_link_libraries(imgui PUBLIC SDL2::SDL2-static opengl32)
target_link_libraries(main_exe PRIVATE SDL2::SDL2main iconv ssp opengl32)
endif()

33
cmake/CPM.cmake

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
set(CPM_DOWNLOAD_VERSION 0.38.2)
if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
elseif(DEFINED ENV{CPM_SOURCE_CACHE})
set(CPM_DOWNLOAD_LOCATION "$ENV{CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
else()
set(CPM_DOWNLOAD_LOCATION "${CMAKE_BINARY_DIR}/cmake/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
endif()
# Expand relative path. This is important if the provided path contains a tilde (~)
get_filename_component(CPM_DOWNLOAD_LOCATION ${CPM_DOWNLOAD_LOCATION} ABSOLUTE)
function(download_cpm)
message(STATUS "Downloading CPM.cmake to ${CPM_DOWNLOAD_LOCATION}")
file(DOWNLOAD
https://github.com/cpm-cmake/CPM.cmake/releases/download/v${CPM_DOWNLOAD_VERSION}/CPM.cmake
${CPM_DOWNLOAD_LOCATION}
)
endfunction()
if(NOT (EXISTS ${CPM_DOWNLOAD_LOCATION}))
download_cpm()
else()
# resume download if it previously failed
file(READ ${CPM_DOWNLOAD_LOCATION} check)
if("${check}" STREQUAL "")
download_cpm()
endif()
unset(check)
endif()
include(${CPM_DOWNLOAD_LOCATION})

60
cmake/emscripten.cmake

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
# https://github.com/pthom/hello_imgui/blob/master/hello_imgui_cmake/emscripten/hello_imgui_emscripten.cmake
if (EMSCRIPTEN)
# Also see global emscripten flags in hello_imgui_cmake/emscripten/hello_imgui_emscripten_global_options.cmake
function(hello_imgui_emscripten_set_shell_file app_name)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/shell.emscripten.html)
set(shell_template_file ${CMAKE_CURRENT_SOURCE_DIR}/shell.emscripten.html)
endif()
message(${shell_template_file})
get_property(runtime_output_directory TARGET ${app_name} PROPERTY RUNTIME_OUTPUT_DIRECTORY)
if ("${runtime_output_directory}" STREQUAL "")
set(real_output_directory ${CMAKE_CURRENT_BINARY_DIR})
else()
set(real_output_directory ${runtime_output_directory})
endif()
set(shell_file ${real_output_directory}/shell.emscripten.in.html)
configure_file(
${shell_template_file}
${shell_file}
@ONLY
)
target_link_options(
${app_name}
PRIVATE
"SHELL:--shell-file ${shell_file}"
)
set_target_properties(
${app_name}
PROPERTIES
SUFFIX .html
)
endfunction()
function(hello_imgui_emscripten_target_compile_options app_name)
target_link_options(${app_name} PRIVATE -sUSE_SDL=2 -sASSERTIONS)
if (NOT HELLOIMGUI_EMSCRIPTEN_PTHREAD OR HELLOIMGUI_EMSCRIPTEN_PTHREAD_ALLOW_MEMORY_GROWTH)
target_link_options(${app_name} PRIVATE -sALLOW_MEMORY_GROWTH)
endif()
endfunction()
function(hello_imgui_set_emscripten_target_initial_memory_megabytes app_name nb_megabytes)
math(EXPR nb_bytes "1048576 * ${nb_megabytes}")
target_link_options(${app_name} PRIVATE -sINITIAL_MEMORY=${nb_bytes})
endfunction()
function(hello_imgui_platform_customization app_name)
hello_imgui_emscripten_set_shell_file(${app_name})
hello_imgui_emscripten_target_compile_options(${app_name})
endfunction()
endif (EMSCRIPTEN)

8
cmake/windows-cross-clang.cmake

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
#set(CMAKE_SYSTEM_NAME Windows)
set(triple x86_64-win32-gnu)
set(CMAKE_C_COMPILER clang)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_CXX_COMPILER_TARGET ${triple})

13
cmake/windows-cross-toolchain.cmake

@ -0,0 +1,13 @@ @@ -0,0 +1,13 @@
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR x86_64)
find_program(CMAKE_C_COMPILER NAMES x86_64-w64-mingw32-gcc)
find_program(CMAKE_CXX_COMPILER NAMES x86_64-w64-mingw32-g++)
if(NOT CMAKE_C_COMPILER)
message(FATAL_ERROR "Failed to find CMAKE_C_COMPILER.")
endif()
if(NOT CMAKE_CXX_COMPILER)
message(FATAL_ERROR "Failed to find CMAKE_CXX_COMPILER.")
endif()

32
readme.md

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
# chipgui
CHIP emulator visualiser
A cross-splatform application using OpenGL ES and Dear ImGui.
Build native
```
cmake -B build .
cmake --build build
```
Build for web
```
emcmake cmake -B bweb
emmake cmake --build bweb
```
Cross-compile for windows
```
cmake -DCMAKE_TOOLCHAIN_FILE=cmake/windows-cross-toolchain.cmake -B bwin .
cmake --build bwin
```

64
shell.emscripten.html

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"/>
<title>@HELLO_IMGUI_ICON_DISPLAY_NAME@</title>
<style>
body { margin: 0; background-color: black }
.emscripten {
position: absolute;
top: 0px;
left: 0px;
margin: 0px;
border: 0;
width: 100%;
height: 100%;
overflow: hidden;
display: block;
image-rendering: optimizeSpeed;
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: optimize-contrast;
image-rendering: crisp-edges;
image-rendering: pixelated;
-ms-interpolation-mode: nearest-neighbor;
}
</style>
</head>
<body>
<canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
<script type='text/javascript'>
var Module = {
preRun: [],
postRun: [],
print: (function() {
return function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
};
})(),
printErr: function(text) {
text = Array.prototype.slice.call(arguments).join(' ');
console.error(text);
},
canvas: (function() {
var canvas = document.getElementById('canvas');
//canvas.addEventListener("webglcontextlost", function(e) { alert('FIXME: WebGL context lost, please reload the page'); e.preventDefault(); }, false);
return canvas;
})(),
setStatus: function(text) {
console.log("status: " + text);
},
monitorRunDependencies: function(left) {
// no run dependencies to log
}
};
window.onerror = function() {
console.log("onerror: " + event);
};
</script>
{{{ SCRIPT }}}
</body>
</html>

203
source/main.cpp

@ -0,0 +1,203 @@ @@ -0,0 +1,203 @@
// Dear ImGui: standalone example application for SDL2 + OpenGL
// (SDL is a cross-platform general purpose library for handling windows,
// inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) If you are new
// to Dear ImGui, read documentation from the docs/ folder + read the top of
// imgui.cpp. Read online: https://github.com/ocornut/imgui/tree/master/docs
// https://github.com/ocornut/imgui/tree/master/examples/example_sdl2_opengl3
#include <fstream>
#include <SDL.h>
#include <backends/imgui_impl_opengl3.h>
#include <backends/imgui_impl_sdl2.h>
#include <fmt/format.h>
#include <imgui.h>
#include <stdio.h>
#if defined(IMGUI_IMPL_OPENGL_ES2)
# include <SDL_opengles2.h>
#else
# include <SDL_opengl.h>
#endif
#ifdef __EMSCRIPTEN__
# include "mainloop_stub.hpp"
#endif
int main(int, char**)
{
// Setup SDL
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0)
{
printf("Error: %s\n", SDL_GetError());
return -1;
}
// Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100
const char* glsl_version = "#version 100";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#elif defined(__APPLE__)
// GL 3.2 Core + GLSL 150
const char* glsl_version = "#version 150";
SDL_GL_SetAttribute(
SDL_GL_CONTEXT_FLAGS,
SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#else
// GL 3.0 + GLSL 130
const char* glsl_version = "#version 130";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif
// From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif
// Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_WindowFlags window_flags =
(SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
| SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example",
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED,
1280,
720,
window_flags);
SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync
// Setup Dear ImGui context
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
(void)io;
io.ConfigFlags |=
ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |=
ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking
// Setup Dear ImGui style
ImGui::StyleColorsDark();
// Setup Platform/Renderer backends
ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init(glsl_version);
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can
// also load multiple fonts and use ImGui::PushFont()/PopFont() to select
// them.
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you
// need to select the font among multiple.
// - If the file cannot be loaded, the function will return a nullptr. Please
// handle those errors in your application (e.g. use an assertion, or display
// an error and quit).
// - The fonts will be rasterized at a given size (w/ oversampling) and stored
// into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which
// ImGui_ImplXXXX_NewFrame below will call.
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype
// for higher quality font rendering.
// - Read 'docs/FONTS.md' for more instructions and details.
// - Remember that in C/C++ if you want to include a backslash \ in a string
// literal you need to write a double backslash \\ !
// - Our Emscripten build process allows embedding fonts to be accessible at
// runtime from the "fonts/" folder. See Makefile.emscripten for details.
// io.Fonts->AddFontDefault();
// io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
// io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f);
// io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f);
// io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f);
// ImFont* font =
// io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f,
// nullptr, io.Fonts->GetGlyphRangesJapanese()); IM_ASSERT(font != nullptr);
// Our state
bool show_demo_window = true;
bool show_another_window = true;
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop
bool done = false;
#ifdef __EMSCRIPTEN__
// For an Emscripten build we are disabling file-system access, so let's not
// attempt to do a fopen() of the imgui.ini file. You may manually call
// LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = nullptr;
EMSCRIPTEN_MAINLOOP_BEGIN
#else
while (!done)
#endif
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to
// tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to
// your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input
// data to your main application, or clear/overwrite your copy of the
// keyboard data. Generally you may always pass all inputs to dear imgui,
// and hide them from your application based on those two flags.
SDL_Event event;
while (SDL_PollEvent(&event)) {
ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_QUIT)
done = true;
if (event.type == SDL_WINDOWEVENT
&& event.window.event == SDL_WINDOWEVENT_CLOSE
&& event.window.windowID == SDL_GetWindowID(window))
done = true;
}
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in
// ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear
// ImGui!).
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// Rendering
ImGui::Render();
glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
glClearColor(clear_color.x * clear_color.w,
clear_color.y * clear_color.w,
clear_color.z * clear_color.w,
clear_color.w);
glClear(GL_COLOR_BUFFER_BIT);
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);
}
#ifdef __EMSCRIPTEN__
EMSCRIPTEN_MAINLOOP_END;
#endif
// Cleanup
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}

54
source/mainloop_stub.hpp

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
// What does this file solves?
// - Since Dear ImGui 1.00 we took pride that most of our examples applications
// had their entire
// main-loop inside the main() function. That's because:
// - It makes the examples easier to read, keeping the code sequential.
// - It permit the use of local variables, making it easier to try things and
// perform quick
// changes when someone needs to quickly test something (vs having to
// structure the example in order to pass data around). This is very
// important because people use those examples to craft easy-to-past repro
// when they want to discuss features or report issues.
// - It conveys at a glance that this is a no-BS framework, it won't take your
// main loop away from you.
// - It is generally nice and elegant.
// - However, comes Emscripten... it is a wonderful and magical tech but it
// requires a "main loop" function.
// - Only some of our examples would run on Emscripten. Typically the ones
// rendering with GL or WGPU ones.
// - I tried to refactor those examples but felt it was problematic that other
// examples didn't follow the
// same layout. Why would the SDL+GL example be structured one way and the
// SGL+DX11 be structured differently? Especially as we are trying hard to
// convey that using a Dear ImGui backend in an *existing application* should
// requires only a few dozens lines of code, and this should be consistent and
// symmetrical for all backends.
// - So the next logical step was to refactor all examples to follow that layout
// of using a "main loop" function.
// This worked, but it made us lose all the nice things we had...
// Since only about 3 examples really need to run with Emscripten, here's our
// solution:
// - Use some weird macros and capturing lambda to turn a loop in main() into a
// function.
// - Hide all that crap in this file so it doesn't make our examples unusually
// ugly.
// As a stance and principle of Dear ImGui development we don't use C++
// headers and we don't want to suggest to the newcomer that we would ever use
// C++ headers as this would affect the initial judgment of many of our target
// audience.
// - Technique is based on this idea:
// https://github.com/ocornut/imgui/pull/2492/
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#include <functional>
static std::function<void()> MainLoopForEmscriptenP;
static void MainLoopForEmscripten() { MainLoopForEmscriptenP(); }
#define EMSCRIPTEN_MAINLOOP_BEGIN MainLoopForEmscriptenP = [&]()
#define EMSCRIPTEN_MAINLOOP_END \
; \
emscripten_set_main_loop(MainLoopForEmscripten, 0, true)
#else
#define EMSCRIPTEN_MAINLOOP_BEGIN
#define EMSCRIPTEN_MAINLOOP_END
#endif
Loading…
Cancel
Save