use ::std::ffi::CStr;
use buffer::{Buffer, DrawMode};
use context::Context;
use orthografic_view::OrthograficView;
use program::{Program, UniformId};
use std::f32::consts::PI;
use vertex_attrib::VertexAttribParams;
#[derive(Debug)]
pub struct AtmosLayer {
buffer: Buffer,
program: Program,
scale_uniform: UniformId,
}
impl AtmosLayer {
pub fn new(cx: &mut Context) -> AtmosLayer {
let vertex_data = {
let mut vertex_data: Vec<f32> = Vec::with_capacity(17 * 4);
let radius_a = 0.75;
let radius_b = 1.25;
for x in 0..17 {
let angle = x as f32 * (PI * 2.0 / 16.0);
vertex_data.extend(&[
angle.cos() * radius_a,
angle.sin() * radius_a,
angle.cos() * radius_b,
angle.sin() * radius_b,
]);
}
vertex_data
};
let buffer = Buffer::new(cx, &vertex_data, vertex_data.len() / 2);
let mut program = Program::new(
cx,
include_bytes!("../shader/atmos.vert"),
include_bytes!("../shader/atmos.frag"),
).unwrap();
program.add_attribute(
cx,
CStr::from_bytes_with_nul(b"position\0").unwrap(),
&VertexAttribParams::new(2, 2, 0)
);
let scale_uniform = program.get_uniform_id(cx, CStr::from_bytes_with_nul(b"scale\0").unwrap()).unwrap();
AtmosLayer {
buffer,
program,
scale_uniform,
}
}
pub fn prepare_draw(&mut self, cx: &mut Context) {
self.program.enable_vertex_attribs(cx);
self.program.set_vertex_attribs(cx, &self.buffer);
}
pub fn draw(
&mut self,
cx: &mut Context,
ortho: &OrthograficView,
) {
let (scale_x, scale_y) = {
let diam = ortho.diameter_physical_pixels();
((diam / ortho.viewport_size.x) as f32, (diam / ortho.viewport_size.y) as f32)
};
self.program.set_uniform_2f(cx, self.scale_uniform, scale_x, scale_y);
self.buffer.draw(cx, &self.program, DrawMode::TriangleStrip);
}
}