-
Notifications
You must be signed in to change notification settings - Fork 16
Description
I was profiling my game and found out that the method glGetInteger in core/render is taking 80% cpu time. My understanding is that this method is taking data from GPU to CPU which is seemingly a costly operation. I try modifying render for my game to not do the glUseProgram and glBinds of the previous state like this
(defn render
"Renders the provided entity."
[game entity]
(let [{:keys [program vao uniforms indices viewport clear index-buffer]} entity]
;; not calling glGetInteger because it will not be used
(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)))))))
;; not doing (gl game useProgram previous-program) etc...and my game still works the same but with better performance. Currently I am going with a locally modified version of play-cljc that includes above, but is there any reason that I am not aware of regarding the need to returning the state to the previous program etc?
(extra note: I am also currently learning OpenGL programming by using the play-cljc/gl macro and reading internals so the goal of opening this issue is also largely for learning)