Browse Source

Added initial Dear ImGui module

* Got rid of GameLibMacros.cake in favor of moving its function to
CHelpers.cake (requires cakelisp update)
* Automatically clone cakelisp for test/ if necessary
* ImGui.cake only really functions for AutoTest.cake currently. I've
got more work to do to make it usable in another project
windows-imgui
Macoy Madson 8 months ago
parent
commit
04ac21e6cb
  1. 3
      .gitignore
  2. 1
      src/Aubio.cake
  3. 109
      src/ImGui.cake
  4. 115
      src/ImGuiSDLOpenGL.cpp
  5. 5
      test/Build.sh
  6. 40
      test/src/GamelibMacros.cake
  7. 3
      test/src/NoHotReload.cake
  8. 2
      test/src/VocalGame.cake

3
.gitignore

@ -67,4 +67,5 @@ test/data/Models/*.skeleton
test/data/Materials/Textures/*.dds
test/data/Models/*
test/imgui.ini

1
src/Aubio.cake

@ -71,6 +71,7 @@
(printf "Pitch:\n")
(fvec_print detected-pitch)
(printf "\n")
(del_fvec buffer)
(del_fvec detected-pitch)

109
src/ImGui.cake

@ -0,0 +1,109 @@
(import &comptime-only "Dependencies.cake" "CHelpers.cake")
;; (c-import &with-decls "imgui.h")
(c-import "imgui.h")
(add-c-search-directory-module "Dependencies/imgui")
(add-cpp-build-dependency "imgui.cpp"
"imgui_draw.cpp"
"imgui_tables.cpp"
"imgui_widgets.cpp")
(add-dependency-git-submodule clone-imgui "https://github.com/ocornut/imgui" "Dependencies/imgui")
(comptime-cond
('auto-test
(import "SDL.cake")
(c-import "<cstdio>" "SDL.h"
"imgui_impl_sdl.h" ;; Platform (inputs etc.)
"imgui_impl_opengl3.h") ;; Rendering
;; From ImGuiSDLOpenGL.cpp
(declare-extern-function ImGuiSDLOpenGL_SetAttributes (glsl-version (* (* (const char)))))
(declare-extern-function ImGuiSDLOpenGL_InitializeGLLoader (&return bool))
(declare-extern-function ImGuiSDLOpenGL_ClearWindow (io (* ImGuiIO) clear-color ImVec4))
(defun test--imgui-main (&return int)
(printf "Hello ImGui\n")
(var glsl-version (* (const char)) null)
(ImGuiSDLOpenGL_SetAttributes (addr glsl-version))
(var window (* SDL_Window) null)
(set window
(SDL_CreateWindow "GameLib ImGui"
SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED 1920 1080
(bit-or SDL_WINDOW_RESIZABLE SDL_WINDOW_OPENGL)))
(unless window
(sdl-print-error)
(return 1))
(var gl-context SDL_GLContext (SDL_GL_CreateContext window))
(SDL_GL_MakeCurrent window gl-context)
(SDL_GL_SetSwapInterval 1) ;; Enable vsync
(unless (ImGuiSDLOpenGL_InitializeGLLoader)
(printf "Failed ImGuiSDLOpenGL_InitializeGLLoader\n")
(return 1))
(call (in ImGui CreateContext))
(call (in ImGui StyleColorsDark))
;; Note: Passing in null for the context will break Viewports branch of ImGui
(unless (ImGui_ImplSDL2_InitForOpenGL window gl-context)
(printf "Failed ImGui_ImplSDL2_InitForOpenGL\n")
(return 1))
(ImGui_ImplOpenGL3_Init glsl-version)
(var exit-reason (* (const char)) null)
(while (not exit-reason)
(var event SDL_Event)
(while (SDL_PollEvent (addr event))
(ImGui_ImplSDL2_ProcessEvent (addr event))
(when (= (field event type) SDL_QUIT)
(set exit-reason "Window event")))
(var currentKeyStates (* (const Uint8)) (SDL_GetKeyboardState null))
(when (at SDL_SCANCODE_ESCAPE currentKeyStates)
(set exit-reason "Escape pressed"))
(ImGui_ImplOpenGL3_NewFrame)
(ImGui_ImplSDL2_NewFrame window)
(call (in ImGui NewFrame))
(call (in ImGui ShowDemoWindow))
(call (in ImGui Render))
(scope ;; Probably will be handled by your game instead
(var imgui-io (& ImGuiIO) (call (in ImGui GetIO)))
(var clear-color ImVec4 (array 0.2f 0.2f 0.2f 1.f))
(ImGuiSDLOpenGL_ClearWindow (addr imgui-io) clear-color))
(ImGui_ImplOpenGL3_RenderDrawData (call (in ImGui GetDrawData)))
(SDL_GL_SwapWindow window))
(when exit-reason
(printf "Exiting. Reason: %s\n" exit-reason))
(ImGui_ImplSDL2_Shutdown)
(call (in ImGui DestroyContext))
(sdl-shutdown window)
(return 0))
(add-c-search-directory-module "Dependencies/imgui/backends"
"Dependencies/imgui/examples/libs/gl3w"
"Dependencies/imgui/examples/libs/gl3w/GL")
(add-cpp-build-dependency "imgui_demo.cpp" "imgui_impl_sdl.cpp"
"ImGuiSDLOpenGL.cpp" "imgui_impl_opengl3.cpp"
"gl3w.c")
(add-library-dependency "GL" "dl") ;; dl for gl3w
(add-build-options "-DIMGUI_IMPL_OPENGL_LOADER_GL3W")
(module-use-sdl-build-options)))

115
src/ImGuiSDLOpenGL.cpp

@ -0,0 +1,115 @@
// Copied parts from Dependencies/imgui/examples/example_sdl_opengl3/main.cpp
#include <SDL.h>
#include <stdio.h>
#include "imgui.h"
#include "imgui_impl_opengl3.h"
#include "imgui_impl_sdl.h"
#if defined(IMGUI_IMPL_OPENGL_ES2)
#include <GLES2/gl2.h>
// About Desktop OpenGL function loaders:
// Modern desktop OpenGL doesn't have a standard portable header file to load OpenGL function
// pointers. Helper libraries are often used for this purpose! Here we are supporting a few common
// ones (gl3w, glew, glad). You may use another loader/header of your choice (glext, glLoadGen,
// etc.), or chose to manually implement your own.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
#include <GL/gl3w.h> // Initialize with gl3wInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
#include <GL/glew.h> // Initialize with glewInit()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
#include <glad/glad.h> // Initialize with gladLoadGL()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
#include <glad/gl.h> // Initialize with gladLoadGL(...) or gladLoaderLoadGL()
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition
// errors.
#include <glbinding/Binding.h> // Initialize with glbinding::Binding::initialize()
#include <glbinding/gl/gl.h>
using namespace gl;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)
#define GLFW_INCLUDE_NONE // GLFW including OpenGL headers causes ambiguity or multiple definition
// errors.
#include <glbinding/gl/gl.h>
#include <glbinding/glbinding.h> // Initialize with glbinding::initialize()
using namespace gl;
#else
#include IMGUI_IMPL_OPENGL_LOADER_CUSTOM
#endif
void ImGuiSDLOpenGL_SetAttributes(const char** glsl_version_out)
{
// 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
// 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);
if (glsl_version_out)
*glsl_version_out = glsl_version;
}
bool ImGuiSDLOpenGL_InitializeGLLoader()
{
// Initialize OpenGL loader
#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W)
bool err = gl3wInit() != 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW)
bool err = glewInit() != GLEW_OK;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD)
bool err = gladLoadGL() == 0;
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD2)
bool err = gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress) ==
0; // glad2 recommend using the windowing library loader instead of the (optionally)
// bundled one.
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2)
bool err = false;
glbinding::Binding::initialize();
#elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3)
bool err = false;
glbinding::initialize(
[](const char* name) { return (glbinding::ProcAddress)SDL_GL_GetProcAddress(name); });
#else
bool err = false; // If you use IMGUI_IMPL_OPENGL_LOADER_CUSTOM, your loader is likely to
// requires some form of initialization.
#endif
if (err)
{
fprintf(stderr, "Failed to initialize OpenGL loader!\n");
return false;
}
return true;
}
void ImGuiSDLOpenGL_ClearWindow(ImGuiIO* io, ImVec4 clear_color)
{
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);
}

5
test/Build.sh

@ -2,6 +2,9 @@
CAKELISP_DIR=Dependencies/cakelisp
# Link Cakelisp if necessary
[ ! -d "$CAKELISP_DIR" ] && git clone git@github.com:makuto/cakelisp.git Dependencies/cakelisp
# Build Cakelisp itself
echo "\n\nCakelisp\n\n"
cd $CAKELISP_DIR
@ -19,7 +22,7 @@ $CAKELISP src/Config_Linux.cake src/SDLOgreApp.cake || exit $?
# echo "\n\nAuto Test (Math only)\n\n"
# $CAKELISP --execute src/Config_Linux.cake src/AutoTest.cake src/Math.cake || exit $?
echo "\n\nAuto Test\n\n"
$CAKELISP --execute src/Config_Linux.cake ../src/AutoTest.cake ../src/SDL.cake ../src/Math.cake ../src/Aubio.cake || exit $?
$CAKELISP --execute src/Config_Linux.cake ../src/AutoTest.cake ../src/SDL.cake ../src/Math.cake ../src/Aubio.cake ../src/ImGui.cake || exit $?
# $CAKELISP src/Config_Linux.cake ../src/AutoTest.cake ../src/SDL.cake ../src/Tracy.cake ../src/Math.cake ../src/Aubio.cake || exit $?
echo "\n\nVocal Game (hot reload)\n\n"

40
test/src/GamelibMacros.cake

@ -1,40 +0,0 @@
(skip-build)
(add-cakelisp-search-directory "Dependencies/cakelisp/runtime")
(import &comptime-only "ComptimeHelpers.cake")
;; Given
;; (declare-extern-function my-func (i int &return bool))
;; Output
;; bool myFunc(int i);
;; This is useful for forward declarations of functions or declaring functions linked dynamically
(defgenerator declare-extern-function (name-token (ref symbol) signature-index (index array))
(quick-token-at signature-token signature-index)
(var return-type-start int -1)
(var arguments (<> std::vector FunctionArgumentTokens))
(unless (parseFunctionSignature tokens signature-index arguments return-type-start)
(return false))
(var end-signature-index int (FindCloseParenTokenIndex tokens signature-index))
(unless (outputFunctionReturnType environment context tokens output return-type-start
startTokenIndex
end-signature-index
true ;; Output to source
false) ;; Output to header
(return false))
(addStringOutput (path output . source) (field name-token contents)
StringOutMod_ConvertFunctionName
(addr name-token))
(addLangTokenOutput (field output source) StringOutMod_OpenParen (addr signature-token))
(unless (outputFunctionArguments environment context tokens output arguments
true ;; Output to source
false) ;; Output to header
(return false))
(addLangTokenOutput (field output source) StringOutMod_CloseParen (addr signature-token))
(addLangTokenOutput (field output source) StringOutMod_EndStatement (addr signature-token))
(return true))

3
test/src/NoHotReload.cake

@ -1,4 +1,5 @@
(import &comptime-only "GamelibMacros.cake")
(add-cakelisp-search-directory "Dependencies/cakelisp/runtime")
(import &comptime-only "CHelpers.cake")
(declare-extern-function
reloadableEntryPoint (&return bool))

2
test/src/VocalGame.cake

@ -1,6 +1,6 @@
(set-cakelisp-option executable-output "VocalGame")
(import &comptime-only "Options.cake" "ComptimeHelpers.cake" "GamelibMacros.cake")
(import &comptime-only "Options.cake" "ComptimeHelpers.cake")
(import "Ogre.cake" "OgreInitialize.cake" "SDL.cake" "Math.cake" "Tracy.cake" "Aubio.cake")

Loading…
Cancel
Save