working game

This commit is contained in:
2023-11-23 00:22:02 +01:00
parent ac8047cfb0
commit 353438ee5d
8 changed files with 3861 additions and 154 deletions

11
include/BinaryData.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
namespace ph {
namespace data {
static const unsigned int NotesMP3_size = 164234;
const char* GetMP3Data();
} // namespace data
} // namespace ph

22
include/Ph.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
namespace ph {
enum Note {
A = 0,
Bb,
B,
C,
Db,
D,
Eb,
E,
F,
Gb,
G,
Ab,
NoteCount,
};
} // namespace ph

17
include/PhAudio.h Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
#include "Ph.h"
namespace ph {
namespace audio {
int Init();
void PlayNote(Note note);
double NoteDuration();
void Destroy();
} // namespace audio
} // namespace ph

10
include/PhGui.h Normal file
View File

@@ -0,0 +1,10 @@
#pragma once
namespace ph {
namespace gui {
void Render();
void Init();
} // namespace gui
} // namespace ph

3437
src/BinaryData.cpp Normal file

File diff suppressed because it is too large Load Diff

78
src/PhAudio.cpp Normal file
View File

@@ -0,0 +1,78 @@
#include "PhAudio.h"
#include "BinaryData.h"
#include <SDL.h>
#include <SDL_mixer.h>
#include <string>
namespace ph {
namespace audio {
static int audio_open = 0;
static Mix_Music* music = NULL;
static int next_track = 0;
static double chunk_duration = 0;
int Init() {
SDL_AudioSpec spec;
/* Initialize variables */
spec.freq = MIX_DEFAULT_FREQUENCY;
spec.format = MIX_DEFAULT_FORMAT;
spec.channels = MIX_DEFAULT_CHANNELS;
/* Initialize the SDL library */
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
SDL_Log("Couldn't initialize SDL: %s\n", SDL_GetError());
return 255;
}
/* Open the audio device */
if (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, MIX_DEFAULT_CHANNELS, 2048) < 0) {
SDL_Log("Couldn't open audio: %s\n", SDL_GetError());
return 2;
} else {
Mix_QuerySpec(&spec.freq, &spec.format, reinterpret_cast<int*>(&spec.channels));
SDL_Log("Opened audio at %d Hz %d bit%s %s audio buffer\n", spec.freq, (spec.format & 0xFF),
(SDL_AUDIO_ISFLOAT(spec.format) ? " (float)" : ""),
(spec.channels > 2) ? "surround"
: (spec.channels > 1) ? "stereo"
: "mono");
}
/* Set the music volume */
Mix_VolumeMusic(MIX_MAX_VOLUME);
/* Set the external music player, if any */
Mix_SetMusicCMD(SDL_getenv("MUSIC_CMD"));
music = Mix_LoadMUS_RW(SDL_RWFromConstMem(data::GetMP3Data(), data::NotesMP3_size), SDL_TRUE);
audio_open = 1;
chunk_duration = Mix_MusicDuration(music) / static_cast<double>(NoteCount);
return 0;
}
double NoteDuration() {
return chunk_duration;
}
void PlayNote(Note note) {
Mix_PlayMusic(music, 0);
Mix_SetMusicPosition(chunk_duration * note);
Mix_FadeOutMusic(chunk_duration * 1000);
}
void Destroy() {
if (music) {
Mix_FreeMusic(music);
music = NULL;
}
if (audio_open) {
Mix_CloseAudio();
audio_open = 0;
}
}
} // namespace audio
} // namespace ph

151
src/PhGui.cpp Normal file
View File

