("Render Pipeline Layout"),
                bind_group_layouts: &[
                    &texture_bind_group_layout,
                    &camera_bind_group_layout,
                    &simple_uniform_layout,
                    &simple_storage_layout,
                ],
                push_constant_ranges: &[],
            });
        println!("Before initial pipeline creation");
        let render_pipeline = {
            let shader = wgpu::ShaderModuleDescriptor {
                label: Some("Normal Shader"),
                source: wgpu::ShaderSource::Wgsl(include_str!("shader.wgsl").into()),
            };
            create_render_pipeline(
                &device,
                &render_pipeline_layout,
                surface_config.format,
                Some(texture::Texture::DEPTH_FORMAT),
                &[model::ModelVertex::desc(), InstanceRaw::desc()],
                shader,
                0,
            )
        };
        println!("After initial pipeline creation");
        let light_render_pipeline = {
            let layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
                label: Some("Light Pipeline Layout"),
                bind_group_layouts: &[
                    &simple_uniform_layout,
                    &camera_bind_group_layout,
                    &camera_bind_group_layout,
                ],
                push_constant_ranges: &[],
            });
            let shader = wgpu::ShaderModuleDescriptor {
                label: Some("Light Shader"),
                source: wgpu::ShaderSource::Wgsl(include_str!("light.wgsl").into()),
            };
            create_render_pipeline(
                &device,
                &layout,
                surface_config.format,
                Some(texture::Texture::DEPTH_FORMAT),
                &[model::ModelVertex::desc(), InstanceRaw::desc()],
                shader,
                1,
            )
        };

        let res_dir = env::current_dir().unwrap().join("renderer/res");

        let mut light_sources: Vec<LightSourcePod> = vec![];

        let (world, mut models) = State::load_world(
            &device,
            &queue,
            &texture_bind_group_layout,
            &simple_uniform_layout,
            &simple_uniform_layout,
        );

        let light_model = model::Model::load(
            &device,
            &queue,
            &texture_bind_group_layout,
            &simple_uniform_layout,
            &simple_uniform_layout,
            res_dir.join("cube.obj"),
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0],
            &String::from("6b761f1a-c88c-436c-8834-494a541e084c"),
        )
       .unwrap();

        log!(log::Level::Warn, "Loaded {} models.", &models.len());

        for model in models.as_mut_slice() {
            for m in model.meshes.as_mut_slice() {
                // Populate light_sources
                let mat_structs = &model.materials[m.material];
                if m.material!= 0 {
                    match mat_structs {
                        MaterialStructs::EMISSION(mat) => {
                            light_sources.push(LightSourcePod {
                                ambient: mat.uniform.ambient,
                                constant: mat.uniform.constant,
                                diffuse: mat.uniform.diffuse,
                                linear: mat.uniform.linear,
                                specular: mat.uniform.specular,
                                quadratic: mat.uniform.quadratic,
                                position: m.mesh_uniform.position,
                                _padding: 0,
                                worldpos: m.mesh_uniform.worldpos,
                                _padding2: 0,
                                model_offset: m.mesh_uniform.model_offset,
                                _padding3: 0,
                                rot_mat_0: m.mesh_uniform.rot_mat_0,
                                _padding4: 0,
                                rot_mat_1: m.mesh_uniform.rot_mat_1,
                                _padding5: 0,
                                rot_mat_2: m.mesh_uniform.rot_mat_2,
                                _padding6: 0,
                            });
                        }
                        _ => {}
                    }
                }
            }
        }

        let light_sources_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
            label: Some("Light sources buffer"),
            contents: bytemuck::cast_slice(light_sources.as_slice()),
            usage: wgpu::BufferUsages::STORAGE | wgpu::BufferUsages::COPY_DST,
        });

        let light_sources_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
            layout: &simple_storage_layout,
            entries: &[wgpu::BindGroupEntry {
                binding: 0,
                resource: light_sources_buffer.as_entire_binding(),
            }],
            label: None,
        });

        Self {
            surface,
            device,
            queue,
            surface_config,
            size,
            render_pipeline,
            camera,
            camera_controller,
            instance_buffer,
            depth_texture,
            models,
            light_render_pipeline,
            platform,
            egui_rpass,
            window,
            clear_color: [0.0, 0.0, 0.0],
            light_model,
            world,
            texture_bind_group_layout,
            simple_uniform_layout,
            light_sources_buffer,
            light_sources_bind_group,
            only_show_emissive: false,
            ampel_index: -1,
            next_cycle: std::time::Duration::new(0, 0),
            green_duration: 10,
            yellow_duration: 5,
            red_yellow_duration: 5,
            all_red_duration: 5,
        }
    }

    fn load_world(
        device: &wgpu::Device,
        queue: &wgpu::Queue,
        texture_bind_group_layout: &wgpu::BindGroupLayout,
        model_bind_group_layout: &wgpu::BindGroupLayout,
        light_bind_group_layout: &wgpu::BindGroupLayout,
    ) -> (World, Vec<Model>) {
        let res_dir = env::current_dir().unwrap().join("renderer/res");
        let world: World = toml::from_str(
            &*fs::read_to_string(res_dir.join("world.toml")).expect("Couldn't open world.toml"),
        )
       .expect("Couldn't deserialize world.toml");

        let mut models = vec![];
        for m in world.scene.as_slice() {
            models.push(
                model::Model::load(
                    device,
                    queue,
                    texture_bind_group_layout,
                    model_bind_group_layout,
                    light_bind_group_layout,
                    res_dir.join(&m.model_file),
                    m.position,
                    m.rotation,
                    &m.id,
                )
               .expect(&*format!("Couldn't load model {}", &m.model_file)),
            );
        }

        (world, models)
    }

    fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) {
        if new_size.width > 0 && new_size.height > 0 {
            self.size = new_size;
            self.surface_config.width = new_size.width;
            self.surface_config.height = new_size.height;
            self.surface.configure(&self.device, &self.surface_config);
        }
        self.depth_texture = texture::Texture::create_depth_texture(
            &self.device,
            &self.surface_config,
            "depth_texture",
        );
        self.camera
           .update_aspect(new_size.width as f32, new_size.height as f32);
    }

    fn input(&mut self, event: &WindowEvent) -> bool {
        self.camera_controller.process_events(event)
    }

    fn find_model(models: &mut [Model], id