gdritter repos chenoska / 03e569d
Start using normal map in drawing as well Getty Ritter 5 years ago
5 changed file(s) with 165 addition(s) and 32 deletion(s). Collapse all Expand all
33 in vec2 t_uv;
44 out vec4 out_color;
55
6 uniform sampler2D nrm;
67 uniform sampler2D tex;
78
89 void main() {
9 out_color = texture(tex, t_uv);
10 vec4 light_dir = normalize(vec4(1.0, 1.0, 1.0, 1.0));
11
12 vec4 pixel = texture(tex, t_uv);
13 vec4 normal = texture(nrm, t_uv);
14
15 float l = max(dot(light_dir, normalize(normal)), 0.0);
16 vec3 col = vec3(pixel) * pow(l, 4.0);
17 out_color = vec4(col, 1.0);
1018 }
77
88 use board::coord::{Coord, Pair};
99
10 const BOARD_WIDTH: u16 = 16;
11 const BOARD_HEIGHT: u16 = 12;
12 const TILE_SIZE: u16 = 24;
13 const HALF_TILE_SIZE: f32 = 24.0;
10 pub const BOARD_WIDTH: u16 = 16;
11 pub const BOARD_HEIGHT: u16 = 12;
12 pub const TILE_SIZE: u16 = 24;
13 pub const HALF_TILE_SIZE: f32 = 24.0;
1414
1515 #[derive(PartialEq, Eq, Debug)]
1616 pub struct Tile {
17 sprite: Coord,
17 pub sprite: Coord,
1818 }
1919
2020 impl Tile {
7676 }
7777 }
7878
79 /// Get the set of entities present at the board location that
80 /// this entity is currently looking at
7981 fn get_focus<'a>(&self, b: &'a Board) -> &'a Vec<Entity> {
8082 b.get_entity(self.game_coords())
8183 }
8284
85 /// Attempt to move this entity, figuring out whether it can move
86 /// and how far to move if so. This does collision detection based
87 /// on the grid and also does some nudging to push the player
88 /// towards being grid-aligned.
8389 fn mv(&self, b: &Board) -> Delta {
8490 if self.dir == Pair::zero() {
8591 return Delta::zero();
96102 delta.dy = self.dir.y;
97103 } else if self.check_collision(b, Pair { y: 0.0, ..self.dir }) {
98104 delta.dx = self.dir.x;
99 } else {
100 // zeroes are fine
101 };
102
105 }
106
107 // if we're not aligned along a half-square, we should try to
108 // push towards aligning there!
103109 if self.dir.x.eq(&0.0) && !self.dir.y.eq(&0.0) {
104110 let xm = self.loc.x % HALF_TILE_SIZE;
105 if 0.0 < xm && xm < HALF_TILE_SIZE && self.check_collision(b, Pair { x: -1.0, y: 0.0 }) {
111 if 0.0 < xm &&
112 xm < HALF_TILE_SIZE &&
113 self.check_collision(b, Pair { x: -1.0, y: 0.0 }) {
106114 delta.dx = delta.dx - 1.0;
107 } else if xm >= HALF_TILE_SIZE && self.check_collision(b, Pair { x: 1.0, y: 0.0 }) {
115 } else if xm >= HALF_TILE_SIZE &&
116 self.check_collision(b, Pair { x: 1.0, y: 0.0 }) {
108117 delta.dx = delta.dx + 1.0;
109118 }
110119 } else if !self.dir.x.eq(&0.0) && self.dir.y.eq(&0.0) {
119128 delta
120129 }
121130
131 /// Get this entity's current location in terms of the game
132 /// coordinates
122133 fn game_coords(&self) -> Coord {
123134 self.loc.to_discrete(TILE_SIZE as f32)
124135 }
125136 }
126137
138 /// A `Delta` is the amount of calculated movement found for a given
139 /// entity when it attempts to move.
127140 #[derive(Debug)]
128141 struct Delta {
129142 dx: f32,
149162 }
150163
151164 impl<T> Grid<T> {
152 pub fn new_with<F: Fn(u16, u16) -> T>(width: u16, height: u16, elem: F) -> Grid<T> {
165 pub fn new_with<F>(
166 width: u16,
167 height: u16,
168 elem: F,
169 ) -> Grid<T>
170 where F: Fn(u16, u16) -> T
171 {
153172 let mut elems = Vec::with_capacity((width * height) as usize);
154173 for y in 0..height {
155174 for x in 0..width {
210229 &self.entity[c]
211230 }
212231
232 /// Take a Tiled-format map and ingest it into our internal map
233 /// format. (Might be a good idea eventually to use a custom
234 /// format, but Tiled is great for now.)
213235 pub fn from_tiled(map: &tiled::Map) -> Board {
214236 fn offset_from_gid(n: u32) -> Option<Coord> {
215237 if n < 1 || n > 1024 {
237259 });
238260 Board { base, entity }
239261 }
240 }
262
263 pub fn each_tile<F>(&self, mut f: F)
264 where F: FnMut(usize, usize, &Tile)
265 {
266 for x in 0..self.base.width {
267 for y in 0..self.base.height {
268 f(x as usize, y as usize, &self.base[Pair::new(x, y)]);
269 }
270 }
271 }
272 }
229229 })
230230 }
231231
232 pub fn set_texture(&self, s: &str, t: &Texture) -> Result<(), Error>{
233 unsafe {
234 gl::ActiveTexture(gl::TEXTURE0);
235 gl::BindTexture(gl::TEXTURE_2D, t.idx);
232 pub fn set_texture(
233 &self,
234 s: &str,
235 tex: &Texture,
236 n: i32,
237 ) -> Result<(), Error>{
238 unsafe {
239 gl::ActiveTexture(match n {
240 0 => gl::TEXTURE0,
241 1 => gl::TEXTURE1,
242 2 => gl::TEXTURE2,
243 _ => panic!("too many textures, i guess"),
244 });
245 gl::BindTexture(gl::TEXTURE_2D, tex.idx);
236246 let t = gl::GetUniformLocation(
237247 self.p,
238248 ffi::CString::new(s)?.as_ptr(),
239249 );
240 gl::Uniform1i(t, 0);
250 gl::Uniform1i(t, n);
241251 }
242252 Ok(())
243253 }
376386 pub fn draw(&self) {
377387 self.bind();
378388 unsafe {
379 gl::DrawArrays(gl::TRIANGLE_STRIP, 0, self.len as i32);
389 gl::DrawArrays(gl::TRIANGLES, 0, self.len as i32);
380390 }
381391 self.unbind();
382392 }
11 #![allow(dead_code)]
22 use gl;
33 use std::mem;
4
5 use board;
46
57 /// A trait defined on each type used to create a VBO
68 pub trait Vertex {
1012 fn normal_location() -> Option<(i32, i32)>;
1113 }
1214
15 #[derive(Debug, PartialEq)]
1316 pub struct V2D {
1417 pub x: gl::GLfloat,
1518 pub y: gl::GLfloat,
8487 None
8588 }
8689 }
90
91 pub fn make_grid(w: usize, h: usize) -> Vec<V2D> {
92 let mut vec = Vec::with_capacity(w * h * 4);
93 let x_stride = 2.0 / w as f32;
94 let y_stride = 2.0 / h as f32;
95 for x in 0..w {
96 for y in 0..h {
97 let x = x as f32;
98 let y = y as f32;
99 let o = 1.0 / 32.0;
100 vec.extend(vec![
101 V2D { x: x_stride * (x + 1.0) - 1.0, y: y_stride * y - 1.0, u: o , v: o },
102 V2D { x: x_stride * x - 1.0, y: y_stride * y - 1.0, u: 0.0, v: o },
103 V2D { x: x_stride * (x + 1.0) - 1.0, y: y_stride * (y + 1.0) - 1.0, u: o, v: 0.0 },
104 V2D { x: x_stride * x - 1.0, y: y_stride * (y + 1.0) - 1.0, u: 0.0, v: 0.0 },
105 ]);
106 }
107 }
108 vec
109 }
110
111
112 pub fn make_grid_with(w: usize, h: usize, b: &board::Board) -> Vec<V2D> {
113 let mut vec = Vec::with_capacity(w * h * 4);
114 let x_stride = 2.0 / w as f32;
115 let y_stride = 2.0 / h as f32;
116 let o_stride = 1.0 / 32.0;
117 b.each_tile(|x, y, t| {
118 let x = x as f32;
119 let y = h as f32 - y as f32 - 1.0;
120 let tx = (t.sprite.x as f32) * o_stride;
121 let ty = (t.sprite.y as f32) * o_stride;
122 vec.extend(vec![
123 V2D {
124 x: x_stride * (x + 1.0) - 1.0,
125 y: y_stride * y - 1.0,
126 u: tx + o_stride,
127 v: ty + o_stride,
128 },
129 V2D {
130 x: x_stride * x - 1.0,
131 y: y_stride * y - 1.0,
132 u: tx,
133 v: ty + o_stride,
134 },
135 V2D {
136 x: x_stride * (x + 1.0) - 1.0,
137 y: y_stride * (y + 1.0) - 1.0,
138 u: tx + o_stride,
139 v: ty,
140 },
141
142 V2D {
143 x: x_stride * x - 1.0,
144 y: y_stride * y - 1.0,
145 u: tx,
146 v: ty + o_stride,
147 },
148 V2D {
149 x: x_stride * (x + 1.0) - 1.0,
150 y: y_stride * (y + 1.0) - 1.0,
151 u: tx + o_stride,
152 v: ty,
153 },
154 V2D {
155 x: x_stride * x - 1.0,
156 y: y_stride * (y + 1.0) - 1.0,
157 u: tx,
158 v: ty,
159 },
160 ]);
161 });
162 vec
163 }
1313 // pub mod audio;
1414
1515 use graphics as gfx;
16 use graphics::vertices::V2D;
1716
18 static TILE_DATA: [V2D; 4] = [
19 V2D { x: 0.5, y: -0.5, u: 1.0, v: 1.0 },
20 V2D { x: -0.5, y: -0.5, u: 0.0, v: 1.0 },
21 V2D { x: 0.5, y: 0.5, u: 1.0, v: 0.0 },
22 V2D { x: -0.5, y: 0.5, u: 0.0, v: 0.0 },
23 ];
17 // static TILE_DATA: [V2D; 4] = [
18 // V2D { x: 0.5, y: -0.5, u: 1.0, v: 1.0 },
19 // V2D { x: -0.5, y: -0.5, u: 0.0, v: 1.0 },
20 // V2D { x: 0.5, y: 0.5, u: 1.0, v: 0.0 },
21 // V2D { x: -0.5, y: 0.5, u: 0.0, v: 0.0 },
22 // ];
2423
2524 // Shader sources
2625 static VS_SRC: &'static str = include_str!("../shaders/basic_vertex.glsl");
3130 /// event loop
3231 pub fn main_loop() -> Result<(), gfx::Error> {
3332 let t = tiled::parse_file(
34 std::path::Path::new("/home/gdritter/projects/animaltransiro/areas/main.tmx")
33 std::path::Path::new("/home/gdritter/projects/animaltransiro/areas/west.tmx")
3534 ).unwrap();
3635 let board = board::Board::from_tiled(&t);
3736
3837 println!("{:#?}", board);
3938
40 return Ok(());
4139 // let audio = audio::Audio::init()?;
4240 let window = gfx::Window::create()?;
4341
4644 gfx::Shader::compile(gfx::ShaderType::Fragment, FS_SRC)?,
4745 ])?;
4846
49 let tex = gfx::Texture::new_from_png("sample.png")?;
47 let tex = gfx::Texture::new_from_png("/home/gdritter/projects/animaltransiro/tiles/spritesheet.png")?;
48 let nrm = gfx::Texture::new_from_png("/home/gdritter/projects/animaltransiro/tiles/spritesheet-normal.png")?;
5049
50 let tile_data = graphics::vertices::make_grid_with(
51 board::BOARD_WIDTH as usize,
52 board::BOARD_HEIGHT as usize,
53 &board,
54 );
5155 let vbo = gfx::VertexBuffer::new_array_buffer(
5256 gfx::VertexArray::new(&program),
53 &TILE_DATA,
57 &tile_data,
5458 );
5559
5660 program.use_program();
5963 vbo.bind_position("position")?;
6064 vbo.bind_uv("uv")?;
6165 vbo.unbind();
66
67 program.set_texture("tex", &tex, 0).unwrap();
68 program.set_texture("nrm", &nrm, 1).unwrap();
6269
6370 window.run(|event| {
6471 use glutin::{ControlFlow, Event, WindowEvent, VirtualKeyCode};
8592 }
8693
8794 gfx::clear();
88 program.set_texture("tex", &tex).unwrap();
8995 vbo.draw();
9096
9197 ControlFlow::Continue