mirror of
https://github.com/TomHarte/CLK.git
synced 2026-03-13 02:42:08 +00:00
Attempt a line output shader.
This commit is contained in:
@@ -1237,6 +1237,7 @@
|
||||
4BF0BC722973318E00CCA2B5 /* RP5C01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC6F2973318E00CCA2B5 /* RP5C01.cpp */; };
|
||||
4BF437EE209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; };
|
||||
4BF437EF209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; };
|
||||
4BF64D672F33D27B001EB900 /* LineOutputShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF64D662F33D27B001EB900 /* LineOutputShader.cpp */; };
|
||||
4BF701A026FFD32300996424 /* AmigaBlitterTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BF7019F26FFD32300996424 /* AmigaBlitterTests.mm */; };
|
||||
4BF8D4C82516E27A00BBE21B /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BB8617024E22F4900A00E03 /* Accelerate.framework */; };
|
||||
4BF8D4D5251C11DD00BBE21B /* 65816Storage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF8D4D4251C11DD00BBE21B /* 65816Storage.cpp */; };
|
||||
@@ -2577,6 +2578,8 @@
|
||||
4BF437F0209D112F008CBD6B /* Sector.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Sector.hpp; sourceTree = "<group>"; };
|
||||
4BF4A2D91F534DB300B171F4 /* TargetPlatforms.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = TargetPlatforms.hpp; sourceTree = "<group>"; };
|
||||
4BF52672218E752E00313227 /* ScanTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = "<group>"; };
|
||||
4BF64D652F33D27B001EB900 /* LineOutputShader.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LineOutputShader.hpp; sourceTree = "<group>"; };
|
||||
4BF64D662F33D27B001EB900 /* LineOutputShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LineOutputShader.cpp; sourceTree = "<group>"; };
|
||||
4BF6606A1F281573002CB053 /* ClockReceiver.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ClockReceiver.hpp; sourceTree = "<group>"; };
|
||||
4BF7019F26FFD32300996424 /* AmigaBlitterTests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = AmigaBlitterTests.mm; sourceTree = "<group>"; };
|
||||
4BF8D4CD251C0C9C00BBE21B /* 65816.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = 65816.hpp; sourceTree = "<group>"; };
|
||||
@@ -5411,12 +5414,14 @@
|
||||
4BD235BF2F312C0C0094AFAE /* CompositionShader.cpp */,
|
||||
4BD235C12F312C0C0094AFAE /* CopyShader.cpp */,
|
||||
4BD235CB2F32A4C80094AFAE /* KernelShaders.cpp */,
|
||||
4BF64D662F33D27B001EB900 /* LineOutputShader.cpp */,
|
||||
4BD235C62F312C3A0094AFAE /* Rectangle.cpp */,
|
||||
4BD235C92F32A2780094AFAE /* CommonAtrributes.hpp */,
|
||||
4BD235BE2F312C0C0094AFAE /* CompositionShader.hpp */,
|
||||
4BD235C02F312C0C0094AFAE /* CopyShader.hpp */,
|
||||
4BD235C82F326A280094AFAE /* DirtyZone.hpp */,
|
||||
4BD235CA2F32A4C80094AFAE /* KernelShaders.hpp */,
|
||||
4BF64D652F33D27B001EB900 /* LineOutputShader.hpp */,
|
||||
4BD235C52F312C3A0094AFAE /* Rectangle.hpp */,
|
||||
);
|
||||
path = Shaders;
|
||||
@@ -6502,6 +6507,7 @@
|
||||
4B302185208A550100773308 /* DiskII.cpp in Sources */,
|
||||
42EB81292B23AAC300429AF4 /* IMD.cpp in Sources */,
|
||||
4B051CB1267C1CA200CA44E8 /* Keyboard.cpp in Sources */,
|
||||
4BF64D672F33D27B001EB900 /* LineOutputShader.cpp in Sources */,
|
||||
4B8855A72E84D51B00E251DD /* SAA5050.cpp in Sources */,
|
||||
4B0F1BB32602645900B85C66 /* StaticAnalyser.cpp in Sources */,
|
||||
4B055A931FAE85B50060FFFF /* BinaryDump.cpp in Sources */,
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "Outputs/OpenGL/Shaders/CompositionShader.hpp"
|
||||
#include "Outputs/OpenGL/Shaders/CopyShader.hpp"
|
||||
#include "Outputs/OpenGL/Shaders/KernelShaders.hpp"
|
||||
#include "Outputs/OpenGL/Shaders/LineOutputShader.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
@@ -127,6 +128,7 @@ ScanTarget::ScanTarget(const API api, const GLuint target_framebuffer, const flo
|
||||
unprocessed_line_texture_(api, LineBufferWidth, LineBufferHeight, UnprocessedLineBufferTextureUnit, GL_NEAREST, false),
|
||||
full_display_rectangle_(api, -1.0f, -1.0f, 2.0f, 2.0f),
|
||||
scans_(scan_buffer_),
|
||||
lines_(line_buffer_),
|
||||
dirty_zones_(dirty_zones_buffer_) {
|
||||
|
||||
set_scan_buffer(scan_buffer_.data(), scan_buffer_.size());
|
||||
@@ -327,8 +329,18 @@ void ScanTarget::setup_pipeline() {
|
||||
dirty_zones_,
|
||||
is_svideo(modals.display_type) ? CompositionTextureUnit : SeparationTextureUnit
|
||||
);
|
||||
|
||||
line_output_shader_ = OpenGL::line_output_shader(
|
||||
api_,
|
||||
buffer_width, 2048,
|
||||
modals.expected_vertical_lines,
|
||||
modals.output_scale.x, modals.output_scale.y,
|
||||
lines_,
|
||||
DemodulationTextureUnit
|
||||
);
|
||||
} else {
|
||||
demodulation_shader_.reset();
|
||||
line_output_shader_.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -164,6 +164,7 @@ private:
|
||||
std::array<DirtyZone, 2> dirty_zones_buffer_{};
|
||||
|
||||
VertexArray scans_;
|
||||
VertexArray lines_;
|
||||
VertexArray dirty_zones_;
|
||||
|
||||
Texture source_texture_;
|
||||
@@ -175,6 +176,7 @@ private:
|
||||
Shader composition_shader_;
|
||||
Shader separation_shader_;
|
||||
Shader demodulation_shader_;
|
||||
Shader line_output_shader_;
|
||||
CopyShader copy_shader_;
|
||||
};
|
||||
|
||||
|
||||
@@ -40,4 +40,14 @@ inline std::vector<std::string> dirty_zone_attributes() {
|
||||
};
|
||||
}
|
||||
|
||||
inline std::vector<std::string> line_attributes() {
|
||||
return std::vector<std::string>{
|
||||
"lineEndpoint0Position",
|
||||
"lineEndpoint0CyclesSinceRetrace",
|
||||
"lineEndpoint1Position",
|
||||
"lineEndpoint1CyclesSinceRetrace",
|
||||
"lineLine",
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
125
Outputs/OpenGL/Shaders/LineOutputShader.cpp
Normal file
125
Outputs/OpenGL/Shaders/LineOutputShader.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
//
|
||||
// LineOutputShader.cpp
|
||||
// Clock Signal Kiosk
|
||||
//
|
||||
// Created by Thomas Harte on 04/02/2026.
|
||||
// Copyright © 2026 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "LineOutputShader.hpp"
|
||||
|
||||
#include "CommonAtrributes.hpp"
|
||||
#include "Outputs/ScanTargets/BufferingScanTarget.hpp"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char vertex_shader[] = R"glsl(
|
||||
|
||||
uniform mediump vec2 sourceSize;
|
||||
uniform highp vec2 positionScale;
|
||||
uniform mediump float lineHeight;
|
||||
|
||||
// TODO: programmable crop should affect scaling via uniforms.
|
||||
|
||||
in highp vec2 lineEndpoint0Position;
|
||||
in highp float lineEndpoint0CyclesSinceRetrace;
|
||||
|
||||
in highp vec2 lineEndpoint1Position;
|
||||
in highp float lineEndpoint1CyclesSinceRetrace;
|
||||
|
||||
in highp float lineLine;
|
||||
|
||||
out mediump vec2 coordinate;
|
||||
|
||||
void main(void) {
|
||||
float lateral = float(gl_VertexID & 1);
|
||||
float longitudinal = float((gl_VertexID & 2) >> 1);
|
||||
|
||||
coordinate = vec2(
|
||||
mix(
|
||||
lineEndpoint0CyclesSinceRetrace,
|
||||
lineEndpoint1CyclesSinceRetrace,
|
||||
lateral
|
||||
),
|
||||
lineLine + 0.5
|
||||
) / sourceSize;
|
||||
|
||||
vec2 tangent = normalize(lineEndpoint1Position - lineEndpoint0Position);
|
||||
vec2 normal = vec2(tangent.y, -tangent.x);
|
||||
|
||||
vec2 centre =
|
||||
mix(
|
||||
lineEndpoint0Position,
|
||||
lineEndpoint1Position,
|
||||
lateral
|
||||
) / positionScale;
|
||||
gl_Position =
|
||||
vec4(
|
||||
centre + (longitudinal - 0.5) * normal,
|
||||
0.0,
|
||||
1.0
|
||||
);
|
||||
}
|
||||
|
||||
)glsl";
|
||||
|
||||
constexpr char fragment_shader[] = R"glsl(
|
||||
|
||||
uniform lowp sampler2D source;
|
||||
in mediump vec2 coordinate;
|
||||
|
||||
out lowp vec4 outputColour;
|
||||
|
||||
void main(void) {
|
||||
outputColour = texture(source, coordinate);
|
||||
}
|
||||
|
||||
)glsl";
|
||||
|
||||
}
|
||||
|
||||
using namespace Outputs::Display;
|
||||
|
||||
OpenGL::Shader OpenGL::line_output_shader(
|
||||
const API api,
|
||||
const int source_width,
|
||||
const int source_height,
|
||||
const int expected_vertical_lines,
|
||||
const int scale_x,
|
||||
const int scale_y,
|
||||
const VertexArray &vertex_array,
|
||||
const GLenum source_texture_unit
|
||||
) {
|
||||
auto shader = OpenGL::Shader(
|
||||
api,
|
||||
vertex_shader,
|
||||
fragment_shader,
|
||||
line_attributes()
|
||||
);
|
||||
|
||||
BufferingScanTarget::Line line;
|
||||
vertex_array.bind_all();
|
||||
const auto enable = [&](const std::string &name, uint16_t &element, const GLint size) {
|
||||
shader.enable_vertex_attribute_with_pointer(
|
||||
name,
|
||||
size,
|
||||
GL_UNSIGNED_SHORT,
|
||||
GL_FALSE,
|
||||
sizeof(line),
|
||||
reinterpret_cast<void *>((reinterpret_cast<uint8_t *>(&element) - reinterpret_cast<uint8_t *>(&line))),
|
||||
1
|
||||
);
|
||||
};
|
||||
enable("lineEndpoint0Position", line.end_points[0].x, 2);
|
||||
enable("lineEndpoint0CyclesSinceRetrace", line.end_points[0].cycles_since_end_of_horizontal_retrace, 1);
|
||||
enable("lineEndpoint1Position", line.end_points[1].x, 2);
|
||||
enable("lineEndpoin10CyclesSinceRetrace", line.end_points[1].cycles_since_end_of_horizontal_retrace, 1);
|
||||
enable("lineLine", line.line, 1);
|
||||
|
||||
shader.set_uniform("lineHeight", 1.0f / float(expected_vertical_lines));
|
||||
shader.set_uniform("positionScale", float(scale_x), float(scale_y));
|
||||
shader.set_uniform("sourceSize", float(source_width), float(source_height));
|
||||
shader.set_uniform("source", GLint(source_texture_unit - GL_TEXTURE0));
|
||||
|
||||
return shader;
|
||||
}
|
||||
30
Outputs/OpenGL/Shaders/LineOutputShader.hpp
Normal file
30
Outputs/OpenGL/Shaders/LineOutputShader.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// LineOutputShader.hpp
|
||||
// Clock Signal Kiosk
|
||||
//
|
||||
// Created by Thomas Harte on 04/02/2026.
|
||||
// Copyright © 2026 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Outputs/OpenGL/Primitives/VertexArray.hpp"
|
||||
#include "Outputs/OpenGL/Primitives/Shader.hpp"
|
||||
|
||||
namespace Outputs::Display::OpenGL {
|
||||
|
||||
/*!
|
||||
Using `Line`s as input, draws output spans.
|
||||
*/
|
||||
Shader line_output_shader(
|
||||
API,
|
||||
int source_width,
|
||||
int source_height,
|
||||
int expected_vertical_lines,
|
||||
int scale_x,
|
||||
int scale_y,
|
||||
const VertexArray &,
|
||||
GLenum source_texture_unit
|
||||
);
|
||||
|
||||
}
|
||||
@@ -74,6 +74,7 @@ public:
|
||||
uint8_t composite_amplitude;
|
||||
uint16_t line;
|
||||
};
|
||||
static_assert(sizeof(Line) == 20);
|
||||
|
||||
/// Provides additional metadata about lines; this is separate because it's unlikely to be of
|
||||
/// interest to the GPU, unlike the fields in Line.
|
||||
|
||||
@@ -166,6 +166,7 @@ set(CLK_SOURCES
|
||||
Outputs/OpenGL/Shaders/CompositionShader.cpp
|
||||
Outputs/OpenGL/Shaders/CopyShader.cpp
|
||||
Outputs/OpenGL/Shaders/KernelShaders.cpp
|
||||
Outputs/OpenGL/Shaders/LineOutputShader.cpp
|
||||
Outputs/OpenGL/Shaders/Rectangle.cpp
|
||||
Outputs/OpenGL/ScanTarget.cpp
|
||||
Outputs/OpenGL/ScanTargetGLSLFragments.cpp
|
||||
|
||||
Reference in New Issue
Block a user