Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lookup-texture style animations #141

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ flamegraph.svg
**/*.rs.bk
*.AppImage
AppDir
.vscode
Binary file modified assets/cursors.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions config/init.rx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ map r :redo -- Redo act
map x :swap -- Swap foreground/background colors
map/normal b :brush -- Reset brush
map/normal g :flood -- Flood tool
map/normal a :lt/sampler {:tool/prev} -- Lookup-texture sample tool
map/normal e :brush/set erase {:brush/unset erase} -- Erase (hold)
map/normal <shift> :brush/set multi {:brush/unset multi} -- Multi-brush (hold)
map/normal = :brush/toggle perfect -- Pixel-perfect brush
Expand Down
18 changes: 18 additions & 0 deletions src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ pub enum Command {
ViewNext,
ViewPrev,

LookupTextureSample,
LookupTextureMode(bool),
LookupTextureSet(i32),

Noop,
}

Expand Down Expand Up @@ -1051,6 +1055,20 @@ impl Default for Commands {
.then(tuple::<i32>(integer().label("<x>"), integer().label("<y>")))
.map(|((_, i), (x, y))| Command::PaintPalette(i, x, y))
})
.command("lt/on", "Set current view as lookup texture", |p| {
p.value(Command::LookupTextureMode(true)) })
.command("lt/off", "Revert view to normal mode", |p| {
p.value(Command::LookupTextureMode(false)) })
.command("lt/set", "Set another view as lookup texture to current view", |p| {
p.then(integer::<i32>().label("<d>"))
.map(|(_, d)| Command::LookupTextureSet(d))
})
.command("lt/sample", "Search lookup texture for matching pixels", |p| {
p.value(Command::LookupTextureSample)
})
.command("lt/sampler", "Switch to lookup texture sampler tool", |p| {
p.value(Command::Tool(Tool::LookupTextureSampler))
})
}
}

Expand Down
58 changes: 56 additions & 2 deletions src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub mod cursors {
const PAN: Cursor = Cursor::new(Rect::new(48., 0., 64., 16.), -8., -8., false);
const ERASE: Cursor = Cursor::new(Rect::new(64., 0., 80., 16.), -8., -8., true);
const FLOOD: Cursor = Cursor::new(Rect::new(80., 0., 96., 16.), -8., -8., false);
const LOOKUP: Cursor = Cursor::new(Rect::new(96., 0., 112., 16.), -5.5, -8., false);

pub fn info(t: &Tool, b: &Brush, m: Mode, in_view: bool, in_selection: bool) -> Option<Cursor> {
match (m, t) {
Expand All @@ -82,6 +83,7 @@ pub mod cursors {
Tool::Sampler => self::SAMPLER,
Tool::Pan(_) => self::PAN,
Tool::FloodFill => self::FLOOD,
Tool::LookupTextureSampler => self::LOOKUP,

Tool::Brush => match m {
Mode::Visual(_) if in_selection && in_view => self::OMNI,
Expand Down Expand Up @@ -150,7 +152,7 @@ impl Context {
fn draw_ui(session: &Session, canvas: &mut shape2d::Batch, text: &mut TextBatch) {
let view = session.active_view();

if let Some(selection) = session.selection {
if let Some(selection) = &session.selection {
let fill = match session.mode {
Mode::Visual(VisualState::Selecting { .. }) => {
Rgba8::new(color::RED.r, color::RED.g, color::RED.b, 0x55)
Expand Down Expand Up @@ -212,6 +214,33 @@ fn draw_ui(session: &Session, canvas: &mut shape2d::Batch, text: &mut TextBatch)
}
}

if let (Some(lss), Some(ltid)) = (&session.lookup_sample_state, view.lookuptexture()) {
match session.mode {
Mode::Visual(VisualState::LookupSampling) => {
let ltv = session.view(ltid);

let offset = session.offset + ltv.offset;
let t = Matrix4::from_translation(offset.extend(0.)) * Matrix4::from_scale(ltv.zoom);

for (i, c) in lss.candidates.iter().enumerate() {
let mut stroke = color::RED;
if i as i32 == lss.selected {
stroke = color::GREEN;
}

canvas.add(Shape::Rectangle(
c.0.transform(t),
self::UI_LAYER,
Rotation::ZERO,
Stroke::new(1., stroke.into()),
Fill::Empty,
));
}
}
_ => ()
};
}

for v in session.views.iter() {
let offset = v.offset + session.offset;

Expand Down Expand Up @@ -254,14 +283,25 @@ fn draw_ui(session: &Session, canvas: &mut shape2d::Batch, text: &mut TextBatch)

if session.settings["ui/view-info"].is_set() {
// View info
text.add(
let x = text.add(
&format!("{}x{}x{}", v.fw, v.fh, v.animation.len()),
offset.x,
offset.y - self::LINE_HEIGHT,
self::TEXT_LAYER,
color::GREY,
TextAlign::Left,
);

if v.is_lookuptexture() {
text.add(
&format!(" LUT"),
x,
offset.y - self::LINE_HEIGHT,
self::TEXT_LAYER,
color::GREEN,
TextAlign::Left,
);
}
}
}
if session.settings["ui/status"].is_set() {
Expand Down Expand Up @@ -730,6 +770,20 @@ pub fn draw_view_animation<R>(session: &Session, v: &View<R>) -> sprite2d::Batch
)
}

pub fn draw_view_lookuptexture_animation<R>(session: &Session, v: &View<R>) -> sprite2d::Batch {
sprite2d::Batch::singleton(
v.width(),
v.fh,
*v.animation.val(),
Rect::new(-(v.fw as f32) * 2., 0., -(v.fw as f32), v.fh as f32) * v.zoom + (session.offset + v.offset),
self::VIEW_LAYER,
Rgba::TRANSPARENT,
1.,
Repeat::default(),
)
}


pub fn draw_view_composites<R>(session: &Session, v: &View<R>) -> sprite2d::Batch {
let mut batch = sprite2d::Batch::new(v.width(), v.fh);

Expand Down
4 changes: 3 additions & 1 deletion src/font.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ impl TextBatch {
z: ZDepth,
color: Rgba8,
align: TextAlign,
) {
) -> f32 {
let offset: usize = 32;

let gw = self.gw;
Expand Down Expand Up @@ -56,6 +56,8 @@ impl TextBatch {
);
sx += gw;
}

return sx;
}

pub fn offset(&mut self, x: f32, y: f32) {
Expand Down
38 changes: 38 additions & 0 deletions src/gl/data/lookuptex.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
uniform sampler2D tex;
uniform sampler2D ltex;
uniform vec2 ltexreg; // lookup texture region normalization vector

in vec2 f_uv;
in vec4 f_color;
in float f_opacity;

out vec4 fragColor;

vec3 linearTosRGB(vec3 linear) {
vec3 lower = linear * 12.92;
vec3 higher = 1.055 * pow(linear, vec3(1.0 / 2.4)) - 0.055;

// Use smoothstep for a smoother transition
vec3 transition = smoothstep(vec3(0.0031308 - 0.00001), vec3(0.0031308 + 0.00001), linear);

return mix(lower, higher, transition);
}

void main() {
vec4 texel = texture(tex, f_uv);
texel = vec4(linearTosRGB(texel.rgb), texel.a); // Convert to linear space
texel.rg = texel.rg * ltexreg;
texel.rg = texel.rg + vec2(0.001953125, 0.001953125);
if (texel.a > 0.0) { // Non-transparent pixel
vec4 lt_texel = texture(ltex, texel.rg);
fragColor = vec4(
mix(lt_texel.rgb, f_color.rgb, f_color.a),
lt_texel.a * f_opacity
);
} else {
fragColor = vec4(
mix(texel.rgb, f_color.rgb, f_color.a),
texel.a * f_opacity
);
}
}
28 changes: 28 additions & 0 deletions src/gl/data/lookuptex.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
uniform mat4 ortho;
uniform mat4 transform;

in vec3 position;
in vec2 uv;
in vec4 color;
in float opacity;

out vec2 f_uv;
out vec4 f_color;
out float f_opacity;

// Convert an sRGB color to linear space.
vec3 linearize(vec3 srgb) {
bvec3 cutoff = lessThan(srgb, vec3(0.04045));
vec3 higher = pow((srgb + vec3(0.055)) / vec3(1.055), vec3(2.4));
vec3 lower = srgb / vec3(12.92);

return mix(higher, lower, cutoff);
}

void main() {
f_color = vec4(linearize(color.rgb), color.a);
f_uv = uv;
f_opacity = opacity;

gl_Position = ortho * transform * vec4(position, 1.0);
}
Loading