mirror of
https://github.com/TomHarte/CLK.git
synced 2026-03-13 19:16:40 +00:00
Use a Texture.
This commit is contained in:
@@ -10,7 +10,30 @@
|
||||
|
||||
using namespace Outputs::Display::OpenGL;
|
||||
|
||||
namespace {
|
||||
constexpr GLint internal_format_for_depth(const std::size_t depth) {
|
||||
switch(depth) {
|
||||
default: return GL_FALSE;
|
||||
case 1: return GL_R8UI;
|
||||
case 2: return GL_RG8UI;
|
||||
case 3: return GL_RGB8UI;
|
||||
case 4: return GL_RGBA8UI;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr GLenum format_for_depth(const std::size_t depth) {
|
||||
switch(depth) {
|
||||
default: return GL_FALSE;
|
||||
case 1: return GL_RED_INTEGER;
|
||||
case 2: return GL_RG_INTEGER;
|
||||
case 3: return GL_RGB_INTEGER;
|
||||
case 4: return GL_RGBA_INTEGER;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Texture(
|
||||
const size_t channels,
|
||||
const GLenum texture_unit,
|
||||
const GLint mag_filter,
|
||||
const GLint min_filter,
|
||||
@@ -29,11 +52,11 @@ Texture::Texture(
|
||||
glTexImage2D,
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
internal_format_for_depth(channels),
|
||||
GLsizei(width_),
|
||||
GLsizei(height_),
|
||||
0,
|
||||
GL_RGBA,
|
||||
format_for_depth(channels),
|
||||
GL_UNSIGNED_BYTE,
|
||||
nullptr
|
||||
);
|
||||
|
||||
@@ -15,12 +15,19 @@ namespace Outputs::Display::OpenGL {
|
||||
/*!
|
||||
Holds a texture of size @c width and @c height, which is bound to @c texture_unit.
|
||||
|
||||
Textures are always four-channel with byte values per channel. Both clamp directions are set to `GL_CLAMP_TO_EDGE`.
|
||||
The magnification and minification filters as specified are attached.
|
||||
Textures are always a single byte per channel. Both clamp directions are set to `GL_CLAMP_TO_EDGE`.
|
||||
The magnification and minification filters are as specified.
|
||||
*/
|
||||
class Texture {
|
||||
public:
|
||||
Texture(GLenum texture_unit, GLint mag_filter, GLint min_filter, GLsizei width, GLsizei height);
|
||||
Texture(
|
||||
size_t channels,
|
||||
GLenum texture_unit,
|
||||
GLint mag_filter,
|
||||
GLint min_filter,
|
||||
GLsizei width,
|
||||
GLsizei height
|
||||
);
|
||||
~Texture();
|
||||
|
||||
Texture() = default;
|
||||
@@ -35,6 +42,10 @@ public:
|
||||
*/
|
||||
void bind();
|
||||
|
||||
bool empty() const {
|
||||
return texture_ == 0;
|
||||
}
|
||||
|
||||
private:
|
||||
GLenum texture_unit_ = GL_TEXTURE0;
|
||||
GLuint texture_ = 0;
|
||||
|
||||
@@ -99,8 +99,6 @@ ScanTarget::ScanTarget(const API api, const GLuint target_framebuffer, const flo
|
||||
// and specify GL_MAP_PERSISTENT_BIT. Then map the buffer now, and let the client
|
||||
// write straight into it.
|
||||
|
||||
test_gl(glGenTextures, 1, &write_area_texture_name_);
|
||||
|
||||
test_gl(glBlendFunc, GL_SRC_ALPHA, GL_CONSTANT_COLOR);
|
||||
test_gl(glBlendColor, 0.4f, 0.4f, 0.4f, 1.0f);
|
||||
|
||||
@@ -109,53 +107,52 @@ ScanTarget::ScanTarget(const API api, const GLuint target_framebuffer, const flo
|
||||
|
||||
|
||||
// TEST CODE. NOCOMMIT.
|
||||
const auto buffer_width = FilterGenerator::SuggestedBufferWidth;
|
||||
const float sample_multiplier =
|
||||
FilterGenerator::suggested_sample_multiplier(227.5f, 1320);
|
||||
|
||||
VertexArray va(scan_buffer_);
|
||||
for(auto &pair: {
|
||||
std::make_pair(InputDataType::Luminance1, DisplayType::CompositeColour),
|
||||
std::make_pair(InputDataType::Luminance8, DisplayType::CompositeColour),
|
||||
std::make_pair(InputDataType::PhaseLinkedLuminance8, DisplayType::CompositeColour),
|
||||
|
||||
std::make_pair(InputDataType::Luminance8Phase8, DisplayType::SVideo),
|
||||
std::make_pair(InputDataType::Luminance8Phase8, DisplayType::CompositeColour),
|
||||
|
||||
std::make_pair(InputDataType::Red1Green1Blue1, DisplayType::RGB),
|
||||
std::make_pair(InputDataType::Red1Green1Blue1, DisplayType::SVideo),
|
||||
std::make_pair(InputDataType::Red1Green1Blue1, DisplayType::CompositeColour),
|
||||
|
||||
std::make_pair(InputDataType::Red2Green2Blue2, DisplayType::RGB),
|
||||
std::make_pair(InputDataType::Red2Green2Blue2, DisplayType::SVideo),
|
||||
std::make_pair(InputDataType::Red2Green2Blue2, DisplayType::CompositeColour),
|
||||
|
||||
std::make_pair(InputDataType::Red4Green4Blue4, DisplayType::RGB),
|
||||
std::make_pair(InputDataType::Red4Green4Blue4, DisplayType::SVideo),
|
||||
std::make_pair(InputDataType::Red4Green4Blue4, DisplayType::CompositeColour),
|
||||
|
||||
std::make_pair(InputDataType::Red8Green8Blue8, DisplayType::RGB),
|
||||
std::make_pair(InputDataType::Red8Green8Blue8, DisplayType::SVideo),
|
||||
std::make_pair(InputDataType::Red8Green8Blue8, DisplayType::CompositeColour),
|
||||
}) {
|
||||
OpenGL::composition_shader(
|
||||
api,
|
||||
pair.first,
|
||||
pair.second,
|
||||
ColourSpace::YIQ,
|
||||
sample_multiplier,
|
||||
BufferingScanTarget::WriteAreaWidth, BufferingScanTarget::WriteAreaHeight,
|
||||
buffer_width, 2048, // TODO: substitute real composition buffer sizes.
|
||||
va,
|
||||
GL_TEXTURE0
|
||||
).bind();
|
||||
}
|
||||
// const auto buffer_width = FilterGenerator::SuggestedBufferWidth;
|
||||
// const float sample_multiplier =
|
||||
// FilterGenerator::suggested_sample_multiplier(227.5f, 1320);
|
||||
//
|
||||
// VertexArray va(scan_buffer_);
|
||||
// for(auto &pair: {
|
||||
// std::make_pair(InputDataType::Luminance1, DisplayType::CompositeColour),
|
||||
// std::make_pair(InputDataType::Luminance8, DisplayType::CompositeColour),
|
||||
// std::make_pair(InputDataType::PhaseLinkedLuminance8, DisplayType::CompositeColour),
|
||||
//
|
||||
// std::make_pair(InputDataType::Luminance8Phase8, DisplayType::SVideo),
|
||||
// std::make_pair(InputDataType::Luminance8Phase8, DisplayType::CompositeColour),
|
||||
//
|
||||
// std::make_pair(InputDataType::Red1Green1Blue1, DisplayType::RGB),
|
||||
// std::make_pair(InputDataType::Red1Green1Blue1, DisplayType::SVideo),
|
||||
// std::make_pair(InputDataType::Red1Green1Blue1, DisplayType::CompositeColour),
|
||||
//
|
||||
// std::make_pair(InputDataType::Red2Green2Blue2, DisplayType::RGB),
|
||||
// std::make_pair(InputDataType::Red2Green2Blue2, DisplayType::SVideo),
|
||||
// std::make_pair(InputDataType::Red2Green2Blue2, DisplayType::CompositeColour),
|
||||
//
|
||||
// std::make_pair(InputDataType::Red4Green4Blue4, DisplayType::RGB),
|
||||
// std::make_pair(InputDataType::Red4Green4Blue4, DisplayType::SVideo),
|
||||
// std::make_pair(InputDataType::Red4Green4Blue4, DisplayType::CompositeColour),
|
||||
//
|
||||
// std::make_pair(InputDataType::Red8Green8Blue8, DisplayType::RGB),
|
||||
// std::make_pair(InputDataType::Red8Green8Blue8, DisplayType::SVideo),
|
||||
// std::make_pair(InputDataType::Red8Green8Blue8, DisplayType::CompositeColour),
|
||||
// }) {
|
||||
// OpenGL::composition_shader(
|
||||
// api,
|
||||
// pair.first,
|
||||
// pair.second,
|
||||
// ColourSpace::YIQ,
|
||||
// sample_multiplier,
|
||||
// BufferingScanTarget::WriteAreaWidth, BufferingScanTarget::WriteAreaHeight,
|
||||
// buffer_width, 2048, // TODO: substitute real composition buffer sizes.
|
||||
// va,
|
||||
// GL_TEXTURE0
|
||||
// ).bind();
|
||||
// }
|
||||
}
|
||||
|
||||
ScanTarget::~ScanTarget() {
|
||||
perform([&] {
|
||||
glDeleteBuffers(1, &scan_buffer_name_);
|
||||
glDeleteTextures(1, &write_area_texture_name_);
|
||||
glDeleteVertexArrays(1, &scan_vertex_array_);
|
||||
});
|
||||
}
|
||||
@@ -352,28 +349,19 @@ void ScanTarget::update(int, int output_height) {
|
||||
|
||||
// Submit texture.
|
||||
if(area.start.write_area_x != area.end.write_area_x || area.start.write_area_y != area.end.write_area_y) {
|
||||
test_gl(glActiveTexture, SourceDataTextureUnit);
|
||||
test_gl(glBindTexture, GL_TEXTURE_2D, write_area_texture_name_);
|
||||
|
||||
// Create storage for the texture if it doesn't yet exist; this was deferred until here
|
||||
// because the pixel format wasn't initially known.
|
||||
if(!texture_exists_) {
|
||||
test_gl(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
test_gl(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
test_gl(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
test_gl(glTexParameteri, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
test_gl(glTexImage2D,
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
internalFormatForDepth(write_area_data_size()),
|
||||
if(source_texture_.empty()) {
|
||||
source_texture_ = Texture(
|
||||
write_area_data_size(),
|
||||
SourceDataTextureUnit,
|
||||
GL_NEAREST,
|
||||
GL_NEAREST,
|
||||
WriteAreaWidth,
|
||||
WriteAreaHeight,
|
||||
0,
|
||||
formatForDepth(write_area_data_size()),
|
||||
GL_UNSIGNED_BYTE,
|
||||
nullptr);
|
||||
texture_exists_ = true;
|
||||
WriteAreaHeight
|
||||
);
|
||||
}
|
||||
source_texture_.bind();
|
||||
|
||||
if(area.end.write_area_y >= area.start.write_area_y) {
|
||||
// Submit the direct region from the submit pointer to the read pointer.
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "API.hpp"
|
||||
#include "OpenGL.hpp"
|
||||
#include "Primitives/Rectangle.hpp"
|
||||
#include "Primitives/Texture.hpp"
|
||||
#include "Primitives/TextureTarget.hpp"
|
||||
#include "Primitives/VertexArray.hpp"
|
||||
|
||||
@@ -94,9 +95,6 @@ private:
|
||||
GLuint scan_buffer_name_ = 0, scan_vertex_array_ = 0;
|
||||
GLuint line_buffer_name_ = 0, line_vertex_array_ = 0;
|
||||
|
||||
GLuint write_area_texture_name_ = 0;
|
||||
bool texture_exists_ = false;
|
||||
|
||||
// Receives scan target modals.
|
||||
std::optional<ScanTarget::Modals> existing_modals_;
|
||||
void setup_pipeline();
|
||||
@@ -122,11 +120,6 @@ 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,
|
||||
normalising the data into one of four forms: RGB, 8-bit luminance,
|
||||
@@ -160,6 +153,15 @@ private:
|
||||
std::array<Scan, LineBufferHeight*5> scan_buffer_;
|
||||
std::array<Line, LineBufferHeight> line_buffer_;
|
||||
std::array<LineMetadata, LineBufferHeight> line_metadata_buffer_;
|
||||
|
||||
//
|
||||
// NEW PIPELINE. Starts here.
|
||||
//
|
||||
Texture source_texture_;
|
||||
VertexArray scans_;
|
||||
TextureTarget composition_buffer_;
|
||||
Shader composition_shader_;
|
||||
Shader copy_shader_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user