1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
use crate::material::{BasicMaterial, AlphaType, Material, texture::TextureSampler};
use super::shader_data::Data;
use super::TexturesPool;
use super::components::ProgramRef;
use rinecs::{EntitiesThreadLocal, ResourcesThreadLocal};
use generational_arena::Arena;
use rin::gl;
use super::pbr_material::into_gl_property;

impl super::Material for BasicMaterial{
    fn data(&self) -> Option<Data>{
        None
    }

    fn uniforms(&self, _: &EntitiesThreadLocal, textures: &TexturesPool) -> Vec<glin::program::Uniform>{
        let mut uniforms = if let Some(color) = self.color(){
            uniforms!{ color: *color }
        }else{
            vec![]
        };

        if let Some(tex) = self.texture(){
            let texture = &textures[tex.texture];
            if let Some(sampler) = tex.sampler.map(|s| &textures[s]){
                let sampler = texture.texture_sampler(sampler);
                uniforms.push(glin::program::uniform("tex", &(sampler, gl::TextureBindingPoints::BaseColor as u32)));
            }else{
                uniforms.push(glin::program::uniform("tex", &(texture, gl::TextureBindingPoints::BaseColor as u32)));
            }
        }

        uniforms
    }

    fn properties(&self) -> Vec<glin::Property>{
        self.properties().iter()
            .map(|p| into_gl_property(p))
            .chain(match self.alpha_type(){
                AlphaType::None => vec![],
                AlphaType::AlphaToCoverage => vec![glin::Property::SampleAlphaToCoverage(true)],
                AlphaType::Blending => vec![
                    glin::Property::Blend(true),
    		        glin::Property::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA),
                ],
                AlphaType::ScreenDoor => unimplemented!(),
                AlphaType::Threshold => unimplemented!(),
            })
            .collect()
    }

    fn program(&self, _: &EntitiesThreadLocal, programs: &mut Arena<glin::Program>, gl: &gl::Renderer) -> ProgramRef{
        if self.texture().is_some() {
            shaders::get_texture_model_program(gl, programs)
        }else if self.color().is_some(){
            shaders::get_color_model_program(gl, programs)
        }else{
            shaders::get_color_coords_model_program(gl, programs)
        }
    }

    fn textures(&self) -> Vec<&TextureSampler>{
        ::std::iter::empty()
            .chain(self.texture())
            .collect()
    }

    fn double_sided(&self) -> bool{
        false
    }

    fn alpha(&self) -> f32{
        self.color().map(|c| c.a).unwrap_or(1.)
    }

    fn update(&mut self, _: &EntitiesThreadLocal, _: &ResourcesThreadLocal) -> bool{
        //TODO: Reload if glsl-debug and return true if changed
        let changed = self.changed();
        self.reset_changed();
        changed
    }

    fn alpha_type(&self) -> AlphaType{
        AlphaType::Blending
    }
}

mod shaders{
    use glin;
    use crate::renderer::{
        default_attribute_bindings, default_glsl_version, use_model_as_attribute,
    };

    programref_cache!(glin::program::Settings{
        version: default_glsl_version(),
        extensions: vec![],
        precission: glin::program::ShaderPrecision::High,
        defines: vec![
            ("USE_GLOBAL_COLOR",  "0"),
            ("HAS_COLOR_TEXTURE", "0"),
            ("USE_BGR",           "0"),
            ("USE_MODEL_ATTR",    &(use_model_as_attribute() as u8).to_string()),
            ("USE_CAMERA_UBO",    "1"),
            ("NEEDS_CAMERA_INFO", "0"),
        ],
        shaders: vec![
            (glin::gl::VERTEX_SHADER, include_str!("shaders/basic_material.vs.glsl")),
            (glin::gl::FRAGMENT_SHADER, include_str!("shaders/basic_material.fs.glsl")),
        ],
        bindings: default_attribute_bindings(),
        base_path: "",
        includes: hash_map!{
            "mvp_uniforms.glsl" => {include_str!("shaders/mvp_uniforms.glsl")}
        },
    }, get_color_coords_model_program, SHADER_MODEL);


    programref_cache!(glin::program::Settings{
        version: default_glsl_version(),
        extensions: vec![],
        precission: glin::program::ShaderPrecision::High,
        defines: vec![
            ("USE_GLOBAL_COLOR",  "1"),
            ("HAS_COLOR_TEXTURE", "0"),
            ("USE_BGR",           "0"),
            ("USE_MODEL_ATTR",    &(use_model_as_attribute() as u8).to_string()),
            ("USE_CAMERA_UBO",    "1"),
            ("NEEDS_CAMERA_INFO", "0"),
        ],
        shaders: vec![
            (glin::gl::VERTEX_SHADER, include_str!("shaders/basic_material.vs.glsl")),
            (glin::gl::FRAGMENT_SHADER, include_str!("shaders/basic_material.fs.glsl")),
        ],
        bindings: default_attribute_bindings(),
        base_path: "",
        includes: hash_map!{
            "mvp_uniforms.glsl" => {include_str!("shaders/mvp_uniforms.glsl")}
        },
    }, get_color_model_program, COLOR_SHADER_MODEL);


    programref_cache!(glin::program::Settings{
        version: default_glsl_version(),
        extensions: vec![],
        precission: glin::program::ShaderPrecision::High,
        defines: vec![
            ("USE_GLOBAL_COLOR",  "0"),
            ("HAS_COLOR_TEXTURE", "1"),
            ("USE_BGR",           "0"),
            ("USE_MODEL_ATTR",    &(use_model_as_attribute() as u8).to_string()),
            ("USE_CAMERA_UBO",    "1"),
            ("NEEDS_CAMERA_INFO", "0"),
        ],
        shaders: vec![
            (glin::gl::VERTEX_SHADER, include_str!("shaders/basic_material.vs.glsl")),
            (glin::gl::FRAGMENT_SHADER, include_str!("shaders/basic_material.fs.glsl")),
        ],
        bindings: default_attribute_bindings(),
        base_path: "",
        includes: hash_map!{
            "mvp_uniforms.glsl" => {include_str!("shaders/mvp_uniforms.glsl")}
        },
    }, get_texture_model_program, TEXTURE_SHADER_MODEL);


    programref_cache!(glin::program::Settings{
        version: default_glsl_version(),
        extensions: vec![],
        precission: glin::program::ShaderPrecision::High,
        defines: vec![
            ("USE_GLOBAL_COLOR",  "0"),
            ("HAS_COLOR_TEXTURE", "1"),
            ("USE_BGR",           "1"),
            ("USE_MODEL_ATTR",    &(use_model_as_attribute() as u8).to_string()),
            ("USE_CAMERA_UBO",    "1"),
            ("NEEDS_CAMERA_INFO", "0"),
        ],
        shaders: vec![
            (glin::gl::VERTEX_SHADER, include_str!("shaders/basic_material.vs.glsl")),
            (glin::gl::FRAGMENT_SHADER, include_str!("shaders/basic_material.fs.glsl")),
        ],
        bindings: default_attribute_bindings(),
        base_path: "",
        includes: hash_map!{
            "mvp_uniforms.glsl" => {include_str!("shaders/mvp_uniforms.glsl")}
        },
    }, get_texture_bg_model_program, TEXTURE_BGR_SHADER_MODEL);
}