(defn
render
"Renders the provided entity."
[game entity]
(let
[{:keys
[program
vao
uniforms
indices
viewport
clear
render-to-texture
index-buffer]}
entity
previous-program
(gl
game
#?(:clj getInteger :cljs getParameter)
(gl game CURRENT_PROGRAM))
previous-vao
(gl
game
#?(:clj getInteger :cljs getParameter)
(gl game VERTEX_ARRAY_BINDING))
previous-index-buffer
(gl
game
#?(:clj getInteger :cljs getParameter)
(gl game ELEMENT_ARRAY_BUFFER_BINDING))]
(some->> program (gl game useProgram))
(some->> vao (gl game bindVertexArray))
(some->>
index-buffer
(gl game bindBuffer (gl game ELEMENT_ARRAY_BUFFER)))
(when
uniforms
(when-not
program
(throw (ex-info "Only compiled entities can be rendered" {})))
(let
[{:keys [textures]}
(reduce (partial call-uniform game) entity uniforms)]
(doseq
[{:keys [unit location]} (vals textures)]
(gl game uniform1i location unit))
(some->>
entity
:render-to-texture
(render->texture game textures))))
(some->> viewport (render-viewport game))
(some->> clear (render-clear game))
(let
[{:keys [draw-count instance-count]}
(set-buffers game entity program)]
(when
draw-count
(if-let
[{:keys [type]} indices]
(gl game drawElements (gl game TRIANGLES) draw-count type 0)
(if
instance-count
(gl
game
drawArraysInstanced
(gl game TRIANGLES)
0
draw-count
instance-count)
(gl game drawArrays (gl game TRIANGLES) 0 draw-count)))))
(gl game useProgram previous-program)
(gl game bindVertexArray previous-vao)
(gl
game
bindBuffer
(gl game ELEMENT_ARRAY_BUFFER)
previous-index-buffer)))