Browse Source

remove the logging system, nearly fix skeletal animation? optimize some code

master
Alison Watson 7 months ago
parent
commit
10372d9cd5
23 changed files with 342 additions and 557 deletions
  1. +1
    -0
      .gitignore
  2. +25
    -17
      Cargo.lock
  3. +4
    -5
      Cargo.toml
  4. +5
    -5
      glsl/main.frag
  5. +29
    -25
      glsl/main.vert
  6. +0
    -25
      source/build.rs
  7. +0
    -1
      source/framework/conf.rs
  8. +17
    -14
      source/framework/data/bit.rs
  9. +198
    -139
      source/framework/data/model.rs
  10. +12
    -0
      source/framework/data/read.rs
  11. +1
    -0
      source/framework/data/vertex.rs
  12. +10
    -10
      source/framework/defl.rs
  13. +0
    -2
      source/framework/lib.rs
  14. +0
    -137
      source/framework/log.rs
  15. +0
    -50
      source/framework/log/color.rs
  16. +0
    -14
      source/framework/log/conf.rs
  17. +0
    -48
      source/framework/log/level.rs
  18. +0
    -27
      source/framework/log/standard.rs
  19. +7
    -1
      source/framework/render/misc.rs
  20. +5
    -1
      source/framework/render/model.rs
  21. +12
    -22
      source/main_test/entry.rs
  22. +8
    -14
      source/main_test/main.rs
  23. +8
    -0
      tools/shader

+ 1
- 0
.gitignore View File

@@ -5,3 +5,4 @@
/out
/target
perf.data*
glsl/*.o

+ 25
- 17
Cargo.lock View File

@@ -11,9 +11,9 @@ dependencies = [

[[package]]
name = "ash"
version = "0.31.0"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c69a8137596e84c22d57f3da1b5de1d4230b1742a710091c85f4d7ce50f00f38"
checksum = "77ea56be8250318e64923c7e65b82a35b5c29dfb6dc1c7d1c0b288c4b1bbb084"
dependencies = [
"libloading",
]
@@ -25,6 +25,7 @@ dependencies = [
"ash",
"blonkus_ma",
"glam",
"intaglio",
"llvm-sys",
"memchr",
"sdl2-sys",
@@ -66,12 +67,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "glam"
version = "0.11.2"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef81f244b2a421ddb8ccb382857772379c0996fe5948992db5bee51cef3c28e"
dependencies = [
"version_check",
]
checksum = "27e6eecbd94ac86b2e1f3b0065ed5f17c097c15d668dddb84208a141e271403b"

[[package]]
name = "intaglio"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "967a032d0341206335b103da5445b3816370c644af65ca3ca1af9999dca7ea0f"

[[package]]
name = "lazy_static"
@@ -87,9 +91,9 @@ checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"

[[package]]
name = "libloading"
version = "0.6.6"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e9367bdfa836b7e3cf895867f7a570283444da90562980ec2263d6e1569b16bc"
checksum = "6f84d96438c15fcd6c3f244c8fce01d1e2b9c6b5623e9c711dc9286d8fc92d6a"
dependencies = [
"cfg-if 1.0.0",
"winapi",
@@ -224,6 +228,12 @@ version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ca0f7ce3a29234210f0f4f0b56f8be2e722488b95cb522077943212da3b32eb"

[[package]]
name = "static_assertions"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"

[[package]]
name = "syn"
version = "1.0.54"
@@ -284,9 +294,13 @@ dependencies = [

[[package]]
name = "twox-hash"
version = "1.5.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bfd5b7557925ce778ff9b9ef90e3ade34c524b5ff10e239c69a42d546d2af56"
checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
dependencies = [
"cfg-if 0.1.10",
"static_assertions",
]

[[package]]
name = "ucd-trie"
@@ -306,12 +320,6 @@ version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"

[[package]]
name = "version_check"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"

[[package]]
name = "winapi"
version = "0.3.9"


+ 4
- 5
Cargo.toml View File

@@ -11,17 +11,16 @@ edition = "2018"
publish = false
keywords = ["gamedev", "engine"]
categories = ["game-development"]
build = "source/build.rs"

[features]
default = ["color-log"]
color-log = ["termcolor"]

[dependencies]
ash = "~0.31"
ash = "~0.32"
blonkus_ma = { path = "source/macros" }
glam = "~0.11"
intaglio = "~1.1"
glam = "~0.13"
intaglio = "~1.2"
llvm-sys = "~110"
memchr = "~2.3"
sdl2-sys = "~0.34"
@@ -31,7 +30,7 @@ smol_str = "~0.1"
termcolor = { version = "~1.1", optional = true }
thiserror = "~1.0"
toml = "~0.5"
twox-hash = { version = "~1.5", default-features = false }
twox-hash = { version = "~1.6", default-features = false }

[profile.dev]
opt-level = 1


+ 5
- 5
glsl/main.frag View File

@@ -1,13 +1,13 @@
layout(location = 0) in vec3 vertex_texcoord;
layout(location = 1) in vec4 vertex_color;
layout(location = 0) in vec3 in_tex_coord;
layout(location = 1) in vec4 in_color;

layout(location = 0) out vec4 frag_color;
layout(location = 0) out vec4 out_color;

layout(binding = 2) uniform sampler2D u_sampler;

void main() {
frag_color = texture(u_sampler, vertex_texcoord.xy);
frag_color *= vertex_color;
out_color = texture(u_sampler, in_tex_coord.xy);
out_color *= in_color;
}

// EOF

+ 29
- 25
glsl/main.vert View File

@@ -1,44 +1,48 @@
layout(location = 0) in vec3 in_position;
layout(location = 1) in vec3 in_texcoord;
layout(location = 1) in vec3 in_tex_coord;
layout(location = 2) in vec3 in_normal;
layout(location = 3) in vec4 in_blendindices;
layout(location = 4) in vec4 in_blendweights;
layout(location = 5) in vec4 in_color;
layout(location = 3) in vec3 in_tangent;
layout(location = 4) in vec4 in_bl_indices;
layout(location = 5) in vec4 in_bl_weights;
layout(location = 6) in vec4 in_color;

layout(location = 0) out vec3 vertex_texcoord;
layout(location = 1) out vec4 vertex_color;
layout(location = 0) out vec3 out_tex_coord;
layout(location = 1) out vec4 out_color;

layout(binding = 0) uniform Uniforms {
mat4 object;
mat4 camera;
mat4 projec;
} uniforms;
} u_matrices;

layout(binding = 1) uniform BoneMatrices {
mat4 matrices[128];
} bones;
} u_bones;

void main() {
/*
mat4 vertex_matrix =
bones.matrices[int(in_blendindices.x)] * in_blendweights.x +
bones.matrices[int(in_blendindices.y)] * in_blendweights.y +
bones.matrices[int(in_blendindices.z)] * in_blendweights.z +
bones.matrices[int(in_blendindices.w)] * in_blendweights.w;
*/

