操作纹理缓冲区 sdl2 rust 时设置正确的像素颜色

问题描述 投票:0回答:1

我正在尝试创建一个稍微有效的函数来渲染圆。我尝试使用中点算法逐像素绘制像素,但这太慢了。因此,经过一些研究,我选择创建纹理,锁定它并操纵它的像素。问题是我似乎无法获得正确的颜色。这是我想到的:

pub fn fill_circle(&mut self, center: impl Into<Vector2>, radius: impl ToF32) {
    let center = center.into();
    let r = radius.to_f32();
    let d = r * 2.0;
    let color = self.canvas.draw_color();

    let mut texture = unsafe {
        TEXTURE_CREATOR
            .get()
            .unwrap()
            .create_texture_streaming(PixelFormatEnum::RGBA8888, d as u32, d as u32)
            .unwrap()
    };

    texture.set_blend_mode(sdl2::render::BlendMode::Blend);

    texture
        .with_lock(None, |buffer, pitch| {
            for x in 0..d as usize {
                for y in 0..d as usize {
                    let circle_v = (x as f32 - r) * (x as f32 - r)
                        + (y as f32 - r) * (y as f32 - r)
                        - r * r;

                    let i = y * pitch + x * 4;

                    if circle_v <= 0.0 {
                        buffer[i] = color.r;
                        buffer[i + 1] = color.g;
                        buffer[i + 2] = color.b;
                        buffer[i + 3] = color.a;
                    }
                }
            }
        })
        .expect("Failed to lock texture");

    let target_rect = FRect::new(center.x - r, center.y - r, d, d);
    self.canvas
        .copy_f(&texture, None, Some(target_rect))
        .unwrap();

    unsafe { texture.destroy() };
}

忽略

unsafe
块,我只是在制作原型。但是当在缓冲区数组中设置颜色时,颜色就不正确。例如,如果我将绘制颜色设置为青色(r:0,g:255,b:255,a:255),则圆圈为白色,如果我设置洋红色,则为黄色。

rust sdl-2
1个回答
0
投票

问题是我没有检查字节序。由于我的系统使用little endian字节顺序,所以如果little -> abgr,big -> rgba。

这是纹理锁定回调:

        texture
            .with_lock(None, |buffer, pitch| {
                for x in 0..d as usize {
                    for y in 0..d as usize {
                        let circle_v = (x as f32 - r) * (x as f32 - r)
                            + (y as f32 - r) * (y as f32 - r)
                            - r * r;

                        let i = y * pitch + x * 4;

                        if circle_v <= 0.0 {
                            #[cfg(target_endian = "little")]
                            {
                                buffer[i] = color.a;
                                buffer[i + 1] = color.b;
                                buffer[i + 2] = color.g;
                                buffer[i + 3] = color.r;
                            }

                            #[cfg(target_endian = "big")]
                            {
                                buffer[i] = color.r;
                                buffer[i + 1] = color.g;
                                buffer[i + 2] = color.b;
                                buffer[i + 3] = color.a;
                            }
                        }
                    }
                }
            })
            .expect("Failed to lock texture");
© www.soinside.com 2019 - 2024. All rights reserved.