Draw the upper and lower stuff in two VBOs
Getty Ritter
7 years ago
| 14 | 14 | |
| 15 | 15 | float l = max(dot(light_dir, normalize(normal)), 0.0); |
| 16 | 16 | vec3 col = vec3(pixel) * pow(l, 4.0); |
| 17 | if (pixel.a < 0.1) { | |
| 18 | discard; | |
| 19 | } | |
| 17 | 20 | out_color = vec4(col, 1.0); |
| 18 | 21 | } |
| 21 | 21 | fn passable(&self) -> bool { |
| 22 | 22 | true |
| 23 | 23 | } |
| 24 | } | |
| 25 | ||
| 26 | #[derive(PartialEq, Eq, Debug)] | |
| 27 | pub struct Esse { | |
| 28 | pub sprite: Coord, | |
| 24 | 29 | } |
| 25 | 30 | |
| 26 | 31 | #[derive(Debug)] |
| 78 | 83 | |
| 79 | 84 | /// Get the set of entities present at the board location that |
| 80 | 85 | /// this entity is currently looking at |
| 81 |
fn get_focus<'a>(&self, b: &'a Board) -> &'a Vec<E |
|
| 86 | fn get_focus<'a>(&self, b: &'a Board) -> &'a Vec<Esse> { | |
| 82 | 87 | b.get_entity(self.game_coords()) |
| 83 | 88 | } |
| 84 | 89 | |
| 208 | 213 | #[derive(Debug)] |
| 209 | 214 | pub struct Board { |
| 210 | 215 | base: Grid<Tile>, |
| 211 |
entity: Grid<Vec<E |
|
| 216 | entity: Grid<Vec<Esse>>, | |
| 212 | 217 | } |
| 213 | 218 | |
| 214 | 219 | |
| 221 | 226 | &mut self.base |
| 222 | 227 | } |
| 223 | 228 | |
| 224 |
pub fn e |
|
| 229 | pub fn esses(&mut self) -> &mut Grid<Vec<Esse>> { | |
| 225 | 230 | &mut self.entity |
| 226 | 231 | } |
| 227 | 232 | |
| 228 |
pub fn get_entity(&self, c: Coord) -> &Vec<E |
|
| 233 | pub fn get_entity(&self, c: Coord) -> &Vec<Esse> { | |
| 229 | 234 | &self.entity[c] |
| 230 | 235 | } |
| 231 | 236 | |
| 250 | 255 | }); |
| 251 | 256 | |
| 252 | 257 | let entity = Grid::new_with(w, h, |x, y| { |
| 253 | let _o1 = map.layers[1].tiles[y as usize][x as usize]; | |
| 254 | let _o2 = map.layers[1].tiles[y as usize][x as usize]; | |
| 255 | vec![ | |
| 256 | Entity::blank(), | |
| 257 | Entity::blank(), | |
| 258 | ] | |
| 258 | let o1 = map.layers[1].tiles[y as usize][x as usize]; | |
| 259 | let o2 = map.layers[2].tiles[y as usize][x as usize]; | |
| 260 | let mut v = Vec::new(); | |
| 261 | if let Some(coord) = offset_from_gid(o1) { | |
| 262 | v.push(Esse { sprite: coord }); | |
| 263 | } | |
| 264 | if let Some(coord) = offset_from_gid(o2) { | |
| 265 | v.push(Esse { sprite: coord }); | |
| 266 | } | |
| 267 | v | |
| 259 | 268 | }); |
| 260 | 269 | Board { base, entity } |
| 261 | 270 | } |
| 269 | 278 | } |
| 270 | 279 | } |
| 271 | 280 | } |
| 272 | } | |
| 281 | ||
| 282 | pub fn each_esse<F>(&self, mut f: F) | |
| 283 | where F: FnMut(usize, usize, &Esse) | |
| 284 | { | |
| 285 | for x in 0..self.base.width { | |
| 286 | for y in 0..self.base.height { | |
| 287 | for e in self.entity[Pair::new(x, y)].iter() { | |
| 288 | f(x as usize, y as usize, &e); | |
| 289 | } | |
| 290 | } | |
| 291 | } | |
| 292 | } | |
| 293 | } | |
| 16 | 16 | /// Clear the screen to a generic color |
| 17 | 17 | pub fn clear() { |
| 18 | 18 | unsafe { |
| 19 | gl::Enable(gl::BLEND); | |
| 20 | gl::BlendFunc(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA); | |
| 19 | 21 | gl::ClearColor(0.3, 0.3, 0.3, 1.0); |
| 20 | 22 | gl::Clear(gl::COLOR_BUFFER_BIT); |
| 21 | 23 | } |
| 40 | 42 | unsafe { gl_window.make_current() }?; |
| 41 | 43 | |
| 42 | 44 | gl::load_with(|symbol| gl_window.get_proc_address(symbol) as *const _); |
| 43 | ||
| 44 | 45 | Ok(Window { events, gl_window }) |
| 45 | 46 | } |
| 46 | 47 | |
| 233 | 234 | &self, |
| 234 | 235 | s: &str, |
| 235 | 236 | 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"), | |
| 237 | n: u32, | |
| 238 | ) -> Result<(), Error> { | |
| 239 | unsafe { | |
| 240 | gl::ActiveTexture(if n < gl::MAX_COMBINED_TEXTURE_IMAGE_UNITS { | |
| 241 | gl::TEXTURE0 + n | |
| 242 | } else { | |
| 243 | panic!("Texture unit {} too high", n) | |
| 244 | 244 | }); |
| 245 | 245 | gl::BindTexture(gl::TEXTURE_2D, tex.idx); |
| 246 | 246 | let t = gl::GetUniformLocation( |
| 247 | 247 | self.p, |
| 248 | 248 | ffi::CString::new(s)?.as_ptr(), |
| 249 | 249 | ); |
| 250 |
gl::Uniform1i(t, n |
|
| 250 | gl::Uniform1i(t, n as i32); | |
| 251 | 251 | } |
| 252 | 252 | Ok(()) |
| 253 | 253 | } |
| 119 | 119 | let y = h as f32 - y as f32 - 1.0; |
| 120 | 120 | let tx = (t.sprite.x as f32) * o_stride; |
| 121 | 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 |
|
|
| 122 | vec.extend(mk_quad((x, y), (x_stride, y_stride), (tx, ty), o_stride)); | |
| 161 | 123 | }); |
| 162 | 124 | vec |
| 163 | 125 | } |
| 126 | ||
| 127 | ||
| 128 | pub fn make_upper_grid_with(w: usize, h: usize, b: &board::Board) -> Vec<V2D> { | |
| 129 | let mut vec = Vec::with_capacity(w * h * 4); | |
| 130 | let x_stride = 2.0 / w as f32; | |
| 131 | let y_stride = 2.0 / h as f32; | |
| 132 | let o_stride = 1.0 / 32.0; | |
| 133 | b.each_esse(|x, y, t| { | |
| 134 | let x = x as f32; | |
| 135 | let y = h as f32 - y as f32 - 1.0; | |
| 136 | let tx = (t.sprite.x as f32) * o_stride; | |
| 137 | let ty = (t.sprite.y as f32) * o_stride; | |
| 138 | vec.extend(mk_quad((x, y), (x_stride, y_stride), (tx, ty), o_stride)); | |
| 139 | }); | |
| 140 | vec | |
| 141 | } | |
| 142 | ||
| 143 | ||
| 144 | fn mk_quad( | |
| 145 | (x, y): (f32, f32), | |
| 146 | (x_stride, y_stride): (f32, f32), | |
| 147 | (tx, ty): (f32, f32), | |
| 148 | o_stride: f32, | |
| 149 | ) -> Vec<V2D> { | |
| 150 | vec![ | |
| 151 | V2D { | |
| 152 | x: x_stride * (x + 1.0) - 1.0, | |
| 153 | y: y_stride * y - 1.0, | |
| 154 | u: tx + o_stride, | |
| 155 | v: ty + o_stride, | |
| 156 | }, | |
| 157 | V2D { | |
| 158 | x: x_stride * x - 1.0, | |
| 159 | y: y_stride * y - 1.0, | |
| 160 | u: tx, | |
| 161 | v: ty + o_stride, | |
| 162 | }, | |
| 163 | V2D { | |
| 164 | x: x_stride * (x + 1.0) - 1.0, | |
| 165 | y: y_stride * (y + 1.0) - 1.0, | |
| 166 | u: tx + o_stride, | |
| 167 | v: ty, | |
| 168 | }, | |
| 169 | ||
| 170 | V2D { | |
| 171 | x: x_stride * x - 1.0, | |
| 172 | y: y_stride * y - 1.0, | |
| 173 | u: tx, | |
| 174 | v: ty + o_stride, | |
| 175 | }, | |
| 176 | V2D { | |
| 177 | x: x_stride * (x + 1.0) - 1.0, | |
| 178 | y: y_stride * (y + 1.0) - 1.0, | |
| 179 | u: tx + o_stride, | |
| 180 | v: ty, | |
| 181 | }, | |
| 182 | V2D { | |
| 183 | x: x_stride * x - 1.0, | |
| 184 | y: y_stride * (y + 1.0) - 1.0, | |
| 185 | u: tx, | |
| 186 | v: ty, | |
| 187 | }, | |
| 188 | ] | |
| 189 | } |
| 14 | 14 | |
| 15 | 15 | use graphics as gfx; |
| 16 | 16 | |
| 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 | // ]; | |
| 23 | ||
| 24 | 17 | // Shader sources |
| 25 | 18 | static VS_SRC: &'static str = include_str!("../shaders/basic_vertex.glsl"); |
| 26 | 19 | static FS_SRC: &'static str = include_str!("../shaders/basic_fragment.glsl"); |
| 30 | 23 | /// event loop |
| 31 | 24 | pub fn main_loop() -> Result<(), gfx::Error> { |
| 32 | 25 | let t = tiled::parse_file( |
| 33 |
std::path::Path::new("/home/gdritter/projects/animaltransiro/areas/ |
|
| 26 | std::path::Path::new("/home/gdritter/projects/animaltransiro/areas/main.tmx") | |
| 34 | 27 | ).unwrap(); |
| 35 | 28 | let board = board::Board::from_tiled(&t); |
| 36 | ||
| 37 | println!("{:#?}", board); | |
| 38 | 29 | |
| 39 | 30 | // let audio = audio::Audio::init()?; |
| 40 | 31 | let window = gfx::Window::create()?; |
| 56 | 47 | gfx::VertexArray::new(&program), |
| 57 | 48 | &tile_data, |
| 58 | 49 | ); |
| 50 | vbo.unbind(); | |
| 51 | ||
| 52 | let upper_tile_data = graphics::vertices::make_upper_grid_with( | |
| 53 | board::BOARD_WIDTH as usize, | |
| 54 | board::BOARD_HEIGHT as usize, | |
| 55 | &board, | |
| 56 | ); | |
| 57 | let upper_vbo = gfx::VertexBuffer::new_array_buffer( | |
| 58 | gfx::VertexArray::new(&program), | |
| 59 | &upper_tile_data, | |
| 60 | ); | |
| 61 | upper_vbo.unbind(); | |
| 59 | 62 | |
| 60 | 63 | program.use_program(); |
| 61 | 64 | program.bind_frag_data_location(0, "out_color")?; |
| 62 | 65 | |
| 66 | vbo.bind(); | |
| 63 | 67 | vbo.bind_position("position")?; |
| 64 | 68 | vbo.bind_uv("uv")?; |
| 65 | 69 | vbo.unbind(); |
| 70 | ||
| 71 | upper_vbo.bind(); | |
| 72 | upper_vbo.bind_position("position")?; | |
| 73 | upper_vbo.bind_uv("uv")?; | |
| 74 | upper_vbo.unbind(); | |
| 66 | 75 | |
| 67 | 76 | program.set_texture("tex", &tex, 0).unwrap(); |
| 68 | 77 | program.set_texture("nrm", &nrm, 1).unwrap(); |
| 93 | 102 | |
| 94 | 103 | gfx::clear(); |
| 95 | 104 | vbo.draw(); |
| 105 | upper_vbo.draw(); | |
| 96 | 106 | |
| 97 | 107 | ControlFlow::Continue |
| 98 | 108 | })?; |