@@ -43,7 +43,7 @@ impl Instance {
43
43
44
44
Ok ( Surface {
45
45
webgl2_context,
46
- present_program : None ,
46
+ srgb_present_program : None ,
47
47
swapchain : None ,
48
48
texture : None ,
49
49
presentable : true ,
@@ -64,7 +64,7 @@ impl Instance {
64
64
65
65
Ok ( Surface {
66
66
webgl2_context,
67
- present_program : None ,
67
+ srgb_present_program : None ,
68
68
swapchain : None ,
69
69
texture : None ,
70
70
presentable : true ,
@@ -144,7 +144,7 @@ pub struct Surface {
144
144
pub ( super ) swapchain : Option < Swapchain > ,
145
145
texture : Option < glow:: Texture > ,
146
146
pub ( super ) presentable : bool ,
147
- present_program : Option < glow:: Program > ,
147
+ srgb_present_program : Option < glow:: Program > ,
148
148
}
149
149
150
150
// SAFE: Because web doesn't have threads ( yet )
@@ -166,35 +166,59 @@ impl Surface {
166
166
_suf_texture : super :: Texture ,
167
167
gl : & glow:: Context ,
168
168
) -> Result < ( ) , crate :: SurfaceError > {
169
- gl. bind_framebuffer ( glow:: DRAW_FRAMEBUFFER , None ) ;
170
- gl. bind_sampler ( 0 , None ) ;
171
- gl. active_texture ( glow:: TEXTURE0 ) ;
172
- gl. bind_texture ( glow:: TEXTURE_2D , self . texture ) ;
173
- gl. use_program ( self . present_program ) ;
174
- gl. disable ( glow:: DEPTH_TEST ) ;
175
- gl. disable ( glow:: STENCIL_TEST ) ;
176
- gl. disable ( glow:: SCISSOR_TEST ) ;
177
- gl. disable ( glow:: BLEND ) ;
178
- gl. disable ( glow:: CULL_FACE ) ;
179
- gl. draw_buffers ( & [ glow:: BACK ] ) ;
180
- gl. draw_arrays ( glow:: TRIANGLES , 0 , 3 ) ;
169
+ let swapchain = self . swapchain . as_ref ( ) . ok_or ( crate :: SurfaceError :: Other (
170
+ "need to configure surface before presenting" ,
171
+ ) ) ?;
172
+
173
+ if swapchain. format . describe ( ) . srgb {
174
+ gl. bind_framebuffer ( glow:: DRAW_FRAMEBUFFER , None ) ;
175
+ gl. bind_sampler ( 0 , None ) ;
176
+ gl. active_texture ( glow:: TEXTURE0 ) ;
177
+ gl. bind_texture ( glow:: TEXTURE_2D , self . texture ) ;
178
+ gl. use_program ( self . srgb_present_program ) ;
179
+ gl. disable ( glow:: DEPTH_TEST ) ;
180
+ gl. disable ( glow:: STENCIL_TEST ) ;
181
+ gl. disable ( glow:: SCISSOR_TEST ) ;
182
+ gl. disable ( glow:: BLEND ) ;
183
+ gl. disable ( glow:: CULL_FACE ) ;
184
+ gl. draw_buffers ( & [ glow:: BACK ] ) ;
185
+ gl. draw_arrays ( glow:: TRIANGLES , 0 , 3 ) ;
186
+ } else {
187
+ gl. bind_framebuffer ( glow:: READ_FRAMEBUFFER , Some ( swapchain. framebuffer ) ) ;
188
+ gl. bind_framebuffer ( glow:: DRAW_FRAMEBUFFER , None ) ;
189
+ // Note the Y-flipping here. GL's presentation is not flipped,
190
+ // but main rendering is. Therefore, we Y-flip the output positions
191
+ // in the shader, and also this blit.
192
+ gl. blit_framebuffer (
193
+ 0 ,
194
+ swapchain. extent . height as i32 ,
195
+ swapchain. extent . width as i32 ,
196
+ 0 ,
197
+ 0 ,
198
+ 0 ,
199
+ swapchain. extent . width as i32 ,
200
+ swapchain. extent . height as i32 ,
201
+ glow:: COLOR_BUFFER_BIT ,
202
+ glow:: NEAREST ,
203
+ ) ;
204
+ }
181
205
182
206
Ok ( ( ) )
183
207
}
184
208
185
- unsafe fn create_present_program ( gl : & glow:: Context ) -> glow:: Program {
209
+ unsafe fn create_srgb_present_program ( gl : & glow:: Context ) -> glow:: Program {
186
210
let program = gl
187
211
. create_program ( )
188
212
. expect ( "Could not create shader program" ) ;
189
213
let vertex = gl
190
214
. create_shader ( glow:: VERTEX_SHADER )
191
215
. expect ( "Could not create shader" ) ;
192
- gl. shader_source ( vertex, include_str ! ( "./shaders/present .vert" ) ) ;
216
+ gl. shader_source ( vertex, include_str ! ( "./shaders/srgb_present .vert" ) ) ;
193
217
gl. compile_shader ( vertex) ;
194
218
let fragment = gl
195
219
. create_shader ( glow:: FRAGMENT_SHADER )
196
220
. expect ( "Could not create shader" ) ;
197
- gl. shader_source ( fragment, include_str ! ( "./shaders/present .frag" ) ) ;
221
+ gl. shader_source ( fragment, include_str ! ( "./shaders/srgb_present .frag" ) ) ;
198
222
gl. compile_shader ( fragment) ;
199
223
gl. attach_shader ( program, vertex) ;
200
224
gl. attach_shader ( program, fragment) ;
@@ -207,7 +231,8 @@ impl Surface {
207
231
}
208
232
209
233
pub fn supports_srgb ( & self ) -> bool {
210
- true // WebGL only supports sRGB
234
+ // present.frag takes care of handling srgb conversion
235
+ true
211
236
}
212
237
}
213
238
@@ -224,8 +249,8 @@ impl crate::Surface<super::Api> for Surface {
224
249
gl. delete_framebuffer ( swapchain. framebuffer ) ;
225
250
}
226
251
227
- if self . present_program . is_none ( ) {
228
- self . present_program = Some ( Self :: create_present_program ( gl) ) ;
252
+ if self . srgb_present_program . is_none ( ) && config . format . describe ( ) . srgb {
253
+ self . srgb_present_program = Some ( Self :: create_srgb_present_program ( gl) ) ;
229
254
}
230
255
231
256
if let Some ( texture) = self . texture . take ( ) {
0 commit comments