>From 6d944bf7850d7420de10b9dbffd4c8aa3d9f7967 Mon Sep 17 00:00:00 2001
From: keltie <garry.keltie@rmit.edu.au>
Date: Thu, 17 Feb 2011 10:39:07 +1100
Subject: [PATCH] Adding first stereoscopic options to glwin32

---
 modules/video_output/msw/glwin32.c |  304 +++++++++++++++++++++++++++++++++++-
 modules/video_output/opengl.h      |  290 +++++++++++++++++++++++++++++++---
 2 files changed, 572 insertions(+), 22 deletions(-)

diff --git a/modules/video_output/msw/glwin32.c b/modules/video_output/msw/glwin32.c
index a3aa25b..799273b 100644
--- a/modules/video_output/msw/glwin32.c
+++ b/modules/video_output/msw/glwin32.c
@@ -48,11 +48,147 @@
 static int  Open (vlc_object_t *);
 static void Close(vlc_object_t *);
 
+/* START Preference pane, advanced options GK */
+static void setStereoSourceFormat( vout_display_sys_t *p_vout,
+									const char *psz_stereoSourceFormat );
+int getStereoSourceFormat(vout_display_sys_t *sys);
+static void setStereoMode( vout_display_sys_t *p_vout,
+							const char *psz_stereoMode );
+int getStereoMode(vout_display_sys_t *sys);
+
+static const char *const stereo_source_format_list[] = {
+		"separated",
+        "horizontal",
+		"horizontal-comp",
+		"vertical",
+		"vertical-comp"
+		};
+
+static const char *const stereo_source_format_list_text[] = {
+		N_("Separated Frames (interleaved) [pending]"),
+		N_("Horizontal Side-by-Side Frame Packing"),
+		N_("Non-Square Horizontal pixels, Side-by-Side Frame Packing"),
+		N_("Vertical Top-over-Bottom Frame Packing [pending]"),
+		N_("Non-Square Vertical pixels, Top-over-Bottom Frame Packing [pending]")
+		};
+
+static const char *const stereo_mode_list[] = {
+		"none",
+		"quadbuffered",
+		"horizontal-split",
+		"vertical-split",
+		"anaglyphic",
+		"checkerboard"
+		};
+
+static const char *const stereo_mode_list_text[] = {
+		N_("None"),
+		N_("Quad Buffered"),
+		N_("Horizontal Split [pending]"),
+		N_("Vertical Split [pending]"),
+		N_("Anaglyphic"),
+		N_("Checkerboard [pending]")
+		};
+
+#define STEREO_ENABLE_TEXT N_("Enable Stereo. ")
+#define STEREO_ENABLE_LONGTEXT N_(\
+    "Toggle to enable stereo using OpenGL within the application. ")
+
+#define STEREO_EYE_SEPARATION_TEXT N_("Eye Separation")
+#define STEREO_EYE_SEPARATION_LONGTEXT N_("Physical intraoculer distance." )
+
+#define STEREO_SCREEN_DISTANCE_TEXT N_("Screen Distance")
+#define STEREO_SCREEN_DISTANCE_LONGTEXT N_(\
+		"Factor for setting parallax plane as screen distance." )
+
+#define STEREO_SCREEN_HEIGHT_TEXT N_("Screen Height")
+#define STEREO_SCREEN_HEIGHT_LONGTEXT N_(\
+		"Factor for modifying eye separation scale by screen height." )
+
+#define STEREO_SOURCE_FORMAT_TEXT N_("Input File Source Format")
+#define STEREO_SOURCE_FORMAT_LONGTEXT N_(\
+		"Input file source format, select the input frame packing format." )
+
+#define STEREO_MODE_TEXT N_("OpenGL Stereo Mode")
+#define STEREO_MODE_LONGTEXT N_(\
+		"OpenGL Stereo Mode, select the output display methods." )
+
+#define STEREO_INVERT_TEXT N_("Swap Left-Right Eyes")
+#define STEREO_INVERT_LONGTEXT N_(\
+		"Swapping eyes can compensate for sync signal latency. ")
+
+#define STEREO_ANAGLYPH_LEFT_RED_TEXT N_("Left Eye: Red")
+#define STEREO_ANAGLYPH_LEFT_RED_LONGTEXT N_("\
+		Red component value for Left Eye anaglyph colour." )
+#define STEREO_ANAGLYPH_LEFT_GREEN_TEXT N_("Left Eye: Green")
+#define STEREO_ANAGLYPH_LEFT_GREEN_LONGTEXT N_(\
+		"Green component value for Left Eye anaglyph colour." )
+#define STEREO_ANAGLYPH_LEFT_BLUE_TEXT N_("Left Eye: Blue")
+#define STEREO_ANAGLYPH_LEFT_BLUE_LONGTEXT N_(\
+		"Blue component value for Left Eye anaglyph colour." )
+#define STEREO_ANAGLYPH_RIGHT_RED_TEXT N_("Right Eye: Red")
+#define STEREO_ANAGLYPH_RIGHT_RED_LONGTEXT N_(\
+		"Red component value for Right Eye anaglyph colour." )
+#define STEREO_ANAGLYPH_RIGHT_GREEN_TEXT N_("Right Eye: Green")
+#define STEREO_ANAGLYPH_RIGHT_GREEN_LONGTEXT N_(\
+		"Green component value for Right Eye anaglyph colour." )
+#define STEREO_ANAGLYPH_RIGHT_BLUE_TEXT N_("Right Eye: Blue")
+#define STEREO_ANAGLYPH_RIGHT_BLUE_LONGTEXT N_(\
+		"Blue component value for Right Eye anaglyph colour." )
+
+/* END Preference pane, advanced options GK */
+
 vlc_module_begin()
     set_category(CAT_VIDEO)
     set_subcategory(SUBCAT_VIDEO_VOUT)
     set_shortname("OpenGL")
     set_description(N_("OpenGL video output"))
