mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
rearrange ui graphic code
Former-commit-id: d0ea7feee59a1daf4ad93e9b9224750deb75ee45
This commit is contained in:
parent
0b4e268dee
commit
7707636c4e
@ -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,
|
||||
}
|
||||
};
|
||||
|
@ -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,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
4
voxygen/src/ui/graphic/mod.rs
Normal file
4
voxygen/src/ui/graphic/mod.rs
Normal file
@ -0,0 +1,4 @@
|
||||
mod graphic;
|
||||
mod renderer;
|
||||
|
||||
pub use graphic::{Graphic, GraphicCache, Id};
|
@ -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,
|
||||
}
|
||||
}
|
@ -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
36
voxygen/src/ui/util.rs
Normal 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,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user