@@ -0,0 +1,151 @@
#include "PhGui.h"
#include "PhAudio.h"
#include "imgui.h"
#include <random>
#include <string>
#define DISABLED_COND(code, cond) \
{ \
bool Disabled = cond; \
if (Disabled) \
ImGui::BeginDisabled(); \
code if (Disabled) ImGui::EndDisabled(); \
}
namespace ph {
namespace gui {
static const std::string Notes[NoteCount] = {"A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"};
static bool InGame = false;
static Note Answer = NoteCount;
static float Cooldown = 0.0f;
static bool Right = false;
static bool ShowAnswer = false;
static bool Hint = true;
static int Score = 0;
template <typename NumberType>
NumberType GetRandomInt(NumberType min, NumberType max) {
std::random_device randomDevice;
std::mt19937 generator(randomDevice());
std::uniform_int_distribution<NumberType> distrib(min, max);
return distrib(generator);
}
static void PickNewRandomNote() {
ShowAnswer = false;
Right = false;
Hint = true;
Note lastAnswer = Answer;
while (Answer == lastAnswer)
Answer = static_cast<Note>(GetRandomInt(0, NoteCount - 1));
audio::PlayNote(Answer);
}
static void RenderRightPopup() {
if (Right)
ImGui::TextColored({0, 1, 0, 1}, "Bravo !");
}
static void RenderWrongPopup() {
if (!Right)
ImGui::TextColored({1, 0, 0, 1}, "Nul !");
}
static void RenderGameWindow() {
ImGui::Text("Score : %i", Score);
ImGui::Text("Quelle est la note ?");
DISABLED_COND(
if (ImGui::Button("Réécouter")) {
audio::PlayNote(Answer);
Hint = false;
},
!Hint)
ImGui::SameLine();
if (ImGui::Button("Voir la réponse")) {
ShowAnswer = true;
Score = 0;
}
ImGui::SameLine();
if (ImGui::Button("Quitter")) {
InGame = false;
Score = 0;
Cooldown = 0;
Right = false;
}
if (Cooldown > 0.0)
ImGui::BeginDisabled();
for (int i = 0; i < NoteCount; i++) {
ImVec4 color = (i == Ab || i == Bb || i == Db || i == Eb || i == Gb) ? ImVec4{0, 0, 0, 1} : ImVec4{0.5, .5, .5, 1};
ImGui::PushStyleColor(ImGuiCol_Button, color);
bool green = (ShowAnswer && i == Answer);
if (green)
ImGui::PushStyleColor(ImGuiCol_Button, {0, 1, 0, 1});
if (ImGui::Button(Notes[i].c_str())) {
Cooldown = audio::NoteDuration();
Right = (i == Answer);
if (Right && !ShowAnswer) {
audio::PlayNote(Answer);
Score++;
} else {
Score = 0;
}
}
if (green)
ImGui::PopStyleColor();
ImGui::PopStyleColor();
ImGui::SameLine();
}
if (Cooldown > 0.0)
ImGui::EndDisabled();
}
static void RenderMainWindow() {
if (ImGui::Button("Nouvelle Partie")) {
InGame = true;
Right = true;
}
if (ImGui::Button("Quitter")) {}
}
void Render() {
ImGuiIO& io = ImGui::GetIO();
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::Begin("MainWindow", nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDecoration);
if (InGame)
RenderGameWindow();
else
RenderMainWindow();
if (Cooldown > 0.0f) {
ImGui::NewLine();
RenderRightPopup();
RenderWrongPopup();
Cooldown -= ImGui::GetIO().DeltaTime;
} else if (Right) {
PickNewRandomNote();
}
ImGui::End();
#ifndef NDEBUG
ImGui::ShowDemoWindow();
#endif
}
void Init() {}
} // namespace gui
} // namespace ph

View File