+
+    add_bool( "opengl-stereo-enable", false, NULL,
+        STEREO_ENABLE_TEXT, STEREO_ENABLE_LONGTEXT, true )
+
+    set_section( N_("OpenGL Stereo Options"), NULL)
+    add_string( "opengl-stereo-source-format", "", NULL,
+        STEREO_SOURCE_FORMAT_TEXT, STEREO_SOURCE_FORMAT_LONGTEXT, true )
+    change_string_list( stereo_source_format_list,
+    		stereo_source_format_list_text, 0 )
+    add_string( "opengl-stereo-mode", "", NULL,
+        STEREO_MODE_TEXT, STEREO_MODE_LONGTEXT, true )
+    change_string_list( stereo_mode_list, stereo_mode_list_text, 0 )
+    add_bool( "opengl-stereo-invert", false, NULL,
+        STEREO_INVERT_TEXT, STEREO_INVERT_LONGTEXT, true )
+
+    set_section( N_("Anaglyph Colour Options " \
+    		"(Default: Left Red 1,0,0 Right Cyan 0,1,1)"), NULL)
+    add_float_with_range( "left-eye-red", 1.00, 0.00, 0.00, NULL,
+        STEREO_ANAGLYPH_LEFT_RED_TEXT, STEREO_ANAGLYPH_LEFT_RED_LONGTEXT,
+        true )
+	add_float_with_range( "left-eye-green", 0.00, 0.00, 0.00, NULL,
+		STEREO_ANAGLYPH_LEFT_GREEN_TEXT, STEREO_ANAGLYPH_LEFT_GREEN_LONGTEXT,
+		true )
+	add_float_with_range( "left-eye-blue", 0.00, 0.00, 0.00, NULL,
+		STEREO_ANAGLYPH_LEFT_BLUE_TEXT, STEREO_ANAGLYPH_LEFT_BLUE_LONGTEXT,
+		true )
+
+	add_float_with_range( "right-eye-red", 0.00, 0.00, 0.00, NULL,
+		STEREO_ANAGLYPH_RIGHT_RED_TEXT, STEREO_ANAGLYPH_RIGHT_RED_LONGTEXT,
+		true )
+	add_float_with_range( "right-eye-green", 1.00, 0.00, 0.00, NULL,
+		STEREO_ANAGLYPH_RIGHT_GREEN_TEXT, STEREO_ANAGLYPH_RIGHT_GREEN_LONGTEXT,
+		true )
+	add_float_with_range( "right-eye-blue", 1.00, 0.00, 0.00, NULL,
+		STEREO_ANAGLYPH_RIGHT_BLUE_TEXT, STEREO_ANAGLYPH_RIGHT_BLUE_LONGTEXT,
+		true )
+
+	set_section( N_("Viewing Environment Options (not enabled)"), NULL)
+	add_float_with_range( "opengl-eye-separation", 0.06, 0.00, 99.99, NULL,
+		STEREO_EYE_SEPARATION_TEXT, STEREO_EYE_SEPARATION_LONGTEXT, true )
+	add_float_with_range( "opengl-screen-distance", 0.50, 0.00, 99.99, NULL,
+		STEREO_SCREEN_DISTANCE_TEXT, STEREO_SCREEN_DISTANCE_LONGTEXT, true )
+	add_float_with_range( "opengl-screen-height", 0.50, 0.00, 99.99, NULL,
+		STEREO_SCREEN_HEIGHT_TEXT, STEREO_SCREEN_HEIGHT_LONGTEXT, true )
+
+
     set_capability("vout display", 20)
     add_shortcut("glwin32")
     add_shortcut("opengl")
