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
use glin;
use graphics::{self, Vertex3DNormal};
use super::{Renderer3d, CreationContext, CreationProxy, Render3d, Renderer};
use glin::CreationContext as GlinCreationContext;
use std::borrow::Borrow;
use glin::RenderSurface;
pub struct Skybox<C = glin::CubeMap>{
cubemap: C,
geometry: glin::SimpleVao<Vertex3DNormal>,
level: f32,
}
pub struct Builder{
pub(crate) gl: CreationProxy
}
impl Builder{
pub fn from_cubemap<C: Borrow<glin::CubeMap>>(&self, cubemap: C, radius: f32) -> Skybox<C> {
let sphere = graphics::sphere(radius, 30, 30);
let geometry = self.gl.to_simple_vao(&sphere).unwrap();
Skybox{
cubemap,
geometry,
level: 0.,
}
}
pub fn from_cubemap_level<C: Borrow<glin::CubeMap>>(&self, cubemap: C, radius: f32, level: f32) -> Skybox<C> {
let sphere = graphics::sphere(radius, 30, 30);
let geometry = self.gl.to_simple_vao(&sphere).unwrap();
Skybox{
cubemap,
geometry,
level,
}
}
pub fn from_cubemap_faces<I: glin::Image>(&self, faces: &glin::cubemap::Faces<I>, radius: f32) -> Skybox {
let cubemap = self.gl.new_cubemap().from_faces(faces).unwrap();
let sphere = graphics::sphere(radius, 30, 30);
let geometry = self.gl.to_simple_vao(&sphere).unwrap();
Skybox{
cubemap,
geometry,
level: 0.,
}
}
pub fn from_cubemap_image<I: glin::CubemapImage>(&self, image: &I, radius: f32) -> Skybox {
let cubemap = self.gl.new_cubemap().from_cubemap_image(image).unwrap();
let sphere = graphics::sphere(radius, 30, 30);
let geometry = self.gl.to_simple_vao(&sphere).unwrap();
Skybox{
cubemap,
geometry,
level: 0.,
}
}
pub fn from_cubemap_image_level<I: glin::CubemapImage>(&self, image: &I, radius: f32, level: f32) -> Skybox {
let cubemap = self.gl.new_cubemap().from_cubemap_image(image).unwrap();
let sphere = graphics::sphere(radius, 30, 30);
let geometry = self.gl.to_simple_vao(&sphere).unwrap();
Skybox{
cubemap,
geometry,
level,
}
}
}
impl Skybox{
pub fn level(&self) -> f32{
self.level
}
pub fn set_level(&mut self, level: f32){
self.level = level;
}
}
impl<C: Borrow<glin::CubeMap>> Render3d for Skybox<C>{
fn render<R: RenderSurface>(&self, gl: &Renderer<R>){
let program = shaders::get_program(gl);
let uniforms = uniforms!{
cubemap_tex: self.cubemap.borrow(),
level: self.level,
};
let properties = &[
glin::Property::CullFace(Some(glin::gl::FRONT)),
glin::Property::DepthFunc(glin::gl::LEQUAL),
#[cfg(feature="gl")]
glin::Property::TextureCubemapSeamless(true),
];
gl.with_properties(properties)
.draw_vao(&self.geometry, program, &uniforms);
}
}
mod shaders{
use glin;
program_cache!(glin::program::Settings{
version: ::gl::default_glsl_version(),
precission: glin::program::ShaderPrecision::High,
defines: vec![],
extensions: vec![],
bindings: ::gl::default_attribute_bindings(),
shaders: vec![
(glin::gl::VERTEX_SHADER, include_str!("shaders/skybox.vs.glsl")),
(glin::gl::FRAGMENT_SHADER, include_str!("shaders/skybox.fs.glsl")),
],
.. Default::default()
}, get_program, SHADER);
}