Skip to content

Commit

Permalink
feat(rendering): Add color highlight color to sprite rendering (#348)
Browse files Browse the repository at this point in the history
  • Loading branch information
suspistew authored Jan 20, 2025
1 parent 2c4b858 commit 0798177
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 21 deletions.
34 changes: 28 additions & 6 deletions examples/feature-showcase/scene.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
use hecs::Entity;
use scion::core::components::maths::transform::TransformBuilder;
use scion::core::resources::asset_manager::AssetType;
use scion::graphics::components::tiles::atlas::importer::load_tilemap;
use std::collections::HashMap;
use std::time::Duration;

use scion::core::scene::Scene;
use scion::core::world::{GameData, World};
use scion::graphics::components::animations::{Animation, AnimationModifier, Animations};
use scion::graphics::components::color::Color;
use scion::graphics::components::tiles::atlas::importer::load_tilemap;
use scion::graphics::components::tiles::sprite::Sprite;
use scion::graphics::components::tiles::tilemap::Tile;
use scion::graphics::rendering::Highlight;
use scion::utils::file::app_base_path_join;
use scion::utils::maths::Vector;
use scion::utils::premade::dummy_camera_controller::DummyCameraConfig;
use std::collections::HashMap;
use std::time::Duration;
use winit::window::CursorIcon;

#[derive(Default)]
pub struct DemoScene {
entity: Option<Entity>,
last_highlighted: Option<Entity>,
last: usize,
}

Expand Down Expand Up @@ -78,8 +82,26 @@ impl Scene for DemoScene {
fn on_update(&mut self, data: &mut GameData) {
let picked = data.game_state().get_color_picked_entity();
if let Some(e) = picked {
let t = data.entry_mut::<(&Tile)>(e).expect("");
println!("currently pointed : {:?} in the tilemap {:?}", t.get_position(), t.get_tilemap_entity());
if let Some(entity) = self.last_highlighted.as_ref() {
let s = data.entry_mut::<(&mut Sprite)>(*entity).expect("");
s.set_highlight(None);
}
{
let t = data.entry_mut::<(&Tile)>(e).expect("");
println!("currently pointed : {:?} in the tilemap {:?}", t.get_position(), t.get_tilemap_entity());
}
{
let s = data.entry_mut::<(&mut Sprite)>(e).expect("");
s.set_highlight(Some(Highlight::ColorNonTransparent(Color::new(255, 255, 255, 0.5))));
}
self.last_highlighted = Some(e);
data.window().set_cursor(CursorIcon::Pointer);
}else{
if let Some(entity) = self.last_highlighted.as_ref() {
let s = data.entry_mut::<(&mut Sprite)>(*entity).expect("");
s.set_highlight(None);
}
data.window().set_cursor(CursorIcon::Default);
}

let animations = data.entry_mut::<&mut Animations>(self.entity.unwrap()).expect("");
Expand Down
16 changes: 14 additions & 2 deletions src/graphics/components/tiles/sprite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
graphics::components::material::Material,
graphics::rendering::Renderable2D,
};
use crate::graphics::rendering::Highlight;

const INDICES: &[u16] = &[0, 1, 3, 3, 1, 2];

Expand All @@ -24,17 +25,19 @@ pub struct Sprite {
dirty: bool,
/// Pivot point of the sprite, default topleft
pivot: Pivot,
/// Highlight type
highlight: Option<Highlight>,
}

impl Sprite {
/// Creates a new sprite that will use the `tile_number` from the tileset associated in the same
/// entity
pub fn new(tile_number: usize) -> Self {
Self { tile_number, contents: None, dirty: false, pivot: Pivot::TopLeft}
Self { tile_number, contents: None, dirty: false, pivot: Pivot::TopLeft, highlight: None }
}

pub fn pivot(self, pivot: Pivot) -> Self {
Self { tile_number: self.tile_number, contents: None, dirty: false, pivot}
Self { tile_number: self.tile_number, contents: None, dirty: false, pivot, highlight: None }
}

/// Modify the current sprite tile number
Expand Down Expand Up @@ -87,6 +90,15 @@ impl Sprite {
INDICES.to_vec()
}

pub fn highlight(&self) -> Option<&Highlight> {
self.highlight.as_ref()
}

pub fn set_highlight(&mut self, highlight: Option<Highlight>){
self.highlight = highlight;
self.dirty = true;
}

pub(crate) fn set_content(&mut self, content: [TexturedGlVertexWithLayer; 4]) {
self.contents = Some(content);
}
Expand Down
5 changes: 5 additions & 0 deletions src/graphics/rendering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ pub struct RenderingInfos {
pub(crate) type_name: String,
pub(crate) render_priority: usize,
}

#[derive(Debug, Clone)]
pub enum Highlight{
ColorNonTransparent(Color),
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::graphics::components::ui::ui_text::UiText;
use crate::graphics::components::{Square, Triangle};
use crate::graphics::rendering::scion2d::pre_renderer::Scion2DPreRenderer;
use crate::graphics::rendering::shaders::gl_representations::TexturedGlVertexWithLayer;
use crate::graphics::rendering::{Renderable2D, RenderableUi, RenderingUpdate};
use crate::graphics::rendering::{Highlight, Renderable2D, RenderableUi, RenderingUpdate};
use hecs::{Component, Entity};
use log::info;
use wgpu::BufferUsages;
Expand Down Expand Up @@ -126,14 +126,17 @@ fn prepare_buffer_update_for_tilemap(renderer: &mut Scion2DPreRenderer, data: &m
} else {
offset_z = depth * 100 - tile.position.z() * 10;
}

vec.iter_mut().for_each(|gl_vertex| {
gl_vertex.position[0] = gl_vertex.position[0] + tile_size as f32 * tile.position.x() as f32 + offset_x;
gl_vertex.position[1] = gl_vertex.position[1] + tile_size as f32 * tile.position.y() as f32 + offset_y;
gl_vertex.position[2] = gl_vertex.position[2] + tile.position.z() as f32 / 100.;
gl_vertex.depth = gl_vertex.depth + offset_z as f32 * 0.00001;
gl_vertex.enable_color_picking_override = 1;
gl_vertex.color_picking_override = color_picking.as_f32_array();
if let Some(Highlight::ColorNonTransparent(c)) = sprite.highlight(){
gl_vertex.enable_highlight = 1;
gl_vertex.highlight_color = c.as_f32_array();
}
});
let sprite_indexes = Sprite::indices();
let mut sprite_indexes: Vec<u16> = sprite_indexes
Expand Down
3 changes: 1 addition & 2 deletions src/graphics/rendering/scion2d/window_rendering_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ impl ScionWindowRenderingManager {
});
let depth_view = depth_texture.create_view(&wgpu::TextureViewDescriptor::default());


if self.should_compute_cursor_color_picking && self.cursor_position_eligible() {
self.compute_color_pixel(&data);
}
Expand Down Expand Up @@ -259,7 +258,7 @@ impl ScionWindowRenderingManager {
fn cursor_position_eligible(&self) -> bool {
match self.cursor_position.as_ref(){
None => false,
Some((x,y)) => *x >= 0 && *y >= 0 && self.config.width <= *x && self.config.height <= *y
Some((x,y)) => *x >= 0 && *y >= 0 && *x <= self.config.width && *y <= self.config.height
}
}
}
22 changes: 19 additions & 3 deletions src/graphics/rendering/shaders/gl_representations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,16 @@ pub(crate) struct TexturedGlVertexWithLayer {
pub depth: f32,
pub color_picking_override: [f32;4],
pub enable_color_picking_override: u32,
pub enable_highlight: u32,
pub highlight_color: [f32;4],

}

impl TexturedGlVertexWithLayer {
pub fn desc<'a>() -> wgpu::VertexBufferLayout<'a> {
use std::mem;
wgpu::VertexBufferLayout {
array_stride: mem::size_of::<TexturedGlVertexWithLayer>() as wgpu::BufferAddress,
array_stride: size_of::<TexturedGlVertexWithLayer>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &[
wgpu::VertexAttribute {
Expand All @@ -114,12 +116,12 @@ impl TexturedGlVertexWithLayer {
format: wgpu::VertexFormat::Float32x3,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 3]>() as wgpu::BufferAddress,
offset: size_of::<[f32; 3]>() as wgpu::BufferAddress,
shader_location: 1,
format: wgpu::VertexFormat::Float32x2,
},
wgpu::VertexAttribute {
offset: (mem::size_of::<[f32; 2]>() + mem::size_of::<[f32; 3]>()) as wgpu::BufferAddress,
offset: (size_of::<[f32; 2]>() + mem::size_of::<[f32; 3]>()) as wgpu::BufferAddress,
shader_location: 2,
format: wgpu::VertexFormat::Uint32,
},
Expand All @@ -138,6 +140,16 @@ impl TexturedGlVertexWithLayer {
shader_location: 5,
format: wgpu::VertexFormat::Uint32,
},
wgpu::VertexAttribute {
offset: (size_of::<[f32; 2]>() + size_of::<[f32; 3]>() + size_of::<u32>() + size_of::<f32>() + size_of::<[f32; 4]>() + size_of::<u32>()) as wgpu::BufferAddress,
shader_location: 6,
format: wgpu::VertexFormat::Uint32,
},
wgpu::VertexAttribute {
offset: (size_of::<[f32; 2]>() + size_of::<[f32; 3]>() + size_of::<u32>() + size_of::<f32>() + size_of::<[f32; 4]>() + size_of::<u32>() + size_of::<u32>()) as wgpu::BufferAddress,
shader_location: 7,
format: wgpu::VertexFormat::Float32x4,
},
],
}
}
Expand Down Expand Up @@ -213,6 +225,8 @@ impl From<(&Coordinates, &Coordinates, usize, f32)> for TexturedGlVertexWithLaye
depth: vertex_infos.3,
color_picking_override: [0.,0.,0.,1.],
enable_color_picking_override: 0,
enable_highlight: 0,
highlight_color: [0.,0.,0.,0.],
}
}
}
Expand All @@ -226,6 +240,8 @@ impl From<(&Coordinates, &Coordinates, usize, f32, Color, bool)> for TexturedGlV
depth: vertex_infos.3,
color_picking_override: [0.,0.,0.,1.],
enable_color_picking_override: if vertex_infos.5 { 1 } else { 0 },
enable_highlight: 0,
highlight_color: [0.,0.,0.,0.],
}
}
}
Expand Down
25 changes: 19 additions & 6 deletions src/graphics/rendering/shaders/sprite_shader.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@ struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(0) v_tex_translation: vec2<f32>,
@location(1) layer: u32,
@location(2) color_picking_override: vec4<f32>,
@location(3) enable_color_picking_override: u32
@location(2) color_picking_override: vec4<f32>,
@location(3) enable_color_picking_override: u32,
@location(4) enable_highlight: u32,
@location(5) highlight_color: vec4<f32>
};