@@ -70,6 +206,7 @@ static void           Manage (vout_display_t *);
 
 static void           Swap   (vout_opengl_t *);
 
+
 /**
  * It creates an OpenGL vout display.
  */
@@ -78,11 +215,18 @@ static int Open(vlc_object_t *object)
     vout_display_t *vd = (vout_display_t *)object;
     vout_display_sys_t *sys;
 
+    /*GK added - */
+    bool stereoEnabled;
+    char *psz_stereoSourceFormat;
+    char *psz_stereoMode;
+
+
     /* Allocate structure */
     vd->sys = sys = calloc(1, sizeof(*sys));
     if (!sys)
         return VLC_ENOMEM;
 
+
     /* */
     if (CommonInit(vd))
         goto error;
@@ -92,12 +236,78 @@ static int Open(vlc_object_t *object)
     /* */
     sys->hGLDC = GetDC(sys->hvideownd);
 
+    /* GK ADDED opengl stereo vars */
+    stereoEnabled = var_CreateGetBool( vd, "opengl-stereo-enable" );
+
+    /* Parse gui vars into the vout_display_opengl_t struct so we can use */
+    sys->vgl.b_opengl_stereo_enable = var_CreateGetBool( vd,
+    		"opengl-stereo-enable" );
+    sys->vgl.b_opengl_stereo_invert = var_CreateGetBool( vd,
+    		"opengl-stereo-invert" );
+    sys->vgl.f_opengl_stereo_separation = var_CreateGetFloat( vd,
+    		"opengl-eye-separation" );
+
+    /* Get selected list items */
+    if (!(psz_stereoSourceFormat = var_CreateGetNonEmptyStringCommand( vd,
+    		"opengl-stereo-source-format" )))
+    {
+    	msg_Err( vd, "Stereo Source Format not found, using side-by-side");
+    	sys->vgl.i_opengl_stereo_source_format = STEREO_FORMAT_SEPARATED;
+    }
+    else
+    {
+    	setStereoSourceFormat( sys, psz_stereoSourceFormat );
+    	/* msg_Info( vd, psz_stereoSourceFormat); */
+    }
+
+    if ( !(psz_stereoMode = var_CreateGetNonEmptyStringCommand( vd,
+    		"opengl-stereo-mode" )))
+    {
+    	msg_Err( vd, "Stereo Mode not found, " \
+    			" turning PFD_STEREO flag on but using None");
+    	sys->vgl.i_opengl_stereo_mode = STEREO_MODE_NONE;
+    }
+    else
+    {
+       	setStereoMode( sys, psz_stereoMode );
+    	/* msg_Info( vd, psz_stereoMode); */
+     }
+
+    /* pass on colour values to the vout_display_opengl_t struct from the gui */
+    sys->vgl.f_anaglyphColourLeft[0] = var_CreateGetFloat( vd,
+    		"left-eye-red");
+    sys->vgl.f_anaglyphColourLeft[1] = var_CreateGetFloat( vd,
+    		"left-eye-green");
+    sys->vgl.f_anaglyphColourLeft[2] = var_CreateGetFloat( vd,
+    		"left-eye-blue");
+
+    sys->vgl.f_anaglyphColourRight[0] = var_CreateGetFloat( vd,
+    		"right-eye-red");
+    sys->vgl.f_anaglyphColourRight[1] = var_CreateGetFloat( vd,
+    		"right-eye-green");
+    sys->vgl.f_anaglyphColourRight[2] = var_CreateGetFloat( vd,
+    		"right-eye-blue");
+
+
     /* Set the pixel format for the DC */
     PIXELFORMATDESCRIPTOR pfd;
     memset(&pfd, 0, sizeof(pfd));
     pfd.nSize = sizeof(pfd);
     pfd.nVersion = 1;
