1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-03 11:30:02 +00:00

Adds a right gutter to clip persistence errors.

Also uncovers and corrects a long-standing centring error.
This commit is contained in:
Thomas Harte 2018-07-16 21:52:31 -04:00
parent 523749edf8
commit efa45b9504
4 changed files with 36 additions and 2 deletions

View File

@ -227,11 +227,18 @@ void OpenGLOutputBuilder::draw_frame(unsigned int output_width, unsigned int out
output_shader_program_->set_output_size(output_width, output_height, visible_area_);
last_output_width_ = output_width;
last_output_height_ = output_height;
// Configure a right gutter to crop the right-hand 2% of the display.
right_overlay_.reset(new OpenGL::Rectangle(output_shader_program_->get_right_extent() * 0.98, -1.0, 1.0, 2.0));
}
output_shader_program_->bind();
// draw
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)array_submission.output_size / OutputVertexSize);
// mask off the gutter
glDisable(GL_BLEND);
right_overlay_->draw(0.0, 0.0, 0.0);
}
#ifdef GL_NV_texture_barrier

View File

@ -20,6 +20,7 @@
#include "Shaders/OutputShader.hpp"
#include "Shaders/IntermediateShader.hpp"
#include "Rectangle.hpp"
#include <mutex>
#include <vector>
@ -106,6 +107,18 @@ class OpenGLOutputBuilder {
float integer_coordinate_multiplier_ = 1.0f;
// 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_;
public:
// These two are protected by output_mutex_.
TextureBuilder texture_builder;

View File

@ -94,15 +94,21 @@ std::unique_ptr<OutputShader> OutputShader::make_shader(const char *fragment_met
void OutputShader::set_output_size(unsigned int output_width, unsigned int output_height, Outputs::CRT::Rect visible_area) {
GLfloat outputAspectRatioMultiplier = (static_cast<float>(output_width) / static_cast<float>(output_height)) / (4.0f / 3.0f);
GLfloat bonusWidth = (outputAspectRatioMultiplier - 1.0f) * visible_area.size.width;
visible_area.origin.x -= bonusWidth * 0.5f * visible_area.size.width;
right_extent_ = (1.0f / outputAspectRatioMultiplier) / visible_area.size.width;
visible_area.origin.x -= bonusWidth * 0.5f;
visible_area.size.width *= outputAspectRatioMultiplier;
set_uniform("boundsOrigin", (GLfloat)visible_area.origin.x, (GLfloat)visible_area.origin.y);
set_uniform("boundsSize", (GLfloat)visible_area.size.width, (GLfloat)visible_area.size.height);
}
float OutputShader::get_right_extent() {
return right_extent_;
}
void OutputShader::set_source_texture_unit(GLenum unit) {
set_uniform("texID", (GLint)(unit - GL_TEXTURE0));
}

View File

@ -87,6 +87,14 @@ public:
space, 0.5 means use half, etc.
*/
void set_input_width_scaler(float input_scaler);
/*!
@returns The location, in eye coordinates, of the right edge of the output area.
*/
float get_right_extent();
private:
float right_extent_ = 0.0f;
};
}