Showing posts with label state. Show all posts
Showing posts with label state. Show all posts

Friday, 18 January 2013

Sweden, Ho!

I moved again! Now living in Uppsala, working in Stockholm. The past few months have been pretty exciting and we just moved to a new flat, but things are settling down. I've had a little time to poke at my personal projects, although I'd always like more.

My recent obsession has been with managing state. For many things, I seem to be tending towards a pipeline approach:

(defn foo [state x y z]
  (let [{:keys [a b c]} state]
    (assoc state 
           :a (bar x a)
           :b (baz b z y)
           :c (inc c))))

(defn quux [state]
   (-> state
       (foo "x" [] 0)
       (foo "y" [:r :s] 42)))

(defn outer-loop [state] (recur (quux state))

And so on and so forth. Passing state around explicitly as maps, writing functions that take the current state as their first argument and return that state modified with assoc, dissoc, assoc-in, update-in, merge etc.

Honestly, I'm not sure that this approach is the best way to do what I want. I have spent a little time looking at Clojure's state monad, but I suspect this is overkill (and despite being simple in practice, the whys and wherefores of all monads ever continue to befuddle me). The piped-stateblob approach translates nicely into ClojureScript with WebGL too; this is another thing I have been investigating of late.

Other advantages include very quick inspection or serialisation of a system's state (pprint to the rescue), and a single obvious point to recurse around in a thread's main loop. The stateblobs can also be useful carriers for communicating between threads.

On the other hand there's nothing particularly elegant or nice about carrying around the entire world with you wherever you go. And it works well enough that I'm starting to feel it is my hammer with which to treat every problem as a nail.

Using stateblobs everwhere: an ugly turn-based for prototype graphical RL #734.

Wednesday, 14 March 2012

Clojure-flavoured Rendering Framework: State

My rendering framework, such as it is, sits on clojars.org and does... not very much. That should change. I can't guess how useful it'd be to anyone else, but it could certainly be a lot more friendly.

With that in mind, I started taking a critical look at a few emergent antipatterns in the very core of the framework: the OpenGL wrapper.

This example, I am happy with. Mostly.

Last time, I mentioned how the rendering functions have state very explicitly threaded through them in the form of an argument. A bunch of my wrapper functions do very simple things to mutate GL state. Some of them reset it afterwards, or wrap those that don't in a friendly way. For example, matrix stuff is done something like this:

(ogl/with-matrix
  (ogl/translate 1 0 0)
  (ogl/scale 5.0)
  (ogl/triangles
    (ogl/vertex 0 0 0)
    (ogl/vertex 1 0 0)
    (ogl/vertex 1 1 0)))


Hopefully that's fairly obvious to someone familiar with OpenGL. The with-matrix wraps a glPush/PopMatrix pair of calls around all the expresions within it. Likewise triangles calls glBegin/glEnd with the appropriate primitive type. I debated not including this ancient method of drawing stuff, but it's so handy for debugging and quick tests... anyway, the point is that even though translate and scale mutate some OpenGL state, they're intended to be used within this kind of protected block. Maybe they should all have exclaimation marks, I'm a little bit hazy of when it's polite to start exclaiming when you're not mutating your arguments.

Obviously the triangles call and all the stuff therein is side effecting like crazy, but I'm not sure how much value attaches to trying to make those calls look different. If anyone has an opinion on the aesthetics of such things, please yell.

A lot of the rendering stuff behaves similarly to with-matrix. I have equivalent calls to wrap GL attribute fiddling, wireframe rendering (mostly debug friendliness), capturing the results of rendering expressions to render targets, assigning vertex buffers, and binding shaders. Some of these are could do with a refactor to make them more consistent, but they generally behave.


But then there's this...

So that's all well and good. Then I came across the with-matrix-mode macro.

Ick.

This one looks so similar to the with-matrix example, but instead of pushing and popping from the current matrix stack to allow safe manipulation of a transformation, it changes which matrix stack is currently active. OpenGL has a few of these, but the only ones that are really relevant are your "world" transform (GL_MODELVIEW) and your view/projection transform (GL_PROJECTION). The former moves vertices around, the latter manipulates your notional camera, as it were.

The reason this makes me twitch is that this doesn't in any way revert the changes you make within it. For example, here's a little function that sets up an orthographic view in place of the conventional camera-like perspective view:

(defn orthographic
  "Loads an orthographic projection matrix to the top
of the projection matrix stack."
  ([left right bottom top near far]
     (with-matrix-mode :projection
       (GL11/glLoadIdentity)
       (GL11/glOrtho left right bottom top near far)))
  ([left right bottom top]
     (orthographic left right bottom top -1.0 1.0)))


Sure, at the end of the function the matrix mode has been restored to whatever it was at the start, but there's no attempt made to preserve the state of the projection matrix. That's rather the point, in fact - it gets murdered and replaced. Everything after this will be rendered using the orthographic projection.

I suppose this function is named in a misleading fashion. Anyone assuming the state of the GL will be unchanged after executing it will be disappointed, whereas elsewhere I'm trying to leave things as I found them. On the other hand, changing matrix mode is rather rare compared to rendering stuff, you generally do it once to set up your camera and then leave it. This kind of mutate-and-forget approach makes it relatively easy to split up the rest of your rendering into small chunks, as long as you keep things in the correct order.

Elsewhere similar compromises might sensibly be made with the excuse of efficiency; there's no sense constantly setting and then resetting a bit of state if the next expression simply sets it again, or worse, if it sets it back to the same value. All told, I probably just want to find a consistent way to signal that some functions do not behave with respect to render state, whilst the default remains that all functions clean up their toys after playing with them.

Thursday, 14 August 2008

GLState Snippet

Nothing particularly big and clever, just something that seems to work quite well for slightly wrapping up OpenGL state in Scala (complete with manual and probably incomplete syntax highlighting):

trait Bound {
  def unbind: Unit
}
trait Bind {
  protected def bind: Bound
  def boundWith( p: =>Unit ) = {
    val b = bind
    p
    b.unbind
  }
  def &&&(other: Bind) = new Bind {
     class CompositeBound( a:Bound, b:Bound ) extends Bound {
       def unbind = {
        a.unbind
        b.unbind
      }
    }
    protected def bind = {
      new CompositeBound( Bind.this.bind, other.bind )
    }
  }
}

And an implementation for those wonderful glEnable/glDisable chains:

object GLUnchanged extends Bound{ def unbind = () }
object GLStateUtil {
  def glSet( s:Int, v:Boolean ) = if(v) GL11.glEnable(s) else GL11.glDisable(s)
}
case class GLEnabledBound( state:Int, value:Boolean ) extends Bound {
  def unbind = GLStateUtil.glSet(state,value)
}
case class GLSetEnabled( state:Int, value:Boolean ) extends Bind {
  protected def bind = if( GL11.glIsEnabled(state) == value ) {
    GLUnchanged
  } else {
    GLStateUtil.glSet( state, value )
    GLEnabledBound( state, !value )
  }
}


And finally a stupid example of usage (I'm refactoring a lot of the rendering code, so I don't have a real example to hand right now):

val playerState = GLSetEnabled( GL13.GL_TEXTURE_CUBE_MAP, false ) &&&
    GLSetEnabled( GL11.GL_TEXTURE_2D, false ) &&&
    GLSetEnabled( GL11.GL_LIGHTING, false )

playerState boundWith {
  playerModel.render
}

I suspect there's a better way to handle the Bound class returned such that it's not sat in the open, and the terminology may change quite a bit (bind/unbind came from various C++ implementations of similar stuff, none this nice to use). I quite like the way state changes can be composed, although it doesn't even attempt to perform any optimisation on the combined set.

I think it could also be made less verbose to good effect, and possibly a way to skip the redundant state checks would also be nice in case the state of the GL changes due to things outside the scope of these classes - especially for debugging.

At some point I think I'll combine all the resources into implementations of this class.

Anyway, back to playing with code...