diff --git a/Samples/SimpleRead/main.cpp b/Samples/SimpleRead/main.cpp
index 163d7e3..8fce467 100644
--- a/Samples/SimpleRead/main.cpp
+++ b/Samples/SimpleRead/main.cpp
@@ -21,6 +21,8 @@
 #include <stdio.h>
 #include <OpenNI.h>
 
+#include <sys/mman.h>
+
 #include "OniSampleUtilities.h"
 
 #define SAMPLE_READ_WAIT_TIMEOUT 2000 //2000ms
@@ -65,6 +67,22 @@ int main()
 
 	VideoFrameRef frame;
 
+	int fbw=720, fbh=1280, fbd=4, fbbufs=2;
+	const char *fbdev = "/dev/graphics/fb0";
+	int fbfd = open(fbdev, O_RDWR, 0);
+	if ( fbfd < 0 ) {
+	  // Fallback for desktop PC
+	  fbdev = "/dev/fb0";
+	  fbfd = open(fbdev, O_RDWR, 0);
+	  fbw=1280; fbh=1024; fbbufs=1;
+	}
+	if ( fbfd < 0 ) { perror(fbdev); return 5; }
+	unsigned long *fb = (unsigned long*)
+	  mmap(NULL, fbw*fbh*fbd*fbbufs, PROT_WRITE, MAP_SHARED, fbfd, 0);
+	if ( fb == MAP_FAILED ) { perror("mmap"); return 6; }
+	memset(fb, 0, fbw*fbh*fbd*fbbufs);
+	int curbuf = 0;
+
 	while (!wasKeyboardHit())
 	{
 		int changedStreamDummy;
@@ -94,6 +112,61 @@ int main()
 		int middleIndex = (frame.getHeight()+1)*frame.getWidth()/2;
 
 		printf("[%08llu] %8d\n", (long long)frame.getTimestamp(), pDepth[middleIndex]);
+
+		//// Source geometry (depth sensor)
+		int fw=frame.getWidth(), fh=frame.getHeight();
+		// ASUS Xtion: 58° HFOV
+		float srck = fw/2 / 0.554;  // tan(58/2*3.1416/180)
+		float srcipd = 65.0;  // IPD of virtual eyes
+
+		//// Destination geometry (side-by-side stereo in framebuffer)
+		// Galaxy S3: 106 mm
+		float dstpixsize = 106.0 / 1280;
+		float dstfl = 65;  // Focal length of VR-spektiv XL
+		float dstk = dstfl / dstpixsize;
+		float dstipd = 60;  // IPD of user (a bit less for comfort)
+		int sep = dstipd / dstpixsize;
+
+		//// Display point cloud in stereo
+
+		// Fill both buffers. FBIOPUT_VSCREENINFO is broken.
+		unsigned long *fbpix = fb + curbuf*fbw*fbh;
+		curbuf = (curbuf+1) % fbbufs;
+
+		// Cleanup repaints by Android
+		if ( *fbpix ) memset(fb, 0, fbw*fbh*fbd*fbbufs);
+
+		for ( int i=0; i<fh; ++i ) {
+		  int u = fbw/2 - (i-fh/2)/srck*dstk;
+		  if ( u<0 || u>=fbw ) continue;
+		  { // Clear line
+		    unsigned long *p = fbpix + u;
+		    for ( int j=fbh; --j>=0; p+=fbw ) *p = 0;
+		  }
+		  DepthPixel *pd = pDepth + i*fw;
+		  for ( int j=0; j<fw; j++,pd++ ) {
+		    DepthPixel d = *pd;
+		    if ( ! d ) continue;
+		    float z = d;
+		    float x = (fw/2-j) / srck * z;
+		    int vl = fbh/2-sep/2 + (x+srcipd/2)/z*dstk;
+		    int vr = fbh/2+sep/2 + (x-srcipd/2)/z*dstk;
+		    unsigned long grey = (4095-d) / 16;
+		    unsigned long pix = grey | (grey<<8) | (grey<<16);
+#define offset(x, y) ((y)*fbw + (x))
+		    if ( vl>=0     && vl<fbh/2 ) fbpix[offset(u,vl)] = pix;
+		    if ( vr>=fbh/2 && vr<fbh   ) fbpix[offset(u,vr)] = pix;
+		  }
+		}
+		// Mark optical centers
+		unsigned long crosscolor = 0x00ff0000;
+		for ( int i=-5; i<5; ++i ) {
+		  fbpix[offset(fbw/2  , fbh/2-sep/2+i)] = crosscolor;
+		  fbpix[offset(fbw/2+i, fbh/2-sep/2  )] = crosscolor;
+		  fbpix[offset(fbw/2  , fbh/2+sep/2+i)] = crosscolor;
+		  fbpix[offset(fbw/2+i, fbh/2+sep/2  )] = crosscolor;
+		}
+#undef offset
 	}
 
 	depth.stop();
