From 4d0a218a576fe0677c41cdd52e25c9a39a5c4842 Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Sun, 7 Feb 2016 17:32:38 -0500 Subject: [PATCH] Certainly at least seriously considering a separate holder for the "compile a shader" logic. Otherwise taking steps back towards PAL/NTSC decoding. --- .../Clock Signal.xcodeproj/project.pbxproj | 10 ++++++-- Outputs/CRT/CRT.cpp | 14 +++++++---- Outputs/CRT/CRT.hpp | 23 ++++++++++++++++--- Outputs/CRT/CRTOpenGL.cpp | 7 +++++- Outputs/CRT/{OpenGL.h => OpenGL.hpp} | 0 Outputs/CRT/Shader.cpp | 9 ++++++++ Outputs/CRT/Shader.hpp | 22 ++++++++++++++++++ Outputs/CRT/TextureTarget.hpp | 2 +- 8 files changed, 75 insertions(+), 12 deletions(-) rename Outputs/CRT/{OpenGL.h => OpenGL.hpp} (100%) create mode 100644 Outputs/CRT/Shader.cpp create mode 100644 Outputs/CRT/Shader.hpp diff --git a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj index fd262e6e2..b521ea229 100644 --- a/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj +++ b/OSBindings/Mac/Clock Signal.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 4B1414601B58885000E04248 /* WolfgangLorenzTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B14145F1B58885000E04248 /* WolfgangLorenzTests.swift */; }; 4B1414621B58888700E04248 /* KlausDormannTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1414611B58888700E04248 /* KlausDormannTests.swift */; }; 4B2039941C67E20B001375C3 /* TextureTarget.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2039921C67E20B001375C3 /* TextureTarget.cpp */; }; + 4B2039991C67FA92001375C3 /* Shader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2039971C67FA92001375C3 /* Shader.cpp */; }; 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2409531C45AB05004DA684 /* Speaker.cpp */; }; 4B2E2D951C399D1200138695 /* ElectronDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4B2E2D931C399D1200138695 /* ElectronDocument.xib */; }; 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B2E2D971C3A06EC00138695 /* Atari2600.cpp */; }; @@ -343,7 +344,9 @@ 4B1414611B58888700E04248 /* KlausDormannTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KlausDormannTests.swift; sourceTree = ""; }; 4B2039921C67E20B001375C3 /* TextureTarget.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureTarget.cpp; sourceTree = ""; }; 4B2039931C67E20B001375C3 /* TextureTarget.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = TextureTarget.hpp; sourceTree = ""; }; - 4B2039951C67E2A3001375C3 /* OpenGL.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OpenGL.h; sourceTree = ""; }; + 4B2039951C67E2A3001375C3 /* OpenGL.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = ""; }; + 4B2039971C67FA92001375C3 /* Shader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Shader.cpp; sourceTree = ""; }; + 4B2039981C67FA92001375C3 /* Shader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Shader.hpp; sourceTree = ""; }; 4B2409531C45AB05004DA684 /* Speaker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Speaker.cpp; path = ../../Outputs/Speaker.cpp; sourceTree = ""; }; 4B2409541C45AB05004DA684 /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Speaker.hpp; path = ../../Outputs/Speaker.hpp; sourceTree = ""; }; 4B24095A1C45DF85004DA684 /* Stepper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Stepper.hpp; sourceTree = ""; }; @@ -696,7 +699,9 @@ 4B7BFEFD1C6446EF00089C1C /* CRTFrameBuilder.cpp */, 4B2039921C67E20B001375C3 /* TextureTarget.cpp */, 4B2039931C67E20B001375C3 /* TextureTarget.hpp */, - 4B2039951C67E2A3001375C3 /* OpenGL.h */, + 4B2039951C67E2A3001375C3 /* OpenGL.hpp */, + 4B2039971C67FA92001375C3 /* Shader.cpp */, + 4B2039981C67FA92001375C3 /* Shader.hpp */, ); name = CRT; path = ../../Outputs/CRT; @@ -1623,6 +1628,7 @@ 4B2409551C45AB05004DA684 /* Speaker.cpp in Sources */, 4B55CE4E1C3B3BDA0093A61B /* CSMachine.mm in Sources */, 4B2E2D9D1C3A070400138695 /* Electron.cpp in Sources */, + 4B2039991C67FA92001375C3 /* Shader.cpp in Sources */, 4B69FB3D1C4D908A00B5F0AA /* Tape.cpp in Sources */, 4B55CE5D1C3B7D6F0093A61B /* CSCathodeRayView.m in Sources */, 4B2E2D9A1C3A06EC00138695 /* Atari2600.cpp in Sources */, diff --git a/Outputs/CRT/CRT.cpp b/Outputs/CRT/CRT.cpp index dde71349e..b80bbc6dc 100644 --- a/Outputs/CRT/CRT.cpp +++ b/Outputs/CRT/CRT.cpp @@ -25,8 +25,12 @@ static const uint32_t kCRTFixedPointOffset = 0x04000000; #define kRetraceXMask 0x01 #define kRetraceYMask 0x02 -void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator) +void CRT::set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display, ColourSpace colour_space, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator) { + _colour_space = colour_space; + _colour_cycle_numerator = colour_cycle_numerator; + _colour_cycle_denominator = colour_cycle_denominator; + const unsigned int syncCapacityLineChargeThreshold = 3; const unsigned int millisecondsHorizontalRetraceTime = 7; // source: Dictionary of Video and Television Technology, p. 234 const unsigned int scanlinesVerticalRetraceTime = 10; // source: ibid @@ -72,11 +76,11 @@ void CRT::set_new_display_type(unsigned int cycles_per_line, DisplayType display switch(displayType) { case DisplayType::PAL50: - set_new_timing(cycles_per_line, 312, 1135, 4); + set_new_timing(cycles_per_line, 312, ColourSpace::YUV, 1135, 4); break; case DisplayType::NTSC60: - set_new_timing(cycles_per_line, 262, 545, 2); + set_new_timing(cycles_per_line, 262, ColourSpace::YIQ, 545, 2); break; } } @@ -111,9 +115,9 @@ CRT::CRT() : construct_openGL(); } -CRT::CRT(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator, unsigned int number_of_buffers, ...) : CRT() +CRT::CRT(unsigned int cycles_per_line, unsigned int height_of_display, ColourSpace colour_space, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator, unsigned int number_of_buffers, ...) : CRT() { - set_new_timing(cycles_per_line, height_of_display, colour_cycle_numerator, colour_cycle_denominator); + set_new_timing(cycles_per_line, height_of_display, colour_space, colour_cycle_numerator, colour_cycle_denominator); va_list buffer_sizes; va_start(buffer_sizes, number_of_buffers); diff --git a/Outputs/CRT/CRT.hpp b/Outputs/CRT/CRT.hpp index 58d818b9e..ce8d6a3f2 100644 --- a/Outputs/CRT/CRT.hpp +++ b/Outputs/CRT/CRT.hpp @@ -28,6 +28,16 @@ class CRT { NTSC60 }; + enum ColourSpace { + YIQ, + YUV + }; + + enum OutputDevice { + Monitor, + Television + }; + /*! Constructs the CRT with a specified clock rate, height and colour subcarrier frequency. The requested number of buffers, each with the requested number of bytes per pixel, is created for the machine to write raw pixel data to. @@ -55,7 +65,7 @@ class CRT { @see @c set_rgb_sampling_function , @c set_composite_sampling_function */ - CRT(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator, unsigned int number_of_buffers, ...); + CRT(unsigned int cycles_per_line, unsigned int height_of_display, ColourSpace colour_space, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator, unsigned int number_of_buffers, ...); /*! Constructs the CRT with the specified clock rate, with the display height and colour subcarrier frequency dictated by a standard display type and with the requested number of @@ -68,7 +78,7 @@ class CRT { /*! Resets the CRT with new timing information. The CRT then continues as though the new timing had been provided at construction. */ - void set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator); + void set_new_timing(unsigned int cycles_per_line, unsigned int height_of_display, ColourSpace colour_space, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator); /*! Resets the CRT with new timing information derived from a new display type. The CRT then continues as though the new timing had been provided at construction. */ @@ -182,7 +192,9 @@ class CRT { `float phase_for_clock_cycle(int cycle)` that returns the colour phase at the beginning of the supplied cycle. */ - void set_phase_function(const char *shader); +// void set_phase_function(const char *shader); + + void set_output_device(OutputDevice output_device); private: CRT(); @@ -196,6 +208,11 @@ class CRT { unsigned int _cycles_per_line; unsigned int _height_of_display; + // colour invormation + ColourSpace _colour_space; + unsigned int _colour_cycle_numerator; + unsigned int _colour_cycle_denominator; + // properties directly derived from there unsigned int _hsync_error_window; // the permitted window around the expected sync position in which a sync pulse will be recognised; calculated once at init diff --git a/Outputs/CRT/CRTOpenGL.cpp b/Outputs/CRT/CRTOpenGL.cpp index e20fb1f18..2a7a37266 100644 --- a/Outputs/CRT/CRTOpenGL.cpp +++ b/Outputs/CRT/CRTOpenGL.cpp @@ -9,7 +9,8 @@ #include "CRT.hpp" #include -#include "OpenGL.h" +#include "OpenGL.hpp" +#include "TextureTarget.hpp" using namespace Outputs; @@ -30,6 +31,10 @@ struct CRT::OpenGLState { CRTSize textureSize; + OpenGL::TextureTarget *compositeTexture; + OpenGL::TextureTarget *colourTexture; + OpenGL::TextureTarget *filteredTexture; + GLuint compile_shader(const char *source, GLenum type) { GLuint shader = glCreateShader(type); diff --git a/Outputs/CRT/OpenGL.h b/Outputs/CRT/OpenGL.hpp similarity index 100% rename from Outputs/CRT/OpenGL.h rename to Outputs/CRT/OpenGL.hpp diff --git a/Outputs/CRT/Shader.cpp b/Outputs/CRT/Shader.cpp new file mode 100644 index 000000000..aae0b835a --- /dev/null +++ b/Outputs/CRT/Shader.cpp @@ -0,0 +1,9 @@ +// +// Shader.cpp +// Clock Signal +// +// Created by Thomas Harte on 07/02/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#include "Shader.hpp" diff --git a/Outputs/CRT/Shader.hpp b/Outputs/CRT/Shader.hpp new file mode 100644 index 000000000..1d9046035 --- /dev/null +++ b/Outputs/CRT/Shader.hpp @@ -0,0 +1,22 @@ +// +// Shader.hpp +// Clock Signal +// +// Created by Thomas Harte on 07/02/2016. +// Copyright © 2016 Thomas Harte. All rights reserved. +// + +#ifndef Shader_hpp +#define Shader_hpp + +namespace OpenGL { + class Shader { + public: + Shader(const char *vertex_shader, const char *fragment_shader); + ~Shader(); + + void bind(); + }; +} + +#endif /* Shader_hpp */ diff --git a/Outputs/CRT/TextureTarget.hpp b/Outputs/CRT/TextureTarget.hpp index f98ad8305..b4b77f42d 100644 --- a/Outputs/CRT/TextureTarget.hpp +++ b/Outputs/CRT/TextureTarget.hpp @@ -9,7 +9,7 @@ #ifndef TextureTarget_hpp #define TextureTarget_hpp -#include "OpenGL.h" +#include "OpenGL.hpp" namespace OpenGL {