:constrution: wip: glTF loading PoC

main
_ 2021-12-19 18:45:57 +00:00
parent d9534554d1
commit 91b3f26e0d
2 changed files with 177 additions and 31 deletions

View File

@ -107,7 +107,7 @@ impl Graphics {
Pass::default ()
.shader (&shaders [0])
.flags ([
(gl::CULL_FACE, true),
(gl::CULL_FACE, false),
(gl::DEPTH_TEST, true),
(gl::TEXTURE_2D, true),
(gl::STENCIL_TEST, false),
@ -164,6 +164,7 @@ impl Graphics {
&self,
state: &GameState,
gl_state: &mut GlState,
level: &crate::LoadedLevel,
) {
use uniforms as u;
@ -192,9 +193,9 @@ impl Graphics {
let attrs = shader_vars.attrs;
let unis = shader_vars.unis;
self.texture_earth.bind ();
{
if false {
self.texture_earth.bind ();
let mvp = view_mat *
Mat4::from_translation (state.player.pos) *
Mat4::from_scale ((0.5, 0.5, 0.5).into ());
@ -209,25 +210,89 @@ impl Graphics {
self.texture_crate.bind ();
glezz::uniform_3fv (unis [&u::ALBEDO], &white);
for aabb in &state.aabbs {
let min = aabb.min;
let max = aabb.max;
let center = (min + max) / 2.0;
let scale = (max - min) / 2.0;
if false {
for aabb in &state.aabbs {
let min = aabb.min;
let max = aabb.max;
let center = (min + max) / 2.0;
let scale = (max - min) / 2.0;
let mvp = view_mat *
Mat4::from_translation (center) *
Mat4::from_scale (scale);
glezz::uniform_matrix_4fv (unis [&u::MVP], &mvp);
self.mesh_cube.draw_all (attrs, |_| {
true
});
}
}
if true {
use opengl_rust::renderable_model::attributes as a;
let mvp = view_mat *
Mat4::from_translation (center) *
Mat4::from_scale (scale);
glezz::uniform_matrix_4fv (unis [&u::MVP], &mvp);
let scene = level.level.scenes ().next ().unwrap ();
self.mesh_cube.draw_all (attrs, |_| {
true
});
unsafe {
gl::BindBuffer (gl::ARRAY_BUFFER, 0);
gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, 0);
}
for node in scene.nodes () {
let mesh = match node.mesh () {
None => continue,
Some (x) => x,
};
let mvp = view_mat *
Mat4::from_cols_array_2d (&node.transform ().matrix ());
glezz::uniform_matrix_4fv (unis [&u::MVP], &mvp);
for prim in mesh.primitives () {
use gltf::{
Semantic,
};
let positions = match prim.get (&Semantic::Positions) {
None => continue,
Some (x) => x,
};
let pos_view = match positions.view () {
None => continue,
Some (x) => x,
};
let indices = match prim.indices () {
None => continue,
Some (x) => x,
};
let indices_view = match indices.view () {
None => continue,
Some (x) => x,
};
unsafe {
gl::VertexAttribPointer (
attrs [a::POS].unwrap (),
3,
gl::FLOAT,
0,
4 * 3,
&level.buffer [positions.offset () + pos_view.offset ()] as *const u8 as *const c_void,
);
gl::DrawElements (
gl::TRIANGLES,
3 * 12,
gl::UNSIGNED_SHORT,
&level.buffer [indices.offset () + indices_view.offset ()] as *const u8 as *const c_void,
);
}
}
}
}
glezz::uniform_3fv (unis [&u::ALBEDO], &shadow_blue);
if true {
if false {
// Raycast for player shadow
let coll = opengl_rust::physics::get_candidate (
&[], &state.aabbs,
@ -274,7 +339,7 @@ impl Graphics {
}
}
{
if false {
let sky_mvp_mat = view_mat * Mat4::from_scale ((64.0, 64.0, 64.0).into ());
self.texture_sky.bind ();
@ -284,7 +349,7 @@ impl Graphics {
glezz::uniform_3fv (unis [&u::MIN_ALBEDO], &black);
glezz::uniform_1i (unis [&u::TEXTURE], 0);
// self.mesh_sky.draw_all (attrs, |_| true);
self.mesh_sky.draw_all (attrs, |_| true);
}
});
}

View File

@ -50,6 +50,13 @@ impl Default for GameState {
}
}
impl GameState {
fn reset_level (&mut self, level: &LoadedLevel) {
self.player = Default::default ();
self.player.pos = level.player_spawn;
}
}
#[tokio::main]
async fn main () -> Result <()> {
tracing_subscriber::fmt::fmt ()
@ -81,16 +88,7 @@ async fn main () -> Result <()> {
let mut time_step = TimeStep::new (60, 1000);
let level = gltf::Gltf::open ("gltf/level-00.gltf")?;
for scene in level.scenes () {
for node in scene.nodes () {
println! (
"Node #{} has {} children",
node.index(),
node.children().count(),
);
}
}
let level = LoadedLevel::from_path ("gltf/level-00.glb")?;
let mut graphics = Graphics::new ();
@ -106,6 +104,8 @@ async fn main () -> Result <()> {
let player_jump_speed = 8.0;
let mut player_jump_vec: Option <Vec3> = None;
game_state.reset_level (&level);
'running: loop {
let _frames_to_do = time_step.step ();
let mut player_wants_to_jump = false;
@ -117,7 +117,7 @@ async fn main () -> Result <()> {
break 'running
},
Event::KeyDown { keycode: Some (Keycode::R), .. } => {
game_state = Default::default ();
game_state.reset_level (&level);
},
Event::KeyDown { keycode: Some (Keycode::Space), .. } => {
player_wants_to_jump = true;
@ -180,7 +180,7 @@ async fn main () -> Result <()> {
window.gl_make_current (&gl_ctx).unwrap ();
graphics.draw (&game_state, &mut gl_state);
graphics.draw (&game_state, &mut gl_state, &level);
graphics.frames += 1;
window.gl_swap_window ();
@ -191,6 +191,87 @@ async fn main () -> Result <()> {
Ok (())
}
struct LoadedLevel {
player_spawn: Vec3,
buffer: Vec <u8>,
level: gltf::Document,
}
impl LoadedLevel {
fn from_path (path: &str) -> Result <Self> {
use gltf::{
Semantic,
scene::Transform,
};
let (level, buffers, _) = gltf::import (path)?;
let buffer = match buffers.get (0) {
None => bail! ("gltf didn't load any buffers"),
Some (x) => x.0.to_vec (),
};
let scene = match level.scenes ().next () {
None => bail! ("No scenes in glTF file"),
Some (x) => x,
};
let mut player_spawn = None;
for node in scene.nodes () {
if node.name () == Some ("Player Spawn") {
let (translation, _, _) = node.transform ().decomposed ();
player_spawn = Some (Vec3::from (translation));
}
else if let Some (camera) = node.camera () {
}
else if let Some (mesh) = node.mesh () {
println! ("Node {:?} is a mesh", node.name ());
for (i, prim) in mesh.primitives ().enumerate () {
let positions = match prim.get (&Semantic::Positions) {
None => continue,
Some (x) => x,
};
let normals = match prim.get (&Semantic::Normals) {
None => continue,
Some (x) => x,
};
let indices = match prim.indices () {
None => continue,
Some (x) => x,
};
let pos_view = match positions.view () {
None => continue,
Some (x) => x,
};
let norm_view = match normals.view () {
None => continue,
Some (x) => x,
};
let indices_view = match indices.view () {
None => continue,
Some (x) => x,
};
dbg! (positions.offset (), pos_view.offset (), pos_view.stride ());
dbg! (normals.offset (), norm_view.offset (), norm_view.stride ());
dbg! (indices.offset (), indices.data_type (), indices_view.offset (), indices_view.stride ());
}
}
}
let player_spawn = match player_spawn {
None => bail! ("glTF file must have `Player Spawn` node"),
Some (x) => x,
};
Ok (Self {
buffer,
level,
player_spawn,
})
}
}
struct ShaderLocations {
attr_pos: u32,
attr_normal: u32,