generated from alistair/sdl-imgui-template
alistair
9 months ago
commit
585f3e522c
11 changed files with 777 additions and 0 deletions
@ -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 |
||||
... |
@ -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: '' |
||||
--- |
@ -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() |
||||
|
@ -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}) |
@ -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) |
@ -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}) |
@ -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() |
@ -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 |
||||
``` |
||||
|
||||
|
||||
|
||||
|
||||
|
@ -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> |
@ -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; |
||||
} |
@ -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…
Reference in new issue