~ubuntu-branches/ubuntu/vivid/bino/vivid-proposed

« back to all changes in this revision

Viewing changes to src/video_output_render.fs.glsl

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Schaal
  • Date: 2011-09-09 14:23:54 UTC
  • Revision ID: james.westby@ubuntu.com-20110909142354-m1a9a4523i7ddb02
Tags: upstream-1.2.0
ImportĀ upstreamĀ versionĀ 1.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of bino, a 3D video player.
 
3
 *
 
4
 * Copyright (C) 2010-2011
 
5
 * Martin Lambers <marlam@marlam.de>
 
6
 * FrĆ©dĆ©ric Devernay <Frederic.Devernay@inrialpes.fr>
 
7
 *
 
8
 * This program is free software; you can redistribute it and/or modify
 
9
 * it under the terms of the GNU General Public License as published by
 
10
 * the Free Software Foundation; either version 3 of the License, or
 
11
 * (at your option) any later version.
 
12
 *
 
13
 * This program is distributed in the hope that it will be useful,
 
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
 * GNU General Public License for more details.
 
17
 *
 
18
 * You should have received a copy of the GNU General Public License
 
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
#version 120
 
23
 
 
24
// mode_onechannel
 
25
// mode_red_cyan_monochrome
 
26
// mode_red_cyan_half_color
 
27
// mode_red_cyan_full_color
 
28
// mode_red_cyan_dubois
 
29
// mode_green_magenta_monochrome
 
30
// mode_green_magenta_half_color
 
31
// mode_green_magenta_full_color
 
32
// mode_green_magenta_dubois
 
33
// mode_amber_blue_monochrome
 
34
// mode_amber_blue_half_color
 
35
// mode_amber_blue_full_color
 
36
// mode_amber_blue_dubois
 
37
// mode_red_green_monochrome
 
38
// mode_red_blue_monochrome
 
39
// mode_even_odd_rows
 
40
// mode_even_odd_columns
 
41
// mode_checkerboard
 
42
#define $mode
 
43
 
 
44
uniform sampler2D rgb_l;
 
45
uniform sampler2D rgb_r;
 
46
uniform float parallax;
 
47
 
 
48
uniform sampler2D subtitle;
 
49
uniform float subtitle_parallax;
 
50
 
 
51
#if defined(mode_onechannel)
 
52
uniform float channel;  // 0.0 for left, 1.0 for right
 
53
#endif
 
54
 
 
55
#if defined(mode_even_odd_rows) || defined(mode_even_odd_columns) || defined(mode_checkerboard)
 
56
uniform sampler2D mask_tex;
 
57
uniform float step_x;
 
58
uniform float step_y;
 
59
#endif
 
60
 
 
61
#if defined(mode_onechannel) || defined(mode_even_odd_rows) || defined(mode_even_odd_columns) || defined(mode_checkerboard)
 
62
uniform vec3 crosstalk;
 
63
#endif
 
64
 
 
65
#if defined(mode_red_cyan_monochrome) || defined(mode_red_cyan_half_color) || defined(mode_green_magenta_monochrome) || defined(mode_green_magenta_half_color) || defined(mode_amber_blue_monochrome) || defined(mode_amber_blue_half_color) || defined(mode_red_green_monochrome) || defined(mode_red_blue_monochrome)
 
66
float srgb_to_lum(vec3 srgb)
 
67
{
 
68
    // Values taken from http://www.fourcc.org/fccyvrgb.php
 
69
    return dot(srgb, vec3(0.299, 0.587, 0.114));
 
70
}
 
71
#endif
 
72
 
 
73
float linear_to_nonlinear(float x)
 
74
{
 
75
    return (x <= 0.0031308 ? (x * 12.92) : (1.055 * pow(x, 1.0 / 2.4) - 0.055));
 
76
}
 
77
 
 
78
vec3 rgb_to_srgb(vec3 rgb)
 
