anchor.diff:  ;;; NBody Demo
   ;;;
   
  -(defun unlines (&rest string-list)
  -  "Concatenates a list of strings and puts newlines between the elements."
  -  (format nil "~{~A~%~}" string-list))
  -
  -(defparameter +vertex-shader+
  -  (unlines "void main()                                                            "
  -           "{                                                                      "
  -           "    float pointSize = 500.0 * gl_Point.size;                           "
  -           "    vec4 vert = gl_Vertex;                                             "
  -           "    vert.w = 1.0;                                                      "
  -           "    vec3 pos_eye = vec3 (gl_ModelViewMatrix * vert);                   "
  -           "    gl_PointSize = max(1.0, pointSize / (1.0 - pos_eye.z));            "
  -           "    gl_TexCoord[0] = gl_MultiTexCoord0;                                "
  -           ;"    gl_TexCoord[1] = gl_MultiTexCoord1;                                "
  -           "    gl_Position = ftransform();                                        "
  -           "    gl_FrontColor = gl_Color;                                          "
  -           "    gl_FrontSecondaryColor = gl_SecondaryColor;                        "
  -           "}                                                                      "))
  -
  -(defparameter +pixel-shader+
  -  (unlines "uniform sampler2D splatTexture;                                        "
  -           "void main()                                                            "
  -           "{                                                                      "
  -           "    vec4 color2 = gl_SecondaryColor;                                   "
  -           "    vec4 color = (0.6 + 0.4 * gl_Color) * texture2D(splatTexture, gl_TexCoord[0].st);"
  -           "    gl_FragColor =                                                     "
  -           "         color * color2;" ;mix(vec4(0.1, 0.0, 0.0, color.w), color2, color.w);"
  -           "}                                                                      "))
  -
  -(defstruct (nbody-demo :conc-name)
  +(defstruct (nbody-demo (:constructor %make-nbody-demo))
     system renderer)
   
  -(defmacro with-nbody-demo ((var num-bodies &key (gpu t) (interop nil)) &body body)
  -  `(let (,var)
  -     (unwind-protect
  -        (progn
  -          (setf ,var (init-nbody-demo ,num-bodies :gpu ,gpu :interop ,interop))
  -          ,@body)
  +(defun init-nbody-demo (num-bodies &key (gpu t) (interop nil))
  +  (let ((system (init-body-system num-bodies :gpu gpu :interop interop))
  +        (renderer (init-particle-renderer)))
  +    ;; Reset body system
  +    (reset-body-system system)
  +    ;; Synchronize memory form host to device
  +    (when (body-system-gpu system)
  +      (sync-body-system system :host-to-device))
  +    ;; Make NBody demo
  +    (%make-nbody-demo :system system :renderer renderer)))
  +
  +(defun release-nbody-demo (demo)
  +  (release-particle-renderer (nbody-demo-renderer demo))
  +  (release-nbody-system (nbody-demo-system demo)))
  +
  +(defmacro with-nbody-demo ((var num-bodies &key (gpu t) (interop nil))
  +                           &body body)
  +  `(let ((,var (init-nbody-demo ,num-bodies :gpu ,gpu :interop ,interop)))
  +     (unwind-protect (progn ,@body)
          (release-nbody-demo ,var))))
   
  -(defun init-nbody-demo (num-bodies &key (gpu t) (interop nil))
  -  (let ((demo (make-nbody-demo)))
  -    (setf (system   demo) (init-body-system num-bodies :gpu gpu :interop interop)
  -          (renderer demo) (init-particle-renderer))
  -    demo))
  -
  -(defun release-nbody-demo (demo)
  -  (let ((renderer (renderer demo))
  -        (system   (system demo)))
  -    (release-particle-renderer renderer)
  -    (release-body-system system)))
  -
   (defun update-nbody-demo (demo)
  -  (update-body-system (system demo)))
  +  (update-body-system (nbody-demo-system demo)))
   
   (defun display-nbody-demo (demo)
  -  (let ((renderer   (renderer demo))
  -        (system     (system   demo)))
  -    (let ((pos        (old-pos system))
  -          (num-bodies (num-bodies system)))
  +  (let ((system (nbody-demo-system demo))
  +        (renderer (nbody-demo-renderer demo)))
  +    (let ((pos (body-system-old-pos system))
  +          (num-bodies (body-system-num-bodies system)))
         (display-particle-renderer renderer pos num-bodies :particle-sprites))))
   
   (defun nbody-demo-num-bodies (demo)
  -  (num-bodies (system demo)))
  +  (body-system-num-bodies (nbody-demo-system demo)))
   
   
   ;;;
   ;;; Body System
   ;;;
   
  -(defstruct (body-system :conc-name)
  +(defstruct (body-system (:constructor %make-body-system))
     ;; CUDA device ID
  -  (dev-id         0     :read-only t)
  -  ;; memory blocks
  -  new-pos old-pos vel
  -  ;; simulation parameters
  -  (num-bodies     0)
  +  (dev-id :dev-id :read-only t)
  +  ;; Memory blocks
  +  (new-pos :new-pos)                    ; Not read-only to flip
  +  (old-pos :old-pos)
  +  (vel :vel :read-only t)
  +  ;; Flags
  +  (gpu :gpu :read-only t)
  +  (interop :interop :read-only t)
  +  ;; Number of bodies
  +  (num-bodies :num-bodies :read-only t)
  +  ;; Simulation parameters
     (delta-time     0.016 :read-only t)
     (damping        1.0   :read-only t)
     (p              256   :read-only t)
  
positive.code:         (window (make-instance 'nbody-window)))
      (glut:display-window window) ; GLUT window must be created before initializing nbody-demo
      (with-nbody-demo (demo 2048 :gpu gpu :interop interop)
        (with-frame-rate-counter (counter)
          (setf (slot-value window 'nbody-demo) demo
                (slot-value window 'counter)    counter)
          (glut:main-loop)))))
  
  
  (defun not-implemented ()
    (error "not implemented."))
  
negative.code:     (gl:link-program program)))
  
  (defun create-texture (renderer resolution)
    (symbol-macrolet ((texture-data (particle-renderer-texture-data renderer))
                      (texture (particle-renderer-texture renderer)))
      ;; prepare texture data
      (setf texture-data (cffi:foreign-alloc :unsigned-char
                                             :count (* 4 resolution
                                                         resolution)))
      (create-gaussian-map texture-data resolution)
      ;; generate texture
      (setf texture (first (gl:gen-textures 1)))
  