main
_ 2020-12-25 12:38:51 -06:00
parent aadc08194f
commit f98d5138ff
2 changed files with 117 additions and 48 deletions

View File

@ -13,7 +13,7 @@ varying lowp vec3 vary_color;
void main (void) { void main (void) {
vec3 sun_dir = normalize (vec3 (1.0, 1.0, 4.0)); vec3 sun_dir = normalize (vec3 (1.0, 1.0, 4.0));
vec3 sun_light = vec3 (1.0, 0.75, 0.5) * max (0.0, dot (attr_normal, sun_dir)); vec3 sun_light = vec3 (1.0, 0.75, 0.5) * sqrt (max (0.0, dot (attr_normal, sun_dir)));
vec3 sky_light = vec3 (0.0, 0.25, 0.5) * (attr_normal.z * 0.5 + 0.5); vec3 sky_light = vec3 (0.0, 0.25, 0.5) * (attr_normal.z * 0.5 + 0.5);
vary_color = sqrt (attr_color * (sun_light + sky_light)); vary_color = sqrt (attr_color * (sun_light + sky_light));

View File

@ -19,7 +19,10 @@ use sdl2::{
event::Event, event::Event,
keyboard::{Keycode, Scancode}, keyboard::{Keycode, Scancode},
}; };
use tracing::instrument; use tracing::{
debug,
instrument,
};
use opengl_rust::{ use opengl_rust::{
glezz, glezz,
@ -66,7 +69,8 @@ impl ShaderLocations {
} }
#[instrument (level = "trace", skip (ctx, state))] #[instrument (level = "trace", skip (ctx, state))]
fn draw_graphics (ctx: &GraphicsContext, state: &GameState) fn draw_graphics (ctx: &GraphicsContext, state: &GameState)
-> anyhow::Result <()>
{ {
let shader_locs = &ctx.shader_locations; let shader_locs = &ctx.shader_locations;
let attr_pos = shader_locs.attr_pos; let attr_pos = shader_locs.attr_pos;
@ -85,7 +89,7 @@ fn draw_graphics (ctx: &GraphicsContext, state: &GameState)
let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), screen_size.0 / screen_size.1, 0.125, 200.0); let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), screen_size.0 / screen_size.1, 0.125, 200.0);
let spin_period = 360 * 4; let spin_period = 360 * 8;
let view_mat = proj_mat * let view_mat = proj_mat *
Mat4::from_translation (Vec3::from ((0.0, 0.0, -80.0))) * Mat4::from_translation (Vec3::from ((0.0, 0.0, -80.0))) *
@ -105,6 +109,19 @@ fn draw_graphics (ctx: &GraphicsContext, state: &GameState)
ctx.vertex_buffer.bind (); ctx.vertex_buffer.bind ();
ctx.index_buffer.bind (); ctx.index_buffer.bind ();
let bump_period = 360 * 7;
let bump_theta = (state.logic_frames % bump_period) as f32 * 3.1415926535 * 2.0 / bump_period as f32;
let ClientArrays {
vertexes,
indexes,
} = make_heightmap_arrays (&[
(32.0, 48.0),
(32.0 + 16.0 * bump_theta.cos (), 32.0 + 16.0 * bump_theta.sin ()),
]);
upload_vertexes (&vertexes)?;
unsafe { unsafe {
let num_quads = 64 * 64; let num_quads = 64 * 64;
let stride = 4 * 9; let stride = 4 * 9;
@ -116,45 +133,16 @@ fn draw_graphics (ctx: &GraphicsContext, state: &GameState)
} }
ctx.window.gl_swap_window (); ctx.window.gl_swap_window ();
Ok (())
} }
fn main () -> anyhow::Result <()> { struct ClientArrays {
tracing_subscriber::fmt::fmt () vertexes: Vec <f32>,
.with_env_filter (tracing_subscriber::EnvFilter::from_default_env()) indexes: Vec <u32>,
.with_span_events (tracing_subscriber::fmt::format::FmtSpan::CLOSE) }
.init ();
fn make_heightmap_arrays (bumps: &[(f32, f32)]) -> ClientArrays {
let sdl_context = sdl2::init ().map_err (|e| anyhow! ("Can't init SDL: {}", e))?;
let video_subsystem = sdl_context.video ().map_err (|e| anyhow! ("Can't get SDL video subsystem: {}", e))?;
let window = video_subsystem.window ("Heightmap terrain demo", 960, 540)
.position_centered ()
.opengl ()
.build ()
?;
gl::load_with (|s| {
video_subsystem.gl_get_proc_address (s) as *const _
});
assert! (gl::ClearColor::is_loaded ());
let gl_ctx = window.gl_create_context ().map_err (|e| anyhow! ("Can't create OpenGL context: {}", e))?;
window.gl_make_current (&gl_ctx).map_err (|e| anyhow! ("Can't make OpenGL context current: {}", e))?;
let mut time_step = TimeStep::new (60, 1000);
let mut graphics_frames = 0;
let controller_subsystem = sdl_context.game_controller ().unwrap ();
let controller = controller_subsystem.open (0).ok ();
let mut event_pump = sdl_context.event_pump ().unwrap ();
let shader_program = shader::shader_from_files ("shaders/terrain-vert.glsl", "shaders/terrain-frag.glsl");
let shader_locations = ShaderLocations::new (&shader_program)?;
let mut vertexes = vec![]; let mut vertexes = vec![];
let mut indexes = vec![]; let mut indexes = vec![];
let mut start_index = 0; let mut start_index = 0;
@ -163,15 +151,22 @@ fn main () -> anyhow::Result <()> {
let x = x - bump_x; let x = x - bump_x;
let y = y - bump_y; let y = y - bump_y;
let d = x * x + y * y; let d2: f32 = x * x + y * y;
if d2 > 8.0 * 8.0 {
return 0.0;
}
let d = d2.sqrt ();
f32::max (0.0, 5.0 - d * 0.125) let t = f32::min (1.0, f32::max (0.0, (8.0 - d) / 6.0));
let z = -2.0 * t * t + 3.0 * t * t;
f32::max (0.0, 4.0 * z)
}; };
let height_fn = |(x, y)| { let height_fn = |(x, y)| {
bump_at (32.0, 32.0, x, y) + bumps.iter ()
bump_at (64.0, 32.0, x, y) + .map (|(bump_x, bump_y)| bump_at (bump_x, bump_y, x, y))
bump_at (32.0, 48.0, x, y) .sum ()
}; };
for y in 0..64 { for y in 0..64 {
@ -227,9 +222,83 @@ fn main () -> anyhow::Result <()> {
} }
} }
let vertex_buffer = gpu_buffers::VertexBuffer::from_slice (&vertexes); ClientArrays {
vertexes,
indexes,
}
}
fn upload_vertexes (vertexes: &[f32]) -> anyhow::Result <()> {
unsafe {
gl::BufferSubData (
gl::ARRAY_BUFFER,
0,
(vertexes.len () * 4).try_into ()?,
&vertexes [0] as *const f32 as *const c_void
);
}
Ok (())
}
fn main () -> anyhow::Result <()> {
tracing_subscriber::fmt::fmt ()
.with_env_filter (tracing_subscriber::EnvFilter::from_default_env())
.with_span_events (tracing_subscriber::fmt::format::FmtSpan::CLOSE)
.init ();
let sdl_context = sdl2::init ().map_err (|e| anyhow! ("Can't init SDL: {}", e))?;
let video_subsystem = sdl_context.video ().map_err (|e| anyhow! ("Can't get SDL video subsystem: {}", e))?;
let window = video_subsystem.window ("Heightmap terrain demo", 960, 540)
.position_centered ()
.opengl ()
.build ()
?;
gl::load_with (|s| {
video_subsystem.gl_get_proc_address (s) as *const _
});
assert! (gl::ClearColor::is_loaded ());
let gl_ctx = window.gl_create_context ().map_err (|e| anyhow! ("Can't create OpenGL context: {}", e))?;
window.gl_make_current (&gl_ctx).map_err (|e| anyhow! ("Can't make OpenGL context current: {}", e))?;
let mut time_step = TimeStep::new (60, 1000);
let mut graphics_frames = 0;
let controller_subsystem = sdl_context.game_controller ().unwrap ();
let controller = controller_subsystem.open (0).ok ();
let mut event_pump = sdl_context.event_pump ().unwrap ();
let shader_program = shader::shader_from_files ("shaders/terrain-vert.glsl", "shaders/terrain-frag.glsl");
let shader_locations = ShaderLocations::new (&shader_program)?;
let ClientArrays {
vertexes,
indexes,
} = make_heightmap_arrays (&[]);
debug! ("Floats in vertex buffer: {}", vertexes.len ());
let vertex_buffer = gpu_buffers::VertexBuffer::streaming (vertexes.len ());
let index_buffer = gpu_buffers::IndexBuffer::from_slice_u32 (&indexes); let index_buffer = gpu_buffers::IndexBuffer::from_slice_u32 (&indexes);
upload_vertexes (&vertexes)?;
unsafe {
gl::BufferSubData (
gl::ARRAY_BUFFER,
0,
(vertexes.len () * 4).try_into ()?,
&vertexes [0] as *const f32 as *const c_void
);
}
let graphics_ctx = GraphicsContext { let graphics_ctx = GraphicsContext {
window, window,
gl_ctx, gl_ctx,
@ -264,7 +333,7 @@ fn main () -> anyhow::Result <()> {
game_state.logic_frames += 1; game_state.logic_frames += 1;
} }
draw_graphics (&graphics_ctx, &game_state); draw_graphics (&graphics_ctx, &game_state)?;
graphics_frames += 1; graphics_frames += 1;
std::thread::sleep (Duration::from_millis (15)); std::thread::sleep (Duration::from_millis (15));