render to texture

This commit is contained in:
~keith 2022-02-17 19:13:45 +00:00
parent 75c03c573f
commit 402cf13d27
Signed by: keith
GPG Key ID: 5BEBEEAB2C73D520
3 changed files with 102 additions and 48 deletions

3
.gitignore vendored
View File

@ -1,4 +1,7 @@
# cloned wiki repo
/doc/wiki
# KDE :')
.directory

View File

@ -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)))
)))))

View File

@ -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)))