Re: Best way to draw 100-200 short strings???

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance

From: mikegi (mikegi_at_prestige.net)
Date: 07/01/04


Date: Thu, 1 Jul 2004 18:18:32 -0400

This has been very useful, especially the part about the string processing
taking up the majority of the time. That makes me wonder if a vertex shader
would give the best performance for my particular app since I'll be
repositioning the strings quite a bit. With a vertex shader I could lay out
the string triangles in a vertex buffer then position them at the proper
location on the screen via constants passed to the shader. I wouldn't need
to lock, update positions, unlock, and draw. No string processing other than
when I initially load them into the vertex buffer. My strings don't change,
only their positions.

I guess it would be a competition between:

1) Setting constants and calling a vertex shader for each string

2) Locking the VB, updating the coords, and blasting the buffer to the GPU

My app isn't a game and only draws on demand (eg. dragging the image around
with a mouse, zooming in/out with the mouse wheel, etc.).

I guess I'll get things going with D3DX and see what happens. If it isn't
fast enough I'll explore the alternatives.

Mike

"Jack Hoxley" <Jack.Hoxley@DirectX4VB.Com> wrote in message
news:%23WLemS7XEHA.384@TK2MSFTNGP10.phx.gbl...
> Answers inline:
>
> "mikegi" <mikegi@prestige.net> wrote in message
> news:Oe%232Ao6XEHA.2016@TK2MSFTNGP11.phx.gbl...
> > Yes, this is of interest and I appreciate your reply. I was wondering
how
> > you handle glyphs whose black box goes negative (eg. the "f" in Times
New
> > Roman Italic).
>
> Hmm, I don't do anything special with that - The GetTextExtentsPoints32
> function is all I use to judge size. Could well be a bug in my code if
that
> function returns dodgy values. However, our game engine is exclusively
> 'Arial' 10 or 12 point, and it works fine for all occurences so far.
>
> >
> > What I have in mind with my custom font class is to create a normal gdi
> font
> > (truetype only) then call GetGlyphOutline for the glyph metrics. I sort
> the
> > glyphs by blackbox height followed by blackbox width in order to pack
them
> > tightly in rows to minimize texture size. Finally, I grab the glyph
> bitmaps
> > and shove them into the texture.
>
> Sounds like a good way to do it. I basically stripped apart the old
D3DFont
> class that used a variety of GDI functions written to a DC, and then
> per-pixel copied to a texture.
>
> >
> > Unfortunately, your nice optimization won't work for my app. It supports
> > zooming in on the underlying data and that makes the strings change
> position
> > (more than just panning which your opt would handle nicely).
>
> It can still work very nicely. I found that, during profiling, its the
> char/string manipulation that is by far and away the slowest aspect.
> Therefore you need only eliminate this aspect to get a very handsome
> improvement.
>
> My code still allows the position and colour of the text to change once
it's
> VB has been created. Just lock-write-unlock the buffer. Sure, not the
> fastest way - but thats a lot faster than regenerating the text each
frame.
> I never thought about implementing it as a shader though, I just locked it
> and for() looped through it...
>
> > to a vertex shader I could use a variant of your optimization. The
string
> VB
> > would contain coords for the string placed at 0,0 or some other known
> > reference point. I would then pass the screen position for the string to
> the
> > vertex shader as constants to be added to the vertex position. Of
course,
> > I'd have to draw each string individually and update the shader
constants
> > for each one.
> >
> > I don't know if this would be any faster than generating a vertex buffer
> for
> > all the strings each time I need to draw them. This way I generate the
> > triangles and blast the whole thing to the GPU in one call.
>
> I can see how that might sound better, but as I mentioned above - the
killer
> in text output is the string/font processing. The finer points of how you
> render/update the buffers will have an impact - but in my experience no
> where near as much impact as optimizing/removing the string/font
processing.
>
> There is one other interesting alternative I've seen used - render to
> texture.
>
> That way, you can map said texture to a standard TL Quad and
> move/rotate/alter very easily with the change of just 4 vertices. The only
> nasty penalty could be the constant switching of render-targets, but I'm
> sure there'd be plenty of room to optimize that back to only occur when
the
> text changed...
>
>
> Jack
>
> >
> > Any thoughts?
> >
> > Mike
> >
> >
> > "Jack Hoxley" <Jack.Hoxley@DirectX4VB.Com> wrote in message
> > news:%23fEG175XEHA.2824@TK2MSFTNGP10.phx.gbl...
> > > If its of any interest, our engine (that I wrote) uses a custom
renderer
> > for
> > > text - and it performs phenomenally well.
> > >
> > > Granted, it was a bit more work to develop than dropping in a few
D3DX
> > > objects - but it's paid off now. iirc, the D3DX font object wasn't
upto
> > > scratch when I started writing our code - although, in retrospect if
I'd
> > > started developing it now I'd probably give more thought to the D3DX
> > > functions.
> > >
> > > Basically, my code takes a given alphabet (currently a subset of the
> ASCII
> > > character set) and uses the 'GetTextExtentsPoint32' API function to
> > measure
> > > their size. It then generates the tighest 2^n texture that will fit
them
> > all
> > > in. It then copies all of the letters to the texture, storing a lookup
> of
> > > the texture coordinates.
> > >
> > > I then make one very distinct optimization - that is, text does not
> change
> > > very often - or, if it does, it won't change every other frame. So I
> > > generate a vertex buffer for a given string object (with a handle),
and
> > then
> > > feed this into a few internal structures...
> > >
> > > When it comes to rendering each frame, all D3D has to do is spit out a
> few
> > > triangles in a VB with a texture - no particular "thought" as such.
Cue
> > > 950fps on a full 800x600 screen of size-10 text.
> > >
> > > hth
> > > Jack
> > >
> > >
> > >
> > > "mikegi" <mikegi@prestige.net> wrote in message
> > > news:%23ne8Fy5XEHA.2016@TK2MSFTNGP11.phx.gbl...
> > > > "Rich [Microsoft Direct3D MVP]" <legalize+jeeves@mail.xmission.com>
> > > > >
> > > > > What version of the SDK are you using? The Summer 2003 Update
> > > > > caches font glyphs more intelligently than before, so it is
> efficient.
> > > > > Generally you can't tell efficiency from examining source code
> anyway,
> > > > > the way to test performance is to run it and measure it, not
inspect
> > > > > the source code.
> > > >
> > > > I'm using the Summer 2003 Update. I could find out plenty of things
> with
> > > the
> > > > source code: whether D3DXSprite handles the size of data I'm
throwing
> at
> > > it
> > > > efficiently, whether it saves many more states than I need saved,
etc.
> > > Also,
> > > > I could find out how the D3DXFont caches glyph bitmaps. I will be
> using
> > > > small fonts so it would be possible to put all the ANSI glyphs into
a
> > > single
> > > > texture. A library function that can handle all sizes would have to
> > juggle
> > > > glyphs in a cached texture due to size restrictions.
> > > >
> > > > The D3DX code is relatively general purpose so it has to handle far
> more
> > > > cases than my app requires.
> > > >
> > > >
> > > > > So use whats in D3DX and only go to create your own font class if
> the
> > > > > performance indicates its a problem.
> > > > >
> > > > > "First get it right, then get it tight."
> > > >
> > > > I was hoping to benefit from the experience of others who have done
> > > > something similar in the past.
> > > >
> > > > Mike
> > > >
> > > >
> > > >
> > >
> > >
> >
> >
>
>



