mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
ingame_ui
Former-commit-id: 5e836043d58f9217d711462d9f700e3eb096a076
This commit is contained in:
parent
f839b623f4
commit
7fd3854093
@ -1,9 +1,16 @@
|
||||
#version 330 core
|
||||
|
||||
#include <globals.glsl>
|
||||
|
||||
in vec2 f_uv;
|
||||
in vec4 f_color;
|
||||
flat in uint f_mode;
|
||||
|
||||
layout (std140)
|
||||
uniform u_locals {
|
||||
vec4 w_pos;
|
||||
};
|
||||
|
||||
uniform sampler2D u_tex;
|
||||
|
||||
out vec4 tgt_color;
|
||||
|
@ -1,10 +1,17 @@
|
||||
#version 330 core
|
||||
|
||||
#include <globals.glsl>
|
||||
|
||||
in vec2 v_pos;
|
||||
in vec2 v_uv;
|
||||
in vec4 v_color;
|
||||
in uint v_mode;
|
||||
|
||||
layout (std140)
|
||||
uniform u_locals {
|
||||
vec4 w_pos;
|
||||
};
|
||||
|
||||
uniform sampler2D u_tex;
|
||||
|
||||
out vec2 f_uv;
|
||||
@ -14,6 +21,15 @@ out vec4 f_color;
|
||||
void main() {
|
||||
f_uv = v_uv;
|
||||
f_color = v_color;
|
||||
gl_Position = vec4(v_pos, 0.0, 1.0);
|
||||
|
||||
if (w_pos.w == 1.0) {
|
||||
// In-game element
|
||||
gl_Position =
|
||||
proj_mat *
|
||||
(view_mat * w_pos + vec4(v_pos, 0.0, 0.0));
|
||||
} else {
|
||||
// Interface element
|
||||
gl_Position = vec4(v_pos, 0.0, 1.0);
|
||||
}
|
||||
f_mode = v_mode;
|
||||
}
|
||||
|
@ -23,17 +23,20 @@ use skillbar::Skillbar;
|
||||
use small_window::{SmallWindow, SmallWindowType};
|
||||
|
||||
use crate::{
|
||||
render::Renderer,
|
||||
render::{Consts, Globals, Renderer},
|
||||
settings::{ControlSettings, Settings},
|
||||
ui::{ScaleMode, Ui},
|
||||
ui::{Ingame, ScaleMode, Ui},
|
||||
window::{Event as WinEvent, Key, Window},
|
||||
GlobalState,
|
||||
};
|
||||
use client::Client;
|
||||
use common::comp;
|
||||
use conrod_core::{
|
||||
color, graph,
|
||||
widget::{self, Button, Image, Rectangle, Text},
|
||||
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget,
|
||||
};
|
||||
use specs::Join;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
const XP_COLOR: Color = Color::Rgba(0.59, 0.41, 0.67, 1.0);
|
||||
@ -43,7 +46,11 @@ const MANA_COLOR: Color = Color::Rgba(0.42, 0.41, 0.66, 1.0);
|
||||
|
||||
widget_ids! {
|
||||
struct Ids {
|
||||
// Character Names
|
||||
name_tags[],
|
||||
|
||||
// Test
|
||||
temp,
|
||||
bag_space_add,
|
||||
// Debug
|
||||
debug_bg,
|
||||
@ -253,7 +260,7 @@ impl Hud {
|
||||
}
|
||||
}
|
||||
|
||||
fn update_layout(&mut self, global_state: &GlobalState, debug_info: DebugInfo) -> Vec<Event> {
|
||||
fn update_layout(&mut self, client: &Client, global_state: &GlobalState, debug_info: DebugInfo) -> Vec<Event> {
|
||||
let mut events = Vec::new();
|
||||
let ref mut ui_widgets = self.ui.set_widgets();
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
@ -263,6 +270,34 @@ impl Hud {
|
||||
return events;
|
||||
}
|
||||
|
||||
// Nametags
|
||||
let ecs = client.state().ecs();
|
||||
/* {
|
||||
let actor_read_storage = ecs.read_storage::<comp::Actor>();
|
||||
let pos_read_storage = ecs.read_storage::<comp::phys::Pos>();
|
||||
let num = (&actor_read_storage, &pos_read_storage).join().count();
|
||||
self.ids
|
||||
.name_tags
|
||||
.resize(num, &mut ui_widgets.widget_id_generator());
|
||||
for (i, (name, pos)) in (&actor_read_storage, &pos_read_storage)
|
||||
.join()
|
||||
.map(|(actor, pos)| match actor {
|
||||
comp::Actor::Character { name, .. } => (name, pos.0),
|
||||
})
|
||||
.enumerate()
|
||||
{
|
||||
Ingame::from_primitive(pos, Text::new(&name))
|
||||
.set(self.ids.name_tags[i], ui_widgets);
|
||||
}
|
||||
}*/
|
||||
// test
|
||||
Ingame::from_primitive(
|
||||
[0.0, 25.0, 25.0].into(),
|
||||
Rectangle::fill_with([1.0, 1.0], Color::Rgba(0.2, 0.0, 0.4, 1.0)),
|
||||
)
|
||||
.x_y(0.0, 0.0)
|
||||
.set(self.ids.temp, ui_widgets);
|
||||
|
||||
// Display debug window.
|
||||
if self.show.debug {
|
||||
// Alpha Version
|
||||
@ -474,7 +509,9 @@ impl Hud {
|
||||
self.ui
|
||||
.widget_graph()
|
||||
.widget(id)
|
||||
.and_then(graph::Container::unique_widget_state::<widget::TextEdit>)
|
||||
.filter(|c| {
|
||||
c.type_id == std::any::TypeId::of::<<widget::TextEdit as Widget>::State>()
|
||||
})
|
||||
.is_some()
|
||||
} else {
|
||||
false
|
||||
@ -580,19 +617,20 @@ impl Hud {
|
||||
|
||||
pub fn maintain(
|
||||
&mut self,
|
||||
client: &Client,
|
||||
global_state: &mut GlobalState,
|
||||
debug_info: DebugInfo,
|
||||
) -> Vec<Event> {
|
||||
if let Some(maybe_id) = self.to_focus.take() {
|
||||
self.ui.focus_widget(maybe_id);
|
||||
}
|
||||
let events = self.update_layout(&global_state, debug_info);
|
||||
let events = self.update_layout(client, global_state, debug_info);
|
||||
self.ui.maintain(&mut global_state.window.renderer_mut());
|
||||
events
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
self.ui.render(renderer);
|
||||
pub fn render(&self, renderer: &mut Renderer, globals: &Consts<Globals>) {
|
||||
self.ui.render(renderer, Some(globals));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ impl PlayState for CharSelectionState {
|
||||
|
||||
// Draw the UI to the screen.
|
||||
self.char_selection_ui
|
||||
.render(global_state.window.renderer_mut());
|
||||
.render(global_state.window.renderer_mut(), self.scene.globals());
|
||||
|
||||
// Tick the client (currently only to keep the connection alive).
|
||||
self.client
|
||||
|
@ -72,6 +72,10 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn globals(&self) -> &Consts<Globals> {
|
||||
&self.globals
|
||||
}
|
||||
|
||||
pub fn maintain(&mut self, renderer: &mut Renderer, client: &Client) {
|
||||
self.camera.set_focus_pos(Vec3::unit_z() * 2.0);
|
||||
self.camera.update(client.state().get_time());
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
render::Renderer,
|
||||
render::{Consts, Globals, Renderer},
|
||||
ui::{
|
||||
self,
|
||||
img_ids::{ImageGraphic, VoxelGraphic},
|
||||
@ -1085,7 +1085,7 @@ impl CharSelectionUi {
|
||||
events
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
self.ui.render(renderer);
|
||||
pub fn render(&self, renderer: &mut Renderer, globals: &Consts<Globals>) {
|
||||
self.ui.render(renderer, Some(globals));
|
||||
}
|
||||
}
|
||||
|
@ -513,6 +513,6 @@ impl MainMenuUi {
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
self.ui.render(renderer);
|
||||
self.ui.render(renderer, None);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,8 @@ pub use self::{
|
||||
skybox::{create_mesh as create_skybox_mesh, Locals as SkyboxLocals, SkyboxPipeline},
|
||||
terrain::{Locals as TerrainLocals, TerrainPipeline},
|
||||
ui::{
|
||||
create_quad as create_ui_quad, create_tri as create_ui_tri, Mode as UiMode, UiPipeline,
|
||||
create_quad as create_ui_quad, create_tri as create_ui_tri, Locals as UiLocals,
|
||||
Mode as UiMode, UiPipeline,
|
||||
},
|
||||
Globals,
|
||||
},
|
||||
|
@ -1,6 +1,7 @@
|
||||
use super::super::{Pipeline, Quad, Tri, WinColorFmt, WinDepthFmt};
|
||||
use super::super::{Globals, Pipeline, Quad, Tri, WinColorFmt, WinDepthFmt};
|
||||
use gfx::{
|
||||
self,
|
||||
gfx_constant_struct_meta,
|
||||
// Macros
|
||||
gfx_defines,
|
||||
gfx_impl_struct_meta,
|
||||
@ -18,15 +19,21 @@ gfx_defines! {
|
||||
mode: u32 = "v_mode",
|
||||
}
|
||||
|
||||
constant Locals {
|
||||
pos: [f32; 4] = "w_pos",
|
||||
}
|
||||
|
||||
pipeline pipe {
|
||||
vbuf: gfx::VertexBuffer<Vertex> = (),
|
||||
|
||||
locals: gfx::ConstantBuffer<Locals> = "u_locals",
|
||||
globals: gfx::ConstantBuffer<Globals> = "u_globals",
|
||||
tex: gfx::TextureSampler<[f32; 4]> = "u_tex",
|
||||
|
||||
scissor: gfx::Scissor = (),
|
||||
|
||||
tgt_color: gfx::BlendTarget<WinColorFmt> = ("tgt_color", gfx::state::ColorMask::all(), gfx::preset::blend::ALPHA),
|
||||
tgt_depth: gfx::DepthTarget<WinDepthFmt> = gfx::preset::depth::PASS_TEST,
|
||||
tgt_depth: gfx::DepthTarget<WinDepthFmt> = gfx::preset::depth::LESS_EQUAL_WRITE,
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +43,20 @@ impl Pipeline for UiPipeline {
|
||||
type Vertex = Vertex;
|
||||
}
|
||||
|
||||
impl From<Vec3<f32>> for Locals {
|
||||
fn from(pos: Vec3<f32>) -> Self {
|
||||
Self {
|
||||
pos: [pos[0], pos[1], pos[2], 1.0],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Locals {
|
||||
fn default() -> Self {
|
||||
Self { pos: [0.0; 4] }
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw text from the text cache texture `tex` in the fragment shader.
|
||||
pub const MODE_TEXT: u32 = 0;
|
||||
/// Draw an image from the texture at `tex` in the fragment shader.
|
||||
|
@ -423,6 +423,8 @@ impl Renderer {
|
||||
model: &Model<ui::UiPipeline>,
|
||||
tex: &Texture<ui::UiPipeline>,
|
||||
scissor: Aabr<u16>,
|
||||
globals: &Consts<Globals>,
|
||||
locals: &Consts<ui::Locals>,
|
||||
) {
|
||||
let Aabr { min, max } = scissor;
|
||||
self.encoder.draw(
|
||||
@ -437,6 +439,8 @@ impl Renderer {
|
||||
h: max.y - min.y,
|
||||
},
|
||||
tex: (tex.srv.clone(), tex.sampler.clone()),
|
||||
locals: locals.buf.clone(),
|
||||
globals: globals.buf.clone(),
|
||||
tgt_color: self.win_color_view.clone(),
|
||||
tgt_depth: self.win_depth_view.clone(),
|
||||
},
|
||||
|
@ -68,6 +68,11 @@ impl Scene {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a reference to the scene's globals
|
||||
pub fn globals(&self) -> &Consts<Globals> {
|
||||
&self.globals
|
||||
}
|
||||
|
||||
/// Get a reference to the scene's camera.
|
||||
pub fn camera(&self) -> &Camera {
|
||||
&self.camera
|
||||
|
@ -100,7 +100,7 @@ impl SessionState {
|
||||
// Render the screen using the global renderer
|
||||
self.scene.render(renderer, &mut self.client.borrow_mut());
|
||||
// Draw the UI to the screen
|
||||
self.hud.render(renderer);
|
||||
self.hud.render(renderer, self.scene.globals());
|
||||
|
||||
// Finish the frame
|
||||
renderer.flush();
|
||||
@ -178,6 +178,7 @@ impl PlayState for SessionState {
|
||||
|
||||
// extract HUD events ensuring the client borrow gets dropped
|
||||
let hud_events = self.hud.maintain(
|
||||
&self.client.borrow(),
|
||||
global_state,
|
||||
DebugInfo {
|
||||
tps: clock.get_tps(),
|
||||
|
@ -12,12 +12,12 @@ mod font_ids;
|
||||
pub use event::Event;
|
||||
pub use graphic::Graphic;
|
||||
pub use scale::ScaleMode;
|
||||
pub use widgets::{image_slider::ImageSlider, toggle_button::ToggleButton};
|
||||
pub use widgets::{image_slider::ImageSlider, ingame::Ingame, toggle_button::ToggleButton};
|
||||
|
||||
use crate::{
|
||||
render::{
|
||||
create_ui_quad, create_ui_tri, DynamicModel, Mesh, RenderError, Renderer, UiMode,
|
||||
UiPipeline,
|
||||
create_ui_quad, create_ui_tri, Consts, DynamicModel, Globals, Mesh, RenderError, Renderer,
|
||||
UiLocals, UiMode, UiPipeline,
|
||||
},
|
||||
window::Window,
|
||||
Error,
|
||||
@ -27,11 +27,11 @@ use common::assets;
|
||||
use conrod_core::{
|
||||
event::Input,
|
||||
graph::Graph,
|
||||
image::{Id as ImgId, Map},
|
||||
image::{self, Map},
|
||||
input::{touch::Touch, Motion, Widget},
|
||||
render::Primitive,
|
||||
render::{Primitive, PrimitiveKind},
|
||||
text::{self, font},
|
||||
widget::{id::Generator, Id as WidgId},
|
||||
widget::{self, id::Generator},
|
||||
Ui as CrUi, UiBuilder, UiCell,
|
||||
};
|
||||
use graphic::Id as GraphicId;
|
||||
@ -55,6 +55,7 @@ enum DrawKind {
|
||||
enum DrawCommand {
|
||||
Draw { kind: DrawKind, verts: Range<usize> },
|
||||
Scissor(Aabr<u16>),
|
||||
WorldPos(Option<Consts<UiLocals>>),
|
||||
}
|
||||
impl DrawCommand {
|
||||
fn image(verts: Range<usize>) -> DrawCommand {
|
||||
@ -88,6 +89,9 @@ pub struct Ui {
|
||||
draw_commands: Vec<DrawCommand>,
|
||||
// Model for drawing the ui
|
||||
model: DynamicModel<UiPipeline>,
|
||||
// Consts for default ui drawing position (ie the interface)
|
||||
interface_locals: Consts<UiLocals>,
|
||||
default_globals: Consts<Globals>,
|
||||
// Window size for updating scaling
|
||||
window_resized: Option<Vec2<f64>>,
|
||||
// Scaling of the ui
|
||||
@ -99,12 +103,16 @@ impl Ui {
|
||||
let scale = Scale::new(window, ScaleMode::Absolute(1.0));
|
||||
let win_dims = scale.scaled_window_size().into_array();
|
||||
|
||||
let mut renderer = window.renderer_mut();
|
||||
|
||||
Ok(Self {
|
||||
ui: UiBuilder::new(win_dims).build(),
|
||||
image_map: Map::new(),
|
||||
cache: Cache::new(window.renderer_mut())?,
|
||||
cache: Cache::new(renderer)?,
|
||||
draw_commands: vec![],
|
||||
model: window.renderer_mut().create_dynamic_model(100)?,
|
||||
model: renderer.create_dynamic_model(100)?,
|
||||
interface_locals: renderer.create_consts(&[UiLocals::default()])?,
|
||||
default_globals: renderer.create_consts(&[Globals::default()])?,
|
||||
window_resized: None,
|
||||
scale,
|
||||
})
|
||||
@ -118,7 +126,7 @@ impl Ui {
|
||||
self.ui.handle_event(Input::Resize(w, h));
|
||||
}
|
||||
|
||||
pub fn add_graphic(&mut self, graphic: Graphic) -> ImgId {
|
||||
pub fn add_graphic(&mut self, graphic: Graphic) -> image::Id {
|
||||
self.image_map.insert(self.cache.add_graphic(graphic))
|
||||
}
|
||||
|
||||
@ -135,7 +143,7 @@ impl Ui {
|
||||
}
|
||||
|
||||
// Accepts Option so widget can be unfocused.
|
||||
pub fn focus_widget(&mut self, id: Option<WidgId>) {
|
||||
pub fn focus_widget(&mut self, id: Option<widget::Id>) {
|
||||
self.ui.keyboard_capture(match id {
|
||||
Some(id) => id,
|
||||
None => self.ui.window,
|
||||
@ -143,7 +151,7 @@ impl Ui {
|
||||
}
|
||||
|
||||
// Get id of current widget capturing keyboard.
|
||||
pub fn widget_capturing_keyboard(&self) -> Option<WidgId> {
|
||||
pub fn widget_capturing_keyboard(&self) -> Option<widget::Id> {
|
||||
self.ui.global_input().current.widget_capturing_keyboard
|
||||
}
|
||||
|
||||
@ -189,7 +197,7 @@ impl Ui {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn widget_input(&self, id: WidgId) -> Widget {
|
||||
pub fn widget_input(&self, id: widget::Id) -> Widget {
|
||||
self.ui.widget_input(id)
|
||||
}
|
||||
|
||||
@ -216,6 +224,9 @@ impl Ui {
|
||||
let window_scissor = default_scissor(renderer);
|
||||
let mut current_scissor = window_scissor;
|
||||
|
||||
let mut in_world = None;
|
||||
let mut p_scale_factor = self.scale.scale_factor_physical();
|
||||
|
||||
// Switches to the `Plain` state and completes the previous `Command` if not already in the
|
||||
// `Plain` state.
|
||||
macro_rules! switch_to_plain_state {
|
||||
@ -223,14 +234,12 @@ impl Ui {
|
||||
if let State::Image = current_state {
|
||||
self.draw_commands
|
||||
.push(DrawCommand::image(start..mesh.vertices().len()));
|
||||
current_state = State::Plain;
|
||||
start = mesh.vertices().len();
|
||||
current_state = State::Plain;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
let p_scale_factor = self.scale.scale_factor_physical();
|
||||
|
||||
while let Some(prim) = primitives.next() {
|
||||
let Primitive {
|
||||
kind,
|
||||
@ -272,9 +281,29 @@ impl Ui {
|
||||
self.draw_commands.push(DrawCommand::Scissor(new_scissor));
|
||||
}
|
||||
|
||||
match in_world {
|
||||
Some(0) => {
|
||||
in_world = None;
|
||||
p_scale_factor = self.scale.scale_factor_physical();
|
||||
// Finish current state
|
||||
self.draw_commands.push(match current_state {
|
||||
State::Plain => DrawCommand::plain(start..mesh.vertices().len()),
|
||||
State::Image => DrawCommand::image(start..mesh.vertices().len()),
|
||||
});
|
||||
start = mesh.vertices().len();
|
||||
// Push new position command
|
||||
self.draw_commands.push(DrawCommand::WorldPos(None));
|
||||
}
|
||||
Some(n) => in_world = Some(n - 1),
|
||||
None => (),
|
||||
}
|
||||
|
||||
// Functions for converting for conrod scalar coords to GL vertex coords (-1.0 to 1.0).
|
||||
let ui_win_w = self.ui.win_w;
|
||||
let ui_win_h = self.ui.win_h;
|
||||
let (ui_win_w, ui_win_h) = if in_world.is_some() {
|
||||
(2.0, 2.0)
|
||||
} else {
|
||||
(self.ui.win_w, self.ui.win_h)
|
||||
};
|
||||
let vx = |x: f64| (x / ui_win_w * 2.0) as f32;
|
||||
let vy = |y: f64| (y / ui_win_h * 2.0) as f32;
|
||||
let gl_aabr = |rect: conrod_core::Rect| {
|
||||
@ -285,7 +314,6 @@ impl Ui {
|
||||
}
|
||||
};
|
||||
|
||||
use conrod_core::render::PrimitiveKind;
|
||||
match kind {
|
||||
PrimitiveKind::Image {
|
||||
image_id,
|
||||
@ -321,16 +349,17 @@ impl Ui {
|
||||
// Transform the source rectangle into uv coordinate.
|
||||
// TODO: Make sure this is right.
|
||||
let source_aabr = {
|
||||
let (uv_l, uv_r, uv_b, uv_t) = (0.0, 1.0, 0.0, 1.0); /*match source_rect {
|
||||
Some(src_rect) => {
|
||||
let (l, r, b, t) = src_rect.l_r_b_t();
|
||||
((l / image_w) as f32,
|
||||
(r / image_w) as f32,
|
||||
(b / image_h) as f32,
|
||||
(t / image_h) as f32)
|
||||
}
|
||||
None => (0.0, 1.0, 0.0, 1.0),
|
||||
};*/
|
||||
let (uv_l, uv_r, uv_b, uv_t) = (0.0, 1.0, 0.0, 1.0);
|
||||
/*match source_rect {
|
||||
Some(src_rect) => {
|
||||
let (l, r, b, t) = src_rect.l_r_b_t();
|
||||
((l / image_w) as f32,
|
||||
(r / image_w) as f32,
|
||||
(b / image_h) as f32,
|
||||
(t / image_h) as f32)
|
||||
}
|
||||
None => (0.0, 1.0, 0.0, 1.0),
|
||||
};*/
|
||||
Aabr {
|
||||
min: Vec2::new(uv_l, uv_b),
|
||||
max: Vec2::new(uv_r, uv_t),
|
||||
@ -371,13 +400,8 @@ impl Ui {
|
||||
font_id,
|
||||
} => {
|
||||
switch_to_plain_state!();
|
||||
// Get screen width and height.
|
||||
let (screen_w, screen_h) =
|
||||
renderer.get_resolution().map(|e| e as f32).into_tuple();
|
||||
// Calculate dpi factor.
|
||||
let dpi_factor = screen_w / ui_win_w as f32;
|
||||
|
||||
let positioned_glyphs = text.positioned_glyphs(dpi_factor);
|
||||
let positioned_glyphs = text.positioned_glyphs(p_scale_factor as f32);
|
||||
let (glyph_cache, cache_tex) = self.cache.glyph_cache_mut_and_tex();
|
||||
// Queue the glyphs to be cached.
|
||||
for glyph in positioned_glyphs {
|
||||
@ -410,12 +434,12 @@ impl Ui {
|
||||
};
|
||||
let rect = Aabr {
|
||||
min: Vec2::new(
|
||||
(screen_rect.min.x as f32 / screen_w - 0.5) * 2.0,
|
||||
(screen_rect.max.y as f32 / screen_h - 0.5) * -2.0,
|
||||
vx(screen_rect.min.x as f64 / p_scale_factor) - 1.0,
|
||||
1.0 - vy(screen_rect.max.y as f64 / p_scale_factor),
|
||||
),
|
||||
max: Vec2::new(
|
||||
(screen_rect.max.x as f32 / screen_w - 0.5) * 2.0,
|
||||
(screen_rect.min.y as f32 / screen_h - 0.5) * -2.0,
|
||||
vx(screen_rect.max.x as f64 / p_scale_factor) - 1.0,
|
||||
1.0 - vy(screen_rect.min.y as f64 / p_scale_factor),
|
||||
),
|
||||
};
|
||||
mesh.push_quad(create_ui_quad(rect, uv, color, UiMode::Text));
|
||||
@ -469,10 +493,32 @@ impl Ui {
|
||||
));
|
||||
}
|
||||
}
|
||||
PrimitiveKind::Other(container) => {
|
||||
if container.type_id == std::any::TypeId::of::<widgets::ingame::State>() {
|
||||
// Retrieve world position
|
||||
let pos = container
|
||||
.state_and_style::<widgets::ingame::State, widgets::ingame::Style>()
|
||||
.unwrap()
|
||||
.state
|
||||
.pos;
|
||||
// Finish current state
|
||||
self.draw_commands.push(match current_state {
|
||||
State::Plain => DrawCommand::plain(start..mesh.vertices().len()),
|
||||
State::Image => DrawCommand::image(start..mesh.vertices().len()),
|
||||
});
|
||||
start = mesh.vertices().len();
|
||||
// Push new position command
|
||||
self.draw_commands.push(DrawCommand::WorldPos(Some(
|
||||
renderer.create_consts(&[pos.into()]).unwrap(),
|
||||
)));
|
||||
|
||||
in_world = Some(1);
|
||||
p_scale_factor = self.scale.dpi_factor();
|
||||
}
|
||||
}
|
||||
_ => {} // TODO: Add this.
|
||||
//PrimitiveKind::TrianglesMultiColor {..} => {println!("primitive kind multicolor with id {:?}", id);}
|
||||
// Other unneeded for now.
|
||||
//PrimitiveKind::Other {..} => {println!("primitive kind other with id {:?}", id);}
|
||||
}
|
||||
}
|
||||
// Enter the final command.
|
||||
@ -506,12 +552,17 @@ impl Ui {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render(&self, renderer: &mut Renderer) {
|
||||
let mut scissor_to_render = default_scissor(renderer);
|
||||
pub fn render(&self, renderer: &mut Renderer, maybe_globals: Option<&Consts<Globals>>) {
|
||||
let mut scissor = default_scissor(renderer);
|
||||
let globals = maybe_globals.unwrap_or(&self.default_globals);
|
||||
let mut locals = &self.interface_locals;
|
||||
for draw_command in self.draw_commands.iter() {
|
||||
match draw_command {
|
||||
DrawCommand::Scissor(scissor) => {
|
||||
scissor_to_render = *scissor;
|
||||
DrawCommand::Scissor(new_scissor) => {
|
||||
scissor = *new_scissor;
|
||||
}
|
||||
DrawCommand::WorldPos(ref pos) => {
|
||||
locals = pos.as_ref().unwrap_or(&self.interface_locals);
|
||||
}
|
||||
DrawCommand::Draw { kind, verts } => {
|
||||
let tex = match kind {
|
||||
@ -519,7 +570,7 @@ impl Ui {
|
||||
DrawKind::Plain => self.cache.glyph_cache_tex(),
|
||||
};
|
||||
let model = self.model.submodel(verts.clone());
|
||||
renderer.render_ui_element(&model, &tex, scissor_to_render);
|
||||
renderer.render_ui_element(&model, &tex, scissor, globals, locals);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,10 @@ impl Scale {
|
||||
pub fn scale_factor_physical(&self) -> f64 {
|
||||
self.scale_factor_logical() * self.dpi_factor
|
||||
}
|
||||
// Get the dpi factor (ratio between physical and logical coordinates)
|
||||
pub fn dpi_factor(&self) -> f64 {
|
||||
self.dpi_factor
|
||||
}
|
||||
// Updates internal window size (and/or dpi_factor).
|
||||
pub fn window_resized(&mut self, new_dims: Vec2<f64>, renderer: &Renderer) {
|
||||
self.dpi_factor = renderer.get_resolution().x as f64 / new_dims.x;
|
||||
|
98
voxygen/src/ui/widgets/ingame.rs
Normal file
98
voxygen/src/ui/widgets/ingame.rs
Normal file
@ -0,0 +1,98 @@
|
||||
use conrod_core::{
|
||||
image,
|
||||
position::Dimension,
|
||||
widget::{self, button},
|
||||
widget_ids, Color, Position, Positionable, Rect, Sizeable, Ui, Widget, WidgetCommon,
|
||||
};
|
||||
use vek::*;
|
||||
|
||||
#[derive(Clone, WidgetCommon)]
|
||||
pub struct Ingame<W>
|
||||
where
|
||||
W: Widget,
|
||||
{
|
||||
#[conrod(common_builder)]
|
||||
common: widget::CommonBuilder,
|
||||
widget: W,
|
||||
pos: Vec3<f32>,
|
||||
}
|
||||
|
||||
// TODO: add convenience function to this trait
|
||||
pub trait Primitive {}
|
||||
impl Primitive for widget::Line {}
|
||||
impl Primitive for widget::Image {}
|
||||
impl<I> Primitive for widget::PointPath<I> {}
|
||||
impl Primitive for widget::Circle {}
|
||||
impl<S> Primitive for widget::Oval<S> {}
|
||||
impl<I> Primitive for widget::Polygon<I> {}
|
||||
impl Primitive for widget::Rectangle {}
|
||||
impl<S, I> Primitive for widget::Triangles<S, I> {}
|
||||
impl<'a> Primitive for widget::Text<'a> {}
|
||||
|
||||
widget_ids! {
|
||||
struct Ids {
|
||||
prim,
|
||||
}
|
||||
}
|
||||
|
||||
pub struct State {
|
||||
ids: Ids,
|
||||
pub pos: Vec3<f32>,
|
||||
}
|
||||
|
||||
pub type Style = ();
|
||||
|
||||
impl<W: Widget + Primitive> Ingame<W> {
|
||||
pub fn from_primitive(pos: Vec3<f32>, widget: W) -> Self {
|
||||
Self {
|
||||
common: widget::CommonBuilder::default(),
|
||||
pos,
|
||||
widget,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Widget> Widget for Ingame<W> {
|
||||
type State = State;
|
||||
type Style = Style;
|
||||
type Event = ();
|
||||
|
||||
fn init_state(&self, id_gen: widget::id::Generator) -> Self::State {
|
||||
State {
|
||||
ids: Ids::new(id_gen),
|
||||
pos: Vec3::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn style(&self) -> Self::Style {
|
||||
()
|
||||
}
|
||||
|
||||
fn update(self, args: widget::UpdateArgs<Self>) -> Self::Event {
|
||||
let widget::UpdateArgs { id, state, ui, .. } = args;
|
||||
let Ingame { widget, pos, .. } = self;
|
||||
|
||||
// Update pos if it has changed
|
||||
if state.pos != pos {
|
||||
state.update(|s| s.pos = pos);
|
||||
}
|
||||
|
||||
widget
|
||||
.graphics_for(ui.window)
|
||||
.parent(id) // is this needed
|
||||
.set(state.ids.prim, ui);
|
||||
}
|
||||
|
||||
fn default_x_position(&self, ui: &Ui) -> Position {
|
||||
Position::Absolute(0.0)
|
||||
}
|
||||
fn default_y_position(&self, ui: &Ui) -> Position {
|
||||
Position::Absolute(0.0)
|
||||
}
|
||||
fn default_x_dimension(&self, ui: &Ui) -> Dimension {
|
||||
Dimension::Absolute(1.0)
|
||||
}
|
||||
fn default_y_dimension(&self, ui: &Ui) -> Dimension {
|
||||
Dimension::Absolute(1.0)
|
||||
}
|
||||
}
|
@ -1,2 +1,3 @@
|
||||
pub mod image_slider;
|
||||
pub mod ingame;
|
||||
pub mod toggle_button;
|
||||
|
Loading…
Reference in New Issue
Block a user