1
0
mirror of https://github.com/jojo61/vdr-plugin-softhdcuvid.git synced 2023-10-10 13:37:41 +02:00
vdr-plugin-softhdcuvid/shaders.h

466 lines
14 KiB
C
Raw Normal View History

2018-08-19 11:45:46 +02:00
// shader
2019-10-04 10:37:57 +02:00
#ifdef CUVID
char vertex_osd[] = {"\
#version 330\n\
in vec2 vertex_position;\n\
in vec2 vertex_texcoord0;\n\
out vec2 texcoord0;\n\
void main() {\n\
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
texcoord0 = vertex_texcoord0;\n\
}\n"};
2018-08-19 11:45:46 +02:00
2019-10-04 10:37:57 +02:00
char fragment_osd[] = {"\
2018-08-19 11:45:46 +02:00
#version 330\n\
2019-10-04 10:37:57 +02:00
#define texture1D texture\n\
precision mediump float; \
layout(location = 0) out vec4 out_color;\n\
in vec2 texcoord0;\n\
uniform sampler2D texture0;\n\
void main() {\n\
vec4 color; \n\
color = vec4(texture(texture0, texcoord0));\n\
out_color = color;\n\
}\n"};
char vertex[] = {"\
#version 310 es\n\
2018-08-19 11:45:46 +02:00
in vec2 vertex_position;\n\
in vec2 vertex_texcoord0;\n\
out vec2 texcoord0;\n\
in vec2 vertex_texcoord1;\n\
out vec2 texcoord1;\n\
void main() {\n\
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
texcoord0 = vertex_texcoord0;\n\
texcoord1 = vertex_texcoord1;\n\
}\n"};
2019-10-04 10:37:57 +02:00
char fragment[] = {"\
#version 310 es\n\
#define texture1D texture\n\
#define texture3D texture\n\
precision mediump float; \
layout(location = 0) out vec4 out_color;\n\
in vec2 texcoord0;\n\
in vec2 texcoord1;\n\
uniform mat3 colormatrix;\n\
uniform vec3 colormatrix_c;\n\
uniform sampler2D texture0;\n\
uniform sampler2D texture1;\n\
void main() {\n\
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
color.r = 1.000000 * vec4(texture(texture0, texcoord0)).r;\n\
color.gb = 1.000000 * vec4(texture(texture1, texcoord1)).rg;\n\
// color conversion\n\
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
color.a = 1.0;\n\
// color mapping\n\
out_color = color;\n\
}\n"};
char fragment_bt2100[] = {"\
#version 310 es\n \
#define texture1D texture\n\
#define texture3D texture\n\
precision mediump float; \
layout(location = 0) out vec4 out_color;\n\
in vec2 texcoord0;\n\
in vec2 texcoord1;\n\
uniform mat3 colormatrix;\n\
uniform vec3 colormatrix_c;\n\
uniform mat3 cms_matrix;\n\
uniform sampler2D texture0;\n\
uniform sampler2D texture1;\n\
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
void main() {\n\
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
color.r = 1.003906 * vec4(texture(texture0, texcoord0)).r;\n\
color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n\
// color conversion\n\
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
color.a = 1.0;\n\
// color mapping\n\
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
color.rgb = pow(color.rgb, vec3(2.4));\n\
color.rgb = cms_matrix * color.rgb;\n\
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
color.rgb = pow(color.rgb, vec3(1.0/2.4));\n\
out_color = color;\n\
}\n"};
#else
char vertex_osd[] = {"\
\n\
in vec2 vertex_position;\n\
in vec2 vertex_texcoord0;\n\
out vec2 texcoord0;\n\
void main() {\n\
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
texcoord0 = vertex_texcoord0;\n\
}\n"};
char fragment_osd[] = {"\
\n\
#define texture1D texture\n\
precision mediump float; \
layout(location = 0) out vec4 out_color;\n\
in vec2 texcoord0;\n\
uniform sampler2D texture0;\n\
void main() {\n\
vec4 color; \n\
color = vec4(texture(texture0, texcoord0));\n\
out_color = color;\n\
}\n"};
char vertex[] = {"\
\n\
in vec2 vertex_position;\n\
in vec2 vertex_texcoord0;\n\
out vec2 texcoord0;\n\
in vec2 vertex_texcoord1;\n\
out vec2 texcoord1;\n\
void main() {\n\
gl_Position = vec4(vertex_position, 1.0, 1.0);\n\
texcoord0 = vertex_texcoord0;\n\
texcoord1 = vertex_texcoord1;\n\
}\n"};
2018-08-19 11:45:46 +02:00
char fragment[] = {"\
2019-10-04 10:37:57 +02:00
\n\
2018-08-19 11:45:46 +02:00
#define texture1D texture\n\
#define texture3D texture\n\
2019-10-04 10:37:57 +02:00
precision mediump float; \
2018-10-04 16:49:06 +02:00
layout(location = 0) out vec4 out_color;\n\
2018-08-19 11:45:46 +02:00
in vec2 texcoord0;\n\
in vec2 texcoord1;\n\
uniform mat3 colormatrix;\n\
uniform vec3 colormatrix_c;\n\
uniform sampler2D texture0;\n\
uniform sampler2D texture1;\n\
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
void main() {\n\
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
color.r = 1.000000 * vec4(texture(texture0, texcoord0)).r;\n\
color.gb = 1.000000 * vec4(texture(texture1, texcoord1)).rg;\n\
// color conversion\n\
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
color.a = 1.0;\n\
// color mapping\n\
out_color = color;\n\
}\n"};
char fragment_bt2100[] = {"\
2019-10-04 10:37:57 +02:00
\n \
#define texture1D texture\n\
#define texture3D texture\n\
2019-10-04 10:37:57 +02:00
precision mediump float; \
2018-10-04 16:49:06 +02:00
layout(location = 0) out vec4 out_color;\n\
in vec2 texcoord0;\n\
in vec2 texcoord1;\n\
uniform mat3 colormatrix;\n\
uniform vec3 colormatrix_c;\n\
uniform mat3 cms_matrix;\n\
uniform sampler2D texture0;\n\
uniform sampler2D texture1;\n\
//#define LUT_POS(x, lut_size) mix(0.5 / (lut_size), 1.0 - 0.5 / (lut_size), (x))\n\
void main() {\n\
vec4 color; // = vec4(0.0, 0.0, 0.0, 1.0);\n\
color.r = 1.003906 * vec4(texture(texture0, texcoord0)).r;\n\
color.gb = 1.003906 * vec4(texture(texture1, texcoord1)).rg;\n\
// color conversion\n\
color.rgb = mat3(colormatrix) * color.rgb + colormatrix_c;\n\
color.a = 1.0;\n\
// color mapping\n\
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
color.rgb = pow(color.rgb, vec3(2.4));\n\
color.rgb = cms_matrix * color.rgb;\n\
color.rgb = clamp(color.rgb, 0.0, 1.0);\n\
color.rgb = pow(color.rgb, vec3(1.0/2.4));\n\
out_color = color;\n\
}\n"};
2019-10-04 10:37:57 +02:00
#endif
2018-08-19 11:45:46 +02:00
/* Color conversion matrix: RGB = m * YUV + c
* m is in row-major matrix, with m[row][col], e.g.:
* [ a11 a12 a13 ] float m[3][3] = { { a11, a12, a13 },
* [ a21 a22 a23 ] { a21, a22, a23 },
* [ a31 a32 a33 ] { a31, a32, a33 } };
* This is accessed as e.g.: m[2-1][1-1] = a21
* In particular, each row contains all the coefficients for one of R, G, B,
* while each column contains all the coefficients for one of Y, U, V:
* m[r,g,b][y,u,v] = ...
* The matrix could also be viewed as group of 3 vectors, e.g. the 1st column
* is the Y vector (1, 1, 1), the 2nd is the U vector, the 3rd the V vector.
* The matrix might also be used for other conversions and colorspaces.
*/
struct mp_cmat {
2019-10-04 10:37:57 +02:00
GLfloat m[3][3]; // colormatrix
GLfloat c[3]; //colormatrix_c
2018-08-19 11:45:46 +02:00
};
struct mp_mat {
2019-10-04 10:37:57 +02:00
GLfloat m[3][3];
};
2018-08-19 11:45:46 +02:00
// YUV input limited range (16-235 for luma, 16-240 for chroma)
// ITU-R BT.601 (SD)
struct mp_cmat yuv_bt601 = {\
{{ 1.164384, 1.164384, 1.164384 },\
{ 0.00000, -0.391762, 2.017232 },\
{ 1.596027, -0.812968 , 0.000000 }},\
{-0.874202, 0.531668, -1.085631 } };
// ITU-R BT.709 (HD)
struct mp_cmat yuv_bt709 = {\
{{ 1.164384, 1.164384, 1.164384 },\
{ 0.00000, -0.213249, 2.112402 },\
{ 1.792741, -0.532909 , 0.000000 }},\
{-0.972945, 0.301483, -1.133402 } };
// ITU-R BT.2020 non-constant luminance system
struct mp_cmat yuv_bt2020ncl = {\
{{ 1.164384, 1.164384, 1.164384 },\
{ 0.00000, -0.187326, 2.141772 },\
{ 1.678674, -0.650424 , 0.000000 }},\
{-0.915688, 0.347459, -1.148145 } };
// ITU-R BT.2020 constant luminance system
struct mp_cmat yuv_bt2020cl = {\
{{ 0.0000, 1.164384, 0.000000 },\
{ 0.00000, 0.000000, 1.138393 },\
{ 1.138393, 0.000000 , 0.000000 }},\
{-0.571429, -0.073059, -0.571429 } };
float cms_matrix[3][3] = \
{{ 1.660497, -0.124547, -0.018154},\
{-0.587657, 1.132895, -0.100597},\
{-0.072840, -0.008348, 1.118751}};
2018-08-19 11:45:46 +02:00
struct gl_vao_entry {
// used for shader / glBindAttribLocation
const char *name;
// glVertexAttribPointer() arguments
int num_elems; // size (number of elements)
GLenum type;
bool normalized;
int offset;
};
struct vertex_pt {
float x, y;
};
2018-10-12 15:12:30 +02:00
struct vertex_pi {
GLint x, y;
};
2018-08-19 11:45:46 +02:00
#define TEXUNIT_VIDEO_NUM 6
2018-10-12 15:12:30 +02:00
2018-08-19 11:45:46 +02:00
struct vertex {
struct vertex_pt position;
struct vertex_pt texcoord[TEXUNIT_VIDEO_NUM];
};
static const struct gl_vao_entry vertex_vao[] = {
{"position", 2, GL_FLOAT, false, offsetof(struct vertex, position)},
{"texcoord0", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[0])},
{"texcoord1", 2, GL_FLOAT, false, offsetof(struct vertex, texcoord[1])},
{0}
};
static void compile_attach_shader(GLuint program,
GLenum type, const char *source)
{
2018-10-14 13:05:22 +02:00
GLuint shader;
GLint status, log_length;
2019-10-04 10:37:57 +02:00
char log[4000];
GLsizei len;
2018-10-14 13:05:22 +02:00
shader = glCreateShader(type);
2018-08-19 11:45:46 +02:00
glShaderSource(shader, 1, &source, NULL);
glCompileShader(shader);
2018-10-14 13:05:22 +02:00
status = 0;
2018-08-19 11:45:46 +02:00
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
2018-10-14 13:05:22 +02:00
log_length = 0;
2018-08-19 11:45:46 +02:00
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length);
2019-10-04 10:37:57 +02:00
glGetShaderInfoLog(shader,4000,&len,log);
GlxCheck();
Debug(3,"compile Status %d loglen %d >%s<\n",status,log_length,log);
2018-08-19 11:45:46 +02:00
glAttachShader(program, shader);
glDeleteShader(shader);
}
static void link_shader(GLuint program)
{
2018-10-14 13:05:22 +02:00
GLint status,log_length;
2018-08-19 11:45:46 +02:00
glLinkProgram(program);
2018-10-14 13:05:22 +02:00
status = 0;
2018-08-19 11:45:46 +02:00
glGetProgramiv(program, GL_LINK_STATUS, &status);
2018-10-14 13:05:22 +02:00
log_length = 0;
2018-08-19 11:45:46 +02:00
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_length);
Debug(3,"Link Status %d loglen %d\n",status,log_length);
2019-10-04 10:37:57 +02:00
}
2018-08-19 11:45:46 +02:00
2019-10-04 10:37:57 +02:00
static GLuint sc_generate_osd(GLuint gl_prog) {
Debug(3,"vor create osd\n");
gl_prog = glCreateProgram();
Debug(3,"vor compile vertex osd\n");
compile_attach_shader(gl_prog, GL_VERTEX_SHADER, vertex_osd);
Debug(3,"vor compile fragment osd \n");
compile_attach_shader(gl_prog, GL_FRAGMENT_SHADER, fragment_osd);
glBindAttribLocation(gl_prog,0,"vertex_position");
glBindAttribLocation(gl_prog,1,"vertex_texcoord0");
link_shader(gl_prog);
return gl_prog;
2018-08-19 11:45:46 +02:00
}
2019-10-04 10:37:57 +02:00
static GLuint sc_generate(GLuint gl_prog, enum AVColorSpace colorspace) {
2018-08-19 11:45:46 +02:00
char vname[80];
int n;
GLint cmsLoc;
float *m,*c,*cms;
char *frag;
switch (colorspace) {
case AVCOL_SPC_RGB:
m = &yuv_bt601.m[0][0];
c = &yuv_bt601.c[0];
frag = fragment;
Debug(3,"BT601 Colorspace used\n");
break;
case AVCOL_SPC_BT709:
case AVCOL_SPC_UNSPECIFIED: // comes with UHD
m = &yuv_bt709.m[0][0];
c = &yuv_bt709.c[0];
frag = fragment;
Debug(3,"BT709 Colorspace used\n");
break;
case AVCOL_SPC_BT2020_NCL:
m = &yuv_bt2020ncl.m[0][0];
c = &yuv_bt2020ncl.c[0];
cms = &cms_matrix[0][0];
frag = fragment_bt2100;
Debug(3,"BT2020NCL Colorspace used\n");
break;
default: // fallback
m = &yuv_bt709.m[0][0];
c = &yuv_bt709.c[0];
frag = fragment;
Debug(3,"default BT709 Colorspace used %d\n",colorspace);
break;
}
2018-08-19 11:45:46 +02:00
Debug(3,"vor create\n");
gl_prog = glCreateProgram();
Debug(3,"vor compile vertex\n");
compile_attach_shader(gl_prog, GL_VERTEX_SHADER, vertex);
2018-08-19 11:45:46 +02:00
Debug(3,"vor compile fragment\n");
compile_attach_shader(gl_prog, GL_FRAGMENT_SHADER, frag);
glBindAttribLocation(gl_prog,0,"vertex_position");
for (n=0;n<6;n++) {
sprintf(vname,"vertex_texcoord%1d",n);
glBindAttribLocation(gl_prog,n+1,vname);
}
2018-08-19 11:45:46 +02:00
link_shader(gl_prog);
2018-08-19 11:45:46 +02:00
gl_colormatrix = glGetUniformLocation(gl_prog,"colormatrix");
Debug(3,"get uniform colormatrix %d \n",gl_colormatrix);
if (gl_colormatrix != -1)
glProgramUniformMatrix3fv(gl_prog,gl_colormatrix,1,0,m);
GlxCheck();
2019-10-04 10:37:57 +02:00
Debug(3,"nach set colormatrix\n");
2018-08-19 11:45:46 +02:00
gl_colormatrix_c = glGetUniformLocation(gl_prog,"colormatrix_c");
Debug(3,"get uniform colormatrix_c %d %f\n",gl_colormatrix_c,*c);
if (gl_colormatrix_c != -1)
glProgramUniform3fv(gl_prog,gl_colormatrix_c,1,c);
GlxCheck();
if (colorspace == AVCOL_SPC_BT2020_NCL) {
cmsLoc = glGetUniformLocation(gl_prog,"cms_matrix");
if (cmsLoc != -1)
glProgramUniformMatrix3fv(gl_prog,cmsLoc,1,0,cms);
GlxCheck();
}
2018-08-19 11:45:46 +02:00
return gl_prog;
}
2018-10-12 15:12:30 +02:00
static void render_pass_quad(int flip, float xcrop, float ycrop)
2018-08-19 11:45:46 +02:00
{
struct vertex va[4];
int n;
const struct gl_vao_entry *e;
// uhhhh what a hack
2018-10-04 16:49:06 +02:00
if (!flip ) {
va[0].position.x = (float) -1.0;
va[0].position.y = (float) 1.0;
va[1].position.x = (float) -1.0;
va[1].position.y = (float) -1.0;
va[2].position.x = (float) 1.0;
va[2].position.y = (float) 1.0;
va[3].position.x = (float) 1.0;
va[3].position.y = (float) -1.0;
} else {
va[0].position.x = (float) -1.0;
va[0].position.y = (float) -1.0;
va[1].position.x = (float) -1.0;
va[1].position.y = (float) 1.0;
va[2].position.x = (float) 1.0;
va[2].position.y = (float) -1.0;
va[3].position.x = (float) 1.0;
va[3].position.y = (float) 1.0;
}
2018-08-19 11:45:46 +02:00
2018-10-12 15:12:30 +02:00
va[0].texcoord[0].x = (float) 0.0 + xcrop;
va[0].texcoord[0].y = (float) 0.0 + ycrop; // abgeschnitten von links oben
va[0].texcoord[1].x = (float) 0.0 + xcrop;
va[0].texcoord[1].y = (float) 0.0 + ycrop; // abgeschnitten von links oben
va[1].texcoord[0].x = (float) 0.0 + xcrop;
va[1].texcoord[0].y = (float) 1.0 - ycrop; // abgeschnitten links unten 1.0 - Wert
va[1].texcoord[1].x = (float) 0.0 + xcrop;
va[1].texcoord[1].y = (float) 1.0 - ycrop; // abgeschnitten links unten 1.0 - Wert
va[2].texcoord[0].x = (float) 1.0 - xcrop;
va[2].texcoord[0].y = (float) 0.0 + ycrop; // abgeschnitten von rechts oben
va[2].texcoord[1].x = (float) 1.0 - xcrop;
va[2].texcoord[1].y = (float) 0.0 + ycrop; // abgeschnitten von rechts oben
va[3].texcoord[0].x = (float) 1.0 - xcrop;
va[3].texcoord[0].y = (float) 1.0 - ycrop; // abgeschnitten von rechts unten 1.0 - wert
va[3].texcoord[1].x = (float) 1.0 - xcrop;
va[3].texcoord[1].y = (float) 1.0 - ycrop; // abgeschnitten von rechts unten 1.0 - wert
2018-08-19 11:45:46 +02:00
2018-10-12 15:12:30 +02:00
2018-08-19 11:45:46 +02:00
glBindBuffer(GL_ARRAY_BUFFER, vao_buffer);
glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(struct vertex), va, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// enable attribs
glBindBuffer(GL_ARRAY_BUFFER, vao_buffer);
for ( n = 0; vertex_vao[n].name; n++) {
e = &vertex_vao[n];
glEnableVertexAttribArray(n);
glVertexAttribPointer(n, e->num_elems, e->type, e->normalized,
sizeof(struct vertex), (void *)(intptr_t)e->offset);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
2018-10-04 16:49:06 +02:00
2018-08-19 11:45:46 +02:00
// draw quad
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
for ( n = 0; vertex_vao[n].name; n++)
glDisableVertexAttribArray(n);
}