Browse Source

Got SDL working; Ogre doesn't use its window yet

* Moved shared macros into new Macros.cake
SDLAttempt
Macoy Madson 2 years ago
parent
commit
7339561e5b
  1. 9
      BuildDependencies_Debug.sh
  2. 4
      Build_Debug.sh
  3. 1
      ReadMe.org
  4. 71
      src/Macros.cake
  5. 72
      src/OgreCore.cake
  6. 86
      src/OgreInitialize.cpp
  7. 1
      src/OgreInitialize.hpp
  8. 90
      src/SDL.cake
  9. 49
      test/SDLOgreApp.cake

9
BuildDependencies_Debug.sh

@ -4,6 +4,15 @@ echo "Building Cakelisp..."
cd Dependencies/cakelisp && jam -j4 && cd ../
echo "done!"
# http://wiki.libsdl.org/Installation
echo "Building SDL"
cd SDL
mkdir -p build
cd build
# mkdir -p SDLBuild
../configure --prefix=$(pwd)SDLBuild && make && make install || exit $?
cd ../
# See the official script at
# https://raw.githubusercontent.com/OGRECave/ogre-next/master/Scripts/BuildScripts/output/build_ogre_linux_c%2B%2Blatest.sh
echo "Building Ogre dependencies..."

4
Build_Debug.sh

@ -3,4 +3,6 @@
# TODO: Support compiling as a library?
# ./Dependencies/cakelisp/bin/cakelisp src/OgreCore.cake || exit $?
./Dependencies/cakelisp/bin/cakelisp --verbose-processes test/OgreApp.cake
# ./Dependencies/cakelisp/bin/cakelisp --verbose-processes test/OgreApp.cake
# ./Dependencies/cakelisp/bin/cakelisp --verbose-processes src/SDL.cake
./Dependencies/cakelisp/bin/cakelisp --verbose-compile-time-build-objects test/SDLOgreApp.cake

1
ReadMe.org

@ -7,6 +7,7 @@ Clone the repository and its dependencies:
#+BEGIN_SRC sh
git clone https://macoy.me/code/macoy/gamelib.git
git submodule update --init --recursive
hg clone http://hg.libsdl.org/SDL Dependencies/SDL
#+END_SRC
Build dependencies:

71
src/Macros.cake

@ -0,0 +1,71 @@
(skip-build)
(import &comptime-only "../Dependencies/cakelisp/runtime/Macros.cake")
;; Creates forward declarations in header files.
;; Example usage:
;; (forward-declare (namespace Ogre (class item) (struct my-struct)))
;; Outputs namespace Ogre { class item; struct my-struct;}
(defgenerator forward-declare ()
;; TODO: Support global vs local?
(var is-global bool true)
(var output-dest (& (<> std::vector StringOutput))
(? is-global (field output header) (field output source)))
(var end-invocation-index int (FindCloseParenTokenIndex tokens startTokenIndex))
(var start-body-index int (+ 2 startTokenIndex))
(var current-index int start-body-index)
(var namespace-stack (<> std::vector int))
(while (< current-index end-invocation-index)
(var current-token (& (const Token)) (at current-index tokens))
;; Invocations
(when (= TokenType_OpenParen (field current-token type))
(var invocation-token (& (const Token)) (at (+ 1 current-index) tokens))
(cond
((= 0 (on-call (field invocation-token contents) compare "namespace"))
(unless (< (+ 3 current-index) end-invocation-index)
(ErrorAtToken invocation-token "missing name or body arguments")
(return false))
(var namespace-name-token (& (const Token)) (at (+ 2 current-index) tokens))
(addStringOutput output-dest "namespace"
StringOutMod_SpaceAfter (addr invocation-token))
(addStringOutput output-dest (field namespace-name-token contents)
StringOutMod_None (addr namespace-name-token))
(addLangTokenOutput output-dest StringOutMod_OpenBlock (addr namespace-name-token))
(on-call namespace-stack push_back (FindCloseParenTokenIndex tokens current-index)))
((or (= 0 (on-call (field invocation-token contents) compare "class"))
(= 0 (on-call (field invocation-token contents) compare "struct")))
(unless (< (+ 2 current-index) end-invocation-index)
(ErrorAtToken invocation-token "missing name argument")
(return false))
(var type-name-token (& (const Token)) (at (+ 2 current-index) tokens))
(unless (ExpectTokenType "forward-declare" type-name-token TokenType_Symbol)
(return false))
(addStringOutput output-dest (field invocation-token contents)
StringOutMod_SpaceAfter (addr invocation-token))
(addStringOutput output-dest (field type-name-token contents)
StringOutMod_None (addr type-name-token))
(addLangTokenOutput output-dest StringOutMod_EndStatement (addr type-name-token)))
(true
(ErrorAtToken invocation-token "unknown forward-declare type")
(return false))))
(when (= TokenType_CloseParen (field current-token type))
(for-in close-block-index int namespace-stack
(when (= close-block-index current-index)
(addLangTokenOutput output-dest StringOutMod_CloseBlock
(addr (at current-index tokens))))))
;; TODO: Support function calls so we can do this recursively?
;; (set current-index
;; (getNextArgument tokens current-index end-invocation-index))
(incr current-index))
(return true))
(defmacro command-add-string-argument ()
(destructure-arguments new-argument-index)
(quick-token-at new-argument new-argument-index)
(tokenize-push output (on-call (field linkCommand arguments) push_back
(array ProcessCommandArgumentType_String
(token-splice (addr new-argument)))))
(return true))

