:constrution: wip: glTF loading PoC
parent
d9534554d1
commit
91b3f26e0d
|
@ -107,7 +107,7 @@ impl Graphics {
|
||||||
Pass::default ()
|
Pass::default ()
|
||||||
.shader (&shaders [0])
|
.shader (&shaders [0])
|
||||||
.flags ([
|
.flags ([
|
||||||
(gl::CULL_FACE, true),
|
(gl::CULL_FACE, false),
|
||||||
(gl::DEPTH_TEST, true),
|
(gl::DEPTH_TEST, true),
|
||||||
(gl::TEXTURE_2D, true),
|
(gl::TEXTURE_2D, true),
|
||||||
(gl::STENCIL_TEST, false),
|
(gl::STENCIL_TEST, false),
|
||||||
|
@ -164,6 +164,7 @@ impl Graphics {
|
||||||
&self,
|
&self,
|
||||||
state: &GameState,
|
state: &GameState,
|
||||||
gl_state: &mut GlState,
|
gl_state: &mut GlState,
|
||||||
|
level: &crate::LoadedLevel,
|
||||||
) {
|
) {
|
||||||
use uniforms as u;
|
use uniforms as u;
|
||||||
|
|
||||||
|
@ -192,9 +193,9 @@ impl Graphics {
|
||||||
let attrs = shader_vars.attrs;
|
let attrs = shader_vars.attrs;
|
||||||
let unis = shader_vars.unis;
|
let unis = shader_vars.unis;
|
||||||
|
|
||||||
self.texture_earth.bind ();
|
if false {
|
||||||
|
self.texture_earth.bind ();
|
||||||
{
|
|
||||||
let mvp = view_mat *
|
let mvp = view_mat *
|
||||||
Mat4::from_translation (state.player.pos) *
|
Mat4::from_translation (state.player.pos) *
|
||||||
Mat4::from_scale ((0.5, 0.5, 0.5).into ());
|
Mat4::from_scale ((0.5, 0.5, 0.5).into ());
|
||||||
|
@ -209,25 +210,89 @@ impl Graphics {
|
||||||
self.texture_crate.bind ();
|
self.texture_crate.bind ();
|
||||||
glezz::uniform_3fv (unis [&u::ALBEDO], &white);
|
glezz::uniform_3fv (unis [&u::ALBEDO], &white);
|
||||||
|
|
||||||
for aabb in &state.aabbs {
|
if false {
|
||||||
let min = aabb.min;
|
for aabb in &state.aabbs {
|
||||||
let max = aabb.max;
|
let min = aabb.min;
|
||||||
let center = (min + max) / 2.0;
|
let max = aabb.max;
|
||||||
let scale = (max - min) / 2.0;
|
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 *
|
let scene = level.level.scenes ().next ().unwrap ();
|
||||||
Mat4::from_translation (center) *
|
|
||||||
Mat4::from_scale (scale);
|
|
||||||
glezz::uniform_matrix_4fv (unis [&u::MVP], &mvp);
|
|
||||||
|
|
||||||
self.mesh_cube.draw_all (attrs, |_| {
|
unsafe {
|
||||||
true
|
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);
|
glezz::uniform_3fv (unis [&u::ALBEDO], &shadow_blue);
|
||||||
|
|
||||||
if true {
|
if false {
|
||||||
// Raycast for player shadow
|
// Raycast for player shadow
|
||||||
let coll = opengl_rust::physics::get_candidate (
|
let coll = opengl_rust::physics::get_candidate (
|
||||||
&[], &state.aabbs,
|
&[], &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 ());
|
let sky_mvp_mat = view_mat * Mat4::from_scale ((64.0, 64.0, 64.0).into ());
|
||||||
|
|
||||||
self.texture_sky.bind ();
|
self.texture_sky.bind ();
|
||||||
|
@ -284,7 +349,7 @@ impl Graphics {
|
||||||
glezz::uniform_3fv (unis [&u::MIN_ALBEDO], &black);
|
glezz::uniform_3fv (unis [&u::MIN_ALBEDO], &black);
|
||||||
glezz::uniform_1i (unis [&u::TEXTURE], 0);
|
glezz::uniform_1i (unis [&u::TEXTURE], 0);
|
||||||
|
|
||||||
// self.mesh_sky.draw_all (attrs, |_| true);
|
self.mesh_sky.draw_all (attrs, |_| true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]
|
#[tokio::main]
|
||||||
async fn main () -> Result <()> {
|
async fn main () -> Result <()> {
|
||||||
tracing_subscriber::fmt::fmt ()
|
tracing_subscriber::fmt::fmt ()
|
||||||
|
@ -81,16 +88,7 @@ async fn main () -> Result <()> {
|
||||||
|
|
||||||
let mut time_step = TimeStep::new (60, 1000);
|
let mut time_step = TimeStep::new (60, 1000);
|
||||||
|
|
||||||
let level = gltf::Gltf::open ("gltf/level-00.gltf")?;
|
let level = LoadedLevel::from_path ("gltf/level-00.glb")?;
|
||||||
for scene in level.scenes () {
|
|
||||||
for node in scene.nodes () {
|
|
||||||
println! (
|
|
||||||
"Node #{} has {} children",
|
|
||||||
node.index(),
|
|
||||||
node.children().count(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut graphics = Graphics::new ();
|
let mut graphics = Graphics::new ();
|
||||||
|
|
||||||
|
@ -106,6 +104,8 @@ async fn main () -> Result <()> {
|
||||||
let player_jump_speed = 8.0;
|
let player_jump_speed = 8.0;
|
||||||
let mut player_jump_vec: Option <Vec3> = None;
|
let mut player_jump_vec: Option <Vec3> = None;
|
||||||
|
|
||||||
|
game_state.reset_level (&level);
|
||||||
|
|
||||||
'running: loop {
|
'running: loop {
|
||||||
let _frames_to_do = time_step.step ();
|
let _frames_to_do = time_step.step ();
|
||||||
let mut player_wants_to_jump = false;
|
let mut player_wants_to_jump = false;
|
||||||
|
@ -117,7 +117,7 @@ async fn main () -> Result <()> {
|
||||||
break 'running
|
break 'running
|
||||||
},
|
},
|
||||||
Event::KeyDown { keycode: Some (Keycode::R), .. } => {
|
Event::KeyDown { keycode: Some (Keycode::R), .. } => {
|
||||||
game_state = Default::default ();
|
game_state.reset_level (&level);
|
||||||
},
|
},
|
||||||
Event::KeyDown { keycode: Some (Keycode::Space), .. } => {
|
Event::KeyDown { keycode: Some (Keycode::Space), .. } => {
|
||||||
player_wants_to_jump = true;
|
player_wants_to_jump = true;
|
||||||
|
@ -180,7 +180,7 @@ async fn main () -> Result <()> {
|
||||||
|
|
||||||
window.gl_make_current (&gl_ctx).unwrap ();
|
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;
|
graphics.frames += 1;
|
||||||
|
|
||||||
window.gl_swap_window ();
|
window.gl_swap_window ();
|
||||||
|
@ -191,6 +191,87 @@ async fn main () -> Result <()> {
|
||||||
Ok (())
|
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 {
|
struct ShaderLocations {
|
||||||
attr_pos: u32,
|
attr_pos: u32,
|
||||||
attr_normal: u32,
|
attr_normal: u32,
|
||||||
|
|
Loading…
Reference in New Issue