1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-06 01:28:57 +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_); output_shader_program_->set_output_size(output_width, output_height, visible_area_);
last_output_width_ = output_width; last_output_width_ = output_width;
last_output_height_ = output_height; 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(); output_shader_program_->bind();
// draw // draw
glDrawArraysInstanced(GL_TRIANGLE_STRIP, 0, 4, (GLsizei)array_submission.output_size / OutputVertexSize); 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 #ifdef GL_NV_texture_barrier

View File

@ -20,6 +20,7 @@
#include "Shaders/OutputShader.hpp" #include "Shaders/OutputShader.hpp"
#include "Shaders/IntermediateShader.hpp" #include "Shaders/IntermediateShader.hpp"
#include "Rectangle.hpp"
#include <mutex> #include <mutex>
#include <vector> #include <vector>
@ -106,6 +107,18 @@ class OpenGLOutputBuilder {
float integer_coordinate_multiplier_ = 1.0f; 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: public:
// These two are protected by output_mutex_. // These two are protected by output_mutex_.
TextureBuilder texture_builder; 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) { 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 outputAspectRatioMultiplier = (static_cast<float>(output_width) / static_cast<float>(output_height)) / (4.0f / 3.0f);
GLfloat bonusWidth = (outputAspectRatioMultiplier - 1.0f) * visible_area.size.width; 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; visible_area.size.width *= outputAspectRatioMultiplier;
set_uniform("boundsOrigin", (GLfloat)visible_area.origin.x, (GLfloat)visible_area.origin.y); 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); 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) { void OutputShader::set_source_texture_unit(GLenum unit) {
set_uniform("texID", (GLint)(unit - GL_TEXTURE0)); set_uniform("texID", (GLint)(unit - GL_TEXTURE0));
} }

View File

@ -87,6 +87,14 @@ public:
space, 0.5 means use half, etc. space, 0.5 means use half, etc.
*/ */
void set_input_width_scaler(float input_scaler); 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;
}; };
} }