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.

152 lines
6.3 KiB

;; Windowing and OpenGL access are provided by SDL
(import "SDL.cake")
(c-import "stdio.h"
;; Use galogen-generated header. See (generate-gl-header)
"gl46.h") ;; "GL/gl.h"
(defun test--opengl (&return int)
(var window (* SDL_Window) null)
(unless (sdl-initialize-for-3d (addr window) "OpenGL" 640 480) (return 1))
(SDL_GL_SetSwapInterval 1) ;; Enable vsync
;; TODO: Support resizing with window resize callback
(glViewport 0 0 640 480)
(scope ;; Make our triangle vertex array object
(var vertex-buffer-id (unsigned int))
(glGenBuffers 1 (addr vertex-buffer-id))
(glBindBuffer GL_ARRAY_BUFFER vertex-buffer-id)
(var vertices ([] float)
0.25f 0.25f 0.25f
0.5f 0.5f 0.5f
0.75f 0.75f 0.75f))
(glBufferData GL_ARRAY_BUFFER (sizeof vertices) vertices GL_STATIC_DRAW))
(var exit-reason (* (const char)) null)
(while (not exit-reason)
(var event SDL_Event)
(while (SDL_PollEvent (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"))
(glClearColor 0.2f 0.3f 0.3f 1.f)
(SDL_GL_SwapWindow window))
(when exit-reason
(printf "Exiting. Reason: %s\n" exit-reason))
(sdl-shutdown window)
(return 0))))
;; Building
(add-library-dependency "GL" "dl"))
(add-linker-options "opengl32.lib")))
;; Most OpenGL loading libraries were not to my tastes. I decided on galogen
;; ( because it's only two C++ files (not python or something else) and
;; reads directly from the Khronos spec (and I don't have to use my web browser for *****-sake)
;; See
(add-dependency-git-submodule clone-galogen "" "Dependencies/galogen")
(defun-comptime generate-gl-header (manager (& ModuleManager) module (* Module) &return bool)
(var galogen-source-file (* (const char)) "Dependencies/galogen/galogen.cpp")
(var galogen-executable (* (const char))
(comptime-cond ('Unix "galogen") ('Windows "galogen.exe")))
;; Build galogen (GL header code generator)
(when (fileIsMoreRecentlyModified galogen-source-file galogen-executable)
((call-on c_str (field manager environment compileTimeBuildCommand fileToExecute))
galogen-source-file "Dependencies/galogen/third_party/tinyxml2.cpp"
"--std=c++11" "-O3"
"-o" galogen-executable)
(Log "error: failed to build galogen. This uses the compile-time build command\n")
(return false))
(addExecutablePermission galogen-executable))
((call-on c_str (field manager environment compileTimeBuildCommand fileToExecute))
galogen-source-file "Dependencies/galogen/third_party/tinyxml2.cpp"
"/Ox" "/EHsc")
(Log "error: failed to build galogen. This uses the compile-time build command\n")
(return false)))))
;; Use galogen to generate gl headers/source
;; TODO Use CURL or something to download the latest version from
(var gl-specification (* (const char)) "Dependencies/galogen/third_party/gl.xml")
;; TODO: Generate the version header name to match the version SDL.cake specifies
(var gl-generated-output-path ([] 256 char) (array 0))
(unless (outputFilenameFromSourceFilename
(call-on c_str (field manager buildOutputDir))
null gl-generated-output-path (sizeof gl-generated-output-path))
(Log "error: failed to generate gl output filename\n")
(return false))
(var gl-generated-source-name ([] 256 char) (array 0))
(PrintfBuffer gl-generated-source-name "%s.c" gl-generated-output-path)
(when (or (fileIsMoreRecentlyModified galogen-executable
(fileIsMoreRecentlyModified gl-specification
(var galogen-executable-path ([] 256 char) (array 0))
(comptime-cond ('Unix (PrintfBuffer galogen-executable-path "./%s" galogen-executable))
('Windows (PrintfBuffer galogen-executable-path "%s" galogen-executable)))
"--api" "gl" "--ver" "4.6" "--profile" "core"
"--filename" gl-generated-output-path)
(Log "error: failed to generate gl headers via galogen\n")
(return false)))
(scope ;; Add the generated file as a dependency
;; TODO: This needs to be cleaned up
(var gl-dependency ModuleDependency (array))
(set (field gl-dependency type) ModuleDependency_CFile)
(set (field gl-dependency name) "gl46.c")
(scope ;; Use this function as the blame token
;; TODO: Add __function__ for this
(var this-definition-name (* (const char)) "generate-gl-header")
(var this-definition (* ObjectDefinition)
(findObjectDefinition (field manager environment) this-definition-name))
(unless this-definition
(Logf "error: failed to find definition of %s to create blame token. Was it
renamed? Search for %s and replace it with the new name of the function it is defined in\n"
this-definition-name this-definition-name)
(return false))
(set (field gl-dependency blameToken) (path this-definition > definitionInvocation)))
(call-on push_back (path module > dependencies) gl-dependency))
(scope ;; Search paths for new dependency
;; Make sure Cakelisp can resolve to the file in the cache
(call-on push_back (path module > cSearchDirectories) (call-on c_str (field manager buildOutputDir)))
;; Make sure the source file can find its header
(call-on push_back (path module > cSearchDirectories) "."))
(return true))
(add-compile-time-hook-module pre-build generate-gl-header)