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.
 
 
 
 
 
 

286 lines
12 KiB

(import &comptime-only "Macros.cake")
(add-build-options "-DOGRE_DEBUG_MODE=1")
(add-c-search-directory "Dependencies/ogre-next/OgreMain/include"
"Dependencies/ogre-next/Components/Hlms/Common/include"
"Dependencies/ogre-next/Components/Hlms/Pbs/include"
"Dependencies/ogre-next/Components/Hlms/Unlit/include"
"Dependencies/ogre-next/build/Debug/include"
"Dependencies/ogre-next/Components/Overlay/include")
;; #pragma GCC diagnostic push
;; #pragma GCC diagnostic ignored "-Woverloaded-virtual"
(c-import
"OgreArchiveManager.h"
"OgreCamera.h"
"OgreConfigFile.h"
"OgreRoot.h"
"OgreWindow.h"
"OgreHlmsManager.h"
"OgreHlmsPbs.h"
"OgreHlmsUnlit.h"
"OgreItem.h"
"OgreMesh.h"
"OgreMesh2.h"
"OgreMeshManager.h"
"OgreMeshManager2.h"
"Compositor/OgreCompositorManager2.h"
"OgreWindowEventUtilities.h")
;; #pragma GCC diagnostic pop
(forward-declare
(namespace Ogre
(class Root)
(class SceneManager)))
(global-var g_ogreRoot (* (in Ogre Root)) null)
(var g_sceneManager (* (in Ogre SceneManager)) null)
(var g_window (* (in Ogre Window)) null)
(var g_graphicsIntialized bool false)
(global-var g_ogreWindowShouldQuit bool false)
;; TODO: Add advanced class definition
;; class MyWindowEventListener : public Ogre::WindowEventListener
;; {
;; public:
;; virtual void windowClosed(Ogre::Window* window)
;; {
;; g_ogreWindowShouldQuit = true;
;; }
;; };
;; (var g_myWindowEventListener MyWindowEventListener)
(defun-local registerHlms ()
(var resourcePath (in Ogre String) "data/")
(var config (in Ogre ConfigFile))
(on-call config load (+ resourcePath "resources2.cfg"))
(var rootHlmsFolder (in Ogre String)
(+ resourcePath (on-call config getSetting "DoNotUseAsResource" "Hlms" "")))
(cond ((on-call rootHlmsFolder empty)
(set rootHlmsFolder "./"))
((!= (deref (- (on-call rootHlmsFolder end) 1)) '/')
(set rootHlmsFolder (+ rootHlmsFolder "/"))))
;; At this point rootHlmsFolder should be a valid path to the Hlms data folder
(var hlmsUnlit (* (in Ogre HlmsUnlit)) null)
(var hlmsPbs (* (in Ogre HlmsPbs)) null)
;; For retrieval of the paths to the different folders needed
(var mainFolderPath (in Ogre String))
(var libraryFoldersPaths (in Ogre StringVector))
(var libraryFolderPathIt (in Ogre StringVector const_iterator))
(var libraryFolderPathEn (in Ogre StringVector const_iterator))
(var archiveManager (& (in Ogre ArchiveManager)) (call (in Ogre ArchiveManager getSingleton)))
(scope ;; Create & Register HlmsUnlit
;; Get the path to all the subdirectories used by HlmsUnlit
(call (in Ogre HlmsUnlit getDefaultPaths) mainFolderPath libraryFoldersPaths)
(var archiveUnlit (* (in Ogre Archive))
(on-call archiveManager load (+ rootHlmsFolder mainFolderPath) "FileSystem" true))
(var archiveUnlitLibraryFolders (in Ogre ArchiveVec))
(set libraryFolderPathIt (on-call libraryFoldersPaths begin))
(set libraryFolderPathEn (on-call libraryFoldersPaths end))
(while (!= libraryFolderPathIt libraryFolderPathEn)
(var archiveLibrary (* (in Ogre Archive))
(on-call archiveManager load
(+ rootHlmsFolder (deref libraryFolderPathIt)) "FileSystem" true))
(on-call archiveUnlitLibraryFolders push_back archiveLibrary)
(incr libraryFolderPathIt))
;; Create and register the unlit Hlms
(set hlmsUnlit (ogre-new (call (type (in Ogre HlmsUnlit)) archiveUnlit
(addr archiveUnlitLibraryFolders))))
(on-call-ptr (on-call (call (in Ogre Root getSingleton)) getHlmsManager) registerHlms hlmsUnlit))
(scope ;; Create & Register HlmsPbs
;; Do the same for HlmsPbs:
(call (in Ogre HlmsPbs getDefaultPaths) mainFolderPath libraryFoldersPaths)
(var archivePbs (* (in Ogre Archive))
(on-call archiveManager load
(+ rootHlmsFolder mainFolderPath) "FileSystem" true))
;; Get the library archive(s)
(var archivePbsLibraryFolders (in Ogre ArchiveVec))
(set libraryFolderPathIt (on-call libraryFoldersPaths begin))
(set libraryFolderPathEn (on-call libraryFoldersPaths end))
(while (!= libraryFolderPathIt libraryFolderPathEn)
(var archiveLibrary (* (in Ogre Archive))
(on-call archiveManager load
(+ rootHlmsFolder (deref libraryFolderPathIt)) "FileSystem" true))
(on-call archivePbsLibraryFolders push_back archiveLibrary)
(incr libraryFolderPathIt))
;; Create and register
(set hlmsPbs (ogre-new (call (type (in Ogre HlmsPbs)) archivePbs
(addr archivePbsLibraryFolders))))
(on-call-ptr (on-call (call (in Ogre Root getSingleton)) getHlmsManager) registerHlms hlmsPbs))
(var renderSystem (* (in Ogre RenderSystem))
(on-call-ptr (call (in Ogre Root getSingletonPtr)) getRenderSystem))
(when (= (on-call-ptr renderSystem getName) "Direct3D11 Rendering Subsystem")
;; Set lower limits 512kb instead of the default 4MB per Hlms in D3D 11.0
;; and below to avoid saturating AMD's discard limit (8MB) or
;; saturate the PCIE bus in some low end machines.
(var supportsNoOverwriteOnTextureBuffers bool)
(on-call-ptr renderSystem getCustomAttribute "MapNoOverwriteOnDynamicBufferSRV"
(addr supportsNoOverwriteOnTextureBuffers))
(unless supportsNoOverwriteOnTextureBuffers
(on-call-ptr hlmsPbs setTextureBufferDefaultSize (* 512 1024))
(on-call-ptr hlmsUnlit setTextureBufferDefaultSize (* 512 1024)))))
(defun OgreInitialize (useCurrentWindow bool &return bool)
(var pluginsFolder (const (in Ogre String)) "./data/")
(var writeAccessFolder (const (in Ogre String)) "./output/")
;; TODO: Support preprocessor?
;; #ifndef OGRE_STATIC_LIB
;; #if OGRE_DEBUG_MODE
(var pluginsFile (* (const char)) "plugins_d.cfg")
;; #else
;; const char* pluginsFile = "plugins.cfg";
;; #endif
;; #endif
(set g_ogreRoot (ogre-new (call (in Ogre Root) (+ pluginsFolder pluginsFile)
(+ writeAccessFolder "ogre.cfg")
(+ writeAccessFolder "Ogre.log"))))
;; This allows the user to configure the graphics. It's damn annoying during dev though
;; TODO: Make this return false and quit the app
;; if (!g_ogreRoot->showConfigDialog())
;; return false;
;; Initialize Root
(var renderSystem (* (in Ogre RenderSystem))
(on-call-ptr g_ogreRoot getRenderSystemByName "OpenGL 3+ Rendering Subsystem"))
(unless renderSystem
(printf "Render system not found!\n")
(return false))
;; renderSystem->setConfigOption("Display Frequency", "N/A");
(on-call-ptr renderSystem setConfigOption "Full Screen" "No")
;; renderSystem->setConfigOption("VSync", "Yes");
(on-call-ptr renderSystem setConfigOption "Video Mode" "1920 x 1080")
(on-call-ptr renderSystem setConfigOption "sRGB Gamma Conversion" "Yes")
(on-call-ptr g_ogreRoot setRenderSystem renderSystem)
(set g_window (on-call-ptr g_ogreRoot initialise
(not useCurrentWindow) ;; autoCreateWindow
"GameLib"))
;; Use the already existing window
;; See http:;;wiki.ogre3d.org/Using+SDL+Input (that actually didn't work 100%)
(when useCurrentWindow
(var windowSettings (in Ogre NameValuePairList))
;; TODO: There is a scary comment about using this option in GLXWindow::create(). It may
;; cause problems later. The documentation for this stuff is sorely lacking
(set (at "currentGLDrawable" windowSettings) (call (type (in Ogre String)) "True"))
(set (at "currentGLContext" windowSettings) (call (type (in Ogre String)) "True"))
(var winWidth int 1920)
(var winHeight int 1080)
(set g_window (on-call-ptr g_ogreRoot createRenderWindow "GameLib" winWidth winHeight
false ;; Fullscreen
(addr windowSettings)))
;; renderWindow->setVisible(true);
)
(registerHlms)
;; Create SceneManager
(var numThreads (const size_t) 1u)
(set g_sceneManager (on-call-ptr g_ogreRoot createSceneManager
(in Ogre ST_GENERIC) numThreads "SceneManager"))
;; Create & setup camera
(var camera (* (in Ogre Camera)) (on-call-ptr g_sceneManager createCamera "Main Camera"))
;; Position it at 500 in Z direction
(on-call-ptr camera setPosition (call (type (in Ogre Vector3)) 0 5 15))
;; Look back along -Z
(on-call-ptr camera lookAt (call (type (in Ogre Vector3)) 0 0 0))
(on-call-ptr camera setNearClipDistance 0.2f)
(on-call-ptr camera setFarClipDistance 1000.0f)
(on-call-ptr camera setAutoAspectRatio true)
;; Setup a basic compositor with a blue clear colour
(var compositorManager (* (in Ogre CompositorManager2))
(on-call-ptr g_ogreRoot getCompositorManager2))
(var workspaceName (const (in Ogre String)) "Main Workspace")
;; const IdString definitionNameId = workspaceName;
;; TODO: This needs initializer parameters
(var-construct backgroundColour (const (in Ogre ColourValue)) 0.2f 0.2f 0.2f)
(on-call-ptr compositorManager createBasicWorkspaceDef
workspaceName backgroundColour (call (in Ogre IdString)))
(on-call-ptr compositorManager addWorkspace
g_sceneManager (on-call-ptr g_window getTexture) camera workspaceName true)
(var resource-group-manager (& (in Ogre ResourceGroupManager))
(call (in Ogre ResourceGroupManager getSingleton)))
(on-call resource-group-manager addResourceLocation
"data/Models" "FileSystem" "Models")
(scope ;; Materials
;; I had to read https://forums.ogre3d.org/viewtopic.php?f=5&t=94769 before figuring out
;; groups needed to be initialized and loaded in order to work (at least, materials do)
(on-call resource-group-manager createResourceGroup "Materials")
(on-call resource-group-manager addResourceLocation
"data/Materials" "FileSystem" "Materials")
(on-call resource-group-manager initialiseResourceGroup "Materials"
true) ;; changeLocaleTemporarily: See comment above initialiseResourceGroup
(on-call resource-group-manager loadResourceGroup "Materials"))
;; (call (in Ogre WindowEventUtilities addWindowEventListener)
;; g_window (addr g_myWindowEventListener))
(set g_graphicsIntialized true)
(return true))
(defun OgreShutdown ()
;; (call (in Ogre WindowEventUtilities removeWindowEventListener)
;; g_window (addr g_myWindowEventListener))
(OGRE_DELETE g_ogreRoot)
(set g_ogreRoot null))
(defun ogreGetSceneManager (&return (* (in Ogre SceneManager)))
(return g_sceneManager))
(defgenerator ogre-new ()
(destructure-arguments expression-index)
(addStringOutput (field output source) "OGRE_NEW" StringOutMod_SpaceAfter
(addr (at startTokenIndex tokens)))
(var expression-context EvaluatorContext context)
(set (field expression-context scope) EvaluatorScope_ExpressionsOnly)
(unless (= (EvaluateGenerate_Recursive environment expression-context
tokens expression-index output)
0)
(return false))
(return true))
;; Given
;; (var-construct name type constructor-arguments)
;; Output
;; type name(constructor-arguments);
(defgenerator var-construct ()
(var constructor-var-statement (const ([] CStatementOperation))
(array
(array TypeNoArray null 2)
(array Keyword " " -1)
(array Expression null 1)
(array OpenParen null -1)
(array ExpressionList null 3)
(array CloseParen null -1)
(array SmartEndStatement null -1)))
(return (CStatementOutput environment context tokens startTokenIndex
constructor-var-statement (array-size constructor-var-statement)
output)))