This example is meant to show off a simple shader using the sin of time to offset the y values of a regular n-gon. This is shows off how you can easily render regular n-gons with Bottomless-Pit.
use std::f32::consts::PI;
use bottomless_pit::colour::Colour;
use bottomless_pit::engine_handle::{Engine, EngineBuilder};
use bottomless_pit::material::{Material, MaterialBuilder};
use bottomless_pit::render::RenderInformation;
use bottomless_pit::shader::Shader;
use bottomless_pit::shader::UniformData;
use bottomless_pit::vectors::Vec2;
use bottomless_pit::Game;
use encase::ShaderType;
fn main() {
let mut engine = EngineBuilder::new()
.with_resolution((500, 500))
.remove_vsync()
.set_clear_colour(Colour::BLACK)
.build()
.unwrap();
let data = Time {
time: 0.0,
_pading: 0.0,
_padding2: 0.0,
_padding4: 0.0,
};
let uniform_data = UniformData::new(&engine, &data);
let mouse_shader = Shader::new("examples/sinewaves.wgsl", true, &mut engine);
let regular_material = MaterialBuilder::new()
.set_uniform(&uniform_data)
.set_shader(mouse_shader)
.build(&mut engine);
let pos = Position {
regular_material,
time: 0.0,
};
engine.run(pos);
}
#[derive(ShaderType)]
struct Time {
time: f32,
_pading: f32,
_padding2: f32,
_padding4: f32,
}
struct Position {
regular_material: Material,
time: f32,
}
impl Game for Position {
fn render<'pass, 'others>(
&'others mut self,
mut render_handle: RenderInformation<'pass, 'others>,
) where
'others: 'pass,
{
self.regular_material.add_regular_n_gon(
120,
200.0,
Vec2 { x: 250.0, y: 250.0 },
Colour::BLUE,
&render_handle,
);
self.regular_material.draw(&mut render_handle);
}
fn update(&mut self, engine_handle: &mut Engine) {
let dt = engine_handle.get_frame_delta_time();
self.time = (self.time + dt) % (32.0 * PI);
self.regular_material
.update_uniform_data(&self.time, &engine_handle);
}
}
struct EngineUniforms {
camera: mat3x3<f32>,
screen_size: vec2<f32>,
}
@group(1) @binding(0)
var<uniform> engine: EngineUniforms;
// now why does this struct look like this?
// its becuase we need 16bit alignment on web
struct Time {
time: f32,
_junk: f32,
_junk1: f32,
_junk4: f32,
}
@group(2) @binding(0)
var<uniform> time: Time;
@group(1) @binding(0)
var<uniform> camera: CameraUniform;
@group(2) @binding(0)
var<uniform> time: Time;
struct VertexInput {
@location(0) position: vec3<f32>,
@location(1) tex_coords: vec2<f32>,
@location(2) colour: vec4<f32>
}
struct VertexOutput {
@builtin(position) clip_position: vec4<f32>,
@location(0) tex_coords: vec2<f32>,
@location(1) colour: vec4<f32>,
}
// vertex shader
@vertex
fn vs_main(model: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.tex_coords = model.tex_coords;
var pos: vec3<f32> = engine.camera * vec3<f32>(
model.position.x,
model.position.y,
1.0
); // the vectors on the right the matrices go on the left in order of importance
pos = pos / pos.z;
pos.x = 2.0 * pos.x / engine.screen_size.x - 1.0;
pos.y = (((2.0 * pos.y / engine.screen_size.y) - 1.0) * -1.0) + sin(time.time + pos.x * 12.0) / 12.0;
out.clip_position = vec4(pos.xy, 0.0, 1.0);
out.colour = model.colour;
return out;
}
// Fragment shader
@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
var r: f32 = (sin((in.clip_position.x + time.time * 16.0)/16.0) + 1.0) / 2.0;
var b: f32 = (sin((in.clip_position.y + time.time * 16.0)/16.0) + 1.0) / 2.0;
var g: f32 = (r + b) / 2.0;
return vec4(r, g, b, 1.0);
}