mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 22:56:30 -10:00
Gamma by Shader (#7484)
* Replace SDL gamma with a blit shader gamma * Window_res comment * Fixes * Gamma command line flag
This commit is contained in:
1 parent
8b80541046
commit
cc63bfa7c1
7 files changed
+58
-112
No files matched your search
@@ -0,0 +1,18 @@
|
||||
in vec4 fragTexCoord;
|
||||
out vec4 fragOut0;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
layout (std140) uniform genericData {
|
||||
float gamma;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture(tex, fragTexCoord.xy);
|
||||
|
||||
float g = max(gamma, 0.001);
|
||||
color.rgb = pow(color.rgb, vec3(1.0 / g));
|
||||
|
||||
fragOut0 = color;
|
||||
}
|
||||
+8
-104
@@ -313,7 +313,7 @@ bool Save_custom_screen_size;
|
||||
bool Deferred_lighting = false;
|
||||
bool High_dynamic_range = false;
|
||||
|
||||
static ushort* Gr_original_gamma_ramp = nullptr;
|
||||
|
||||
|
||||
static int videodisplay_deserializer(const json_t* value)
|
||||
{
|
||||
@@ -755,7 +755,6 @@ void removeVSyncOption()
|
||||
static std::unique_ptr<graphics::util::UniformBufferManager> UniformBufferManager;
|
||||
|
||||
// Forward definitions
|
||||
static void uniform_buffer_managers_init();
|
||||
static void uniform_buffer_managers_deinit();
|
||||
static void uniform_buffer_managers_retire_buffers();
|
||||
|
||||
@@ -1305,15 +1304,6 @@ void gr_close()
|
||||
if(Cmdline_enable_vr)
|
||||
openxr_close();
|
||||
|
||||
if (Gr_original_gamma_ramp != nullptr && os::getSDLMainWindow() != nullptr) {
|
||||
SDL_SetWindowGammaRamp(os::getSDLMainWindow(), Gr_original_gamma_ramp, (Gr_original_gamma_ramp + 256),
|
||||
(Gr_original_gamma_ramp + 512));
|
||||
}
|
||||
|
||||
// This is valid even if Gr_original_gamma_ramp is nullptr
|
||||
vm_free(Gr_original_gamma_ramp);
|
||||
Gr_original_gamma_ramp = nullptr;
|
||||
|
||||
gpu_heap_deinit();
|
||||
|
||||
// Cleanup uniform buffer managers
|
||||
@@ -1870,8 +1860,13 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
|
||||
// (be that a window, a render overlay from nsight, or an FSO-internal buffer) instead of directly rendering to the OS-provided direct screen backbuffer.
|
||||
// As the cost of -window_res is one single blit of a fullscreen buffer, it's probably an acceptable compromise to get rid of render artifacts.
|
||||
// As such, forcibly enable -window_res at the screen resolution here, if we're in fullscreen.
|
||||
|
||||
//
|
||||
// Additionally, SDL3+ doesn't work when reading from the GL_FRONT buffers, so we need our own intermediate buffers.
|
||||
//
|
||||
// Furthermore, gamma handling now also requires a blit of the final scene (not just the 3D scene, since it needs to work on menus as well).
|
||||
//
|
||||
// As such, window_res is effectively no longer optional, part of the core render path and must always be enabled.
|
||||
// The only reason it is not yet refactored into an always-on thing is due to issues with FRED integration.
|
||||
Cmdline_window_res.emplace(static_cast<uint16_t>(width), static_cast<uint16_t>(height));
|
||||
}
|
||||
|
||||
@@ -1984,9 +1979,6 @@ bool gr_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps, int d_mode,
|
||||
|
||||
gr_light_init();
|
||||
|
||||
// Initialize uniform buffer managers
|
||||
uniform_buffer_managers_init();
|
||||
|
||||
gpu_heap_init();
|
||||
|
||||
mprintf(("Checking graphics capabilities:\n"));
|
||||
@@ -2995,7 +2987,7 @@ void gr_print_timestamp(int x, int y, fix timestamp, int resize_mode)
|
||||
gr_string(x, y, time.c_str(), resize_mode);
|
||||
}
|
||||
|
||||
static void uniform_buffer_managers_init()
|
||||
void gr_uniform_buffer_managers_init()
|
||||
{
|
||||
if (gr_screen.mode == GR_STUB) {
|
||||
return;
|
||||
@@ -3197,62 +3189,6 @@ void gr_heap_deallocate(GpuHeap heap_type, size_t data_offset)
|
||||
gpuHeap->freeGpuData(data_offset);
|
||||
}
|
||||
|
||||
// I feel dirty...
|
||||
static void make_gamma_ramp(float gamma, ushort* ramp)
|
||||
{
|
||||
ushort x, y;
|
||||
ushort base_ramp[256];
|
||||
|
||||
Assert(ramp != nullptr);
|
||||
|
||||
// generate the base ramp values first off
|
||||
|
||||
// if no gamma set then just do this quickly
|
||||
if (gamma <= 0.0f) {
|
||||
memset(ramp, 0, 3 * 256 * sizeof(ushort));
|
||||
return;
|
||||
}
|
||||
// identity gamma, avoid all of the math
|
||||
else if (gamma == 1.0f || Gr_original_gamma_ramp == nullptr) {
|
||||
if (Gr_original_gamma_ramp != nullptr) {
|
||||
memcpy(ramp, Gr_original_gamma_ramp, 3 * 256 * sizeof(ushort));
|
||||
}
|
||||
// set identity if no original ramp
|
||||
else {
|
||||
for (x = 0; x < 256; x++) {
|
||||
ramp[x] = (x << 8) | x;
|
||||
ramp[x + 256] = (x << 8) | x;
|
||||
ramp[x + 512] = (x << 8) | x;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
// for everything else we need to actually figure it up
|
||||
else {
|
||||
double g = 1.0 / (double)gamma;
|
||||
double val;
|
||||
|
||||
Assert(Gr_original_gamma_ramp != nullptr);
|
||||
|
||||
for (x = 0; x < 256; x++) {
|
||||
val = (pow(x / 255.0, g) * 65535.0 + 0.5);
|
||||
CLAMP(val, 0., 65535.);
|
||||
|
||||
base_ramp[x] = (ushort)val;
|
||||
}
|
||||
|
||||
for (y = 0; y < 3; y++) {
|
||||
for (x = 0; x < 256; x++) {
|
||||
val = (base_ramp[x] * 2) - Gr_original_gamma_ramp[x + y * 256];
|
||||
CLAMP(val, 0., 65535.);
|
||||
|
||||
ramp[x + y * 256] = (ushort)val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gr_set_gamma(float gamma)
|
||||
{
|
||||
if (gr_screen.mode == GR_STUB) {
|
||||
@@ -3260,38 +3196,6 @@ void gr_set_gamma(float gamma)
|
||||
}
|
||||
|
||||
Gr_gamma = gamma;
|
||||
|
||||
// new way - but not while running FRED
|
||||
if (!Fred_running && !Cmdline_no_set_gamma && os::getSDLMainWindow() != nullptr) {
|
||||
if (Gr_original_gamma_ramp == nullptr) {
|
||||
// First time we are here so get the current (original) gamma ramp here so we can reset it later
|
||||
Gr_original_gamma_ramp = (ushort*)vm_malloc(3 * 256 * sizeof(ushort), memory::quiet_alloc);
|
||||
|
||||
if (Gr_original_gamma_ramp == nullptr) {
|
||||
mprintf((" Unable to allocate memory for gamma ramp! Disabling...\n"));
|
||||
Cmdline_no_set_gamma = 1;
|
||||
} else {
|
||||
SDL_GetWindowGammaRamp(os::getSDLMainWindow(), Gr_original_gamma_ramp, (Gr_original_gamma_ramp + 256),
|
||||
(Gr_original_gamma_ramp + 512));
|
||||
}
|
||||
}
|
||||
|
||||
auto gamma_ramp = (ushort*)vm_malloc(3 * 256 * sizeof(ushort), memory::quiet_alloc);
|
||||
|
||||
if (gamma_ramp == nullptr) {
|
||||
Int3();
|
||||
return;
|
||||
}
|
||||
|
||||
memset(gamma_ramp, 0, 3 * 256 * sizeof(ushort));
|
||||
|
||||
// Create the Gamma lookup table
|
||||
make_gamma_ramp(gamma, gamma_ramp);
|
||||
|
||||
SDL_SetWindowGammaRamp(os::getSDLMainWindow(), gamma_ramp, (gamma_ramp + 256), (gamma_ramp + 512));
|
||||
|
||||
vm_free(gamma_ramp);
|
||||
}
|
||||
}
|
||||
|
||||
void gr_get_post_process_effect_names(SCP_vector<SCP_string>& names)
|
||||
|
||||
@@ -214,6 +214,8 @@ enum shader_type {
|
||||
|
||||
SDR_TYPE_IRRADIANCE_MAP_GEN,
|
||||
|
||||
SDR_TYPE_GAMMA_BLIT,
|
||||
|
||||
NUM_SHADER_TYPES
|
||||
};
|
||||
|
||||
@@ -1487,6 +1489,8 @@ void gr_get_post_process_effect_names(SCP_vector<SCP_string> &names);
|
||||
|
||||
bool gr_is_viewport_window();
|
||||
|
||||
void gr_uniform_buffer_managers_init();
|
||||
|
||||
// Include this last to make the 2D rendering function available everywhere
|
||||
#include "graphics/render.h"
|
||||
|
||||
|
||||
@@ -119,15 +119,24 @@ void gr_opengl_flip()
|
||||
return;
|
||||
|
||||
if (Cmdline_window_res) {
|
||||
GL_state.BindFrameBuffer(0, GL_DRAW_FRAMEBUFFER);
|
||||
GL_state.BindFrameBuffer(Back_framebuffer, GL_READ_FRAMEBUFFER);
|
||||
|
||||
glReadBuffer(GL_COLOR_ATTACHMENT0);
|
||||
glDrawBuffer(GL_BACK);
|
||||
glBlitFramebuffer(0, 0, gr_screen.max_w, gr_screen.max_h, 0, 0, Cmdline_window_res->first, Cmdline_window_res->second, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
glDrawBuffer(GL_NONE);
|
||||
|
||||
GL_state.PopFramebufferState();
|
||||
|
||||
glViewport(0, 0, Cmdline_window_res->first, Cmdline_window_res->second);
|
||||
|
||||
opengl_shader_set_current(gr_opengl_maybe_create_shader(SDR_TYPE_GAMMA_BLIT, 0));
|
||||
|
||||
GL_state.Texture.Enable(0, GL_TEXTURE_2D, Back_texture);
|
||||
Current_shader->program->Uniforms.setTextureUniform("tex", 0);
|
||||
|
||||
GL_state.SetAlphaBlendMode(gr_alpha_blend::ALPHA_BLEND_NONE);
|
||||
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
|
||||
|
||||
opengl_set_generic_uniform_data<graphics::generic_data::gamma_blit_data>(
|
||||
[](graphics::generic_data::gamma_blit_data* data) {
|
||||
data->gamma = Cmdline_no_set_gamma ? 1.f : Gr_gamma;
|
||||
});
|
||||
|
||||
opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
if (Cmdline_gl_finish)
|
||||
@@ -1485,6 +1494,8 @@ bool gr_opengl_init(std::unique_ptr<os::GraphicsOperations>&& graphicsOps)
|
||||
Gr_current_green = &Gr_green;
|
||||
Gr_current_alpha = &Gr_alpha;
|
||||
|
||||
// Initialize uniform buffer managers
|
||||
gr_uniform_buffer_managers_init();
|
||||
|
||||
gr_setup_frame();
|
||||
gr_opengl_reset_clip();
|
||||
|
||||
@@ -178,6 +178,9 @@ static opengl_shader_type_t GL_shader_types[] = {
|
||||
|
||||
{ SDR_TYPE_IRRADIANCE_MAP_GEN, "post-v.sdr", "irrmap-f.sdr", nullptr,
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Irradiance Map Generation", false },
|
||||
|
||||
{ SDR_TYPE_GAMMA_BLIT, "post-v.sdr", "gamma-correct-f.sdr", nullptr,
|
||||
{ opengl_vert_attrib::POSITION, opengl_vert_attrib::TEXCOORD }, "Gamma correct blit", false },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -408,6 +408,11 @@ struct irrmap_data {
|
||||
int face;
|
||||
};
|
||||
|
||||
struct gamma_blit_data {
|
||||
float gamma;
|
||||
float pad[3];
|
||||
};
|
||||
|
||||
} // namespace generic_data
|
||||
|
||||
} // namespace graphics
|
||||
@@ -247,6 +247,7 @@ add_file_folder("Default files\\\\data\\\\effects"
|
||||
def_files/data/effects/fxaa-v.sdr
|
||||
def_files/data/effects/fxaapre-f.sdr
|
||||
def_files/data/effects/gamma.sdr
|
||||
def_files/data/effects/gamma-correct-f.sdr
|
||||
def_files/data/effects/irrmap-f.sdr
|
||||
def_files/data/effects/lighting.sdr
|
||||
def_files/data/effects/ls-f.sdr
|
||||
|
||||
Reference in new issue
Block a user