(defpackage #:workbench (:use #:cl+trial) (:shadow #:launch) (:local-nicknames) (:export #:workbench #:launch)) (in-package #:workbench) (defclass workbench (main) () (:default-initargs :clear-color (vec 0.25 0.3 0.35 0))) (defun launch () (trial:launch 'workbench)) (define-pool workbench) (define-asset (workbench cat) image #p"cat.png" :wrapping :repeat) (define-asset (workbench cube) mesh (make-cube 15)) (define-asset (workbench grid) mesh (make-line-grid 10 100 100)) (define-shader-entity player (vertex-entity textured-entity located-entity listener) ((name :initform 'player) (texture :initform (// 'workbench 'cat)) (vertex-array :initform (// 'workbench 'cube)))) (define-handler (player tick) (dt) (when (retained :w) (incf (vz (location player)) (* dt +50))) (when (retained :a) (incf (vx (location player)) (* dt +50))) (when (retained :s) (incf (vz (location player)) (* dt -50))) (when (retained :d) (incf (vx (location player)) (* dt -50)))) (define-gl-struct bg (parallax :vec2 :accessor parallax) (scaling :vec2 :accessor scaling) (offset :vec2 :accessor offset)) (define-asset (workbench bg) uniform-block 'bg) (define-shader-entity parallax-background (renderable) ((name :initform 'parallax-background) (texture :initarg :texture :initform (error "TEXTURE REQUIRED") :accessor texture)) (:buffers (workbench bg))) (defmethod render ((parallax-background parallax-background) (program shader-program)) (with-buffer-tx (bg (// 'workbench 'bg)) (setf (parallax bg) (vec 2 2)) (setf (scaling bg) (vec 1 1)) (setf (offset bg) (vec 0 0))) (setf (uniform program "view_size") (vec2 (max 1 (width *context*)) (max 1 (height *context*)))) (setf (uniform program "view_matrix") (minv *view-matrix*)) (gl:active-texture :texture0) (gl:bind-texture :texture-2d (gl-name (texture parallax-background))) (gl:bind-vertex-array (gl-name (// 'trial:trial 'trial::empty-vertex-array))) (gl:draw-arrays :triangle-strip 0 4) (gl:bind-vertex-array 0)) (defmethod stage :after ((entity parallax-background) (area staging-area)) (stage (// 'trial:trial 'trial::empty-vertex-array) area) (stage (texture entity) area)) (define-class-shader (parallax-background :vertex-shader) (gl-source (asset 'workbench 'bg)) "const vec2 quad_vertices[4] = vec2[4](vec2(-1.0, -1.0), vec2(1.0, -1.0), vec2(-1.0, 1.0), vec2(1.0, 1.0)); uniform sampler2D tex_image; uniform mat4 view_matrix; uniform vec2 view_size; out vec2 map_coord; void main(){ gl_Position = vec4(quad_vertices[gl_VertexID], 0, 1); vec2 vertex_uv = (quad_vertices[gl_VertexID]+1)*0.5; vec2 tex_size = textureSize(tex_image, 0).xy; map_coord = (view_matrix * vec4(vertex_uv*view_size*bg.parallax, 0, 1)).xy; map_coord += tex_size/2 + bg.offset; map_coord /= bg.parallax * bg.scaling * tex_size; }") (define-class-shader (parallax-background :fragment-shader) "uniform sampler2D tex_image; in vec2 map_coord; out vec4 color; void main(){ color = texture(tex_image, map_coord); }") (progn (defmethod setup-scene ((workbench workbench) scene) (enter (make-instance 'trial::fps-counter) scene) (enter (make-instance 'parallax-background :texture (// 'workbench 'cat)) scene) (enter (make-instance 'vertex-entity :vertex-array (// 'workbench 'grid)) scene) (enter (make-instance 'player) scene) (enter (make-instance 'following-camera :target (unit 'player scene) :location (vec 0 100 -100)) scene) (enter (make-instance 'render-pass) scene)) (maybe-reload-scene))