summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Michelotti <michelotti.matthew@gmail.com>2018-05-24 16:29:37 -0500
committerMatthew Michelotti <michelotti.matthew@gmail.com>2018-05-24 17:29:18 -0500
commit7091ab728345607cc028a1364ba1280df69cc58b (patch)
tree74f98444f024266f13a12819b2af186b73cf86a5
parentf905b3148397c1db1f283e1cf78f5ae5326147dd (diff)
changed how render dims are computed, changed origin to bottom-left corner
-rw-r--r--example/src/main.rs28
-rw-r--r--gate/src/app_context.rs5
-rw-r--r--gate/src/app_info.rs38
-rw-r--r--gate/src/renderer/render_buffer.rs67
-rw-r--r--gate/src/renderer/renderer.rs15
-rw-r--r--gate/src/renderer/vbo_packer.rs5
-rw-r--r--gate_build/src/asset_packer.rs4
-rw-r--r--gate_build/src/lib.rs1
8 files changed, 64 insertions, 99 deletions
diff --git a/example/src/main.rs b/example/src/main.rs
index b4e0942..c06f1ce 100644
--- a/example/src/main.rs
+++ b/example/src/main.rs
@@ -21,7 +21,7 @@ mod asset_id { include!(concat!(env!("OUT_DIR"), "/asset_id.rs")); }
use asset_id::{AssetId, SpriteId, MusicId, SoundId};
// Note: the assets that we placed in the src_assets directory can be referenced using the
-// SpriteId, TileId, MusicId, and SoundId enums
+// SpriteId, MusicId, and SoundId enums
struct HeldDisc { value: u8, pos: (f64, f64) }
@@ -40,7 +40,8 @@ fn disc_pos(pillar_index: usize, height_index: usize) -> (f64, f64) {
(-27. + pillar_index as f64 * 27., 2.5 + height_index as f64 * 5.)
}
-fn pillar_for_cursor(cursor: (f64, f64)) -> Option<usize> {
+fn pillar_for_cursor(cursor: (f64, f64), dims: (f64, f64)) -> Option<usize> {
+ let cursor = (cursor.0 - 0.5 * dims.0, cursor.1 - 0.5 * dims.1);
(0..3).find(|&idx| {
let cursor_x = cursor.0 + 13.5 - (13.5 * idx as f64);
cursor_x > -6. && cursor_x < 6. && cursor.1 > -5.5 && cursor.1 < 9.
@@ -65,7 +66,7 @@ impl App<AssetId> for TowerGame {
KeyCode::Num1 => Some(0),
KeyCode::Num2 => Some(1),
KeyCode::Num3 => Some(2),
- KeyCode::MouseLeft => pillar_for_cursor(ctx.cursor()),
+ KeyCode::MouseLeft => pillar_for_cursor(ctx.cursor(), ctx.dims()),
_ => None,
};
if let Some(index) = index {
@@ -95,25 +96,12 @@ impl App<AssetId> for TowerGame {
let mut renderer = renderer.sprite_mode();
for x in 0..((app_width / 16.).ceil() as usize) {
for y in 0..((app_height / 16.).ceil() as usize) {
- let affine = Affine::translate(
- 8. + x as f64 * 16. - 0.5 * app_width,
- 8. + y as f64 * 16. - 0.5 * app_height,
- );
+ let affine = Affine::translate(8. + x as f64 * 16., 8. + y as f64 * 16.);
let tile = if (x + y) % 2 == 0 { SpriteId::BgTileR0C0 } else { SpriteId::BgTileR0C1 };
renderer.draw(&affine, tile);
}
}
- /*{ // drawing tiles
- let mut renderer = renderer.tiled_mode(0.5 * app_width, 0.5 * app_height);
- for x in 0..((app_width / 16.).ceil() as usize) {
- for y in 0..((app_height / 16.).ceil() as usize) {
- let affine = Affine::translate(8. + x as f64 * 16., 8. + y as f64 * 16.);
- let tile = if (x + y) % 2 == 0 { TileId::BgTileR0C0 } else { TileId::BgTileR0C1 };
- renderer.draw(&affine, tile);
- }
- }
- }*/
- let base = Affine::scale(0.5).pre_translate(0., -10.);
+ let base = Affine::translate(0.5 * app_width, 0.5 * app_height - 5.).pre_scale(0.5);
renderer.draw(&base, SpriteId::Pillars);
for pillar_index in 0..self.pillars.len() {
let pillar = &self.pillars[pillar_index];
@@ -129,6 +117,8 @@ impl App<AssetId> for TowerGame {
}
fn main() {
- let info = AppInfo::with_app_height(48.).title("Tower");
+ let info = AppInfo::with_max_dims(86., 48.)
+ .min_dims(64., 44.)
+ .title("Tower");
gate::run(info, TowerGame { pillars: vec![vec![4, 3, 2, 1, 0], vec![], vec![]], held: None });
}
diff --git a/gate/src/app_context.rs b/gate/src/app_context.rs
index 40c09ce..1dfe3e1 100644
--- a/gate/src/app_context.rs
+++ b/gate/src/app_context.rs
@@ -47,10 +47,9 @@ impl<A: AppAssetId> AppContext<A> {
}
fn bound_cursor(&mut self) {
- let (half_width, half_height) = (self.dims.0 * 0.5, self.dims.1 * 0.5);
self.cursor = (
- self.cursor.0.max(-half_width).min(half_width),
- self.cursor.1.max(-half_height).min(half_height),
+ self.cursor.0.max(0.).min(self.dims.0),
+ self.cursor.1.max(0.).min(self.dims.1),
);
}
diff --git a/gate/src/app_info.rs b/gate/src/app_info.rs
index 8f3dac6..e1c48bc 100644
--- a/gate/src/app_info.rs
+++ b/gate/src/app_info.rs
@@ -25,39 +25,33 @@
/// ```rust
/// use gate::AppInfo;
///
-/// let info = AppInfo::with_app_height(100.)
+/// let info = AppInfo::with_max_dims(160., 90.)
+/// .min_dims(120., 86.)
/// .title("My Game")
/// .target_fps(30.)
/// .print_workload_info()
/// .print_gl_info();
/// ```
pub struct AppInfo {
- pub(crate) app_height: f64,
pub(crate) window_pixels: (u32, u32),
- pub(crate) min_aspect_ratio: f64,
- pub(crate) max_aspect_ratio: f64,
+ pub(crate) min_dims: (f64, f64),
+ pub(crate) max_dims: (f64, f64),
pub(crate) title: &'static str,
pub(crate) target_fps: f64,
pub(crate) print_workload_info: bool,
pub(crate) print_gl_info: bool,
}
-impl AppInfo {
- /// Returns a new AppInfo, initialized with the required value `app_height`.
- ///
- /// The `app_height` is the height of the screen in conceptual "app pixels",
- /// which defines the units used by the renderers.
- /// Even if the window is resized and the aspect ratio changed,
- /// the app height will always remain the same.
- /// The choice of this is important for the `TiledRenderer` in particular.
- pub fn with_app_height(app_height: f64) -> AppInfo {
- assert!(app_height >= 1e-30 && app_height <= 3000., "unrealistic app height {}", app_height);
+// FIXME update rustdoc comments relating to app dims...
+impl AppInfo {
+ pub fn with_max_dims(max_width: f64, max_height: f64) -> AppInfo {
+ assert!(max_width >= 1e-30 && max_width <= 3000., "unrealistic max_width: {}", max_width);
+ assert!(max_height >= 1e-30 && max_height <= 3000., "unrealistic max_height: {}", max_height);
AppInfo {
- app_height,
window_pixels: (800, 600),
- min_aspect_ratio: 4. / 3.,
- max_aspect_ratio: 16. / 9.,
+ min_dims: (0., 0.),
+ max_dims: (max_width, max_height),
title: "untitled app",
target_fps: 60.,
print_workload_info: false,
@@ -65,13 +59,9 @@ impl AppInfo {
}
}
- /// Specifies the minimum and maximum aspect ratio for the game, enforced by
- /// letterboxing/pillarboxing if necessary (default is `4/3` to `16/9`).
- pub fn aspect_ratio_range(mut self, min_ratio: f64, max_ratio: f64) -> Self {
- assert!(0.2 < min_ratio && min_ratio < max_ratio && max_ratio < 5.0, "invalid aspect ratios");
- // TODO ensure there is a large enough gap between min_ratio and max_ratio, so that pixel rounding isn't an issue
- self.min_aspect_ratio = min_ratio;
- self.max_aspect_ratio = max_ratio;
+ pub fn min_dims(mut self, min_width: f64, min_height: f64) -> Self {
+ assert!(self.min_dims.0 <= self.max_dims.0 && self.min_dims.1 <= self.max_dims.1);
+ self.min_dims = (min_width, min_height);
self
}
diff --git a/gate/src/renderer/render_buffer.rs b/gate/src/renderer/render_buffer.rs
index 2b4e042..916863a 100644
--- a/gate/src/renderer/render_buffer.rs
+++ b/gate/src/renderer/render_buffer.rs
@@ -23,58 +23,43 @@ use super::geom::Affine;
pub(super) enum Mode { Sprite }
pub(super) struct RenderDims {
- pub min_aspect_ratio: f64,
- pub max_aspect_ratio: f64,
- pub app_dims: (f64, f64),
- pub full_screen_dims: (u32, u32),
- pub tiled_fbo_dims: (u32, u32),
- pub used_screen_dims: (u32, u32),
- pub app_pixel_scalar: f64,
+ pub min_dims: (f64, f64),
+ pub max_dims: (f64, f64),
+ pub native_dims: (u32, u32),
+ pub pixel_scalar: f64,
+ pub native_pre_pad: (u32, u32),
+ pub used_native_dims: (u32, u32),
+ pub dims: (f64, f64),
}
impl RenderDims {
- fn new(min_aspect_ratio: f64, max_aspect_ratio: f64, app_height: f64, full_screen_dims: (u32, u32)) -> RenderDims {
- let ratio = full_screen_dims.0 as f64 / full_screen_dims.1 as f64;
- let used_screen_dims = if ratio < min_aspect_ratio {
- let mut h = (full_screen_dims.0 as f64 / min_aspect_ratio).floor() as u32;
- if (full_screen_dims.1 - h) % 2 != 0 { h -= 1; }
- (full_screen_dims.0, h)
- } else if ratio > max_aspect_ratio {
- let mut w = (full_screen_dims.1 as f64 * max_aspect_ratio).floor() as u32;
- if (full_screen_dims.0 - w) % 2 != 0 { w -= 1; }
- (w, full_screen_dims.1)
- } else {
- full_screen_dims
- };
- let ratio = used_screen_dims.0 as f64 / used_screen_dims.1 as f64;
- let app_dims = (app_height * ratio, app_height);
- let app_pixel_scalar = if used_screen_dims.1 == full_screen_dims.1 {
- full_screen_dims.1 as f64 / app_dims.1
- } else {
- full_screen_dims.0 as f64 / app_dims.0
- };
- RenderDims {
- min_aspect_ratio, max_aspect_ratio, app_dims, full_screen_dims, used_screen_dims, app_pixel_scalar,
- tiled_fbo_dims: (to_fbo_dim(app_height * max_aspect_ratio), to_fbo_dim(app_height)),
- }
+ fn new(min_dims: (f64, f64), max_dims: (f64, f64), native_dims: (u32, u32)) -> RenderDims {
+ let scalar_from_min = (native_dims.0 as f64 / min_dims.0).min(native_dims.1 as f64 / min_dims.1);
+ let scalar_from_max = (native_dims.0 as f64 / max_dims.0).max(native_dims.1 as f64 / max_dims.1);
+ let pixel_scalar = scalar_from_min.min(scalar_from_max).max(1.0);
+ let used_native_dims = (
+ native_dims.0.min((max_dims.0 * pixel_scalar).floor() as u32),
+ native_dims.1.min((max_dims.1 * pixel_scalar).floor() as u32),
+ );
+ let native_pad = (native_dims.0 - used_native_dims.0, native_dims.1 - used_native_dims.1);
+ let native_pre_pad = (native_pad.0 / 2, native_pad.1 / 2);
+ let dims = (used_native_dims.0 as f64 / pixel_scalar, used_native_dims.1 as f64 / pixel_scalar);
+ RenderDims { min_dims, max_dims, native_dims, pixel_scalar, native_pre_pad, used_native_dims, dims }
}
- pub fn set_full_screen_dims(&mut self, screen_dims: (u32, u32)) {
- *self = RenderDims::new(self.min_aspect_ratio, self.max_aspect_ratio, self.app_dims.1, screen_dims);
+ pub fn set_native_dims(&mut self, native_dims: (u32, u32)) {
+ *self = RenderDims::new(self.min_dims, self.max_dims, native_dims);
}
pub fn to_app_pos(&self, raw_x: i32, raw_y: i32) -> (f64, f64) {
+ let raw_y = self.native_dims.1 as i32 - raw_y;
(
- (raw_x as f64 - 0.5 * self.full_screen_dims.0 as f64) / self.app_pixel_scalar,
- -(raw_y as f64 - 0.5 * self.full_screen_dims.1 as f64) / self.app_pixel_scalar,
+ (raw_x - self.native_pre_pad.0 as i32) as f64 / self.pixel_scalar,
+ (raw_y - self.native_pre_pad.1 as i32) as f64 / self.pixel_scalar,
)
}
}
-fn to_fbo_dim(app_dim: f64) -> u32 {
- (app_dim - 1e-7).ceil() as u32 + 1
-}
-
pub struct RenderBuffer {
pub(super) sprite_atlas: Atlas,
pub(super) mode: Mode,
@@ -83,12 +68,12 @@ pub struct RenderBuffer {
}
impl RenderBuffer {
- pub fn new(info: &AppInfo, screen_dims: (u32, u32), sprite_atlas: Atlas) -> RenderBuffer {
+ pub fn new(info: &AppInfo, native_dims: (u32, u32), sprite_atlas: Atlas) -> RenderBuffer {
RenderBuffer {
sprite_atlas,
mode: Mode::Sprite,
vbo_data: Vec::new(),
- dims: RenderDims::new(info.min_aspect_ratio, info.max_aspect_ratio, info.app_height, screen_dims),
+ dims: RenderDims::new(info.min_dims, info.max_dims, native_dims),
}
}
diff --git a/gate/src/renderer/renderer.rs b/gate/src/renderer/renderer.rs
index 4e58f51..e2ff84f 100644
--- a/gate/src/renderer/renderer.rs
+++ b/gate/src/renderer/renderer.rs
@@ -55,7 +55,7 @@ impl<A: AppAssetId> Renderer<A> {
SpriteRenderer { r: self }
}
- pub(crate) fn app_dims(&self) -> (f64, f64) { self.b.dims.app_dims }
+ pub(crate) fn app_dims(&self) -> (f64, f64) { self.b.dims.dims }
pub(crate) fn to_app_pos(&self, raw_x: i32, raw_y: i32) -> (f64, f64) {
self.b.dims.to_app_pos(raw_x, raw_y)
@@ -66,18 +66,19 @@ impl<A: AppAssetId> Renderer<A> {
}
pub(crate) fn set_screen_dims(&mut self, dims: (u32, u32)) {
- if dims != self.b.dims.full_screen_dims {
- self.b.dims.set_full_screen_dims(dims);
+ if dims != self.b.dims.native_dims {
+ self.b.dims.set_native_dims(dims);
self.set_scissor();
}
}
fn set_scissor(&mut self) {
+ let dims = &self.b.dims;
self.c.set_scissor(
- (self.b.dims.full_screen_dims.0 - self.b.dims.used_screen_dims.0) / 2,
- (self.b.dims.full_screen_dims.1 - self.b.dims.used_screen_dims.1) / 2,
- self.b.dims.used_screen_dims.0,
- self.b.dims.used_screen_dims.1,
+ dims.native_pre_pad.0,
+ dims.native_pre_pad.1,
+ dims.used_native_dims.0,
+ dims.used_native_dims.1,
);
}
}
diff --git a/gate/src/renderer/vbo_packer.rs b/gate/src/renderer/vbo_packer.rs
index 1ef7e68..d052abe 100644
--- a/gate/src/renderer/vbo_packer.rs
+++ b/gate/src/renderer/vbo_packer.rs
@@ -19,7 +19,7 @@ pub fn append_sprite(r: &mut RenderBuffer, affine: &Affine, sprite_id: u16, flas
assert!(r.mode == Mode::Sprite);
let img_coords = r.sprite_atlas.images[&sprite_id];
- let affine = affine.post_scale(r.dims.app_pixel_scalar);
+ let affine = affine.post_scale(r.dims.pixel_scalar);
let flash_ratio = (flash_ratio as f32).max(0.0).min(1.0);
let pad = (
@@ -37,7 +37,8 @@ pub fn append_sprite(r: &mut RenderBuffer, affine: &Affine, sprite_id: u16, flas
let dst_lb = (dst_lt.0, dst_rb.1);
let dst_rt = (dst_rb.0, dst_lt.1);
- let affine = affine.post_scale_axes(2.0 / r.dims.full_screen_dims.0 as f64, 2.0 / r.dims.full_screen_dims.1 as f64);
+ let affine = affine.post_translate(-0.5 * r.dims.used_native_dims.0 as f64, -0.5 * r.dims.used_native_dims.1 as f64)
+ .post_scale_axes(2.0 / r.dims.native_dims.0 as f64, 2.0 / r.dims.native_dims.1 as f64);
let aff_lt = affine.apply_f32(dst_lt);
let aff_rb = affine.apply_f32(dst_rb);
let aff_lb = affine.apply_f32(dst_lb);
diff --git a/gate_build/src/asset_packer.rs b/gate_build/src/asset_packer.rs
index f604fb0..679f42c 100644
--- a/gate_build/src/asset_packer.rs
+++ b/gate_build/src/asset_packer.rs
@@ -152,14 +152,14 @@ impl AssetPacker {
/// Generates Rust enums to use as handles for all of the packed assets.
///
/// The generated code will consist of four enums:
- /// `SpriteId`, `TileId`, `MusicId`, and `SoundId`.
+ /// `SpriteId`, `MusicId`, and `SoundId`.
/// These types are collected together in the type `AssetId`,
/// which implements `gate::asset_id::AppAssetId`.
/// Constructing a `gate::App` instance with this as the Asset ID type
/// will allow you to use the generated handles to refer to assets.
///
/// This method should be called after packing all of the assets.
- /// The `sprites` and `tiles` methods must be called before this,
+ /// The `sprites` method must be called before this,
/// but `music` and `sounds` may be omitted if there is no audio.
///
/// The generated Rust code is written to `out`.
diff --git a/gate_build/src/lib.rs b/gate_build/src/lib.rs
index 87f0931..d324db6 100644
--- a/gate_build/src/lib.rs
+++ b/gate_build/src/lib.rs
@@ -38,7 +38,6 @@
//! let mut packer = AssetPacker::new(Path::new("assets"));
//! packer.cargo_rerun_if_changed();
//! packer.sprites(Path::new("sprites"));
-//! packer.tiles(Path::new("tiles"));
//! packer.music(Path::new("music"));
//! packer.sounds(Path::new("sounds"));
//! packer.gen_asset_id_code(&gen_code_path);