rearrange ui graphic code

Former-commit-id: d0ea7feee59a1daf4ad93e9b9224750deb75ee45
This commit is contained in:
Imbris 2019-04-19 14:55:38 -04:00
parent 0b4e268dee
commit 7707636c4e
6 changed files with 132 additions and 163 deletions

View File

@ -65,13 +65,13 @@ impl Mode {
}
}
pub fn create_quad(rect: Aabr<f32>, uv_rect: Aabr<f32>, color: [f32; 4], mode: Mode) -> Quad<UiPipeline> {
pub fn create_quad(rect: Aabr<f32>, uv_rect: Aabr<f32>, color: Rgba<f32>, mode: Mode) -> Quad<UiPipeline> {
let mode_val = mode.value();
let v = |pos, uv| {
Vertex {
pos,
uv,
color,
color: color.into_array(),
mode: mode_val,
}
};
@ -90,13 +90,13 @@ pub fn create_quad(rect: Aabr<f32>, uv_rect: Aabr<f32>, color: [f32; 4], mode: M
)
}
pub fn create_tri(tri: [[f32; 2]; 3], uv_tri: [[f32; 2]; 3], color: [f32; 4], mode: Mode) -> Tri<UiPipeline> {
pub fn create_tri(tri: [[f32; 2]; 3], uv_tri: [[f32; 2]; 3], color: Rgba<f32>, mode: Mode) -> Tri<UiPipeline> {
let mode_val = mode.value();
let v = |pos, uv| {
Vertex {
pos,
uv,
color,
color: color.into_array(),
mode: mode_val,
}
};

View File

@ -1,11 +1,7 @@
use common::figure::Segment;
use image::DynamicImage;
use guillotiere::{
AtlasAllocator,
Allocation,
size2,
};
use fnv::FnvHashMap;
use guillotiere::{size2, Allocation, AtlasAllocator};
use image::DynamicImage;
use vek::*;
pub enum Graphic {
@ -45,14 +41,30 @@ impl GraphicCache {
pub fn get_graphic(&self, id: Id) -> Option<&Graphic> {
self.graphic_map.get(&id)
}
pub fn cache_res<F>(&mut self, graphic_id: Id, dims: Vec2<u16>, source: Aabr<f64>, mut cacher: F) -> Option<Aabr<u16>> where F: FnMut(Aabr<u16>, Vec<[u8; 4]>) {
match self.rect_map.get(&(graphic_id, dims, source.map(|e| e.to_bits()))) { //<-------- TODO: Replace this with rounded representation of source
pub fn cache_res<F>(
&mut self,
graphic_id: Id,
dims: Vec2<u16>,
source: Aabr<f64>,
mut cacher: F,
) -> Option<Aabr<u16>>
where
F: FnMut(Aabr<u16>, Vec<[u8; 4]>),
{
match self
.rect_map
.get(&(graphic_id, dims, source.map(|e| e.to_bits())))
{
//<-------- TODO: Replace this with rounded representation of source
Some(aabr) => Some(*aabr),
None => match self.graphic_map.get(&graphic_id) {
Some(graphic) => {
// Allocate rectangle
let aabr = match self.atlas.allocate(size2(i32::from(dims.x + 2), i32::from(dims.y + 2))) {
Some(Allocation{id, rectangle}) => {
let aabr = match self
.atlas
.allocate(size2(i32::from(dims.x + 2), i32::from(dims.y + 2)))
{
Some(Allocation { id, rectangle }) => {
let (min, max) = (rectangle.min, rectangle.max);
Aabr {
min: Vec2::new(min.x as u16 + 1, min.y as u16 + 1),
@ -67,16 +79,18 @@ impl GraphicCache {
// Render image
// TODO: use source
let data = match graphic {
Graphic::Image(ref image) => {
image
.resize_exact(u32::from(aabr.size().w), u32::from(aabr.size().h), image::FilterType::Nearest)
.to_rgba()
.pixels()
.map(|p| p.data)
.collect::<Vec<[u8; 4]>>()
}
Graphic::Image(ref image) => image
.resize_exact(
u32::from(aabr.size().w),
u32::from(aabr.size().h),
image::FilterType::Nearest,
)
.to_rgba()
.pixels()
.map(|p| p.data)
.collect::<Vec<[u8; 4]>>(),
Graphic::Voxel(segment) => {
super::veuc::draw_vox(&segment, aabr.size().into())
super::renderer::draw_vox(&segment, aabr.size().into())
}
Graphic::Blank => return None,
};
@ -85,13 +99,14 @@ impl GraphicCache {
cacher(aabr, data);
// Insert area into map for retrieval
self.rect_map.insert((graphic_id, dims, source.map(|e| e.to_bits())), aabr);
self.rect_map
.insert((graphic_id, dims, source.map(|e| e.to_bits())), aabr);
// Return area
Some(aabr)
}
None => None,
}
},
}
}
}
}

View File

@ -0,0 +1,4 @@
mod graphic;
mod renderer;
pub use graphic::{Graphic, GraphicCache, Id};

View File

@ -1,20 +1,11 @@
use euc::{
Pipeline,
rasterizer,
buffer::Buffer2d,
Interpolate,
};
use super::super::{linear_to_srgb, srgb_to_linear};
use common::{
figure::Segment,
vol::{
Vox,
SizedVol,
ReadVol,
},
vol::{ReadVol, SizedVol, Vox},
};
use euc::{buffer::Buffer2d, rasterizer, Pipeline};
use vek::*;
struct Voxel {
mvp: Mat4<f32>,
}
@ -43,15 +34,25 @@ impl<'a> Pipeline for Voxel {
type Pixel = [u8; 4];
#[inline(always)]
fn vert(&self, Vert { pos, col, norm, ao_level}: &Self::Vertex) -> ([f32; 3], Self::VsOut) {
let light = Rgba::from_opaque(Rgb::from(*ao_level as f32 / 4.0 + 0.25));
fn vert(
&self,
Vert {
pos,
col,
norm,
ao_level,
}: &Self::Vertex,
) -> ([f32; 3], Self::VsOut) {
let light = Rgba::from_opaque(Rgb::from(*ao_level as f32 / 4.0 + 0.25));
let color = light * srgb_to_linear(Rgba::from_opaque(*col));
let position = Vec3::from(self.mvp * Vec4::from_point(*pos)).into_array();
(position, color)
}
#[inline(always)]
fn frag(&self, color: &Self::VsOut) -> Self::Pixel {
linear_to_srgb(*color).map(|e| (e * 255.0) as u8).into_array()
linear_to_srgb(*color)
.map(|e| (e * 255.0) as u8)
.into_array()
}
}
@ -62,17 +63,16 @@ pub fn draw_vox(segment: &Segment, output_size: Vec2<u16>) -> Vec<[u8; 4]> {
let (w, h, d) = segment.get_size().map(|e| e as f32).into_tuple();
let mvp =
Mat4::<f32>::orthographic_rh_no(FrustumPlanes {
left: -1.0, right: 1.0, bottom: -1.0, top: 1.0,
near: 0.0, far: 1.0
}) *
Mat4::scaling_3d(2.0 / w.max(h)) *
Mat4::translation_3d([-w / 2.0, -h / 2.0, -d / 2.0]);
Voxel {
mvp,
}
.draw::<rasterizer::Triangles<_>, _>(
let mvp = Mat4::<f32>::orthographic_rh_no(FrustumPlanes {
left: -1.0,
right: 1.0,
bottom: -1.0,
top: 1.0,
near: 0.0,
far: 1.0,
}) * Mat4::scaling_3d(2.0 / w.max(h))
* Mat4::translation_3d([-w / 2.0, -h / 2.0, -d / 2.0]);
Voxel { mvp }.draw::<rasterizer::Triangles<_>, _>(
&generate_mesh(segment, Vec3::from(0.0)),
&mut color,
&mut depth,
@ -98,7 +98,6 @@ fn create_quad(
col: Rgb<f32>,
occluders: [bool; 8],
) -> [Vert; 6] {
let a_ao = ao_level(occluders[0], occluders[1], occluders[2]);
let b_ao = ao_level(occluders[2], occluders[3], occluders[4]);
let c_ao = ao_level(occluders[4], occluders[5], occluders[6]);
@ -126,18 +125,10 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
let mut vertices = Vec::new();
for pos in segment.iter_positions() {
if let Some(col) = segment
.get(pos)
.ok()
.and_then(|vox| vox.get_color())
{
if let Some(col) = segment.get(pos).ok().and_then(|vox| vox.get_color()) {
let col = col.map(|e| e as f32 / 255.0);
let is_empty = |pos| {
segment.get(pos)
.map(|v| v.is_empty())
.unwrap_or(true)
};
let is_empty = |pos| segment.get(pos).map(|v| v.is_empty()).unwrap_or(true);
let occluders = |unit_x, unit_y, dir| {
// would be nice to generate unit_x and unit_y from a given direction
@ -154,99 +145,69 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
};
// -x
if is_empty(pos - Vec3::unit_x())
{
if is_empty(pos - Vec3::unit_x()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(),
-Vec3::unit_y(),
Vec3::unit_z(),
-Vec3::unit_x(),
col,
occluders(
-Vec3::unit_y(),
Vec3::unit_z(),
-Vec3::unit_x(),
),
occluders(-Vec3::unit_y(), Vec3::unit_z(), -Vec3::unit_x()),
));
}
// +x
if is_empty(pos + Vec3::unit_x())
{
if is_empty(pos + Vec3::unit_x()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_x(),
Vec3::unit_y(),
Vec3::unit_z(),
Vec3::unit_x(),
col,
occluders(
Vec3::unit_y(),
Vec3::unit_z(),
Vec3::unit_x(),
),
occluders(Vec3::unit_y(), Vec3::unit_z(), Vec3::unit_x()),
));
}
// -y
if is_empty(pos - Vec3::unit_y())
{
if is_empty(pos - Vec3::unit_y()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32),
Vec3::unit_x(),
Vec3::unit_z(),
-Vec3::unit_y(),
col,
occluders(
Vec3::unit_x(),
Vec3::unit_z(),
-Vec3::unit_y(),
),
occluders(Vec3::unit_x(), Vec3::unit_z(), -Vec3::unit_y()),
));
}
// +y
if is_empty(pos + Vec3::unit_y())
{
if is_empty(pos + Vec3::unit_y()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_y(),
Vec3::unit_z(),
Vec3::unit_x(),
Vec3::unit_y(),
col,
occluders(
Vec3::unit_z(),
Vec3::unit_x(),
Vec3::unit_y(),
),
occluders(Vec3::unit_z(), Vec3::unit_x(), Vec3::unit_y()),
));
}
// -z
if is_empty(pos - Vec3::unit_z())
{
if is_empty(pos - Vec3::unit_z()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32),
Vec3::unit_y(),
Vec3::unit_x(),
-Vec3::unit_z(),
col,
occluders(
Vec3::unit_y(),
Vec3::unit_x(),
-Vec3::unit_z(),
),
occluders(Vec3::unit_y(), Vec3::unit_x(), -Vec3::unit_z()),
));
}
// +z
if is_empty(pos + Vec3::unit_z())
{
if is_empty(pos + Vec3::unit_z()) {
vertices.extend_from_slice(&create_quad(
offs + pos.map(|e| e as f32) + Vec3::unit_z(),
Vec3::unit_x(),
Vec3::unit_y(),
Vec3::unit_z(),
col,
occluders(
Vec3::unit_x(),
Vec3::unit_y(),
Vec3::unit_z(),
),
occluders(Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()),
));
}
}
@ -254,39 +215,3 @@ fn generate_mesh(segment: &Segment, offs: Vec3<f32>) -> Vec<Vert> {
vertices
}
// TODO: put these in utility a module
#[inline(always)]
fn srgb_to_linear(c: Rgba<f32>) -> Rgba<f32> {
#[inline(always)]
fn to_linear(x: f32) -> f32 {
if x <= 0.04045 {
x / 12.92
} else {
((x + 0.055) / 1.055).powf(2.4)
}
}
Rgba {
r: to_linear(c.r),
g: to_linear(c.g),
b: to_linear(c.b),
a: c.a,
}
}
#[inline(always)]
fn linear_to_srgb(c: Rgba<f32>) -> Rgba<f32> {
#[inline(always)]
fn to_srgb(x: f32) -> f32 {
if x <= 0.0031308 {
x * 12.92
} else {
x.powf(1.0 / 2.4) * 1.055 - 0.055
}
}
Rgba {
r: to_srgb(c.r),
g: to_srgb(c.g),
b: to_srgb(c.b),
a: c.a,
}
}

View File

@ -1,15 +1,15 @@
mod widgets;
mod graphic;
mod veuc;
mod util;
pub use widgets::toggle_button::ToggleButton;
pub use graphic::Graphic;
pub(self) use util::{srgb_to_linear, linear_to_srgb};
use graphic::{
GraphicCache,
Id as GraphicId,
};
use image::DynamicImage;
use conrod_core::{
Ui as CrUi,
UiBuilder,
@ -23,7 +23,7 @@ use conrod_core::{
widget::{Id as WidgId, id::Generator},
render::Primitive,
event::Input,
input::{touch::Touch, Widget, Motion, Button, MouseButton},
input::{touch::Touch, Widget, Motion, Button},
};
use vek::*;
use crate::{
@ -410,7 +410,7 @@ impl Ui {
current_state = State::Image;
}
let color = srgb_to_linear(color.unwrap_or(conrod_core::color::WHITE).to_fsa());
let color = srgb_to_linear(color.unwrap_or(conrod_core::color::WHITE).to_fsa().into());
let resolution = Vec2::new(
@ -481,7 +481,7 @@ impl Ui {
renderer.update_texture(cache_tex, offset, size, &new_data);
}).unwrap();
let color = srgb_to_linear(color.to_fsa());
let color = srgb_to_linear(color.to_fsa().into());
for g in positioned_glyphs {
if let Ok(Some((uv_rect, screen_rect))) = glyph_cache.rect_for(font_id.index(), g) {
@ -509,7 +509,7 @@ impl Ui {
}
}
PrimitiveKind::Rectangle { color } => {
let color = srgb_to_linear(color.to_fsa());
let color = srgb_to_linear(color.to_fsa().into());
// Don't draw a transparent rectangle
if color[3] == 0.0 {
continue;
@ -529,7 +529,7 @@ impl Ui {
}
PrimitiveKind::TrianglesSingleColor { color, triangles } => {
// Don't draw transparent triangle or switch state if there are actually no triangles
let color: [f32; 4] = srgb_to_linear(color.into());
let color = srgb_to_linear(Rgba::from(Into::<[f32; 4]>::into(color)));
if triangles.is_empty() || color[3] == 0.0 {
continue;
}
@ -561,9 +561,10 @@ impl Ui {
}
_ => {}
// TODO: Add these
//PrimitiveKind::Other {..} => {println!("primitive kind other with id {:?}", id);}
// TODO: Add this
//PrimitiveKind::TrianglesMultiColor {..} => {println!("primitive kind multicolor with id {:?}", id);}
// Other uneeded for now
//PrimitiveKind::Other {..} => {println!("primitive kind other with id {:?}", id);}
}
}
// Enter the final command
@ -612,16 +613,4 @@ fn default_scissor(renderer: &mut Renderer) -> Aabr<u16> {
min: Vec2 { x: 0, y: 0 },
max: Vec2 { x: screen_w, y: screen_h }
}
}
fn srgb_to_linear(color: [f32; 4]) -> [f32; 4] {
fn linearize(comp: f32) -> f32 {
if comp <= 0.04045 {
comp / 12.92
} else {
((comp + 0.055) / 1.055).powf(2.4)
}
}
[linearize(color[0]), linearize(color[1]), linearize(color[2]), color[3]]
}
}

36
voxygen/src/ui/util.rs Normal file
View File

@ -0,0 +1,36 @@
use vek::*;
#[inline(always)]
pub fn srgb_to_linear(c: Rgba<f32>) -> Rgba<f32> {
#[inline(always)]
fn to_linear(x: f32) -> f32 {
if x <= 0.04045 {
x / 12.92
} else {
((x + 0.055) / 1.055).powf(2.4)
}
}
Rgba {
r: to_linear(c.r),
g: to_linear(c.g),
b: to_linear(c.b),
a: c.a,
}
}
#[inline(always)]
pub fn linear_to_srgb(c: Rgba<f32>) -> Rgba<f32> {
#[inline(always)]
fn to_srgb(x: f32) -> f32 {
if x <= 0.0031308 {
x * 12.92
} else {
x.powf(1.0 / 2.4) * 1.055 - 0.055
}
}
Rgba {
r: to_srgb(c.r),
g: to_srgb(c.g),
b: to_srgb(c.b),
a: c.a,
}
}