Added example for android (#368)
This commit is contained in:
parent
39e84aacbe
commit
d140eba7c9
29
Cargo.lock
generated
29
Cargo.lock
generated
|
@ -88,6 +88,24 @@ version = "0.2.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
|
||||
|
||||
[[package]]
|
||||
name = "android_log-sys"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e"
|
||||
|
||||
[[package]]
|
||||
name = "android_logger"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8619b80c242aa7bd638b5c7ddd952addeecb71f69c75e33f1d47b2804f8f883a"
|
||||
dependencies = [
|
||||
"android_log-sys",
|
||||
"env_logger",
|
||||
"log",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "android_system_properties"
|
||||
version = "0.1.5"
|
||||
|
@ -1921,6 +1939,17 @@ dependencies = [
|
|||
"winit_input_helper 0.14.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-winit-android"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"android_logger",
|
||||
"env_logger",
|
||||
"log",
|
||||
"pixels",
|
||||
"winit 0.28.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.6.2"
|
||||
|
|
27
examples/minimal-winit-android/Cargo.toml
Normal file
27
examples/minimal-winit-android/Cargo.toml
Normal file
|
@ -0,0 +1,27 @@
|
|||
[package]
|
||||
name = "minimal-winit-android"
|
||||
version = "0.1.0"
|
||||
authors = ["Randommist <andreq11s@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.19"
|
||||
pixels = { path = "../.." }
|
||||
winit = { version = "0.28.6", features = ["android-native-activity"] }
|
||||
|
||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||
env_logger = "0.10.0"
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
android_logger = "0.11.0"
|
||||
|
||||
[lib]
|
||||
crate_type = ["cdylib"]
|
||||
|
||||
|
||||
[package.metadata.android.signing.release]
|
||||
path = "./path/to/KeyStoreFile.jks"
|
||||
keystore_password = "password"
|
18
examples/minimal-winit-android/README.md
Normal file
18
examples/minimal-winit-android/README.md
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Hello Android
|
||||
|
||||
![Hello Android](../../img/minimal-winit-android.png)
|
||||
|
||||
Minimal example to run on android using `winit` with `android-native-activity` feature
|
||||
|
||||
## Running
|
||||
```
|
||||
export ANDROID_HOME="path/to/sdk"
|
||||
export ANDROID_NDK_HOME="path/to/ndk"
|
||||
|
||||
rustup target add aarch64-linux-android
|
||||
cargo install cargo-apk
|
||||
```
|
||||
Connect your Android device via USB cable to your computer in debug mode and run the following command
|
||||
```
|
||||
cargo apk run
|
||||
```
|
130
examples/minimal-winit-android/src/lib.rs
Normal file
130
examples/minimal-winit-android/src/lib.rs
Normal file
|
@ -0,0 +1,130 @@
|
|||
#[cfg(target_os = "android")]
|
||||
use winit::platform::android::activity::AndroidApp;
|
||||
|
||||
use pixels::{Pixels, SurfaceTexture};
|
||||
use winit::event::Event;
|
||||
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
|
||||
use winit::window::Window;
|
||||
|
||||
const WIDTH: u32 = 320;
|
||||
const HEIGHT: u32 = 240;
|
||||
const BOX_SIZE: i16 = 64;
|
||||
|
||||
/// Representation of the application state. In this example, a box will bounce around the screen.
|
||||
struct World {
|
||||
box_x: i16,
|
||||
box_y: i16,
|
||||
velocity_x: i16,
|
||||
velocity_y: i16,
|
||||
}
|
||||
|
||||
fn _main(event_loop: EventLoop<()>) {
|
||||
let mut window: Option<Window> = None;
|
||||
let mut pixels: Option<Pixels> = None;
|
||||
|
||||
let mut world = World::new();
|
||||
|
||||
event_loop.run(move |event, event_loop, control_flow| {
|
||||
*control_flow = ControlFlow::Wait;
|
||||
match event {
|
||||
Event::Resumed => {
|
||||
let _window = Window::new(event_loop).unwrap();
|
||||
let _pixels = {
|
||||
let window_size = _window.inner_size();
|
||||
let surface_texture =
|
||||
SurfaceTexture::new(window_size.width, window_size.height, &_window);
|
||||
Pixels::new(WIDTH, HEIGHT, surface_texture).unwrap()
|
||||
};
|
||||
_window.request_redraw();
|
||||
window = Some(_window);
|
||||
pixels = Some(_pixels);
|
||||
}
|
||||
Event::Suspended => {
|
||||
pixels = None;
|
||||
window = None;
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
if let (Some(pixels), Some(window)) = (&mut pixels, &window) {
|
||||
world.draw(pixels.frame_mut());
|
||||
pixels.render().unwrap();
|
||||
window.request_redraw();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
if window.is_some() {
|
||||
world.update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
impl World {
|
||||
/// Create a new `World` instance that can draw a moving box.
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
box_x: 24,
|
||||
box_y: 16,
|
||||
velocity_x: 1,
|
||||
velocity_y: 1,
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the `World` internal state; bounce the box around the screen.
|
||||
fn update(&mut self) {
|
||||
if self.box_x <= 0 || self.box_x + BOX_SIZE > WIDTH as i16 {
|
||||
self.velocity_x *= -1;
|
||||
}
|
||||
if self.box_y <= 0 || self.box_y + BOX_SIZE > HEIGHT as i16 {
|
||||
self.velocity_y *= -1;
|
||||
}
|
||||
|
||||
self.box_x += self.velocity_x;
|
||||
self.box_y += self.velocity_y;
|
||||
}
|
||||
|
||||
/// Draw the `World` state to the frame buffer.
|
||||
///
|
||||
/// Assumes the default texture format: `wgpu::TextureFormat::Rgba8UnormSrgb`
|
||||
fn draw(&self, frame: &mut [u8]) {
|
||||
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() {
|
||||
let x = (i % WIDTH as usize) as i16;
|
||||
let y = (i / WIDTH as usize) as i16;
|
||||
|
||||
let inside_the_box = x >= self.box_x
|
||||
&& x < self.box_x + BOX_SIZE
|
||||
&& y >= self.box_y
|
||||
&& y < self.box_y + BOX_SIZE;
|
||||
|
||||
let rgba = if inside_the_box {
|
||||
[0x5e, 0x48, 0xe8, 0xff]
|
||||
} else {
|
||||
[0x48, 0xb2, 0xe8, 0xff]
|
||||
};
|
||||
|
||||
pixel.copy_from_slice(&rgba);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[cfg(target_os = "android")]
|
||||
#[no_mangle]
|
||||
fn android_main(app: AndroidApp) {
|
||||
use winit::platform::android::EventLoopBuilderExtAndroid;
|
||||
android_logger::init_once(android_logger::Config::default().with_min_level(log::Level::Info));
|
||||
let event_loop = EventLoopBuilder::new().with_android_app(app).build();
|
||||
log::info!("Hello from android!");
|
||||
_main(event_loop);
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[cfg(not(target_os = "android"))]
|
||||
fn main() {
|
||||
env_logger::builder()
|
||||
.filter_level(log::LevelFilter::Info) // Default Log Level
|
||||
.parse_default_env()
|
||||
.init();
|
||||
let event_loop = EventLoopBuilder::new().build();
|
||||
log::info!("Hello from desktop!");
|
||||
_main(event_loop);
|
||||
}
|
BIN
img/minimal-winit-android.png
Normal file
BIN
img/minimal-winit-android.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
Loading…
Reference in a new issue