mirror of
https://github.com/TomHarte/CLK.git
synced 2026-01-22 08:26:48 +00:00
Ensure OpenGL appropriately letterboxes or pillarboxes.
This commit is contained in:
@@ -167,20 +167,21 @@ void ScanTarget::setup_pipeline() {
|
||||
set_uniforms(ShaderType::QAMSeparation, *qam_separation_shader_);
|
||||
}
|
||||
|
||||
// Pick a single zoom level to apply to the output, given the intended aspect ratio compared to the 4/3 this
|
||||
// scan target halways uses, and the required output dimensions.
|
||||
// Select whichever of a letterbox or pillarbox avoids cropping.
|
||||
constexpr float output_ratio = 4.0f / 3.0f;
|
||||
const float aspect_ratio_stretch = modals.aspect_ratio / output_ratio;
|
||||
const float zoom = modals.visible_area.appropriate_zoom(aspect_ratio_stretch);
|
||||
|
||||
// TODO: Adjust origin to recentre content, given the zoom.
|
||||
auto adjusted_rect = modals.visible_area;
|
||||
// adjusted_rect.origin.x = (aspect_ratio_stretch * zoom - modals.visible_area.size.width) * 0.5f;
|
||||
// adjusted_rect.origin.y -= (zoom - modals.visible_area.size.height) * 0.5f;
|
||||
const float letterbox_scale = adjusted_rect.size.height / (adjusted_rect.size.width * aspect_ratio_stretch);
|
||||
if(letterbox_scale > 1.0f) {
|
||||
adjusted_rect.scale(letterbox_scale, 1.0f);
|
||||
} else {
|
||||
adjusted_rect.scale(1.0f, 1.0f / letterbox_scale);
|
||||
}
|
||||
|
||||
// Provide to shader.
|
||||
output_shader_->set_uniform("origin", adjusted_rect.origin.x, adjusted_rect.origin.y);
|
||||
output_shader_->set_uniform("size", zoom, zoom / aspect_ratio_stretch);
|
||||
output_shader_->set_uniform("size", 1.0f / adjusted_rect.size.width, 1.0f / adjusted_rect.size.height);
|
||||
|
||||
// Establish an input shader.
|
||||
if(!existing_modals_ || existing_modals_->input_data_type != modals.input_data_type) {
|
||||
|
||||
@@ -40,7 +40,7 @@ struct Rect {
|
||||
return size.width == 0.0f || size.height == 0.0f;
|
||||
}
|
||||
|
||||
void expand(const float min_x, const float max_x, const float min_y, float max_y) {
|
||||
void expand(const float min_x, const float max_x, const float min_y, const float max_y) {
|
||||
origin.x = std::min(origin.x, min_x);
|
||||
size.width = std::max(size.width, max_x - origin.x);
|
||||
|
||||
@@ -48,6 +48,18 @@ struct Rect {
|
||||
size.height = std::max(size.height, max_y - origin.y);
|
||||
}
|
||||
|
||||
/// Scales a rectange around its centre.
|
||||
void scale(const float scale_x, const float scale_y) {
|
||||
const float centre[] = {
|
||||
origin.x + size.width * 0.5f,
|
||||
origin.y + size.height * 0.5f,
|
||||
};
|
||||
size.width *= scale_x;
|
||||
size.height *= scale_y;
|
||||
origin.x = centre[0] - size.width * 0.5f;
|
||||
origin.y = centre[1] - size.height * 0.5f;
|
||||
}
|
||||
|
||||
float appropriate_zoom(const float aspect_ratio_stretch) const {
|
||||
const float width_zoom = 1.0f / (size.width * aspect_ratio_stretch);
|
||||
const float height_zoom = 1.0f / size.height;
|
||||
|
||||
Reference in New Issue
Block a user