@@ -3,12 +3,14 @@
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. // 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 // Read online: https://github.com/ocornut/imgui/tree/master/docs
#include "imgui.h" #include "PhAudio.h"
#include "imgui_impl_sdl2.h" #include "PhGui.h"
#include "imgui_impl_opengl3.h"
#include <stdio.h>
#include <SDL.h>
#include "backends/imgui_impl_opengl3_loader.h" #include "backends/imgui_impl_opengl3_loader.h"
#include "imgui.h"
#include "imgui_impl_opengl3.h"
#include "imgui_impl_sdl2.h"
#include <SDL.h>
#include <stdio.h>
// This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details. // This example can also compile and run with Emscripten! See 'Makefile.emscripten' for details.
#ifdef __EMSCRIPTEN__ #ifdef __EMSCRIPTEN__
@@ -16,179 +18,158 @@
#endif #endif
// Main code // Main code
int main(int, char**) int main(int, char**) {
{ // Setup SDL
// Setup SDL if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) {
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) printf("Error: %s\n", SDL_GetError());
{ return -1;
printf("Error: %s\n", SDL_GetError()); }
return -1;
}
// Decide GL+GLSL versions // Decide GL+GLSL versions
#if defined(IMGUI_IMPL_OPENGL_ES2) #if defined(IMGUI_IMPL_OPENGL_ES2)
// GL ES 2.0 + GLSL 100 // GL ES 2.0 + GLSL 100
const char* glsl_version = "#version 100"; const char* glsl_version = "#version 100";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); 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_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#elif defined(__APPLE__) #elif defined(__APPLE__)
// GL 3.2 Core + GLSL 150 // GL 3.2 Core + GLSL 150
const char* glsl_version = "#version 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_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_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
#else #else
// GL 3.0 + GLSL 130 // GL 3.0 + GLSL 130
const char* glsl_version = "#version 130"; const char* glsl_version = "#version 130";
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); 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_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
#endif #endif
// From 2.0.18: Enable native IME. // From 2.0.18: Enable native IME.
#ifdef SDL_HINT_IME_SHOW_UI #ifdef SDL_HINT_IME_SHOW_UI
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
#endif #endif
// Create window with graphics context // Create window with graphics context
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); 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_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_Window* window = SDL_CreateWindow("PerfectHear", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GLContext gl_context = SDL_GL_CreateContext(window);
SDL_GL_MakeCurrent(window, gl_context); SDL_GL_MakeCurrent(window, gl_context);
SDL_GL_SetSwapInterval(1); // Enable vsync SDL_GL_SetSwapInterval(1); // Enable vsync
// Setup Dear ImGui context // Setup Dear ImGui context
IMGUI_CHECKVERSION(); IMGUI_CHECKVERSION();
ImGui::CreateContext(); ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls (void)io;
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls
// Setup Dear ImGui style // Setup Dear ImGui style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
//ImGui::StyleColorsLight(); // ImGui::StyleColorsLight();
// Setup Platform/Renderer backends // Setup Platform/Renderer backends
ImGui_ImplSDL2_InitForOpenGL(window, gl_context); ImGui_ImplSDL2_InitForOpenGL(window, gl_context);
ImGui_ImplOpenGL3_Init(glsl_version); ImGui_ImplOpenGL3_Init(glsl_version);
// Load Fonts // 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. // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use
// - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. // ImGui::PushFont()/PopFont() to select them.
// - 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). // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
// - 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. // - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an
// - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. // assertion, or display an error and quit).
// - Read 'docs/FONTS.md' for more instructions and details. // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling
// - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! // ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call.
// - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See Makefile.emscripten for details. // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering.
//io.Fonts->AddFontDefault(); // - Read 'docs/FONTS.md' for more instructions and details.
//io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ !
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); // - Our Emscripten build process allows embedding fonts to be accessible at runtime from the "fonts/" folder. See
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); // Makefile.emscripten for details.
//io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); // io.Fonts->AddFontDefault();
//ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); // io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f);
//IM_ASSERT(font != nullptr); // 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 ImFontConfig cfg;
bool show_demo_window = true; cfg.SizePixels = 30;
bool show_another_window = false; io.Fonts->AddFontDefault(&cfg);
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
// Main loop ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
bool done = false;
int result = ph::audio::Init();
if (result != 0)
return result;
ph::gui::Init();
// Main loop
bool done = false;
#ifdef __EMSCRIPTEN__ #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. // 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. // You may manually call LoadIniSettingsFromMemory() to load settings from your own storage.
io.IniFilename = nullptr; io.IniFilename = nullptr;
EMSCRIPTEN_MAINLOOP_BEGIN EMSCRIPTEN_MAINLOOP_BEGIN
#else #else
while (!done) while (!done)
#endif #endif
{ {
// Poll and handle events (inputs, window resize, etc.) // 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. // 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.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. // of the mouse data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your
SDL_Event event; // copy of the keyboard data. Generally you may always pass all inputs to dear imgui, and hide them from your application based
while (SDL_PollEvent(&event)) // on those two flags.
{ SDL_Event event;
ImGui_ImplSDL2_ProcessEvent(&event); while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) ImGui_ImplSDL2_ProcessEvent(&event);
done = true; if (event.type == SDL_QUIT)
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) done = true;
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 // Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame(); ImGui_ImplSDL2_NewFrame();
ImGui::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!). ph::gui::Render();
if (show_demo_window)
ImGui::ShowDemoWindow(&show_demo_window);
// 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window. // Rendering
{ ImGui::Render();
static float f = 0.0f; glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y);
static int counter = 0; 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::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
SDL_GL_SwapWindow(window);
ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) }
ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state
ImGui::Checkbox("Another Window", &show_another_window);
ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f
ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color
if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated)
counter++;
ImGui::SameLine();
ImGui::Text("counter = %d", counter);
ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate);
ImGui::End();
}
// 3. Show another simple window.
if (show_another_window)
{
ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked)
ImGui::Text("Hello from another window!");
if (ImGui::Button("Close Me"))
show_another_window = false;
ImGui::End();
}
// 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__ #ifdef __EMSCRIPTEN__
EMSCRIPTEN_MAINLOOP_END; EMSCRIPTEN_MAINLOOP_END;
#endif #endif
// Cleanup // Cleanup
ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplSDL2_Shutdown(); ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext(); ImGui::DestroyContext();
SDL_GL_DeleteContext(gl_context); ph::audio::Destroy();
SDL_DestroyWindow(window);
SDL_Quit();
return 0; SDL_GL_DeleteContext(gl_context);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
} }