[fluxus] Stereo Fluxus

Alex Norman alex at neisis.net
Wed May 16 07:54:09 PDT 2007


Sure thing, I've attached the diff of the code and updates to the two help files
that this change affects.  It only works for Linux right now as I've only
updated the X window initialization to allow for a stereo window, but I figure
making it work for OSX and Windoze wouldn't be a problem, I just haven't had
time/drive to do that, if you do either please send the updates my way.  I sent
this to the GEM main developer but haven't heard anything about it, I guess I
should just post it to the PD list.

-Alex

On  0, "Pagano, Patrick" <pat at digitalworlds.ufl.edu> wrote:
> care to share that GEM patch?
> :-)
> 
> 
> 
> -----Original Message-----
> From: fluxus-bounces at lists.pawfal.org on behalf of Dave Griffiths
> Sent: Wed 5/16/2007 5:20 AM
> To: Alex Norman
> Cc: Fluxus List
> Subject: Re: [fluxus] Stereo Fluxus
>  
> 
> > Hi,
> > I want to modify fluxus to allow for active stereo video [via crystal
> > glasses], I've already done this for pd's GEM and it was quite easy,
> > though they already had some other stereo modes.  Basically, I need to
> > render the scene one time for each eye, selecting a different buffer to
> > write to for each and offsetting the camera position slightly for each
> > eye.  I intend to write it in such a way that one could select this
> > functionality or not, so that it might actually be put into the main
> > distro eventually as others might find it useful (once this stereo mode
> > is in place it probably wouldn't be hard to implement other stereo modes).
> >
> > Anyways, if anyone could suggest where to implement this I'd appreciate
> > it (i figure in the renderer, but where in the renderer :)
> 
> Do you want to do this inside the fluxus scratchpad (traditional style) or
> with mred? It should be possible to do this with mred now, but I haven't
> had a chance to figure out much of mred's gl canvas yet - but you should
> be able to get it to change the draw buffer and rerender the scene.
> 
> To get it to work in the scratchpad, it'll take some C++ work - I think we
> need a low level render command which sets the current buffer to draw to
> from scheme (via glDrawBuffer) and enumerate all the options.
> 
> But however it's set, the place to make it work is from the frame
> callback, which currently looks like this (and lives inside
> scratchpad.ss):
> 
> (define (fluxus-frame-callback)
>   (set-camera (get-camera-transform))
>   (framedump-update)
>   (begin-scene)
>   (if (not (null? user-callback))
>       (user-callback))
>   (end-scene)
>   (tick-physics)
>   (update-audio))
> 
> We should be able to change it to something like:
> 
> (define (fluxus-frame-callback)
> 
>   ; draw the left buffer
>   (draw-buffer 'back-left) ; or equivelent mred func call
>   (set-camera (mmul (get-camera-transform)
>      (mtranslate (vector -1 0 0)) ; move to the left
>   (begin-scene)
>   (if (not (null? user-callback))
>       (user-callback))
>   (end-scene)
> 
>   ; draw the right buffer
>   (draw-buffer 'back-right) ; or equivelent mred func call
>   (set-camera (mmul (get-camera-transform)
>      (mtranslate (vector 1 0 0)) ; move to the right
>   (begin-scene)
>   (if (not (null? user-callback))
>       (user-callback)) ; need to call the user callback twice, as immediate
>                        ; mode objects will be lost the second time otherwise
>   (end-scene)
> 
>   ; update everything that should only be updated once per frame
>   (tick-physics)
>   (update-audio))
> 
> 
> 
-------------- next part --------------
Index: Base/GemMan.cpp
===================================================================
RCS file: /cvsroot/pd-gem/Gem/src/Base/GemMan.cpp,v
retrieving revision 1.59
diff -d -r1.59 GemMan.cpp
792a793,808
>   //test to see if stereo is supported
>   //XXX maybe there is a better place to do this?
>   GLboolean stereoWindowTest;
>   glGetBooleanv (GL_STEREO, &stereoWindowTest);
>   //if we're trying to do crystal glasses stereo but don't have a stereo window
>   //disable stereo and post a warning
>   if(m_stereo == 3 && !stereoWindowTest){
>     post("you've selected Crystal Glasses Stereo but your graphics card isn't set up for stereo, setting stereo=0");
>     //GetMyClass(data)->error("you've selected Crystal Glasses Stereo but your graphics card isn't set up for stereo, setting stereo=0");
>     m_stereo = GemMan::m_stereo = 0;
>   } else if(stereoWindowTest) {
>     //if we're not doing crystal eyes stereo but our window is enabled to do stereo
>     //select the back buffer for drawing
>     glDrawBuffer(GL_BACK);
>   }
> 
959a976,1037
>     case 3: // Crystal Eyes Stereo
>       {
>         int xSize = m_w;
>         int ySize = m_h;
>         float xDivy = (float)xSize / (float)ySize;
> 
>         // setup the left viewpoint
> 
>         // setup the matrices
>         glMatrixMode(GL_PROJECTION);
>         glLoadIdentity();
>         glFrustum(GemMan::m_perspect[0] * xDivy, GemMan::m_perspect[1] * xDivy, // left, right
>             GemMan::m_perspect[2], GemMan::m_perspect[3],     // bottom, top
>             GemMan::m_perspect[4], GemMan::m_perspect[5]);      // front, back
> 
>         glMatrixMode(GL_MODELVIEW);
>         glDrawBuffer(GL_BACK_LEFT);
>         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> 
>         glLoadIdentity();
>         gluLookAt(m_lookat[0] - m_stereoSep / 100.f, m_lookat[1], m_lookat[2], m_lookat[3], m_lookat[4],
>             m_lookat[5] + m_stereoFocal, m_lookat[6], m_lookat[7], m_lookat[8]);
> 
>         // render left view
>         fillGemState(currentState);
>         renderChain(s_linkHead, &currentState);
>         glMatrixMode(GL_MODELVIEW);
>         glLoadIdentity();
>         gluLookAt(0 - m_stereoSep / 100.f, 0, 4, 0, 0, 0 + m_stereoFocal, 0, 1, 0);
>         renderChain(s_linkHead_2, &currentState);
> 
>         // setup the right viewpoint
>         glClear(GL_DEPTH_BUFFER_BIT & m_clear_mask);
> 
>         // setup the matrices
>         glMatrixMode(GL_PROJECTION);
>         glLoadIdentity();
>         glFrustum(GemMan::m_perspect[0] * xDivy, GemMan::m_perspect[1] * xDivy, // left, right
>             GemMan::m_perspect[2], GemMan::m_perspect[3],     // bottom, top
>             GemMan::m_perspect[4], GemMan::m_perspect[5]);      // front, back
> 
>         glMatrixMode(GL_MODELVIEW);
>         glDrawBuffer(GL_BACK_RIGHT);
>         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> 
>         glLoadIdentity();
>         gluLookAt(m_lookat[0] + m_stereoSep / 100.f, m_lookat[1], m_lookat[2], m_lookat[3], m_lookat[4],
>             m_lookat[5] + m_stereoFocal, m_lookat[6], m_lookat[7], m_lookat[8]);
> 
>         // render right view
>         fillGemState(currentState);
>         currentState.tickTime=0.f;
>         renderChain(s_linkHead, &currentState);
> 
>         glMatrixMode(GL_MODELVIEW);
>         glLoadIdentity();
>         gluLookAt(0 + m_stereoSep / 100.f, 0, 4, 0, 0, 0 + m_stereoFocal, 0, 1, 0);
>         renderChain(s_linkHead_2, &currentState);
> 
>         glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);
>       }
>       break;
Index: Base/GemWinCreateXWin.cpp
===================================================================
RCS file: /cvsroot/pd-gem/Gem/src/Base/GemWinCreateXWin.cpp,v
retrieving revision 1.20
diff -d -r1.20 GemWinCreateXWin.cpp
40a41,51
> static int snglBuf24Stereo[] = {GLX_RGBA, 
>                           GLX_RED_SIZE, 8, 
>                           GLX_GREEN_SIZE, 8, 
>                           GLX_BLUE_SIZE, 8, 
>                           GLX_DEPTH_SIZE, 16, 
>                           GLX_STENCIL_SIZE, 8, 
>                           GLX_ACCUM_RED_SIZE, 8,
>                           GLX_ACCUM_GREEN_SIZE, 8,
>                           GLX_ACCUM_BLUE_SIZE, 8,
>                           GLX_STEREO,
>                           None};
51a63,74
> static int dblBuf24Stereo[] =  {GLX_RGBA, 
>                           GLX_RED_SIZE, 4, 
>                           GLX_GREEN_SIZE, 4, 
>                           GLX_BLUE_SIZE, 4, 
>                           GLX_DEPTH_SIZE, 16, 
>                           GLX_STENCIL_SIZE, 8, 
>                           GLX_ACCUM_RED_SIZE, 8,
>                           GLX_ACCUM_GREEN_SIZE, 8,
>                           GLX_ACCUM_BLUE_SIZE, 8,
>                           GLX_DOUBLEBUFFER, 
>                           GLX_STEREO,
>                           None};
57a81,87
> static int snglBuf8Stereo[] =  {GLX_RGBA, 
>                           GLX_RED_SIZE, 3, 
>                           GLX_GREEN_SIZE, 3, 
>                           GLX_BLUE_SIZE, 2, 
>                           GLX_DEPTH_SIZE, 16, 
>                           GLX_STEREO,
>                           None};
65a96,103
> static int dblBuf8Stereo[] =   {GLX_RGBA, 
>                           GLX_RED_SIZE, 1, 
>                           GLX_GREEN_SIZE, 2, 
>                           GLX_BLUE_SIZE, 1, 
>                           GLX_DEPTH_SIZE, 16, 
>                           GLX_DOUBLEBUFFER, 
>                           GLX_STEREO,
>                           None};
139,140c177,180
<     // try for a double-buffered on 24bit machine
<     vi = glXChooseVisual(info.dpy, info.screen, dblBuf24);
---
>     // try for a double-buffered on 24bit machine (try stereo first)
>     vi = glXChooseVisual(info.dpy, info.screen, dblBuf24Stereo);
>     if (vi == NULL)
>       vi = glXChooseVisual(info.dpy, info.screen, dblBuf24);
142,143c182,185
<       // try for a double buffered on a 8bit machine
<       vi = glXChooseVisual(info.dpy, info.screen, dblBuf8);
---
>       // try for a double buffered on a 8bit machine (try stereo first)
>       vi = glXChooseVisual(info.dpy, info.screen, dblBuf8Stereo);
>       if(vi == NULL)
>         vi = glXChooseVisual(info.dpy, info.screen, dblBuf8);
154,155c196,199
<     // try for a single buffered on a 24bit machine
<     vi = glXChooseVisual(info.dpy, info.screen, snglBuf24);
---
>     // try for a single buffered on a 24bit machine (try stereo first)
>     vi = glXChooseVisual(info.dpy, info.screen, snglBuf24Stereo);
>     if (vi == NULL)
>       vi = glXChooseVisual(info.dpy, info.screen, snglBuf24);
157,158c201,204
<       // try for a single buffered on a 8bit machine
<       vi = glXChooseVisual(info.dpy, info.screen, snglBuf8);
---
>       // try for a single buffered on a 8bit machine (try stereo first)
>       vi = glXChooseVisual(info.dpy, info.screen, snglBuf8Stereo);
>       if (vi == NULL)
>         vi = glXChooseVisual(info.dpy, info.screen, snglBuf8);
Index: Controls/gemwin.cpp
===================================================================
RCS file: /cvsroot/pd-gem/Gem/src/Controls/gemwin.cpp,v
retrieving revision 1.28
diff -d -r1.28 gemwin.cpp
571,572c571,572
<   if (mode<0 || mode>2){
<     GetMyClass(data)->error("possible stereo-modes are: 0, 1, 2");
---
>   if (mode<0 || mode>3){
>     GetMyClass(data)->error("possible stereo-modes are: 0, 1, 2, 3");
574a575
> 
-------------- next part --------------
#N canvas 0 0 1114 726 12;
#X obj 285 51 gemwin 20;
#X text 222 25 access to the window manager;
#X text 183 144 The initial argument is the number of frames per second
to render. The default value is 20 frames per second.;
#X text 568 354 1/0 : turn rendering on/off;
#X text 70 442 create : create the graphics window;
#X text 70 463 destroy : destroy the graphics window;
#X text 70 489 buffer 1/2 : single or double buffering;
#X text 566 431 frame num : the number of frames per second to render
at;
#X text 46 656 reset : reset the graphics manager to the default values
;
#X text 184 175 Editing at the same time as rendering is not encouraged
and is a good way to generate a segmentation fault or core dump!;
#X text 570 399 bang : clear the buffer (single buffer mode);
#X text 569 382 bang : swap the buffers (double buffer mode);
#X text 182 231 It is EXTREMELEY IMPORTANT that you turn on rendering
before trying to draw anything \, including in single buffer mode.
When rendering is turned on \, the gem objects establish a rendering
network. When rendering is turned off \, they remove this network.
;
#X text 599 309 after window-creation::;
#X text 124 393 before/during window-creation::;
#N canvas 10 74 575 310 lighting 0;
#X text 47 96 lighting 1/0 : turn lighting on/off;
#X text 45 143 ambient R G B : the ambient lighting color;
#X text 44 164 specular R G B : the specular lighting color;
#X text 45 184 shininess num : the shininess value;
#X text 47 120 color R G B : the background color of the window;
#X text 45 213 fogmode 0/1/2/3 : set the fog mode (OFF/LINEAR/EXP/EXP^2)
;
#X text 45 256 fogcolor R G B : the color of the fog;
#X text 44 234 fog num : the fog density;
#X text 64 25 messages to the [gemwin] regarding lighting effects;
#X restore 580 520 pd lighting and fog;
#N canvas 236 183 746 676 viewing 0;
#X text 43 31 messages to [gemwin] regarding the view-point ("camera")
;
#X text 37 129 perspec <left> <right> <bottom> <top> <front> <back>::
;
#X text 88 155 set the clipping planes of the view-point. this might
be what you need \, if all the objects that re further away than 20
units suddenly disappear;
#X text 83 220 default: -1 1 -1 1 1 20;
#X text 26 303 view <x> <y> <z>::;
#X text 62 329 translate the camera / set the viewpoint:: the viewing-direction
will not be changed.;
#X text 59 369 default: 0 0 4;
#X text 58 388 the viewing direction defaults to "0 0 1" \, with y-axis
as "up";
#X text 25 434 view <x> <y> <z> <azimuth>::;
#X text 27 452 view <x> <y> <z> <azimuth> <elevation>::;
#X text 59 481 translate/rotate camera/viewpoint \; the "up" direction
will still be the y-axis;
#X text 20 556 view <view_x> <view_y> <view_z> <target_x> <target_y>
<target_z> <up_x> <up_y> <up_z>::;
#X text 54 597 set viewpoint (view_X view_Y view_Z). the camera will
look at the target-point (target_X \, target_Y \, target_Z). "up" is
defined via the vector (up_X \, up_Y \, up_Z);
#X text 61 522 default: 0 0 4 0 0;
#X text 54 650 default: 0 0 4 0 0 0 0 1 0;
#X restore 578 582 pd viewing;
#X text 566 465 cursor 0/1: turn the cursor on/off;
#X text 47 682 print : show some information on the stderr.;
#X text 137 610 misc::;
#N canvas 185 171 594 382 window 0;
#X text 28 188 dimen x y : the x and y dimensions of the window;
#X text 27 144 offset x y : the x and y offset of the window (might
not work under certain window-managers when borders are on);
#X text 27 117 border 0/1: create a window with/out borders;
#X text 26 216 fullscreen 0/1: make fullscreen-window (if possible
with the dimensions passed via "dimen");
#X text 44 31 messages to [gemwin] regarding the window;
#X text 26 275 title <title_symbol>: set the title for the window;
#X restore 138 526 pd window propoerties;
#N canvas 4 20 600 400 stereoscopic 1;
#X text 35 176 stereoSep val : set the stereo-separation (default:
-15);
#X text 34 193 stereoFoc val : set the stereo-focal;
#X text 34 211 stereoLine 0/1 : turn the seperation-line between the
2 screens in stereo-mode 1 on/off;
#X text 71 56 messages to [gemwin] regarding stereoscopic appearance:
;
#X text 35 142 stereo 0/1/2/3 : set stereo-mode to off(0) \, 2-screen-mode(1)
\, Red/Green-mode(2) \, CrystalEyes-mode(3);
#X restore 580 548 pd stereoscopic display;
#X text 596 657 createStereo:: do not use this!! use 'create'+'stereo
1';
#X text 617 631 deprecated::;
#X text 285 5 [gemwin];
#X text 186 92 [gemwin] controls the window manager. It passes various
messages to the manager \, controlling the attributes of the window.
;
-------------- next part --------------
#N canvas 0 38 600 504 10;
#X obj 74 279 gemwin;
#X obj 426 54 gemhead;
#X msg 120 159 destroy;
#X msg 117 72 1;
#X msg 118 102 0;
#X floatatom 464 134 0 0 0 0 - - -;
#X obj 464 307 gemhead 1;
#X obj 464 332 world_light;
#X obj 426 181 model ../data/venus.obj;
#X text 185 21 load in a model file;
#X obj 426 81 translateXYZ 0 0 2;
#X obj 426 157 rotateXYZ;
#X text 149 40 and display it stereoscopically;
#X msg 221 130 stereoSep \$1;
#X msg 318 129 stereoFoc \$1;
#X floatatom 221 92 0 0 0 0 - - -;
#X floatatom 318 87 0 0 0 0 - - -;
#X text 24 313 The default stereoSep is -15;
#X text 24 333 The model may appear inside out depending on what viewing
method you use.;
#X text 24 368 If it does \, change the stereoSep to 15;
#N canvas 30 60 290 300 Gem.init 0;
#X obj 71 191 outlet;
#X obj 71 81 loadbang;
#X msg 101 134 reset;
#X obj 71 109 t b b;
#X msg 71 164 lighting 1;
#X msg 148 165 stereo 1;
#X connect 1 0 3 0;
#X connect 2 0 0 0;
#X connect 3 0 4 0;
#X connect 3 0 5 0;
#X connect 3 1 2 0;
#X connect 4 0 0 0;
#X connect 5 0 0 0;
#X restore 126 232 pd Gem.init;
#X msg 117 132 create;
#X msg 271 206 stereo 1;
#X msg 271 228 stereo 2;
#X msg 269 270 stereo 0;
#X text 335 207 2 separate images;
#X text 338 230 red/green stereo;
#X text 334 272 no stereo;
#X text 338 250 crystal eyes stereo;
#X msg 271 248 stereo 3;
#X connect 1 0 10 0;
#X connect 2 0 0 0;
#X connect 3 0 0 0;
#X connect 4 0 0 0;
#X connect 5 0 11 2;
#X connect 6 0 7 0;
#X connect 10 0 11 0;
#X connect 11 0 8 0;
#X connect 13 0 0 0;
#X connect 14 0 0 0;
#X connect 15 0 13 0;
#X connect 16 0 14 0;
#X connect 20 0 0 0;
#X connect 21 0 0 0;
#X connect 22 0 0 0;
#X connect 23 0 0 0;
#X connect 24 0 0 0;
#X connect 29 0 0 0;


More information about the Fluxus mailing list