79
{
 
80
#if $srgb_broken
 
81
    return rgb;
 
82
#else
 
83
# if 1
 
84
    // Correct variant, see GL_ARB_framebuffer_sRGB extension
 
85
    float sr = linear_to_nonlinear(rgb.r);
 
86
    float sg = linear_to_nonlinear(rgb.g);
 
87
    float sb = linear_to_nonlinear(rgb.b);
 
88
    return vec3(sr, sg, sb);
 
89
# endif
 
90
# if 0
 
91
    // Faster variant
 
92
    return pow(rgb, 1.0 / 2.2);
 
93
# endif
 
94
# if 0
 
95
    // Even faster variant, assuming gamma = 2.0
 
96
    return sqrt(rgb);
 
97
# endif
 
98
#endif
 
99
}
 
100
 
 
101
#if defined(mode_onechannel) || defined(mode_even_odd_rows) || defined(mode_even_odd_columns) || defined(mode_checkerboard)
 
102
vec3 ghostbust(vec3 original, vec3 other)
 
103
{
 
104
    return original + crosstalk - (other + original) * crosstalk;
 
105
}
 
106
#endif
 
107
 
 
108
vec3 tex_l(vec2 texcoord)
 
109
{
 
110
    return texture2D(rgb_l, texcoord + vec2(parallax, 0.0)).rgb;
 
111
}
 
112
 
 
113
vec3 tex_r(vec2 texcoord)
 
114
{
 
115
    return texture2D(rgb_r, texcoord - vec2(parallax, 0.0)).rgb;
 
116
}
 
117
 
 
118
vec4 sub_l(vec2 texcoord)
 
119
{
 
120
    return texture2D(subtitle, vec2(texcoord.x + subtitle_parallax, 1.0 - texcoord.y));
 
121
}
 
122
 
 
123
vec4 sub_r(vec2 texcoord)
 
124
{
 
125
    return texture2D(subtitle, vec2(texcoord.x - subtitle_parallax, 1.0 - texcoord.y));
 
126
}
 
127
 
 
128
vec3 blend_subtitle(vec3 rgb, vec4 sub)
 
129
{
 
130
    return mix(rgb, sub.rgb, sub.a);
 
131
}
 
132
 
 
133
void main()
 
