Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add TextureFormat::LuminanceAlpha, fix #333 #334

Merged
merged 5 commits into from
Jan 3, 2023
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
16 changes: 10 additions & 6 deletions src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -634,11 +634,15 @@ pub const MAX_SHADERSTAGE_IMAGES: usize = 12;

pub struct Features {
pub instancing: bool,
pub alpha_texture: bool,
}

impl Default for Features {
fn default() -> Features {
Features { instancing: true }
impl Features {
pub fn from_gles2(is_gles2: bool) -> Self {
Features {
instancing: !is_gles2,
alpha_texture: is_gles2,
}
}
}

Expand All @@ -654,7 +658,7 @@ pub struct GraphicsContext {
}

impl GraphicsContext {
pub fn new() -> GraphicsContext {
pub fn new(is_gles2: bool) -> GraphicsContext {
unsafe {
let mut default_framebuffer: GLuint = 0;
glGetIntegerv(
Expand All @@ -670,7 +674,7 @@ impl GraphicsContext {
shaders: vec![],
pipelines: vec![],
passes: vec![],
features: Default::default(),
features: Features::from_gles2(is_gles2),
cache: GlCache {
stored_index_buffer: 0,
stored_index_type: None,
Expand Down Expand Up @@ -698,7 +702,7 @@ impl GraphicsContext {
}
}

impl Context {
impl GraphicsContext {
pub fn apply_pipeline(&mut self, pipeline: &Pipeline) {
self.cache.cur_pipeline = Some(*pipeline);

Expand Down
89 changes: 57 additions & 32 deletions src/graphics/texture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,24 +54,37 @@ pub enum TextureFormat {
RGBA8,
Depth,
Alpha,
LuminanceAlpha,
}

/// Converts from TextureFormat to (internal_format, format, pixel_type)
impl From<TextureFormat> for (GLenum, GLenum, GLenum) {
fn from(format: TextureFormat) -> Self {
match format {
impl TextureFormat {
/// Converts from TextureFormat to (internal_format, format, pixel_type)
fn into_gl_params(self, alpha_texture: bool) -> (GLenum, GLenum, GLenum) {
match self {
TextureFormat::RGB8 => (GL_RGB, GL_RGB, GL_UNSIGNED_BYTE),
TextureFormat::RGBA8 => (GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE),
TextureFormat::Depth => (GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT),

#[cfg(target_arch = "wasm32")]
TextureFormat::Alpha => (GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE),
#[cfg(not(target_arch = "wasm32"))]
TextureFormat::Alpha if alpha_texture => (GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE),
#[cfg(not(target_arch = "wasm32"))]
TextureFormat::Alpha => (GL_R8, GL_RED, GL_UNSIGNED_BYTE), // texture updates will swizzle Red -> Alpha to match WASM

#[cfg(target_arch = "wasm32")]
TextureFormat::LuminanceAlpha => {
(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE)
}
#[cfg(not(target_arch = "wasm32"))]
TextureFormat::LuminanceAlpha if alpha_texture => {
(GL_LUMINANCE_ALPHA, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE)
}
#[cfg(not(target_arch = "wasm32"))]
TextureFormat::LuminanceAlpha => (GL_RG, GL_RG, GL_UNSIGNED_BYTE), // texture updates will swizzle Green -> Alpha to match WASM
}
}
}

impl TextureFormat {
/// Returns the size in bytes of texture with `dimensions`.
pub fn size(self, width: u32, height: u32) -> u32 {
let square = width * height;
Expand All @@ -80,6 +93,7 @@ impl TextureFormat {
TextureFormat::RGBA8 => 4 * square,
TextureFormat::Depth => 2 * square,
TextureFormat::Alpha => 1 * square,
TextureFormat::LuminanceAlpha => 2 * square,
}
}
}
Expand Down Expand Up @@ -149,7 +163,8 @@ impl Texture {
);
}

let (internal_format, format, pixel_type) = params.format.into();
let (internal_format, format, pixel_type) =
params.format.into_gl_params(ctx.features().alpha_texture);

ctx.cache.store_texture_binding(0);

Expand All @@ -160,17 +175,7 @@ impl Texture {
ctx.cache.bind_texture(0, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // miniquad always uses row alignment of 1

if cfg!(not(target_arch = "wasm32")) {
// if not WASM
if params.format == TextureFormat::Alpha {
// if alpha miniquad texture, the value on non-WASM is stored in red channel
// swizzle red -> alpha
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED as _);
} else {
// keep alpha -> alpha
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA as _);
}
}
Self::apply_swizzle_parameter(params.format);

glTexImage2D(
GL_TEXTURE_2D,
Expand Down Expand Up @@ -247,12 +252,19 @@ impl Texture {
pub fn resize(&mut self, ctx: &mut Context, width: u32, height: u32, bytes: Option<&[u8]>) {
ctx.cache.store_texture_binding(0);

let (internal_format, format, pixel_type) = self.format.into();
let (internal_format, format, pixel_type) =
self.format.into_gl_params(ctx.features().alpha_texture);

self.width = width;
self.height = height;

unsafe {
ctx.cache.bind_texture(0, self.texture);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // miniquad always uses row alignment of 1

Self::apply_swizzle_parameter(self.format);

glTexImage2D(
GL_TEXTURE_2D,
0,
Expand Down Expand Up @@ -303,22 +315,12 @@ impl Texture {
ctx.cache.store_texture_binding(0);
ctx.cache.bind_texture(0, self.texture);

let (_, format, pixel_type) = self.format.into();
let (_, format, pixel_type) = self.format.into_gl_params(ctx.features().alpha_texture);

unsafe {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // miniquad always uses row alignment of 1

if cfg!(not(target_arch = "wasm32")) {
// if not WASM
if self.format == TextureFormat::Alpha {
// if alpha miniquad texture, the value on non-WASM is stored in red channel
// swizzle red -> alpha
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED as _);
} else {
// keep alpha -> alpha
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_ALPHA as _);
}
}
Self::apply_swizzle_parameter(self.format);

glTexSubImage2D(
GL_TEXTURE_2D,
Expand All @@ -338,7 +340,10 @@ impl Texture {

/// Read texture data into CPU memory
pub fn read_pixels(&self, bytes: &mut [u8]) {
let (_, format, pixel_type) = self.format.into();
if self.format == TextureFormat::Alpha || self.format == TextureFormat::LuminanceAlpha {
unimplemented!("read_pixels is not implement for Alpha and LuminanceAlpha textures");
}
let (_, format, pixel_type) = self.format.into_gl_params(false);

let mut fbo = 0;
unsafe {
Expand Down Expand Up @@ -373,4 +378,24 @@ impl Texture {
fn size(&self, width: u32, height: u32) -> usize {
self.format.size(width, height) as usize
}

#[inline]
unsafe fn apply_swizzle_parameter(format: TextureFormat) {
if cfg!(not(target_arch = "wasm32")) {
// if not WASM
match format {
// on non-WASM alpha value is stored in red channel
// swizzle red -> alpha
TextureFormat::Alpha => {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_RED as _)
}
// on non-WASM luminance is stored in red channel, alpha is stored in green channel
// keep red, swizzle green -> alpha
TextureFormat::LuminanceAlpha => {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_A, GL_GREEN as _)
}
_ => {}
}
}
}
}
3 changes: 1 addition & 2 deletions src/native/android.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,8 +431,7 @@ where
panic!();
}

let mut context = GraphicsContext::new();
context.features.instancing = !gl::is_gl2();
let mut context = GraphicsContext::new(gl::is_gl2());

let mut display = AndroidDisplay {
screen_width,
Expand Down
2 changes: 2 additions & 0 deletions src/native/apple/gl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,8 @@ pub const GL_BLUE: u32 = 6405;
pub const GL_ALPHA: u32 = 6406;
pub const GL_RGB: u32 = 6407;
pub const GL_RGBA: u32 = 6408;
pub const GL_LUMINANCE: u32 = 6409;
pub const GL_LUMINANCE_ALPHA: u32 = 6410;
pub const GL_POINT: u32 = 6912;
pub const GL_LINE: u32 = 6913;
pub const GL_FILL: u32 = 6914;
Expand Down
4 changes: 1 addition & 3 deletions src/native/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,7 @@ pub fn define_glk_view_dlg() -> *const Class {
let payload = get_window_payload(this);
if payload.event_handler.is_none() {
let f = payload.f.take().unwrap();
let mut context = GraphicsContext::new();
context.features.instancing = !payload.gles2;
payload.context = Some(context);
payload.context = Some(GraphicsContext::new(payload.gles2));
payload.event_handler = Some(f(payload
.context
.as_mut()
Expand Down
3 changes: 1 addition & 2 deletions src/native/linux_wayland.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,8 +484,7 @@ where
));
}

let context = crate::GraphicsContext::new();
payload.context = Some(context);
payload.context = Some(crate::GraphicsContext::new(false));
payload.display.data.screen_width = conf.window_width;
payload.display.data.screen_height = conf.window_height;

Expand Down
8 changes: 2 additions & 6 deletions src/native/linux_x11.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,9 +719,7 @@ where
display.data.screen_width = w;
display.data.screen_height = h;

let mut context = GraphicsContext::new();

context.features.instancing = !gl::is_gl2();
let mut context = GraphicsContext::new(gl::is_gl2());

let mut data = (f.take().unwrap())(context.with_display(&mut display));

Expand Down Expand Up @@ -807,9 +805,7 @@ where

(display.libx11.XFlush)(display.display);

let mut context = GraphicsContext::new();

context.features.instancing = !gl::is_gl2();
let mut context = GraphicsContext::new(gl::is_gl2());

let (w, h) = display.query_window_size(window);
display.data.screen_width = w;
Expand Down
2 changes: 1 addition & 1 deletion src/native/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ pub fn define_cocoa_view_class() -> *const Class {
let () = msg_send![ctx, makeCurrentContext];
}

payload.context = Some(GraphicsContext::new());
payload.context = Some(GraphicsContext::new(false));

let f = payload.f.take().unwrap();
payload.event_handler = Some(f(payload
Expand Down
2 changes: 1 addition & 1 deletion src/native/wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ where
}

// run user intialisation code
let mut context = crate::GraphicsContext::new();
let mut context = crate::GraphicsContext::new(false);

GLOBALS.with(|g| {
let mut display = WasmDisplay {
Expand Down
3 changes: 1 addition & 2 deletions src/native/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -848,8 +848,7 @@ where

super::gl::load_gl_funcs(|proc| display.get_proc_address(proc));

let mut context = GraphicsContext::new();
context.features.instancing = !crate::gl::is_gl2();
let mut context = GraphicsContext::new(crate::gl::is_gl2());

let event_handler = f(context.with_display(&mut display));

Expand Down