Add default texture which fixes render error, fix cube rendering

This commit is contained in:
SeanOMik 2023-10-05 11:42:24 -04:00
parent a5b145c9b3
commit 8f7288339d
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
10 changed files with 93 additions and 62 deletions

10
.vscode/launch.json vendored
View File

@ -7,20 +7,20 @@
{
"type": "lldb",
"request": "launch",
"name": "Debug executable 'lyra-engine'",
"name": "Debug lyra testbed",
"cargo": {
"args": [
"build",
"--bin=lyra-engine",
"--package=lyra-engine"
"--manifest-path", "${workspaceFolder}/examples/testbed/Cargo.toml"
//"--bin=testbed",
],
"filter": {
"name": "lyra-engine",
"name": "testbed",
"kind": "bin"
}
},
"args": [],
"cwd": "${workspaceFolder}"
"cwd": "${workspaceFolder}/examples/testbed"
},
{
"type": "lldb",

1
Cargo.lock generated
View File

@ -1304,6 +1304,7 @@ dependencies = [
"image",
"percent-encoding",
"thiserror",
"tracing",
"uuid",
]

View File

@ -1343,6 +1343,7 @@ dependencies = [
"image",
"percent-encoding",
"thiserror",
"tracing",
"uuid",
]

View File

@ -6,13 +6,13 @@ use lyra_engine::assets::{ResourceManager, Texture, Model};
use tracing::debug;
pub const VERTICES: &[Vertex] = &[
/* pub const VERTICES: &[Vertex] = &[
Vertex { position: [-0.0868241, 0.49240386, 0.0], tex_coords: [0.4131759, 0.00759614], }, // A
Vertex { position: [-0.49513406, 0.06958647, 0.0], tex_coords: [0.0048659444, 0.43041354], }, // B
Vertex { position: [-0.21918549, -0.44939706, 0.0], tex_coords: [0.28081453, 0.949397], }, // C
Vertex { position: [0.35966998, -0.3473291, 0.0], tex_coords: [0.85967, 0.84732914], }, // D
Vertex { position: [0.44147372, 0.2347359, 0.0], tex_coords: [0.9414737, 0.2652641], }, // E
];
]; */
pub const INDICES: &[u16] = &[
0, 1, 4,
@ -67,11 +67,11 @@ impl Point3d {
#[async_std::main]
async fn main() {
let setup_sys = |world: &mut World| -> anyhow::Result<()> {
{
/* {
let mut window_options = world.get_resource_mut::<Ct<WindowOptions>>().unwrap();
window_options.cursor_grab = CursorGrabMode::Confined;
window_options.cursor_visible = false;
}
} */
let mut resman = world.get_resource_mut::<ResourceManager>().unwrap();
let diffuse_texture = resman.request::<Texture>("assets/happy-tree.png").unwrap();
@ -102,11 +102,11 @@ async fn main() {
world.spawn((
ModelComponent(cube_model),
TransformComponent::from(Transform::from_xyz(0.005, 0.5, -1.2)),
TransformComponent::from(Transform::from_xyz(0.005, 0.5, -2.2)),
));
let mut camera = CameraComponent::new_3d();
camera.transform.translation += math::Vec3::new(0.0, 0.0, 2.0);
camera.transform.translation += math::Vec3::new(0.0, 0.0, 7.5);
//camera.transform.rotate_y(Angle::Degrees(-25.0));
camera.transform.rotate_z(math::Angle::Degrees(-90.0));
world.spawn((camera,));
@ -140,10 +140,14 @@ async fn main() {
let keys: Ref<InputButtons<KeyCode>> = keys.unwrap();
let speed = 0.001;
let rot_speed = 1.0;
let mut dir_x = 0.0;
let mut dir_y = 0.0;
let mut rot_x = 0.0;
let mut rot_y = 0.0;
if keys.is_pressed(KeyCode::A) {
dir_x += speed;
}
@ -160,9 +164,25 @@ async fn main() {
dir_y -= speed;
}
if keys.is_pressed(KeyCode::Left) {
rot_y -= rot_speed;
}
if keys.is_pressed(KeyCode::Right) {
rot_y += rot_speed;
}
if keys.is_pressed(KeyCode::Up) {
rot_x -= rot_speed;
}
if keys.is_pressed(KeyCode::Down) {
rot_x += rot_speed;
}
drop(keys);
if dir_x == 0.0 && dir_y == 0.0 {
if dir_x == 0.0 && dir_y == 0.0 && rot_x == 0.0 && rot_y == 0.0 {
return Ok(());
}
@ -170,12 +190,15 @@ async fn main() {
for transform in world.query_mut::<(&mut TransformComponent,)>().iter_mut() {
let t = &mut transform.transform;
debug!("Translation: {}", t.translation);
//debug!("Translation: {}", t.translation);
//debug!("Rotation: {}", t.rotation);
/* t.translation += glam::Vec3::new(0.0, 0.001, 0.0);
t.translation.x *= -1.0; */
t.translation.x += dir_x;
t.translation.y += dir_y;
t.rotate_x(math::Angle::Degrees(rot_x));
t.rotate_y(math::Angle::Degrees(rot_y));
}
let events = world.get_resource_mut::<EventQueue>().unwrap();

View File

@ -14,4 +14,5 @@ gltf = { version = "1.3.0", features = ["KHR_materials_pbrSpecularGlossiness"] }
image = "0.24.7"
percent-encoding = "2.3.0"
thiserror = "1.0.48"
tracing = "0.1.37"
uuid = { version = "1.4.1", features = ["v4"] }

View File

@ -4,6 +4,8 @@ use base64::Engine;
use crate::{ResourceLoader, LoaderError, Mesh, Model, MeshVertexAttribute, VertexAttributeData, Resource, Material, ResHandle};
use tracing::debug;
impl From<gltf::Error> for LoaderError {
fn from(value: gltf::Error) -> Self {
LoaderError::DecodingError(value.into())
@ -40,6 +42,7 @@ impl ModelLoader {
// read the positions
if let Some(pos) = reader.read_positions() {
debug!("Mesh mode is {:?}", prim.mode());
let pos: Vec<glam::Vec3> = pos.map(|t| t.into()).collect();
new_mesh.add_attribute(MeshVertexAttribute::Position, VertexAttributeData::Vec3(pos));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 B

View File

@ -40,7 +40,6 @@ struct RenderBufferStorage {
render_texture: Option<RenderTexture>,
texture_bindgroup: Option<BindGroup>,
texture_layout: Option<BindGroupLayout>,
/// The index of the transform for this entity.
/// The tuple is structured like this: (transform index, index of transform inside the buffer)
@ -155,6 +154,8 @@ pub struct BasicRenderer {
camera_buffer: wgpu::Buffer,
camera_bind_group: wgpu::BindGroup,
texture_bind_group_layout: BindGroupLayout,
default_texture_bind_group: BindGroup,
depth_buffer_texture: RenderTexture,
}
@ -343,12 +344,27 @@ impl BasicRenderer {
let depth_texture = RenderTexture::create_depth_texture(&device, &config, "Depth Buffer");
let mut pipelines = HashMap::new();
pipelines.insert(0, Arc::new(FullRenderPipeline::new(&device, &config, &shader,
vec![super::vertex::Vertex::desc(),],
vec![&texture_bind_group_layout, &transform_bind_group_layout, &camera_bind_group_layout])));
// load the default texture
let bytes = include_bytes!("default_texture.png");
let tex = RenderTexture::from_bytes(&device, &queue, bytes, "default_texture").unwrap();
let default_tex_bindgroup = device.create_bind_group(
&wgpu::BindGroupDescriptor {
layout: &texture_bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: wgpu::BindingResource::TextureView(tex.view()),
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Sampler(tex.sampler()),
}
],
label: Some("default_texture"),
}
);
Self {
let mut s = Self {
window,
surface,
device,
@ -361,7 +377,7 @@ impl BasicRenderer {
b: 0.3,
a: 1.0,
},
render_pipelines: pipelines,
render_pipelines: HashMap::new(),
render_jobs: VecDeque::new(),
buffer_storage: HashMap::new(),
@ -373,8 +389,19 @@ impl BasicRenderer {
camera_buffer,
camera_bind_group,
texture_bind_group_layout,
default_texture_bind_group: default_tex_bindgroup,
depth_buffer_texture: depth_texture,
}
};
// create the default pipelines
let mut pipelines = HashMap::new();
pipelines.insert(0, Arc::new(FullRenderPipeline::new(&s.device, &s.config, &shader,
vec![super::vertex::Vertex::desc(),],
vec![&s.texture_bind_group_layout, &s.transform_bind_group_layout, &camera_bind_group_layout])));
s.render_pipelines = pipelines;
s
}
fn find_next_multiple(n: u32, mul: u32) -> u32 {
@ -385,13 +412,13 @@ impl BasicRenderer {
}
}
// TODO: minimize how often model buffers are updated by checking if they changed
fn update_mesh_buffers(&mut self, entity: EntityId, mesh: &Mesh) {
if let Some(buffers) = self.buffer_storage.get_mut(&entity) {
// check if the buffer sizes dont match. If they dont, completely remake the buffers
let vertices = mesh.position().unwrap();
if buffers.buffer_vertex.count() != vertices.len() {
drop(buffers);
debug!("Recreating buffers for mesh");
let (vert, idx) = self.create_vertex_index_buffers(mesh);
// have to re-get buffers because of borrow checker
@ -456,38 +483,13 @@ impl BasicRenderer {
fn create_mesh_buffers(&mut self, mesh: &Mesh, transform_indices: TransformBufferIndices) -> RenderBufferStorage {
let (vertex_buffer, buffer_indices) = self.create_vertex_index_buffers(mesh);
let (diffuse_layout, diffuse_bindgroup) = if let Some(model_texture) = &mesh.material().texture {
let diffuse_bindgroup = if let Some(model_texture) = &mesh.material().texture {
let image = &model_texture.data.as_ref().unwrap().image;
let diffuse_texture = RenderTexture::from_image(&self.device, &self.queue, image, None).unwrap();
let texture_bind_group_layout =
self.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
multisampled: false,
view_dimension: wgpu::TextureViewDimension::D2,
sample_type: wgpu::TextureSampleType::Float { filterable: true },
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::FRAGMENT,
// This should match the filterable field of the
// corresponding Texture entry above.
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
count: None,
},
],
label: Some("texture_bind_group_layout"),
});
let diffuse_bind_group = self.device.create_bind_group(
&wgpu::BindGroupDescriptor {
layout: &texture_bind_group_layout,
layout: &self.texture_bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
@ -502,16 +504,15 @@ impl BasicRenderer {
}
);
(Some(texture_bind_group_layout), Some(diffuse_bind_group))
Some(diffuse_bind_group)
} else {
(None, None)
None
};
RenderBufferStorage {
buffer_vertex: vertex_buffer,
buffer_indices,
render_texture: None,
texture_layout: diffuse_layout,
texture_bindgroup: diffuse_bindgroup,
transform_index: transform_indices
}
@ -561,7 +562,6 @@ impl Renderer for BasicRenderer {
let mut alive_entities = HashSet::new();
for (entity, model, model_epoch, transform) in main_world.query::<(Entities, &ModelComponent, EpochOf<ModelComponent>, &TransformComponent)>().iter() {
debug!("Collecting model things");
let model = model.data.as_ref().unwrap().as_ref();
let model_mesh = model.meshes.first().unwrap();
@ -649,8 +649,6 @@ impl Renderer for BasicRenderer {
}),
});
debug!("Executing {} render jobs", self.render_jobs.len());
// Pop off jobs from the queue as they're being processed
while let Some(job) = self.render_jobs.pop_front() {
if let Some(pipeline) = self.render_pipelines.get(&job.mesh().material().shader_uuid.unwrap_or(0)) {
@ -664,6 +662,8 @@ impl Renderer for BasicRenderer {
// Bind the optional texture
if let Some(tex) = buffers.texture_bindgroup.as_ref() {
render_pass.set_bind_group(0, &tex, &[]);
} else {
render_pass.set_bind_group(0, &self.default_texture_bind_group, &[]);
}
// Get the bindgroup for job's transform and bind to it using an offset.
@ -680,7 +680,7 @@ impl Renderer for BasicRenderer {
let indices_len = indices.count() as u32;
render_pass.set_vertex_buffer(buffers.buffer_vertex.slot(), buffers.buffer_vertex.buffer().slice(..));
render_pass.set_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint16);
render_pass.set_index_buffer(indices.buffer().slice(..), wgpu::IndexFormat::Uint32);
render_pass.draw_indexed(0..indices_len, 0, 0..1);
} else {
let vertices = mesh.position().unwrap();

View File

@ -2,7 +2,7 @@
struct VertexInput {
@location(0) position: vec3<f32>,
@location(1) tex_coords: vec2<f32>,
//@location(1) tex_coords: vec2<f32>,
}
struct VertexOutput {
@ -25,7 +25,7 @@ fn vs_main(
model: VertexInput,
) -> VertexOutput {
var out: VertexOutput;
out.tex_coords = model.tex_coords;
out.tex_coords = vec2<f32>(1.0, 1.0);
out.clip_position = camera.view_proj * u_model_transform * vec4<f32>(model.position, 1.0);
return out;
}

View File

@ -1,3 +1,5 @@
use glam::Vec3;
use super::desc_buf_lay::DescVertexBufferLayout;
#[repr(C)]
@ -5,13 +7,13 @@ use super::desc_buf_lay::DescVertexBufferLayout;
pub struct Vertex {
pub position: [f32; 3],
//pub color: [f32; 3], // TODO: add color again
pub tex_coords: [f32; 2]
//pub tex_coords: [f32; 2]
}
impl DescVertexBufferLayout for Vertex {
fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
array_stride: std::mem::size_of::<Vec3>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &[
wgpu::VertexAttribute {
@ -19,11 +21,11 @@ impl DescVertexBufferLayout for Vertex {
shader_location: 0,
format: wgpu::VertexFormat::Float32x3,
},
wgpu::VertexAttribute {
/* wgpu::VertexAttribute {
offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
shader_location: 1,
format: wgpu::VertexFormat::Float32x2,
}
} */
]
}
}