From 538c57664f79d8b904e499efe9e2886cfd603a5f Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sat, 24 Nov 2018 16:06:26 -0500 Subject: [PATCH] Establishes attribute bindings to allow multiple shaders to use the same vertex array. --- Outputs/OpenGL/ScanTarget.cpp | 21 +++++--- Outputs/OpenGL/ScanTarget.hpp | 3 +- Outputs/OpenGL/ScanTargetGLSLFragments.cpp | 63 ++++++++++++++++------ 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/Outputs/OpenGL/ScanTarget.cpp b/Outputs/OpenGL/ScanTarget.cpp index 2c147ae61..5363741a3 100644 --- a/Outputs/OpenGL/ScanTarget.cpp +++ b/Outputs/OpenGL/ScanTarget.cpp @@ -103,8 +103,8 @@ ScanTarget::~ScanTarget() { } void ScanTarget::set_modals(Modals modals) { - // TODO: consider resizing the write_area_texture_, and setting - // write_area_texture_line_length_ appropriately. + modals.display_type = DisplayType::SVideo; + modals_ = modals; const auto data_type_size = Outputs::Display::size_for_data_type(modals.input_data_type); @@ -139,7 +139,8 @@ void ScanTarget::set_modals(Modals modals) { "void main(void) {" "fragColour = vec4(texture(textureName, textureCoordinate).rgb, 0.64);" - "}" + "}", + attribute_bindings(ShaderType::Line) )); glBindVertexArray(line_vertex_array_); @@ -162,11 +163,11 @@ void ScanTarget::set_modals(Modals modals) { (modals_.display_type == DisplayType::CompositeColour) ? RGBLineBufferTextureUnit : SVideoLineBufferTextureUnit); } - // Establish an input shader. - input_shader_ = input_shader(modals_.input_data_type, modals_.display_type); - glBindVertexArray(scan_vertex_array_); glBindBuffer(GL_ARRAY_BUFFER, scan_buffer_name_); + + // Establish an input shader. + input_shader_ = input_shader(modals_.input_data_type, modals_.display_type); enable_vertex_attributes(ShaderType::InputScan, *input_shader_); set_uniforms(ShaderType::InputScan, *input_shader_); input_shader_->set_uniform("textureName", GLint(SourceData1BppTextureUnit - GL_TEXTURE0)); @@ -185,6 +186,8 @@ void ScanTarget::set_modals(Modals modals) { } output_shader_->set_uniform("textureName", texture_unit); +// enable_vertex_attributes(ShaderType::InputScan, *input_shader_); + // Ensure that all shaders involved in the input pipeline have the proper colour space knowledged. for(auto shader: input_shaders) { switch(modals.composite_colour_space) { @@ -615,6 +618,12 @@ void ScanTarget::draw(bool synchronous, int output_width, int output_height) { glViewport(0, 0, (GLsizei)output_width, (GLsizei)output_height); glClear(GL_COLOR_BUFFER_BIT); +// unprocessed_line_texture_.bind_texture(); +// unprocessed_line_texture_.draw(float(output_width) / float(output_height), 4.0f / 255.0f); + +// pipeline_stages_.front().target.bind_texture(); +// pipeline_stages_.front().target.draw(float(output_width) / float(output_height), 4.0f / 255.0f); + accumulation_texture_->bind_texture(); accumulation_texture_->draw(float(output_width) / float(output_height), 4.0f / 255.0f); diff --git a/Outputs/OpenGL/ScanTarget.hpp b/Outputs/OpenGL/ScanTarget.hpp index 1303f8011..e01e1effd 100644 --- a/Outputs/OpenGL/ScanTarget.hpp +++ b/Outputs/OpenGL/ScanTarget.hpp @@ -165,7 +165,8 @@ class ScanTarget: public Outputs::Display::ScanTarget { Calls @c taret.enable_vertex_attribute_with_pointer to attach all globals for shaders of @c type to @c target. */ - void enable_vertex_attributes(ShaderType type, Shader &target); + static void enable_vertex_attributes(ShaderType type, Shader &target); + static std::vector attribute_bindings(ShaderType type); void set_uniforms(ShaderType type, Shader &target); GLsync fence_ = nullptr; diff --git a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp index e262ccea5..51fbdf772 100644 --- a/Outputs/OpenGL/ScanTargetGLSLFragments.cpp +++ b/Outputs/OpenGL/ScanTargetGLSLFragments.cpp @@ -60,6 +60,31 @@ std::string ScanTarget::glsl_globals(ShaderType type) { } } +std::vector ScanTarget::attribute_bindings(ShaderType type) { + switch(type) { + case ShaderType::InputScan: + case ShaderType::ProcessedScan: + return { + {"startPoint", 0}, + {"startDataX", 1}, + {"startCompositeAngle", 2}, + {"endPoint", 3}, + {"endDataX", 4}, + {"endCompositeAngle", 5}, + {"dataY", 6}, + {"lineY", 7}, + {"compositeAmplitude", 8}, + }; + + case ShaderType::Line: + return { + {"startPoint", 0}, + {"endPoint", 1}, + {"lineY", 2}, + }; + } +} + std::string ScanTarget::glsl_default_vertex_shader(ShaderType type) { switch(type) { case ShaderType::InputScan: @@ -85,25 +110,25 @@ std::string ScanTarget::glsl_default_vertex_shader(ShaderType type) { if(type == ShaderType::InputScan) { result += - "textureCoordinate = vec2(mix(startDataX, endDataX, lateral), dataY) / textureSize(textureName, 0);" + "textureCoordinate = vec2(mix(startDataX, endDataX, lateral), dataY) / textureSize(textureName, 0);" // TODO: dataY + 0.5 "vec2 eyePosition = vec2(mix(startPoint.x, endPoint.x, lateral) * processingWidth, lineY + longitudinal) / vec2(scale.x, 2048.0);"; } else { result += - "vec2 eyePosition = vec2(mix(startDataX, endDataX, lateral) - 10.0 + lateral*20.0, dataY + longitudinal);" + "vec2 eyePosition = vec2(mix(startPoint.x, endPoint.x, lateral) * processingWidth, lineY + longitudinal) / vec2(scale.x, 2048.0);" - "textureCoordinates[0] = (eyePosition - vec2(5.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[1] = (eyePosition - vec2(4.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[2] = (eyePosition - vec2(3.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[3] = (eyePosition - vec2(2.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[4] = (eyePosition - vec2(1.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[5] = eyePosition / textureSize(textureName, 0);" - "textureCoordinates[6] = (eyePosition + vec2(1.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[7] = (eyePosition + vec2(2.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[8] = (eyePosition + vec2(3.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[9] = (eyePosition + vec2(4.0, 0.0)) / textureSize(textureName, 0);" - "textureCoordinates[10] = (eyePosition + vec2(5.0, 0.0)) / textureSize(textureName, 0);" + "textureCoordinates[0] = eyePosition + vec2(-5.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[1] = eyePosition + vec2(-4.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[2] = eyePosition + vec2(-3.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[3] = eyePosition + vec2(-2.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[4] = eyePosition + vec2(-1.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[5] = eyePosition;" + "textureCoordinates[6] = eyePosition + vec2(1.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[7] = eyePosition + vec2(2.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[8] = eyePosition + vec2(3.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[9] = eyePosition + vec2(4.0, 0.0) / textureSize(textureName, 0);" + "textureCoordinates[10] = eyePosition + vec2(5.0, 0.0) / textureSize(textureName, 0);" - "eyePosition = eyePosition / textureSize(textureName, 0);"; + "eyePosition = eyePosition;"; } return result + @@ -130,6 +155,7 @@ std::string ScanTarget::glsl_default_vertex_shader(ShaderType type) { } void ScanTarget::enable_vertex_attributes(ShaderType type, Shader &target) { + target.bind(); switch(type) { case ShaderType::InputScan: case ShaderType::ProcessedScan: @@ -280,7 +306,8 @@ std::unique_ptr ScanTarget::input_shader(InputDataType input_data_type, return std::unique_ptr(new Shader( glsl_globals(ShaderType::InputScan) + glsl_default_vertex_shader(ShaderType::InputScan), - fragment_shader + "}" + fragment_shader + "}", + attribute_bindings(ShaderType::InputScan) )); } @@ -302,11 +329,13 @@ std::unique_ptr ScanTarget::svideo_to_rgb_shader(int colour_cycle_numera "in vec2 textureCoordinates[11];" "uniform float textureWeights[11];" + "uniform usampler2D textureName;" "out vec4 fragColour;" "void main(void) {" - "fragColour = vec4(1.0);" - "}" + "fragColour = texture(textureName, textureCoordinates[5]);" + "}", + attribute_bindings(ShaderType::ProcessedScan) )); shader->set_uniform("textureWeights", GLint(sizeof(GLfloat)), GLsizei(coefficients.size()), coefficients.data()); return shader;