diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index 63ccd6d7a..b1ebd39f6 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -1164,6 +1164,7 @@ 4BD191F52191180E0042E144 /* ScanTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD191F22191180E0042E144 /* ScanTarget.cpp */; }; 4BD235B42F27AC680094AFAE /* CompositionShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD235B32F27AC680094AFAE /* CompositionShader.cpp */; }; 4BD235B72F2C11A40094AFAE /* VertexArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD235B62F2C11A40094AFAE /* VertexArray.cpp */; }; + 4BD235BA2F2C22280094AFAE /* CopyShader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD235B92F2C22280094AFAE /* CopyShader.cpp */; }; 4BD388882239E198002D14B5 /* 68000Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BD388872239E198002D14B5 /* 68000Tests.mm */; }; 4BD424E02193B5340097291A /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD424DD2193B5340097291A /* TextureTarget.cpp */; }; 4BD424E62193B5830097291A /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD424E12193B5820097291A /* Shader.cpp */; }; @@ -2466,6 +2467,8 @@ 4BD235B32F27AC680094AFAE /* CompositionShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CompositionShader.cpp; sourceTree = ""; }; 4BD235B52F2C11A40094AFAE /* VertexArray.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = VertexArray.hpp; sourceTree = ""; }; 4BD235B62F2C11A40094AFAE /* VertexArray.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VertexArray.cpp; sourceTree = ""; }; + 4BD235B82F2C22280094AFAE /* CopyShader.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = CopyShader.hpp; sourceTree = ""; }; + 4BD235B92F2C22280094AFAE /* CopyShader.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CopyShader.cpp; sourceTree = ""; }; 4BD388411FE34E010042B588 /* 9918Base.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = 9918Base.hpp; sourceTree = ""; }; 4BD388872239E198002D14B5 /* 68000Tests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = 68000Tests.mm; sourceTree = ""; }; 4BD424DD2193B5340097291A /* TextureTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureTarget.cpp; sourceTree = ""; }; @@ -5383,10 +5386,12 @@ isa = PBXGroup; children = ( 4BD235B32F27AC680094AFAE /* CompositionShader.cpp */, + 4BD235B92F2C22280094AFAE /* CopyShader.cpp */, 4BD191F22191180E0042E144 /* ScanTarget.cpp */, 4BD5D2672199148100DDF17D /* ScanTargetGLSLFragments.cpp */, 4BA3AF5C2EF252320088C3BC /* API.hpp */, 4BD235B22F27AC680094AFAE /* CompositionShader.hpp */, + 4BD235B82F2C22280094AFAE /* CopyShader.hpp */, 4BD191D9219113B80042E144 /* OpenGL.hpp */, 4BD191F32191180E0042E144 /* ScanTarget.hpp */, 4B961408222760E0001A7BF2 /* Screenshot.hpp */, @@ -6270,6 +6275,7 @@ 4B2E86D025D8D8C70024F1E9 /* Keyboard.cpp in Sources */, 4B89452F201967B4007DE474 /* StaticAnalyser.cpp in Sources */, 4B894531201967B4007DE474 /* StaticAnalyser.cpp in Sources */, + 4BD235BA2F2C22280094AFAE /* CopyShader.cpp in Sources */, 4BB5057B2B962DDF0031C43C /* Electron.cpp in Sources */, 4B0ACC2D23775819008902D0 /* IntelligentKeyboard.cpp in Sources */, 4B894539201967B4007DE474 /* Tape.cpp in Sources */, diff --git a/Outputs/OpenGL/CopyShader.cpp b/Outputs/OpenGL/CopyShader.cpp new file mode 100644 index 000000000..404c9cf6f --- /dev/null +++ b/Outputs/OpenGL/CopyShader.cpp @@ -0,0 +1,90 @@ +// +// CopyShader.cpp +// Clock Signal Kiosk +// +// Created by Thomas Harte on 29/01/2026. +// Copyright © 2026 Thomas Harte. All rights reserved. +// + +#include "CopyShader.hpp" + +namespace { + +constexpr char vertex_shader[] = R"glsl( + +out mediump vec2 coordinate; + +void main(void) { + float lateral = float(gl_VertexID & 1); + float longitudinal = float((gl_VertexID & 2) >> 1); + + gl_Position = vec4) + lateral * 2.0 - 1.0, + longitudinal * 2.0 - 1.0, + 0.0, + 1.0 + ); +} + +)glsl"; + + +constexpr char fragment_shader[] = R"glsl( + +uniform sampler2D source; +uniform float brightness; +uniform float gamma; + +in mediump vec2 coordinate; + +out lowp vec4 outputColour; + +void main(void) { + outputColour = texture(source, coordinate); + +#ifdef APPLY_BRIGHTNESS + outputColour *= brightness; +#endif + +#ifdef APPLY_GAMMA + outputColour = pow(outputColour, gamma); +#endif +} + +)glsl"; + +} + +using namespace Outputs::Display; + +OpenGL::Shader OpenGL::copy_shader( + const OpenGL::API api, + const GLenum source_texture_unit, + std::optional brightness, + std::optional gamma +) { + std::string prefix; + + if(brightness) { + prefix += "#define APPLY_BRIGHTNESS\n"; + } + if(gamma) { + prefix += "#define APPLY_GAMMA\n"; + } + + auto shader = OpenGL::Shader( + api, + prefix + vertex_shader, + prefix + fragment_shader + ); + + shader.set_uniform("source", GLint(source_texture_unit - GL_TEXTURE0)); + if(brightness) { + shader.set_uniform("brightness", *brightness); + } + if(gamma) { + shader.set_uniform("gamma", *gamma); + } + + return shader; +} diff --git a/Outputs/OpenGL/CopyShader.hpp b/Outputs/OpenGL/CopyShader.hpp new file mode 100644 index 000000000..07379bc2e --- /dev/null +++ b/Outputs/OpenGL/CopyShader.hpp @@ -0,0 +1,28 @@ +// +// CopyShader.hpp +// Clock Signal Kiosk +// +// Created by Thomas Harte on 29/01/2026. +// Copyright © 2026 Thomas Harte. All rights reserved. +// + +#pragma once + +#include "Outputs/OpenGL/Primitives/Shader.hpp" + +#include + +namespace Outputs::Display::OpenGL { + +/*! + Copies a source texture in its entirety to a destination, optionally applying + a change in brightness and a gamma adjustment. +*/ +Shader copy_shader( + API, + const GLenum source_texture_unit, + std::optional brightness, + std::optional gamma +); + +} diff --git a/cmake/CLK_SOURCES.cmake b/cmake/CLK_SOURCES.cmake index cb1cc753b..e45f310a0 100644 --- a/cmake/CLK_SOURCES.cmake +++ b/cmake/CLK_SOURCES.cmake @@ -164,6 +164,7 @@ set(CLK_SOURCES Outputs/OpenGL/Primitives/TextureTarget.cpp Outputs/OpenGL/Primitives/VertexArray.cpp Outputs/OpenGL/CompositionShader.cpp + Outputs/OpenGL/CopyShader.cpp Outputs/OpenGL/ScanTarget.cpp Outputs/OpenGL/ScanTargetGLSLFragments.cpp Outputs/ScanTarget.cpp