vec4 position =
//vertex_matrix *
vec4(in_position, 1.0);
mat4 pos_mat =
u_bones.matrices[int(in_bl_indices.x)] * in_bl_weights.x +
u_bones.matrices[int(in_bl_indices.y)] * in_bl_weights.y +
u_bones.matrices[int(in_bl_indices.z)] * in_bl_weights.z +
u_bones.matrices[int(in_bl_indices.w)] * in_bl_weights.w;

mat3 adj_mat =
mat3(cross(pos_mat[1].xyz, pos_mat[2].xyz),
cross(pos_mat[2].xyz, pos_mat[0].xyz),
cross(pos_mat[0].xyz, pos_mat[1].xyz));

vec3 pos = vec3(pos_mat * vec4(in_position, 1.0));
vec3 nrm = adj_mat * in_normal;
vec3 tng = adj_mat * in_tangent;

gl_Position =
uniforms.projec *
uniforms.camera *
uniforms.object *
position;
u_matrices.projec *
u_matrices.camera *
u_matrices.object *
vec4(pos, 1.0);

vertex_texcoord = in_texcoord;
vertex_color = in_color;
out_tex_coord = in_tex_coord;
out_color = in_color;
}

// EOF

+ 0
- 25
source/build.rs View File

@@ -1,25 +0,0 @@
fn main() {
let out_dir = std::env::var("OUT_DIR").unwrap();

for file in std::fs::read_dir("glsl").unwrap() {
let file = file.unwrap();
let path = file.path();
let file_name = path.file_name().unwrap();
let out = format!("{}/{}.o", out_dir, file_name.to_str().unwrap());
let path = path.to_str().unwrap();
println!("rerun-if-changed={}", path);
std::process::Command::new("glslc")
.arg("-O")
.arg("-o")
.arg(&out)
.arg("-std=450core")
.arg("--target-env=vulkan1.0")
.arg("-Werror")
.arg("-xglsl")
.arg(&path)
.status()
.unwrap();
}
}

// EOF

+ 0
- 1
source/framework/conf.rs View File

@@ -1,7 +1,6 @@
#[blonkus_ma::serialize_config]
#[derive(Default)]
pub struct Conf {
pub log: crate::log::Conf,
pub render: crate::render::Conf,
}



+ 17
- 14
source/framework/data/bit.rs View File

