Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 43 additions & 13 deletions code/graphics/opengl/gropengl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,52 @@ void gr_opengl_flip()
if (Cmdline_window_res) {
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);
const float gamma = Cmdline_no_set_gamma ? 1.0f : Gr_gamma;
GLuint present_source = Back_framebuffer;

// At gamma 1.0 the correction shader is an identity transform, so skip the extra
// fullscreen pass and present Back_framebuffer directly.
if (gamma != 1.0f) {
// Gamma-correct Back_texture into an offscreen scratch texture. This is an FBO -> FBO
// draw, the same class of operation as every other post-process pass. Presenting straight
// into the window-system default framebuffer from a shader draw that samples a
// just-rendered texture caused flicker on some drivers, so the hand-off to the screen
// always goes through glBlitFramebuffer instead.
GL_state.BindFrameBuffer(GammaBlit_framebuffer);
glViewport(0, 0, gr_screen.max_w, gr_screen.max_h);

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);
// The last material of the frame may have left color writes disabled (e.g. a masked
// model pass in the briefing map render). The old blit-only present ignored the color
// mask, but this is a regular draw and needs color writes and no stencil to take effect.
GL_state.ColorMask(true, true, true, true);
GL_state.StencilTest(GL_FALSE);

opengl_set_generic_uniform_data<graphics::generic_data::gamma_blit_data>(
[gamma](graphics::generic_data::gamma_blit_data* data) {
data->gamma = gamma;
});

opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);

present_source = GammaBlit_framebuffer;
}

GL_state.SetAlphaBlendMode(gr_alpha_blend::ALPHA_BLEND_NONE);
GL_state.SetZbufferType(ZBUFFER_TYPE_NONE);
GL_state.BindFrameBuffer(0, GL_DRAW_FRAMEBUFFER);
GL_state.BindFrameBuffer(present_source, GL_READ_FRAMEBUFFER);

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;
});
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);

opengl_draw_full_screen_textured(0.0f, 0.0f, 1.0f, 1.0f);
GL_state.BindFrameBuffer(0, GL_READ_FRAMEBUFFER);
}

if (Cmdline_gl_finish)
Expand Down
53 changes: 52 additions & 1 deletion code/graphics/opengl/gropengldraw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ GLuint Back_framebuffer;
GLuint Back_texture;
GLuint Back_depth_texture;

GLuint GammaBlit_framebuffer;
GLuint GammaBlit_texture;

GLuint Distortion_framebuffer = 0;
GLuint Distortion_texture[2];
int Distortion_switch = 0;
Expand Down Expand Up @@ -578,6 +581,44 @@ void opengl_setup_scene_textures()
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, Back_depth_texture, 0);
gr_zbuffer_set(GR_ZBUFF_FULL);
glClear(GL_DEPTH_BUFFER_BIT);

// Intermediate target for the gamma-correction pass. The gamma pass samples Back_texture and writes
// here (an offscreen FBO->FBO draw, same as every other post-process pass); the result is then
// presented to the window via glBlitFramebuffer. Some drivers show flicker when a shader draw that
// samples a just-rendered texture targets the window-system default framebuffer directly, so the
// final presentation step always goes through a blit instead.
glGenFramebuffers(1, &GammaBlit_framebuffer);
GL_state.BindFrameBuffer(GammaBlit_framebuffer);
opengl_set_object_label(GL_FRAMEBUFFER, GammaBlit_framebuffer, "Gamma blit framebuffer");

if (Scene_ldr_texture != 0 && Scene_texture_width == gr_screen.max_w && Scene_texture_height == gr_screen.max_h) {
// Scene_ldr_texture is dead scratch by flip time: its consumers (tonemap, AA, the final
// post pass) all write before reading within gr_opengl_post_process_end(), which completes
// before the flip. Reuse it as the gamma pass target instead of allocating another
// screen-sized texture. GammaBlit_texture stays 0 so shutdown won't delete it.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_ldr_texture, 0);
} else {
// Scene textures are clamped to GL_max_renderbuffer_size and may not cover the screen;
// fall back to a dedicated texture in that case.
glGenTextures(1, &GammaBlit_texture);

GL_state.Texture.SetActiveUnit(0);
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
GL_state.Texture.Enable(GammaBlit_texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, gr_screen.max_w, gr_screen.max_h, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, nullptr);

glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, GammaBlit_texture, 0);
opengl_set_object_label(GL_TEXTURE, GammaBlit_texture, "Gamma blit texture");
}

GL_state.BindFrameBuffer(Back_framebuffer);
}

//Setup thruster distortion framebuffer
Expand Down Expand Up @@ -695,7 +736,17 @@ void opengl_scene_texture_shutdown()
glDeleteFramebuffers(1, &Back_framebuffer);
Back_framebuffer = 0;
}


if (GammaBlit_texture) {
glDeleteTextures(1, &GammaBlit_texture);
GammaBlit_texture = 0;
}

if (GammaBlit_framebuffer) {
glDeleteFramebuffers(1, &GammaBlit_framebuffer);
GammaBlit_framebuffer = 0;
}

glDeleteTextures(2, Distortion_texture);
Distortion_texture[0] = 0;
Distortion_texture[1] = 0;
Expand Down
3 changes: 3 additions & 0 deletions code/graphics/opengl/gropengldraw.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ extern GLuint Cockpit_depth_texture;
extern GLuint Back_framebuffer;
extern GLuint Back_texture;

extern GLuint GammaBlit_framebuffer;
extern GLuint GammaBlit_texture;

void gr_opengl_update_distortion();

void gr_opengl_sphere(material *material_def, float rad);
Expand Down
Loading