-    pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
+    
+    /* ADDED GK */
+    if (( stereoEnabled ))
+    {
+        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
+        		PFD_DOUBLEBUFFER | PFD_STEREO;
+    }
+    /* original flags */
+    else
+    {
+        pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
+        		PFD_DOUBLEBUFFER;
+    }
+
     pfd.iPixelType = PFD_TYPE_RGBA;
     pfd.cColorBits = 24;
     pfd.cDepthBits = 16;
@@ -134,6 +344,10 @@ static int Open(vlc_object_t *object)
     vd->control = Control;
     vd->manage  = Manage;
 
+    /* Added GK */
+    free( psz_stereoSourceFormat );
+    free( psz_stereoMode );
+
     return VLC_SUCCESS;
 
 error:
@@ -203,6 +417,7 @@ static int Control(vout_display_t *vd, int query, va_list args)
         CommonDisplay(vd);
         return VLC_SUCCESS;
     }
+
     default:
         return CommonControl(vd, query, args);
     }
@@ -226,3 +441,90 @@ static void Swap(vout_opengl_t *gl)
     SwapBuffers(vd->sys->hGLDC);
 }
 
+/**
+ * Get the stereo source format from the vout_display_sys_t struct
+ * @return int the i_opengl_stereo_source_format held in vout_display_sys_t
+ */
+int getStereoSourceFormat(vout_display_sys_t *sys)
+{
+	return sys->vgl.i_opengl_stereo_source_format;
+}
+
+/**
+ * Set the stereo source format for the vout_display_sys_t struct
+ * to be used in opengl.h
+ * @param vout_display_sys_t
+ * @param cont char*, the source format selected from the gui
+ */
+static void setStereoSourceFormat(vout_display_sys_t *sys,
+		const char *psz_stereoSourceFormat )
+{
+	if (strcmp( psz_stereoSourceFormat, "separated") == 0 )
+	{
+	    sys->vgl.i_opengl_stereo_source_format = STEREO_FORMAT_SEPARATED;
+	}
+	else if (strcmp( psz_stereoSourceFormat, "horizontal") == 0 )
+	{
+		sys->vgl.i_opengl_stereo_source_format = STEREO_FORMAT_HORIZONTAL;
+	}
+	else if (strcmp( psz_stereoSourceFormat, "horizontal-comp") == 0 )
+	{
+		sys->vgl.i_opengl_stereo_source_format = STEREO_FORMAT_HORIZONTAL_COMP;
+	}
+	else if (strcmp( psz_stereoSourceFormat, "vertical") == 0 )
+	{
+		sys->vgl.i_opengl_stereo_source_format = STEREO_FORMAT_VERTICAL;
+	}
+	else if (strcmp( psz_stereoSourceFormat, "vertical-comp" ) == 0 )
+	{
+		sys->vgl.i_opengl_stereo_source_format = STEREO_FORMAT_VERTICAL_COMP;
+	}
+	else
+	{
+		sys->vgl.i_opengl_stereo_source_format = STEREO_FORMAT_SEPARATED;
+	}
+}
+
+/**
+ * Get the stereo mode from the vout_display_sys_t struct
+ * @return int the i_opengl_stereo_mode held in vout_display_sys_t
+ */
+int getStereoMode(vout_display_sys_t *sys)
+{
+	return sys->vgl.i_opengl_stereo_mode;
+}
+
+/**
+ * Set the stereo mode for the vout_display_sys_t struct
+ * to be used in opengl.h
+ * @param vout_display_sys_t
+ * @param cont char*, the mode selected from the gui
+ */
+static void setStereoMode(vout_display_sys_t *sys,
+		const char *psz_stereoMode )
+{
+	if (strcmp( psz_stereoMode, "quadbuffered") == 0 )
+	{
+	    sys->vgl.i_opengl_stereo_mode = STEREO_MODE_QUADBUFFER;
+	}
+	else if (strcmp( psz_stereoMode, "horizontal-split") == 0 )
+	{
+	    sys->vgl.i_opengl_stereo_mode = STEREO_MODE_HORIZONTAL;
+	}
+	else if (strcmp( psz_stereoMode, "vertical-split") == 0 )
+	{
+	    sys->vgl.i_opengl_stereo_mode = STEREO_MODE_VERTICAL;
+	}
+	else if (strcmp( psz_stereoMode, "anaglyphic") == 0 )
+	{
+	    sys->vgl.i_opengl_stereo_mode = STEREO_MODE_ANAGLYPH;
+	}
+	else if (strcmp( psz_stereoMode, "checkerboard") == 0 )
+	{
+	    sys->vgl.i_opengl_stereo_mode = STEREO_MODE_CHECKERBOARD;
+	}
+	else
+	{
+		sys->vgl.i_opengl_stereo_mode = STEREO_MODE_NONE;
+	}
+}
diff --git a/modules/video_output/opengl.h b/modules/video_output/opengl.h
index c54258f..e2d61de 100644
--- a/modules/video_output/opengl.h
+++ b/modules/video_output/opengl.h
@@ -80,6 +80,44 @@
 # define VLCGL_TEXTURE_COUNT (1)
 #endif
 
