# HG changeset patch # User Robert McIntyre # Date 1327036126 25200 # Node ID a980462ebe76dfc001a7c7cb1e30323b9bc77cd8 # Parent 128fa71ee188801c63fae4b2ddd378fbd118159a more lazy/functional version of eyes diff -r 128fa71ee188 -r a980462ebe76 org/eyes.org --- a/org/eyes.org Thu Jan 19 11:29:46 2012 -0700 +++ b/org/eyes.org Thu Jan 19 22:08:46 2012 -0700 @@ -20,21 +20,23 @@ {:author "Robert McIntyre"} (:use cortex.world) (:import com.jme3.post.SceneProcessor) - (:import (com.jme3.util BufferUtils)) + (:import (com.jme3.util BufferUtils Screenshots)) (:import java.nio.ByteBuffer) (:import java.awt.image.BufferedImage) (:import com.jme3.renderer.ViewPort) - (:import com.jme3.math.ColorRGBA)) + (:import com.jme3.math.ColorRGBA) + (:import com.jme3.renderer.Renderer)) -(defn scene-processor + +(defn vision-pipeline "Create a SceneProcessor object which wraps a vision processing - continuation function. The SceneProcessor will take care of - converting the rendered frame to a BufferedImage and passing that - BufferedImage to the continuation. The continuation should be a - function that takes a ByteBuffer which represents the image." + continuation function. The continuation is a function that takes + [#^Renderer r #^FrameBuffer fb #^ByteBuffer b #^BufferedImage bi], + each of which has already been appropiately sized." [continuation] (let [byte-buffer (atom nil) - renderer (atom nil)] + renderer (atom nil) + image (atom nil)] (proxy [SceneProcessor] [] (initialize [renderManager viewPort] @@ -44,7 +46,10 @@ (reset! renderer (.getRenderer renderManager)) (reset! byte-buffer (BufferUtils/createByteBuffer - (* width height 4))))) + (* width height 4))) + (reset! image (BufferedImage. + width height + BufferedImage/TYPE_4BYTE_ABGR)))) (isInitialized [] (not (nil? @byte-buffer))) (reshape [_ _ _]) (preFrame [_]) @@ -52,16 +57,27 @@ (postFrame [#^FrameBuffer fb] (.clear @byte-buffer) - ;;(.readFrameBuffer @renderer fb @byte-buffer) - (continuation @byte-buffer)) + (continuation @renderer fb @byte-buffer @image)) (cleanup [])))) -(defn buffer->image! [width height] - (let [image (BufferedImage. width height - BufferedImage/TYPE_4BYTE_ABGR)] - (fn [byte-buffer] - (Screenshots/convertScreenShot byte-buffer image) - image))) +(defn frameBuffer->byteBuffer! + "Transfer the data in the graphics card (Renderer, FrameBuffer) to + the CPU (ByteBuffer)." + [#^Renderer r #^FrameBuffer fb #^ByteBuffer bb] + (.readFrameBuffer r fb bb) bb) + +(defn byteBuffer->bufferedImage! + "Convert the C-style BGRA image data in the ByteBuffer bb to the AWT + style ABGR image data and place it in BufferedImage bi." + [#^ByteBuffer bb #^BufferedImage bi] + (Screenshots/convertScreenShot bb bi) bi) + +(defn BufferedImage! + "Continuation which will grab the buffered image from the materials + provided by (vision-pipeline)." + [#^Renderer r #^FrameBuffer fb #^ByteBuffer bb #^BufferedImage bi] + (byteBuffer->bufferedImage! + (frameBuffer->byteBuffer! r fb bb) bi)) (defn add-eye "Add an eye to the world, calling continuation on every frame @@ -74,7 +90,7 @@ (doto viewport (.setClearFlags true true true) (.setBackgroundColor ColorRGBA/Black) - (.addProcessor (scene-processor continuation)) + (.addProcessor (vision-pipeline continuation)) (.attachScene (.getRootNode world))))) #+end_src @@ -101,8 +117,7 @@ (:import javax.swing.JFrame) (:import com.jme3.math.ColorRGBA) (:import com.jme3.scene.Node) - (:import com.jme3.math.Vector3f) - (:import (com.jme3.util Screenshots))) + (:import com.jme3.math.Vector3f)) (defn view-image "Initailizes a JPanel on which you may draw a BufferedImage. @@ -152,18 +167,15 @@ width (.getWidth cam) height (.getHeight cam)] (add-eye world cam - no-op - ;;(comp (view-image) (buffer->image! width height)) + ;;no-op + (comp (view-image) BufferedImage!) ) (add-eye world (doto (.clone cam) (.setLocation (Vector3f. -10 0 0)) (.lookAt Vector3f/ZERO Vector3f/UNIT_Y)) - no-op - ;;(comp (view-image) (buffer->image! width height)) - ) - - + ;;no-op + (comp (view-image) BufferedImage!)) ;; This is here to restore the main view ;; after the other views have completed processing (add-eye world (.getCamera world) no-op)))