@@ -8,7 +8,7 @@ pub trait ReadBits {
///
/// This function will return `None` if there are not enough bits left
/// in the buffer.
fn read_bits_be(b: &[u8], cr_bit: usize, width: u8) -> Option<Self>
fn read_bits_be(b: &[u8], cr_bit: usize, width: usize) -> Option<Self>
where
Self: Sized;

@@ -18,7 +18,7 @@ pub trait ReadBits {
///
/// This function will return `None` if there are not enough bits left
/// in the buffer.
fn read_bits_le(b: &[u8], cr_bit: usize, width: u8) -> Option<Self>
fn read_bits_le(b: &[u8], cr_bit: usize, width: usize) -> Option<Self>
where
Self: Sized;
}
@@ -27,12 +27,12 @@ macro_rules! read_bits_impl {
($t:ty) => {
#[allow(clippy::use_self)]
impl ReadBits for $t {
fn read_bits_be(b: &[u8], cr_bit: usize, width: u8) -> Option<Self> {
fn read_bits_be(b: &[u8], cr_bit: usize, mut width: usize) -> Option<Self> {
if width == 0 {
return Some(0);
}

let last = (cr_bit + width as usize - 1) / 8;
let last = (cr_bit + width - 1) / 8;

if last >= b.len() {
return None;
@@ -43,10 +43,11 @@ macro_rules! read_bits_impl {

let mut res = 0;

for _ in 0..width {
res <<= 1_u8;
while width > 0 {
width -= 1;
res <<= 1;

if b[byte_ptr] & (1 << bits_ptr) != 0 {
if b[byte_ptr] & 1 << bits_ptr != 0 {
res |= 1;
}

@@ -61,12 +62,12 @@ macro_rules! read_bits_impl {
Some(res)
}

fn read_bits_le(b: &[u8], cr_bit: usize, width: u8) -> Option<Self> {
fn read_bits_le(b: &[u8], cr_bit: usize, mut width: usize) -> Option<Self> {
if width == 0 {
return Some(0);
}

let last = (cr_bit + width as usize - 1) / 8;
let last = (cr_bit + width - 1) / 8;

if last >= b.len() {
return None;
@@ -76,14 +77,16 @@ macro_rules! read_bits_impl {
let mut bits_ptr = cr_bit % 8;

let mut res = 0;
let mut bit = 1;

for i in 0..width {
if b[byte_ptr] & (1 << bits_ptr) != 0 {
let mut n = 1;
n <<= i;
res |= n;
while width > 0 {
width -= 1;
if b[byte_ptr] & 1 << bits_ptr != 0 {
res |= bit;
}

bit <<= 1;
bits_ptr += 1;

if bits_ptr > 7 {


+ 198
- 139
source/framework/data/model.rs View File

@@ -6,7 +6,6 @@ use glam::{Mat4, Quat, Vec3, Vec3A, Vec4};
use smol_str::SmolStr;
use std::{
collections::HashMap,
convert::TryInto,
io::{self, Read, Seek, SeekFrom},
ops::Range,
str::Utf8Error,
@@ -22,10 +21,16 @@ pub enum Err {
NumPoses,
#[error("Bad text offset")]
TextOffset,
#[error("Unknown vertex array type")]
UnknownType,
#[error(transparent)]
Utf8(#[from] Utf8Error),
#[error("Bad parent joint")]
Parent,
#[error("Bad frame count")]
FrameCount,
#[error("Unknown vertex array type")]
VaType,
#[error("Unsupported vertex array format")]
VaFormat,
}

struct VertexZipper {
@@ -33,6 +38,7 @@ struct VertexZipper {
pos_v: std::vec::IntoIter<Vec3A>,
tex_v: std::vec::IntoIter<Vec3A>,
nrm_v: std::vec::IntoIter<Vec3A>,
tan_v: std::vec::IntoIter<Vec4>,
idx_v: std::vec::IntoIter<Vec4>,
wgt_v: std::vec::IntoIter<Vec4>,
clr_v: std::vec::IntoIter<Vec4>,
@@ -45,16 +51,9 @@ pub struct Mesh {
}

pub struct Joint {
//nam: SmolStr,
par: Option<usize>,
nam: SmolStr,
mat: Mat4,
}

pub struct Pose {
par: Option<usize>,
msk: u32,
ofs: [f32; 10],
scl: [f32; 10],
inv: Mat4,
}

/// Data to be uploaded to the GPU. Separate from Model so that it may
@@ -68,10 +67,8 @@ pub struct ModelData {
/// the GPU.
pub struct Model {
meshes: HashMap<SmolStr, Mesh>,
num_frmc: usize,
frames: Vec<u16>,
joints: Vec<Joint>,
poses: Vec<Pose>,
frames: Vec<Vec<Mat4>>,
num_frms: usize,
}

impl Iterator for VertexZipper {
@@ -82,6 +79,7 @@ impl Iterator for VertexZipper {
Option<Vec4>,
Option<Vec4>,
Option<Vec4>,
Option<Vec4>,
);

fn next(&mut self) -> Option<Self::Item> {
@@ -89,16 +87,74 @@ impl Iterator for VertexZipper {
self.pos_v.next(),
self.tex_v.next(),
self.nrm_v.next(),
self.tan_v.next(),
self.idx_v.next(),
self.wgt_v.next(),
self.clr_v.next(),
) {
| (None, None, None, None, None, None) => None,
| (None, None, None, None, None, None, None) => None,
| tuple => Some(tuple),
}
}
}

const FMT_I8: u32 = 0;
const FMT_U8: u32 = 1;
const FMT_I16: u32 = 2;
const FMT_U16: u32 = 3;
const FMT_I32: u32 = 4;
const FMT_U32: u32 = 5;
const FMT_F32: u32 = 7;
const FMT_F64: u32 = 8;

fn fmt_check(fm: u32) -> Result<(), Err> {
match fm {
FMT_I8 | FMT_U8 |
FMT_I16 | FMT_U16 |
FMT_I32 | FMT_U32 | FMT_F32 |
FMT_F64 => Ok(()),
_ => Err(Err::VaFormat),
}
}

fn fmt_size(fm: u32) -> usize {
match fm {
FMT_I8 | FMT_U8 => 1,
FMT_I16 | FMT_U16 => 2,
FMT_I32 | FMT_U32 | FMT_F32 => 4,
FMT_F64 => 8,
_ => unsafe { std::hint::unreachable_unchecked() },
}
}

fn fmt_read_abs(fm: u32, vec: &[u8], pos: usize) -> f32 {
match fm {
FMT_I8 => f32::from(vec[pos] as i8),
FMT_U8 => f32::from(vec[pos]),
FMT_I16 => f32::from(read::i16le_16(vec, pos)),
FMT_U16 => f32::from(read::u16le_16(vec, pos)),
FMT_I32 => read::i32le_32(vec, pos) as f32,
FMT_U32 => read::u32le_32(vec, pos) as f32,
FMT_F32 => read::f32le_32(vec, pos),
FMT_F64 => read::f64le_64(vec, pos) as f32,
_ => unsafe { std::hint::unreachable_unchecked() },
}
}

fn fmt_read_nrm(fm: u32, vec: &[u8], pos: usize) -> f32 {
match fm {
FMT_I8 => f32::abs(f32::from(vec[pos] as i8) / 128.0),
FMT_U8 => f32::from(vec[pos]) / 255.0,
FMT_I16 => f32::abs(f32::from(read::i16le_16(vec, pos)) / 32768.0),
FMT_U16 => f32::from(read::u16le_16(vec, pos)) / 65535.0,
FMT_I32 => (read::i32le_32(vec, pos) as f64 / 2147483648.0) as f32,
FMT_U32 => (read::u32le_32(vec, pos) as f64 / 4294967295.0) as f32,
FMT_F32 => f32::clamp(read::f32le_32(vec, pos), 0.0, 1.0),
FMT_F64 => f32::clamp(read::f64le_64(vec, pos) as f32, 0.0, 1.0),
_ => unsafe { std::hint::unreachable_unchecked() },
}
}

impl Mesh {
pub fn get_mat(&self) -> &str {
&self.mat
@@ -159,12 +215,12 @@ impl Model {
let ofs_join = read::u32le_64(&head, 72);
let num_pose = read::u32le_sz(&head, 76);
let ofs_pose = read::u32le_64(&head, 80);
//let num_anim = read::u32le_sz(&head, 84);
//let ofs_anim = read::u32le_64(&head, 88);
let num_anim = read::u32le_sz(&head, 84);
let ofs_anim = read::u32le_64(&head, 88);
let num_frms = read::u32le_sz(&head, 92);
let num_frmc = read::u32le_sz(&head, 96);
let ofs_frms = read::u32le_64(&head, 100);
//let ofs_bnds = read::u32le_64(&head, 104);
let ofs_bnds = read::u32le_64(&head, 104);

if num_join != 0 && num_pose != 0 && num_pose != num_join {
return Err(Err::NumPoses);
@@ -174,6 +230,7 @@ impl Model {
let mut pos_v = Vec::with_capacity(num_vert);
let mut tex_v = Vec::with_capacity(num_vert);
let mut nrm_v = Vec::with_capacity(num_vert);
let mut tan_v = Vec::with_capacity(num_vert);
let mut idx_v = Vec::with_capacity(num_vert);
let mut wgt_v = Vec::with_capacity(num_vert);
let mut clr_v = Vec::with_capacity(num_vert);
@@ -182,65 +239,72 @@ impl Model {

for array_def in read::hunk(rd, num_vinf * 20)?.chunks(20) {
let ty = read::u32le_32(array_def, 0);
let fl = read::u32le_32(array_def, 4);
let fm = read::u32le_32(array_def, 8);
let sz = read::u32le_32(array_def, 12);
let of = read::u32le_64(array_def, 16);

fmt_check(fm)?;

rd.seek(SeekFrom::Start(of))?;

match ty {
| 0 => {
for pos in read::hunk(rd, 4 * 3 * num_vert)?.chunks(4 * 3) {
let x = read::f32le_32(pos, 0);
let y = read::f32le_32(pos, 4);
let z = read::f32le_32(pos, 8);
pos_v.push(Vec3A::new(x, y, z));
}
}
| 1 => {
for tex in read::hunk(rd, 4 * 2 * num_vert)?.chunks(4 * 2) {
let u = read::f32le_32(tex, 0);
let v = read::f32le_32(tex, 4);
tex_v.push(Vec3A::new(u, v, 0.0));
}
}
| 2 => {
for nrm in read::hunk(rd, 4 * 3 * num_vert)?.chunks(4 * 3) {
let x = read::f32le_32(nrm, 0);
let y = read::f32le_32(nrm, 4);
let z = read::f32le_32(nrm, 8);
nrm_v.push(Vec3A::new(x, y, z));
}
}
| 3 => {
// ignore tangents for now
}
| 4 => {
for idx in read::hunk(rd, 4 * num_vert)?.chunks(4) {
let idx0 = f32::from(idx[0]);
let idx1 = f32::from(idx[1]);
let idx2 = f32::from(idx[2]);
let idx3 = f32::from(idx[3]);
idx_v.push(Vec4::new(idx0, idx1, idx2, idx3));
let obj_size = fmt_size(fm);
let obj_amnt = sz as usize;
let obj_blks = obj_size * obj_amnt;

let hunk = read::hunk(rd, obj_blks * num_vert)?;

let v2 = |v: &mut Vec<Vec3A>, rd: fn(u32, &[u8], usize) -> f32| {
if obj_amnt != 2 {
Err(Err::VaFormat)
} else {
for vec in hunk.chunks(obj_blks) {
let x = rd(fm, vec, obj_size * 0);
let y = rd(fm, vec, obj_size * 1);
v.push(Vec3A::new(x, y, 0.0));
}
Ok(())
}
| 5 => {
for wgt in read::hunk(rd, 4 * num_vert)?.chunks(4) {
let wgt0 = f32::from(wgt[0]) / 255.0;
let wgt1 = f32::from(wgt[1]) / 255.0;
let wgt2 = f32::from(wgt[2]) / 255.0;
let wgt3 = f32::from(wgt[3]) / 255.0;
wgt_v.push(Vec4::new(wgt0, wgt1, wgt2, wgt3));
};

let v3 = |v: &mut Vec<Vec3A>, rd: fn(u32, &[u8], usize) -> f32| {
if obj_amnt != 3 {
Err(Err::VaFormat)
} else {
for vec in hunk.chunks(obj_blks) {
let x = rd(fm, vec, obj_size * 0);
let y = rd(fm, vec, obj_size * 1);
let z = rd(fm, vec, obj_size * 2);
v.push(Vec3A::new(x, y, z));
}
Ok(())
}
| 6 => {
for clr in read::hunk(rd, 4 * num_vert)?.chunks(4) {
let r = f32::from(clr[0]) / 255.0;
let g = f32::from(clr[1]) / 255.0;
let b = f32::from(clr[2]) / 255.0;
let a = f32::from(clr[3]) / 255.0;
clr_v.push(Vec4::new(r, g, b, a));
};

let v4 = |v: &mut Vec<Vec4>, rd: fn(u32, &[u8], usize) -> f32| {
if obj_amnt != 4 {
Err(Err::VaFormat)
} else {
for vec in hunk.chunks(obj_blks) {
let x = rd(fm, vec, obj_size * 0);
let y = rd(fm, vec, obj_size * 1);
let z = rd(fm, vec, obj_size * 2);
let w = rd(fm, vec, obj_size * 3);
v.push(Vec4::new(x, y, z, w));
}
Ok(())
}
| _ => return Err(Err::UnknownType),
};

match ty {
| 0 => v3(&mut pos_v, fmt_read_abs)?,
| 1 => v2(&mut tex_v, fmt_read_abs)?,
| 2 => v3(&mut nrm_v, fmt_read_abs)?,
| 3 => v4(&mut tan_v, fmt_read_abs)?,
| 4 => v4(&mut idx_v, fmt_read_abs)?,
| 5 => v4(&mut wgt_v, fmt_read_nrm)?,
| 6 => v4(&mut clr_v, fmt_read_nrm)?,
| _ => return Err(Err::VaType),
}
}

@@ -249,6 +313,7 @@ impl Model {
pos_v: pos_v.into_iter(),
tex_v: tex_v.into_iter(),
nrm_v: nrm_v.into_iter(),
tan_v: tan_v.into_iter(),
idx_v: idx_v.into_iter(),
wgt_v: wgt_v.into_iter(),
clr_v: clr_v.into_iter(),
@@ -256,14 +321,15 @@ impl Model {

let mut vert_dat = Vec::with_capacity(num_vert);

for (pos, tex, nrm, idx, wgt, clr) in zipper {
let pos = pos.unwrap_or_else(|| Vec3A::new(0.0, 0.0, 0.0));
let tex = tex.unwrap_or_else(|| Vec3A::new(0.0, 0.0, 0.0));
let nrm = nrm.unwrap_or_else(|| Vec3A::new(0.0, 0.0, 0.0));
let idx = idx.unwrap_or_else(|| Vec4::new(0.0, 0.0, 0.0, 0.0));
let wgt = wgt.unwrap_or_else(|| Vec4::new(0.0, 0.0, 0.0, 0.0));
let clr = clr.unwrap_or_else(|| Vec4::new(1.0, 1.0, 1.0, 1.0));
vert_dat.push(Vertex { pos, tex, nrm, idx, wgt, clr });
for (pos, tex, nrm, tan, idx, wgt, clr) in zipper {
let pos = pos.unwrap_or_else(|| Vec3A::ZERO);
let tex = tex.unwrap_or_else(|| Vec3A::ZERO);
let nrm = nrm.unwrap_or_else(|| Vec3A::ZERO);
let tan = tan.unwrap_or_else(|| Vec4::ZERO);
let idx = idx.unwrap_or_else(|| Vec4::ZERO);
let wgt = wgt.unwrap_or_else(|| Vec4::ZERO);
let clr = clr.unwrap_or_else(|| Vec4::ONE);
vert_dat.push(Vertex { pos, tex, nrm, tan, idx, wgt, clr });
}

// collect index info
@@ -305,25 +371,32 @@ impl Model {
}

// collect joint info
let mut joints = Vec::with_capacity(num_join);
let mut joints: Vec<Joint> = Vec::with_capacity(num_join);

rd.seek(SeekFrom::Start(ofs_join))?;

for join in read::hunk(rd, num_join * 4 * 12)?.chunks(4 * 12) {
let trs = &mut [0.0; 10];
//let nam = read::u32le_sz(join, 0);
let mut trs = [0.0; 10];
let nam = read::u32le_sz(join, 0);
let par = read::u32le_sz(join, 4);
let trs = read::array(read::f32le_32, join, trs, 4, 8);
read::array(read::f32le_32, join, &mut trs, 4, 8);

//let nam = SmolStr::new(from_stab(&stab, nam)?);
let par = if par & 0x8000_0000 != 0 { None } else { Some(par) };
let mat = Mat4::from_scale_rotation_translation(
Vec3::new(trs[0], trs[1], trs[2]),
Quat::from_xyzw(trs[3], trs[4], trs[5], trs[6]),
let nam = SmolStr::new(from_stab(&stab, nam)?);

let mut mat = Mat4::from_scale_rotation_translation(
Vec3::new(trs[7], trs[8], trs[9]),
Quat::from_xyzw(trs[3], trs[4], trs[5], trs[6]).normalize(),
Vec3::new(trs[0], trs[1], trs[2]),
);
let mut inv = mat.inverse();

if par & 0x8000_0000 == 0 {
let parent = joints.get(par).ok_or(Err::Parent)?;
mat = parent.mat * mat;
inv = inv * parent.inv;
}

joints.push(Joint { /*nam,*/ par, mat });
joints.push(Joint { nam, mat, inv });
}

// collect frames
@@ -336,77 +409,63 @@ impl Model {
}

// collect pose info
let mut poses = Vec::with_capacity(num_pose);
let mut frame = frames.iter();
let mut frames = Vec::with_capacity(num_pose);

rd.seek(SeekFrom::Start(ofs_pose))?;

for pose in read::hunk(rd, num_pose * 4 * 22)?.chunks(4 * 22) {
let ofs = &mut [0.0; 10];
let scl = &mut [0.0; 10];
for (pose, pose_n) in
read::hunk(rd, num_pose * 4 * 22)?.chunks(4 * 22).zip(0..num_pose)
{
let par = read::u32le_sz(pose, 0);
let msk = read::u32le_32(pose, 4);
let ofs = read::array(read::f32le_32, pose, ofs, 4, 8);
let scl = read::array(read::f32le_32, pose, scl, 4, 48);
let par = if par & 0x8000_0000 != 0 { None } else { Some(par) };

poses.push(Pose {
par,
msk,
ofs: ofs.try_into().unwrap(),
scl: scl.try_into().unwrap(),
});
}
let mut ofs = [0.0; 10];
let mut scl = [0.0; 10];
read::array(read::f32le_32, pose, &mut ofs, 4, 8);
read::array(read::f32le_32, pose, &mut scl, 4, 48);

Ok((
Self { meshes, num_frmc, frames, joints, poses },
ModelData { vtx: vert_dat, idx: indx_dat },
))
}
let mut pose_mats = Vec::with_capacity(num_frms);

pub fn num_frames(&self) -> usize {
self.frames.len() / self.num_frmc
}
for _frame_num in 0..num_frms {
let mut ofs = ofs;

pub fn frame(&self, joint: usize, frame: usize) -> Option<Mat4> {
Some(self.joint_mat(joint)? * self.pose_mat(joint, frame)?)
}
for i in 0..10 {
if msk & 1 << i != 0 {
ofs[i] +=
f32::from(*frame.next().ok_or(Err::FrameCount)?) * scl[i];
}
}

pub fn pose_mat(&self, joint: usize, frame: usize) -> Option<Mat4> {
let pose = self.poses.get(joint)?;
let mut mat = Mat4::from_scale_rotation_translation(
Vec3::new(ofs[7], ofs[8], ofs[9]),
Quat::from_xyzw(ofs[3], ofs[4], ofs[5], ofs[6]).normalize(),
Vec3::new(ofs[0], ofs[1], ofs[2]),
);

let mut trs = [0.0; 10];
let joint = &joints[pose_n];

let mut frames = self.frames.iter().skip(frame * self.num_frmc);
if par & 0x8000_0000 == 0 {
let parent = joints.get(par).ok_or(Err::Parent)?;
mat = parent.mat * mat * joint.inv;
} else {
mat = mat * joint.inv;
}

for i in 0..10 {
if pose.msk & 1 << i != 0 {
let frame = f32::from(*frames.next()?);
trs[i] = frame.mul_add(pose.scl[i], pose.ofs[i]);
pose_mats.push(mat);
}
}

let mut mat = Mat4::from_scale_rotation_translation(
Vec3::new(trs[0], trs[1], trs[2]),
Quat::from_xyzw(trs[3], trs[4], trs[5], trs[6]),
Vec3::new(trs[7], trs[8], trs[9]),
);

if let Some(parent) = pose.par {
mat = self.pose_mat(parent, frame)? * mat;
frames.push(pose_mats);
}

Some(mat)
Ok((Self { meshes, frames, num_frms }, ModelData { vtx: vert_dat, idx: indx_dat }))
}

fn joint_mat(&self, joint: usize) -> Option<Mat4> {
let jnt = self.joints.get(joint)?;
let mut mat = jnt.mat;

if let Some(parent) = jnt.par {
mat = self.joint_mat(parent)? * mat;
}
pub fn frame(&self, joint: usize, frame: usize) -> Option<Mat4> {
Some(*self.frames.get(joint)?.get(frame)?)
}

Some(mat)
pub const fn num_frames(&self) -> usize {
self.num_frms
}
}



+ 12
- 0
source/framework/data/read.rs View File

@@ -1,5 +1,9 @@
use std::io::{self, Read};

pub const fn i16le_16(b: &[u8], p: usize) -> i16 {
i16::from_le_bytes([b[p], b[p + 1]])
}

pub const fn u16le_16(b: &[u8], p: usize) -> u16 {
u16::from_le_bytes([b[p], b[p + 1]])
}
@@ -8,6 +12,10 @@ pub const fn u16le_sz(b: &[u8], p: usize) -> usize {
u16le_16(b, p) as usize
}

pub const fn i32le_32(b: &[u8], p: usize) -> i32 {
i32::from_le_bytes([b[p], b[p + 1], b[p + 2], b[p + 3]])
}

pub const fn u32le_32(b: &[u8], p: usize) -> u32 {
u32::from_le_bytes([b[p], b[p + 1], b[p + 2], b[p + 3]])
}
@@ -24,6 +32,10 @@ pub fn f32le_32(b: &[u8], p: usize) -> f32 {
f32::from_le_bytes([b[p], b[p + 1], b[p + 2], b[p + 3]])
}

pub fn f64le_64(b: &[u8], p: usize) -> f64 {
f64::from_le_bytes([b[p], b[p + 1], b[p + 2], b[p + 3], b[p + 4], b[p + 5], b[p + 6], b[p + 7]])
}

pub fn array<'a, 'b, T>(
f: impl Fn(&[u8], usize) -> T, b: &'a [u8], v: &'b mut [T], step: usize,
beg: usize,


+ 1
- 0
source/framework/data/vertex.rs View File

@@ -5,6 +5,7 @@ pub struct Vertex {
pub pos: Vec3A,
pub tex: Vec3A,
pub nrm: Vec3A,
pub tan: Vec4,
pub idx: Vec4,
pub wgt: Vec4,
pub clr: Vec4,


+ 10
- 10
source/framework/defl.rs View File

@@ -267,7 +267,7 @@ fn output_tables(
67, 83, 99, 115, 131, 163, 195, 227, 258,
];

const LEN_EXTRA_BITS: [u8; 29] = [
const LEN_EXTRA_BITS: [usize; 29] = [
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
5, 5, 5, 5, 0,
];
@@ -278,7 +278,7 @@ fn output_tables(
0x6001,
];

const DST_EXTRA_BITS: [u8; 30] = [
const DST_EXTRA_BITS: [usize; 30] = [
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10,
10, 11, 11, 12, 12, 13, 13,
];
@@ -309,7 +309,7 @@ fn output_tables(
let bit = LEN_EXTRA_BITS[sym];
let len = usize::read_bits_le(b, *p, bit).ok_or(Err::Pair)?;

*p += usize::from(bit);
*p += bit;

LEN_BASE[sym] + len
};
@@ -321,7 +321,7 @@ fn output_tables(
let bit = DST_EXTRA_BITS[sym];
let dst = usize::read_bits_le(b, *p, bit).ok_or(Err::Pair)?;

*p += usize::from(bit);
*p += bit;

DST_BASE[sym] + dst
};
@@ -349,7 +349,7 @@ impl HuffmanTable {
nums[usize::from(length)] += 1;
}

if usize::from(nums[0]) == table.len() {
if nums[0] == table.len() {
return Err(Err::Table);
}

@@ -357,7 +357,7 @@ impl HuffmanTable {
let mut ofs = [0; 16];

for i in 1..=14 {
ofs[i + 1] = ofs[i] + usize::from(nums[i]);
ofs[i + 1] = ofs[i] + nums[i];
}

// make the actual bit pattern table
@@ -382,14 +382,14 @@ impl HuffmanTable {

for i in 1..=15 {
// add bit from file
codes |= u16::read_bits_le(b, *p, 1).ok_or(Err::Table)?;
codes |= usize::read_bits_le(b, *p, 1).ok_or(Err::Table)?;
*p += 1;

// check our symbol table for this one (quick tree check)
let count = self.nums[i];

if i32::from(codes) - i32::from(count) < i32::from(first) {
return Ok(self.syms[usize::from(index + codes - first)]);
if (codes as isize) - (count as isize) < (first as isize) {
return Ok(self.syms[index + codes - first]);
}

// continue on, trying to find the correct sequence
@@ -406,7 +406,7 @@ impl HuffmanTable {

#[derive(Debug)]
struct HuffmanTable {
nums: [u16; 16],
nums: [usize; 16],
syms: Vec<u16>,
}



+ 0
- 2
source/framework/lib.rs View File

@@ -16,8 +16,6 @@

#[macro_use]
pub mod ffi;
#[macro_use]
pub mod log;

#[macro_use(Error)]
extern crate thiserror;


+ 0
- 137
source/framework/log.rs View File

@@ -1,137 +0,0 @@
mod color;
mod conf;
mod level;
mod standard;

pub use self::{color::Color, conf::Conf, level::Level, standard::Std};

use std::collections::HashMap;

#[macro_export]
macro_rules! lg {
($to:expr, $level:expr, $($args:tt)+) => {
match ($level, $to) {
(level, to) => {
if to.enabled(level) {
let record = $crate::log::Record {
level,
module: std::module_path!(),
file: std::file!(),
line: std::line!(),
column: std::column!(),
};

to.log(std::format_args!($($args)+), record);
}
}
}
};
}

#[macro_export]
macro_rules! trace {
($to:expr) => {
{
#[cfg(debug_assertions)]
$crate::lg!($to, $crate::log::Level::Trace, "");
}
};

($to:expr, $val:expr) => {
match $val {
val => {
#[cfg(debug_assertions)]
$crate::lg!(
$to,
$crate::log::Level::Trace,
"{} = {:#?}",
std::stringify!($val),
&val,
);
val
}
}
};

($to:expr, $($val:expr),+ $(,)?) => {
($($crate::trace!($to, $val)),+,)
};
}

pub struct Record {
pub level: Level,
pub module: &'static str,
pub file: &'static str,
pub line: u32,
pub column: u32,
}

pub struct Log {
level: Level,
begin: std::time::Instant,
modes: HashMap<&'static str, Box<dyn Mode>>,
mode: &'static str,
}

pub trait Mode {
fn log(&self, args: std::fmt::Arguments, record: Record, log: &Log);
}

impl Default for Log {
fn default() -> Self {
let mut modes: HashMap<_, Box<dyn Mode>> = HashMap::new();
modes.insert("Std", Box::new(Std));
Self {
modes,
level: Level::default(),
begin: std::time::Instant::now(),
mode: "Std",
}
}
}

impl Log {
pub fn enabled(&self, level: Level) -> bool {
level <= self.level
}

pub fn insert_mode<M>(mut self, name: &'static str, mode: M) -> Self
where
M: Mode + 'static,
{
self.modes.insert(name, Box::new(mode));
self
}

pub fn set_mode(mut self, name: &'static str) -> Result<Self, ()> {
if self.modes.contains_key(name) {
self.mode = name;
Ok(self)
} else {
Err(())
}
}

pub fn log(&self, args: std::fmt::Arguments, record: Record) {
self.modes[self.mode].log(args, record, self);
}

pub fn write_into(
&self, args: std::fmt::Arguments, record: Record,
out: &mut impl std::io::Write,
) -> std::io::Result<()> {
writeln!(
out,
"[{}:{}:{}:{}][{}ms] {}",
record.file,
record.line,
record.column,
record.module,
self.begin.elapsed().as_millis(),
args,
)?;
Ok(())
}
}

// EOF

+ 0
- 50
source/framework/log/color.rs View File

@@ -1,50 +0,0 @@
#![cfg(feature = "color-log")]

use crate::log::{Level, Log, Mode, Record};
use termcolor::{ColorSpec, WriteColor};

pub struct Color;

impl Color {
fn write_level(
&self, level: Level, out: &mut impl WriteColor,
) -> std::io::Result<()> {
use termcolor::Color;

let (color, intense) = match level {
| Level::Critical => (Color::Red, true),
| Level::Error => (Color::Red, false),
| Level::Warning => (Color::Yellow, true),
| Level::Notice => (Color::Yellow, false),
| Level::Info => (Color::Cyan, true),
| Level::Debug => (Color::Cyan, false),
#[cfg(debug_assertions)]
| Level::Trace => (Color::Magenta, true),
};

let mut spec = ColorSpec::new();
spec.set_fg(Some(color)).set_intense(intense);

out.write_all(b"[")?;
out.set_color(&spec)?;
write!(out, "{:^8}", level)?;
out.reset()?;
out.write_all(b"]")?;
Ok(())
}
}

impl Mode for Color {
fn log(&self, args: std::fmt::Arguments, record: Record, log: &Log) {
let color = termcolor::ColorChoice::Auto;
let mut out = if record.level <= Level::Warning {
termcolor::StandardStream::stderr(color)
} else {
termcolor::StandardStream::stdout(color)
};
let _ = self.write_level(record.level, &mut out);
let _ = log.write_into(args, record, &mut out);
}
}

// EOF

+ 0
- 14
source/framework/log/conf.rs View File

@@ -1,14 +0,0 @@
use crate::log::Level;

#[blonkus_ma::serialize_config]
pub struct Conf {
pub level: Level,
}

impl Default for Conf {
fn default() -> Self {
Self { level: Level::default() }
}
}

// EOF

+ 0
- 48
source/framework/log/level.rs View File

@@ -1,48 +0,0 @@
use std::fmt;

#[blonkus_ma::serialize_config]
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub enum Level {
/// Errata that will imminently crash the program.
Critical,
/// Errata that will cause issues.
Error,
/// Errata that can be ignored but should be fixed.
Warning,
/// Information the user will want to read.
Notice,
/// Information that is strictly non-essential.
Info,
/// Debugging information available in all builds.
Debug,
/// Debugging information only available in debug builds.
#[cfg(debug_assertions)]
Trace,
}

impl Default for Level {
fn default() -> Self {
#[cfg(debug_assertions)]
let level = Self::Trace;
#[cfg(not(debug_assertions))]
let level = Self::Notice;
level
}
}

impl fmt::Display for Level {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
| Self::Critical => f.write_str("Critical"),
| Self::Error => f.write_str("Error"),
| Self::Warning => f.write_str("Warning"),
| Self::Notice => f.write_str("Notice"),
| Self::Info => f.write_str("Info"),
| Self::Debug => f.write_str("Debug"),
#[cfg(debug_assertions)]
| Self::Trace => f.write_str("Trace"),
}
}
}

// EOF

+ 0
- 27
source/framework/log/standard.rs View File

@@ -1,27 +0,0 @@
use crate::log::{Level, Log, Mode, Record};
use std::io::Write;

pub struct Std;

impl Std {
fn write_into(
&self, args: std::fmt::Arguments, record: Record, log: &Log,
out: &mut impl Write,
) -> std::io::Result<()> {
write!(out, "[{:^8}]", record.level)?;
log.write_into(args, record, out)?;
Ok(())
}
}

impl Mode for Std {
fn log(&self, args: std::fmt::Arguments, record: Record, log: &Log) {
let _ = if record.level <= Level::Warning {
self.write_into(args, record, log, &mut std::io::stderr())
} else {
self.write_into(args, record, log, &mut std::io::stdout())
};
}
}

// EOF

+ 7
- 1
source/framework/render/misc.rs View File

@@ -46,7 +46,7 @@ pub const VTX_BIND_DESC: [vk::VertexInputBindingDescription; 1] =
input_rate: vk::VertexInputRate::VERTEX,
}];

pub const VTX_ATTR_DESC: [vk::VertexInputAttributeDescription; 6] = [
pub const VTX_ATTR_DESC: [vk::VertexInputAttributeDescription; 7] = [
vk::VertexInputAttributeDescription {
location: 0,
binding: 0,
@@ -83,6 +83,12 @@ pub const VTX_ATTR_DESC: [vk::VertexInputAttributeDescription; 6] = [
format: vk::Format::R32G32B32A32_SFLOAT,
offset: 80,
},
vk::VertexInputAttributeDescription {
location: 6,
binding: 0,
format: vk::Format::R32G32B32A32_SFLOAT,
offset: 96,
},
];

// EOF

+ 5
- 1
source/framework/render/model.rs View File

@@ -74,7 +74,7 @@ impl Model {
}

pub fn frame_matrices(&self, frame: usize) -> [Mat4; 128] {
let mut matrices = [Mat4::identity(); 128];
let mut matrices = [Mat4::IDENTITY; 128];
let mut joint = 0;

while let Some(mat) = self.model.frame(joint, frame) {
@@ -84,6 +84,10 @@ impl Model {

matrices
}

pub const fn num_frames(&self) -> usize {
self.model.num_frames()
}
}

// EOF

+ 12
- 22
source/main_test/entry.rs View File

@@ -6,7 +6,7 @@ use ash::{version::DeviceV1_0, vk};
use blonkus_fw::{
conf,
data::{self, vfs},
hal, lg, log, meta,
hal, meta,
render::{
self, misc, Buffer, CommandBuffers, CommandPool, DescriptorPool,
DescriptorSetLayout, Device, ErrAllocMem, Fence, Framebuffer, GetDevice,
@@ -273,19 +273,14 @@ fn draw_frame<'b>(
/ sc_data.swapchain.extent.height as f32,
0.01,
100_000.0,
) * Mat4::from_cols(
Vec4::new(1.0, 0.0, 0.0, 0.0),
Vec4::new(0.0, -1.0, 0.0, 0.0),
Vec4::new(0.0, 0.0, 1.0, 0.0),
Vec4::new(0.0, 0.0, 0.0, 1.0),
);
) * Mat4::from_cols(Vec4::X, -Vec4::Y, Vec4::Z, Vec4::W);

let uniforms = data::uniforms::Uniforms { object, camera, projec };

let (ufm_buf, bon_buf) = &sc_data.descriptor_pool.buffers[image_index];
ufm_buf.write_data(&[uniforms])?;
bon_buf.write_data(
&sc_data.info.model.frame_matrices((time_ms / 500 % 30) as usize),
&sc_data.info.model.frame_matrices((time_ms / 100 % sc_data.info.model.num_frames() as u128) as usize),
)?;

let wait_semaphores = [**image_avail_s];
@@ -339,16 +334,14 @@ fn draw_frame<'b>(
Ok(())
}

fn seize_device(lg: &log::Log, device: &Device) {
fn seize_device(device: &Device) {
let seize = unsafe { device.device_wait_idle() };
if let Err(e) = seize {
lg!(lg, log::Level::Error, "Error seizing renderer state: {}", e);
eprintln!("Error seizing renderer state: {}", e);
}
}

pub fn run(
conf: &conf::Conf, lg: &log::Log,
) -> Result<(), Box<dyn std::error::Error>> {
pub fn run(conf: &conf::Conf) -> Result<(), Box<dyn std::error::Error>> {
let start_time = std::time::Instant::now();

let mut vfs = vfs::Vfs::default();
@@ -374,7 +367,7 @@ pub fn run(
let hal = hal::ctx::Context::new()?;
let window = hal::win::Window::new(&hal, meta::ffi::NAME, 640, 480)?;

let entry = ash::Entry::new()?;
let entry = unsafe { ash::Entry::new()? };
let instance = Instance::create(&conf.render, entry, &window)?;

let physical = PhysicalDevice::get(instance.clone(), &conf.render)?;
@@ -460,26 +453,23 @@ pub fn run(
match frame {
| Ok(()) => {}
| Err(vk::Result::ERROR_OUT_OF_DATE_KHR) => {
seize_device(lg, sc_data.get_device());
seize_device(sc_data.get_device());
sc_data = SwapchainData::create(sc_data.info)?;
}
| Err(res) => {
lg!(lg, log::Level::Error, "Error rendering frame: {}", res);
eprintln!("Error rendering frame: {}", res);
}
}

cur_c_frame = (cur_c_frame + 1) % concur_frames;
}

seize_device(lg, sc_data.get_device());
seize_device(sc_data.get_device());

Ok(())
}

const MAIN_VERT: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/main.vert.o"));

const MAIN_FRAG: &[u8] =
include_bytes!(concat!(env!("OUT_DIR"), "/main.frag.o"));
const MAIN_VERT: &[u8] = include_bytes!(concat!("../../glsl/main.vert.o"));
const MAIN_FRAG: &[u8] = include_bytes!(concat!("../../glsl/main.frag.o"));

// EOF

+ 8
- 14
source/main_test/main.rs View File

@@ -14,28 +14,22 @@
#![cfg_attr(test, allow(dead_code))]
#![cfg(not(test))]

use blonkus_fw::{conf, lg, log};

pub mod entry;

fn main() {
let lg = log::Log::default();

#[cfg(feature = "color-log")]
let lg = lg.insert_mode("Color", log::Color).set_mode("Color").unwrap();
use blonkus_fw::conf;

fn main() {
let conf = conf::Conf::read("blonkus.toml").unwrap_or_else(|err| {
let level = match err {
| conf::ErrConfLoad::NoFile => log::Level::Notice,
| _ => log::Level::Error,
match err {
| conf::ErrConfLoad::NoFile => println!("{}", err),
| _ => eprintln!("{}", err),
};
lg!(&lg, level, "{}", err);
lg!(&lg, log::Level::Notice, "Using default configuration.");
println!("Using default configuration.");
conf::Conf::default()
});

if let Err(e) = entry::run(&conf, &lg) {
lg!(&lg, log::Level::Critical, "Uncaught error: {}", e);
if let Err(e) = entry::run(&conf) {
eprintln!("Uncaught error: {}", e);
}
}



+ 8
- 0
tools/shader View File

@@ -0,0 +1,8 @@
#!/bin/sh

compile() {
glslc -O -o $1 -std=450core --target-env=vulkan1.0 -Werror -xglsl $2
}

compile glsl/main.frag.o glsl/main.frag
compile glsl/main.vert.o glsl/main.vert

Loading…
Cancel
Save