hecrj / wgpu_glyph Goto Github PK
View Code? Open in Web Editor NEWA fast text renderer for wgpu (https://github.com/gfx-rs/wgpu)
Home Page: https://docs.rs/wgpu_glyph
License: MIT License
A fast text renderer for wgpu (https://github.com/gfx-rs/wgpu)
Home Page: https://docs.rs/wgpu_glyph
License: MIT License
EDIT: Looking at the backtrace more carefully, I actually realize that this is probably not a problem in wgpu_glyph
but a problem in iced
which is the same as reported by the two issue mentioned below, since I think it is in iced
code that the Scissor_rect region is set. Sorry for the duplicate.
When a text is displayed on several line, a validation error similar to iced-rs/iced#816 and iced-rs/iced#775 happens.
I believe a fix similar to iced-rs/iced#818 could work
Here is a validation error + backtrace
wgpu error: Validation Error
Caused by:
In a RenderPass
note: encoder = `<CommandBuffer-(0, 245, Vulkan)>`
In a set_scissor_rect command
Invalid ScissorRect parameters
thread 'main' panicked at 'Handling wgpu errors as fatal by default', /home/nlevy/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.0/src/backend/direct.rs:1896:5
stack backtrace:
0: std::panicking::begin_panic
1: wgpu::backend::direct::default_error_handler
2: core::ops::function::Fn::call
3: <wgpu::backend::direct::Context as wgpu::Context>::command_encoder_end_render_pass
4: wgpu_glyph::pipeline::Pipeline<()>::draw
5: iced_wgpu::backend::Backend::flush
6: iced_wgpu::backend::Backend::draw
7: ensnano::gui::Gui::render
8: ensnano::main::{{closure}}
9: winit::platform_impl::platform::x11::EventLoop<T>::run
10: winit::platform_impl::platform::EventLoop<T>::run
11: winit::event_loop::EventLoop<T>::run
12: ensnano::main
I'll try to make a minimal example to reproduce the bug tomorrow
I have managed to compile hello
example to wasm32
target with some changes to winit initialization, however, when trying to render new text on the next frame, part of the text disappear (e.g I just render text with content that changes each frame with format!("Frame {}!, counter)
).
I have modified the example I'm my fork to help reproduce the issue:
https://github.com/pacmancoder/wgpu_glyph/tree/issue-report/wasm32-text-rendering
UPD: Reproduces only on Firefox (v93)
# 0. Install prerequisites
cargo install wasm-bindgen-cli https
# 1. Compile wasm module
cargo build --example hello --target=wasm32-unknown-unknown
# 2. Invoke wasm-bindgen
wasm-bindgen target/wasm32-unknown-unknown/debug/examples/hello.wasm --out-dir . --target web --no-typescript
# 3. run http server
http
# 4. Open 127.0.0.1:8000 in browser
Results can be compared with non-wasm32 build of example cargo run --example hello
Not sure yet if it is related to wgpu
or wgpu_glyph
implementation.
Although you can provide a multisample_state for your Font, I don't see any use of this when you are unable to pass a resolve_target to the wgpu::RenderPass created by wgpu_glyph. The resolve_target is needed to apply the changes from the multisample view to the actual texture, as just parsing the multisample view alone does practically nothing.
I wish to calculate an optimal window size (using GlyphCruncher::glyph_bounds
), then create that window. Resizing the window after creation has unwanted side-effects.
Using wgpu_glyph
it does not appear that I am able to do this, at least without creating the GlyphBrush
twice. Yet from examining the source, it appears that the only reason for this is that GlyphBrush
encapsulates both the glyph_brush
and the pipeline
.
Probably the simplest solution (though awkward) is to allow a GlyphBrush
to be created from an existing object of the upstream GlyphBrush
type.
https://docs.rs/wgpu_glyph/0.9.0/wgpu_glyph/struct.Text.html
scale: PxScale
Position on screen to render text, in pixels from top-left. Defaults to (0, 0).
The latest wgpu-glyph(0.21.0) codebase depends on wgpu 0.18, but on crates.io, showing it depends on 0.17.
is it possible to release on crates, i think iced will need this too
After upgrading to wgpu 0.11.1, I'm getting the following error:
thread 'main' panicked at 'wgpu error: Validation Error
Caused by:
In Device::create_render_pipeline
error matching FRAGMENT shader requirements against the pipeline
unable to filter the texture (ResourceBinding { group: 0, binding: 2 }) by the sampler (ResourceBinding { group: 0, binding: 1 })
non-filterable float texture
', /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.1/src/backend/direct.rs:2195:5
stack backtrace:
0: rust_begin_unwind
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:517:5
1: std::panicking::begin_panic_fmt
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/panicking.rs:460:5
2: wgpu::backend::direct::default_error_handler
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.1/src/backend/direct.rs:2195:5
3: core::ops::function::Fn::call
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/ops/function.rs:70:5
4: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/alloc/src/boxed.rs:1650:9
5: wgpu::backend::direct::ErrorSinkRaw::handle_error
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.1/src/backend/direct.rs:2183:9
6: wgpu::backend::direct::Context::handle_error
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.1/src/backend/direct.rs:184:9
7: <wgpu::backend::direct::Context as wgpu::Context>::device_create_render_pipeline
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.1/src/backend/direct.rs:1276:13
8: wgpu::Device::create_render_pipeline
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.11.1/src/lib.rs:1770:17
9: wgpu_glyph::pipeline::build
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu_glyph-0.15.1/src/pipeline.rs:290:15
10: wgpu_glyph::pipeline::Pipeline<()>::new
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu_glyph-0.15.1/src/pipeline.rs:34:9
11: wgpu_glyph::GlyphBrush<(),F,H>::new
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu_glyph-0.15.1/src/lib.rs:221:23
12: wgpu_glyph::builder::GlyphBrushBuilder<(),F,H>::build
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu_glyph-0.15.1/src/builder.rs:113:9
13: fj_host::graphics::config_ui::ConfigUi::new
at ./src/graphics/config_ui.rs:22:13
14: fj_host::graphics::renderer::Renderer::new::{{closure}}
at ./src/graphics/renderer.rs:121:25
15: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/future/mod.rs:80:19
16: futures_executor::local_pool::block_on::{{closure}}
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-executor-0.3.18/src/local_pool.rs:315:23
17: futures_executor::local_pool::run_executor::{{closure}}
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-executor-0.3.18/src/local_pool.rs:90:37
18: std::thread::local::LocalKey<T>::try_with
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/thread/local.rs:399:16
19: std::thread::local::LocalKey<T>::with
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/std/src/thread/local.rs:375:9
20: futures_executor::local_pool::run_executor
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-executor-0.3.18/src/local_pool.rs:86:5
21: futures_executor::local_pool::block_on
at /home/hanno/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-executor-0.3.18/src/local_pool.rs:315:5
22: fj_host::main
at ./src/main.rs:177:24
23: core::ops::function::FnOnce::call_once
at /rustc/59eed8a2aac0230a8b53e89d4e99d55912ba6b35/library/core/src/ops/function.rs:227:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
The error seems to originate from this call:
https://github.com/hecrj/wgpu_glyph/blob/0.15.1/src/pipeline.rs#L290-L335
And this is the relevant bit of configuration, I believe:
https://github.com/hecrj/wgpu_glyph/blob/0.15.1/src/pipeline.rs#L236-L256
Based on some digging I did in the wgpu validation code, I think the problem is the mismatch between filtering: true
and filterable: false
.
This problem has been fixed on master (thank you, @Bobo1239!), but that fix hasn't made it into a release yet. I figured it's worth opening this issue despite the fix existing, to provide information to those searching the internet for that error message, and to document that the latest releases of wgpu_glyph
and wgpu
don't work with one another.
After adding wgpu_glyph to my application everything works fine.
However once when running, I got these repeating validation errors:
ERROR gfx_backend_vulkan
VALIDATION [VUID-VkBufferImageCopy-imageOffset-00197 (0)] : vkCmdCopyBufferToImage(): Both pRegion[0] imageoffset.x (264) and (imageExtent.width + imageOffset.x) (312) must be >= zero or <= image subresource width (256). The Vulkan spec states: imageOffset.x and (imageExtent.width + imageOffset.x) must both be greater than or equal to 0 and less than or equal to the image subresource width (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-VkBufferImageCopy-imageOffset-00197)
object info: (type: IMAGE, hndl: 22)
ERROR gfx_backend_vulkan
VALIDATION [VUID-vkCmdCopyBufferToImage-pRegions-00172 (0)] : vkCmdCopyBufferToImage(): pRegion[0] exceeds image bounds.. The Vulkan spec states: The image region specified by each element of pRegions must be a region that is contained within dstImage (https://www.khronos.org/registry/vulkan/specs/1.1-extensions/html/vkspec.html#VUID-vkCmdCopyBufferToImage-pRegions-00172)
object info: (type: COMMAND_BUFFER, hndl: 0)
And then it panicked with:
thread '<unnamed>' panicked at 'assertion failed: `(left == right)`
left: `Ok(false)`,
right: `Ok(true)`: GPU got stuck on a frame (image 1) :(', /home/rubic/.cargo/git/checkouts/wgpu-53e70f8674b08dd4/dbef9f3/wgpu-native/src/swap_chain.rs:178:5
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/libunwind.rs:88
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.29/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:47
3: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:36
4: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:200
5: std::panicking::default_hook
at src/libstd/panicking.rs:214
6: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:477
7: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:384
8: std::panicking::begin_panic_fmt
at src/libstd/panicking.rs:339
9: wgpu_swap_chain_get_next_texture
10: wgpu::SwapChain::get_next_texture
11: pf_sandbox::wgpu::WgpuGraphics::run
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
Illegal instruction (core dumped)
I believe this was caused by wgpu_glyph as my application does not copy buffers to images, but wgpu_glyph does.
I need to know the dimensions of the rendered text after it is drawn or calculate if beforehand. Is there a suitable method for that in this library?
From my own attempts at working with wgpu, it seems like the wgpu::Device only needs to get mutably borrowed for submitting CommandBuffers into the queue.
Indeed, I can run the following line in wgpu_glyph:
sed -i 's/&mut wgpu::Device/\&wgpu::Device/g' $(find src -iname '*.rs')
and the whole crate can still be built without any issue, and its example binary still runs perfectly fine.
Hello,
Do have any plan to handle stroke text ?
I don't know if it here or in ab_glyph ?
Best regards
Marc-Antoine
re: iced-rs/iced#96
hello example is just a gray background
I also have the same problem as the author of the iced issue. I was originally investigating why iced doesn't display text in its examples.
AdapterInfo { name: "Radeon (TM) Pro WX 4100", vendor: 4098, device: 26595, device_type: DiscreteGpu }
Suppose I want to make an editable text field. This requires displaying a cursor in the text. However I cannot figure out how to get the position (baseline of the row would probably also be required) of a given glyph at a particular index in a section. I see that it is possible to get the bounding box a complete section, but I individual glyphs seem harder.
Given that the main user of the crate (iced
) seems to have moved from wgpu_glyph
to glyphon
(as per this pr). It may be helpful to people browsing crates to have a comparison between the two?
This is probably caused by creating a 0-sized buffer.
It should be easy to fix.
I'm getting vulkan validation errors when running the examples on windows, the following output is from the hello
example, but I get similar results from the clipping
and depth
examples as well.
[2021-02-16T00:39:25Z ERROR gfx_backend_vulkan]
VALIDATION [VUID-VkRenderPassBeginInfo-framebuffer-03210 (-872316813)] : Validation Error: [ VUID-VkRenderPassBeginInfo-framebuffer-03210 ] Object 0: handle = 0xbb4e7a000000001f, type = VK_OBJECT_TYPE_RENDER_PASS; | MessageID = 0xcc018073 | vkCmdBeginRenderPass(): Image view #0 created from an image with usage set as 0x11, but image info #0 used to create the framebuffer had usage set as 0x10 The Vulkan spec states: If framebuffer was created with a VkFramebufferCreateInfo::flags value that included VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of the pAttachments member of a VkRenderPassAttachmentBeginInfo structure included in the pNext chain must be a VkImageView of an image created with a value of VkImageCreateInfo::usage equal to the usage member of the corresponding element of VkFramebufferAttachmentsCreateInfo::pAttachments used to create framebuffer (https://vulkan.lunarg.com/doc/view/1.2.162.0/windows/1.2-extensions/vkspec.html#VUID-VkRenderPassBeginInfo-framebuffer-03210)
object info: (type: RENDER_PASS, hndl: 13496859273694543903)
[2021-02-16T00:39:25Z ERROR gfx_backend_vulkan]
VALIDATION [VUID-VkRenderPassBeginInfo-framebuffer-03210 (-872316813)] : Validation Error: [ VUID-VkRenderPassBeginInfo-framebuffer-03210 ] Object 0: handle = 0x8483000000000025, type = VK_OBJECT_TYPE_RENDER_PASS; | MessageID = 0xcc018073 | vkCmdBeginRenderPass(): Image view #0 created from an image with usage set as 0x11, but image info #0 used to create the framebuffer had usage set as 0x10 The Vulkan spec states: If framebuffer was created with a VkFramebufferCreateInfo::flags value that included VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of the pAttachments member of a VkRenderPassAttachmentBeginInfo structure included in the pNext chain must be a VkImageView of an image created with a value of VkImageCreateInfo::usage equal to the usage member of the corresponding element of VkFramebufferAttachmentsCreateInfo::pAttachments used to create framebuffer (https://vulkan.lunarg.com/doc/view/1.2.162.0/windows/1.2-extensions/vkspec.html#VUID-VkRenderPassBeginInfo-framebuffer-03210)
object info: (type: RENDER_PASS, hndl: 9548475634955583525)
This is running with VulkanSDK version 1.2.162.0 on an nvidia gtx 1050.
Is it possible to draw text with a stroke using this library? Will this be coming in the future?
It appears that the choice of anchor point for text positioning depends on the actual width of the text in pixels rather than the width of the glyphs. In general this is hard to notice, but it definitely causes issues with monospaced/fixed width fonts that are dynamically updated. For instance, consider a simple counter app, where the text of the current count is positioned with the following Layout
:
wgpu_glyph::Layout::default_single_line()
.h_align(wgpu_glyph::HorizontalAlign::Right)
.v_align(wgpu_glyph::VerticalAlign::Center)
When the rightmost character of the text updates from a wide character (e.g. 0
) to a narrow character (e.g. 1
) or vice versa, there is a noticeable horizontal shift in the rest of the characters on the left.
I think that all mutable references to wgpu::Device can be replaced by immutable references, considering that wgpu::Device has no &mut self
function. Do you think this could be changed?
I can submit a PR myself if you want me to.
Thanks
Do you have any started work on background color support ?
It can be great to have in on Text and Section.
Do you have any advice to start to implement it ?
Thanks,
Marc-Antoine
error[E0658]: use of unstable library feature 'try_from' (see issue #33417)
Getting this while trying to run the example.
cargo run --example hello --features wgpu/vulkan --release
There's been quite a few changes since 0.2 crates and master wgpu-rs; are there any plans to upgrade this to the api that's on master any time soonish?
Hello, I'm not sure if this is a problem with wgpu, wgpu_glyph, or my understanding of wgpu so I'm posting it to both projects.
I've created a minimal runnable example here: https://github.com/MichaelBaker/wgpu-glyph-example
This is the line that causes the problem. If you comment this line out, the text renders correctly: https://github.com/MichaelBaker/wgpu-glyph-example/blob/5bcd7200d1a27df7add4a68b744b41df9b1de681/src/main.rs#L70
My best guess is that creating a buffer here corrupts or invalidates wgpu_glyph's cached transform buffer because if I remove this check from the pipeline it starts rendering correctly:
Line 353 in e53659e
Otherwise this library has worked great so thanks for putting it together.
I'm on a Macbook Pro running macOS 10.15.3 (Catalina).
Here is the wgpu issue: gfx-rs/wgpu-rs#288
The font weight of text rendered with this library seems to be off in comparison to the font rendering used in browsers.
If you look closely, there's a pixel difference between these two—easy to spot at the plus or equals sign. They both don't have any font weight modifications; it's the default font weight.
The same holds true for Firefox and Chrome.
I'm not a font expert, so I have no idea what method would need to be implemented, which one is used in browsers to achieve this, or whether browsers diverge from default OS font rendering in this case.
Nevertheless, the text seems to be just a little bit too thin in comparison. Help would be much appreciated here :-)
Edit: using macOS.
wgpu_glyph
causes my application to crash with exit code 0xc000041d
on Windows 10, with no error or panic message, seemingly randomly while resizing the window. You can see an adaptation of the hello
example that reproduces the problem, at least for me, here.
Hi I encountered a problem when using wgpu with DX12.
The following issue did not appear when using wgpu with Vulcan on linux.
As soon as I create a bind group it overrides one inside of glyph.
In this case, it is transform uniform.
For example if I edit examples/hello.rs
like so:
... [Begining Of The File]
let mut glyph_brush = GlyphBrushBuilder::using_font_bytes(inconsolata)
.expect("Load fonts")
.build(&device, render_format);
//Here I create my uniform, that should not interrupt glyph inner workings
{
let data = TransformUniform::default();
let bind_group_layout_descriptor = wgpu::BindGroupLayoutDescriptor {
label: Some("new_1"),
bindings: &[wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStage::VERTEX,
ty: wgpu::BindingType::UniformBuffer { dynamic: false },
}],
};
let buffer = device.create_buffer_with_data(
&data.as_bytes(),
wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST,
);
let bind_group_layout =
device.create_bind_group_layout(&bind_group_layout_descriptor);
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("new_2"),
layout: &bind_group_layout,
bindings: &[wgpu::Binding {
binding: 1,
resource: wgpu::BindingResource::Buffer {
buffer: &buffer,
range: 0..std::mem::size_of_val(&data)
as wgpu::BufferAddress,
},
}],
});
}
#[repr(C)]
#[derive(Clone, Copy, AsBytes)]
struct TransformUniform {
transform: [f32; 16],
}
impl Default for TransformUniform {
fn default() -> Self {
Self {
// Here I intentionally create projection with wrong size to demonstrate that it affects glyph
transform: orthographic_projection(100.0, 100.0),
}
}
}
... [Rest Of The File]
It gives me output like this
Same Code on Linux with Vulcan
This issue is probably not wgpu-glyph related and should be submitted to main wgpu repo,
but I decided to ask here first in case I made some stupid mistake related to my small wgpu knowledge
While setting up a test suite to compare images rendered and captured using wgpu_glyph
, I discovdred a very slight difference between the image generated on one run vs. another. The pink areas in the attachment are where the pixels don't match exactly.
As far as I can tell, my code has nothing non-deterministic going on that could cause this behavior, so I wanted to check in here just to see if there are any potential obvious reasons why wgpu_glyph
might produce a different result from one run to the next.
The difference is unnoticeable to the human eye, I only spotted it because of my testing work, which can easily be modified to use a more lenient comparison algorithm. Just wanted to deepen my understanding about whether the issue might be on my end or not.
I added text in my game in 30min with your work.
Worked exactly as I wanted.
Thank you thank you.
Hello I'm new to wgpu glyph, I have managed to run the hello example, but I got a bad result when I replace the font with SourceHanSerifCN-VF(.otf or .ttf)。
if this line is added(after build the section and before queue), the app will panic:
let bound = glyph_brush.glyph_bounds(section.clone());
// panic:
//thread 'main' panicked at 'Invalid glyph_hor_side_bearing', C:\Users\MY_USERNAME\.cargo\registry\src\github.com-1ecc6299db9ec823\ab_glyph-0.2.13\src\ttfp.rs:333:1
I don't known if it's an issue for wgpu_glyph, or ab_glyph, or other dependencies, so I create this issue. Any advice will be appreciated:rose:.
Windows 10, intel 7700, Nvidia 1060, 32gb ram
font file is downloaded from adobe-fonts/source-han-serif
I've been investigating frame stutter in a game and it seems to happen when drawing dynamic characters in this library. "dynamic" meaning characters that change every frame, e.g. FPS counter or score.
I've found that it takes ~10-50ms of CPU time sometimes, which is too much. According to Nvidia's profiler, this is coming from a vkAllocateMemory call. Any ideas what is going on here? I assume this has something to do with caching because of the dynamic aspect, but even when all I am doing is flipping between 0 and 1 displayed in alternating frames it takes 10s of ms. But when I show 0 twice or 1 twice, the second time doesn't cause stutter.
Could also be a faulty gpu memory allocator in wgpu/gfx-rs I suppose, but curious if you know offhand what this might be.
The README example is still for 0.9.0
Im writing a game engine and using wgpu_glyph for the text rendering and here is the snippet of my code
render_items.transformed_text.iter()
.map(|text| (wgpu_glyph::Section{
screen_position: (text.position.x, text.position.y),
bounds: (self.size.width as f32, self.size.height as f32),
text: vec![wgpu_glyph::Text::new(&text.text).with_color(text.colour.to_raw())],
..Default::default()
}, text.transformation))
.for_each(|(section, transform)| {
let text_transform = unflatten_matrix(transform);
let ortho = unflatten_matrix(orthographic_projection(self.size.width, self.size.height));
let transform = flatten_matrix(ortho * text_transform);
self.glyph_brush.queue(section);
self.glyph_brush.draw_queued_with_transform(
&self.device, &mut staging_belt, &mut encoder, &view, &self.camera_bind_group, transform,
).unwrap();
});
let text_sections = render_items.text
.iter()
.map(|text| wgpu_glyph::Section{
screen_position: (text.position.x, text.position.y),
bounds: (self.size.width as f32, self.size.height as f32),
text: vec![wgpu_glyph::Text::new(&text.text).with_color(text.colour.to_raw())],
..Default::default()
})
.collect::<Vec<wgpu_glyph::Section>>();
text_sections.into_iter().for_each(|s| self.glyph_brush.queue(s));
self.glyph_brush.draw_queued(&self.device, &mut staging_belt, &mut encoder, &view, &self.camera_bind_group, self.size.width, self.size.height).unwrap();
This produces a strange result where the text that is supposed to have no transformations (other than the orthographic transformation) So i went to the documentation for the glyph_brush and under queue
it states Benefits from caching, see caching behaviour; however, when I click the link to see this caching behavior it links nowhere.
Compiling wgpu v0.7.1
error[E0658]: use of unstable library feature 'future_readiness_fns'
--> /Users/tiantengfei/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.1/src/backend/direct.rs:17:14
|
17 | future::{ready, Ready},
| ^^^^^
|
= note: see issue #70921 <https://github.com/rust-lang/rust/issues/70921> for more information
error[E0658]: use of unstable library feature 'future_readiness_fns'
--> /Users/tiantengfei/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.1/src/backend/direct.rs:17:21
|
17 | future::{ready, Ready},
| ^^^^^
|
= note: see issue #70921 <https://github.com/rust-lang/rust/issues/70921> for more information
error[E0658]: use of unstable library feature 'future_readiness_fns'
--> /Users/tiantengfei/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.1/src/backend/direct.rs:657:33
|
657 | type RequestAdapterFuture = Ready<Option<Self::AdapterId>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #70921 <https://github.com/rust-lang/rust/issues/70921> for more information
error[E0658]: use of unstable library feature 'future_readiness_fns'
--> /Users/tiantengfei/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.1/src/backend/direct.rs:659:9
|
659 | Ready<Result<(Self::DeviceId, Self::QueueId), crate::RequestDeviceError>>;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #70921 <https://github.com/rust-lang/rust/issues/70921> for more information
error[E0658]: use of unstable library feature 'future_readiness_fns'
--> /Users/tiantengfei/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.1/src/backend/direct.rs:688:9
|
688 | ready(id.ok())
| ^^^^^
|
= note: see issue #70921 <https://github.com/rust-lang/rust/issues/70921> for more information
error[E0658]: use of unstable library feature 'future_readiness_fns'
--> /Users/tiantengfei/.cargo/registry/src/github.com-1ecc6299db9ec823/wgpu-0.7.1/src/backend/direct.rs:712:9
|
712 | ready(Ok((device, device_id)))
| ^^^^^
|
= note: see issue #70921 <https://github.com/rust-lang/rust/issues/70921> for more information
error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0658`.
error: could not compile `wgpu`.
To learn more, run the command again with --verbose.
I have modified the hello.rs
example to display a decreasing counter that is updated every frame.
Where the numbers are different compared to the first frame I get the following artifacts:
The numbers are rendered as expected when using the vulkan backend for wgpu.
I can also run the opengl example in glyph_brush without artifacts.
I would greatly appreciate any advice that can help me narrow down the cause of this problem.
Here is source code of my modified hello.rs:
use std::error::Error;
use wgpu_glyph::{ab_glyph, GlyphBrushBuilder, Section, Text};
fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
// Open window and create a surface
let event_loop = winit::event_loop::EventLoop::new();
let window = winit::window::WindowBuilder::new()
.with_resizable(false)
.build(&event_loop)
.unwrap();
let instance = wgpu::Instance::new(wgpu::BackendBit::GL);
let surface = unsafe { instance.create_surface(&window) };
// Initialize GPU
let (device, queue) = futures::executor::block_on(async {
let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
})
.await
.expect("Request adapter");
adapter
.request_device(&wgpu::DeviceDescriptor::default(), None)
.await
.expect("Request device")
});
// Create staging belt and a local pool
let mut staging_belt = wgpu::util::StagingBelt::new(1024);
let mut local_pool = futures::executor::LocalPool::new();
let local_spawner = local_pool.spawner();
// Prepare swap chain
let render_format = wgpu::TextureFormat::Bgra8UnormSrgb;
let mut size = window.inner_size();
let mut swap_chain = device.create_swap_chain(
&surface,
&wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
format: render_format,
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
},
);
// Prepare glyph_brush
let inconsolata = ab_glyph::FontArc::try_from_slice(include_bytes!(
"Inconsolata-Regular.ttf"
))?;
let mut counter: usize = 9876543210;
let mut glyph_brush = GlyphBrushBuilder::using_font(inconsolata)
.build(&device, render_format);
// Render loop
window.request_redraw();
event_loop.run(move |event, _, control_flow| {
*control_flow = winit::event_loop::ControlFlow::Poll;
match event {
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::CloseRequested,
..
} => *control_flow = winit::event_loop::ControlFlow::Exit,
winit::event::Event::WindowEvent {
event: winit::event::WindowEvent::Resized(new_size),
..
} => {
size = new_size;
swap_chain = device.create_swap_chain(
&surface,
&wgpu::SwapChainDescriptor {
usage: wgpu::TextureUsage::RENDER_ATTACHMENT,
format: render_format,
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Mailbox,
},
);
}
winit::event::Event::RedrawRequested { .. } => {
counter -= 1;
// Get a command encoder for the current frame
let mut encoder = device.create_command_encoder(
&wgpu::CommandEncoderDescriptor {
label: Some("Redraw"),
},
);
// Get the next frame
let frame = swap_chain
.get_current_frame()
.expect("Get next frame")
.output;
// Clear frame
{
let _ = encoder.begin_render_pass(
&wgpu::RenderPassDescriptor {
label: Some("Render pass"),
color_attachments: &[
wgpu::RenderPassColorAttachmentDescriptor {
attachment: &frame.view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(
wgpu::Color {
r: 0.4,
g: 0.4,
b: 0.4,
a: 1.0,
},
),
store: true,
},
},
],
depth_stencil_attachment: None,
},
);
}
glyph_brush.queue(Section {
screen_position: (30.0, 30.0),
bounds: (size.width as f32, size.height as f32),
text: vec![Text::new(&counter.to_string())
.with_color([0.0, 0.0, 0.0, 1.0])
.with_scale(40.0)],
..Section::default()
});
glyph_brush.queue(Section {
screen_position: (30.0, 90.0),
bounds: (size.width as f32, size.height as f32),
text: vec![Text::new("Hello wgpu_glyph!")
.with_color([1.0, 1.0, 1.0, 1.0])
.with_scale(40.0)],
..Section::default()
});
// Draw the text!
glyph_brush
.draw_queued(
&device,
&mut staging_belt,
&mut encoder,
&frame.view,
size.width,
size.height,
)
.expect("Draw queued");
// Submit the work!
staging_belt.finish();
queue.submit(Some(encoder.finish()));
// Recall unused staging buffers
use futures::task::SpawnExt;
local_spawner
.spawn(staging_belt.recall())
.expect("Recall staging belt");
local_pool.run_until_stalled();
}
winit::event::Event::MainEventsCleared => window.request_redraw(),
_ => {
}
}
})
}
Here is the log at the info level:
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
Running `target/debug/examples/hello`
[2021-04-06T15:16:29Z INFO winit::platform_impl::platform::x11::window] Guessed window scale factor: 1.25
[2021-04-06T15:16:29Z INFO gfx_backend_gl::window::egl] Client extensions: "EGL_EXT_platform_base EGL_EXT_device_base EGL_EXT_device_enumeration EGL_EXT_device_query EGL_KHR_client_get_all_proc_addresses EGL_EXT_client_extensions EGL_KHR_debug EGL_KHR_platform_x11 EGL_EXT_platform_x11 EGL_EXT_platform_device EGL_EXT_platform_wayland EGL_KHR_platform_wayland EGL_MESA_platform_gbm EGL_KHR_platform_gbm EGL_MESA_platform_surfaceless"
[2021-04-06T15:16:29Z INFO gfx_backend_gl::window::egl] Loading Wayland library to get the current display
[2021-04-06T15:16:29Z INFO gfx_backend_gl::window::egl] Loading X11 library to get the current display
[2021-04-06T15:16:29Z INFO gfx_backend_gl::window::egl] Using X11 platform
[2021-04-06T15:16:29Z INFO gfx_backend_gl::window::egl] Display vendor "NVIDIA", version (1, 5), extensions: "EGL_EXT_buffer_age EGL_EXT_client_sync EGL_EXT_create_context_robustness EGL_EXT_image_dma_buf_import EGL_EXT_image_dma_buf_import_modifiers EGL_MESA_image_dma_buf_export EGL_EXT_output_base EGL_EXT_stream_acquire_mode EGL_EXT_sync_reuse EGL_IMG_context_priority EGL_KHR_config_attribs EGL_KHR_create_context_no_error EGL_KHR_context_flush_control EGL_KHR_create_context EGL_KHR_fence_sync EGL_KHR_get_all_proc_addresses EGL_KHR_partial_update EGL_KHR_swap_buffers_with_damage EGL_KHR_no_config_context EGL_KHR_gl_colorspace EGL_KHR_gl_renderbuffer_image EGL_KHR_gl_texture_2D_image EGL_KHR_gl_texture_3D_image EGL_KHR_gl_texture_cubemap_image EGL_KHR_image EGL_KHR_image_base EGL_KHR_image_pixmap EGL_KHR_reusable_sync EGL_KHR_stream EGL_KHR_stream_attrib EGL_KHR_stream_consumer_gltexture EGL_KHR_stream_cross_process_fd EGL_KHR_stream_fifo EGL_KHR_stream_producer_eglsurface EGL_KHR_surfaceless_context EGL_KHR_wait_sync EGL_NV_nvrm_fence_sync EGL_NV_post_sub_buffer EGL_NV_quadruple_buffer EGL_NV_stream_consumer_eglimage EGL_NV_stream_cross_display EGL_NV_stream_cross_object EGL_NV_stream_cross_process EGL_NV_stream_cross_system EGL_NV_stream_dma EGL_NV_stream_flush EGL_NV_stream_metadata EGL_NV_stream_remote EGL_NV_stream_reset EGL_NV_stream_socket EGL_NV_stream_socket_inet EGL_NV_stream_socket_unix EGL_NV_stream_sync EGL_NV_stream_fifo_next EGL_NV_stream_fifo_synchronous EGL_NV_stream_consumer_gltexture_yuv EGL_NV_stream_attrib EGL_NV_stream_origin EGL_NV_system_time EGL_NV_output_drm_flip_event EGL_NV_triple_buffer"
[2021-04-06T15:16:29Z INFO gfx_backend_gl::window::egl] Trying native-render
[2021-04-06T15:16:29Z WARN gfx_backend_gl::window::egl] No config found!
[2021-04-06T15:16:29Z INFO gfx_backend_gl::window::egl] Trying presentation
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Vendor: "NVIDIA Corporation"
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Renderer: "GeForce RTX 2070/PCIe/SSE2"
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Version: 3.2, NVIDIA 460.39
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Shading Language: 3.2
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Supported Features: INDEPENDENT_BLENDING | SAMPLER_ANISOTROPY | INSTANCE_RATE | MUTABLE_COMPARISON_SAMPLER | NDC_Y_UP
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Legacy Features: DRAW_INSTANCED | DRAW_INDEXED_INSTANCED | VERTEX_BASE | CONSTANT_BUFFER | COPY_BUFFER | SAMPLER_OBJECTS | EXPLICIT_LAYOUTS_IN_SHADER | INSTANCED_ATTRIBUTE_BINDING
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Memory types: [
(
MemoryType {
properties: CPU_VISIBLE | COHERENT | CPU_CACHED,
heap_index: 1,
},
Buffer(
TRANSFER_SRC | TRANSFER_DST | UNIFORM_TEXEL | STORAGE_TEXEL | UNIFORM | STORAGE | INDEX | VERTEX | INDIRECT,
),
),
(
MemoryType {
properties: CPU_VISIBLE | COHERENT,
heap_index: 1,
},
Buffer(
TRANSFER_SRC | TRANSFER_DST | UNIFORM_TEXEL | STORAGE_TEXEL | UNIFORM | STORAGE | INDEX | VERTEX | INDIRECT,
),
),
(
MemoryType {
properties: DEVICE_LOCAL,
heap_index: 0,
},
Buffer(
TRANSFER_SRC | TRANSFER_DST | UNIFORM_TEXEL | STORAGE_TEXEL | UNIFORM | STORAGE | INDEX | VERTEX | INDIRECT,
),
),
(
MemoryType {
properties: DEVICE_LOCAL,
heap_index: 0,
},
Image,
),
]
[2021-04-06T15:16:29Z INFO gfx_backend_gl] Debug output is enabled
[2021-04-06T15:16:29Z INFO gfx_backend_gl::device] Created frame buffer 1
[2021-04-06T15:16:29Z WARN gfx_backend_gl::device] View format 33321 is different from base 6403
[2021-04-06T15:16:29Z WARN naga::front::spv] Unknown decoration ColMajor
[2021-04-06T15:16:29Z WARN naga::front::spv] Unknown decoration MatrixStride
[2021-04-06T15:16:29Z WARN naga::front::spv] Treating VertexIndex as unsigned
[2021-04-06T15:16:29Z INFO gfx_backend_gl::device] Compiled shader 2
[2021-04-06T15:16:29Z INFO gfx_backend_gl::device] Compiled shader 3
[2021-04-06T15:16:29Z INFO gfx_backend_gl::device] Linked program 1
This has a new release out, itself depending on a new rusttype version. It would be nice to have a new release for this.
BTW you can also correct the doc here: https://github.com/hecrj/wgpu_glyph/blob/master/src/lib.rs#L36
Hello!
The glyph is working super awesome, except when rendering, it blink repeatedly... the library that I'm working on that uses it is this.
I thought at first it's a problem on my side, and I tried limiting FPS, debugged by rechecking everything from examples, and did anything I for optimization, but still couldn't save the blinking problem...
I'm using latest Rust, on Windows x64 latest version
Hey, wgpu_glyph is awesome. I am using it for a nodegraph UI, and it's beautiful.
I have one question though. What do you advise as the best way to rotate text?
I've found 'draw_queued_with_transform', which allows me to provide a transform matrix for the position/scale/rotation of the text I'm drawing but:
I want to double check I'm not going down the wrong path.
OS: Arch Linux
GPU: GTX 960
Driver: Nvidia proprietary driver
If I change the example to use a scale of Scale::uniform(200)
then I get a panic
thread 'main' panicked at 'assertion failed: `(left == right)`
left: `Ok(false)`,
right: `Ok(true)`: GPU got stuck on a frame (image 0) :(', /home/rubic/.cargo/git/checkouts/wgpu-53e70f8674b08dd4/dbef9f3/wgpu-native/src/swap_chain.rs:178:5
stack backtrace:
0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
1: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:71
2: std::panicking::default_hook::{{closure}}
at src/libstd/sys_common/backtrace.rs:59
at src/libstd/panicking.rs:197
3: std::panicking::default_hook
at src/libstd/panicking.rs:211
4: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:474
5: std::panicking::continue_panic_fmt
at src/libstd/panicking.rs:381
6: std::panicking::begin_panic_fmt
at src/libstd/panicking.rs:336
7: wgpu_swap_chain_get_next_texture
8: wgpu::SwapChain::get_next_texture
9: hello::main
10: std::rt::lang_start::{{closure}}
11: std::panicking::try::do_call
at src/libstd/rt.rs:49
at src/libstd/panicking.rs:293
12: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:87
13: std::rt::lang_start_internal
at src/libstd/panicking.rs:272
at src/libstd/panic.rs:388
at src/libstd/rt.rs:48
14: main
15: __libc_start_main
16: _start
enabling logging does also display this warning:
[2019-07-14T08:43:35Z WARN wgpu_glyph] Increasing glyph texture size (256, 256) -> (512, 512). Consider building with `.initial_cache_size((512, 512))` to avoid resizing
I created an example here that illustrates. I would expect that the base of the text and the top of a capital letter are each the same distance from the vertical border of the window, but instead I observe that the base of the text is closer to the bottom of the window than the top of the capital is to the top of the window.
I'm running into an issue with wgpu_glyph where it renders gibberish letters if an OpenGL or ANGLE backend is used. But if a Metal backend is used everything renders perfectly normally. Unfortunately Chrome does not yet support Metal unless enabled in an experimental feature flag. See images below
ANGLE On Chrome 114, With M2 Macbook:
METAL On Chrome 114, With M2 Macbook:
One thing to note is that the gibberish letters are different every time a new window is opened. But are not different within the same window. This is not the case with Firefox where the gibberish is different every time. It does work without changing any feature flags in Safari. But that is because Safari Uses Metal by default. This issue also happens with Firefox (113.0) .
The glyph_brush crate has OwnedText
and OwnedSection
. Why aren't they re-exported?
Hello! So I tried out some of the examples following the directions in wgpu-rs's wiki to compile them to wasm, but they all seemed to fail on trying to create a surface from the winit window (or various other reasons; I tried to get them to work by modifying them based on wgpu-rs's examples, but to no avail). Am I doing something wrong, or does this library not support targeting wasm? If the latter, could support for wasm be added?
Thanks!
In certain cases, it might be nice to be able to render text that is behind objects that have already been rendered, i.e. by using depth testing.
I'm not 100% clear on how wgpu_glyph
's rendering pipeline should interact with the user's rendering pipeline, but I think it might be possible to have the user pass in a DepthStencilStateDescriptor
and a RenderPassDepthStencilAttachmentDescriptor
.
I'm working on using wgpu_glyph in the context of a code editor, in particular the ability to show that text has been selected. This is proving more difficult than I anticipated, but seems like a common use case, so once I figure it out I intend to make a PR to add examples for how to go about this. If anyone has already figured this out, I would love to hear how they went about it.
I don't see any way to get the name of a font. am I overlooking something or isn't such method not implemented?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.