diff --git a/YUViewLib/YUViewLib.pro b/YUViewLib/YUViewLib.pro index 2e6f1da52..d6513589c 100644 --- a/YUViewLib/YUViewLib.pro +++ b/YUViewLib/YUViewLib.pro @@ -14,7 +14,8 @@ INCLUDEPATH += src/ RESOURCES += \ images/images.qrc \ - docs/docs.qrc + docs/docs.qrc \ + shaders/shaders.qrc contains(QT_ARCH, x86_32|i386) { warning("You are building for a 32 bit system. This is untested and not supported.") diff --git a/YUViewLib/shaders/fragmentYUV2RGBshader.glsl b/YUViewLib/shaders/fragmentYUV2RGBshader.glsl new file mode 100644 index 000000000..7ffaf185d --- /dev/null +++ b/YUViewLib/shaders/fragmentYUV2RGBshader.glsl @@ -0,0 +1,69 @@ +#version 330 core + +// A Fragment Shader is the Shader stage that will process a Fragment generated by the +// Rasterization into a set of colors and a single depth value. +// The fragment shader is the OpenGL pipeline stage after a primitive is rasterized. +// For each sample of the pixels covered by a primitive, a "fragment" is generated. +// Each fragment has a Window Space position, a few other values, and it contains +// all of the interpolated per-vertex output values from the last Vertex Processing stage. +// The output of a fragment shader is a depth value, a possible stencil value +// (unmodified by the fragment shader), and zero or more color values to be +// potentially written to the buffers in the current framebuffers. +// Fragment shaders take a single fragment as input and produce a single fragment as output. + +// Interpolated values from the vertex shaders +in vec2 texture_coordinate; +//in vec2 fragmentUVChroma; + +// Ouput data +out vec4 color_0; +//out vec3 color_1; + +// Values that stay constant for the whole mesh. +uniform usampler2D textureSamplerY; +uniform usampler2D textureSamplerU; +uniform usampler2D textureSamplerV; + +uniform float sampleMaxVal; + +void main(){ + // ITU-R BT 709 to RGB mapping matrix + mat3 mat709toRGB = mat3(1.164, 1.164, 1.164, // definition looks transposed + 0.0, -0.213, 2.112, // since openGL uses column-major order + 1.793, -0.533, 0.0); + + + + // Output color = color of the texture at the specified UV + vec3 color709; + //color709.rgb = texture2D( textureSamplerYUV, fragmentUV ).rgb; + color709.r = float(texture( textureSamplerY, texture_coordinate ).r); + color709.g = float(texture( textureSamplerU, texture_coordinate ).r); + color709.b = float(texture( textureSamplerV, texture_coordinate ).r); + + // normalize color values to the intervall [0, 1] + color709.r = color709.r / sampleMaxVal; + color709.g = color709.g / sampleMaxVal; + color709.b = color709.b / sampleMaxVal; + +// obsolete, but still missing atm. +// // make sure input has correct range, 8bit +// color709.r = clamp(color709.r, 16.0/255, 235.0/255); // Y +// color709.g = clamp(color709.g, 16.0/255, 240.0/255); // U +// color709.b = clamp(color709.b, 16.0/255, 240.0/255); // V +// // make sure input has correct range, 10bit +// color709.r = clamp(color709.r, 16.0/1023, 235.0/1023); // Y +// color709.g = clamp(color709.g, 16.0/1023, 240.0/1023); // U +// color709.b = clamp(color709.b, 16.0/1023, 240.0/1023); // V + + + // de/normalization + color709.r = color709.r - 0.0625; + color709.g = color709.g - 0.5; + color709.b = color709.b - 0.5; + // finally the conversion + color_0 = vec4(clamp(mat709toRGB * color709, 0.0, 1.0), 1.0f); + //color_1.r = 0.5; + //color_1.g = 0.7; + //color_1.b = 0.8; +} diff --git a/YUViewLib/shaders/shaders.qrc b/YUViewLib/shaders/shaders.qrc new file mode 100644 index 000000000..09ff73e26 --- /dev/null +++ b/YUViewLib/shaders/shaders.qrc @@ -0,0 +1,6 @@ + + + fragmentYUV2RGBshader.glsl + vertexshader.glsl + + diff --git a/YUViewLib/shaders/vertexshader.glsl b/YUViewLib/shaders/vertexshader.glsl new file mode 100644 index 000000000..366981d7c --- /dev/null +++ b/YUViewLib/shaders/vertexshader.glsl @@ -0,0 +1,30 @@ +#version 330 core + +// The Vertex Shader is the programmable Shader stage in the rendering pipeline that +// handles the processing of individual vertices. Vertex shaders are fed +// Vertex Attribute data, as specified from a vertex array object by a drawing command. +// A vertex shader receives a single vertex from the vertex stream and generates +// a single vertex to the output vertex stream. There must be a 1:1 mapping from +// input vertices to output vertices. + +// Input vertex data, different for all executions of this shader. +layout(location = 0) in vec3 vertexPosition_modelspace; +layout(location = 1) in vec2 vertexLuma; + +// Output data ; will be interpolated for each fragment. +out vec2 texture_coordinate; // texture coordinates + +// Mmodel view projection (MVP) matrix +// the vertices are setup to be aligned with openGL clip coordinates. +// Thus no further coordinate transform will be necessary. +// Further, textrue coordinates can be obtained by dropping the z-axis coordinate. +// https://learnopengl.com/Getting-started/Coordinate-Systems +// However we need to scale in case the aspect ratio of the window does not match the videos +uniform mat4 mvp_matrix; + + +void main(){ + gl_Position = mvp_matrix * vec4(vertexPosition_modelspace, 1.0f); + // for texture coordinates we simply discard the z axis, and flip the y axis + texture_coordinate = vec2(vertexLuma.x, 1.0 - vertexLuma.y); +} diff --git a/YUViewLib/src/playlistitem/playlistItem.h b/YUViewLib/src/playlistitem/playlistItem.h index 860216f27..8b38f70ea 100644 --- a/YUViewLib/src/playlistitem/playlistItem.h +++ b/YUViewLib/src/playlistitem/playlistItem.h @@ -40,6 +40,7 @@ #include "common/YUViewDomElement.h" #include "ui_playlistItem.h" +#include