Skip to content

Commit 9013d39

Browse files
committed
Fix wrong usage of cockpit depth buffer
The root issue of #976 was that the code that reset the depth buffer of the scene framebuffer was actually setting the depth buffer of the bloom framebuffer since that didn't get reset properly. To fix this I introduced a system in our GL_state which keeps track of a stack of "bound" framebuffers which allows us to return to the previous framebuffer with a simple function call. I also added support for GL_KHR_debug since that help me while debugging which texture was in use. In the future I'll probably extend that to other areas of the OpenGL code as needed. This fixes #976.
1 parent 7c55685 commit 9013d39

File tree

7 files changed

+103
-46
lines changed

7 files changed

+103
-46
lines changed

code/graphics/opengl/gropengldraw.cpp

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,8 @@ void opengl_setup_scene_textures()
15761576

15771577
// create framebuffer
15781578
glGenFramebuffers(1, &Scene_framebuffer);
1579-
glBindFramebuffer(GL_FRAMEBUFFER, Scene_framebuffer);
1579+
GL_state.BindFrameBuffer(Scene_framebuffer);
1580+
glObjectLabelKHR(GL_FRAMEBUFFER, Scene_framebuffer, -1, "Scene framebuffer");
15801581

15811582
// setup main render texture
15821583

@@ -1596,6 +1597,7 @@ void opengl_setup_scene_textures()
15961597
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, Scene_texture_width, Scene_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
15971598

15981599
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Scene_color_texture, 0);
1600+
glObjectLabelKHR(GL_TEXTURE, Scene_color_texture, -1, "Scene color texture");
15991601

16001602
// setup low dynamic range color texture
16011603
glGenTextures(1, &Scene_ldr_texture);
@@ -1611,6 +1613,7 @@ void opengl_setup_scene_textures()
16111613
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
16121614

16131615
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Scene_texture_width, Scene_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
1616+
glObjectLabelKHR(GL_TEXTURE, Scene_ldr_texture, -1, "Scene LDR texture");
16141617

16151618
// setup position render texture
16161619
glGenTextures(1, &Scene_position_texture);
@@ -1626,6 +1629,7 @@ void opengl_setup_scene_textures()
16261629
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
16271630

16281631
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, Scene_texture_width, Scene_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
1632+
glObjectLabelKHR(GL_TEXTURE, Scene_position_texture, -1, "Scene Position texture");
16291633

16301634
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, Scene_position_texture, 0);
16311635

@@ -1643,6 +1647,7 @@ void opengl_setup_scene_textures()
16431647
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
16441648

16451649
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, Scene_texture_width, Scene_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
1650+
glObjectLabelKHR(GL_TEXTURE, Scene_normal_texture, -1, "Scene Normal texture");
16461651

16471652
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, Scene_normal_texture, 0);
16481653

@@ -1660,6 +1665,7 @@ void opengl_setup_scene_textures()
16601665
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
16611666

16621667
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, Scene_texture_width, Scene_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
1668+
glObjectLabelKHR(GL_TEXTURE, Scene_specular_texture, -1, "Scene Specular texture");
16631669

16641670
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_TEXTURE_2D, Scene_specular_texture, 0);
16651671

@@ -1678,6 +1684,7 @@ void opengl_setup_scene_textures()
16781684
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
16791685

16801686
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, Scene_texture_width, Scene_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
1687+
glObjectLabelKHR(GL_TEXTURE, Scene_luminance_texture, -1, "Scene Luminance texture");
16811688

16821689
// setup effect texture
16831690

@@ -1694,6 +1701,7 @@ void opengl_setup_scene_textures()
16941701
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
16951702

16961703
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, Scene_texture_width, Scene_texture_height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
1704+
glObjectLabelKHR(GL_TEXTURE, Scene_effect_texture, -1, "Scene Effect texture");
16971705

16981706
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT4, GL_TEXTURE_2D, Scene_effect_texture, 0);
16991707

@@ -1712,6 +1720,8 @@ void opengl_setup_scene_textures()
17121720
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
17131721

17141722
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, Scene_texture_width, Scene_texture_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
1723+
glObjectLabelKHR(GL_TEXTURE, Cockpit_depth_texture, -1, "Cockpit depth texture");
1724+
17151725
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Cockpit_depth_texture, 0);
17161726
gr_zbuffer_set(GR_ZBUFF_FULL);
17171727
glClear(GL_DEPTH_BUFFER_BIT);
@@ -1731,6 +1741,7 @@ void opengl_setup_scene_textures()
17311741
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
17321742

