mirror of
https://github.com/TomHarte/CLK.git
synced 2026-04-20 10:17:05 +00:00
Add some TODOs, make TextureTargets moveable.
This commit is contained in:
@@ -17,11 +17,24 @@ namespace Outputs::Display::OpenGL {
|
||||
/*!
|
||||
Copies a source texture in its entirety to a destination, optionally applying
|
||||
a change in brightness and a gamma adjustment.
|
||||
|
||||
This always copies the entirety of the source texture to the entirety of the
|
||||
target surface; hence no inputs are required to the vertex program. Simply
|
||||
issue a four-vertex triangle strip.
|
||||
|
||||
TODO: consider colour adaptations beyond mere brightness.
|
||||
I want at least a 'tint' and am considering a full-on matrix application for any
|
||||
combination of tint, brightness and channel remapping — e.g. imagine a
|
||||
handheld console in which the native red pixels are some colour other than
|
||||
pure red.
|
||||
|
||||
(would need support in the ScanTarget modals and therefore also a correlated
|
||||
change in the other scan targets)
|
||||
*/
|
||||
Shader copy_shader(
|
||||
API,
|
||||
const GLenum source_texture_unit,
|
||||
std::optional<float> brightness,
|
||||
std::optional<float> brightness, // Optionally: multiply all input
|
||||
std::optional<float> gamma
|
||||
);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "TextureTarget.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace Outputs::Display::OpenGL;
|
||||
@@ -96,9 +97,27 @@ TextureTarget::TextureTarget(
|
||||
TextureTarget::~TextureTarget() {
|
||||
glDeleteFramebuffers(1, &framebuffer_);
|
||||
glDeleteTextures(1, &texture_);
|
||||
if(renderbuffer_) glDeleteRenderbuffers(1, &renderbuffer_);
|
||||
if(drawing_vertex_array_) glDeleteVertexArrays(1, &drawing_vertex_array_);
|
||||
if(drawing_array_buffer_) glDeleteBuffers(1, &drawing_array_buffer_);
|
||||
glDeleteRenderbuffers(1, &renderbuffer_);
|
||||
glDeleteVertexArrays(1, &drawing_vertex_array_);
|
||||
glDeleteBuffers(1, &drawing_array_buffer_);
|
||||
}
|
||||
|
||||
TextureTarget::TextureTarget(TextureTarget &&rhs) {
|
||||
*this = std::move(rhs);
|
||||
}
|
||||
|
||||
TextureTarget &TextureTarget::operator =(TextureTarget &&rhs) {
|
||||
api_ = rhs.api_;
|
||||
std::swap(framebuffer_, rhs.framebuffer_);
|
||||
std::swap(texture_, rhs.texture_);
|
||||
std::swap(renderbuffer_, rhs.renderbuffer_);
|
||||
std::swap(width_, rhs.width_);
|
||||
std::swap(height_, rhs.height_);
|
||||
std::swap(texture_unit_, rhs.texture_unit_);
|
||||
std::swap(texture_unit_, rhs.texture_unit_);
|
||||
GLsizei expanded_width_ = 0, expanded_height_ = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TextureTarget::bind_framebuffer() {
|
||||
@@ -111,6 +130,7 @@ void TextureTarget::bind_texture() const {
|
||||
test_gl(glBindTexture, GL_TEXTURE_2D, texture_);
|
||||
}
|
||||
|
||||
// TODO: eliminate below, plus relevant local storage.
|
||||
void TextureTarget::draw(const float aspect_ratio, const float colour_threshold) const {
|
||||
if(!pixel_shader_) {
|
||||
const char *const vertex_shader =
|
||||
|
||||
@@ -37,6 +37,10 @@ public:
|
||||
TextureTarget(API, GLsizei width, GLsizei height, GLenum texture_unit, GLint mag_filter, bool has_stencil_buffer);
|
||||
~TextureTarget();
|
||||
|
||||
TextureTarget() = default;
|
||||
TextureTarget(TextureTarget &&);
|
||||
TextureTarget &operator =(TextureTarget &&);
|
||||
|
||||
/*!
|
||||
Binds this target as a framebuffer and sets the @c glViewport accordingly.
|
||||
*/
|
||||
@@ -75,11 +79,11 @@ public:
|
||||
void draw(float aspect_ratio, float colour_threshold = 0.0f) const;
|
||||
|
||||
private:
|
||||
API api_;
|
||||
API api_{};
|
||||
GLuint framebuffer_ = 0, texture_ = 0, renderbuffer_ = 0;
|
||||
const GLsizei width_ = 0, height_ = 0;
|
||||
GLsizei width_ = 0, height_ = 0;
|
||||
GLsizei expanded_width_ = 0, expanded_height_ = 0;
|
||||
const GLenum texture_unit_ = 0;
|
||||
GLenum texture_unit_ = 0;
|
||||
|
||||
mutable std::unique_ptr<Shader> pixel_shader_;
|
||||
mutable GLuint drawing_vertex_array_ = 0, drawing_array_buffer_ = 0;
|
||||
|
||||
@@ -122,7 +122,10 @@ private:
|
||||
std::unique_ptr<Shader> output_shader_;
|
||||
std::unique_ptr<Shader> qam_separation_shader_;
|
||||
|
||||
VertexArray scans_;
|
||||
TextureTarget composition_buffer_;
|
||||
Shader composition_shader_;
|
||||
Shader copy_shader_;
|
||||
|
||||
/*!
|
||||
Produces a shader that composes fragment of the input stream to a single buffer,
|
||||
|
||||
@@ -233,6 +233,17 @@ enum class InputDataType {
|
||||
Red4Green4Blue4, // 2 bytes/pixel; low nibble in first byte is red, high nibble in second is green, low is blue.
|
||||
// i.e. if it were a little endian word, 0xgb0r; or 0x0rgb big endian.
|
||||
Red8Green8Blue8, // 4 bytes/pixel; first is red, second is green, third is blue, fourth is vacant.
|
||||
|
||||
// TODO, probably:
|
||||
//
|
||||
// TaggedRGBW8 — top two bits select a channel, either red, green or blue (and something else for the fourth
|
||||
// option; white maybe?). Low six bits are an intensity. I'm imagining this is good for
|
||||
// handheld systems with known subpixel layouts; the scan target can be fed with the subpixels.
|
||||
// Correlated assumption: such systems are old enough that 6 bits of intensity is sufficient.
|
||||
// If I decide to switch from 'brightness' as a final modal output property to a full-on
|
||||
// matrix transform then the tag will stop meaning RGB literally and just pick a
|
||||
// single channel, in which case 'white' makes sense as 'all channels'.
|
||||
//
|
||||
};
|
||||
|
||||
constexpr const char *name(const InputDataType data_type) {
|
||||
|
||||
Reference in New Issue
Block a user