GameLib is a collection of libraries for creating applications in Cakelisp.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

273 lines
12 KiB

(import &comptime-only "Dependencies.cake" "CHelpers.cake")
(c-import "imgui.h")
(defmacro imgui-call (function symbol &rest &optional arguments any)
(if arguments
(tokenize-push output
(call (in ImGui (token-splice function)) (token-splice-rest arguments tokens)))
(tokenize-push output
(call (in ImGui (token-splice function)))))
(return true))
;; When you just don't care about the details and want a ImGui window
(defmacro make-imgui-sdl-gl3-application (entry-point-name symbol
window-name string
initialization array
once-per-frame array
shutdown array)
(tokenize-push output
(defun (token-splice entry-point-name) (&return int)
(comptime-cond
('Windows
;; We are handling DPI scaling, so don't let Windows scale us again
(SetProcessDpiAwarenessContext DPI_AWARENESS_CONTEXT_SYSTEM_AWARE)))
;; Must do this before choosing the GL version
(SDL_Init SDL_INIT_VIDEO)
;; Not actually used: ImGuiSDLOpenGL_SetAttributes override these for SDL_GL_CreateContext
(SDL_GL_SetAttribute SDL_GL_CONTEXT_MAJOR_VERSION 3)
(SDL_GL_SetAttribute SDL_GL_CONTEXT_MINOR_VERSION 2)
(var display-bounds SDL_Rect (array 0))
;; Primary display
(SDL_GetDisplayBounds 0 (addr display-bounds))
;; Define the window size as a factor of the display size so that it should always fit
(var window-display-ratio float 0.75f)
(var window (* SDL_Window) null)
(set window
(SDL_CreateWindow (token-splice window-name)
SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED
(* window-display-ratio (field display-bounds w))
(* window-display-ratio (field display-bounds h))
(bit-or SDL_WINDOW_RESIZABLE SDL_WINDOW_OPENGL)))
(unless window
(sdl-print-error)
(return 1))
(var glsl-version (* (const char)) null)
(ImGuiSDLOpenGL_SetAttributes (addr glsl-version))
(var gl-context SDL_GLContext (SDL_GL_CreateContext window))
(SDL_GL_MakeCurrent window gl-context)
(SDL_GL_SetSwapInterval 1) ;; Enable vsync
(unless (ImGuiSDLOpenGL_InitializeGLLoader)
(fprintf stderr "Failed ImGuiSDLOpenGL_InitializeGLLoader\n")
(return 1))
(imgui-call CreateContext)
(scope ;; Enable docking
(var imgui-io (& ImGuiIO) (imgui-call GetIO))
(set (field imgui-io ConfigFlags) (bit-or (field imgui-io ConfigFlags)
ImGuiConfigFlags_DockingEnable)))
(scope ;; Enable keyboard navigation
(var imgui-io (& ImGuiIO) (imgui-call GetIO))
(set (field imgui-io ConfigFlags) (bit-or (field imgui-io ConfigFlags)
ImGuiConfigFlags_NavEnableKeyboard)))
;; DPI scaling
(var g-dpi-scale float 1.f)
;; Somewhat arbitrary numbers here which seemed to make sense on my 4k screen
(when (> (field display-bounds h) 1440)
(set g-dpi-scale 1.6f))
(scope
(var style (& ImGuiStyle) (imgui-call GetStyle))
(call-on ScaleAllSizes style g-dpi-scale))
(scope ;; Font
(var imgui-io (& ImGuiIO) (imgui-call GetIO))
(var g-font-size-pixels int 16)
(var ubuntu-mono-font (* ImFont)
(call-on-ptr AddFontFromFileTTF (field imgui-io Fonts)
;; TODO: Automatically copy this to user's project directory?
;; "data/Fonts/UbuntuMono-R.ttf"
"data/Fonts/Ubuntu-R.ttf"
(* g-font-size-pixels g-dpi-scale)))
;; imgui-io.Fonts->GetTexDataAsRGBA32();
(call-on-ptr Build (field imgui-io Fonts)))
;; (imgui-call StyleColorsDark)
(imgui-set-style-red-dark)
;; Note: Passing in null for the context will break Viewports branch of ImGui
(unless (ImGui_ImplSDL2_InitForOpenGL window gl-context)
(fprintf stderr "Failed ImGui_ImplSDL2_InitForOpenGL\n")
(return 1))
(ImGui_ImplOpenGL3_Init glsl-version)
(token-splice initialization)
(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)
(imgui-call NewFrame)
(scope ;; Probably will be handled by your game instead
(var imgui-io (& ImGuiIO) (imgui-call GetIO))
(var clear-color ImVec4 (array 0.1f 0.1f 0.1f 1.f))
(ImGuiSDLOpenGL_ClearWindow (addr imgui-io) clear-color))
(imgui-call DockSpaceOverViewport (imgui-call GetMainViewport)
;; Allow inputs and graphics to go through the dock
ImGuiDockNodeFlags_PassthruCentralNode)
(token-splice once-per-frame)
(imgui-call Render)
(ImGui_ImplOpenGL3_RenderDrawData (imgui-call GetDrawData))
(SDL_GL_SwapWindow window))
(when exit-reason
(SDL_HideWindow window)
(fprintf stderr "Exiting. Reason: %s\n" exit-reason))
(token-splice shutdown)
(ImGui_ImplOpenGL3_Shutdown)
(ImGui_ImplSDL2_Shutdown)
(imgui-call DestroyContext)
(sdl-shutdown window)
(return 0)))
(return true))
(defun imgui-set-style-red-dark ()
;; copied and modified from https://github.com/ocornut/imgui/issues/707
(var colors (* ImVec4) (field (imgui-call GetStyle) Colors))
(set (at ImGuiCol_Text colors) (ImVec4 0.75f 0.75f 0.75f 1.00f))
(set (at ImGuiCol_TextDisabled colors) (ImVec4 0.35f 0.35f 0.35f 1.00f))
(set (at ImGuiCol_WindowBg colors) (ImVec4 0.00f 0.00f 0.00f 0.94f))
(set (at ImGuiCol_ChildBg colors) (ImVec4 0.00f 0.00f 0.00f 0.00f))
(set (at ImGuiCol_PopupBg colors) (ImVec4 0.08f 0.08f 0.08f 0.94f))
(set (at ImGuiCol_Border colors) (ImVec4 0.00f 0.00f 0.00f 0.50f))
(set (at ImGuiCol_BorderShadow colors) (ImVec4 0.00f 0.00f 0.00f 0.00f))
(set (at ImGuiCol_FrameBg colors) (ImVec4 0.25f 0.25f 0.25f 0.54f))
(set (at ImGuiCol_FrameBgHovered colors) (ImVec4 0.37f 0.14f 0.14f 0.67f))
(set (at ImGuiCol_FrameBgActive colors) (ImVec4 0.39f 0.20f 0.20f 0.67f))
(set (at ImGuiCol_TitleBg colors) (ImVec4 0.04f 0.04f 0.04f 1.00f))
(set (at ImGuiCol_TitleBgActive colors) (ImVec4 0.48f 0.16f 0.16f 1.00f))
(set (at ImGuiCol_TitleBgCollapsed colors) (ImVec4 0.48f 0.16f 0.16f 1.00f))
(set (at ImGuiCol_MenuBarBg colors) (ImVec4 0.14f 0.14f 0.14f 1.00f))
(set (at ImGuiCol_ScrollbarBg colors) (ImVec4 0.02f 0.02f 0.02f 0.53f))
(set (at ImGuiCol_ScrollbarGrab colors) (ImVec4 0.31f 0.31f 0.31f 1.00f))
(set (at ImGuiCol_ScrollbarGrabHovered colors) (ImVec4 0.41f 0.41f 0.41f 1.00f))
(set (at ImGuiCol_ScrollbarGrabActive colors) (ImVec4 0.51f 0.51f 0.51f 1.00f))
(set (at ImGuiCol_CheckMark colors) (ImVec4 0.56f 0.10f 0.10f 1.00f))
(set (at ImGuiCol_SliderGrab colors) (ImVec4 1.00f 0.19f 0.19f 0.40f))
(set (at ImGuiCol_SliderGrabActive colors) (ImVec4 0.89f 0.00f 0.19f 1.00f))
(set (at ImGuiCol_Button colors) (ImVec4 1.00f 0.19f 0.19f 0.40f))
(set (at ImGuiCol_ButtonHovered colors) (ImVec4 0.80f 0.17f 0.00f 1.00f))
(set (at ImGuiCol_ButtonActive colors) (ImVec4 0.89f 0.00f 0.19f 1.00f))
(set (at ImGuiCol_Header colors) (ImVec4 0.33f 0.35f 0.36f 0.53f))
(set (at ImGuiCol_HeaderHovered colors) (ImVec4 0.76f 0.28f 0.44f 0.67f))
(set (at ImGuiCol_HeaderActive colors) (ImVec4 0.47f 0.47f 0.47f 0.67f))
(set (at ImGuiCol_Separator colors) (ImVec4 0.32f 0.32f 0.32f 1.00f))
(set (at ImGuiCol_SeparatorHovered colors) (ImVec4 0.32f 0.32f 0.32f 1.00f))
(set (at ImGuiCol_SeparatorActive colors) (ImVec4 0.32f 0.32f 0.32f 1.00f))
(set (at ImGuiCol_ResizeGrip colors) (ImVec4 1.00f 1.00f 1.00f 0.85f))
(set (at ImGuiCol_ResizeGripHovered colors) (ImVec4 1.00f 1.00f 1.00f 0.60f))
(set (at ImGuiCol_ResizeGripActive colors) (ImVec4 1.00f 1.00f 1.00f 0.90f))
(set (at ImGuiCol_Tab colors) (ImVec4 0.07f 0.07f 0.07f 0.51f))
(set (at ImGuiCol_TabHovered colors) (ImVec4 0.86f 0.23f 0.43f 0.67f))
(set (at ImGuiCol_TabActive colors) (ImVec4 0.19f 0.19f 0.19f 0.57f))
(set (at ImGuiCol_TabUnfocused colors) (ImVec4 0.05f 0.05f 0.05f 0.90f))
(set (at ImGuiCol_TabUnfocusedActive colors) (ImVec4 0.13f 0.13f 0.13f 0.74f))
(set (at ImGuiCol_DockingPreview colors) (ImVec4 0.47f 0.47f 0.47f 0.47f))
(set (at ImGuiCol_DockingEmptyBg colors) (ImVec4 0.20f 0.20f 0.20f 1.00f))
(set (at ImGuiCol_PlotLines colors) (ImVec4 0.61f 0.61f 0.61f 1.00f))
(set (at ImGuiCol_PlotLinesHovered colors) (ImVec4 1.00f 0.43f 0.35f 1.00f))
(set (at ImGuiCol_PlotHistogram colors) (ImVec4 0.90f 0.70f 0.00f 1.00f))
(set (at ImGuiCol_PlotHistogramHovered colors) (ImVec4 1.00f 0.60f 0.00f 1.00f))
(set (at ImGuiCol_TableHeaderBg colors) (ImVec4 0.19f 0.19f 0.20f 1.00f))
(set (at ImGuiCol_TableBorderStrong colors) (ImVec4 0.31f 0.31f 0.35f 1.00f))
(set (at ImGuiCol_TableBorderLight colors) (ImVec4 0.23f 0.23f 0.25f 1.00f))
(set (at ImGuiCol_TableRowBg colors) (ImVec4 0.00f 0.00f 0.00f 0.00f))
(set (at ImGuiCol_TableRowBgAlt colors) (ImVec4 1.00f 1.00f 1.00f 0.07f))
(set (at ImGuiCol_TextSelectedBg colors) (ImVec4 0.26f 0.59f 0.98f 0.35f))
(set (at ImGuiCol_DragDropTarget colors) (ImVec4 1.00f 1.00f 0.00f 0.90f))
(set (at ImGuiCol_NavHighlight colors) (ImVec4 0.26f 0.59f 0.98f 1.00f))
(set (at ImGuiCol_NavWindowingHighlight colors) (ImVec4 1.00f 1.00f 1.00f 0.70f))
(set (at ImGuiCol_NavWindowingDimBg colors) (ImVec4 0.80f 0.80f 0.80f 0.20f))
(set (at ImGuiCol_ModalWindowDimBg colors) (ImVec4 0.80f 0.80f 0.80f 0.35f)))
;;
;; Building
;;
(add-dependency-git-submodule clone-imgui "https://github.com/ocornut/imgui"
"Dependencies/imgui"
"docking")
;; TODO This is a hack: add build output dir as search directory. Should be built in?
(defun-comptime add-search-build-directory (manager (& ModuleManager) module (* Module)
&return bool)
(call-on push_back (path module > cSearchDirectories)
(call-on c_str (field manager buildOutputDir)))
(return true))
(export-and-evaluate
;; Different loaders are available. Loader selection could be done via macro to allow that flexibility
(import "OpenGL.cake")
(import "SDL.cake")
(c-import "SDL.h"
"imgui.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))
(add-c-search-directory-module
"Dependencies/gamelib/src"
"Dependencies/imgui"
"Dependencies/imgui/backends")
(add-compile-time-hook-module pre-build add-search-build-directory)
(comptime-cond
('Unix
(add-library-dependency "GL" "dl"))
('Windows
(add-linker-options "opengl32.lib"))))
(add-cpp-build-dependency "imgui.cpp"
"imgui_demo.cpp"
"imgui_draw.cpp"
"imgui_tables.cpp"
"imgui_widgets.cpp")
(add-cpp-build-dependency "imgui_impl_sdl.cpp" "ImGuiSDLOpenGL.cpp" "imgui_impl_opengl3.cpp")
;;
;; Testing
;;
(comptime-cond
('auto-test
(c-import "<stdio.h>")
(make-imgui-sdl-gl3-application ;; If you want your own entry point, check this macro's body
test--imgui-main
"GameLib ImGui test"
(scope (fprintf stderr "Initializing\n")) ;; Initialization
(scope ;; Once per frame
(imgui-call ShowDemoWindow))
(scope (fprintf stderr "Shut down\n"))))) ;; Shutdown