mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Adds a right gutter to clip persistence errors.
Also uncovers and corrects a long-standing centring error.
This commit is contained in:
parent
523749edf8
commit
efa45b9504
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user