17331743
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, Scene_texture_width, Scene_texture_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
1744+
glObjectLabelKHR(GL_TEXTURE, Scene_depth_texture, -1, "Scene depth texture");
17341745
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Scene_depth_texture, 0);
17351746

17361747
//setup main stencil buffer
@@ -1742,7 +1753,7 @@ void opengl_setup_scene_textures()
17421753
glReadBuffer(GL_COLOR_ATTACHMENT0);
17431754

17441755
if ( opengl_check_framebuffer() ) {
1745-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
1756+
GL_state.BindFrameBuffer(0);
17461757
glDeleteFramebuffers(1, &Scene_framebuffer);
17471758
Scene_framebuffer = 0;
17481759

@@ -1779,7 +1790,7 @@ void opengl_setup_scene_textures()
17791790
if (Cmdline_fb_thrusters || Cmdline_fb_explosions)
17801791
{
17811792
glGenFramebuffers(1, &Distortion_framebuffer);
1782-
glBindFramebuffer(GL_FRAMEBUFFER, Distortion_framebuffer);
1793+
GL_state.BindFrameBuffer(Distortion_framebuffer);
17831794

17841795
glGenTextures(2, Distortion_texture);
17851796

@@ -1810,7 +1821,7 @@ void opengl_setup_scene_textures()
18101821

18111822

18121823
if ( opengl_check_framebuffer() ) {
1813-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
1824+
GL_state.BindFrameBuffer(0);
18141825
glDeleteFramebuffers(1, &Distortion_framebuffer);
18151826
Distortion_framebuffer = 0;
18161827

@@ -1829,7 +1840,7 @@ void opengl_setup_scene_textures()
18291840
return;
18301841
}
18311842

1832-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
1843+
GL_state.BindFrameBuffer(0);
18331844

18341845
Scene_texture_initialized = 1;
18351846
Scene_framebuffer_in_frame = false;
@@ -1902,7 +1913,9 @@ void gr_opengl_scene_texture_begin()
19021913

19031914
GR_DEBUG_SCOPE("Begin scene texture");
19041915

1905-
glBindFramebuffer(GL_FRAMEBUFFER, Scene_framebuffer);
1916+
GL_state.PushFramebufferState();
1917+
GL_state.BindFrameBuffer(Scene_framebuffer);
1918+
//glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Scene_depth_texture, 0);
19061919

19071920
if (GL_rendering_to_texture)
19081921
{
@@ -1967,7 +1980,7 @@ void gr_opengl_scene_texture_end()
19671980
GLboolean blend = GL_state.Blend(GL_FALSE);
19681981
GLboolean cull = GL_state.CullFace(GL_FALSE);
19691982

1970-
glBindFramebuffer(GL_FRAMEBUFFER, opengl_get_rtt_framebuffer());
1983+
GL_state.PopFramebufferState();
19711984

19721985
GL_state.Texture.SetActiveUnit(0);
19731986
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
@@ -2046,6 +2059,8 @@ void gr_opengl_deferred_lighting_begin()
20462059
if ( Cmdline_no_deferred_lighting)
20472060
return;
20482061

2062+
GR_DEBUG_SCOPE("Deferred lighting begin");
2063+
20492064
Deferred_lighting = true;
20502065
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
20512066

@@ -2057,6 +2072,9 @@ void gr_opengl_deferred_lighting_end()
20572072
{
20582073
if(!Deferred_lighting)
20592074
return;
2075+
2076+
GR_DEBUG_SCOPE("Deferred lighting end");
2077+
20602078
Deferred_lighting = false;
20612079
glDrawBuffer(GL_COLOR_ATTACHMENT0);
20622080

@@ -2071,6 +2089,7 @@ extern float static_tube_factor;
20712089

20722090
void gr_opengl_deferred_lighting_finish()
20732091
{
2092+
GR_DEBUG_SCOPE("Deferred lighting finish");
20742093
TRACE_SCOPE(tracing::ApplyLights);
20752094

20762095
if ( Cmdline_no_deferred_lighting ) {
@@ -2122,6 +2141,8 @@ void gr_opengl_deferred_lighting_finish()
21222141

21232142
for(int i = 0; i < Num_lights; ++i)
21242143
{
2144+
GR_DEBUG_SCOPE("Deferred apply single light");
2145+
21252146
light *l = &lights_copy[i];
21262147
Current_shader->program->Uniforms.setUniformi( "lightType", 0 );
21272148
switch(l->type)
@@ -2209,6 +2230,7 @@ void gr_opengl_deferred_lighting_finish()
22092230
GL_state.Texture.Enable(Scene_luminance_texture);
22102231

22112232
GL_state.SetAlphaBlendMode( ALPHA_BLEND_ADDITIVE );
2233+
GL_state.DepthMask(GL_FALSE);
22122234

22132235
opengl_draw_textured_quad(0.0f, 0.0f, 0.0f, Scene_texture_v_scale, (float)gr_screen.max_w, (float)gr_screen.max_h, Scene_texture_u_scale, 0.0f);
22142236

@@ -2270,7 +2292,9 @@ void gr_opengl_update_distortion()
22702292
GLboolean cull = GL_state.CullFace(GL_FALSE);
22712293

22722294
opengl_shader_set_passthrough(true, false);
2273-
glBindFramebuffer(GL_FRAMEBUFFER, Distortion_framebuffer);
2295+
2296+
GL_state.PushFramebufferState();
2297+
GL_state.BindFrameBuffer(Distortion_framebuffer);
22742298
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Distortion_texture[!Distortion_switch], 0);
22752299
glDrawBuffer(GL_COLOR_ATTACHMENT0);
22762300

@@ -2339,7 +2363,7 @@ void gr_opengl_update_distortion()
23392363
Distortion_switch = !Distortion_switch;
23402364

23412365
// reset state
2342-
glBindFramebuffer(GL_FRAMEBUFFER, Scene_framebuffer);
2366+
GL_state.PopFramebufferState();
23432367

23442368
glViewport(0,0,gr_screen.max_w,gr_screen.max_h);
23452369

code/graphics/opengl/gropenglpostprocessing.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,15 @@ void opengl_post_pass_bloom()
103103
// we need the scissor test disabled
104104
GLboolean scissor_test = GL_state.ScissorTest(GL_FALSE);
105105

106+
GL_state.PushFramebufferState();
107+
106108
// ------ begin bright pass ------
107109
int width, height;
108110
{
109111
GR_DEBUG_SCOPE("Bloom bright pass");
110112
TRACE_SCOPE(tracing::BloomBrightPass);
111113

112-
glBindFramebuffer(GL_FRAMEBUFFER, Bloom_framebuffer);
114+
GL_state.BindFrameBuffer(Bloom_framebuffer);
113115
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, Bloom_textures[0], 0);
114116

115117
// width and height are 1/2 for the bright pass
@@ -224,7 +226,8 @@ void gr_opengl_post_process_begin()
224226
return;
225227
}
226228

227-
glBindFramebuffer(GL_FRAMEBUFFER, Post_framebuffer_id[0]);
229+
GL_state.PushFramebufferState();
230+
GL_state.BindFrameBuffer(Post_framebuffer_id[0]);
228231

229232
glDrawBuffer(GL_COLOR_ATTACHMENT0);
230233

@@ -383,6 +386,8 @@ void gr_opengl_post_process_end()
383386
// do tone mapping
384387
opengl_post_pass_tonemap();
385388

389+
GL_state.PopFramebufferState();
390+
386391
// Do FXAA
387392
if (Cmdline_fxaa && !fxaa_unavailable && !GL_rendering_to_texture) {
388393
opengl_post_pass_fxaa();
@@ -394,8 +399,8 @@ void gr_opengl_post_process_end()
394399
GR_DEBUG_SCOPE("Draw post effects");
395400
TRACE_SCOPE(tracing::DrawPostEffects);
396401

397-
// now write to the on-screen buffer
398-
glBindFramebuffer(GL_FRAMEBUFFER, opengl_get_rtt_framebuffer());
402+
// now write to the previous buffer
403+
GL_state.PopFramebufferState();
399404

400405
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
401406
glClear(GL_COLOR_BUFFER_BIT);
@@ -432,7 +437,7 @@ void gr_opengl_post_process_end()
432437
}
433438

434439
// now render it to the screen ...
435-
glBindFramebuffer(GL_FRAMEBUFFER,0);
440+
GL_state.BindFrameBuffer(0);
436441
GL_state.Texture.SetActiveUnit(0);
437442
GL_state.Texture.SetTarget(GL_TEXTURE_2D);
438443
//GL_state.Texture.Enable(Scene_color_texture);
@@ -585,6 +590,7 @@ void gr_opengl_post_process_set_defaults()
585590
extern GLuint Cockpit_depth_texture;
586591
void gr_opengl_post_process_save_zbuffer()
587592
{
593+
GR_DEBUG_SCOPE("Save z-Buffer");
588594
if (Post_initialized)
589595
{
590596
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, Cockpit_depth_texture, 0);
@@ -870,7 +876,7 @@ void opengl_setup_bloom_textures()
870876
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MAX_MIP_BLUR_LEVELS-1);
871877
}
872878

873-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
879+
GL_state.BindFrameBuffer(0);
874880
}
875881

876882
// generate and test the framebuffer and textures that we are going to use
@@ -896,7 +902,7 @@ static bool opengl_post_init_framebuffer()
896902
int size = (Cmdline_shadow_quality == 2 ? 1024 : 512);
897903

898904
glGenFramebuffers(1, &Post_shadow_framebuffer_id);
899-
glBindFramebuffer(GL_FRAMEBUFFER, Post_shadow_framebuffer_id);
905+
GL_state.BindFrameBuffer(Post_shadow_framebuffer_id);
900906

901907
glGenTextures(1, &Post_shadow_texture_id);
902908

@@ -947,7 +953,7 @@ static bool opengl_post_init_framebuffer()
947953
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, Post_shadow_depth_texture_id, 0);
948954
}
949955

950-
glBindFramebuffer(GL_FRAMEBUFFER, 0);
956+
GL_state.BindFrameBuffer(0);
951957

952958
rval = true;
953959

code/graphics/opengl/gropenglstate.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ void opengl_state::init()
180180

181181
current_program = 0;
182182
glUseProgram(0);
183+
184+
current_framebuffer = 0;
185+
glBindFramebuffer(GL_FRAMEBUFFER, 0);
186+
187+
framebuffer_stack.clear();
183188
}
184189