struct Uniforms {
Expand All @@ -16,11 +18,11 @@ struct PickingData {
}



@group(0)
@binding(0)
var<uniform> r_data: Uniforms;


@vertex
fn vs_main(
@location(0) a_position : vec3<f32>,
Expand All @@ -29,6 +31,8 @@ fn vs_main(
@location(3) depth: f32,
@location(4) color_picking_override: vec4<f32>,
@location(5) enable_color_picking_override: u32,
@location(6) enable_highlight: u32,
@location(7) highlight_color: vec4<f32>
) -> VertexOutput {
var result: VertexOutput;
let world_position = r_data.model_trans * vec4<f32>(a_position, 1.0);
Expand All @@ -39,8 +43,9 @@ fn vs_main(
result.layer = u32(layer);
result.color_picking_override = color_picking_override;
result.enable_color_picking_override = u32(enable_color_picking_override);
result.enable_highlight = u32(enable_highlight);
result.highlight_color = highlight_color;
return result;

}

@group(1)
Expand All @@ -53,11 +58,11 @@ var s_diffuse: sampler;

@group(2)
@binding(0)
var<uniform> picking_data: PickingData;
var<uniform> picking_data: PickingData;

@fragment
fn fs_main(vertex: VertexOutput) -> @location(0) vec4<f32> {
let depth = vertex.position.z / vertex.position.w;
let depth = vertex.position.z / vertex.position.w;
let color = textureSample(t_diffuse, s_diffuse, vertex.v_tex_translation, vertex.layer);

if (color.a < 0.0001) {
Expand All @@ -68,5 +73,13 @@ fn fs_main(vertex: VertexOutput) -> @location(0) vec4<f32> {
return vertex.color_picking_override;
}

if(vertex.enable_highlight > 0){
let final_color = vec4<f32>(
mix(color.rgb, color.rgb + vertex.highlight_color.rgb * vertex.highlight_color.a, vertex.highlight_color.a),
color.a
);
return final_color;
}

return color;
}

0 comments on commit 0798177

Please sign in to comment.