From 402cf13d27f00223e0c75ec2a9b64f620db17942 Mon Sep 17 00:00:00 2001 From: ~keith Date: Thu, 17 Feb 2022 19:13:45 +0000 Subject: [PATCH] render to texture --- .gitignore | 3 + wh-engine/main.lisp | 136 +++++++++++++++++++++++---------- wh-engine/render/drawable.lisp | 11 ++- 3 files changed, 102 insertions(+), 48 deletions(-) diff --git a/.gitignore b/.gitignore index e7fbbf7..32fe47c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ +# cloned wiki repo +/doc/wiki + # KDE :') .directory diff --git a/wh-engine/main.lisp b/wh-engine/main.lisp index 7d89cbb..d8aaa90 100644 --- a/wh-engine/main.lisp +++ b/wh-engine/main.lisp @@ -77,31 +77,26 @@ (setq *id-counter* (+ id 1))) id) -(defvar *running-scenes* nil - "List of running scenes.") +(defvar *world-scenes* () + "List of all running scenes.") (defun add-scene (scene) "Add a scene to the list of running scenes." (declare (type scene scene)) - (push scene *running-scenes*) + (push scene *world-scenes*) scene) (defun remove-scene (scene) "Remove a scene from the list of running scenes." (declare (type scene scene)) - (setf *running-scenes* (remove scene *running-scenes*)) + (setf *world-scenes* (remove scene *world-scenes*)) scene) (defun get-scene (scene-id) "Get a scene by its ID." - (find-if (lambda (scene) (eq [scene id] scene-id)) *running-scenes*)) - -(defun update-all-scenes () - "Update all running scenes." - (loop for scene in *running-scenes* - do [scene (update)])) + (find-if (lambda (scene) (eq [scene id] scene-id)) *world-scenes*)) (defvar *view-width* 384 "View-space width in pixels.") @@ -184,38 +179,95 @@ sdl2-ffi:+sdl-patchlevel+) (finish-output) (sdl2:with-window (win :flags '(:shown :opengl) - :w *view-width* :h *view-height* - :title (format nil "wh-engine ~D.~D.~D (Affero GPL; NON-FREE USAGE PROHIBITED)" - (nth 0 +version+) (nth 1 +version+) (nth 2 +version+))) + :w (* *view-width* *pixel-scale*) :h (* *view-height* *pixel-scale*) + :title (format nil "wh-engine ~1{~D.~D.~D~} (Affero GPL; NON-FREE USAGE PROHIBITED)" + +version+)) (sdl2:with-gl-context (gl-context win) (sdl2:gl-make-current win gl-context) - (gl:viewport 0 0 *view-width* *view-height*) - (gl:matrix-mode :projection) - (gl:ortho 0 *view-width* - 0 *view-height* - -1024 1024) - (gl:matrix-mode :modelview) - (gl:load-identity) - (gl:clear-color 0.0 0.0 0.0 1.0) - (gl:clear :color-buffer) - (gl:clear :depth-buffer) - (gl:enable :depth-test) + (let ((framebuf (car (gl:gen-framebuffers 1))) + (renderbuf (car (gl:gen-renderbuffers 1))) + (render-texture (car (gl:gen-textures 1))) + (win-width (nth-value 0 (sdl2:get-window-size win))) + (win-height (nth-value 1 (sdl2:get-window-size win)))) + ;; set up framebuffer + (gl:bind-framebuffer :framebuffer framebuf) - (sdl2:with-event-loop (:method :poll) - (:quit () t) - (:idle () - (update-all-scenes) - (gl:clear :color-buffer) - (let ((render-pass nil)) - (loop for view-ptr in *world-views* - for view = (ensure-live (weak-pointer-value view-ptr)) - when (and [view active-p] [view actor tree-active-p]) - do (progn - (unless (eq [view render-pass] render-pass) - (setf render-pass [view render-pass]) - (gl:clear :depth-buffer) - ) - [view (render-view *world-drawables*)]))) - (gl:flush) - (sdl2:gl-swap-window win))) - )))) + (gl:bind-texture :texture-2d render-texture) + (gl:tex-image-2d :texture-2d 0 :rgba *view-width* *view-height* 0 :rgba :unsigned-byte (cffi:null-pointer)) + (gl:tex-parameter :texture-2d :texture-wrap-s :clamp-to-edge) + (gl:tex-parameter :texture-2d :texture-wrap-t :clamp-to-edge) + (gl:tex-parameter :texture-2d :texture-min-filter :nearest) + (gl:tex-parameter :texture-2d :texture-mag-filter :nearest) + (gl:bind-texture :texture-2d 0) + + (gl:framebuffer-texture-2d :framebuffer :color-attachment0 :texture-2d render-texture 0) + + (gl:bind-renderbuffer :renderbuffer renderbuf) + (gl:renderbuffer-storage :renderbuffer :depth24-stencil8 *view-width* *view-height*) + (gl:bind-renderbuffer :renderbuffer 0) + + (gl:framebuffer-renderbuffer :framebuffer :depth-stencil-attachment :renderbuffer renderbuf) + + ;; make sure it's valid + (let ((result (gl:check-framebuffer-status :framebuffer))) + (unless (gl::enum= result :framebuffer-complete) + (error "Failed to create framebuffer: ~S" result))) + + ;; set up gl + (gl:matrix-mode :projection) + (gl:ortho 0 *view-width* + 0 *view-height* + -1024 1024) + (gl:matrix-mode :modelview) + (gl:load-identity) + (gl:clear-color 0.0 0.0 0.0 1.0) + (gl:clear :color-buffer) + (gl:clear :depth-buffer) + + (sdl2:with-event-loop (:method :poll) + (:quit () t) + (:idle () + ;; update + (loop for scene in *world-scenes* + do [scene (update)]) + ;; draw to render texture + (gl:bind-framebuffer :framebuffer framebuf) + (gl:viewport 0 0 *view-width* *view-height*) + (gl:clear :color-buffer) + (gl:enable :depth-test) + (let ((render-pass nil)) + (loop for view-ptr in *world-views* + for view = (ensure-live (weak-pointer-value view-ptr)) + when (and [view active-p] [view actor tree-active-p]) + do (progn + (unless (eq [view render-pass] render-pass) + (setf render-pass [view render-pass]) + (gl:clear :depth-buffer)) + [view (render-view *world-drawables*)]))) + + ;; now draw to window + (gl:bind-framebuffer :framebuffer 0) + (gl:viewport 0 0 win-width win-height) + (gl:clear :color-buffer) + (gl:disable :depth-test) + (gl:enable :texture-2d) + (gl:bind-texture :texture-2d render-texture) + (gl:matrix-mode :modelview) + (gl:load-identity) + + (gl:with-primitive :quads + (gl:color 1.0 1.0 1.0 1.0) + (gl:tex-coord 0.0 0.0) + (gl:vertex 0.0 0.0) + (gl:tex-coord 1.0 0.0) + (gl:vertex *view-width* 0.0) + (gl:tex-coord 1.0 1.0) + (gl:vertex *view-width* *view-height*) + (gl:tex-coord 0.0 1.0) + (gl:vertex 0.0 *view-height*)) + + (gl:disable :texture-2d) + + (gl:flush) + (sdl2:gl-swap-window win))) + ))))) diff --git a/wh-engine/render/drawable.lisp b/wh-engine/render/drawable.lisp index 07a3053..596db0b 100644 --- a/wh-engine/render/drawable.lisp +++ b/wh-engine/render/drawable.lisp @@ -33,10 +33,9 @@ (cons (vec2 -0.5 -0.5) (vec2 0.5 0.5))) (defmethod draw ((this drawable-test) view) - (gl:begin :quads) (gl:color (vx4 [this colour]) (vy4 [this colour]) (vz4 [this colour]) (vw4 [this colour])) - (gl:vertex -0.5 -0.5 0.0 1.0) - (gl:vertex 0.5 -0.5 0.0 1.0) - (gl:vertex 0.5 0.5 0.0 1.0) - (gl:vertex -0.5 0.5 0.0 1.0) - (gl:end)) + (gl:with-primitives :quads + (gl:vertex -0.5 -0.5 0.0 1.0) + (gl:vertex 0.5 -0.5 0.0 1.0) + (gl:vertex 0.5 0.5 0.0 1.0) + (gl:vertex -0.5 0.5 0.0 1.0)))