diff --git a/examples/msaa_render_texture.rs b/examples/msaa_render_texture.rs index b99f5d31..d81ba16a 100644 --- a/examples/msaa_render_texture.rs +++ b/examples/msaa_render_texture.rs @@ -37,7 +37,13 @@ impl Stage { sample_count: 4, ..Default::default() }); - + // Without this check, new_render_pass_mrt might panic on GL2/WebGl1. + // It is recommended to handle it and create a normal, + // non-msaa render pass instead. + assert!( + ctx.info().features.resolve_attachments, + "MSAA render targets are not supported on current rendering backend!" + ); let offscreen_pass = ctx.new_render_pass_mrt(&[color_img], Some(&[color_resolve_img]), Some(depth_img)); @@ -235,7 +241,7 @@ impl EventHandler for Stage { self.ctx.apply_pipeline(&self.display_pipeline); self.ctx.apply_bindings(&self.display_bind); self.ctx.apply_uniforms(UniformsSource::table(&vs_params)); - self.ctx.draw(0, 36, 1); + self.ctx.draw(0, 6, 1); self.ctx.end_render_pass(); self.ctx.commit_frame(); @@ -245,6 +251,7 @@ impl EventHandler for Stage { fn main() { let mut conf = conf::Conf::default(); let metal = std::env::args().nth(1).as_deref() == Some("metal"); + conf.platform.webgl_version = conf::WebGLVersion::WebGL2; conf.platform.apple_gfx_api = if metal { conf::AppleGfxApi::Metal } else { diff --git a/examples/quad.rs b/examples/quad.rs index dfb938b0..821acb11 100644 --- a/examples/quad.rs +++ b/examples/quad.rs @@ -123,7 +123,6 @@ fn main() { } else { conf::AppleGfxApi::OpenGl }; - conf.platform.webgl_version = conf::WebGLVersion::WebGL2; miniquad::start(conf, move || Box::new(Stage::new())); } diff --git a/src/graphics.rs b/src/graphics.rs index 28f9e304..c2a270a1 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -392,7 +392,7 @@ pub struct TextureParams { /// On OpenGL, for a `sample_count > 1` render texture, render buffer object will /// be created instead of a regulat texture. /// - /// The only way to use + /// The only way to use pub sample_count: i32, } @@ -569,11 +569,21 @@ pub const MAX_SHADERSTAGE_IMAGES: usize = 12; #[derive(Clone, Debug)] pub struct Features { pub instancing: bool, + /// Does current rendering backend support automatic resolve of + /// multisampled render passes on end_render_pass. + /// Would be false on WebGl1 and GL2. + /// + /// With resolve_attachments: false, not-none resolve_img in new_render_pass will + /// result in a runtime panic. + pub resolve_attachments: bool, } impl Default for Features { fn default() -> Features { - Features { instancing: true } + Features { + instancing: true, + resolve_attachments: true, + } } } @@ -1203,7 +1213,10 @@ pub trait RenderingBackend { /// Same as "new_render_pass", but allows multiple color attachments. /// if `resolve_img` is set, MSAA-resolve operation will happen in `end_render_pass` /// this operation require `color_img` to have sample_count > 1,resolve_img have - /// sample_count == 1, and color_img.len() should be equal to resolve_img.len() + /// sample_count == 1, and color_img.len() should be equal to resolve_img.len() + /// + /// Note that resolve attachments may be not supported by current backend! + /// They are only available when `ctx.info().features.resolve_attachments` is true. fn new_render_pass_mrt( &mut self, color_img: &[TextureId], diff --git a/src/graphics/gl.rs b/src/graphics/gl.rs index d5cd77ee..1bc24708 100644 --- a/src/graphics/gl.rs +++ b/src/graphics/gl.rs @@ -501,11 +501,7 @@ impl GlContext { glGenVertexArrays(1, &mut vao as *mut _); glBindVertexArray(vao); - let features = Features { - instancing: !crate::native::gl::is_gl2(), - ..Default::default() - }; - let info = gl_info(features); + let info = gl_info(); GlContext { default_framebuffer, shaders: ResourceManager::default(), @@ -782,7 +778,7 @@ impl GlContext { } } -fn gl_info(features: Features) -> ContextInfo { +fn gl_info() -> ContextInfo { let version_string = unsafe { glGetString(super::gl::GL_VERSION) }; let gl_version_string = unsafe { std::ffi::CStr::from_ptr(version_string as _) } .to_str() @@ -790,6 +786,17 @@ fn gl_info(features: Features) -> ContextInfo { .to_string(); //let gles2 = !gles3 && gl_version_string.contains("OpenGL ES"); + let gl2 = gl_version_string.is_empty() + || gl_version_string.starts_with("2") + || gl_version_string.starts_with("OpenGL ES 2"); + let webgl1 = gl_version_string == "WebGL 1.0"; + + let features = Features { + instancing: !gl2, + resolve_attachments: !webgl1 && !gl2, + ..Default::default() + }; + let mut glsl_support = GlslSupport::default(); // this is not quite documented,