2

I need to render some text in my Metal app. Rather then doing it manually, I'd like to use Apple's text rendering API.

Calling this code in a simple empty window's drawRect prints the string:

NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont fontWithName:@"Helvetica" size:26], NSFontAttributeName,[NSColor blackColor], NSForegroundColorAttributeName, nil];

NSAttributedString * s = [[NSAttributedString alloc] initWithString:@"Hello!"
attributes: attributes];


[s drawAtPoint:NSMakePoint(300, 300)];

But this doesn't work in a window with a Metal view. I guess everything gets flushed?

Is it possible? And the same thing with displaying a button (NSButton) on top of a Metal view.

Thanks.

Alex
  • 34,581
  • 26
  • 91
  • 135

1 Answers1

3

It is possible, but not simple. You will need to use drawViewHierarchyInRect with UILabel or UIButton, and pass a context created from a CVPixelBufferRef. From there, you need to use metal api's to link the CVPixelBufferRef to a metal texture, which you can then draw as normal. I would not recommend doing this every frame.

If you need some fancy UI that is rendered with metal, there are probably better alternatives, or you can just render your labels, buttons, etc. inside a UIView on top of your metal view.

Does your text need to be in the 3D world or is it overlay on top in 2D?

jjxtra
  • 20,415
  • 16
  • 100
  • 140
  • Thanks. The text needs to be on top of 2D. – Alex Dec 25 '20 at 08:03
  • 1
    In that case just a transparent ui view on top of your metal view should work great! – jjxtra Dec 25 '20 at 18:08
  • Thanks a lot. One last thing. Can I use Apple's font rendering to write a string to a texture to display it via Metal? This should be simpler than using UILabel. I think Valve is doing something similar with GDI+ here: https://github.com/lua9520/source-engine-2018-hl2_src/blob/master/vgui2/vgui_surfacelib/Win32Font.cpp#L251 – Alex Dec 25 '20 at 23:05
  • Yes you can write into a texture, see the top of my answer about using cv pixel buffer and mapping it to a texture. – jjxtra Dec 25 '20 at 23:06
  • https://stackoverflow.com/questions/37445052/how-to-create-a-mtltexture-backed-by-a-cvpixelbuffer – jjxtra Dec 25 '20 at 23:06
  • @jixtra I managed to make this work with a UILabel via `drawViewHierarchyInRect`, but I'd like to avoid creating a UILabel just for rendering a string. Can I use it with `[NSString drawAtPoint]`? – Alex Jan 12 '21 at 04:31