185190
GLboolean opengl_state::Blend(GLint state)
@@ -508,6 +513,23 @@ void opengl_state::UseProgram(GLuint program)
508513
bool opengl_state::IsCurrentProgram(GLuint program) {
509514
return current_program == program;
510515
}
516+
void opengl_state::BindFrameBuffer(GLuint name) {
517+
if (current_framebuffer != name) {
518+
glBindFramebuffer(GL_FRAMEBUFFER, name);
519+
current_framebuffer = name;
520+
}
521+
}
522+
void opengl_state::PushFramebufferState() {
523+
framebuffer_stack.push_back(current_framebuffer);
524+
}
525+
void opengl_state::PopFramebufferState() {
526+
Assertion(framebuffer_stack.size() > 0, "Tried to pop the framebuffer state stack while it was empty!");
527+
528+
auto restoreBuffer = framebuffer_stack.back();
529+
framebuffer_stack.pop_back();
530+
531+
BindFrameBuffer(restoreBuffer);
532+
}
511533

512534
opengl_array_state::~opengl_array_state()
513535
{

code/graphics/opengl/gropenglstate.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ class opengl_state
173173
gr_stencil_type Current_stencil_type;
174174

175175
GLuint current_program;
176+
177+
// The framebuffer state actually consists of draw and read buffers but we only use both at the same time
178+
GLuint current_framebuffer;
179+
SCP_vector<GLuint> framebuffer_stack;
176180
public:
177181
opengl_state() {}
178182
~opengl_state() {}
@@ -213,6 +217,11 @@ class opengl_state
213217

214218
void UseProgram(GLuint program);
215219
bool IsCurrentProgram(GLuint program);
220+
221+
void BindFrameBuffer(GLuint name);
222+
223+
void PushFramebufferState();
224+
void PopFramebufferState();
216225
};
217226

218227
inline GLenum opengl_state::FrontFaceValue(GLenum new_val)
@@ -277,5 +286,4 @@ extern opengl_state GL_state;
277286
void gr_opengl_clear_states();
278287
void opengl_setup_render_states(int &r,int &g,int &b,int &alpha, int &tmap_type, int flags, int is_scaler = 0);
279288

280-
281289
#endif // _GROPENGLSTATE_H

0 commit comments

Comments
 (0)