gdritter repos utmyen / 3ec590d
Refactored drawing code a little bit Getty Ritter 7 years ago
4 changed file(s) with 133 addition(s) and 162 deletion(s). Collapse all Expand all
1 #version 140
2
3 in vec3 o_nrm;
4 in vec2 o_tex;
5
6 uniform vec3 u_light;
7 uniform sampler2D tex;
8
9 out vec4 color;
10
11 void main() {
12 float brightness = dot(normalize(o_nrm), normalize(u_light));
13 float factor = 0.5 + (brightness * 0.5);
14 color = texture(tex, o_tex) * factor;
15 }
1 #version 140
2
3 in vec3 pos;
4 in vec3 nrm;
5 in vec2 tex;
6
7 uniform mat4 perspective;
8 uniform mat4 matrix;
9
10 out vec3 o_nrm;
11 out vec2 o_tex;
12
13 void main() {
14 o_nrm = transpose(inverse(mat3(matrix))) * nrm;
15 o_tex = tex;
16 gl_Position = perspective * matrix * vec4(pos, 1.0);
17 }
11 extern crate glium;
22
3 use glium::{DisplayBuild, Display, Frame, Surface};
4 use glium::glutin::WindowBuilder;
3 use glium::{DisplayBuild, Display, Frame, Program, Surface};
4 use glium::glutin::{Event,WindowBuilder};
5 use glium::texture::{RawImage2d,Texture2d};
56
6 struct Graphics {
7 use model::Model;
8
9 const VERTEX_SHADER: &'static str = include_str!("../data/shaders/vertex.glsl");
10
11 const FRAGMENT_SHADER: &'static str = include_str!("../data/shaders/fragment.glsl");
12
13 pub struct Graphics {
714 disp: Display,
15 rt: f32,
16 px: f32,
17 py: f32,
18 pz: f32,
19 light: [f32;3],
20 model: Model,
21 program: Program,
22 tex: Texture2d,
823 }
924
1025 impl Graphics {
11 fn new() -> Self {
26 pub fn new(m: Model, t: RawImage2d<u8>) -> Self {
1227 let disp = WindowBuilder::new()
1328 .with_title(format!("utmyen"))
1429 .with_depth_buffer(24)
1530 .build_glium()
1631 .unwrap();
17 Graphics { disp: disp }
32 let program = Program::from_source(
33 &disp,
34 VERTEX_SHADER,
35 FRAGMENT_SHADER,
36 None).unwrap();
37 let tex = Texture2d::new(&disp, t).unwrap();
38 Graphics {
39 disp: disp,
40 rt: 0.0,
41 px: 0.0,
42 py: 0.0,
43 pz: 0.0,
44 light: [-1.0, 0.4, 0.9f32],
45 model: m,
46 program: program,
47 tex: tex,
48 }
1849 }
1950
20 fn run(&mut self) {
21 while (Target { frame: self.disp.draw() }).step() {}
51 pub fn run(&mut self) {
52 loop {
53 let mut tgt = self.disp.draw();
54 if ! (Target { frame: &mut tgt }).step(self) {
55 return;
56 }
57 tgt.finish().unwrap();
58
59 for ev in self.disp.poll_events() {
60 match ev {
61 Event::Closed => return,
62 Event::KeyboardInput(_, n, _) =>
63 match n {
64 9 => return,
65 24 => self.rt -= 0.1,
66 25 => self.py -= DX,
67 26 => self.rt += 0.1,
68 38 => self.px -= DX,
69 39 => self.py += DX,
70 40 => self.px += DX,
71 44 => self.pz -= DX,
72 45 => self.pz += DX,
73 _ => {},
74 },
75 _ => {},
76 }
77 }
78 }
2279 }
2380 }
2481
25 struct Target {
26 frame: Frame,
82 const DX: f32 = 0.001;
83 const SX: f32 = 0.01;
84
85 struct Target<'a> {
86 frame: &'a mut Frame,
2787 }
2888
29 impl Target {
30 fn step(&mut self) -> bool {
31 let light = [-1.0, 0.4, 0.9f32];
89 impl<'a> Target<'a> {
90 fn step(&mut self, g: &mut Graphics) -> bool {
3291 let uniforms = uniform! {
3392 perspective: self.perspective(),
34 u_light: light,
35 matrix: self.matrix(),
93 u_light: g.light,
94 matrix: self.matrix(g),
95 tx: &g.tex,
3696 };
3797
3898 let params = glium::DrawParameters {
43103 },
44104 .. Default::default()
45105 };
106
107 let vbuf = g.model.get_vbuf(&g.disp);
108 let idxs = g.model.get_ibuf(&g.disp);
109 self.frame.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
110 self.frame.draw(&vbuf,
111 &idxs,
112 &g.program,
113 &uniforms,
114 &params).unwrap();
46115 return true;
47116 }
48117
49 fn matrix(&self) -> [[f32;4];4] {
50 let rt = 0.0f32;
51 let sx = 0.0f32;
52 let px = 0.0f32;
53 let py = 0.0f32;
54 let pz = 0.0f32;
55 [ [ rt.cos() * sx, 0.0, -rt.sin() * sx, 0.0 ],
56 [ 0.0, sx, 0.0, 0.0 ],
57 [ rt.sin() * sx, 0.0, rt.cos() * sx, 0.0 ],
58 [ px, pz, py, sx ]
118 fn matrix(&self, g: &Graphics) -> [[f32;4];4] {
119 let rt = g.rt;
120 let px = g.px;
121 let py = g.py;
122 let pz = g.pz;
123 [ [ rt.cos() * SX, 0.0, -rt.sin() * SX, 0.0 ],
124 [ 0.0, SX, 0.0, 0.0 ],
125 [ rt.sin() * SX, 0.0, rt.cos() * SX, 0.0 ],
126 [ px, pz, py, SX ]
59127 ]
60128 }
61129
66 mod model;
77 mod graphics;
88
9 use glium::{DisplayBuild, Program, Surface};
10 use glium::glutin::Event;
11 use glium::glutin::WindowBuilder;
12 use glium::texture::Texture2d;
9 use glium::texture::{RawImage2d};
1310
1411 fn sample() -> model::Model {
1512 let file = std::env::args().nth(1)
1714 model::Model::load_from_file(&file).unwrap()
1815 }
1916
20 fn sample_texture(display: &glium::Display) -> Texture2d {
17 fn sample_texture<'a>() -> RawImage2d<'a, u8> {
2118 use std::io::Cursor;
22 let img = image::load(Cursor::new(&include_bytes!("/home/gdritter/pictures/cube-uv.png")[..]),
23 image::PNG).unwrap().to_rgba();
19 let img = image::load(
20 Cursor::new(&include_bytes!("/home/gdritter/pictures/rainbow.png")[..]),
21 image::PNG).unwrap().to_rgba();
2422 let dims = img.dimensions();
2523 let img = glium::texture::RawImage2d::from_raw_rgba_reversed(img.into_raw(), dims);
26 Texture2d::new(display, img).unwrap()
24 img
2725 }
28
29 const VERTEX_SHADER: &'static str = r#"
30 #version 140
31
32 in vec3 pos;
33 in vec3 nrm;
34 in vec2 tex;
35
36 uniform mat4 perspective;
37 uniform mat4 matrix;
38
39 out vec3 o_nrm;
40 out vec2 o_tex;
41
42 void main() {
43 o_nrm = transpose(inverse(mat3(matrix))) * nrm;
44 o_tex = tex;
45 gl_Position = perspective * matrix * vec4(pos, 1.0);
46 }
47 "#;
48
49 const FRAGMENT_SHADER: &'static str = r#"
50 #version 140
51
52 in vec3 o_nrm;
53 in vec2 o_tex;
54
55 uniform vec3 u_light;
56 uniform sampler2D tex;
57
58 out vec4 color;
59
60 void main() {
61 float brightness = dot(normalize(o_nrm), normalize(u_light));
62 float factor = 0.5 + (brightness * 0.5);
63 color = texture(tex, o_tex) * factor;
64 }
65 "#;
6626
6727 fn main() {
6828 let md = sample();
69 let display = WindowBuilder::new()
70 .with_title(format!("utymen"))
71 .with_depth_buffer(24)
72 .build_glium()
73 .unwrap();
29 let tex = sample_texture();
7430
75 let vbuf = md.get_vbuf(&display);
76 let idxs = md.get_ibuf(&display);
77 let tx = md.get_tex(&display).unwrap_or(sample_texture(&display));
78
79 let program = Program::from_source(
80 &display,
81 VERTEX_SHADER,
82 FRAGMENT_SHADER,
83 None).unwrap();
84
85 let light = [-1.0, 0.4, 0.9f32];
86 let mut px = 0f32;
87 let mut py = 0.02f32;
88 let mut pz = 0.0f32;
89 let mut rt = 0f32;
90 let dx = 0.001;
91 let sx = 0.01f32;
92
93 loop {
94 let mut target = display.draw();
95
96 let perspective = {
97 let (width, height) = target.get_dimensions();
98 let aspect_ratio = height as f32 / width as f32;
99
100 let fov: f32 = 3.141592 / 3.0;
101 let zfar = 1024.0;
102 let znear = 0.1;
103
104 let f = 1.0 / (fov / 2.0).tan();
105
106 [
107 [f * aspect_ratio , 0.0, 0.0 , 0.0],
108 [ 0.0 , f , 0.0 , 0.0],
109 [ 0.0 , 0.0, (zfar+znear)/(zfar-znear) , 1.0],
110 [ 0.0 , 0.0, -(2.0*zfar*znear)/(zfar-znear), 0.0],
111 ]
112 };
113
114 let uniforms = uniform! {
115 perspective: perspective,
116 u_light: light,
117 tex: &tx,
118 matrix: [ [ rt.cos() * sx, 0.0, -rt.sin() * sx, 0.0 ],
119 [ 0.0, sx, 0.0, 0.0 ],
120 [ rt.sin() * sx, 0.0, rt.cos() * sx, 0.0 ],
121 [ px, pz, py, sx ]
122 ]
123 };
124
125 let params = glium::DrawParameters {
126 depth: glium::Depth {
127 test: glium::draw_parameters::DepthTest::IfLess,
128 write: true,
129 .. Default::default()
130 },
131 .. Default::default()
132 };
133
134 target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
135 target.draw(&vbuf,
136 &idxs,
137 &program,
138 &uniforms,
139 &params).unwrap();
140 target.finish().unwrap();
141
142 for ev in display.poll_events() {
143 match ev {
144 Event::Closed => return,
145 Event::KeyboardInput(_, n, _) =>
146 match n {
147 9 => return,
148 24 => rt -= 0.1,
149 25 => py -= dx,
150 26 => rt += 0.1,
151 38 => px -= dx,
152 39 => py += dx,
153 40 => px += dx,
154 44 => pz -= dx,
155 45 => pz += dx,
156 _ => {},
157 },
158 _ => {},
159 }
160 }
161 }
31 let mut g = graphics::Graphics::new(md, tex);
32 g.run();
16233 }