Relevant Pages

  • Re: Best way to draw 100-200 short strings???
    ... you handle glyphs whose black box goes negative (eg. the "f" in Times New ... tightly in rows to minimize texture size. ... to a vertex shader I could use a variant of your optimization. ... The string VB ...
    (microsoft.public.win32.programmer.directx.graphics)
  • Re: Best way to draw 100-200 short strings???
    ... > tightly in rows to minimize texture size. ... I never thought about implementing it as a shader though, ... I would then pass the screen position for the string to ... render/update the buffers will have an impact - but in my experience no ...
    (microsoft.public.win32.programmer.directx.graphics)
  • Ambiguity about ambiguity
    ... he existing square bracket notation in the texture call for channel ... string array elements for texture names. ... the channel number is *not* optional. ...
    (comp.graphics.rendering.renderman)
  • Re: Looking for information on string processing performance
    ... I love Ruby and would like to use Ruby in my new ... > performance) string processing scripts. ... and gsub) ...
    (comp.lang.ruby)
  • Re: fast text processing
    ... Can I switch to some fast byte-oriented immutable string library? ... Python strings are immutable anyway. ... I would have thought that dumping the standard string processing libraries in favor of byte manipulation would have been one of the biggest wins. ... I'm still curious if optimizing compilers are worth examining. ...
    (comp.lang.python)