A demonstration that Direct2D is patently ridiculous.

The previous blog post expressed the opinion that Microsoft’s new Direct2D API is bad. Some people might have been thinking, hey, that’s just your opinion, Direct2D is actually kind of neat.

As responsible party Thomas Olsen says on his blog, Direct2D is layered on top of Direct3D. The goal of such an abstraction layer ought to be to make the underlying functionality easy to understand, use and debug.

It seems like a natural question, then: if we take that hideous Rectangle demo application and re-implement it in Direct3D, what does it look like?

I have the answer for you; today I wrote a Direct3D version of this application. The output looks like this (click for full-sized image):

The source code is here.

You can compare it with Microsoft’s version: header file, cpp file.

My version (Direct3D) is 308 lines long. Microsoft’s version (Direct2D) is 519 lines long, or 69% bigger. There are some reasons why this code size comparison may not be equally weighted, which I’ll discuss at the end of the posting. But let’s get to the important point.

Just look at the code for the two of these examples. We know that 2D is a lot simpler than 3D. So, looking at the Direct2D code, it should be much easier to understand, right? Looking at these samples side by side, do you find that to be true? Honestly?

There are a couple of functions in the Direct3D code that might be confusing to someone who hasn’t done any 3D stuff; I think rendering_2d() is the main one. But (a) hey, if I were to write a 2D API, that function would just be the default and the user would never see it; (b) at least it is only confusing in terms of having some obscure numbers being computed — not in terms of having control flow go somewhere surprising, or having resources allocated and destroyed behind your back and not understanding the scope of when things exist (both of which are much, much worse).

Which brings up an important point:

The Direct3D version does not need to allocate permanent resources that would need to be tracked, destroyed on a reset, etc. Direct2D has you allocating ludicrous things like solid-color brushes, which for some reason are intimately tied to the device and need to be reset all the time. The D3D version of the code proves this isn’t necessary. The only allocated objects in use are the D3D interface and device. This makes the program easier to write, easier to understand, and more robust.

Now, about the code length comparison:

  • I started with the Microsoft .cpp and edited it. I kept the ridiculous 5-6 line block comments that don’t say anything useful, just to keep the size comparison more even (though the more you write fundamentally-understandable code, the less you find it necessary to drown the code in comments). I couldn’t bring myself to add these huge block comments to new functions, though, so if I were to do that, my version would be a bit longer. Also, I don’t have a big copyright notice.
  • I am not using their bloated overkill DemoApp class or any structure related to that. This results in a significant drop in program size, and an increase in understandability. Some people would say that it’s bad style not to use a wrapper class or something like that; those people are wrong, and probably believe too much of what they were taught at school. But the point is, if I were to write the Direct2D app without using that DemoApp structure, it would be smaller and simper as well (but not to the degree of the Direct3D app, I think). But then the real point is, Direct2D is designed by people who think this kind of DemoApp structure is a good idea.
  • Again to keep length comparisons fair, I kept their 1-function-argument-per-line style in places like the CreateWindow call, but again, I couldn’t bring myself to do that very many places in the new code that I wrote. Hint: If you are so scared of function arguments that you need to put each one on a separate line or else they might bite you, then you are making way too big a deal out of calling a function. You are signaling that maybe you find calling a function a little difficult — maybe you can barely manage it! Mr. Microsoft, I think you’re making the problem more difficult than it really is.
  • I didn’t vary the thickness of the grid lines or the non-filled rectangle in a device-independent way. This would be some more lines of code (10-20 maybe?) but again, that is something that would be built into a well-designed 2D API at a fundamental level, so it’s not really part of the comparison. Because…

My point is, “what would a Direct2D sample program look like if it were exactly Direct3D except with appropriate simplifications?” And the answer is, “like the program I wrote here, but simpler.” And that of course raises the next question, how could they have made this so much worse?

My impression is that Microsoft is pushing this API as the new thing for app writers in general to use when they do 2D stuff. It’s a noble aspiration to want to replace GDI, but this train-wreck of an API is about the worst they could have chosen.

Direct3D used to be terrible; in its initial release, it was very hard to make games with it. Over all the many versions from DirectX3 to the DirectX9 used here, Microsoft slowly learned to cut the bullshit and aim the API toward things that people actually want to use. (They never got all the way there; an OpenGL version of this app would be even shorter and simpler, and a more-complicated OpenGL program has none of the annoying problems with reference counting that Direct3D has; Microsoft, cut it out with the reference counting already, you are only making life harder!) With each revision of DirectX, game developers had to rewrite their games. But we did that, because hardware was evolving rapidly, and our games got big benefits out of being redesigned every 1-2 years anyway.

This will not work for general application authors. Whatever Microsoft releases as the initial version of Direct2D, however horrible it is, they are going to be stuck supporting it for damn near forever, with full backward compatibility. That’s going to make it harder for them to revise the API, to evolve it toward something reasonable.

For these reasons, I hope Direct2D doesn’t catch on. I hope it is DOA. Because if it goes into widespread use, software developers’ lives are going to get a lot more complicated for no particular reason. Software itself will become that much harder to write, and thus will become even slower and more bug-filled.

I think I have ranted about this enough.