72
src/OgreCore.cake

@ -1,5 +1,7 @@
(set-cakelisp-option cakelisp-src-dir "Dependencies/cakelisp/src")
(import &comptime-only "Macros.cake")
(c-import "<stdio.h>"
;; Ogre dependencies
"OgreItem.h"
@ -16,6 +18,8 @@
;; TODO: convert these functions to cakelisp eventually
(defun ogre-initialize (&return bool)
(return (OgreInitialize)))
(defun ogre-initialize-sdl (&return bool)
(return (OgreInitializeSDL)))
(defun ogre-shutdown ()
(OgreShutdown))
@ -94,66 +98,6 @@
(set (field new-scene-node node) scene-node)))
(return new-scene-node))
;; Creates forward declarations in header files.
;; Example usage:
;; (forward-declare (namespace Ogre (class item) (struct my-struct)))
;; Outputs namespace Ogre { class item; struct my-struct;}
(defgenerator forward-declare ()
;; TODO: Support global vs local?
(var is-global bool true)
(var output-dest (& (<> std::vector StringOutput))
(? is-global (field output header) (field output source)))
(var end-invocation-index int (FindCloseParenTokenIndex tokens startTokenIndex))
(var start-body-index int (+ 2 startTokenIndex))
(var current-index int start-body-index)
(var namespace-stack (<> std::vector int))
(while (< current-index end-invocation-index)
(var current-token (& (const Token)) (at current-index tokens))
;; Invocations
(when (= TokenType_OpenParen (field current-token type))
(var invocation-token (& (const Token)) (at (+ 1 current-index) tokens))
(cond
((= 0 (on-call (field invocation-token contents) compare "namespace"))
(unless (< (+ 3 current-index) end-invocation-index)
(ErrorAtToken invocation-token "missing name or body arguments")
(return false))
(var namespace-name-token (& (const Token)) (at (+ 2 current-index) tokens))
(addStringOutput output-dest "namespace"
StringOutMod_SpaceAfter (addr invocation-token))
(addStringOutput output-dest (field namespace-name-token contents)
StringOutMod_None (addr namespace-name-token))
(addLangTokenOutput output-dest StringOutMod_OpenBlock (addr namespace-name-token))
(on-call namespace-stack push_back (FindCloseParenTokenIndex tokens current-index)))
((or (= 0 (on-call (field invocation-token contents) compare "class"))
(= 0 (on-call (field invocation-token contents) compare "struct")))
(unless (< (+ 2 current-index) end-invocation-index)
(ErrorAtToken invocation-token "missing name argument")
(return false))
(var type-name-token (& (const Token)) (at (+ 2 current-index) tokens))
(unless (ExpectTokenType "forward-declare" type-name-token TokenType_Symbol)
(return false))
(addStringOutput output-dest (field invocation-token contents)
StringOutMod_SpaceAfter (addr invocation-token))
(addStringOutput output-dest (field type-name-token contents)
StringOutMod_None (addr type-name-token))
(addLangTokenOutput output-dest StringOutMod_EndStatement (addr type-name-token)))
(true
(ErrorAtToken invocation-token "unknown forward-declare type")
(return false))))
(when (= TokenType_CloseParen (field current-token type))
(for-in close-block-index int namespace-stack
(when (= close-block-index current-index)
(addLangTokenOutput output-dest StringOutMod_CloseBlock
(addr (at current-index tokens))))))
;; TODO: Support function calls so we can do this recursively?
;; (set current-index
;; (getNextArgument tokens current-index end-invocation-index))
(incr current-index))
(return true))
(defun ogre-node-set-position (node (* scene-node) x float y float z float)
(on-call-ptr (path node > node) setPosition x y z))
@ -188,14 +132,6 @@
;; (return true))
;; (add-compile-time-hook-module pre-build ogre-pre-build-hook)
(defmacro command-add-string-argument ()
(destructure-arguments new-argument-index)
(quick-token-at new-argument new-argument-index)
(tokenize-push output (on-call (field linkCommand arguments) push_back
(array ProcessCommandArgumentType_String
(token-splice (addr new-argument)))))
(return true))
(defun-comptime ogre-link-hook (manager (& ModuleManager)
linkCommand (& ProcessCommand)
linkTimeInputs (* ProcessCommandInput) numLinkTimeInputs int

86
src/OgreInitialize.cpp

@ -207,6 +207,92 @@ bool OgreInitialize()
return true;
}
bool OgreInitializeSDL()
{
using namespace Ogre;
const String pluginsFolder = "./data/";
const String writeAccessFolder = "./output/";
#ifndef OGRE_STATIC_LIB
#if OGRE_DEBUG_MODE
const char* pluginsFile = "plugins_d.cfg";
#else
const char* pluginsFile = "plugins.cfg";
#endif
#endif
g_ogreRoot = OGRE_NEW 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
RenderSystem* renderSystem = g_ogreRoot->getRenderSystemByName("OpenGL 3+ Rendering Subsystem");
if (!renderSystem)
{
printf("Render system not found!\n");
return false;
}
// renderSystem->setConfigOption("Display Frequency", "N/A");
renderSystem->setConfigOption("Full Screen", "No");
// renderSystem->setConfigOption("VSync", "Yes");
renderSystem->setConfigOption("Video Mode", "1920 x 1080");
renderSystem->setConfigOption("sRGB Gamma Conversion", "Yes");
g_ogreRoot->setRenderSystem(renderSystem);
g_window = g_ogreRoot->initialise(/*autoCreateWindow=*/false, "GameLib");
// Use the already existing window
// See http://wiki.ogre3d.org/Using+SDL+Input
{
Ogre::NameValuePairList windowSettings;
windowSettings["currentGLContext"] = String("True");
int winWidth = 1920;
int winHeight = 1080;
g_window =
g_ogreRoot->createRenderWindow("GameLib", winWidth, winHeight, false, &windowSettings);
// renderWindow->setVisible(true);
}
registerHlms();
// Create SceneManager
const size_t numThreads = 1u;
g_sceneManager = g_ogreRoot->createSceneManager(ST_GENERIC, numThreads, "SceneManager");
// Create & setup camera
Camera* camera = g_sceneManager->createCamera("Main Camera");
// Position it at 500 in Z direction
camera->setPosition(Vector3(0, 5, 15));
// Look back along -Z
camera->lookAt(Vector3(0, 0, 0));
camera->setNearClipDistance(0.2f);
camera->setFarClipDistance(1000.0f);
camera->setAutoAspectRatio(true);
// Setup a basic compositor with a blue clear colour
CompositorManager2* compositorManager = g_ogreRoot->getCompositorManager2();
const String workspaceName("Main Workspace");
// const IdString definitionNameId = workspaceName;
const ColourValue backgroundColour(0.2f, 0.4f, 0.6f);
compositorManager->createBasicWorkspaceDef(workspaceName, backgroundColour, IdString());
compositorManager->addWorkspace(g_sceneManager, g_window->getTexture(), camera, workspaceName,
true);
Ogre::ResourceGroupManager::getSingleton().addResourceLocation("data/Models", "FileSystem",
"Models");
Ogre::WindowEventUtilities::addWindowEventListener(g_window, &g_myWindowEventListener);
g_graphicsIntialized = true;
return true;
}
void OgreShutdown()
{
Ogre::WindowEventUtilities::removeWindowEventListener(g_window, &g_myWindowEventListener);

1
src/OgreInitialize.hpp

@ -1,6 +1,7 @@
#pragma once
bool OgreInitialize();
bool OgreInitializeSDL();
void OgreShutdown();
namespace Ogre

90
src/SDL.cake

@ -0,0 +1,90 @@
(set-cakelisp-option cakelisp-src-dir "Dependencies/cakelisp/src")
(import &comptime-only "Macros.cake")
(c-import "stdio.h"
"SDL.h"
"SDL_syswm.h")
(defun-local print-sdl-error ()
(printf "SDL_Error: %s\n" (SDL_GetError)))
(forward-declare (struct SDL_Window))
(defun sdl-initialize (window-out (* (* SDL_Window)) &return bool)
(when (< (SDL_Init SDL_INIT_VIDEO) 0)
(print-sdl-error)
(return false))
(set (deref window-out)
(SDL_CreateWindow "Gamelib"
SDL_WINDOWPOS_UNDEFINED SDL_WINDOWPOS_UNDEFINED 1920 1080
(bit-or SDL_WINDOW_RESIZABLE SDL_WINDOW_OPENGL)))
(unless (deref window-out)
(print-sdl-error)
(return false))
;; Must explicitly create the GL context for Ogre
(unless (SDL_GL_CreateContext (deref window-out))
(print-sdl-error)
(return false))
(return true))
(defun sdl-shutdown (window (* SDL_Window))
(SDL_DestroyWindow window)
(SDL_Quit))
;; TODO: Automatically promote this if no main is defined. Separate target instead?
(defun sdl-main (&return int)
(printf "Hello, SDL!\n")
(var window (* SDL_Window) nullptr)
(unless (sdl-initialize (addr window)) (return 1))
;; (var window-surface (* SDL_Surface) (SDL_GetWindowSurface window))
(var exit-reason (* (const char)) nullptr)
(while (not exit-reason)
(var event SDL_Event)
(while (SDL_PollEvent (addr event))
(when (= (field event type) SDL_QUIT)
(set exit-reason "Window event")))
(SDL_UpdateWindowSurface window))
(when exit-reason
(printf "Exiting. Reason: %s\n" exit-reason))
(sdl-shutdown window)
(return 0))
;;
;; Building
;;
(set-module-option build-time-compiler "/usr/bin/clang++")
;; Include cakelisp source for DynamicLoader.hpp
(set-module-option build-time-compile-arguments
"-Wall" "-Wextra" "-Wno-unused-parameter"
"-g" "-c" 'source-input "-o" 'object-output "-fPIC"
"-IDependencies/SDL/buildSDLBuild/include/SDL2")
(defun-comptime sdl-link-hook (manager (& ModuleManager)
linkCommand (& ProcessCommand)
linkTimeInputs (* ProcessCommandInput) numLinkTimeInputs int
&return bool)
;; TODO: Expose this option somehow?
(var is-debug-build bool true)
(printf "SDL: Adding %s link arguments\n" (? is-debug-build "debug" "release"))
(if is-debug-build
;; TODO: Actually add debug build
(block
(command-add-string-argument "-LDependencies/SDL/buildSDLBuild/lib")
(command-add-string-argument "-lSDL2")
(command-add-string-argument "-Wl,-rpath,.:../Dependencies/SDL/buildSDLBuild/lib"))
(block
(command-add-string-argument "-LDependencies/sdl-next/build/Release/lib")
(command-add-string-argument "-lSDL2")
(command-add-string-argument "-Wl,-rpath,.:../Dependencies/SDL/buildSDLBuild/lib")))
(return true))
(add-compile-time-hook pre-link sdl-link-hook)

49
test/SDLOgreApp.cake

@ -0,0 +1,49 @@
(set-cakelisp-option cakelisp-src-dir "Dependencies/cakelisp/src")
(import "../src/OgreCore.cake"
"../src/SDL.cake")
(c-import "SDL.h" "SDL_syswm.h")
(defun main (&return int)
(var window (* SDL_Window) nullptr)
(unless (sdl-initialize (addr window))
(return 1))
;; Ogre uses exceptions for error handling, so we can't gracefully close without getting all that
;; stuff set up (which I don't really want to do; it belongs in Gamelib)
(ogre-initialize-sdl)
(var monkey-mesh mesh-handle (ogre-load-mesh "Suzanne.mesh"))
(var monkey-node scene-node (ogre-node-from-item monkey-mesh))
(var exit-reason (* (const char)) nullptr)
(var x float 0.f)
(var y float 0.f)
(var z float 0.f)
;; Main loop
(while true
(unless (ogre-handle-window-events)
(set exit-reason "Window closed")
(break))
(ogre-node-set-position (addr monkey-node) x y z)
(set x (+ x 0.01f))
(unless (ogre-render-frame)
(set exit-reason "Failed to render frame")
(break)))
(ogre-shutdown)
(when exit-reason
(printf "Exit reason: %s\n" exit-reason))
(return 0))
(set-cakelisp-option executable-output "test/ogreSDLApp")
;; TODO: Somehow inherit this from SDL.cake?
(set-module-option build-time-compiler "/usr/bin/clang++")
;; Include cakelisp source for DynamicLoader.hpp
(set-module-option build-time-compile-arguments
"-Wall" "-Wextra" "-Wno-unused-parameter"
"-g" "-c" 'source-input "-o" 'object-output "-fPIC"
"-IDependencies/SDL/buildSDLBuild/include/SDL2")
Loading…
Cancel
Save