134
{
 
135
    vec3 srgb;
 
136
 
 
137
#if defined(mode_onechannel)
 
138
 
 
139
    vec3 l = blend_subtitle(tex_l(gl_TexCoord[0].xy), sub_l(gl_TexCoord[0].xy));
 
140
    vec3 r = blend_subtitle(tex_r(gl_TexCoord[1].xy), sub_r(gl_TexCoord[1].xy));
 
141
    srgb = rgb_to_srgb(ghostbust(mix(l, r, channel), mix(r, l, channel)));
 
142
 
 
143
#elif defined(mode_even_odd_rows) || defined(mode_even_odd_columns) || defined(mode_checkerboard)
 
144
 
 
145
    /* This implementation of the masked modes works around many different problems and therefore may seem strange.
 
146
     * Why not use stencil buffers?
 
147
     *  - Because we want to filter, to account for masked out features
 
148
     *  - Because stencil did not work with some drivers when switching fullscreen on/off
 
149
     * Why not use polygon stipple?
 
150
     *  - Because we want to filter, to account for masked out features
 
151
     *  - Because polygon stippling may not be hardware accelerated and is currently broken with many free drivers
 
152
     * Why use a mask texture? Why not use the mod() function to check for even/odd pixels?
 
153
     *  - Because mod() is broken with many drivers, and I found no reliable way to work around it. Some
 
154
     *    drivers seem to use extremely low precision arithmetic in the shaders; too low for reliable pixel
 
155
     *    position computations.
 
156
     */
 
157
    float m = texture2D(mask_tex, gl_TexCoord[2].xy).x;
 
158
# if defined(mode_even_odd_rows)
 
159
    vec3 rgb0_l = tex_l(gl_TexCoord[0].xy - vec2(0.0, step_y));
 
160
    vec3 rgb1_l = tex_l(gl_TexCoord[0].xy);
 
161
    vec3 rgb2_l = tex_l(gl_TexCoord[0].xy + vec2(0.0, step_y));
 
162
    vec3 rgbc_l = (rgb0_l + 2.0 * rgb1_l + rgb2_l) / 4.0;
 
163
    vec3 rgb0_r = tex_r(gl_TexCoord[1].xy - vec2(0.0, step_y));
 
164
    vec3 rgb1_r = tex_r(gl_TexCoord[1].xy);
 
165
    vec3 rgb2_r = tex_r(gl_TexCoord[1].xy + vec2(0.0, step_y));
 
166
    vec3 rgbc_r = (rgb0_r + 2.0 * rgb1_r + rgb2_r) / 4.0;
 
167
# elif defined(mode_even_odd_columns)
 
168
    vec3 rgb0_l = tex_l(gl_TexCoord[0].xy - vec2(step_x, 0.0));
 
169
    vec3 rgb1_l = tex_l(gl_TexCoord[0].xy);
 
170
    vec3 rgb2_l = tex_l(gl_TexCoord[0].xy + vec2(step_x, 0.0));
 
171
    vec3 rgbc_l = (rgb0_l + 2.0 * rgb1_l + rgb2_l) / 4.0;
 
172
    vec3 rgb0_r = tex_r(gl_TexCoord[1].xy - vec2(step_x, 0.0));
 
173
    vec3 rgb1_r = tex_r(gl_TexCoord[1].xy);
 
174
    vec3 rgb2_r = tex_r(gl_TexCoord[1].xy + vec2(step_x, 0.0));
 
175
    vec3 rgbc_r = (rgb0_r + 2.0 * rgb1_r + rgb2_r) / 4.0;
 
176
# elif defined(mode_checkerboard)
 
177
    vec3 rgb0_l = tex_l(gl_TexCoord[0].xy - vec2(0.0, step_y));
 
178
    vec3 rgb1_l = tex_l(gl_TexCoord[0].xy - vec2(step_x, 0.0));
 
179
    vec3 rgb2_l = tex_l(gl_TexCoord[0].xy);
 
180
    vec3 rgb3_l = tex_l(gl_TexCoord[0].xy + vec2(step_x, 0.0));
 
181
    vec3 rgb4_l = tex_l(gl_TexCoord[0].xy + vec2(0.0, step_y));
 
182
    vec3 rgbc_l = (rgb0_l + rgb1_l + 4.0 * rgb2_l + rgb3_l + rgb4_l) / 8.0;
 
183
    vec3 rgb0_r = tex_r(gl_TexCoord[1].xy - vec2(0.0, step_y));
 
184
    vec3 rgb1_r = tex_r(gl_TexCoord[1].xy - vec2(step_x, 0.0));
 
185
    vec3 rgb2_r = tex_r(gl_TexCoord[1].xy);
 
186
    vec3 rgb3_r = tex_r(gl_TexCoord[1].xy + vec2(step_x, 0.0));
 
187
    vec3 rgb4_r = tex_r(gl_TexCoord[1].xy + vec2(0.0, step_y));
 
188
    vec3 rgbc_r = (rgb0_r + rgb1_r + 4.0 * rgb2_r + rgb3_r + rgb4_r) / 8.0;
 
189
# endif
 
190
    vec3 rgbcs_l = blend_subtitle(rgbc_l, sub_l(gl_TexCoord[0].xy));
 
191
    vec3 rgbcs_r = blend_subtitle(rgbc_r, sub_r(gl_TexCoord[1].xy));
 
192
    srgb = rgb_to_srgb(ghostbust(mix(rgbcs_r, rgbcs_l, m), mix(rgbcs_l, rgbcs_r, m)));
 
193
 
 
194
#elif defined(mode_red_cyan_dubois) || defined(mode_green_magenta_dubois) || defined(mode_amber_blue_dubois)
 
195
 
 
196
    // The Dubois anaglyph method is generally the highest quality anaglyph method.
 
197
    // Authors page: http://www.site.uottawa.ca/~edubois/anaglyph/
 
198
    // This method depends on the characteristics of the display device and the anaglyph glasses.
 
199
    // According to the author, the matrices below are intended to be applied to linear RGB values,
 
200
    // and are designed for CRT displays.
 
201
    vec3 l = blend_subtitle(tex_l(gl_TexCoord[0].xy), sub_l(gl_TexCoord[0].xy));
 
202
    vec3 r = blend_subtitle(tex_r(gl_TexCoord[1].xy), sub_r(gl_TexCoord[1].xy));
 
203
# if defined(mode_red_cyan_dubois)
 
204
    // Source of this matrix: http://www.site.uottawa.ca/~edubois/anaglyph/LeastSquaresHowToPhotoshop.pdf
 
205
    mat3 m0 = mat3(
 
206
             0.437, -0.062, -0.048,
 
207
             0.449, -0.062, -0.050,
 
208
             0.164, -0.024, -0.017);
 
209
    mat3 m1 = mat3(
 
210
            -0.011,  0.377, -0.026,
 
211
            -0.032,  0.761, -0.093,
 
212
            -0.007,  0.009,  1.234);
 
213
# elif defined(mode_green_magenta_dubois)
 
214
    // Source of this matrix: http://www.flickr.com/photos/e_dubois/5132528166/
 
215
    mat3 m0 = mat3(
 
216
            -0.062,  0.284, -0.015,
 
217
            -0.158,  0.668, -0.027,
 
218
            -0.039,  0.143,  0.021);
 
219
    mat3 m1 = mat3(
 
220
             0.529, -0.016,  0.009,
 
221
             0.705, -0.015,  0.075,
 
222
             0.024, -0.065,  0.937);
 
223
# elif defined(mode_amber_blue_dubois)
 
224
    // Source of this matrix: http://www.flickr.com/photos/e_dubois/5230654930/
 
225
    mat3 m0 = mat3(
 
226
             1.062, -0.026, -0.038,
 
227
            -0.205,  0.908, -0.173,
 
228
             0.299,  0.068,  0.022);
 
229
    mat3 m1 = mat3(
 
230
            -0.016,  0.006,  0.094,
 
231
            -0.123,  0.062,  0.185,
 
232
            -0.017, -0.017,  0.911);
 
233
# endif
 
234
    srgb = rgb_to_srgb(m0 * l + m1 * r);
 
235
 
 
236
#else // lower quality anaglyph methods
 
237
 
 
238
    vec3 l = rgb_to_srgb(blend_subtitle(tex_l(gl_TexCoord[0].xy), sub_l(gl_TexCoord[0].xy)));
 
239
    vec3 r = rgb_to_srgb(blend_subtitle(tex_r(gl_TexCoord[1].xy), sub_r(gl_TexCoord[1].xy)));
 
240
# if defined(mode_red_cyan_monochrome)
 
241
    srgb = vec3(srgb_to_lum(l), srgb_to_lum(r), srgb_to_lum(r));
 
242
# elif defined(mode_red_cyan_half_color)
 
243
    srgb = vec3(srgb_to_lum(l), r.g, r.b);
 
244
# elif defined(mode_red_cyan_full_color)
 
245
    srgb = vec3(l.r, r.g, r.b);
 
246
# elif defined(mode_green_magenta_monochrome)
 
247
    srgb = vec3(srgb_to_lum(r), srgb_to_lum(l), srgb_to_lum(r));
 
248
# elif defined(mode_green_magenta_half_color)
 
249
    srgb = vec3(r.r, srgb_to_lum(l), r.b);
 
250
# elif defined(mode_green_magenta_full_color)
 
251
    srgb = vec3(r.r, l.g, r.b);
 
252
# elif defined(mode_amber_blue_monochrome)
 
253
    srgb = vec3(srgb_to_lum(l), srgb_to_lum(l), srgb_to_lum(r));
 
254
# elif defined(mode_amber_blue_half_color)
 
255
    srgb = vec3(srgb_to_lum(l), srgb_to_lum(l), r.b);
 
256
# elif defined(mode_amber_blue_full_color)
 
257
    srgb = vec3(l.r, l.g, r.b);
 
258
# elif defined(mode_red_green_monochrome)
 
259
    srgb = vec3(srgb_to_lum(l), srgb_to_lum(r), 0.0);
 
260
# elif defined(mode_red_blue_monochrome)
 
261
    srgb = vec3(srgb_to_lum(l), 0.0, srgb_to_lum(r));
 
262
# endif
 
263
 
 
264
#endif
 
265
 
 
266
    gl_FragColor = vec4(srgb, 1.0);
 
267
}