Copyright | (c) 2015 Brian W Bush |
---|---|
License | MIT |
Maintainer | Brian W Bush <consult@brianwbush.info> |
Stability | Stable |
Portability | Portable |
Safe Haskell | None |
Language | Haskell2010 |
Functions for using DLP stereo with 3-D Ready Sync projectors and OpenGL. This uses the specification <http://lists.gnu.org/archive/html/bino-list/2013-03/pdfz6rW7jUrgI.pdf> and is based on the implementation for the stereo movie viewer Bino <http://git.savannah.gnu.org/cgit/bino.git/tree/src/video_output.cpp?id=bino-1.6.1#n1389>. In particular, note that this technique does not require a graphics card that supports GL_STEREO
.
Below is a skeletal example illustrating the use of frame-sequential DLP. See Graphics.Rendering.DLP.Callbacks for a simpler example that uses callbacks.
main :: IO () main = do _ <- getArgsAndInitialize initialDisplayMode $= [WithDepthBuffer, DoubleBuffered] _ <- createWindow "DLP Stereo OpenGL Example" depthFunc $= Just Less dlp <- initDlp FrameSequential -- Initialize the DLP state. displayCallback $= display dlp -- The display callback needs the DLP state. idleCallback $= Just (postRedisplay Nothing) -- The idle callback must force redisplay for frame-sequential encoding. mainLoop display :: IORef DlpState -> DisplayCallback display dlp = do clear [ColorBuffer, DepthBuffer] isLeftEye <- showEye' LeftDlp dlp -- Determine whether to draw the view for the left or right eye. translate $ Vector3 (if isLeftEye then -0.05 else 0.05 :: GLfloat) 0 0 -- Shift the view slightly, depending on for which eye to draw. renderPrimitive . . . -- All of the rendering actions go here. drawDlp dlp -- Draw the colored DLP reference line just before swapping framebuffers. swapBuffers
This code has been validated with the following configuration of hardware and software:
- Optoma ML550 WXGA 500 Lumen 3D Ready Portable DLP LED Projector, running 120 Hz at 1024x768 resolution
- Optoma ZD302 DLP Link Active Shutter 3D Glasses
- Ubuntu 15.04, 64-bit
- NVIDIA Driver Version 340.93, with
xorg.conf
optionStereo
set to8
- GHC 7.6.3
- OpenGL == 2.8.0.0
- GLUT == 2.4.0.0
- data DlpEncoding
- data DlpState
- initDlp :: DlpEncoding -> IO (IORef DlpState)
- drawDlp :: IORef DlpState -> IO ()
- data DlpEye
- showEye :: DlpEye -> DlpState -> Bool
- showEye' :: DlpEye -> IORef DlpState -> IO Bool
- whichView :: DlpEye -> DlpState -> IO (Position, Size)
- whichView' :: DlpEye -> IORef DlpState -> IO (Position, Size)
DLP State and Encoding
data DlpEncoding Source #
The type of DLP encoding. See the specification <http://lists.gnu.org/archive/html/bino-list/2013-03/pdfz6rW7jUrgI.pdf> for further details.
SideBySide | Side-by-side encoding, where the left image is stored to the left of the right image in the framebuffer. |
FrameSequential | Frame-sequential encoding, where left and right images alternate, each filling the whole framebuffer. |
TopAndBottom | Top-and-bottom encoding, where the top image is stored above the bottom image in the framebuffer. |
LeftOnly | Monoscopic with only the left eye's view. |
RightOnly | Monoscopic with only the right eye's view. |
:: IORef DlpState | A reference to the current DLP state. |
-> IO () | An action to draw the DLP reference line. |
Draw the DLP reference line. This action should be executed after all other drawing is complete, just before buffers are swapped.
Active Frame(s)
Labels for the left and right eyes' views.
:: DlpEye | The eye in question. |
-> DlpState | The current DLP state. |
-> Bool | Whether the view of the specified eye should be shown for the current frame. |
Query whether to show the view from the specified eye for the current frame. Client code should call this function to determine which views to draw into the framebuffer.
:: DlpEye | The eye in question. |
-> IORef DlpState | A reference to the current DLP state. |
-> IO Bool | An action for determining whether the view of the specified eye should be shown for the current frame. |
Query whether to show the view from the specified eye for the current frame. Client code should call this function to determine which views to draw into the framebuffer.