Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
538865a6
Commit
538865a6
authored
Dec 20, 2012
by
Laurent Aimar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reorganized shader/program building (opengl).
parent
a910b4e7
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
174 additions
and
130 deletions
+174
-130
modules/video_output/opengl.c
modules/video_output/opengl.c
+174
-130
No files found.
modules/video_output/opengl.c
View file @
538865a6
...
...
@@ -204,6 +204,133 @@ static bool IsLuminance16Supported(int target)
}
#endif
static
void
BuildVertexShader
(
vout_display_opengl_t
*
vgl
,
GLint
*
shader
)
{
/* Basic vertex shader */
const
char
*
vertexShader
=
"#version 120
\n
"
"varying vec4 TexCoord0,TexCoord1, TexCoord2;"
"attribute vec4 MultiTexCoord0,MultiTexCoord1,MultiTexCoord2;"
"attribute vec4 vertex_position;"
"void main() {"
" TexCoord0 = MultiTexCoord0;"
" TexCoord1 = MultiTexCoord1;"
" TexCoord2 = MultiTexCoord2;"
" gl_Position = vertex_position;"
"}"
;
*
shader
=
vgl
->
CreateShader
(
GL_VERTEX_SHADER
);
vgl
->
ShaderSource
(
*
shader
,
1
,
&
vertexShader
,
NULL
);
vgl
->
CompileShader
(
*
shader
);
}
static
void
BuildYUVFragmentShader
(
vout_display_opengl_t
*
vgl
,
GLint
*
shader
,
int
*
local_count
,
GLfloat
*
local_value
,
const
video_format_t
*
fmt
,
float
yuv_range_correction
)
{
/* [R/G/B][Y U V O] from TV range to full range
* XXX we could also do hue/brightness/constrast/gamma
* by simply changing the coefficients
*/
const
float
matrix_bt601_tv2full
[
12
]
=
{
1
.
164383561643836
,
0
.
0000
,
1
.
596026785714286
,
-
0
.
874202217873451
,
1
.
164383561643836
,
-
0
.
391762290094914
,
-
0
.
812967647237771
,
0
.
531667823499146
,
1
.
164383561643836
,
2
.
017232142
857142
,
0
.
0000
,
-
1
.
085630789302022
,
};
const
float
matrix_bt709_tv2full
[
12
]
=
{
1
.
164383561643836
,
0
.
0000
,
1
.
792741071428571
,
-
0
.
972945075016308
,
1
.
164383561643836
,
-
0
.
21324861427373
,
-
0
.
532909328559444
,
0
.
301482665475862
,
1
.
164383561643836
,
2
.
112401785714286
,
0
.
0000
,
-
1
.
133402217873451
,
};
const
float
(
*
matrix
)
=
fmt
->
i_height
>
576
?
matrix_bt709_tv2full
:
matrix_bt601_tv2full
;
/* Basic linear YUV -> RGB conversion using bilinear interpolation */
const
char
*
template_glsl_yuv
=
"#version 120
\n
"
"uniform sampler2D Texture[3];"
"uniform vec4 coefficient[4];"
"varying vec4 TexCoord0,TexCoord1,TexCoord2;"
"void main(void) {"
" vec4 x,y,z,result;"
" x = texture2D(Texture[0], TexCoord0.st);"
" %c = texture2D(Texture[1], TexCoord1.st);"
" %c = texture2D(Texture[2], TexCoord2.st);"
" result = x * coefficient[0] + coefficient[3];"
" result = (y * coefficient[1]) + result;"
" result = (z * coefficient[2]) + result;"
" gl_FragColor = result;"
"}"
;
bool
swap_uv
=
fmt
->
i_chroma
==
VLC_CODEC_YV12
||
fmt
->
i_chroma
==
VLC_CODEC_YV9
;
char
*
code
;
if
(
asprintf
(
&
code
,
template_glsl_yuv
,
swap_uv
?
'z'
:
'y'
,
swap_uv
?
'y'
:
'z'
)
<
0
)
code
=
NULL
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
correction
=
i
<
3
?
yuv_range_correction
:
1
.
0
;
/* We place coefficient values for coefficient[4] in one array from matrix values.
Notice that we fill values from top down instead of left to right.*/
for
(
int
j
=
0
;
j
<
4
;
j
++
)
local_value
[
*
local_count
+
i
*
4
+
j
]
=
j
<
3
?
correction
*
matrix
[
j
*
4
+
i
]
:
0
.
0
;
}
(
*
local_count
)
+=
4
;
*
shader
=
vgl
->
CreateShader
(
GL_FRAGMENT_SHADER
);
vgl
->
ShaderSource
(
*
shader
,
1
,
(
const
char
**
)
&
code
,
NULL
);
vgl
->
CompileShader
(
*
shader
);
free
(
code
);
}
static
void
BuildRGBFragmentShader
(
vout_display_opengl_t
*
vgl
,
GLint
*
shader
)
{
// Simple shader for RGB
const
char
*
code
=
"#version 120
\n
"
"uniform sampler2D Texture[3];"
"uniform vec4 fillColor;"
"varying vec4 TexCoord0,TexCoord1,TexCoord2;"
"void main()"
"{ "
" gl_FragColor = texture2D(Texture[0], TexCoord0.st)*fillColor;"
"}"
;
*
shader
=
vgl
->
CreateShader
(
GL_FRAGMENT_SHADER
);
vgl
->
ShaderSource
(
*
shader
,
1
,
&
code
,
NULL
);
vgl
->
CompileShader
(
*
shader
);
}
static
void
BuildRGBAFragmentShader
(
vout_display_opengl_t
*
vgl
,
GLint
*
shader
)
{
// Simple shader for RGBA
const
char
*
code
=
"#version 120
\n
"
"uniform sampler2D Texture[3];"
"uniform vec4 fillColor;"
"varying vec4 TexCoord0,TexCoord1,TexCoord2;"
"void main()"
"{ "
" gl_FragColor = texture2D(Texture[0], TexCoord0.st)*fillColor;"
"}"
;
*
shader
=
vgl
->
CreateShader
(
GL_FRAGMENT_SHADER
);
vgl
->
ShaderSource
(
*
shader
,
1
,
&
code
,
NULL
);
vgl
->
CompileShader
(
*
shader
);
}
vout_display_opengl_t
*
vout_display_opengl_New
(
video_format_t
*
fmt
,
const
vlc_fourcc_t
**
subpicture_chromas
,
vlc_gl_t
*
gl
)
...
...
@@ -344,150 +471,67 @@ vout_display_opengl_t *vout_display_opengl_New(video_format_t *fmt,
}
}
/* Build
fragment
program if needed */
vgl
->
program
[
0
]
=
0
;
/* Build program if needed */
vgl
->
program
[
0
]
=
vgl
->
program
[
1
]
=
0
;
vgl
->
shader
[
0
]
=
vgl
->
shader
[
1
]
=
vgl
->
shader
[
2
]
=
-
1
;
vgl
->
local_count
=
0
;
vgl
->
shader
[
0
]
=
vgl
->
shader
[
1
]
=
vgl
->
shader
[
2
]
=
-
1
;
if
(
supports_shaders
)
{
char
*
code
=
NULL
;
/* [R/G/B][Y U V O] from TV range to full range
* XXX we could also do hue/brightness/constrast/gamma
* by simply changing the coefficients
*/
const
float
matrix_bt601_tv2full
[
12
]
=
{
1
.
164383561643836
,
0
.
0000
,
1
.
596026785714286
,
-
0
.
874202217873451
,
1
.
164383561643836
,
-
0
.
391762290094914
,
-
0
.
812967647237771
,
0
.
531667823499146
,
1
.
164383561643836
,
2
.
017232142
857142
,
0
.
0000
,
-
1
.
085630789302022
,
};
const
float
matrix_bt709_tv2full
[
12
]
=
{
1
.
164383561643836
,
0
.
0000
,
1
.
792741071428571
,
-
0
.
972945075016308
,
1
.
164383561643836
,
-
0
.
21324861427373
,
-
0
.
532909328559444
,
0
.
301482665475862
,
1
.
164383561643836
,
2
.
112401785714286
,
0
.
0000
,
-
1
.
133402217873451
,
};
const
float
(
*
matrix
)
=
fmt
->
i_height
>
576
?
matrix_bt709_tv2full
:
matrix_bt601_tv2full
;
/* Basic linear YUV -> RGB conversion using bilinear interpolation */
const
char
*
template_glsl_yuv
=
"#version 120
\n
"
"uniform sampler2D Texture[3];"
"uniform vec4 coefficient[4];"
"varying vec4 TexCoord0,TexCoord1,TexCoord2;"
"void main(void) {"
" vec4 x,y,z,result;"
" x = texture2D(Texture[0], TexCoord0.st);"
" %c = texture2D(Texture[1], TexCoord1.st);"
" %c = texture2D(Texture[2], TexCoord2.st);"
" result = x * coefficient[0] + coefficient[3];"
" result = (y * coefficient[1]) + result;"
" result = (z * coefficient[2]) + result;"
" gl_FragColor = result;"
"}"
;
bool
swap_uv
=
vgl
->
fmt
.
i_chroma
==
VLC_CODEC_YV12
||
vgl
->
fmt
.
i_chroma
==
VLC_CODEC_YV9
;
if
(
asprintf
(
&
code
,
template_glsl_yuv
,
swap_uv
?
'z'
:
'y'
,
swap_uv
?
'y'
:
'z'
)
<
0
)
code
=
NULL
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
{
float
correction
=
i
<
3
?
yuv_range_correction
:
1
.
0
;
/* We place coefficient values for coefficient[4] in one array from matrix values.
Notice that we fill values from top down instead of left to right.*/
for
(
int
j
=
0
;
j
<
4
;
j
++
)
vgl
->
local_value
[
vgl
->
local_count
+
i
*
4
+
j
]
=
j
<
3
?
correction
*
matrix
[
j
*
4
+
i
]
:
0
.
0
;
if
(
need_fs_yuv
)
BuildYUVFragmentShader
(
vgl
,
&
vgl
->
shader
[
0
],
&
vgl
->
local_count
,
vgl
->
local_value
,
fmt
,
yuv_range_correction
);
else
BuildRGBFragmentShader
(
vgl
,
&
vgl
->
shader
[
0
]);
BuildRGBAFragmentShader
(
vgl
,
&
vgl
->
shader
[
1
]);
BuildVertexShader
(
vgl
,
&
vgl
->
shader
[
2
]);
/* Check shaders messages */
for
(
unsigned
j
=
0
;
j
<
3
;
j
++
)
{
int
infoLength
;
vgl
->
GetShaderiv
(
vgl
->
shader
[
j
],
GL_INFO_LOG_LENGTH
,
&
infoLength
);
if
(
infoLength
<=
1
)
continue
;
char
*
infolog
=
malloc
(
infoLength
);
int
charsWritten
;
vgl
->
GetShaderInfoLog
(
vgl
->
shader
[
j
],
infoLength
,
&
charsWritten
,
infolog
);
fprintf
(
stderr
,
"shader %d: %s
\n
"
,
j
,
infolog
);
free
(
infolog
);
}
vgl
->
local_count
+=
4
;
// Basic vertex shader that we use in both cases
const
char
*
vertexShader
=
"#version 120
\n
"
"varying vec4 TexCoord0,TexCoord1, TexCoord2;"
"attribute vec4 MultiTexCoord0,MultiTexCoord1,MultiTexCoord2;"
"attribute vec4 vertex_position;"
"void main() {"
" TexCoord0 = MultiTexCoord0;"
" TexCoord1 = MultiTexCoord1;"
" TexCoord2 = MultiTexCoord2;"
" gl_Position = vertex_position;"
"}"
;
// Dummy shader for text overlay
const
char
*
helloShader
=
"#version 120
\n
"
"uniform sampler2D Texture[3];"
"uniform vec4 fillColor;"
"varying vec4 TexCoord0,TexCoord1,TexCoord2;"
"void main()"
"{ "
" gl_FragColor = texture2D(Texture[0], TexCoord0.st)*fillColor;"
"}"
;
vgl
->
shader
[
2
]
=
vgl
->
CreateShader
(
GL_VERTEX_SHADER
);
vgl
->
ShaderSource
(
vgl
->
shader
[
2
],
1
,
(
const
GLchar
**
)
&
vertexShader
,
NULL
);
vgl
->
CompileShader
(
vgl
->
shader
[
2
]);
vgl
->
program
[
0
]
=
vgl
->
CreateProgram
();
vgl
->
AttachShader
(
vgl
->
program
[
0
],
vgl
->
shader
[
0
]);
vgl
->
AttachShader
(
vgl
->
program
[
0
],
vgl
->
shader
[
2
]);
vgl
->
LinkProgram
(
vgl
->
program
[
0
]);
/* Create 'dummy' shader that handles subpicture overlay for now*/
vgl
->
shader
[
1
]
=
vgl
->
CreateShader
(
GL_FRAGMENT_SHADER
);
vgl
->
ShaderSource
(
vgl
->
shader
[
1
],
1
,
&
helloShader
,
NULL
);
vgl
->
CompileShader
(
vgl
->
shader
[
1
]);
vgl
->
program
[
1
]
=
vgl
->
CreateProgram
();
vgl
->
AttachShader
(
vgl
->
program
[
1
],
vgl
->
shader
[
1
]);
vgl
->
AttachShader
(
vgl
->
program
[
1
],
vgl
->
shader
[
2
]);
vgl
->
LinkProgram
(
vgl
->
program
[
1
]);
// Create shader from code
vgl
->
shader
[
0
]
=
vgl
->
CreateShader
(
GL_FRAGMENT_SHADER
);
vgl
->
program
[
0
]
=
vgl
->
CreateProgram
();
if
(
need_fs_yuv
)
{
vgl
->
ShaderSource
(
vgl
->
shader
[
0
],
1
,
(
const
GLchar
**
)
&
code
,
NULL
);
vgl
->
CompileShader
(
vgl
->
shader
[
0
]);
vgl
->
AttachShader
(
vgl
->
program
[
0
],
vgl
->
shader
[
0
]);
}
else
{
/* Use simpler shader if we don't need to to yuv -> rgb,
for example when input is allready rgb (.bmp image).*/
vgl
->
AttachShader
(
vgl
->
program
[
0
],
vgl
->
shader
[
1
]);
}
vgl
->
AttachShader
(
vgl
->
program
[
0
],
vgl
->
shader
[
2
]);
vgl
->
LinkProgram
(
vgl
->
program
[
0
]);
free
(
code
);
/* Check program messages */
for
(
GLuint
i
=
0
;
i
<
2
;
i
++
)
{
int
infoLength
=
0
;
vgl
->
GetProgramiv
(
vgl
->
program
[
i
],
GL_INFO_LOG_LENGTH
,
&
infoLength
);
if
(
infoLength
>
1
)
{
int
charsWritten
;
char
*
infolog
;
infolog
=
malloc
(
infoLength
);
vgl
->
GetProgramInfoLog
(
vgl
->
program
[
i
],
infoLength
,
&
charsWritten
,
infolog
);
fprintf
(
stderr
,
"shader program %d: %s
\n
"
,
i
,
infolog
);
free
(
infolog
);
/* Check shaders messages too */
for
(
GLuint
j
=
0
;
j
<
2
;
j
++
)
{
vgl
->
GetShaderiv
(
vgl
->
shader
[
j
],
GL_INFO_LOG_LENGTH
,
&
infoLength
);
if
(
infoLength
>
1
)
{
infolog
=
malloc
(
infoLength
);
vgl
->
GetShaderInfoLog
(
vgl
->
shader
[
j
],
infoLength
,
&
charsWritten
,
infolog
);
fprintf
(
stderr
,
"shader %d: %s
\n
"
,
j
,
infolog
);
free
(
infolog
);
}
}
/* If there is some message, better to check linking is ok */
GLint
link_status
=
GL_TRUE
;
vgl
->
GetProgramiv
(
vgl
->
program
[
i
],
GL_LINK_STATUS
,
&
link_status
);
if
(
link_status
==
GL_FALSE
)
{
fprintf
(
stderr
,
"Unable to use program %d
\n
"
,
i
);
free
(
vgl
);
return
NULL
;
}
if
(
infoLength
<=
1
)
continue
;
char
*
infolog
=
malloc
(
infoLength
);
int
charsWritten
;
vgl
->
GetProgramInfoLog
(
vgl
->
program
[
i
],
infoLength
,
&
charsWritten
,
infolog
);
fprintf
(
stderr
,
"shader program %d: %s
\n
"
,
i
,
infolog
);
free
(
infolog
);
/* If there is some message, better to check linking is ok */
GLint
link_status
=
GL_TRUE
;
vgl
->
GetProgramiv
(
vgl
->
program
[
i
],
GL_LINK_STATUS
,
&
link_status
);
if
(
link_status
==
GL_FALSE
)
{
fprintf
(
stderr
,
"Unable to use program %d
\n
"
,
i
);
free
(
vgl
);
return
NULL
;
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment