135 lines
4.0 KiB
Common Lisp
135 lines
4.0 KiB
Common Lisp
;;;; wh-engine/render/render-system.lisp
|
|
;;;; render system main code
|
|
(defpackage wh-engine/render
|
|
(:nicknames whe/render)
|
|
(:use common-lisp 3d-vectors 3d-matrices wh-engine)
|
|
(:import-from sb-ext
|
|
weak-pointer weak-pointer-p make-weak-pointer weak-pointer-value)
|
|
(:import-from objective-lisp O!)
|
|
(:export
|
|
;; render/drawable.lisp
|
|
drawable
|
|
; virtual properties
|
|
culling-box
|
|
; methods
|
|
draw
|
|
|
|
drawable-test
|
|
|
|
;; render/view.lisp
|
|
view
|
|
; properties
|
|
render-pass render-mask cull-p
|
|
; virtual properties
|
|
view-matrix world-matrix
|
|
; methods
|
|
view-point render-view render-drawable
|
|
|
|
*view-width* *view-height* *view-ppu* *pixel-scale*
|
|
|
|
;; render/render-target.lisp
|
|
render-target
|
|
; properties
|
|
width height framebuffer renderbuffer render-texture
|
|
; methods
|
|
bind-for-rendering
|
|
))
|
|
|
|
(in-package wh-engine/render)
|
|
|
|
(defun opengl-matrix (matrix)
|
|
(declare (type mat3 matrix))
|
|
(with-fast-matref (m matrix 3)
|
|
(make-array '(16) :initial-contents
|
|
`(,(m 0 0) ,(m 0 1) 0.0 ,(m 0 2)
|
|
,(m 1 0) ,(m 1 1) 0.0 ,(m 1 2)
|
|
0.0 0.0 1.0 0.0
|
|
,(m 2 0) ,(m 2 1) 0.0 ,(m 2 2))
|
|
)))
|
|
|
|
(defvar *view-width* 384
|
|
"View-space width in pixels.")
|
|
(defvar *view-height* 256
|
|
"View-space height in pixels.")
|
|
(defvar *view-ppu* 64
|
|
"Pixels in view-space per unit in world-space.")
|
|
|
|
(defvar *pixel-scale* 2
|
|
"Scaling factor for rendered pixels.")
|
|
|
|
(defvar *world-drawables* ()
|
|
"List of all known drawables.")
|
|
(defvar *world-views* ()
|
|
"List of all known views.")
|
|
|
|
(defun sort-world-views ()
|
|
"Re-sort the *world-views* list by render pass."
|
|
(sort *world-views* #'< :key (lambda (v) (o! (deref-pointer v) render-pass))))
|
|
|
|
(let (render-target win-width win-height)
|
|
(defun render-system-init ()
|
|
(setf win-width (* *view-width* *pixel-scale*)
|
|
win-height (* *view-height* *pixel-scale*)
|
|
render-target (make-instance 'render-target :width *view-width* :height *view-height*))
|
|
|
|
;; change render target mode
|
|
(gl:bind-texture :texture-2d (o! render-target render-texture))
|
|
(gl:tex-parameter :texture-2d :texture-min-filter :nearest)
|
|
(gl:tex-parameter :texture-2d :texture-mag-filter :nearest)
|
|
(gl:bind-texture :texture-2d 0)
|
|
|
|
;; 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 :depth-buffer :stencil-buffer))
|
|
|
|
(defun render-system-update ()
|
|
;; draw to render texture
|
|
(o! render-target (bind-for-rendering))
|
|
(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 (o! view active-p) (o! view actor tree-active-p))
|
|
do (progn
|
|
(unless (eql (o! view render-pass) render-pass)
|
|
(setf render-pass (o! view render-pass))
|
|
(gl:clear :depth-buffer))
|
|
(o! view (render-view *world-drawables*)))))
|
|
(gl:flush)
|
|
|
|
;; 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 (o! render-target render-texture))
|
|
(gl:matrix-mode :modelview)
|
|
(gl:load-identity)
|
|
|
|
(gl:with-primitives :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)))
|
|
|
|
(register-system :wh-engine/render 'render-system-init 'render-system-update nil)
|
|
|
|
(install-systems :wh-engine/render)
|