91 lines
4.4 KiB
Common Lisp
91 lines
4.4 KiB
Common Lisp
;;;; wh-engine/render/render-target.lisp
|
|
;;;; Render targets - structures that store a GL framebuffer, renderbuffer, and texture.
|
|
(in-package wh-engine/render)
|
|
|
|
(defclass render-target ()
|
|
((width :documentation "The width in pixels of this render target."
|
|
:reader width
|
|
:type fixnum
|
|
:initarg :width
|
|
:initform *view-width*)
|
|
(height :documentation "The height in pixels of this render target."
|
|
:reader height
|
|
:type fixnum
|
|
:initarg :height
|
|
:initform *view-height*)
|
|
(depth-texture-p :documentation "Whether or not to render depth (and stencil) information to a texture."
|
|
:reader depth-texture-p
|
|
:type boolean
|
|
:initarg :depth-texture-p
|
|
:initform nil)
|
|
(framebuffer :documentation "The GL framebuffer associated with this render target."
|
|
:reader framebuffer
|
|
:type (or fixnum null)
|
|
:initform nil)
|
|
(renderbuffer :documentation "The GL renderbuffer associated with this render target."
|
|
:reader renderbuffer
|
|
:type (or fixnum null)
|
|
:initform nil)
|
|
(depth-texture :documentation "The GL texture containing the depth and stencil output for this render target."
|
|
:reader depth-texture
|
|
:type (or fixnum null)
|
|
:initform nil)
|
|
(render-texture :documentation "The GL render texture containing the output of this render target."
|
|
:reader render-texture
|
|
:type (or fixnum null)
|
|
:initform nil))
|
|
(:documentation "Stores a GL framebuffer, and its associated renderbuffer and output texture."))
|
|
|
|
(defmethod make-load-form ((this render-target) &optional environment)
|
|
(declare (ignore environment))
|
|
`(make-instance ',(class-name (class-of this))
|
|
:width ,(o! this width) :height ,(o! this height)
|
|
:depth-texture-p ,(o! this depth-texture-p)))
|
|
|
|
(defmethod initialize-instance :after ((this render-target) &key)
|
|
;; create render texture
|
|
(setf (o! this :slot render-texture) (gl:gen-texture))
|
|
(gl:bind-texture :texture-2d (o! this :slot render-texture))
|
|
(gl:tex-image-2d :texture-2d 0 :rgba
|
|
(o! this :slot width) (o! this :slot 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 :linear)
|
|
(gl:tex-parameter :texture-2d :texture-mag-filter :linear)
|
|
(gl:bind-texture :texture-2d 0)
|
|
|
|
(if (o! this depth-texture-p)
|
|
(progn
|
|
;; create depth texture
|
|
(setf (o! this :slot depth-texture) (gl:gen-texture))
|
|
(gl:bind-texture :texture-2d (o! this :slot depth-texture))
|
|
(gl:tex-image-2d :texture-2d 0 :depth24-stencil8
|
|
(o! this :slot width) (o! this :slot height)
|
|
0 :depth-stencil :unsigned-int-24-8 (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 :linear)
|
|
(gl:tex-parameter :texture-2d :texture-mag-filter :linear)
|
|
(gl:bind-texture :texture-2d 0))
|
|
(progn
|
|
;; create renderbuffer
|
|
(setf (o! this :slot renderbuffer) (gl:gen-renderbuffer))
|
|
(gl:bind-renderbuffer :renderbuffer (o! this :slot renderbuffer))
|
|
(gl:renderbuffer-storage :renderbuffer :depth24-stencil8 (o! this :slot width) (o! this :slot height))
|
|
(gl:bind-renderbuffer :renderbuffer 0)))
|
|
|
|
;; create framebuffer
|
|
(setf (o! this :slot framebuffer) (gl:gen-framebuffer))
|
|
(gl:bind-framebuffer :framebuffer (o! this :slot framebuffer))
|
|
(gl:framebuffer-texture-2d :framebuffer :color-attachment0 :texture-2d (o! this :slot render-texture) 0)
|
|
(if (o! this depth-texture-p)
|
|
(gl:framebuffer-texture-2d :framebuffer :depth-stencil-attachment :texture-2d (o! this :slot depth-texture) 0)
|
|
(gl:framebuffer-renderbuffer :framebuffer :depth-stencil-attachment :renderbuffer (o! this :slot renderbuffer)))
|
|
|
|
(gl:bind-framebuffer :framebuffer 0))
|
|
|
|
(defmethod bind-for-rendering ((this render-target))
|
|
(gl:bind-framebuffer :framebuffer (o! this framebuffer))
|
|
(gl:viewport 0 0 (o! this width) (o! this height)))
|