mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-09 17:31:18 +00:00
Gives the shader builders freer rein over what to use as inputs, and turns angles
into a varying.
All dropping out during the never-ending diagnosis at play here.
This commit is contained in:
parent
727f2e2ba0
commit
a8acadbe13
@ -294,7 +294,7 @@ void ScanTarget::setup_pipeline() {
|
|||||||
processing_width_ = modals_.cycles_per_line / modals_.clocks_per_pixel_greatest_common_divisor;
|
processing_width_ = modals_.cycles_per_line / modals_.clocks_per_pixel_greatest_common_divisor;
|
||||||
|
|
||||||
// Establish an output shader.
|
// Establish an output shader.
|
||||||
output_shader_ = conversion_shader(modals_.input_data_type, modals_.display_type, modals_.composite_colour_space, output_gamma_ / modals_.intended_gamma, modals_.brightness);
|
output_shader_ = conversion_shader();
|
||||||
glBindVertexArray(line_vertex_array_);
|
glBindVertexArray(line_vertex_array_);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, line_buffer_name_);
|
glBindBuffer(GL_ARRAY_BUFFER, line_buffer_name_);
|
||||||
enable_vertex_attributes(ShaderType::Conversion, *output_shader_);
|
enable_vertex_attributes(ShaderType::Conversion, *output_shader_);
|
||||||
@ -304,7 +304,7 @@ void ScanTarget::setup_pipeline() {
|
|||||||
output_shader_->set_uniform("textureName", GLint(UnprocessedLineBufferTextureUnit - GL_TEXTURE0));
|
output_shader_->set_uniform("textureName", GLint(UnprocessedLineBufferTextureUnit - GL_TEXTURE0));
|
||||||
|
|
||||||
// Establish an input shader.
|
// Establish an input shader.
|
||||||
input_shader_ = composition_shader(modals_.input_data_type);
|
input_shader_ = composition_shader();
|
||||||
glBindVertexArray(scan_vertex_array_);
|
glBindVertexArray(scan_vertex_array_);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, scan_buffer_name_);
|
glBindBuffer(GL_ARRAY_BUFFER, scan_buffer_name_);
|
||||||
enable_vertex_attributes(ShaderType::Composition, *input_shader_);
|
enable_vertex_attributes(ShaderType::Composition, *input_shader_);
|
||||||
|
@ -182,12 +182,12 @@ class ScanTarget: public Outputs::Display::ScanTarget {
|
|||||||
normalising the data into one of four forms: RGB, 8-bit luminance,
|
normalising the data into one of four forms: RGB, 8-bit luminance,
|
||||||
phase-linked luminance or luminance+phase offset.
|
phase-linked luminance or luminance+phase offset.
|
||||||
*/
|
*/
|
||||||
static std::unique_ptr<Shader> composition_shader(InputDataType input_data_type);
|
std::unique_ptr<Shader> composition_shader() const;
|
||||||
/*!
|
/*!
|
||||||
Produces a shader that reads from a composition buffer and converts to host
|
Produces a shader that reads from a composition buffer and converts to host
|
||||||
output RGB, decoding composite or S-Video as necessary.
|
output RGB, decoding composite or S-Video as necessary.
|
||||||
*/
|
*/
|
||||||
static std::unique_ptr<Shader> conversion_shader(InputDataType input_data_type, DisplayType display_type, ColourSpace colour_space, float gamma_ratio, float brightness);
|
std::unique_ptr<Shader> conversion_shader() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ void ScanTarget::enable_vertex_attributes(ShaderType type, Shader &target) {
|
|||||||
|
|
||||||
target.enable_vertex_attribute_with_pointer(
|
target.enable_vertex_attribute_with_pointer(
|
||||||
prefix + "CompositeAngle",
|
prefix + "CompositeAngle",
|
||||||
1, GL_UNSIGNED_SHORT, GL_FALSE,
|
1, GL_SHORT, GL_FALSE,
|
||||||
sizeof(Line),
|
sizeof(Line),
|
||||||
reinterpret_cast<void *>(offsetof(Line, end_points[c].composite_angle)),
|
reinterpret_cast<void *>(offsetof(Line, end_points[c].composite_angle)),
|
||||||
1);
|
1);
|
||||||
@ -99,7 +99,7 @@ void ScanTarget::enable_vertex_attributes(ShaderType type, Shader &target) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Shader> ScanTarget::composition_shader(InputDataType input_data_type) {
|
std::unique_ptr<Shader> ScanTarget::composition_shader() const {
|
||||||
const std::string vertex_shader =
|
const std::string vertex_shader =
|
||||||
"#version 150\n"
|
"#version 150\n"
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ std::unique_ptr<Shader> ScanTarget::composition_shader(InputDataType input_data_
|
|||||||
|
|
||||||
"void main(void) {";
|
"void main(void) {";
|
||||||
|
|
||||||
switch(input_data_type) {
|
switch(modals_.input_data_type) {
|
||||||
case InputDataType::Luminance1:
|
case InputDataType::Luminance1:
|
||||||
fragment_shader += "fragColour = texture(textureName, textureCoordinate).rrrr;";
|
fragment_shader += "fragColour = texture(textureName, textureCoordinate).rrrr;";
|
||||||
break;
|
break;
|
||||||
@ -180,7 +180,7 @@ std::unique_ptr<Shader> ScanTarget::composition_shader(InputDataType input_data_
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_type, DisplayType display_type, ColourSpace colour_space, float gamma_ratio, float brightness) {
|
std::unique_ptr<Shader> ScanTarget::conversion_shader() const {
|
||||||
// Compose a vertex shader. If the display type is RGB, generate just the proper
|
// Compose a vertex shader. If the display type is RGB, generate just the proper
|
||||||
// geometry position, plus a solitary textureCoordinate.
|
// geometry position, plus a solitary textureCoordinate.
|
||||||
//
|
//
|
||||||
@ -219,7 +219,7 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
"uniform sampler2D textureName;"
|
"uniform sampler2D textureName;"
|
||||||
"out vec4 fragColour;";
|
"out vec4 fragColour;";
|
||||||
|
|
||||||
if(display_type != DisplayType::RGB) {
|
if(modals_.display_type != DisplayType::RGB) {
|
||||||
vertex_shader +=
|
vertex_shader +=
|
||||||
"out float compositeAngle;"
|
"out float compositeAngle;"
|
||||||
"out float compositeAmplitude;"
|
"out float compositeAmplitude;"
|
||||||
@ -230,7 +230,7 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
"in float oneOverCompositeAmplitude;";
|
"in float oneOverCompositeAmplitude;";
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(display_type){
|
switch(modals_.display_type){
|
||||||
case DisplayType::RGB:
|
case DisplayType::RGB:
|
||||||
case DisplayType::CompositeMonochrome:
|
case DisplayType::CompositeMonochrome:
|
||||||
vertex_shader += "out vec2 textureCoordinate;";
|
vertex_shader += "out vec2 textureCoordinate;";
|
||||||
@ -239,8 +239,12 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
|
|
||||||
case DisplayType::CompositeColour:
|
case DisplayType::CompositeColour:
|
||||||
case DisplayType::SVideo:
|
case DisplayType::SVideo:
|
||||||
vertex_shader += "out vec2 textureCoordinates[4];";
|
vertex_shader +=
|
||||||
fragment_shader += "in vec2 textureCoordinates[4];";
|
"out vec2 textureCoordinates[4];"
|
||||||
|
"out vec4 angles;";
|
||||||
|
fragment_shader +=
|
||||||
|
"in vec2 textureCoordinates[4];"
|
||||||
|
"in vec4 angles;";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,13 +253,13 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
"void main(void) {"
|
"void main(void) {"
|
||||||
"float lateral = float(gl_VertexID & 1);"
|
"float lateral = float(gl_VertexID & 1);"
|
||||||
"float longitudinal = float((gl_VertexID & 2) >> 1);"
|
"float longitudinal = float((gl_VertexID & 2) >> 1);"
|
||||||
"vec2 centrePoint = mix(startPoint, endPoint, lateral) / scale;"
|
"vec2 centrePoint = mix(startPoint, vec2(endPoint.x, startPoint.y), lateral) / scale;"
|
||||||
"vec2 height = normalize(endPoint - startPoint).yx * (longitudinal - 0.5) * rowHeight;"
|
"vec2 height = normalize(vec2(endPoint.x, startPoint.y) - startPoint).yx * (longitudinal - 0.5) * rowHeight;"
|
||||||
"vec2 eyePosition = vec2(-1.0, 1.0) + vec2(2.0, -2.0) * (((centrePoint + height) - origin) / size);"
|
"vec2 eyePosition = vec2(-1.0, 1.0) + vec2(2.0, -2.0) * (((centrePoint + height) - origin) / size);"
|
||||||
"gl_Position = vec4(eyePosition, 0.0, 1.0);";
|
"gl_Position = vec4(eyePosition, 0.0, 1.0);";
|
||||||
|
|
||||||
// For everything other than RGB, calculate the two composite outputs.
|
// For everything other than RGB, calculate the two composite outputs.
|
||||||
if(display_type != DisplayType::RGB) {
|
if(modals_.display_type != DisplayType::RGB) {
|
||||||
vertex_shader +=
|
vertex_shader +=
|
||||||
"compositeAngle = (mix(startCompositeAngle, endCompositeAngle, lateral) / 32.0) * 3.141592654;"
|
"compositeAngle = (mix(startCompositeAngle, endCompositeAngle, lateral) / 32.0) * 3.141592654;"
|
||||||
"compositeAmplitude = lineCompositeAmplitude / 255.0;"
|
"compositeAmplitude = lineCompositeAmplitude / 255.0;"
|
||||||
@ -264,7 +268,7 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
|
|
||||||
// For RGB and monochrome composite, generate the single texture coordinate; otherwise generate either three
|
// For RGB and monochrome composite, generate the single texture coordinate; otherwise generate either three
|
||||||
// or four depending on the type of decoding to apply.
|
// or four depending on the type of decoding to apply.
|
||||||
switch(display_type){
|
switch(modals_.display_type){
|
||||||
case DisplayType::RGB:
|
case DisplayType::RGB:
|
||||||
case DisplayType::CompositeMonochrome:
|
case DisplayType::CompositeMonochrome:
|
||||||
vertex_shader +=
|
vertex_shader +=
|
||||||
@ -279,7 +283,13 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
"textureCoordinates[0] = vec2(centreClock - 0.375*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);"
|
"textureCoordinates[0] = vec2(centreClock - 0.375*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);"
|
||||||
"textureCoordinates[1] = vec2(centreClock - 0.125*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);"
|
"textureCoordinates[1] = vec2(centreClock - 0.125*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);"
|
||||||
"textureCoordinates[2] = vec2(centreClock + 0.125*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);"
|
"textureCoordinates[2] = vec2(centreClock + 0.125*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);"
|
||||||
"textureCoordinates[3] = vec2(centreClock + 0.375*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);";
|
"textureCoordinates[3] = vec2(centreClock + 0.375*clocksPerAngle, lineY + 0.5) / textureSize(textureName, 0);"
|
||||||
|
"angles = vec4("
|
||||||
|
"compositeAngle - 2.356194490192345,"
|
||||||
|
"compositeAngle - 0.785398163397448,"
|
||||||
|
"compositeAngle + 0.785398163397448,"
|
||||||
|
"compositeAngle + 2.356194490192345"
|
||||||
|
");";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,17 +299,17 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
//
|
//
|
||||||
// For an RGB display ... [TODO]
|
// For an RGB display ... [TODO]
|
||||||
|
|
||||||
if(display_type != DisplayType::RGB) {
|
if(modals_.display_type != DisplayType::RGB) {
|
||||||
fragment_shader +=
|
fragment_shader +=
|
||||||
"uniform mat3 lumaChromaToRGB;"
|
"uniform mat3 lumaChromaToRGB;"
|
||||||
"uniform mat3 rgbToLumaChroma;";
|
"uniform mat3 rgbToLumaChroma;";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(display_type == DisplayType::SVideo) {
|
if(modals_.display_type == DisplayType::SVideo) {
|
||||||
fragment_shader +=
|
fragment_shader +=
|
||||||
"vec2 svideo_sample(vec2 coordinate, float angle) {";
|
"vec2 svideo_sample(vec2 coordinate, float angle) {";
|
||||||
|
|
||||||
switch(input_data_type) {
|
switch(modals_.input_data_type) {
|
||||||
case InputDataType::Luminance1:
|
case InputDataType::Luminance1:
|
||||||
case InputDataType::Luminance8:
|
case InputDataType::Luminance8:
|
||||||
// Easy, just copy across.
|
// Easy, just copy across.
|
||||||
@ -335,11 +345,11 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
fragment_shader += "}";
|
fragment_shader += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(display_type == DisplayType::CompositeMonochrome || display_type == DisplayType::CompositeColour) {
|
if(modals_.display_type == DisplayType::CompositeMonochrome || modals_.display_type == DisplayType::CompositeColour) {
|
||||||
fragment_shader +=
|
fragment_shader +=
|
||||||
"float composite_sample(vec2 coordinate, float angle) {";
|
"float composite_sample(vec2 coordinate, float angle) {";
|
||||||
|
|
||||||
switch(input_data_type) {
|
switch(modals_.input_data_type) {
|
||||||
case InputDataType::Luminance1:
|
case InputDataType::Luminance1:
|
||||||
case InputDataType::Luminance8:
|
case InputDataType::Luminance8:
|
||||||
// Easy, just copy across.
|
// Easy, just copy across.
|
||||||
@ -379,18 +389,7 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
"void main(void) {"
|
"void main(void) {"
|
||||||
"vec3 fragColour3;";
|
"vec3 fragColour3;";
|
||||||
|
|
||||||
if(display_type == DisplayType::CompositeColour || display_type == DisplayType::SVideo) {
|
switch(modals_.display_type) {
|
||||||
fragment_shader +=
|
|
||||||
// Figure out the four composite angles.
|
|
||||||
"vec4 angles = vec4("
|
|
||||||
"compositeAngle - 2.356194490192345,"
|
|
||||||
"compositeAngle - 0.785398163397448,"
|
|
||||||
"compositeAngle + 0.785398163397448,"
|
|
||||||
"compositeAngle + 2.356194490192345"
|
|
||||||
");";
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(display_type) {
|
|
||||||
case DisplayType::RGB:
|
case DisplayType::RGB:
|
||||||
fragment_shader += "fragColour3 = texture(textureName, textureCoordinate).rgb;";
|
fragment_shader += "fragColour3 = texture(textureName, textureCoordinate).rgb;";
|
||||||
break;
|
break;
|
||||||
@ -461,12 +460,13 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Apply a brightness adjustment if requested.
|
// Apply a brightness adjustment if requested.
|
||||||
if(fabs(brightness - 1.0f) > 0.05f) {
|
if(fabs(modals_.brightness - 1.0f) > 0.05f) {
|
||||||
fragment_shader += "fragColour3 = fragColour3 * " + std::to_string(brightness) + ";";
|
fragment_shader += "fragColour3 = fragColour3 * " + std::to_string(modals_.brightness) + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply a gamma correction if required.
|
// Apply a gamma correction if required.
|
||||||
if(fabs(gamma_ratio - 1.0f) > 0.05f) {
|
if(fabs(output_gamma_ - modals_.intended_gamma) > 0.05f) {
|
||||||
|
const float gamma_ratio = output_gamma_ / modals_.intended_gamma;
|
||||||
fragment_shader += "fragColour3 = pow(fragColour3, vec3(" + std::to_string(gamma_ratio) + "));";
|
fragment_shader += "fragColour3 = pow(fragColour3, vec3(" + std::to_string(gamma_ratio) + "));";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,8 +490,8 @@ std::unique_ptr<Shader> ScanTarget::conversion_shader(InputDataType input_data_t
|
|||||||
);
|
);
|
||||||
|
|
||||||
// If this isn't an RGB or composite colour shader, set the proper colour space.
|
// If this isn't an RGB or composite colour shader, set the proper colour space.
|
||||||
if(display_type != DisplayType::RGB) {
|
if(modals_.display_type != DisplayType::RGB) {
|
||||||
switch(colour_space) {
|
switch(modals_.composite_colour_space) {
|
||||||
case ColourSpace::YIQ: {
|
case ColourSpace::YIQ: {
|
||||||
const GLfloat rgbToYIQ[] = {0.299f, 0.596f, 0.211f, 0.587f, -0.274f, -0.523f, 0.114f, -0.322f, 0.312f};
|
const GLfloat rgbToYIQ[] = {0.299f, 0.596f, 0.211f, 0.587f, -0.274f, -0.523f, 0.114f, -0.322f, 0.312f};
|
||||||
const GLfloat yiqToRGB[] = {1.0f, 1.0f, 1.0f, 0.956f, -0.272f, -1.106f, 0.621f, -0.647f, 1.703f};
|
const GLfloat yiqToRGB[] = {1.0f, 1.0f, 1.0f, 0.956f, -0.272f, -1.106f, 0.621f, -0.647f, 1.703f};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user