mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-28 22:29:36 +00:00
Removes some migrated work.
This commit is contained in:
parent
0ba3ae53ab
commit
d5af1f3948
@ -1363,8 +1363,6 @@
|
||||
4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Oric.cpp; path = Oric/Oric.cpp; sourceTree = "<group>"; };
|
||||
4BCF1FA31DADC3DD0039D2E7 /* Oric.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Oric.hpp; path = Oric/Oric.hpp; sourceTree = "<group>"; };
|
||||
4BD060A51FE49D3C006E14BE /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Speaker.hpp; sourceTree = "<group>"; };
|
||||
4BD191D6219113B80042E144 /* ArrayBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ArrayBuilder.cpp; sourceTree = "<group>"; };
|
||||
4BD191D7219113B80042E144 /* CRTOpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CRTOpenGL.hpp; sourceTree = "<group>"; };
|
||||
4BD191D8219113B80042E144 /* TextureBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextureBuilder.cpp; sourceTree = "<group>"; };
|
||||
4BD191D9219113B80042E144 /* OpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = "<group>"; };
|
||||
4BD191DC219113B80042E144 /* CRTOpenGL.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CRTOpenGL.cpp; sourceTree = "<group>"; };
|
||||
@ -1373,7 +1371,6 @@
|
||||
4BD191E1219113B80042E144 /* OutputShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OutputShader.cpp; sourceTree = "<group>"; };
|
||||
4BD191E3219113B80042E144 /* IntermediateShader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntermediateShader.cpp; sourceTree = "<group>"; };
|
||||
4BD191E4219113B80042E144 /* OutputShader.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OutputShader.hpp; sourceTree = "<group>"; };
|
||||
4BD191E7219113B90042E144 /* ArrayBuilder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ArrayBuilder.hpp; sourceTree = "<group>"; };
|
||||
4BD191F22191180E0042E144 /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScanTarget.cpp; sourceTree = "<group>"; };
|
||||
4BD191F32191180E0042E144 /* ScanTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = "<group>"; };
|
||||
4BD388411FE34E010042B588 /* 9918Base.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = 9918Base.hpp; path = 9918/Implementation/9918Base.hpp; sourceTree = "<group>"; };
|
||||
@ -3025,12 +3022,9 @@
|
||||
4BD191D5219113B80042E144 /* OpenGL */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4BD191D6219113B80042E144 /* ArrayBuilder.cpp */,
|
||||
4BD191DC219113B80042E144 /* CRTOpenGL.cpp */,
|
||||
4BD191F22191180E0042E144 /* ScanTarget.cpp */,
|
||||
4BD191D8219113B80042E144 /* TextureBuilder.cpp */,
|
||||
4BD191E7219113B90042E144 /* ArrayBuilder.hpp */,
|
||||
4BD191D7219113B80042E144 /* CRTOpenGL.hpp */,
|
||||
4BD191D9219113B80042E144 /* OpenGL.hpp */,
|
||||
4BD191F32191180E0042E144 /* ScanTarget.hpp */,
|
||||
4BD191DD219113B80042E144 /* TextureBuilder.hpp */,
|
||||
|
@ -1,149 +0,0 @@
|
||||
//
|
||||
// ArrayBuilder.cpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 17/11/2016.
|
||||
// Copyright 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#include "ArrayBuilder.hpp"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
using namespace Outputs::CRT;
|
||||
|
||||
ArrayBuilder::ArrayBuilder(std::size_t input_size, std::size_t output_size) :
|
||||
output_(output_size, nullptr),
|
||||
input_(input_size, nullptr) {}
|
||||
|
||||
ArrayBuilder::ArrayBuilder(std::size_t input_size, std::size_t output_size, std::function<void(bool is_input, uint8_t *, std::size_t)> submission_function) :
|
||||
output_(output_size, submission_function),
|
||||
input_(input_size, submission_function) {}
|
||||
|
||||
bool ArrayBuilder::is_full() {
|
||||
bool was_full;
|
||||
was_full = is_full_;
|
||||
return was_full;
|
||||
}
|
||||
|
||||
uint8_t *ArrayBuilder::get_input_storage(std::size_t size) {
|
||||
return get_storage(size, input_);
|
||||
}
|
||||
|
||||
uint8_t *ArrayBuilder::get_output_storage(std::size_t size) {
|
||||
return get_storage(size, output_);
|
||||
}
|
||||
|
||||
void ArrayBuilder::flush(const std::function<void(uint8_t *input, std::size_t input_size, uint8_t *output, std::size_t output_size)> &function) {
|
||||
if(!is_full_) {
|
||||
std::size_t input_size = 0, output_size = 0;
|
||||
uint8_t *input = input_.get_unflushed(input_size);
|
||||
uint8_t *output = output_.get_unflushed(output_size);
|
||||
function(input, input_size, output, output_size);
|
||||
|
||||
input_.flush();
|
||||
output_.flush();
|
||||
}
|
||||
}
|
||||
|
||||
void ArrayBuilder::bind_input() {
|
||||
input_.bind();
|
||||
}
|
||||
|
||||
void ArrayBuilder::bind_output() {
|
||||
output_.bind();
|
||||
}
|
||||
|
||||
ArrayBuilder::Submission ArrayBuilder::submit() {
|
||||
ArrayBuilder::Submission submission;
|
||||
|
||||
submission.input_size = input_.submit(true);
|
||||
submission.output_size = output_.submit(false);
|
||||
if(is_full_) {
|
||||
is_full_ = false;
|
||||
input_.reset();
|
||||
output_.reset();
|
||||
}
|
||||
|
||||
return submission;
|
||||
}
|
||||
|
||||
ArrayBuilder::Buffer::Buffer(std::size_t size, std::function<void(bool is_input, uint8_t *, std::size_t)> submission_function) :
|
||||
submission_function_(submission_function) {
|
||||
if(!submission_function_) {
|
||||
glGenBuffers(1, &buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)size, NULL, GL_STREAM_DRAW);
|
||||
}
|
||||
data.resize(size);
|
||||
}
|
||||
|
||||
ArrayBuilder::Buffer::~Buffer() {
|
||||
if(!submission_function_)
|
||||
glDeleteBuffers(1, &buffer);
|
||||
}
|
||||
|
||||
uint8_t *ArrayBuilder::get_storage(std::size_t size, Buffer &buffer) {
|
||||
uint8_t *pointer = buffer.get_storage(size);
|
||||
if(!pointer) is_full_ = true;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
uint8_t *ArrayBuilder::Buffer::get_storage(std::size_t size) {
|
||||
if(is_full || allocated_data + size > data.size()) {
|
||||
is_full = true;
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t *pointer = &data[allocated_data];
|
||||
allocated_data += size;
|
||||
return pointer;
|
||||
}
|
||||
|
||||
uint8_t *ArrayBuilder::Buffer::get_unflushed(std::size_t &size) {
|
||||
if(is_full) {
|
||||
return nullptr;
|
||||
}
|
||||
size = allocated_data - flushed_data;
|
||||
return &data[flushed_data];
|
||||
}
|
||||
|
||||
void ArrayBuilder::Buffer::flush() {
|
||||
if(submitted_data) {
|
||||
memmove(data.data(), &data[submitted_data], allocated_data - submitted_data);
|
||||
allocated_data -= submitted_data;
|
||||
flushed_data -= submitted_data;
|
||||
submitted_data = 0;
|
||||
}
|
||||
|
||||
flushed_data = allocated_data;
|
||||
}
|
||||
|
||||
std::size_t ArrayBuilder::Buffer::submit(bool is_input) {
|
||||
std::size_t length = flushed_data;
|
||||
if(submission_function_) {
|
||||
submission_function_(is_input, data.data(), length);
|
||||
} else {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
uint8_t *destination = static_cast<uint8_t *>(glMapBufferRange(GL_ARRAY_BUFFER, 0, (GLsizeiptr)length, GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_FLUSH_EXPLICIT_BIT));
|
||||
if(!glGetError() && destination) {
|
||||
std::memcpy(destination, data.data(), length);
|
||||
glFlushMappedBufferRange(GL_ARRAY_BUFFER, 0, (GLsizeiptr)length);
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
} else {
|
||||
glBufferData(GL_ARRAY_BUFFER, (GLsizeiptr)length, data.data(), GL_STREAM_DRAW);
|
||||
}
|
||||
}
|
||||
submitted_data = flushed_data;
|
||||
return length;
|
||||
}
|
||||
|
||||
void ArrayBuilder::Buffer::bind() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
}
|
||||
|
||||
void ArrayBuilder::Buffer::reset() {
|
||||
is_full = false;
|
||||
allocated_data = 0;
|
||||
flushed_data = 0;
|
||||
submitted_data = 0;
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
//
|
||||
// ArrayBuilder.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 17/11/2016.
|
||||
// Copyright 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef ArrayBuilder_hpp
|
||||
#define ArrayBuilder_hpp
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "OpenGL.hpp"
|
||||
|
||||
namespace Outputs {
|
||||
namespace CRT {
|
||||
|
||||
/*!
|
||||
Owns two array buffers, an 'input' and an 'output' and vends pointers to allow an owner to write provisional data into those
|
||||
plus a flush function to lock provisional data into place. Also supplies a submit method to transfer all currently locked
|
||||
data to the GPU and bind_input/output methods to bind the internal buffers.
|
||||
|
||||
It is safe for one thread to communicate via the get_*_storage and flush inputs asynchronously from another that is making
|
||||
use of the bind and submit outputs.
|
||||
*/
|
||||
class ArrayBuilder {
|
||||
public:
|
||||
/// Creates an instance of ArrayBuilder with @c output_size bytes of storage for the output buffer and
|
||||
/// @c input_size bytes of storage for the input buffer.
|
||||
ArrayBuilder(std::size_t input_size, std::size_t output_size);
|
||||
|
||||
/// Creates an instance of ArrayBuilder with @c output_size bytes of storage for the output buffer and
|
||||
/// @c input_size bytes of storage for the input buffer that, rather than using OpenGL, will submit data
|
||||
/// to the @c submission_function. [Teleological: this is provided as a testing hook.]
|
||||
ArrayBuilder(std::size_t input_size, std::size_t output_size, std::function<void(bool is_input, uint8_t *, std::size_t)> submission_function);
|
||||
|
||||
/// Attempts to add @c size bytes to the input set.
|
||||
/// @returns a pointer to the allocated area if allocation was possible; @c nullptr otherwise.
|
||||
uint8_t *get_input_storage(std::size_t size);
|
||||
|
||||
/// Attempts to add @c size bytes to the output set.
|
||||
/// @returns a pointer to the allocated area if allocation was possible; @c nullptr otherwise.
|
||||
uint8_t *get_output_storage(std::size_t size);
|
||||
|
||||
/// @returns @c true if either of the input or output storage areas is currently exhausted; @c false otherwise.
|
||||
bool is_full();
|
||||
|
||||
/// If neither input nor output was exhausted since the last flush, atomically commits both input and output
|
||||
/// up to the currently allocated size for use upon the next @c submit, giving the supplied function a
|
||||
/// chance to perform last-minute processing. Otherwise acts as a no-op.
|
||||
void flush(const std::function<void(uint8_t *input, std::size_t input_size, uint8_t *output, std::size_t output_size)> &);
|
||||
|
||||
/// Binds the input array to GL_ARRAY_BUFFER.
|
||||
void bind_input();
|
||||
|
||||
/// Binds the output array to GL_ARRAY_BUFFER.
|
||||
void bind_output();
|
||||
|
||||
struct Submission {
|
||||
std::size_t input_size, output_size;
|
||||
};
|
||||
|
||||
/// Submits all flushed input and output data to the corresponding arrays.
|
||||
/// @returns A @c Submission record, indicating how much data of each type was submitted.
|
||||
Submission submit();
|
||||
|
||||
private:
|
||||
class Buffer {
|
||||
public:
|
||||
Buffer(std::size_t size, std::function<void(bool is_input, uint8_t *, std::size_t)> submission_function);
|
||||
~Buffer();
|
||||
|
||||
uint8_t *get_storage(std::size_t size);
|
||||
uint8_t *get_unflushed(std::size_t &size);
|
||||
|
||||
void flush();
|
||||
std::size_t submit(bool is_input);
|
||||
void bind();
|
||||
void reset();
|
||||
|
||||
private:
|
||||
bool is_full = false;
|
||||
GLuint buffer = 0;
|
||||
std::function<void(bool is_input, uint8_t *, std::size_t)> submission_function_;
|
||||
std::vector<uint8_t> data;
|
||||
std::size_t allocated_data = 0;
|
||||
std::size_t flushed_data = 0;
|
||||
std::size_t submitted_data = 0;
|
||||
} output_, input_;
|
||||
uint8_t *get_storage(std::size_t size, Buffer &buffer);
|
||||
|
||||
bool is_full_ = false;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* ArrayBuilder_hpp */
|
@ -1,181 +0,0 @@
|
||||
//
|
||||
// CRTOpenGL.hpp
|
||||
// Clock Signal
|
||||
//
|
||||
// Created by Thomas Harte on 13/02/2016.
|
||||
// Copyright 2016 Thomas Harte. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef CRTOpenGL_h
|
||||
#define CRTOpenGL_h
|
||||
|
||||
#include "CRTConstants.hpp"
|
||||
#include "OpenGL.hpp"
|
||||
#include "TextureTarget.hpp"
|
||||
#include "Shaders/Shader.hpp"
|
||||
|
||||
#include "ArrayBuilder.hpp"
|
||||
#include "TextureBuilder.hpp"
|
||||
|
||||
#include "Shaders/OutputShader.hpp"
|
||||
#include "Shaders/IntermediateShader.hpp"
|
||||
#include "Rectangle.hpp"
|
||||
|
||||
#include "../ScanTarget.hpp"
|
||||
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace Outputs {
|
||||
namespace CRT {
|
||||
|
||||
class OpenGLOutputBuilder {
|
||||
private:
|
||||
// colour information
|
||||
ColourSpace colour_space_;
|
||||
unsigned int colour_cycle_numerator_;
|
||||
unsigned int colour_cycle_denominator_;
|
||||
VideoSignal video_signal_;
|
||||
float gamma_;
|
||||
|
||||
// timing information to allow reasoning about input information
|
||||
unsigned int input_frequency_;
|
||||
unsigned int cycles_per_line_;
|
||||
unsigned int height_of_display_;
|
||||
unsigned int horizontal_scan_period_;
|
||||
unsigned int vertical_scan_period_;
|
||||
unsigned int vertical_period_divider_;
|
||||
|
||||
// The user-supplied visible area
|
||||
Rect visible_area_;
|
||||
|
||||
// Other things the caller may have provided.
|
||||
std::string composite_shader_;
|
||||
std::string svideo_shader_;
|
||||
std::string rgb_shader_;
|
||||
GLint target_framebuffer_ = 0;
|
||||
|
||||
// Methods used by the OpenGL code
|
||||
void prepare_output_shader();
|
||||
void prepare_rgb_input_shaders();
|
||||
void prepare_svideo_input_shaders();
|
||||
void prepare_composite_input_shaders();
|
||||
|
||||
void prepare_output_vertex_array();
|
||||
void prepare_source_vertex_array();
|
||||
|
||||
// the run and input data buffers
|
||||
std::mutex output_mutex_;
|
||||
std::mutex draw_mutex_;
|
||||
|
||||
// transient buffers indicating composite data not yet decoded
|
||||
GLsizei composite_src_output_y_;
|
||||
|
||||
std::unique_ptr<OpenGL::OutputShader> output_shader_program_;
|
||||
|
||||
std::unique_ptr<OpenGL::IntermediateShader> composite_input_shader_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> composite_separation_filter_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> composite_chrominance_filter_shader_program_;
|
||||
|
||||
std::unique_ptr<OpenGL::IntermediateShader> svideo_input_shader_program_;
|
||||
|
||||
std::unique_ptr<OpenGL::IntermediateShader> rgb_input_shader_program_;
|
||||
std::unique_ptr<OpenGL::IntermediateShader> rgb_filter_shader_program_;
|
||||
|
||||
std::unique_ptr<OpenGL::TextureTarget> composite_texture_; // receives raw composite levels
|
||||
std::unique_ptr<OpenGL::TextureTarget> separated_texture_; // receives filtered Y in the R channel plus unfiltered but demodulated chrominance in G and B
|
||||
std::unique_ptr<OpenGL::TextureTarget> filtered_texture_; // receives filtered YIQ or YUV
|
||||
|
||||
std::unique_ptr<OpenGL::TextureTarget> work_texture_; // used for all intermediate rendering if texture fences are supported
|
||||
|
||||
std::unique_ptr<OpenGL::TextureTarget> framebuffer_; // the current pixel output
|
||||
|
||||
GLuint output_vertex_array_;
|
||||
GLuint source_vertex_array_;
|
||||
|
||||
unsigned int last_output_width_, last_output_height_;
|
||||
|
||||
void set_timing_uniforms();
|
||||
void set_colour_space_uniforms();
|
||||
void set_gamma();
|
||||
|
||||
void establish_OpenGL_state();
|
||||
void reset_all_OpenGL_state();
|
||||
|
||||
GLsync fence_;
|
||||
float get_composite_output_width() const;
|
||||
void set_output_shader_width();
|
||||
|
||||
// Maintain a couple of rectangles for masking off the extreme edge of the display;
|
||||
// this is a bit of a cheat: there's some tolerance in when a sync pulse will be
|
||||
// generated. So it might be slightly later than expected. Which might cause a scan
|
||||
// that is slightly longer than expected. Which means that from then on, those scans
|
||||
// might have touched parts of the extreme edge of the display which are not rescanned.
|
||||
// Which because I've implemented persistence-of-vision as an in-buffer effect will
|
||||
// cause perpetual persistence.
|
||||
//
|
||||
// The fix: just always treat that area as invisible. This is acceptable thanks to
|
||||
// the concept of overscan. One is allowed not to display extreme ends of the image.
|
||||
std::unique_ptr<OpenGL::Rectangle> right_overlay_;
|
||||
std::unique_ptr<OpenGL::Rectangle> left_overlay_;
|
||||
|
||||
public:
|
||||
// These two are protected by output_mutex_.
|
||||
TextureBuilder texture_builder;
|
||||
ArrayBuilder array_builder;
|
||||
|
||||
OpenGLOutputBuilder(std::size_t bytes_per_pixel);
|
||||
~OpenGLOutputBuilder();
|
||||
|
||||
inline void set_colour_format(ColourSpace colour_space, unsigned int colour_cycle_numerator, unsigned int colour_cycle_denominator) {
|
||||
std::lock_guard<std::mutex> output_guard(output_mutex_);
|
||||
colour_space_ = colour_space;
|
||||
colour_cycle_numerator_ = colour_cycle_numerator;
|
||||
colour_cycle_denominator_ = colour_cycle_denominator;
|
||||
set_colour_space_uniforms();
|
||||
}
|
||||
|
||||
inline void set_visible_area(Rect visible_area) {
|
||||
visible_area_ = visible_area;
|
||||
}
|
||||
|
||||
inline void set_gamma(float gamma) {
|
||||
gamma_ = gamma;
|
||||
set_gamma();
|
||||
}
|
||||
|
||||
inline std::unique_lock<std::mutex> get_output_lock() {
|
||||
return std::unique_lock<std::mutex>(output_mutex_);
|
||||
}
|
||||
|
||||
inline VideoSignal get_output_device() {
|
||||
return video_signal_;
|
||||
}
|
||||
|
||||
inline uint16_t get_composite_output_y() {
|
||||
return static_cast<uint16_t>(composite_src_output_y_);
|
||||
}
|
||||
|
||||
inline bool composite_output_buffer_is_full() {
|
||||
return composite_src_output_y_ == IntermediateBufferHeight;
|
||||
}
|
||||
|
||||
inline void increment_composite_output_y() {
|
||||
if(!composite_output_buffer_is_full())
|
||||
composite_src_output_y_++;
|
||||
}
|
||||
|
||||
void set_target_framebuffer(GLint);
|
||||
void draw_frame(unsigned int output_width, unsigned int output_height, bool only_if_dirty);
|
||||
void set_openGL_context_will_change(bool should_delete_resources);
|
||||
void set_composite_sampling_function(const std::string &);
|
||||
void set_svideo_sampling_function(const std::string &);
|
||||
void set_rgb_sampling_function(const std::string &);
|
||||
void set_video_signal(VideoSignal);
|
||||
void set_timing(unsigned int input_frequency, unsigned int cycles_per_line, unsigned int height_of_display, unsigned int horizontal_scan_period, unsigned int vertical_scan_period, unsigned int vertical_period_divider);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CRTOpenGL_h */
|
@ -18,7 +18,26 @@ constexpr int WriteAreaHeight = 2048;
|
||||
|
||||
constexpr int CompositeLineBufferWidth = 2048;
|
||||
constexpr int CompositeLineBufferHeight = 2048;
|
||||
constexpr int CompositeLineBufferTextureUnit = 0;
|
||||
|
||||
/// The texture unit from which to source 1bpp input data.
|
||||
constexpr GLenum SourceData1BppTextureUnit = GL_TEXTURE0;
|
||||
/// The texture unit from which to source 2bpp input data.
|
||||
constexpr GLenum SourceData2BppTextureUnit = GL_TEXTURE1;
|
||||
/// The texture unit from which to source 4bpp input data.
|
||||
constexpr GLenum SourceData4BppTextureUnit = GL_TEXTURE2;
|
||||
|
||||
/// The texture unit which contains raw line-by-line composite or RGB data.
|
||||
constexpr GLenum UnprocessedLineBufferTextureUnit = GL_TEXTURE3;
|
||||
/// The texture unit which contains line-by-line records of luminance and amplitude-modulated chrominance.
|
||||
constexpr GLenum CompositeSeparatedTextureUnit = GL_TEXTURE4;
|
||||
/// The texture unit which contains line-by-line records of luminance and demodulated chrominance.
|
||||
constexpr GLenum DemodulatedCompositeTextureUnit = GL_TEXTURE5;
|
||||
|
||||
/// The texture unit which contains line-by-line RGB.
|
||||
constexpr GLenum LineBufferTextureUnit = GL_TEXTURE6;
|
||||
|
||||
/// The texture unit that contains the current display.
|
||||
constexpr GLenum AccumulationTextureUnit = GL_TEXTURE7;
|
||||
|
||||
#define TextureAddress(x, y) (((y) << 11) | (x))
|
||||
#define TextureAddressGetY(v) uint16_t((v) >> 11)
|
||||
@ -48,13 +67,12 @@ const GLenum formatForDepth(std::size_t depth) {
|
||||
}
|
||||
|
||||
ScanTarget::ScanTarget() :
|
||||
composite_line_texture_(CompositeLineBufferWidth, CompositeLineBufferHeight, CompositeLineBufferTextureUnit, GL_LINEAR) {
|
||||
unprocessed_line_texture_(CompositeLineBufferWidth, CompositeLineBufferHeight, UnprocessedLineBufferTextureUnit, GL_LINEAR) {
|
||||
|
||||
// Allocate space for the scans.
|
||||
const auto buffer_size = scan_buffer_.size() * sizeof(Scan);
|
||||
glGenBuffers(1, &scan_buffer_name_);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, scan_buffer_name_);
|
||||
|
||||
const auto buffer_size = scan_buffer_.size() * sizeof(Scan);
|
||||
glBufferData(GL_ARRAY_BUFFER, GLsizeiptr(buffer_size), NULL, GL_STREAM_DRAW);
|
||||
|
||||
// TODO: if this is OpenGL 4.4 or newer, use glBufferStorage rather than glBufferData
|
||||
|
@ -78,7 +78,7 @@ class ScanTarget: public Outputs::Display::ScanTarget {
|
||||
uint16_t composite_y;
|
||||
};
|
||||
std::array<CompositeLine, 2048> composite_line_buffer_;
|
||||
TextureTarget composite_line_texture_;
|
||||
TextureTarget unprocessed_line_texture_;
|
||||
GLuint composite_line_vertex_array_ = 0;
|
||||
CompositeLine *active_composite_line_ = nullptr;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user