diff --git a/engine/all.lisp b/engine/all.lisp index d0ac7df..a320c78 100644 --- a/engine/all.lisp +++ b/engine/all.lisp @@ -1,20 +1,23 @@ #| This file is a part of stoe project. - Copyright (c) 2015 Renaud Casenave-Péré (renaud@casenave-pere.fr) + Copyright (c) 2017 Renaud Casenave-Péré (renaud@casenave-pere.fr) |# (uiop:define-package :stoe/engine/all (:nicknames :engine) (:use-reexport - :stoe/engine/gl-utils - :stoe/engine/mesh - :stoe/engine/scene-graph - :stoe/engine/camera - :stoe/engine/scene - :stoe/engine/input - :stoe/engine/viewport - :stoe/engine/shaders + ;; :stoe/engine/gl-utils + ;; :stoe/engine/mesh + ;; :stoe/engine/scene-graph + ;; :stoe/engine/camera + ;; :stoe/engine/scene + ;; :stoe/engine/input + ;; :stoe/engine/viewport + ;; :stoe/engine/shaders + ;; :stoe/engine/render + ;; :stoe/engine/model + ;; #+stoe-foreign-assets + ;; :stoe/engine/import + :stoe/engine/window :stoe/engine/render - :stoe/engine/model - #+stoe-foreign-assets - :stoe/engine/import)) + )) diff --git a/engine/render-gl.lisp b/engine/render-gl.lisp new file mode 100644 index 0000000..4c38bc7 --- /dev/null +++ b/engine/render-gl.lisp @@ -0,0 +1,109 @@ +#| + This file is a part of stoe project. + Copyright (c) 2015 Renaud Casenave-Péré (renaud@casenave-pere.fr) +|# + +(uiop:define-package :stoe/engine/render + (:use :cl :cffi :maths :shader + :stoe/core/utils + :stoe/core/containers + :stoe/core/time + :stoe/core/modules + :stoe/core/thread + :stoe/core/jobs + :stoe/core/entity + :stoe/engine/gl-utils + :stoe/engine/mesh + :stoe/engine/viewport + :stoe/engine/scene-graph + :stoe/engine/camera + :stoe/engine/scene) + (:export #:on-render-thread + #:render #:render-single-mesh)) +(in-package :stoe/engine/render) + +(defclass render-thread (specialized-thread) + ()) + +(defvar *render-thread* nil) +(defvar *frames-per-second* 0.0) + +(defun initialize (&optional argv) + "Initialize the render module. +Create an opengl context attached to a window." + (format t "Initialize Render module~%") + (viewport-configure argv) + (setf *render-thread* (push-new-thread 'render-thread "Render thread"))) + +(defun finalize () + "Finalize the render module. +Destroy the opengl context and the related resources." + (format t "Finalize Render module~%") + (terminate-thread *render-thread*)) + +(defun update (delta-time) + (declare (ignore delta-time))) + +(defmodule stoe/engine/render :render) + +(let ((time-counter 0.0) + (frames-counter 0)) + (defun compute-fps (delta-time) + (incf time-counter delta-time) + (incf frames-counter) + (when (> time-counter 1000000.0) + (setf *frames-per-second* (if (> frames-counter 1) + frames-counter + (/ frames-counter (/ time-counter 1000000.0)))) + (setf time-counter 0.0) + (setf frames-counter 0)))) + +(defun render-single-mesh (mesh transform) + (using-program (program 'simple-shader) + (with-locations (model-to-camera camera-to-clip) program + (with-components (camera-component) (main-camera (world)) + (let ((mtc (m* (view camera-component) transform)) + (ctc (projection camera-component))) + (gl:uniform-matrix model-to-camera 4 (vector (raw-data mtc)) nil) + (gl:uniform-matrix camera-to-clip 4 (vector (raw-data ctc)) nil)))) + (render-mesh mesh program))) + +(defgeneric render (node)) + +(defmethod render ((node graph-node-component))) + +(defmethod render :after ((node graph-node-component)) + (mapc #'render (children node))) + +(defun render-world (world) + (unless (null world) + (locking-scene + (with-components ((root graph-node-component)) (current-scene) + (render root))))) + +(defmethod thread-initialize ((thread render-thread)) + (format t "Initialize ~a~%" (name thread)) + (viewport-initialize) + (compile-all-shaders)) + +(defmethod thread-finalize ((thread render-thread)) + (format t "Finalize ~a~%" (name thread)) + (destroy-all-shaders) + (viewport-finalize)) + +(defmethod thread-process ((thread render-thread)) + (let ((clock (make-clock))) + (loop until (thread-terminate-p thread) + do (restartable + (during-one-frame + (loop for job = (get-next-job thread) + while job + do (progn + (format t "Thread ~a: Running job ~a~%" (name thread) (id job)) + (job-run job thread))) + (render-world (world))) + (update-clock clock) + (compute-fps (clock-delta clock)))))) + +(defmacro on-render-thread (args &body body) + `(eval-on-thread ,args *render-thread* ,@body)) diff --git a/engine/render.lisp b/engine/render.lisp index 4c38bc7..f2217c8 100644 --- a/engine/render.lisp +++ b/engine/render.lisp @@ -1,25 +1,12 @@ #| This file is a part of stoe project. - Copyright (c) 2015 Renaud Casenave-Péré (renaud@casenave-pere.fr) + Copyright (c) 2017 Renaud Casenave-Péré (renaud@casenave-pere.fr) |# (uiop:define-package :stoe/engine/render - (:use :cl :cffi :maths :shader - :stoe/core/utils - :stoe/core/containers - :stoe/core/time + (:use :cl :vk :alexandria :cffi :stoe/core/modules - :stoe/core/thread - :stoe/core/jobs - :stoe/core/entity - :stoe/engine/gl-utils - :stoe/engine/mesh - :stoe/engine/viewport - :stoe/engine/scene-graph - :stoe/engine/camera - :stoe/engine/scene) - (:export #:on-render-thread - #:render #:render-single-mesh)) + :stoe/engine/window)) (in-package :stoe/engine/render) (defclass render-thread (specialized-thread) @@ -28,82 +15,73 @@ (defvar *render-thread* nil) (defvar *frames-per-second* 0.0) +(defvar *engine-name* "Stoe") +(defvar *engine-version* 0) + +(defvar *instance-extension-properties* nil) +(defvar *instance-layer-properties* nil) +(defvar *physical-devices* nil) +(defvar *physical-device-index* 0) +(defvar *queue-family-properties* nil) +(defvar *device-extension-properties* nil) +(defvar *device* nil) + +(push :vk-xlib *features*) + (defun initialize (&optional argv) "Initialize the render module. -Create an opengl context attached to a window." +Create a vulkan instance." + (declare (ignore argv)) (format t "Initialize Render module~%") - (viewport-configure argv) - (setf *render-thread* (push-new-thread 'render-thread "Render thread"))) + (window-initialize) + (setf *instance-layer-properties* (enumerate-instance-layer-properties)) + (setf *instance-extension-properties* (enumerate-instance-extension-properties "")) + (unless (and (boundp '%vk::*instance*) %vk::*instance*) + (let ((layers '("VK_LAYER_LUNARG_standard_validation")) + (exts '("VK_EXT_debug_report" + #+vk-xlib + "VK_KHR_xlib_surface" + #+vk-xcb + "VK_KHR_xcb_surface" + #+vk-wayland + "VK_KHR_wayland_surface"))) + (setf %vk::*instance-extensions* (make-hash-table)) + (setf %vk::*instance-params* (list :layers layers :exts exts)) + (let ((instance (vk-assert (create-instance :app "Stoe test" :app-version 0 + :engine *engine-name* :engine-version *engine-version* + :layers layers + :exts exts)))) + (setf %vk::*instance* instance)))) + (unless *device* + (let ((phys-devices (vk-assert (enumerate-physical-devices %vk::*instance*)))) + (setf *physical-devices* phys-devices) + (setf *queue-family-properties* + (mapcar (lambda (phys-device) + (get-physical-device-queue-family-properties phys-device)) + phys-devices)) + (let ((queue-family-index + (loop for queue-family in (nth *physical-device-index* + *queue-family-properties*) + for index = 0 then (1+ index) + when (member :graphics (getf queue-family :queue-flags)) + return index))) + (setf *device-extension-properties* (enumerate-device-extension-properties + (nth *physical-device-index* + *physical-devices*) "")) + (let ((device (vk-assert (create-device (first phys-devices) + :queue-family-index queue-family-index + :exts '("VK_KHR_swapchain"))))) + (setf *device* device)))))) (defun finalize () - "Finalize the render module. -Destroy the opengl context and the related resources." + "Finalize the render module." (format t "Finalize Render module~%") - (terminate-thread *render-thread*)) + (%vk::destroy-device *device* (null-pointer)) + (setf *device* nil) + (%vk::destroy-instance %vk::*instance* (null-pointer)) + (setf %vk::*instance* nil)) (defun update (delta-time) (declare (ignore delta-time))) (defmodule stoe/engine/render :render) - -(let ((time-counter 0.0) - (frames-counter 0)) - (defun compute-fps (delta-time) - (incf time-counter delta-time) - (incf frames-counter) - (when (> time-counter 1000000.0) - (setf *frames-per-second* (if (> frames-counter 1) - frames-counter - (/ frames-counter (/ time-counter 1000000.0)))) - (setf time-counter 0.0) - (setf frames-counter 0)))) - -(defun render-single-mesh (mesh transform) - (using-program (program 'simple-shader) - (with-locations (model-to-camera camera-to-clip) program - (with-components (camera-component) (main-camera (world)) - (let ((mtc (m* (view camera-component) transform)) - (ctc (projection camera-component))) - (gl:uniform-matrix model-to-camera 4 (vector (raw-data mtc)) nil) - (gl:uniform-matrix camera-to-clip 4 (vector (raw-data ctc)) nil)))) - (render-mesh mesh program))) - -(defgeneric render (node)) - -(defmethod render ((node graph-node-component))) - -(defmethod render :after ((node graph-node-component)) - (mapc #'render (children node))) - -(defun render-world (world) - (unless (null world) - (locking-scene - (with-components ((root graph-node-component)) (current-scene) - (render root))))) - -(defmethod thread-initialize ((thread render-thread)) - (format t "Initialize ~a~%" (name thread)) - (viewport-initialize) - (compile-all-shaders)) - -(defmethod thread-finalize ((thread render-thread)) - (format t "Finalize ~a~%" (name thread)) - (destroy-all-shaders) - (viewport-finalize)) - -(defmethod thread-process ((thread render-thread)) - (let ((clock (make-clock))) - (loop until (thread-terminate-p thread) - do (restartable - (during-one-frame - (loop for job = (get-next-job thread) - while job - do (progn - (format t "Thread ~a: Running job ~a~%" (name thread) (id job)) - (job-run job thread))) - (render-world (world))) - (update-clock clock) - (compute-fps (clock-delta clock)))))) - -(defmacro on-render-thread (args &body body) - `(eval-on-thread ,args *render-thread* ,@body)) diff --git a/engine/vk-utils.lisp b/engine/vk-utils.lisp new file mode 100644 index 0000000..af8c211 --- /dev/null +++ b/engine/vk-utils.lisp @@ -0,0 +1,26 @@ +#| + This file is a part of stoe project. + Copyright (c) 2017 Renaud Casenave-Péré (renaud@casenave-pere.fr) +|# + +(uiop:define-package :stoe/engine/vk-utils + (:use :cl :vk)) +(in-package :stoe/engine/vk-utils) + +(defvar *engine-name* "Stoe") +(defvar *engine-version* 0) + +(defvar *physical-devices* nil) +(defvar *instance-layer-properties* nil) +(defvar *instance-extension-properties* nil) + +(defun create-vk-instance (&key app-name app-version) + (setf *instance-layer-properties* (enumerate-instance-layer-properties)) + (setf *instance-extension-properties* (enumerate-instance-extension-properties "")) + (let ((instance (vk:create-instance :app app-name :app-version app-version + :engine *engine-name* :engine-version *engine-version* + :layers '("VK_LAYER_LUNARG_standard_validation") + :exts '("VK_EXT_debug_report" + "VK_KHR_xlib_surface")))) + (setf *physical-devices* (vk:enumerate-physical-devices instance)) + (setf cl-vulkan-bindings::*instance* instance))) diff --git a/engine/window.lisp b/engine/window.lisp new file mode 100644 index 0000000..e080120 --- /dev/null +++ b/engine/window.lisp @@ -0,0 +1,23 @@ +#| + This file is a part of stoe project. + Copyright (c) 2017 Renaud Casenave-Péré (renaud@casenave-pere.fr) +|# + +(uiop:define-package :stoe/engine/window + (:use :cl :glop) + (:export + #:window-initialize #:window-finalize)) +(in-package :stoe/engine/window) + +(let ((main-window)) + (defun window () main-window) + + (defun window-initialize () + "Initialize the window." + (setf *main-window* (create-window "Stoe" 1280 720 :gl nil))) + + (defun window-finalize () + "Finalize the window." + (when *main-window* + (destroy-window *main-window*) + (setf *main-window* nil)))) diff --git a/stoe.asd b/stoe.asd index d52efc6..1c762a6 100644 --- a/stoe.asd +++ b/stoe.asd @@ -14,7 +14,7 @@ (:use :cl :asdf)) (in-package :stoe-asd) -(pushnew :stoe-foreign-assets *features*) +;; (pushnew :stoe-foreign-assets *features*) ; classimp is out-of-date (pushnew :stoe-debug *features*) (defsystem stoe @@ -45,14 +45,12 @@ "bordeaux-threads" "blackbird" #+stoe-foreign-assets - "classimp" - "cl-opengl" + ;; "classimp" "closer-mop" - "glop" + "cl-vulkan" "stoe/core/all" "stoe/maths/all" - "stoe/engine/all" - "stoe/shader/all") + "stoe/engine/all") :components ((:file "stoe")) :in-order-to ((test-op (load-op stoe/test)))) @@ -62,7 +60,6 @@ (register-system-packages "stoe/maths/all" '(:maths)) (register-system-packages "stoe/core/all" '(:core)) (register-system-packages "stoe/engine/all" '(:engine)) -(register-system-packages "stoe/shader/all" '(:shader)) (register-system-packages "stoe/test/all" '(:stoe/test)) -(register-system-packages "cl-opengl" '(:gl)) +(register-system-packages "cl-vulkan" '(:vk)) diff --git a/stoe.lisp b/stoe.lisp index 9423c24..b8045ef 100644 --- a/stoe.lisp +++ b/stoe.lisp @@ -4,8 +4,8 @@ |# (uiop:define-package :stoe - (:use :cl :maths :core :engine :shader) - (:reexport :maths :core :engine :shader) + (:use :cl :maths :core) + (:reexport :maths :core) (:export #:main #:quit)) (in-package :stoe)