Add macro for guarenteeing the gl state within a scope
something along the lines of
(with-fixed-state (..options..)
..body..)
To start with just reset all state we cache to something sane, then expose a means to pick what is set. We should then look at all state we touch and add those too. The reason for splitting the task is the first part is easier and will inform us of the api.
as a concrete example here is the state touched by nanovg
;; glUseProgram(prog)
;; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
;; glEnable(GL_CULL_FACE)
;; glCullFace(GL_BACK)
;; glFrontFace(GL_CCW)
;; glEnable(GL_BLEND)
;; glDisable(GL_DEPTH_TEST)
;; glDisable(GL_SCISSOR_TEST)
;; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
;; glStencilMask(0xffffffff)
;; glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
;; glStencilFunc(GL_ALWAYS, 0, 0xffffffff)
;; glActiveTexture(GL_TEXTURE0)
;; glBindBuffer(GL_UNIFORM_BUFFER, buf)
;; glBindVertexArray(arr)
;; glBindBuffer(GL_ARRAY_BUFFER, buf)
;; glBindTexture(GL_TEXTURE_2D, tex)
;; glUniformBlockBinding(... , GLNVG_FRAG_BINDING)
the reason this became a ticket as I started looking at using with-setf* and we dont expose enough for that to be viable.
the garbage below is just for my own reference.
(uiop:define-package moo (:use :cl :cepl :with-setf))
(in-package moo)
(defun foo ()
(with-cepl-context ()
(cepl.pipelines::use-program (cepl-context) 0)
(with-setf* ((cull-face) :back
(front-face) :ccw
(depth-test-function) nil
(cepl.scissor:scissor-viewport) nil
(color-masks) (make-array 4 :element-type 'boolean
:initial-element t)
(stencil-mask :front-and-back) #xffffffff
(gpu-buffer-bound (cepl-context) :))
;; call some other code safely
)))
Progress :)
CONTEXT>
(progn
(print (clear-color))
(with-context-state-restored (:clear-color t)
(gl:clear-color 0f0 5f0 10f0 15f0))
(print (clear-color)))
#(1.0 2.0 3.0 4.0)
#(1.0 2.0 3.0 4.0)
#(1.0 2.0 3.0 4.0)
More
(in-package :cepl)
;; Supported
;;
;; glUseProgram(prog)
;; glEnable(GL_CULL_FACE)
;; glCullFace(GL_BACK)
;; glFrontFace(GL_CCW)
;; glDisable(GL_DEPTH_TEST)
;; glStencilMask(0xffffffff)
;; glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)
;; glStencilFunc(GL_ALWAYS, 0, 0xffffffff)
;; glBindVertexArray(arr)
;; glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
;; glActiveTexture(GL_TEXTURE0)
;; glBindTexture(GL_TEXTURE_2D, tex)
;; glBindBuffer(GL_ARRAY_BUFFER, buf)
;; glDisable(GL_SCISSOR_TEST)
;; WIP
;;
;; glEnable(GL_BLEND)
;; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
;; glBindBuffer(GL_UNIFORM_BUFFER, buf)
;; glUniformBlockBinding(... , GLNVG_FRAG_BINDING)
(defun foo ()
(with-context-state-restored (:program t
:stencil t
:vao t
:cull-face t
:front-face t
:depth-test-function t
:color-mask-indices (0)
:tex-unit-ids (0)
:buffer-targets (:array-buffer)
:scissor-viewport-indices (0))
(print "call some gl code")))
so it's just ubo & blending left. Ubo is tricky because of ranges (I guess we have to start caching them) and blending because it's usually applied to the fbos themselves.. but not always.
@borodust Merged v1 of this into master. We can try this out and see what breaks