70 thoughts on “A demonstration that Direct2D is patently ridiculous.”

  1. What’s the point of doing a code size comparison of two ways of solving a problem if the two implementations are completely different in style and code structure? I understand the point you’re trying to make, but not keeping the two examples consistent basically eliminates any value your data would have otherwise had.

    Why not convert their example to more closely match your coding style, but still use the Direct2D API, so you can perform a direct LoC comparison? Kill the comments, kill the extra line fluff, etc. At that point it’s a more fair comparison and the line counts actually mean something, and you can use them to help support your actual point (that the Direct2D API is overcomplicated). The code formatting for MSDN examples is almost *universally* horrible and I strongly doubt that anyone at MS actually likes to write code that way, so it’s best to treat the formatting as an unrelated horror, not a failing of Direct2D specifically.

    I don’t agree that reference-counted resources are inferior to the OpenGL model, but I will agree with you that handling COM reference counting in C++ is a pain in the ass. I’d be interested in hearing more about why you believe the OpenGL model for handling resources is better than Direct3D’s – from my experience working with renderers that need to support both APIs, neither approach feels superior to me, just different.

    Either way, somebody has to be responsible for freeing those resource handles at some point in a ‘correct’ program: In OpenGL you have to do it at the exact right moment by invoking APIs, and in Direct3D it’s done automatically for you by the resource itself as long as you implement the reference-counting pattern correctly.

    The need to create and destroy solid-colored brushes is pretty much unjustifiably ridiculous – the only reason I can come up with for them to do that is ‘because GDI did it that way’, or perhaps ‘well, you need to dispose textured brushes so that we don’t leak the texture’, but honestly those are both utter shit. You shouldn’t need to create a COM object to apply a solid-colored fill to a path, and you probably shouldn’t need to create a COM object to apply a gradient or a texture either. Brushes should be structs, or raw values in the case of solid colors.

    Overall, though, I think the issues you’ve raised about Direct2D are fairly weak in comparison to the biggest issue that affects it: Any API like this is basically meaningless if it only works on Windows 7. Unless they backport it to Vista and Windows XP, it’s guaranteed to almost never catch on. (Backporting to Vista alone would probably give it a chance of success, but you’ve still got 60-70% of Windows users running XP.)

    Any design issues and architectural problems in the API don’t really matter in the long run if MS doesn’t understand how to get people to adopt it; if they truly don’t understand what’s going on there, they’re as doomed as you think they are, if not more so.

    Thanks for elaborating more on your thoughts here – I think I understand you a little bit better, even if I still disagree. 🙂

  2. Structure and, to a lesser extent, style are very important elements in how understandable a program is. What you want out of APIs is for them to give you maximal freedom in structure so that *you* make the decisions. Windows is pretty terrible at this, historically (why do I have to have a callback, that I can’t necessarily do nontrivial work from, just to process window messages?) but sometimes they get better about it (e.g. Direct3D9 compared to something like Direct3D5).

    The problem with all this COM-ization of APIs is that it slants heavily toward a heavier-weight structure, and yet yields no benefit. In fact it just creates more work and confusion. In complex Direct3D apps (and, apparently, Direct2D apps of any level of complexity) I have to be able to iterate over all resources of a certain class, free them, and reallocate them. If I have to keep track of them like that myself, what is the purpose of reference counting? It’s just extra overhead and complication, and it’s an extra source of bugs (because now if I ever want to free that reference, I have to make sure that nobody points to it. This becomes a significant problem when, for example, something like a D3DXShader holds a pointer to a texture but I don’t know about that; I don’t think such a pointer should be active, but it is, so that shader prevents me from resetting the device because I can’t free the texture because the reference count will never go to 0, when in fact there is no bug in the program: next time I use that shader I am going to set the texture before I do anything anyway. Since there is no way for me to know where the reference comes from, I just have to do a lot of guessing, and this is a heinous bug that takes a long time to debug. This is not theoretical: this was a problem in Braid and it was a waste of my time and Sean Barrett’s time to figure out what was going on. Just one example of many. Want to know why so many Windows programs don’t properly handle Alt-Tab and Alt-Enter, when it seems like such a simple thing? It’s because it is *not* a simple thing because of exactly this. If the API were not refcount- and callback-based, a lot more programs would handle Alt-Tab and Alt-Enter more robustly.)

    Automatic deallocation of resources only works in a paradigm where you don’t care when something goes away: when it’s not a matter of program semantics, just resource reclamation. For simple stuff like strings, that’s the case. But when you start talking about textures and shaders and whatever, your program needs to know for sure if they are alive or not, and it needs to be able to make them no-longer-alive on demand, so the reference counts just get in your way. They are a pain in the ass. They do not belong in an API like this.

    Neither does COM, at all. In my 14 years of 3D programming do you know how many times I have ever QueryInterfaced a COM object of my own accord, when I wasn’t forced to by some version of Direct3D because that was just the way they required implementations to go? (For example: QueryInterface some D3DSurface to see if it is a D3DTexture or not). ZERO. I have NEVER done this and I never plan to. The COM stuff is just overhead and annoyance. I could have written more, faster, more-bug-free programs if it were not there.

    But anyway, about the code comparison: if you want to transpose this Direct3D example into the structure that the Direct2D app uses, go ahead. It’ll take a lot less time than it took for me to write it originally, and the end result will still be smaller and simpler. For me the important part isn’t the lines of code; that is just a side-illustration. For me the important part is how the D2D version imposes constraints and resource requirements that are not present in the D3D version. So rather than simplifying access to the lower-level, it is complicating it, and adding bloat and bugs.

  3. Everyone standing up for this obscenity seem to be missing a key point, which is that this is clearly insane.

    It may be superior to the GDI, which is possibly even worse, but nothing about that makes it any less turgid and incomprehensible by any objective standard. This would never fly coming from any other developer. It is laughable.

    And the example provided is simply unreadable. Hungarian notation? What year is this?

  4. well, I am an novice game programmer… when I started game programming I thought: I want to make 2D. I looked at DirectX and OpenGL and other APIs and thought: forget it, that is ridiculous…. I decided to go with Dark Basic SDK/ Dark GDK… because that’s an easy to use a 2D/3D API

    #include “DarkSDK.h”

    void DarkSDK ( void )

    while ( LoopSDK ( ) )
    dbBox( 10, 10, 100, 100 );


    2D programming should be that easy!

  5. Okay, what we see here in this Direct3D Example is: First, its actually shorter and easier to understand than the “newer” Direct2D. But Second, it shows that actually its not only the Direct2D API but the whole way of writing APIs like Microsoft does… I’ve NEVER seen something more complicated for such a trivial task. I mean, it would even be simpler to implement the drawing yourself and then blitting the bitmap to screen. ANY other API that I’ve seen is much easier to use and hasn’t that many overhead that the COM Model requires. If you look into APIs like SDL, Quartz on Mac, any API on .NET (like WPF or System.Drawing) or Java2D you can clearly see how it HAS to be done. I can’t imagine why it wouldn’t work on Windows too…

  6. How about this “pattern”?

    #define IFR(expr) do {{hr = (expr); Assert(SUCCEEDED(hr)); if (FAILED(hr)) return(hr);}} while(0)

    foo= ….;
    IFR(foo ? S_OK : E_FAIL);

    IFR(m_hwnd ? S_OK : E_FAIL);

  7. @Christophe

    Fantastic! It’s funny that you mentioned a Java example as being “about 50 lines of code”, because yesterday I was curious and wrote a Java class to do exactly that, then decided not to post it for fear of not getting the code to format properly. It was exactly 50 lines! It renders the grid, the two rectangles, and allows for resizing the frame (with the grid lines remaining a constant 10 pixels from each other and the rectangles remaining the same size but always centered in the frame). A single line of code and the app closes when the ‘x’ button is clicked (minimizing and maximizing are automatic). Swing takes care of repainting as needed (such as when the frame is resized), so I needed to write no code to do that. It does not need code for double buffering, as Swing does this for you (come on, having to allocate your own buffer in D2/3D???). Swing even double buffers properly as you resize the frame. I would need to add two lines for anti-aliasing, but that is senseless in a demo with screen-parallel lines, so I left it out. Also noteworthy is the fact that you do not need to create any “brush” for coloring. Garbage collection prevents me from having to write a lot of allocation/deallocation lines. And it’s cross platform. Though to be fair, using Color objects is less memory-friendly than D2/3D’s method of using longs, especially given Java’s liberal memory bloat inherited from the Object class. Assuming the compiler doesn’t already do so, it might be better to store the colors as constants, but I just new them each time out of laziness. Storing them as constants would add 5 lines, once commenting and formatting are done.

    This is the rendering code:

    // Draw a gray grid
    g.setColor(new Color(208, 208, 208));
    // Draw vertical grid lines
    for (int i = 0; i < getWidth(); i += 10)
    g.drawLine(i, 0, i, getHeight());
    // Draw horizontal grid lines
    for (int j = 0; j < getHeight(); j += 10)
    g.drawLine(0, j, getWidth(), j);

    int centerX = getWidth() / 2;
    int centerY = getHeight() / 2;

    // Draw a solid, bluish gray rectangle
    g.setColor(new Color(119, 136, 153));
    g.fillRect(centerX – 50, centerY – 50, 100, 100);

    // Draw a blue rectangle outline
    g.setColor(new Color(176, 199, 238));
    g.drawRect(centerX – 100, centerY – 100, 200, 200);

  8. I thought the last article was well said. This one just drives the point even further.

    I don’t get who Microsoft is trying to market this to; I don’t see any practical application for this new Direct2D. The API and its examples look like a cesspool of complexity and horrible engineering choices.

  9. The overhead is amazing. For all of my 2D work (ps2, psp, linux and win32,) I use SDL. It works great and is amazingly portable. It also supports rendering over DirectX.

    Being a top Microsoft Arcade developer, and still biting the hand that feeds you just made my hero! You’re my hero 🙂


  10. I am not a game programmer. I am not a graphics programmer. However, I would highly recommend at least skimming through “Essential COM” by Don Box. Reference counting with COM is ridiculously simple, especially if you use the autogenerated smart pointer. There are simple rules that add minimal overhead if you follow them; it’s a set of extraordinary circumstances when you need to do anything complicated.

    Object-oriented programming is appropriate in a lot of circumstances when writing exponentially more complicated programs — code will compile down to roughly the same as the functional version. For a sample, OO programming is rarely necessary. However, presenting HOW to structure it as object-oriented code is more valuable than demonstrating how to write it in a functional style, as it demonstrates object lifetime constraints, interdependencies, and how to structure code if you CHOOSE to write object oriented code. Converting from OO code to functional code is simpler than going the other direction. Also, having the same basic sample pattern across multiple applications makes it that multiple samples can be more easily integrated and understood. Look at how Raymond Chen at The Old New Thing structures his examples.

    You may have perfectly valid complaints about the lack of necessity of Direct2D; I thought when I saw this on reddit that this was a historical post from a decade ago. However, the value of the arguments you presented rested mostly on the shortcomings of the Direct2D API itself — the wonky render_2d method and the unnecessary screen-reset-related tasks.

    Getting sidelined by the apparent complexities of COM and demo structure just loses the value of your position — and I applaud you for pointing out the shortcomings of MSFT’s new API.

  11. Andrew, all experienced programmers understand reference counting. Yes, the basic idea of reference counting is simple. What is *not* simple is what happens when objects are reference counted but you don’t want them to be — for example, you need to forcibly destroy them all, as the Direct2D API requires you to do. In such a case, your application needs to carefully track all the objects and explicitly control their lifetimes, so reference counting just gets in the way and acts as a source of bugs.

    Also, trust me, the idea of object-oriented code is not new to myself or to the podcast guys. Braid, a game recently released on the Xbox 360, uses a very light level of single inheritance for entities in the world and a few other cases (resource catalogs and the like). But, you know what — no part of the Braid source code is as complicated as this Direct2D sample code. Yet Braid is a much, much more complicated program in terms of functionality, and does several orders of magnitude more stuff. In most places it uses what you are calling the “functional” style, which I used in my version of the Rectangle program, where there are some file-scope variables and most functions are top-level. In fact I would suggest that keeping to this level of structural simplicity was critical to my being able to manage the complexity of the program well enough to ship the game.

    It’s not valuable for the author of a “Hello World”-style program to “show how to structure it as object-oriented code”… sample code is supposed to focus on just showing me how to use the API in as straightforward a manner as possible! Any C++ programmer, no matter how mediocre, can wrap functionality in classes — why do I want an API sample to “teach” me how to do that? I already know how to do that, it is the same for everything! What’s important, and different and thus needs to be demonstrated, is the actual functionality of the API.

    Honestly, I don’t know why anyone defends COM. It is obviously, objectively a net lose.

  12. FYI, here are the code metrics on Braid as given by some random program I just downloaded:

    Global Summary (4.05 MB, actual: 3.23 MB)
    Number of lines of code: 89556
    Number of directive lines: 4772
    Number of empty lines: 30532
    Number of comment lines: 11046
    Number of empty comment lines: 2725
    Total number of lines: 138631

    483 file(s) processed.


    That doesn’t include the perl script tools or the shaders which are written in HLSL, but those are pretty small; it probably adds up to another 2000 lines total.

  13. Re Andrew’s comments:

    I am not unfamiliar with COM. My experience with it dates all the way back to 1993 _at Microsoft_, where I interned for the summer while I was still in school.

    The reason I’m not intimately familiar with it these days is because I quickly recognized it for the worthless pile that it is, and I never use it except when I am forced to in order to interface with the operating system.

    Whether or not reference counting is useful or appropriate is a separate discussion, but in general it is universally true that APIs should not pass their decisions about these things on to their users. If a library wants to use reference counting, or garbage collection, or arenas, or whatever else, great – but the app shouldn’t know or care about that. The fact that Microsoft APIs routinely expose these decisions and force the application to deal with their implications is just one of the many ways in which they fail to provide a platform for fast, reliable, and interoperable application development.

    – Casey

  14. It baffles me to see you so vehemently bashing a compensatory API developed by the company that incidentally developed the API’s you used to make your blockbuster title. You’ve entirely missed the point of Direct2D/DirectWrite by focusing on the boilerplate aspects of a very basic sample application. In the interest of killing misinformation, I strongly uge you to read up on the API(‘s) before coming up with these ridiculous, unfounded opinions. http://blogs.technet.com/thomasolsen/archive/2008/10/29/introducing-the-microsoft-direct2d-api.aspx is a good start. You might even want to post some comments of your own to the people who actually know what they’re talking about.

  15. Tom, I have already read all the stuff on that page, and more — if you’ll notice, I linked to that blog in this very posting that you are now commenting on! So I’m not sure why you think that reading it would change my opinion.

    Yes, Microsoft developed an API (Direct3D) that I used to draw graphics for a game I recently released. And it’s exactly that API that I am saying is better than Direct2D! I don’t think Direct3D is ideal by any means, but my entire point was that Microsoft already knows how to do this kind of thing in a somewhat reasonable way, but somehow the Direct2D team did not get the memo.

    It’s weird that you and some others seem to think that I should have some kind of weird reality-distorting loyalty to Microsoft just because I released a game on their console. Look, here’s how it is: some APIs that Microsoft creates are all right, quality-wise. Others (the vast majority, in fact) are terrible. Whether or not I release a game on a Microsoft machine has nothing to do with the objective facts about those APIs, so why would you expect my opinion to change? Are you saying that corruption and nepotism are virtues and that if I don’t display them, I am some kind of traitor?

    I am going to be honest about my opinions on technical matters like this; not to do so would make me a lesser human being.

    If I’ve entirely missed the point of Direct2D and DirectWrite, then would you mind telling me what that point is? And why it is effective and efficient at getting to that point?

  16. It may be the case that Microsoft API’s are supposed to be this way. Making them obtuse, hard to learn & use also makes them a large sunk-cost and harder to justify migrating away from. This (and poor documentation) has also historically made them harder to re-implement or work around independently. Microsoft API’s have always been pretty awful – Win16, Win32, GDI, GDI+, COM, COM+, etc… the remarkable thing about them all is how terrible they are. It seems like if this was a problem, rather than an asset for Microsoft, they would have done something to correct this, over the past 25+ years.

    Yet as these APIs are kinda mandated on the monopoly platform, you are probably stuck using them anyway, whether you like it or not. You’ve said that Direct3D was initially awful and has only got incrementally better – but you’re still stuck with that. The fact that Microsoft are now extending the same monopoly building API-lock-in strategy into games development is un-surprising.

    The only difference now, is that there _are_ alternatives – OpenGL, Freetype, SDL and, to a lesser extent, things like clutter and pango. Obviously this is a simplification, but the trouble is, no one actually uses them for anything much commercially, so they have limited leverage. I can’t help wishing that this weren’t true – maybe more meaningful competition would give Microsoft a kick in the pants and force them to improve this situation?

  17. Perhaps the value (to Microsoft) of D2D, might be that it would allow developers that haven’t used DirectX to stop using GDI, while still using a GDI-like language.

    This would mean that there would be a relatively easy way for Microsoft to cut support for a set of API’s, while still supporting the set of developers that still use them.

    Basically, D2D isn’t for people who know DirectX, but for people who know GDI/GDI+. I remember hearing big noises from the complaining about how different VB.Net was from VB 6… so this might be a preventative measure.

  18. This rant would make sense if Direct2D was just an API for drawing rectangles. For a real comparison, show us the Direct3D application that renders complex fonts, gradient fills, opacity masks, path geometries, etc etc.

    Also, you can’t tell me that a typical Direct3D application does not manage resources. Sure, in this one particular case, you don’t need any resources, but it’s a contrived example.

    Creating a resource for a solid-color brush might seem like overkill, but it allows the API to treat them consistently with more complex brush types, like radial-fill brushes and bitmap brushes.

    Really, I’m surprised that a C++ programmer would whinge about having to manage resources.

  19. Direct3D does gradient fills, opacity masks, and the like automatically! (You can do these things using iterated vertex color and/or texture mapping and it’s a lot more versatile than the specific examples you’re talking about.) In fact I would get an automatic gradient fill if I just passed different colors in with each vertex in that rectangle demo, instead of the same color every time.

    This example was not contrived! It’s an exact translation of the sample app that Microsoft themselves put forth. And as I just got done saying, I’ve written 100,000-line Direct3D programs, and whereas yes, they have to do some resource management, and I find that annoying, it’s nowhere near the amount of resource management required by Direct2D. And Direct2D is approaching an overall simpler problem!

    When you start talking about more-complex paths (concave or self-intersecting paths, say, and radial-fill brushes and whatnot) yes, that requires more things to be specified via the API. But it doesn’t require weird, horrible resource management! For example, I have done all sorts of things like that with the free library “gpc”, and the API there is just fine. If Direct2D enabled me to do things as complicated as gpc does, with an API that’s as reasonable, I wouldn’t be making postings like one above.

    When you say this:

    “Creating a resource for a solid-color brush might seem like overkill, but it allows the API to treat them consistently with more complex brush types, like radial-fill brushes and bitmap brushes.”

    You’ve got a very damaging core assumption, which is that it is required to create a “brush object” for any kind of drawing, ever. It’s not! It’s especially not required to manually destroy and re-create your “brush object” when your app gets iconified.

    “Really, I’m surprised that a C++ programmer would whinge about having to manage resources.”

    Look, I “manage resources” all the time. That’s not the issue. The issue is whether said “resource management” is necessary, or whether it’s making unnecessary work for the programmer and decreasing the reliability and understandability of the program. I am tired of repeating this, especially to people who would come here and try to insult me, rather than than actually thinking about what I am saying and making a reasonable reply. I often wonder why I bother posting anything on the Internet at all.

    I’m going to stop arguing with you Direct2D apologists; I have more constructive things to do. If you guys enjoy Direct2D so much, then I guess if it gains widespread adoption, you’ll get what you deserve!

  20. I noticed that my original comments have been deleted. How big of you. Jonathan Blowhard apparently doesn’t like criticism. Waaaaaaaaaaaah.

    Youre pretty vague about what part of text drawing represents “complication of the API”. Direct2D text drawing doesn’t seem any more complicated than GDI. Its definitely less complicated than drawing text with Direct3D. So wheres the problem? Why not include the code in your sample to do the font rasterization that you do with FreeType2 and then compare. Im guessing you wont do that NOT because you arent inclined but because you know that it would destroy the point that you were atttempting to make. Also you say that the “overall API design is quite bad” but really that boils down to nothing more than your not liking the fact that resources can get lost and then having to recreate them. Which is no different than what youd have to do with Direct3D. So it appears that your complaining that its not GDI. To which I say bollocks. I dont want GDI. I want something closer to the hardware. Direct2D apparently gives me that an Im willing to pay for more complexity.

    Whoever told you that DirectWrite doesnt kern is wrong. Microsofts docs say that DWrite supports font rasterization with or w/o ClearType filtering, and they do more powerful kerning than FreeType2 via OpenType. So your just wrong.

    Ive gone thru all of your comments on this thread about COM and I dont see anywhere that you explain why deleting an object through a reference count is bad. If its too much effort for you to describe what your saying maybe you should consider whether the real problem is you dont have a point to make. The rules on using COM IUnknown are simple. If you take ownership of a pointer to an object, it needs to be AddRef’d by you or by the API that you recvd it from. Once you own a pointer, you need to Release it before you go out of scope. Thats it. The reason you dont need to worry about whether a framework like D3DX is holding onto references is that COM rules are the same for all components. Follow the rules above and everything is fine. Now compare that to the nightmare of handing off references to concrete C++ classes or handles. You never know when another component is done using a particular concrete class or handle. Youre forced to to make wild-ass assumptions about which component is using which reference or handle, things can get deleted from underneath you, and it sucks ass.

    Your basic problem is that you think just in terms of writing a monolithic app like a game. If you have to write an app that hosts other components like plugins youve gotta think about how those components are going to talk to one another, what sorts of things theyre gonna share, and how different components are gonna hang onto shared things without screwing one another up, and so on. An example is a web browser or a 3D engine or a word processor or whatever. Thats one of the places where COM shines. It allows components to interact with one another thru a well defined contract. You dont seem to understand this basic principle which probably explains why you dont like COM. Its pretty basic. As for not deleting stuff because you know itll get cleaned up on process exit, what happens if someone wants to refactor your code inside their app? Your code is too brittle. Theyll have leaks cause your code just assumes it can allocate stuff w/o having to clean up. They call it more than once and the leaks are going to be a problem. Im guessing that youd probably say well they shouldnt just use my code w/o going thru it carefully. But the fact that your code wasnt properly designed in the first place means its a poor candidate for refactoring. I wouldnt use it. Not freeing resources is possibly the lamest excuse for accelerating shutdown that I can think of. Sure nobody gives a crap if your little game lets the OS reclaim its unreleased resources but what about a real app like a word processor or a CAD program that needs to close files or is in the middle of background processing etc? Is crashing a better way to go in your world? Rubbish. Not everything is a game with zero consequences for bad design.

    Huh? Reading the dox, Direct2D uses Direct3D. So how is it possible for there to be MORE cases where device loss ocurs on Direct2D than Direct3D? Thats bollocks. Youd have the same or less overhead if you wrote an app in Direct2D that youd have in Direct3d. If you added the stuff to your sample app that youd need to do to draw a toolbar or a menu or a page of html it would be hands down more complicated than what your saying. From the looks of things your just throwing crap against the wall in hopes that something will stick.

    You find my comment tiresome? I’m sorry. I didnt realize that writing an xbox game caused such ego overinflation. Whoopie shit! Little me, Ive worked on large-scale commercial CAD apps that use a plugin architecture on top of OpenGL/Direct3D and run cross platform. No its not a game. Its a professional app and thats really the point Im making. The things that you complain about and try to shortcut would be considered by many people to be reasonable well factored design. Not everythings a game and there are different tiers of devs who use technology. Maybe this stuff just isnt for you but badmouthing it smacks of misplaced, undeserved arrogance.

  21. Willard, when comments are just random Internet flaming with no content, I decline to pass them through the moderation process. So I did not pass that first comment of yours. There’s a difference between criticism and “u r dumb kthx bye”.

    As mentioned before, I have no desire to continue on in this argument… if you want to believe all the stuff you wrote above, that’s great, enjoy your lovely Direct2D future. I will give you points for the funniest 2-word phrase I have heard in a long time: “COM shines”.

    About this:

    “Reading the dox, Direct2D uses Direct3D. So how is it possible for there to be MORE cases where device loss ocurs on Direct2D than Direct3D?”

    That’s exactly my point — this is ridiculous! But it is true. You seem to be claiming that because it’s ridiculous, it could not be true. But it *is* true, and my sample app was a demonstration of that point.

    Lastly, I’ll just say that you are accusing me of arrogance for some reason, but you and several others are assuming that games are not “real apps” and are somehow simpler and lesser than something like a word processor. A word processor, are you kidding me?? Do you know what kinds of resource constraints a game has to run under and what kind of testing it has to go through to be published on a console?

    All the examples you gave about resources are straw men. I am talking about writing robust, efficient apps in the simplest and most stable way possible, and you are talking about “what if you write stuff that leaks all over the place, or tries to quit while a thread is running”. Uhh, I wouldn’t do those things! Of course I am going to close a file after opening it! Hello, are we even living on the same planet? Did you understand anything that I have written here? Nobody is saying that cleaning up resources is a bad thing, when it’s necessary for a program to run quickly and stably. However, it’s bad when an API makes you do it for no reason, and especially when the constraints introduced by the API make your program *more* brittle, because all the time you spent worrying about that stuff is time you could have instead spent working on the app’s actual functionality.

    Wow, and yet I got sucked back into the argument somehow. That’s it — I am out, no longer posting in this thread.

  22. “No its not a game. Its a professional app..”.

    Pfff, ha, ha, ha. That’s it. That proves how ignorant you are. Also, it would be nice to see a proof that you’ve “worked on large-scale commercial CAD apps that use a plugin architecture on top of OpenGL/Direct3D and run cross platform”. What are the names of that companies? What are those products?

    And I’m sorry but I find it too suspicious that there’s so many Direct2D advocates. In Tom’s blog, you can read almost the exact same arguments (but with different names). Funny…

  23. Of course you don’t want to continue the argument. You really don’t have a leg to stand on. You hit and run on COM and then refuse to describe why. I woouldnt have a problem with anybody that disagrees with me as long as they actually bothered to be specific about why.

    Your sample doesnt handle device loss. You need to modify the Present to check for a return code (in D3D10, at least) DXGI_ERROR_DEVICE_RESET or DXGI_ERROR_DEVICE_REMOVED. Direct2D returns D2DERR_RECREATE_TARGET but thats just its own HRESULT for the two D3D error codes. In other words, you dont have to handle more cases than D3D. You just look for a single error code in Direct2D of D2DERR_RECREATE_TARGET.

    Sorry but games dont have the same level of quality as most professional apps (Photoshop, Office). If a game crashes its not a big deal, you just restart it. Weve all seen this happen and nobody gives a rats ass when games crash. What do you lose? Profile data? Game progress? Big deal. Also games dont have to run in the same variety of environments as most pro apps. They usually pick a particular display bit depth and resolution and if it doesnt run then screw the user, it bails. They usually assume they have total control of the machine and its resources. They dont have to share. When Crysis runs you better not be running anything else. Try running games and then start swtiching round and doing other tings. Change your display settings. Give it a shot and see how bad thigns get. Most likely the game will crash or stop rendering. So please spare me the nonsense about the socalled level of “quality” of games. Im pretty certain taht a reasonably competent tester could rip the crap out of braid and make you want to delete all of her bug reports inside an hour.

    Maybe u missed the point earlier. Direct2D seems like a lower level API to me, like Direct3D. Not a lot of devs use Direct3D. For most of them its voodooo and requires special knowledge. Im sure that the same will be true with Direct2D altho less so, because you dont have to dig down into shaders and resource mapping. theres always a cost with using a lower level API and that cost is more complexity. But think about it. GDI could be built on top of Direct2D and you would never know it as a GDI programmer. I think thats what they are going for here which suits me just fine. Like I said I dont want GDI.

  24. “Professional” software for 3D is often much worse than games … Maya crashes all the time, for example. It’s really terrible software.

    It seems like the people who think D2D looks acceptable are just accustomed to the stench of worse APIs. It’s always surprising how a body can adapt to conditions …

  25. I’m constantly amazed by the way Microsoft took a well-known problem – that C++ code can’t be componentized into libraries because C++ classes are specific to the version of the compiler they were compiled with – and created COM, the most ridiculously complex solution imaginable, instead of doing the obvious thing: fixing the language, a la Qt. GNOME on Linux did much the same thing with GObject, which is almost as bad as COM (but at least there’s no IDL to worry about, and it’s also C instead of C++, which helps manage the complexity a little bit).

    The literature is pretty much clear these days that generational copying garbage collectors are superior to reference counting in performance anyhow. I imagine GC is a hard sell to game developers, but I think that eventually the state of the art in GC will be so compelling as to drive a switch.

    Unless Microsoft clings to COM, of course.

  26. @Willard your complete ignorance of game development and platforms is showing.

    “If a game crashes its not a big deal, you just restart it.”

    Braid was released on Xbox 360, a fixed hardware platform with a stack of technical requirements as deep as my arm. Any game released on 360/PS3/Wii requires us to go through an incredibly rigourous testing process, any crashes and game stoppers are cause for rejection. Rejection = delay and more re-cert costs.

    I’d suggest that if you actually *played* Braid, you’d notice that testing it must have been a difficult task given the complexity of situations that users can create. And that’s just to make sure people can play the game, let alone stability issues, sound drops, graphical glitches etc. etc.

    “What do you lose? Profile data? Game progress? Big deal.”

    This is just as big a deal to games as it is to apps, it may not have impacted your productivity but it certainly broke your experience. I agree with you, users of any software should be able to reasonably assume it won’t crash, but saying that “professional apps” don’t crash is completely false. In fact right now I can see the artist sitting next to me holding his hands in his head and I don’t even have to ask: Maya just crashed. … crap.

    Ok, yeah that was Maya going down again.

    On PC not being able to Alt-Tab from games to other apps is a pet peeve of mine as well, particularly if I’m on a dual monitor setup. I suspect that part of the reason is how Windows handles memory and resource allocation as getting most games up and running requires the vast majority of the resources available to a system to be committed.

    Your Crysis example is perfect, the complexity and fidelity of that game can bring any PC to its knees. If you work in graphics intensive programs with large image formats, or 3D apps with big scenes, you’ll notice a similar slowdown when attempting to go between multiple windows. When you start up Photoshop it’s snappy and responsive, get a couple hundred MB worth of images in there (or a few large RAW files) and pretty soon it starts to chug. Crysis goes from 0 to OMFG RENDER THE WORLD on launch.

    The complexity of a $20/$40/$60 game, the amount of systems interacting, the *variety* of expertise required to build one is nothing short of astonishing. To top it all off they usually get built in 9 to 18 months. (I’m speaking of larger commercial games here, not the (in many ways more remarkable) indie titles done by smaller teams) Comparing that to a tool like Photoshop with nearly 20 years of development history which costs hundreds of dollars… well I’d say it just demonstrates how incredibly *good* most game teams are.

  27. For what it’s worth, the price of photoshop has more to do with the target market than the cost of development; it’s not the right number to be looking at. (Also, comparing photoshop and crysis is a bit absurd; they’re solving very different problems!)

  28. Willard, the majority of “professional apps” I use are a pile of garbage especially MS products. Office is laughable its only usable because it autosaves every minute in fear of yet another bug toppling it the next. I don’t see where your games are simple and any fool could write them attitude is coming from.

    And have you not played on a computer since windows 98? I am playing L4D windowed right now to prove you wrong (1024×768 max settings), windows taskbar is glitched slightly but otherwise I have google chrome over the top of L4D, office, an IM client with overlays with no problems. I suggest you 1) get a clue. 2) have some fun.

  29. Willard:
    “Sorry but games dont have the same level of quality as most professional apps (Photoshop, Office).”

    First of all, games programmers are not magically stupid, they’ve got the same education, dedication and constraints as every other programmer, sometimes, the circumstances they write code for are even more demanding than other programs’ circumstances. Yet they can handle it.

    Second of all, why don’t you have a look at what games actually pull off in realtime and how they handle error situations in reality, and not in a freaking code sample? Because as soon as you’re bringing Photoshop and the like into the mix, we’re not exactly on code sample level anymore.

    Third, your examples crash all the time, can’t handle networked devices reliably, aren’t flexible enough to get bugs fixed, ..

    And CAD software isn’t any better in that regard. I’m just adding that because people on this blog like to refer to them for some reason.

    If you actually want to talk about “superior software”, get some decent examples. I can name quite a few games that blow Office or Photoshop out of the water quality-wise, some of them dating back to ’98, which is amusing by itself if you consider in what state for example Office was at that point and what history it had.


    “Some people would say that it’s bad style not to use a wrapper class or something like that; those people are wrong, and probably believe too much of what they were taught at school.”

    I’ve got an academic education, basically learned ‘serious’ programming at Uni, and having some real-life experience now, I am rather amused by you mentioning this.

    In fact, I developed a fairly complex web application in Java with some other people fresh out of or still going to Uni some years ago, and looking back at that experience, I want to say that the amount of overthinking that is taught and expected nowadays is disgusting.
    A lot of APIs really grind my gears in that sense, meaning that they want you to interface here with that pattern and overwrite that in this particular OO fashion, and what you end up with is NOT A GOOD TIME and code containing tons of generically-named junk you only need because some dude read a Programming Patterns book and subsequently declared it as religion.

    I’m not even sure we’ll ever grow out of this. All you really can do as a person is not subscribe to that mindset in your own code and point at horrid examples in the world from time to time to make people aware of it.

    Which is what you, Jon, did, and therefore I salute you.

  30. Rather than investigate Direct2D so that I can make an informed opinion, I think I’ll just trust you so that I can save myself some time.

    I am not particularly interested in Direct2D. However, I have been waiting to say that Microsoft’s use of “helper” classes in their tutorials/samples is an atrocity. Despite this, I would still say that Microsoft has the best first-party documentation, samples, and tools of any producer of game-development related APIs which I have had the displeasure of using.. and that is why they continue to be a thorn in my side.

  31. Amazing, some of the bull shit trolling you’re getting in this thread.

    Props for calling out a bad API and refusing to back down when you’re clearly correct from a technical perspective.

    I hope you’re able to avoid too many unfortunate collisions with D2D, as it looks about as pleasant as doing OO in BASIC.

  32. @Blow: “Direct3D does gradient fills, opacity masks, and the like automatically! (You can do these things using iterated vertex color and/or texture mapping and it’s a lot more versatile than the specific examples you’re talking about.) In fact I would get an automatic gradient fill if I just passed different colors in with each vertex in that rectangle demo, instead of the same color every time.”

    You’re missing the point, Blow. This API isn’t targeted at people who use Direct3D. People who use Direct3D crowd are a very small segment of the developer community, and they want complete control over the rendering pipeline, so they’re not likely to use Direct2D unless, say, they want to simplify text rendering. Nah, this API is for people who currently use GDI/GDI+ and want the *possibility* of interop’ing with Direct3D, if they need that much power. Most people won’t use Direct3D. Ever. When you look at the API thru that lens, it makes sense. People that use GDI/GDI+ are accustomed to managing resources. No, GDI/GDI+ devs don’t have to worry about device loss but, then again, they can’t interop with Direct3D (which does require managing resources thru device loss), either.

    Also, I don’t think you’re considering the bloat that would have resulted if this API had virtualized every resource. Let’s take the example of a virtualized bitmap. In order to make sure that the bitmap sticks around thru device loss, the API would need to keep a system memory copy so that when the device goes away, the resource can transparently recreate the one in GPU texture memory from the copy in system memory. Now imagine it had to do this for EVERY resource. Not to mention that the application probably loaded a codec that has its own decode buffer to open the bitmap from disk. Are you getting the picture here? Virtualization carries a very heavy price in terms of bloat. The way that Direct2D has structured things, apps get to decide how (or IF) things get virtualized. This reduces bloat, at the cost of complexity. Which is probably the right tradeoff, given that the API is sitting somewhere between GDI/GDI+ and Direct3D.

  33. @Wolf: “Which is what you, Jon, did, and therefore I salute you.”

    No, what Blow did was grind his axe over four things. He criticized the samples’ use of a C++ class (rather than use global variables), number of lines of code it took to draw a rectangle, COM ref-counting, and resource management thru device loss. I find the first two rather ridiculous. The sample isn’t the API. Don’t like the sample’s use of a C++ class, and prefer to use global variables? Fine. Don’t use a class! That has no bearing on the API or its use whatsoever.

    Regarding lines of code, Direct2D does a helluva lot more than draw rectangles, but he never even scratches the surface with the wider set of features because he’s cherry-picking his arguments. Blow really owes you an example of how to draw anti-aliased text using Direct3D vs Direct2D. I’d love to see that. Really, I would. It won’t happen, though, because he knows he’s wrong. He just won’t admit it here.

    Criticizing COM is pointless and silly. GDI/GDI+ allocates objects with handles. When you’re done with them, you release them. That’s functio

  34. (Continued)

    …That’s functionally equivalent to releasing objects via COM ref-counting.

    Not virtualizing resources through device loss is a debatable “feature”. However, read my post above, and you’ll realize that virtualization carries with it a stiff cost of BLOAT. I would rather choose when resources should be created and discarded, rather than have some middleware layer guess when it should do so. It’s simply more efficient that way, because only I know my app scenarios.

  35. @If: “How about this pattern”?

    #define IFR(expr) do {{hr = (expr); Assert(SUCCEEDED(hr)); if (FAILED(hr)) return(hr);}} while(0)

    foo= ….;
    IFR(foo ? S_OK : E_FAIL);
    IFR(m_hwnd ? S_OK : E_FAIL);

    Sigh. do while(false) is a widely known pattern for dealing with complex macros. Here’s an article on it…


    It’s also favored in the C++ FAQ. Educate yourself.

  36. Hey, Blow. Direct2D is built on top of Direct3D10. Your code is written for Direct3D9. Looks like a case of comparing apples and oranges.

  37. What a bizarre post.

    “But then the real point is, Direct2D is designed by people who think this kind of DemoApp structure is a good idea”

    I don’t know about this particular one, but code samples are very often written by someone other than those building the platform. Then again, I think the fact that they’re properly scoping their resources and writing maintainable code is a good thing.

    And the rest of this rant is just absurd. You don’t like refcounting? Why the *hell* not? You do realize that a sample isn’t a complete project. If you were writing a real app where these objects are passed around to different threads/processes and being used by code owned by several developers, you’ll be damn thankful for refcounted objects.

    @Wolf –
    That’s odd, your perception seems to be the opposite of mine. I tend to see college grads / newbies as the ones who just throw some half-assed code into the editor and call it good, instead of thinking through the design and building something clear, maintainable, and extendable. Not to mention supportive of static code analysis tools that help proactively identify bugs or security holes.

    If you want “easy mode” programming, go use .NET. If you want to use Direct3D then gosh darn it, use Direct3Dj and stop complaining that your way isn’t the only way. This API is for native C++ programmers who WANT a nice clean refcounted model.

  38. Willard said: “Sorry but games dont have the same level of quality as most professional apps (Photoshop, Office).”

    You’re comparing software with a relatively short development cycle to software that has been refined over many iterations over many years. Any comparison in regards to robustness (or bug tolerance and other metrics) is almost meaningless.

    The development cycle of a game typically a fraction of the development cycle of software you are mentioning (large scale CAD apps, for example). An extra 2 months of development time on a game does wonders in terms of polish (bug fixes, gameplay tweaks, including more animations and art, etc.). 2 extra months for large scale software is typically reserved for critical bug fixes only.

    With that in mind, you can’t label someone as lazy when they expect tools that would save them time, effort, and piece of mind in making software with such short development times. Especially when there are alternatives out there that do so.

    Though I do agree with Brandon that .NET would be the sort of tool one would look to if their goal is to reduce time, effort, and piece of mind (perhaps at the expense of performance among other things). At the same time, I can see why someone wouldn’t want to use something like XNA (I’ve taken a peek at it and I think it’s great, personally…but I’m a guy who enjoys doing art and music rather than programming, so I like seeing results on screen very fast while my code is an unreadable hack job).

  39. I was really interested in having a look at that new API that was said to be harware accelerated and much more efficient that GDI and GDI.

    This week, I’ve written a small Direct3D 10 to check the performance of Direct2D and DirectWrite. I wanted to compare the results against pure Direct3D features – the config : Dell XPS1730/Vista 32/SLI of 8800m GTX/4Go

    The application was quite simple : it creates a 640x480x32 window, clears the render target and the depth stencil buffer, and just displays the frame rate (using either Direct3D font or Direct2d/DirectWrite).

    Using Direct3D, the frame rate was about 4600 FPS. Using DirectWrite, it fall down to 2500 FPS !!!!

    I found the Direct2D API really hard – the documentation was horrible, just like it is for Direct3D.
    I was first enthousiast when I glanced at the possibilities regarding text formatting, but this went far away when I tried to write a simple peace of text and realized that the promised performances where desperately not there.

  40. you’re totally right, and as usual with one-sided top-of-the-surface articles like this, you’re also very much wrong.

    D2D is meant for serious, heavyweight 2D apps that require interop with D3D and/or GDI/GDI+. It’s real power / efficiency is not shown in a tutorial demo such as this. I completely agree that it is a complicated API, and that Java2D or Qt would be easier APIs to do something like this — but just as OpenGL is really designed to make it easy to get a triangle on the screen, DirectX is designed to ensure top-tier programmers can use the GPU optimally, there is an analogous situation between D2D and these other APIs that should be considered. Microsoft *does* have easier-to-use APIs that ABSOLUTELY wipe the floor with other 2D drawing frameworks, namely Silverlight / WPF, and if you wanted to write the equivalent app in one of these, your example of being simpler to develop would be easily shot down. D2D just fits into a middle-layer that is right for certain customers / applications, and not right for many others — but I think that’s probably okay / desired by Microsoft because they have like thousands and thousands of customers who all have different needs.

  41. D2D is not going to help with rendering common controls in a 3D application. This is pretty unbelievable really. If I were writing Windows 7, I would have implemented all common controls using D2D and then they could be used wherever. Instead D3D developers are still stuck having to implement their own controls. This is crazy having to waste time creating a D2D textbox, listbox, etc etc. When will this be fixed?

  42. The fact that they do not have a wrapper for XP makes D2D unsuccessful, fortunately.

    Microsoft C is not C anymore with all IDL stuff and being tied to registry.
    The next time we are going to redesign our code it will be all in Qt, no more COM shit.

  43. Thanks for the post.

    Well, maybe you are right, because MS code and APIs are always quite bloated.
    But i must admit that after N years striving to have some basic shape generation on GPU, without falling back to sw rendering to texture and the transforming on the 3d pipeline, D2D vectorial functions are at least “interesting”.

    The problem shifts on other topics.. WPF integration? Managed Wrappers?
    Who knows.. MS makes it very difficult choosing a long term technology..

  44. The past few months i learned vb .net..
    Last week i learned win32 c++..
    This week i learned direct2d..
    next week ill learn direct3d and never look back on direct2d..

    d2d1 = crap

  45. “making unnecessary work for the programmer and decreasing the reliability and understandability of the program.”

    Well said.

    Microsoft are hardly ever able to put themselves in the place of the developer who has to use their APIs and probably never will. As long as they are able to maintain their stranglehold on the desktop they can impose their shitty ways or think they can. Nothing new there. I’m using SDL for 2D apps and it’s simplicity, clarity and cross-platform nature is ideal.
    I am ignoring this API since it is not compatible with XP and I doubt it ever will. It also appears to complicate things where they shouldn’t be.

  46. So, if one has been using the oroginal Windows GDI and now wants faster better looking screen draws where does one look? I would think this is a simple question but from what I’ve read everyone has a different answer.

    Thanks for any informed replys

  47. Some comments say that Direct2D is sought to be a replacement for GDI, but everybody seems to be missing the point: why did Microsoft feel like they had to reinvent the wheel?

    I see things this simple: re-implement GDI32.DLL on top of Direct3D, and replace indexed-color support with alpha blending in all of the APIs. I’m pretty sure that every object in GDI can be re-implemented on top of Direct3D and stored in video memory with little effort. All they had to do was change the internals. For example, they already identify 3D surfaces with a specific COM Interface in Direct3D. Coming from GDI, as most graphics programmers might be, when I learned Direct3D, the best thing to compare a Direct3D surface with was a GDI Device Context.

  48. Right or wrong, bloated or not, I appreciate the fact that I found this article and read opinions, pro and con, about this interface. The feedback makes it impossible to tell who is right and in what context. That’s the ill of the internet.

    Jon, thanks for writing a review and a comparison even if it’s not what many think is meaningful.

    All I want to do is get 30+ FPS for a 2D simulation program. It’s a prototype for a game and the 2d is needed to test the basic internal functionality of the simulation. I’ve written a few “simulation” programs using GDI and I get a high enough frame rate rending GDI stuff in a bitmap and blitting it to the window, that I don’t really need another API. The only reason I was looking at 2d rendering tools, and found this, is because I’d like to get some anti-aliasing to make things look nicer. Rendering to a 2x bitmap and shrinking it does the trick if I don’t mind the 5x loss in FPS to get the smoothing effect that shrinking provides (using GDI or GDI+).

    I blather.

    Thanks again for the review and comparison.

  49. But dude..you did ur demo using dx9 stuff…D3D10(the one used by d2d) dont have the fixed function pipeline, that is what makes doing 2D stuff kind bottled and messy, having an api that does all that stuff is the point of D2D..at least its my understandment of it…
    But Im kind noob, if you thing Im saying shit Id like to know your opinion about it..

  50. Unfortunately, a lot of people are missing the point here. As much as I’d hate to say it, that includes Mr. Blow.

    Let me break it down into easily digestible pieces. This is from the perspective of a developer and not an industry keyboard-jockey so I can
    honestly say that this is fact, from experience and not merely speculation.

    1. GDI. GDI is faster than GDI+ in many ways, but lacks significant features which GDI simply cannot replicate. GDI+ was a logical path in the evolution of GDI in spite of the performance hit that was taken — considering the addition of Antialiasing as probably the most significant improvement, without hardware support a performance hit is expected.

    Microsoft had originally envisioned that GDI+ would be supported at the driver level and thus, would be hardware accelerated. Out of all the video card manufacturers who were active in the market at the time, Matrox was, as is my understanding, the one and only manufacturer to provide that hardware acceleration. Unsurprising, considering the effort they went to in order to support as much of the DirectDraw API as they possibly could.

    With the plans to see GDI+ supported in hardware fail, the only other choice at the time was DirectDraw. Unfortunately, like GDI, DirectDraw lacks significant and important features and even with the full API supported at hardware level, all you’re really getting is hardware accelerated blitting, clipping, colorkeying and stretching. Rotation and Mirroring were not supported by most manufacturers, Alphablending was also omitted in the desktop version of DirectDraw and had to be done through software calls. All 2D primative functions were mapped through GDI and even with the ability to call GDI+ and draw to a DirectDraw surface in system memory, there are still obvious pieces missing from the overall “2D API” picture. Had the integration between GDI+ and DirectDraw been a little tighter and had DirectDraw supported Alphablending at the hardware level, the situation would be a little different.

    And so, without a ‘true’ hardware accelerated 2D API on the desktop, using Direct3D to create a ‘hardware accelerated GDI+’ hybrid is the next best and most logical step. Introducing a completely new 2D API is not only unnecessary but places needless burden on hardware manufacturers to support it at hardware level, write more drivers, etc.

    Direct2D is excellent — especially for .NET Developers who have had to cope with a less-than-ideal Managed DirectX, DXGI or a third party OpenGL wrapper of some description. Microsoft have done an excellent job and porting a DirectDraw or GDI+ project to Direct2D is not only extremely easy but most definitely worthwhile.

  51. Giuliano, don’t worry, the author of this article and several commentators are just ignorant. Anyone doing this article would have read the most basic d2d information and seen that it’s built on top of dx10, not 9… The reason this article used directx9 instead of 10 is because they know that if they had used 10 it would have been longer and more complex than d2d.

  52. Irrelevant strawman comparison. What is the BINARY size difference between these two files? Benchmarks of speed?

    Just counting the source-lines says nothing about the resulting program after compile-time transformations and optimizations.

    Example: STL is HUGE but can compile to a tiny binary vs hand-coding a similar data-structure in C. And, you know STL is already well-debugged.

  53. “Direct2D is excellent — especially for .NET Developers who have had to cope with a less-than-ideal Managed DirectX”

    So you’re saying it’s allright to develop a needlessly complicated direct2d API, just as long as it somewhat fixes another needlessly complicated framework of .NET?

    Not being able to use directx the relatively easier way from .NET just shows one of .NET’s weaknesses. Desgining a Direct2D API just for that is not a solution, but rather allowing a continuation of the troubled .NET situation.

  54. The fact remains that there is NO cross platform accelerated vector graphics API’s out there for UI developers that are 1. Open Source, 2. GPL licensed or 3. MIT licensed. Direct 2D is an Excellent API for those of us that do not do 3D graphics. Compared to GDI ( in which you have to do resource management ), Direct 2D with a ComPtr class ( easy to roll your own or if you are using Visual Studio professional to build windows apps for sale (like you should) you have ATL’s CComPtr ) is easy to set up, and use. Speed wise? On windows 7 it’s slightly faster than gdi, which is CONSIDERABLY faster than gdi+. With Windows 8 it’s improved, and give it some time as you had to do with Direct 3D and it’ll be on par for good use. Coverage wise? It’s available on Windows Vista platform update, along with a plethora of technologies that were made available with Windows 7. Will it ever be ported to XP? Highly doubtful, as the hardware vendors will not support that platform. Pick up the newest NVidia or ATI card and see if you can find XP drivers for it. Enough said. Code wise? It’s lightweight COM. Meaning it’s an extremely stripped down Com. With proper design you never even have to call QueryInterface(). Of course you know this already, as it’s the same lightweight com that you use for Direct 3D.

    Honestly, the ability to make a fluid anti-aliased UI that customers are increasingly demanding is there with Direct 2D. And the why the api was designed for cross compatibility within the Microsoft ecosystem was THE best move they made with the api. It allows older GDI based code to be piece mail migrated to Direct 2D. It also allows Direct 3D developers to use it for 2D graphics in a much more natural way than having to go through the loops of changing the perspective to just draw the 2d portion of the UI.

    I know everyone loves to rant about Microsoft, and as a large part of our code base was written to be cross platform, I get to read a lot of rants in the comments in the code. Some are funny, and I agree with, and some are just plain opinion.

    Tell you what.. Make a Direct 3D program that draws an anti-aliased rounded rectangle, fills it with a pleasing color gradient, and do hit testing on it, is as few a lines as what Direct 2D can. THEN come back and make a widely read blog post ranting about Direct 2D, or OpenGL. Something tells me (IMHO my own experience) you wont.

    I’ll say this much though. The Minute a good OpenGL c++ library becomes publicly available I’ll jump on it like white on rice. Until then, when on a MS system, Direct 2D it is!

  55. Nowadays applications MUST be DPI-aware.

    Therefore Direct2D is way better than DirectX, since it supports vectorized graphics.

    I think you missed this very important point in your article.

Leave a Reply to Jonathan Blow Cancel reply

Your email address will not be published. Required fields are marked *