@@ -286,12 +286,19 @@ void gr_opengl_print_screen(const char *filename)
286286 // Reading from the front buffer here seems to no longer work correctly; that just reads back all zeros
287287 glReadBuffer (Cmdline_window_res ? GL_COLOR_ATTACHMENT0 : GL_FRONT );
288288
289+ // Clamp float values to [0,1] when reading from the GL_RGBA16F back framebuffer.
290+ // The default GL_FIXED_ONLY only clamps fixed-point FBOs, leaving float FBO reads
291+ // with out-of-range values (HDR > 1.0) producing undefined behavior when converted
292+ // to integer types, which manifests as rainbow artifacts on bright areas.
293+ glClampColor (GL_CLAMP_READ_COLOR , GL_TRUE );
294+
289295 // now for the data
290296 if (Use_PBOs) {
291297 Assert ( !pbo );
292298 glGenBuffers (1 , &pbo);
293299
294300 if ( !pbo ) {
301+ glClampColor (GL_CLAMP_READ_COLOR , GL_FIXED_ONLY );
295302 return ;
296303 }
297304
@@ -306,17 +313,28 @@ void gr_opengl_print_screen(const char *filename)
306313 pixels = (GLubyte*) vm_malloc (gr_screen.max_w * gr_screen.max_h * 4 , memory::quiet_alloc);
307314
308315 if (pixels == NULL ) {
316+ glClampColor (GL_CLAMP_READ_COLOR , GL_FIXED_ONLY );
309317 return ;
310318 }
311319
312320 glReadPixels (0 , 0 , gr_screen.max_w , gr_screen.max_h , GL_RGBA , GL_UNSIGNED_INT_8_8_8_8_REV , pixels);
313321 glFlush ();
314322 }
315323
324+ glClampColor (GL_CLAMP_READ_COLOR , GL_FIXED_ONLY );
325+
326+ // Force alpha to fully opaque so screenshots are not saved with transparency.
327+ // The framebuffer alpha can be < 255 due to blending operations affecting the alpha
328+ // channel as a side effect, even though the rendered image itself is opaque.
329+ int num_pixels = gr_screen.max_w * gr_screen.max_h ;
330+ for (int i = 0 ; i < num_pixels; i++) {
331+ pixels[i * 4 + 3 ] = 255 ;
332+ }
333+
316334 if (!png_write_bitmap (os_get_config_path (tmp).c_str (), gr_screen.max_w , gr_screen.max_h , true , pixels)) {
317335 ReleaseWarning (LOCATION , " Failed to write screenshot to \" %s\" ." , os_get_config_path (tmp).c_str ());
318336 }
319-
337+
320338 if (pbo) {
321339 glUnmapBuffer (GL_PIXEL_PACK_BUFFER );
322340 pixels = NULL ;
0 commit comments