+ Reply to Thread
Results 1 to 21 of 21

Thread: optimising rendering using DirectX7

  1. #1
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default optimising rendering using DirectX7

    Im using an engine based on DX7 for my '2D using 3D acceleration' game. I want to optimise the rendering so that I'm not going to tax older cards (I have a geforce6800 but want it to run on much older cards).
    The best optimising tool I can find is the nvdia perfhud stuff, but the code it requires assumes directx9, which im not using at all. Moving to DX9 seems like mega hassle right now.
    Does anyone have any good ideas or tips for speeding up DX7 rendering? I'd love some kind of data on how much Im taxing the fill rate and the poly count. I'd also REALLY like to know when the card stalls, as I do a lot of getDC() to use GDI for text rendering, and I'd love to know when (and how badly) this stalls everything.
    Im interested to know the approaches used by people using a 3D engine on casual games so it works fast and reliably on older hardware. Especially using DX7.
    thanks.

  2. #2
    Moderator
    Join Date
    Jul 2004
    Location
    Zürich, Switzerland
    Posts
    1,966

    Default

    Are you sure you have a problem to begin with? I haven't done any interesting optimizations in our 3D renderers, and Pirate Poppers didn't have any technical problem with requirements. I use D3D7 and I saw the game running in laptops with onboard videocards with 8 MB of RAM.

    About the text issue, can you render to a bitmap and convert it to a texture instead of using GDI every frame? I render TrueType fonts with SDL_TTF which is slow but as long as you don't render every frame and reupload the texture every frame, you should be OK.
    Gabriel Gambetta
    Google Zürich - Formerly Mystery Studio

  3. #3
    Senior Member
    Join Date
    Jul 2004
    Posts
    280

    Default

    I don't really have any good suggestions for an automated perf tuner, but I know from experience that calling GetDC even once per frame really can be a framerate killer on some cards.

    I second ggambett's suggestion to cache the font to bitmap textures. You can do this at runtime so you have full font flexibility just as you have now, just draw the characters via gdi once (per font/fontsize) and hold onto the results in a resuable D3D texture. As long as you keep the alpha information intact, this can look just as good as if you're rendering them using gdi.

  4. #4
    Senior Member
    Join Date
    Sep 2004
    Location
    San Jose, CA.
    Posts
    1,726

    Default

    Surprisingly, most games are actually CPU bound. If you are doing a 2D game, chances are even lower that you'll ever be GPU bound, even going back as far as GeForce 2.

    To keep CPU overhead down, try to avoid touching the runtime as much as possible. Keep the draw calls under 1000 or so, batch according to render/texture/material state, and follow ggambett's advice about compositing your textures. That should be enough, barring anything silly.

    Integrated graphics however are a different story. It's really easy to become framebuffer bandwidth limited on them.
    Peter Young | www.attitudegain.com | Linkedin | Twitter

    Projects:
    Meridian 59: Evolution
    ???
    ???

  5. #5
    Senior Member
    Join Date
    Aug 2004
    Location
    Edinburgh, UK
    Posts
    342

    Default

    If Direct3D is using hardware rendering, and you're batching half-decently, then you're almost guaranteed to be CPU bound.

    If you lock anything in D3D you could be stalling your rendering, so ideally you should lock as infrequently as possible, preferably never on a per-frame basis.

    Direct3D 7 also has a bug where switching vertex buffer is unusually expensive, so you may want to sort your rendering by vertex buffer first, then by 'shader' then by texture.

    Probably the best thing to do if you can't profile on an older card is to find some of the older NVIDIA presentations when D3D7 was the standard. Have a look here, and read the docs from the bottom up:
    http://developer.nvidia.com/object/p...s_by_date.html

    Hope this helps,
    Pete

  6. #6
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    I used to do my own font stuff with bitmaps, but the results just arent as elegant as GDI. Are you suggesting just rendering out each character and then piecing words together? or rendering out whole blocks of text , cacheing them, and resuing them each frame?
    I find that GDI seems to do a lot of funky smoothing and kerning and so on that makes its text look way better than I could get doing it by blitting.
    Democracy uses GDI, and Starship Tycoon uses bitmaps, and I think the Democracy text looks much nicer.
    I'm going to poke around a bit mroe and see if I can reduce my GDI locks.

  7. #7
    Senior Member
    Join Date
    Jul 2004
    Posts
    280

    Default

    If your text is very static you should be able to get away with just caching full blocks of text, but in my case I drew out all of the printable characters for the font to one texture and then mapped sections of that texture to simple quads (same as the standad 2D/3D sprite drawing trick) to draw individual letters. You could do it more simply by having one sprite/texture per character, but you'd of course waste a lot more vram that way (maybe it wouldn't be a big deal depending upon the situation).

    The smoothing should remain intact as long as you properly cache the alpha information that is written to the destination DC's bitmap when you do the drawstring and encode that in the texture (and use a texture format that supports alpha). When I did this I actually used Gdiplus and capturing the alpha along with the rest of the drawn bits (drawn into a 32bit ARGB offscreen bitmap) was very easy. I assume it is possible to do the same with plain old GDI, but probably far more cumbersome (everything is). Getting the kerning to look good is a bit of extra work but not as bad as it seems, I used MeasureString (again, Gdiplus) to measure the width of each character at the font size being used and kept that in an array and used those values when drawing out the characters, so 'i' wouldn't display at the same width as 'A', for example.

  8. #8
    Senior Member
    Join Date
    Jul 2004
    Posts
    1,216

    Default

    Quote Originally Posted by gmcbay
    [...]Getting the kerning to look good is a bit of extra work but not as bad as it seems, I used MeasureString (again, Gdiplus) to measure the width of each character at the font size being used and kept that in an array and used those values when drawing out the characters, so 'i' wouldn't display at the same width as 'A', for example.
    Uhm... thats just proportional font stuff. Kerning is unfortunately more difficult than that.

    http://en.wikipedia.org/wiki/Kerning

    (So far I havent bothered with that. Its not worth the trouble if there are only a few lines of text.)

  9. #9
    Senior Member
    Join Date
    Jan 2006
    Location
    UK
    Posts
    221

    Default

    What you need is mudgefont. Someone on here made it I think. Might have been Larry Hastings. It's a great program that lets you output smoothed tga's with alpha information at various sizes, with various borders/styles, and also exports an xml file with all the widths and offsets you need to make a decent kerning system. Sorry I don't have a link handy. I downloaded it years ago, and I think that was a direct link from a post on the old dexterity forums. Google probably knows where. It took me less than 2 hours to make a fully-featured font system based off of mudge fonts outputs.

  10. #10
    Senior Member
    Join Date
    Mar 2005
    Location
    England
    Posts
    531

    Default

    Quote Originally Posted by cliffski
    I'm going to poke around a bit mroe and see if I can reduce my GDI locks.
    It's worth writing something that you can submit your text & it's positioning to, and then rendering all of the text in one go in your render loop at a later time. That way you should only have one GDI lock per render update.

    Personally, i wouldn't use GDI. I tend to go with the texture/vertex buffer method.

  11. #11
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Default

    I cant quite do that because I have draggable overlapping windows ;(
    It turns out that slowdowns some testers saw were game loop Sleep() related and not frame rate anyway
    But I still intend to rearrange stuff to cut down on my GDI locks. I didnt have any compatibility issues with Democracy, but I'm hoping to lower my system reqs.

  12. #12
    Senior Member
    Join Date
    Jul 2004
    Location
    Isle of Wight, UK
    Posts
    3,773

    Default

    GDI is shit in so many different ways. You should see what's going on inside the innermost loop! The GetDC call may or may not be hurting you based on what else you're doing, but it really is a bad thing to be doing generally and as your target card gets older, the pool of bad things you shouldn't do gets ever deeper.

    If you really must use GDI for its few nice advantages/features, you should consider rendering your text into a texture and using that. I don't mean on-the-fly as that would be bad too - just use GDI to make a tileset texture at loadtime in much the same way you would if you'd hand-authored a bitmap font in the first place.

    My previous engine did this and it worked a treat. (Well, until I ported it to PS2, which is why I try to rely as little on O/S calls as possible, but that's another topic.)

    EDIT: I of course meant rendering a character set, not "text"
    Regards,
    Paul Johnson

    [Great BIG War Game: iOS | Android] [Great Little War Game: iOS | Android] [Fruit Blitz: iOS | Android] [Yachty Deluxe: iOS | Android]

  13. #13
    Moderator
    Join Date
    Jul 2004
    Posts
    3,905

    Smile

    yes Ive done this before, for older games, and now I've come back to GDI because of the quality. I know it *should* be a bad thing, but Democracy had very little end-user problems. In an ideal world I would have a bitmap font system that looked as nice. I think I notice the nice stuff GDI does more because my games are strategy ones with a LOT of text, often in many different sizes. I think if you only have a few lines of text per screen, rendering to a texture and then doing your own compositing from there is certainly the way to go. Thats obviously how big 3D games do it (The movies did this).
    Right now I'm on the fence about redoing it using that approach, because of the work that's involved in getting it right.
    As someone pointed out, getting character widths automatically is one thing, but sorting it so that (for example) a VA goes together taking into account the relative position of the 2 characters is another matter. I'm pretty sure that GDI does this.

    Don't you wish there was an option in windows to say "just render like a card with half the memory and draw speed" so you could check this stuff easily?
    Im concluding that even if I had some mega debugging stuff that told me my GDI calls werent a bottleneck, its only going to be true for MY card anyway ;(

  14. #14
    Senior Member
    Join Date
    Sep 2005
    Location
    Citizen of the Universe
    Posts
    492

    Default

    Quote Originally Posted by cliffski
    Don't you wish there was an option in windows to say "just render like a card with half the memory and draw speed" so you could check this stuff easily?
    For a start they could add "at next reboot simulate x physical memory" (where x is of course <= your max physical memory), so that I could test my proggies on PCs with less than my gig without having to remove the sticks or even having to buy small ones (since I can't cut in half a 512MB one anyway).

    It's astonishing how simple options things like this never appeared in twentyfive years of PCs.

    Now you'll see Bill Gates feature it and promote as something smart and cool (well, still better than promoting it as an absolute innovation like he did with Windows95's preemptive multitasking after that the Amiga had a MUCH better one already 13 years before, ouch).
    Greets,
    Fabio

  15. #15
    Senior Member
    Join Date
    Sep 2004
    Location
    San Jose, CA.
    Posts
    1,726

    Default

    Quote Originally Posted by cliffski
    Don't you wish there was an option in windows to say "just render like a card with half the memory and draw speed" so you could check this stuff easily?
    Im concluding that even if I had some mega debugging stuff that told me my GDI calls werent a bottleneck, its only going to be true for MY card anyway ;(
    For draw speed, you can always lower the clocks...
    Peter Young | www.attitudegain.com | Linkedin | Twitter

    Projects:
    Meridian 59: Evolution
    ???
    ???

  16. #16
    Senior Member
    Join Date
    Jul 2004
    Location
    Isle of Wight, UK
    Posts
    3,773

    Default

    Just find yourself a TNT2 PCI card and stick that in (either for your second monitor or on a switch if you only have one). They should be about 5 bucks by now if you can even find someone to sell you one.

    It's dead easy to fire that up as your games main target.
    Regards,
    Paul Johnson

    [Great BIG War Game: iOS | Android] [Great Little War Game: iOS | Android] [Fruit Blitz: iOS | Android] [Yachty Deluxe: iOS | Android]

  17. #17
    Senior Member
    Join Date
    Feb 2005
    Posts
    1,667

    Default

    Well, and then there are people developing on laptops...

  18. #18
    Senior Member
    Join Date
    Jul 2004
    Location
    Isle of Wight, UK
    Posts
    3,773

    Default

    Yeah, I couldn't envisage trying to develop games without the right kit.

    If you're developing for a wide (especially low-end) pc audience you should really have an entire box full of older video cards lying around, and something to test them in.
    Regards,
    Paul Johnson

    [Great BIG War Game: iOS | Android] [Great Little War Game: iOS | Android] [Fruit Blitz: iOS | Android] [Yachty Deluxe: iOS | Android]

  19. #19

    Default

    You might also want to look into using Thom Wetzel's "Bitmap Font Builder" tool, possibly using DrunkenHyena's dhFastFont code as an example of how to do this. I found it quite simple to setup and integrate with my code, though dhFastFont appears to be DirectX 8+ only.

    If nothing else, I think it's a good reference for creating your own sprite-based text library.

  20. #20
    Senior Member
    Join Date
    Aug 2004
    Location
    Edinburgh, UK
    Posts
    342

    Default

    Things like localization and/or unicode characters make packing a whole font onto a texture difficult, making a caching system necessary.

    I would probably go for some kind of LRU phrase-id-to-texture mapping, but it depends on your requirements/workload involved/benefits gained.

  21. #21
    Senior Member
    Join Date
    Jul 2004
    Location
    Hamburg, Germany
    Posts
    298

    Default

    After trying a few solutions (like prerendered bitmap fonts) I ended up using FreeType to render the text into a piece of texture and re-render it when the text changes. To make this efficient I pick the label sizes to match frequency of change. Frequently changing text will take effort anyway, you either need to hack VB's or upload textures. This solution works OK to the extent that text rendering is no longer a performance issue, and the resulting text looks smooth and can be scaled as much as the TrueType font permits. I also modify the texture in other ways before it's uploaded, to create things like drop shadows.

    At one point I did the whole UI by CPU using AntiGrain and then cached the textures for fast rendering. Pretty good tradeoff between performance and looks.
    Kai Backman, programmer (Blog)
    ShortHike Space Station Game

+ Reply to Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts