Add basic lighting

This commit is contained in:
crumblingstatue 2023-04-06 18:40:34 +02:00
parent 45acd4c1ac
commit d1df7cd472
4 changed files with 58 additions and 17 deletions

16
shaders/lighting.glsl Normal file
View file

@ -0,0 +1,16 @@
uniform sampler2D texture;
uniform float ambient;
uniform bool has_texture;
void main()
{
// lookup the pixel in the texture
vec4 pixel = texture2D(texture, gl_TexCoord[0].xy);
// multiply it by the color
vec4 col = gl_Color;
if (has_texture) {
col = gl_Color * pixel;
}
gl_FragColor = vec4(col.x * ambient, col.y * ambient, col.z * ambient, col.w);
}

View file

@ -220,8 +220,9 @@ impl App {
fn do_rendering(&mut self) { fn do_rendering(&mut self) {
self.rw.clear(Color::rgb(55, 221, 231)); self.rw.clear(Color::rgb(55, 221, 231));
self.game.draw_world(&mut self.rw, &self.res); self.game.render_pre_step(&mut self.res);
self.game.draw_entities(&mut self.rw); self.game.draw_world(&mut self.rw, &mut self.res);
self.game.draw_entities(&mut self.rw, &mut self.res);
self.sf_egui self.sf_egui
.do_frame(|ctx| { .do_frame(|ctx| {
if self.debug.panel { if self.debug.panel {
@ -290,6 +291,8 @@ fn debug_panel_ui(
ui.add(egui::DragValue::new(&mut vol)); ui.add(egui::DragValue::new(&mut vol));
res.surf_music.set_volume(vol); res.surf_music.set_volume(vol);
ui.separator(); ui.separator();
ui.label("Ambient light");
ui.add(egui::DragValue::new(&mut game.ambient_light).speed(0.01));
egui::ScrollArea::vertical().show(ui, |ui| { egui::ScrollArea::vertical().show(ui, |ui| {
gamedebug_core::for_each_imm(|info| match info { gamedebug_core::for_each_imm(|info| match info {
gamedebug_core::Info::Msg(msg) => { gamedebug_core::Info::Msg(msg) => {

View file

@ -1,7 +1,8 @@
mod player; mod player;
use sfml::graphics::{ use sfml::graphics::{
Color, Rect, RectangleShape, RenderTarget, RenderWindow, Shape, Sprite, Transformable, Color, Rect, RectangleShape, RenderStates, RenderTarget, RenderWindow, Shape, Sprite,
Transformable,
}; };
use crate::{ use crate::{
@ -23,6 +24,7 @@ pub struct GameState {
pub current_biome: Biome, pub current_biome: Biome,
pub prev_biome: Biome, pub prev_biome: Biome,
pub worldgen: Worldgen, pub worldgen: Worldgen,
pub ambient_light: f32,
} }
#[derive(PartialEq, Eq, Clone, Copy)] #[derive(PartialEq, Eq, Clone, Copy)]
@ -32,41 +34,51 @@ pub enum Biome {
} }
impl GameState { impl GameState {
pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &Res) { pub(crate) fn draw_world(&mut self, rw: &mut RenderWindow, res: &mut Res) {
let mut rs = RenderStates::default();
res.lighting_shader.set_uniform_bool("has_texture", true);
rs.set_shader(Some(&res.lighting_shader));
let mut s = Sprite::with_texture(&res.tile_atlas); let mut s = Sprite::with_texture(&res.tile_atlas);
for_each_tile_on_screen(self.camera_offset, |tp, sp| { for_each_tile_on_screen(self.camera_offset, |tp, sp| {
let tile = self.world.tile_at_mut(tp, &self.worldgen); let tile = self.world.tile_at_mut(tp, &self.worldgen);
s.set_position(sp.to_sf_vec()); s.set_position(sp.to_sf_vec());
if tile.bg != Tile::EMPTY { if tile.bg != Tile::EMPTY {
s.set_texture_rect(Rect::new((tile.bg - 1) as i32 * 32, 0, 32, 32)); s.set_texture_rect(Rect::new((tile.bg - 1) as i32 * 32, 0, 32, 32));
rw.draw(&s); rw.draw_with_renderstates(&s, &rs);
} }
if tile.mid != Tile::EMPTY { if tile.mid != Tile::EMPTY {
s.set_texture_rect(Rect::new((tile.mid - 1) as i32 * 32, 0, 32, 32)); s.set_texture_rect(Rect::new((tile.mid - 1) as i32 * 32, 0, 32, 32));
rw.draw(&s); rw.draw_with_renderstates(&s, &rs);
} }
if tile.fg != Tile::EMPTY { if tile.fg != Tile::EMPTY {
s.set_texture_rect(Rect::new((tile.fg - 1) as i32 * 32, 0, 32, 32)); s.set_texture_rect(Rect::new((tile.fg - 1) as i32 * 32, 0, 32, 32));
rw.draw(&s); rw.draw_with_renderstates(&s, &rs);
} }
}); });
} }
pub fn draw_entities(&mut self, rw: &mut RenderWindow) { pub fn draw_entities(&mut self, rw: &mut RenderWindow, res: &mut Res) {
let mut rend_st = RenderStates::default();
res.lighting_shader.set_uniform_bool("has_texture", false);
rend_st.set_shader(Some(&res.lighting_shader));
let (x, y, w, h) = self.player.col_en.en.xywh(); let (x, y, w, h) = self.player.col_en.en.xywh();
let mut rs = RectangleShape::new(); let mut rect_sh = RectangleShape::new();
rs.set_position(( rect_sh.set_position((
(x - self.camera_offset.x as i32) as f32, (x - self.camera_offset.x as i32) as f32,
(y - self.camera_offset.y as i32) as f32, (y - self.camera_offset.y as i32) as f32,
)); ));
rs.set_size((w as f32, h as f32)); rect_sh.set_size((w as f32, h as f32));
rw.draw(&rs); rw.draw_with_renderstates(&rect_sh, &rend_st);
rs.set_size((2., 2.)); rect_sh.set_size((2., 2.));
rs.set_fill_color(Color::RED); rect_sh.set_fill_color(Color::RED);
rs.set_position(( rect_sh.set_position((
(self.player.col_en.en.pos.x - self.camera_offset.x as i32) as f32, (self.player.col_en.en.pos.x - self.camera_offset.x as i32) as f32,
(self.player.col_en.en.pos.y - self.camera_offset.y as i32) as f32, (self.player.col_en.en.pos.y - self.camera_offset.y as i32) as f32,
)); ));
rw.draw(&rs); rw.draw(&rect_sh);
}
pub fn render_pre_step(&mut self, res: &mut Res) {
res.lighting_shader
.set_uniform_float("ambient", self.ambient_light);
} }
} }
@ -100,6 +112,7 @@ impl Default for GameState {
current_biome: Biome::Surface, current_biome: Biome::Surface,
prev_biome: Biome::Surface, prev_biome: Biome::Surface,
worldgen: Worldgen::default(), worldgen: Worldgen::default(),
ambient_light: 1.0,
} }
} }
} }

View file

@ -1,9 +1,14 @@
use sfml::{audio::Music, graphics::Texture, SfBox}; use sfml::{
audio::Music,
graphics::{Shader, ShaderType, Texture},
SfBox,
};
pub struct Res { pub struct Res {
pub tile_atlas: SfBox<Texture>, pub tile_atlas: SfBox<Texture>,
pub surf_music: Music<'static>, pub surf_music: Music<'static>,
pub und_music: Music<'static>, pub und_music: Music<'static>,
pub lighting_shader: Shader<'static>,
} }
impl Res { impl Res {
@ -12,6 +17,10 @@ impl Res {
tile_atlas: Texture::from_file("res/tiles.png")?, tile_atlas: Texture::from_file("res/tiles.png")?,
surf_music: Music::from_file("res/music.ogg").unwrap(), surf_music: Music::from_file("res/music.ogg").unwrap(),
und_music: Music::from_file("res/cave2.ogg").unwrap(), und_music: Music::from_file("res/cave2.ogg").unwrap(),
lighting_shader: Shader::from_memory(
include_str!("../shaders/lighting.glsl"),
ShaderType::Fragment,
)?,
}) })
} }
} }