Raw File
ENSnano, a 3d graphical application for DNA nanostructures.
    Copyright (C) 2021  Nicolas Levy <nicolaspierrelevy@gmail.com> and Nicolas Schabanel <nicolas.schabanel@ens-lyon.fr>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.
use crate::utils::create_buffer_with_data;
use iced_wgpu::wgpu;
use ultraviolet::Vec3;
use wgpu::{BindGroup, BindGroupLayout, Device};

#[derive(Debug, Copy, Clone)]
pub struct Light {
    position: Vec3,
    // Due to uniforms requiring 16 byte (4 float) spacing, we need to use a padding field here
    _padding: u32,
    color: Vec3,

impl Light {
    pub fn new(position: [f32; 3], color: [f32; 3]) -> Self {
        Self {
            position: position.into(),
            _padding: 0,
            color: color.into(),

pub fn create_light(device: &Device) -> (BindGroup, BindGroupLayout) {
    let light = Light::new([0.0, 0.0, 1000.0], [1.0, 1.0, 1.0]);

    let light_buffer = create_buffer_with_data(
        wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,

    let light_bind_group_layout =
        device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
            entries: &[wgpu::BindGroupLayoutEntry {
                binding: 0,
                visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
                ty: wgpu::BindingType::Buffer {
                    ty: wgpu::BufferBindingType::Uniform,
                    has_dynamic_offset: false,
                    min_binding_size: None,
                count: None,
            label: Some("light_bind_group_layout"),

    let light_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
        layout: &light_bind_group_layout,
        entries: &[wgpu::BindGroupEntry {
            binding: 0,
            resource: wgpu::BindingResource::Buffer {
                buffer: &light_buffer,
                offset: 0,
                size: None,
        label: Some("light bind group"),
    (light_bind_group, light_bind_group_layout)

unsafe impl bytemuck::Zeroable for Light {}
unsafe impl bytemuck::Pod for Light {}
back to top