+/* GK Added for stereo */
+
+/* Stereo source formats
+ * Currently we are only dealing with side by side frame packing */
+
+/* interleaved */
+#define STEREO_FORMAT_SEPARATED        0
+/* standard side by side frame packing */
+#define STEREO_FORMAT_HORIZONTAL       1
+/* non-square horizontal pixels, side by side frame packing
+ * (eg H.264/AVC broadcast) */
+#define STEREO_FORMAT_HORIZONTAL_COMP  2
+/* top and bottom frame packing */
+#define STEREO_FORMAT_VERTICAL         3
+/* non-square vertical pixels top and bottom frame packing */
+#define STEREO_FORMAT_VERTICAL_COMP    4
+
+/* Stereo rendering types
+ * Currently we are only dealing with quadbuffered and anaglyphic stereo */
+
+/* show the left image only */
+#define STEREO_MODE_LEFT         0
+/* show the right image only */
+#define STEREO_MODE_RIGHT        1
+/* colour separated L/R images composited as one frame */
+#define STEREO_MODE_ANAGLYPH     2
+/* OpenGL Quadro series page flipping active stereo option */
+#define STEREO_MODE_QUADBUFFER   3
+/* L/R output images are overlapped and separated with polarising filters */
+#define STEREO_MODE_HORIZONTAL   4
+/* T/B output images are overlapped and separated with polarising filters */
+#define STEREO_MODE_VERTICAL     5
+/* DLP TV/projector technique */
+#define STEREO_MODE_CHECKERBOARD 6
+/* Test */
+#define STEREO_MODE_NONE         7
+
+
 static inline int GetAlignedSize(int i_size)
 {
     /* Return the nearest power of 2 */
@@ -103,6 +141,16 @@ typedef struct {
     uint8_t    *buffer[VLCGL_TEXTURE_COUNT];
 
     picture_pool_t *pool;
+
+    /* GK ADDED opengl stereo vars */
+    bool          b_opengl_stereo_enable;
+    bool          b_opengl_stereo_invert;
+    float         f_opengl_stereo_separation;
+    int           i_opengl_stereo_source_format;
+    int           i_opengl_stereo_mode;
+    float         f_anaglyphColourLeft[3];
+    float         f_anaglyphColourRight[3];
+
 } vout_display_opengl_t;
 
 static int vout_display_opengl_Init(vout_display_opengl_t *vgl,
@@ -111,9 +159,11 @@ static int vout_display_opengl_Init(vout_display_opengl_t *vgl,
 {
 	vgl->gl = gl;
 
-    /* Find the chroma we will use and update fmt */
-    /* TODO: We use YCbCr on Mac which is Y422, but on OSX it seems to == YUY2. Verify */
-#if (defined(WORDS_BIGENDIAN) && VLCGL_FORMAT == GL_YCBCR_422_APPLE) || (VLCGL_FORMAT == YCBCR_MESA)
+	/* Find the chroma we will use and update fmt */
+    /* TODO: We use YCbCr on Mac which is Y422,
+     * but on OSX it seems to == YUY2. Verify */
+#if (defined(WORDS_BIGENDIAN) && VLCGL_FORMAT == GL_YCBCR_422_APPLE)
+	|| (VLCGL_FORMAT == YCBCR_MESA)
     fmt->i_chroma = VLC_CODEC_YUYV;
     vgl->tex_pixel_size = 2;
 #elif defined(GL_YCBCR_422_APPLE) && (VLCGL_FORMAT == GL_YCBCR_422_APPLE)
@@ -192,6 +242,7 @@ static int vout_display_opengl_Init(vout_display_opengl_t *vgl,
     }
 	return VLC_SUCCESS;
 }
+
 static void vout_display_opengl_Clean(vout_display_opengl_t *vgl)
 {
     /* */
@@ -409,31 +460,228 @@ static int vout_display_opengl_Display(vout_display_opengl_t *vgl,
     const float f_normh = 1.0;
 #endif
 
-    float f_x      = (source->i_x_offset +                       0 ) / f_normw;
-    float f_y      = (source->i_y_offset +                       0 ) / f_normh;
-    float f_width  = (source->i_x_offset + source->i_visible_width ) / f_normw;
-    float f_height = (source->i_y_offset + source->i_visible_height) / f_normh;
-
-    /* Why drawing here and not in Render()? Because this way, the
-       OpenGL providers can call vout_display_opengl_Display to force redraw.i
-       Currently, the OS X provider uses it to get a smooth window resizing */
-
-    glClear(GL_COLOR_BUFFER_BIT);
-
-    glEnable(VLCGL_TARGET);
+    /* Added GK */
+    /* local stereo variables */
+    bool b_stereoEnabled = vgl->b_opengl_stereo_enable;
+    bool b_stereoInvert = vgl->b_opengl_stereo_invert;
+    int i_stereoMode   = vgl->i_opengl_stereo_mode;
+    int i_stereoFormat = vgl->i_opengl_stereo_source_format;
+
+    /* Initialise anaglyph colours with a default */
+    float f_anaglyphColourLeft[3] = {1.f, 0.f, 0.f};
+    float f_anaglyphColourRight[3] = {0.f, 1.f, 1.f};
+
+    /* Variable to compensate for double width/height frames
+     * Initialised for STEREO_FORMAT_SEPARATED */
+	float f_horizAspect = 1.f;
+	float f_vertAspect =  1.f;
+
+	float f_x_right = 0.f;
+	float f_y_right = 0.f;
+	float f_width_right = 0.f;
+	float f_height_right = 0.f;
+
+	float f_x_left = 0.f;
+	float f_y_left = 0.f;
+	float f_width_left = 0.f;
+	float f_height_left = 0.f;
+
+	if (b_stereoEnabled) /* Skip a lot of stuff if only rendering in mono */
+	{
+		if ((vgl->f_anaglyphColourLeft != NULL) &&
+				(vgl->f_anaglyphColourRight != NULL))
+		{
+			f_anaglyphColourLeft[0] = vgl->f_anaglyphColourLeft[0];
+			f_anaglyphColourLeft[1] = vgl->f_anaglyphColourLeft[1];
+			f_anaglyphColourLeft[2] = vgl->f_anaglyphColourLeft[2];
+			f_anaglyphColourRight[0] = vgl->f_anaglyphColourRight[0];
+			f_anaglyphColourRight[1] = vgl->f_anaglyphColourRight[1];
+			f_anaglyphColourRight[2] = vgl->f_anaglyphColourRight[2];
+		}
+
+		if (( i_stereoFormat == STEREO_FORMAT_HORIZONTAL ) ||
+				( i_stereoFormat == STEREO_FORMAT_HORIZONTAL_COMP ))
+		{
+			f_horizAspect = 2.f;
+			f_vertAspect =  1.f;
+		}
+		/* vertical modes need to be tested still */
+		if (( i_stereoFormat == STEREO_FORMAT_VERTICAL ) ||
+				( i_stereoFormat == STEREO_FORMAT_VERTICAL_COMP ))
+		{
+			f_horizAspect = 1.f;
+			f_vertAspect =  2.f;
+		}
+
+		f_x_left      = (source->i_x_offset +                       0 ) / ( f_normw );
+		f_y_left      = (source->i_y_offset +                       0 ) / ( f_normh );
+		f_width_left  = (source->i_x_offset + source->i_visible_width)  / ( f_normw );
+		f_height_left = (source->i_y_offset + source->i_visible_height) / ( f_normh );
+
+		f_x_right      = (source->i_x_offset +                       0 ) / ( f_normw );
+		f_y_right      = (source->i_y_offset +                       0 ) / ( f_normh );
+		f_width_right  = (source->i_x_offset + source->i_visible_width)  / ( f_normw );
+		f_height_right = (source->i_y_offset + source->i_visible_height) / ( f_normh );
+
+		glClear(GL_COLOR_BUFFER_BIT);
+
+        glEnable(VLCGL_TARGET);
+
+		if ( i_stereoMode == STEREO_MODE_ANAGLYPH ) {
+			glEnable(GL_BLEND);
+			glBlendFunc(GL_ONE, GL_ONE);
+		}
+
+		/* Set the ClearColor and clear the buffers */
+		glClearColor(0.f, 0.f ,0.f, 0.f);
+
+		if ( i_stereoMode == STEREO_MODE_QUADBUFFER )
+		{
+			glDrawBuffer(GL_BACK_LEFT);
+			glClear(GL_COLOR_BUFFER_BIT);
+			glDrawBuffer(GL_BACK_RIGHT);
+		}
+		else /* anaglyphic, horizontal & vertical split methods */
+		{
+			glDrawBuffer(GL_BACK);
+		}
+		glClear(GL_COLOR_BUFFER_BIT);
+
+
+		/* Set the base colour */
+		if ( i_stereoMode == STEREO_MODE_ANAGLYPH ) {
+			glDisable(GL_BLEND);
+			glDisable(GL_TEXTURE_2D);
+			glColor4f(0.0f, 0.0f, 0.0f, 1.0f);
+		}
+		else
+		{
+			glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+		}
+
+
+ 		/* Draw the left eye */
+		{
+			if ( i_stereoMode == STEREO_MODE_QUADBUFFER )
+			{
+				glDrawBuffer(GL_BACK_LEFT);
+			}
+
+			if ( i_stereoMode == STEREO_MODE_ANAGLYPH )
+			{
+				glEnable(GL_BLEND);
+				glEnable(GL_TEXTURE_2D);
+
+				glColor3fv(f_anaglyphColourLeft);
+			}
+
+			glBegin(GL_POLYGON);
+
+			if ( b_stereoInvert )  /* If we want to swap eyes for some reason */
+			{
+				glTexCoord2f(( f_width_right / f_horizAspect ), f_y_right);
+				glVertex2f( -1.0,  1.0 );
+				glTexCoord2f( f_width_right, f_y_right);
+				glVertex2f( 1.0,  1.0 );
+				glTexCoord2f( f_width_right, ( f_height_right / f_vertAspect ));
+				glVertex2f( 1.0, -1.0 );
+				glTexCoord2f(( f_width_right / f_horizAspect ),
+						( f_height_right / f_vertAspect ));
+				glVertex2f( -1.0, -1.0 );
+			}
+			else
+			{
+				glTexCoord2f( f_x_left, f_y_left );
+				glVertex2f( -1.0,  1.0 );
+				glTexCoord2f(( f_width_left / f_horizAspect ), f_y_left );
+				glVertex2f( 1.0,  1.0);
+				glTexCoord2f(( f_width_left / f_horizAspect ),
+						( f_height_left / f_vertAspect ));
+				glVertex2f( 1.0, -1.0 );
+				glTexCoord2f( f_x_left, ( f_height_left / f_vertAspect ));
+				glVertex2f( -1.0, -1.0 );
+			}
+
+			glEnd();
+        }
 
-    glBegin(GL_POLYGON);
-    glTexCoord2f(f_x,      f_y);      glVertex2f(-1.0,  1.0);
-    glTexCoord2f(f_width,  f_y);      glVertex2f( 1.0,  1.0);
-    glTexCoord2f(f_width,  f_height); glVertex2f( 1.0, -1.0);
-    glTexCoord2f(f_x,      f_height); glVertex2f(-1.0, -1.0);
-    glEnd();
+		/* Draw the right eye
+		 * but only if side-by-side or above-below source format */
+		if ( i_stereoFormat != STEREO_FORMAT_SEPARATED )
+		{
+			if ( i_stereoMode == STEREO_MODE_QUADBUFFER )
+			{
+				glDrawBuffer(GL_BACK_RIGHT);
+			}
+
+			if ( i_stereoMode == STEREO_MODE_ANAGLYPH )
+			{
+				glEnable(GL_BLEND);
+				glEnable(GL_TEXTURE_2D);
+
+				glColor3fv(f_anaglyphColourRight);
+			}
+
+
+			glBegin(GL_POLYGON);
+
+			if ( b_stereoInvert ) /* If we want to swap eyes for some reason */
+			{
+				glTexCoord2f( f_x_left, f_y_left );
+				glVertex2f( -1.0,  1.0 );
+				glTexCoord2f(( f_width_left / f_horizAspect ), f_y_left );
+				glVertex2f( 1.0,  1.0 );
+				glTexCoord2f(( f_width_left / f_horizAspect ),
+						( f_height_left / f_vertAspect ));
+				glVertex2f( 1.0, -1.0 );
+				glTexCoord2f( f_x_left, ( f_height_left / f_vertAspect ));
+				glVertex2f( -1.0, -1.0 );
+			}
+			else
+			{
+				glTexCoord2f(( f_width_right / f_horizAspect ), f_y_right );
+				glVertex2f( -1.0,  1.0 );
+				glTexCoord2f( f_width_right, f_y_right );
+				glVertex2f( 1.0,  1.0 );
+				glTexCoord2f( f_width_right, ( f_height_right / f_vertAspect ));
+				glVertex2f( 1.0, -1.0 );
+				glTexCoord2f(( f_width_right / f_horizAspect ),
+						( f_height_right / f_vertAspect ));
+				glVertex2f( -1.0, -1.0 );
+			}
+
+			glEnd();
+        }
+    }
+    else /* original non stereoscopic mode */
+    {
+		f_x_left      = (source->i_x_offset +                       0 ) / ( f_normw );
+		f_y_left      = (source->i_y_offset +                       0 ) / ( f_normh );
+		f_width_left  = (source->i_x_offset + source->i_visible_width)  / ( f_normw );
+		f_height_left = (source->i_y_offset + source->i_visible_height) / ( f_normh );
+
+	   /* Why drawing here and not in Render()? Because this way, the
+		  OpenGL providers can call vout_display_opengl_Display to force redraw.i
+		  Currently, the OS X provider uses it to get a smooth window resizing */
+
+	    glClear(GL_COLOR_BUFFER_BIT);
+
+	    glEnable(VLCGL_TARGET);
+
+        glBegin(GL_POLYGON);
+        glTexCoord2f(f_x_left,      f_y_left);      glVertex2f(-1.0,  1.0);
+        glTexCoord2f(f_width_left,  f_y_left);      glVertex2f( 1.0,  1.0);
+        glTexCoord2f(f_width_left,  f_height_left); glVertex2f( 1.0, -1.0);
+        glTexCoord2f(f_x_left,      f_height_left); glVertex2f(-1.0, -1.0);
+        glEnd();
+    }
 
     glDisable(VLCGL_TARGET);
 
     vout_opengl_Swap(vgl->gl);
 
     vout_opengl_Unlock(vgl->gl);
+
     return VLC_SUCCESS;
 }
 
-- 
1.7.4



