Add support for brightness and contrast modifiers (#4041)

This commit is contained in:
Alex
2025-10-07 21:53:16 +01:00
committed by GitHub
parent 48903fc6f8
commit 3f75e5d504
12 changed files with 80 additions and 20 deletions
+4
View File
@@ -67,6 +67,10 @@ struct GfxGlobalSettings {
// multi-sampled anti-aliasing sample count. 1 = disabled.
int msaa_samples = 1;
// brightness and contrast values set from GOAL (see jak 3)
int brightness_contrast_color = 0;
int brightness_contrast_alpha = 128;
// current renderer
const GfxRendererModule* renderer;
+1 -1
View File
@@ -48,4 +48,4 @@ struct Fbo {
valid = false;
}
}
};
};
@@ -1024,11 +1024,13 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
blit_display(prof);
}
// apply effects done with PCRTC registers
// apply effects done with PCRTC registers, as well as blit the framebuffer to the window and
// apply brightness/contrast
{
g_current_renderer = "pcrtc";
auto prof = m_profiler.root()->make_scoped_child("pcrtc");
do_pcrtc_effects(settings.pmode_alp_register, &m_render_state, prof);
do_pcrtc_effects(settings.pmode_alp_register, settings.brightness_contrast_color,
settings.brightness_contrast_alpha, &m_render_state, prof);
if (settings.gpu_sync) {
glFinish();
}
@@ -1610,6 +1612,8 @@ void OpenGLRenderer::finish_screenshot(const std::string& output_name,
}
void OpenGLRenderer::do_pcrtc_effects(float alp,
int brightness_contrast_color,
int brightness_contrast_alpha,
SharedRenderState* render_state,
ScopedProfilerNode& prof) {
Fbo* window_blit_src = nullptr;
@@ -1642,9 +1646,22 @@ void OpenGLRenderer::do_pcrtc_effects(float alp,
glBindVertexArray(screen_vao);
glBindBuffer(GL_ARRAY_BUFFER, screen_vbo);
auto& shader = render_state->shaders[ShaderId::PLAIN_TEXTURE];
float color = (float)brightness_contrast_color / 128.0f;
float alpha = (float)brightness_contrast_alpha / 128.0f;
auto& shader = render_state->shaders[ShaderId::POST_PROCESSING];
shader.activate();
glUniform1i(glGetUniformLocation(shader.id(), "tex_T0"), 0);
if (brightness_contrast_color < 0) {
// subtractive blend - note that color is already negative
float color_neg = color * alpha;
glUniform4f(glGetUniformLocation(shader.id(), "color_mult"), 1.0f, 1.0f, 1.0f, alpha);
glUniform4f(glGetUniformLocation(shader.id(), "color_add"), color_neg, color_neg, color_neg,
0.0f);
} else {
// additive blend
glUniform4f(glGetUniformLocation(shader.id(), "color_mult"), 1.0f, 1.0f, 1.0f, alpha);
glUniform4f(glGetUniformLocation(shader.id(), "color_add"), color, color, color, 0.0f);
}
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE0);
@@ -48,6 +48,9 @@ struct RenderOptions {
float pmode_alp_register = 1.f;
int brightness_contrast_color = 0; // 0 - no change
int brightness_contrast_alpha = 128; // 128 - no change
// when enabled, does a `glFinish()` after each major rendering pass. This blocks until the GPU
// is done working, making it easier to profile GPU utilization.
bool gpu_sync = false;
@@ -78,7 +81,11 @@ class OpenGLRenderer {
void dispatch_buckets_jak2(DmaFollower dma, ScopedProfilerNode& prof, bool sync_after_buckets);
void dispatch_buckets_jak3(DmaFollower dma, ScopedProfilerNode& prof, bool sync_after_buckets);
void do_pcrtc_effects(float alp, SharedRenderState* render_state, ScopedProfilerNode& prof);
void do_pcrtc_effects(float alp,
int brightness_contrast_color,
int brightness_contrast_alpha,
SharedRenderState* render_state,
ScopedProfilerNode& prof);
void blit_display(ScopedProfilerNode& prof);
void init_bucket_renderers_jak1();
void init_bucket_renderers_jak2();
@@ -1,13 +1,12 @@
#version 410 core
in vec2 screen_pos;
out vec4 color;
uniform vec4 fragment_color;
uniform sampler2D tex_T0;
out vec4 color;
in vec2 tex_coord;
uniform vec4 color_mult;
uniform vec4 color_add;
void main() {
color = vec4(texture(tex_T0, screen_pos).rgb * fragment_color.a, 1.0);
color = vec4(texture(tex_T0, tex_coord).rgb * color_mult.rgb * color_mult.a, 1.0) + color_add;
}
@@ -2,9 +2,9 @@
layout (location = 0) in vec2 position_in;
out vec2 screen_pos;
out vec2 tex_coord;
void main() {
gl_Position = vec4(position_in, 0, 1.0);
screen_pos = (position_in + 1) / 2;
tex_coord = (position_in + vec2(1.0, 1.0)) * 0.5;
}
+6
View File
@@ -398,6 +398,8 @@ void render_game_frame(int game_width,
int draw_region_width,
int draw_region_height,
int msaa_samples,
int brightness_contrast_color,
int brightness_contrast_alpha,
bool take_screenshot) {
// wait for a copied chain.
bool got_chain = false;
@@ -419,6 +421,8 @@ void render_game_frame(int game_width,
options.draw_region_width = draw_region_width;
options.draw_region_height = draw_region_height;
options.msaa_samples = msaa_samples;
options.brightness_contrast_color = brightness_contrast_color;
options.brightness_contrast_alpha = brightness_contrast_alpha;
options.draw_render_debug_window = g_gfx_data->debug_gui.should_draw_render_debug();
options.draw_profiler_window = g_gfx_data->debug_gui.should_draw_profiler();
options.draw_loader_window = g_gfx_data->debug_gui.should_draw_loader_menu();
@@ -572,6 +576,8 @@ void GLDisplay::render() {
render_game_frame(
game_res_w, game_res_h, fbuf_w, fbuf_h, Gfx::g_global_settings.lbox_w,
Gfx::g_global_settings.lbox_h, Gfx::g_global_settings.msaa_samples,
Gfx::g_global_settings.brightness_contrast_color,
Gfx::g_global_settings.brightness_contrast_alpha,
m_take_screenshot_next_frame && g_gfx_data->debug_gui.screenshot_hotkey_enabled);
// If we took a screenshot, stop taking them now!
if (m_take_screenshot_next_frame) {
+6
View File
@@ -916,6 +916,11 @@ void pc_set_letterbox(int w, int h) {
Gfx::g_global_settings.lbox_h = h;
}
void pc_set_brightness_contrast(s32 color, s32 alpha) {
Gfx::g_global_settings.brightness_contrast_color = color;
Gfx::g_global_settings.brightness_contrast_alpha = alpha;
}
void pc_renderer_tree_set_lod(Gfx::RendererTreeType tree, int lod) {
switch (tree) {
case Gfx::RendererTreeType::TFRAG3:
@@ -1108,6 +1113,7 @@ void init_common_pc_port_functions(
make_func_symbol_func("pc-set-msaa", (void*)pc_set_msaa);
make_func_symbol_func("pc-set-frame-rate", (void*)pc_set_frame_rate);
make_func_symbol_func("pc-set-game-resolution", (void*)pc_set_game_resolution);
make_func_symbol_func("pc-set-brightness-contrast", (void*)pc_set_brightness_contrast);
make_func_symbol_func("pc-set-letterbox", (void*)pc_set_letterbox);
make_func_symbol_func("pc-renderer-tree-set-lod", (void*)pc_renderer_tree_set_lod);
make_func_symbol_func("pc-set-collision-mode", (void*)Gfx::CollisionRendererSetMode);
+2
View File
@@ -564,6 +564,8 @@
(define-extern pc-set-game-resolution (function int int none))
(define-extern pc-set-brightness-contrast (function int int none))
(define-extern pc-set-msaa (function int none))
(define-extern pc-set-gfx-hack (function pc-gfx-hack symbol none))
+1
View File
@@ -263,6 +263,7 @@
(define-extern pc-sound-set-fade-hack (function int none))
(define-extern pc-set-window-lock (function symbol none))
(define-extern pc-set-game-resolution (function int int none))
(define-extern pc-set-brightness-contrast (function int int none))
(define-extern pc-set-msaa (function int none))
(define-extern pc-set-gfx-hack (function pc-gfx-hack symbol none))
(define-extern pc-get-unix-timestamp (function int))
+23 -6
View File
@@ -614,13 +614,30 @@
;; in-place draw on rasterization buffer to apply brightness and contrast. Added to almost
;; the last bucket, so it applies to HUD too.
;; this type of full-screen draw is done at the end of rendering a frame on PC port, so we just pass the parameters required for it instead
(let ((v1-3 (-> *setting-control* user-current)))
(when (or (!= (-> v1-3 contrast) 0.5) (!= (-> v1-3 brightness) 0.5))
(with-dma-buffer-add-bucket ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id debug-menu)
)
(draw-brightness-and-contrast this s4-0 (-> v1-3 brightness) (-> v1-3 contrast))
(reset-display-gs-state *display* s4-0)
(#cond
((not PC_PORT)
(when (or (!= (-> v1-3 contrast) 0.5) (!= (-> v1-3 brightness) 0.5))
(with-dma-buffer-add-bucket ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf))
(bucket-id debug-menu)
)
(draw-brightness-and-contrast this s4-0 (-> v1-3 brightness) (-> v1-3 contrast))
(reset-display-gs-state *display* s4-0)
)
)
)
(#t
;; og:preserve-this always calculate contrast and brightness and pass it to display settings
(let ((contrast (fmax 0.0 (fmin 1.0 (-> v1-3 contrast))))
(brightness (fmax 0.0 (fmin 1.0 (-> v1-3 brightness))))
)
(let ((bc-color (the int (* 64.2509 (+ (- 0.5 contrast) (* 2.0 (fmax 0.0 (+ -0.5 brightness)))))))
(bc-alpha (the int (fmin 255.0 (* 256.0 (fmin 1.0 (* 2.0 brightness)) contrast))))
)
(pc-set-brightness-contrast bc-color bc-alpha)
)
)
)
)
)
+1
View File
@@ -263,6 +263,7 @@
(define-extern pc-sound-set-fade-hack (function int none))
(define-extern pc-set-window-lock (function symbol none))
(define-extern pc-set-game-resolution (function int int none))
(define-extern pc-set-brightness-contrast (function int int none))
(define-extern pc-set-msaa (function int none))
(define-extern pc-set-gfx-hack (function pc-gfx-hack symbol none))
(define-extern pc-get-unix-timestamp (function int))