With-pushed-matrix* does. What are the issues with making with-pushed-matrix behave sanely w.r.t. non-local exits? I assume that this is a deep issue since the fix is so simple and has already been implemented in With-pushed-matrix*?
As a test case:
(dotimes (i 33) (ignore-errors (with-pushed-matrix (error "Uh-oh"))))
might break conforming OpenGL programs. I'm not an OpenGL guru, am I missing something?
I think the reason I added with-pushed-matrix* instead of adding unwind-protect to with-pushed-matrix was due to the possibility of the current matrix changing before the non-local exit, in which case we pop the wrong matrix, and leave something on the original matrix stack anyway.
Not sure if that is actually enough of a concern to avoid handling the normal case better though...
Is it ever ok (i.e. not an eventual matrix stack overflow) to not pop a matrix that has been pushed? Perhaps I misunderstand push and pop matrix. My understanding:
(init_matrix) ;; matrix stack (), current matrix is A
(push-matrix) ;; matrix stack (A) and current matrix is A
;; Do anything other than push or pop. Matrix stack is still (A), current matrix is B where in general B /= A
(push-matrix) ;; matrix stack (B A) and current matrix is B
;; Do anything other than push or pop. Matrix stack is still (B A), current matrix is C /= B /= A
(pop-matrix) ;; matrix stack (A), current matrix B
;; Do anything other than push or pop. Matrix stack is still (A), current matrix is D /= A
(pop-matrix) ;; matrix stack is () and current matrix is A
This is how OpenGL works, right? If there is ever an unbalanced push-matrix, and it is in code that is called often, there will eventually be a stack overflow.
Right, push without pop is bad, but we can't (efficiently) be sure we are popping the right matrix stack, which is why with-pushed-matrix* requires explicitly specifying which matrix stack to push/pop.
(gl:with-pushed-matrix ;;; pushes the current matrix stack, 'modelview' in this case
(gl:matrix-mode :modelview) ;; would set 'current' matrix mode back, but error skips that
) ;;; unwind-protect would pop current matrix stack, 'projection' in this case
In this case, even with unwind-protect we still eventually get an overflow on the modelview stack, and we probably get an underflow on the projection matrix stack (or at least the wrong projection matrix for following code)
Oh, right, good point. In light of this, I change my complaint to: "Really just seems like with-pushed-matrix* is the right default tool for the job, maybe it should be the unstarred version."
I suppose you could do something efficient by having gl:matrix-mode set a special variable that holds what matrix is active, but it is a bit messy. Or you could limit the damage by promoting usage of a gl:with-matrix-mode macro.