Welcome to TechNet Blogs Sign in | Join | Help

New Direct2D Article by Kenny Kerr in June 2009 MSDN Magazine

http://msdn.microsoft.com/en-us/magazine/dd861344.aspx

 

DirectX Blog is Live

In order to consolidate a lot of the information from various blogs, we decided to create a common DirectX blog. You can find it here:

 http://blogs.msdn.com/DirectX/

 This is where I'll be posting upcoming information about Direct2D. I may link from this blog, but assume that the DirectX blog is the place to go. :)

Posted by Thomas.Olsen | 0 Comments
Filed under: , ,

Updated Direct2D in March DirectX SDK

The March DirectX SDK includes an updated build of Direct2D. Note that this build of Direct2D runs on both Windows 7 and Windows Vista.

http://msdn.microsoft.com/directx

After the Windows 7 Beta release, we received some customer feedback, and made a few minor Direct2D API changes.  These changes are present in the March DirectX SDK, but the documentation will not be ready until the Windows 7 RC release. In the interest of getting prelease code into the hands of customers faster, here is a list of breaking changes...

·         Refactored some values of D2D1_RENDER_TARGET_USAGE into D2D1_RENDER_TARGET_TYPE for better clarity.

·         Added D2D1_FEATURE_LEVEL  structure variable to  D2D1_RENDER_TARGET_PROPERTIES. Allows the caller to specify a minimum hardware feature level (9, 10, etc) to use.

·         Added D2D1_OPACITY_MASK_CONTENT parameter to ID2D1RenderTarget::FillOpacityMask. This tells us what gamma to use.

·         Removed D2D1_GAMMA parameter  from ID2D1RenderTarget::FillOpacityMask. Based on customer feedback, we determined that this parameter was difficult to understand, and the same information could be gleaned by adding a D2D1_OPACITY_MASK_CONTENT parameter.

I've also attached updated Direct2D samples for use with the March DX SDK. You should be able to simply recompile these samples when the Windows 7 RC SDK is released.

If you're using Visual Studio, install the March DX SDK, and make sure that VS's VC++ directories include the following (for example, x86) ...

Tools | Options | Projects and Solutions | VC++ Directories

Executable Files="c:\Program Files (x86)\Microsoft DirectX SDK (March 2009)\Utilities\Bin\x86"

Include Files="c:\Program Files (x86)\Microsoft DirectX SDK (March 2009)\Include"

Library Files="c:\Program Files (x86)\Microsoft DirectX SDK (March 2009)\Lib\x86"

Link with ...

Project | Properties | Configuration Properties | Linker | Input | Additional Dependencies ... 

 

d2d1_beta.lib dwrite_beta.lib D3D10_1_beta.lib dxgi_beta.lib windowscodecs.lib etc...

 

Posted by Thomas.Olsen | 15 Comments

Attachment(s): D2D_DXSDK_Samples.zip

Upcoming Event: Visual Studio 2010 C++ ISV Development Laboratory

 

Visual Studio C++ ISV Development Lab
May 4th – 8th, Redmond

http://www.microsoft.com/isv/events/vs2010.aspx

"Meet with teams dedicated to your success, such as Windows, the Visual Studio debugger team, the Parallel Computing team, CLR, WPF, and more… Hear about native features in Win7 and learn about how we are making parallel computing and multi-core development easier."

Request application by email:vcdevlab@microsoft.com

 

Windows 7 Beta

Steve Ballmer announced yesterday at CES that the Windows 7 Beta is available, effective immediately, to MSDN, TechBeta, and TechNet subscribers via downloadable-image. The general public will have access to the Windows 7 Beta, on or after Friday. Here's a link to the CES keynote: http://www.microsoft.com/presspass/events/ces/default.aspx

For those of you who don't have access to MSDN, TechBeta, or Technet, I would suggest that you visit http://www.microsoft.com/windows/windows-7/, and register for the Windows 7 team's RSS feed, so that you can get the latest news on the availability of the public Beta release.

Here's the placeholder link for the public bits: http://msdn.microsoft.com/evalcenter/dd353271

Direct2D Sample Videos

ChartDemo.wmv -- Although D2D can render thousands (the exact amount depends on the video hardware that's used, quality of drivers, amount of memory, etc) of anti-aliased primitives per second, there are some cases where even greater performance is required. ChartDemo demonstrates an alternative approach that uses aliased lines and rectangles (primitives that have been highly optimized in D2D) along with MSAA rendering (via D3D interop). With this approach, ChartDemo is able to scale much further.

 

Chomp.wmv -- This demo started out as a simple 2D Pac Man-like game and, gradually, we kept adding features; for example, zooming, god-mode and, unlike the original Pac Man game, our variation maps the playfield onto the outside faces of a cube, and rotates the cube to the closest contiguous face as the Chomp character runs through the tunnels. One other important note is that the playfield is rendered entirely using anti-aliased vector primitives -- not bitmaps -- so features such as zooming can be accomplished without scaling artifacts.

 

SciFiText.wmv -- This sample combines Direct2D and Direct3D to achieve what is commonly known as the "scrolling Star Wars text effect". An application can render Direct2D content into a Direct3D surface, and then display that surface at an angle to the camera.

 

SimplePathAnimation.wmv -- This sample demonstrates how to use a Direct2D Path Geometry to drive a path animation. Every D2D geometry exposes a ID2D1Geometry::ComputePointAtLength method, which can be used to obtain a point and tangent vector for any given length.

 

TextExtrusion.wmv -- This sample illustrates how DirectWrite, Direct2D, and Direct3D can be combined to create a text-extrusion effect. Text geometry is generated using a custom IDWriteTextRenderer that calls into IDWriteFontFace::GetGlyphRunOutline. D2D geometry operations are then used to eliminate self-intersections and tessellate the front and back faces. Side faces are generated by walking the text geometry and emitting quads. DWrite hit-testing is also used for positioning of the cursor. Finally, the generated triangles are sent to D3D for rasterization.

 

Demos.zip

 

Direct2D Interop with Direct3D10

Tom Mulcahy is a Software Design Engineer on the Direct2D team. He posted a cool sample on his blog (Zemblanity) that demonstrates how to do interop between Direct2D and Direct3D10. Check it out.

http://blogs.msdn.com/tmulcahy/archive/2008/10/31/rendering-text-in-the-style-of-the-star-wars-opening-credits-using-direct2d-with-direct3d-interop.aspx

 

Posted by Thomas.Olsen | 0 Comments

Using Direct2D

In today's post, we're going to walk through a simple demonstration of Direct2D. We're not going to cover advanced features, such as interop with GDI/GDI+ or Direct3D. More on that in upcoming posts.

 

Direct2D integrates seamlessly into the familiar Win32 programming paradigm, and follows a usage pattern which is similar to Direct3D. First, you create a factory...

 

 

ID2D1FactoryPtr m_spD2DFactory;

 

HRESULT hr = D2D1CreateFactory(

    D2D1_FACTORY_TYPE_SINGLE_THREADED,

    &m_spD2DFactory

    );

 

 

Next, you use the factory to create resources that you need.  One important distinction from GDI/GDI+ is that, since Direct2D is a lower-level API (like Direct3D), you need to be aware that some resources (eg. render targets, bitmaps, brushes, gradient stop collections, layers, etc) have a close association with the device on which they were created, while others (eg. geometries, meshes, stroke style, geometry sinks, tessellation sinks, etc) are not associated with a device.  Also, like Direct3D, device-dependent resources need to be recreated in cases where the device is lost or undergoes a state change. Okay, now let's create a simple geometry. Geometries are examples of device-independent resources which can be used with any render target.

 

   

ID2D1RectangleGeometryPtr m_spRectangleGeometry;

 

IFR(m_spD2DFactory->CreateRectangleGeometry(

            D2D1::Rect(20.f, 20.f, 30.f, 50.f),           

            &m_spRectangleGeometry));

 

 

Before we can draw this geometry, we're going to need a few other things. Let's create a render target . Direct2D will attempt to create a hardware render target and, if hardware isn't available, it will fall back to a software render target. We need to create a red brush to draw the geometry. Also, we're going to use Windows Imaging Codecs (WIC) to load an image from disk, convert it to 32bppPBGRA, and then create a Direct2D bitmap from it. Note that brushes and bitmaps are device-dependent resources that are associated with a render target.

 

 

HRESULT Application::CreateDeviceResources()

{

   HRESULT hr = S_OK;

 

   if (!m_spRT)

   {

       IWICImagingFactoryPtr spWICFactory;

       IWICBitmapDecoderPtr spDecoder;

       IWICFormatConverterPtr spConverter;

 

       RECT rc;

       GetClientRect(

           m_hwnd,

           &rc);

 

       D2D1_SIZE_U size = D2D1::SizeU(

           rc.right - rc.left,

           rc.bottom - rc.top);

 

       //create a D2D render target

       hr = spD2DFactory->CreateHwndRenderTarget(

           D2D1::RenderTargetProperties(),

           D2D1::HwndRenderTargetProperties(

               hwnd,

               size),

   &spRT);

 

//create a red brush

IFR(spRT->CreateSolidColorBrush(

    D2D1::ColorF(1.0f, 0.0f, 0.0f, 1.0f),

    &spRedBrush));

 

//create WIC factory

IFR(CoCreateInstance(

    CLSID_WICImagingFactory,

    NULL,

    CLSCTX_INPROC_SERVER,

    IID_IWICImagingFactory,

    reinterpret_cast<void **>(&spWICFactory)

    ));

 

//load image using WIC

IFR(spWICFactory->CreateDecoderFromFilename(

    L"tiger.jpg",

    NULL,

    GENERIC_READ,

    WICDecodeMetadataCacheOnLoad,

    &spDecoder));

 

//get the initial frame

IFR(spDecoder->GetFrame(

    0,

    &spSource));

 

//format convert to 32bppPBGRA -- which D2D expects

IFR(spWICFactory->CreateFormatConverter(

    &spConverter));

 

//initialize the format converter

IFR(spConverter->Initialize(

    spSource,

    GUID_WICPixelFormat32bppPBGRA,

    WICBitmapDitherTypeNone,

    NULL,

    0.f,

    WICBitmapPaletteTypeMedianCut));

 

//create a D2D bitmap from the WIC bitmap.

IFR(spRT->CreateBitmapFromWicBitmap(

    spConverter,

    NULL,

    &m_spBitmap));

}

return S_OK;

}

 

At this point, we have the basic resources that we need to draw. What we need is a place to do it. Note that we're drawing in response to a WM_PAINT message, but we aren't using a GDI HDC at all.

 

   

        case WM_PAINT:

        case WM_DISPLAYCHANGE:

            {

                PAINTSTRUCT ps;

                BeginPaint(hwnd, &ps);

 

                OnRender(ps.rcPaint);

 

                EndPaint(hwnd, &ps);

            }

 

 

Here is our render function. You've already seen the CreateDeviceResources function above. This is where you create any device-dependent resources. Note that creation of device resources is only done once. After a render target and its associated resources have been created, CreateDeviceResources does nothing. Our render function checks to see whether the render target is occluded (aka covered). This is an optimization which prevents unnecessary drawing in cases where the window is hidden from view. We call BeginDraw on the render target to initiate drawing. All drawing instructions must be bracketed between BeginDraw and EndDraw calls.

 

Next, we set an identity transform, which means that anything drawn will be relative to the origin in the top left hand corner of the render target. Next, we clear the render target with a white color. You need to clear the target; otherwise, the render target will be initialized with the content from the previous drawing operations. If none have been performed yet, the result is undefined. We draw a bitmap, and then set a transform and draw our red rectangle geometry. We call EndDraw on the render target to signify that drawing operations are complete. Finally,we check the return code from EndDraw to determine whether there was any kind of failure condition.

 

 

HRESULT Application::OnRender(const RECT &rcPaint)

{

  HRESULT hr = S_OK;

 

  //this is where we create device resources if they don't already

  //exist (eg. m_spRT, m_spBitmap)

 

  IFR(CreateDeviceResources());

 

  if (!(m_spRT->CheckWindowState() & D2D1_WINDOW_STATE_OCCLUDED))

  {

    m_spRT->BeginDraw();

 

    m_spRT->SetTransform(D2D1::Matrix3x2F::Identity());

 

    m_spRT->Clear(D2D1::ColorF(D2D1::ColorF::White));

 

    D2D1_SIZE_F size = m_spBitmap->GetSize();

 

    m_spRT->DrawBitmap(

       m_spBitmap,

       D2D1::Rect<float>(0.0f, 0.0f, size.width, size.height));

 

    m_spRT->SetTransform(

        D2D1::Matrix3x2F::Translation(rtSize.width - 200, 0));

 

    m_spRT->FillGeometry(

        m_spRectangleGeometry,

        m_spRedBrush);

 

    hr = m_spRT->EndDraw();

}

 

if (hr == D2DERR_RECREATE_TARGET)

{

    //if the device is lost, we need to discard all of the resources

    //associated with that device (eg. m_spRT, m_spBitmap, etc). We will

    //recreate the next time we need to paint

    DiscardDeviceResources();

}

 

return hr;

}    

 

As mentioned above, Direct2D is a lower-level API, and there are scenarios under which the display device can be lost (eg. adapter removed, display resolution changed, etc). GDI handles these device lost scenarios transparently but, with Direct2D (as with Direct3D), you need to be aware of and handle these conditions. If the device is lost for any reason, Direct2D will let you know, and you should free any  resources that are associated with that render target. Keep in mind that you don't have to release device-independent resources (eg. m_spRectangleGeometry).

  

 

void Application::DiscardDeviceResources()

{

m_spRT.Release();

m_spBitmap.Release();

m_spRedBrush.Release();

}

    

 

 

Render Target Interfaces

 

 

 

Device-Independent Resource Interfaces

 

 

 

 

Device-Dependent Resource Interfaces

 

Posted by Thomas.Olsen | 19 Comments
Filed under: , , ,

Introducing the Microsoft Direct2D API

One of the challenging aspects of working on a product development team is that you often have to keep the subject of your work secret for various reasons. I’m a Dev Lead in the Windows Desktop Graphics organization, and my team has been working quietly for the past year on an exciting new graphics technology – Direct2D –that was announced recently at the Professional Developer’s Conference (PDC) in Los Angeles.

 

Direct2D (or D2D) is a native immediate-mode 2D graphics rendering API that is built on top of Direct3D, and offers some compelling performance and visual quality improvements over GDI and GDI+:

·         Hardware-acceleration

·         Software fallback when hardware isn’t available

·         Interoperability with GDI, GDI+, and Direct3D

·         ClearType text rendering

·         Per primitive antialiasing

·         Device-independent coordinate system

·         Draw and fill commands for geometries (lines, curves) and bitmaps

·         Solid color, linear, radial, and bitmap brushes.

·         Rendering to intermediate layers

·         Rich geometry operations (eg. unions, intersections, widening, outlining, etc)

·         Server-side rendering

·         Preservation of rendering state

 

Since Direct2D is now public, I can finally talk about it, and this blog is intended to provide a forum for sharing information and tips. I encourage you to send me your feedback and comments, and I will share them with the rest of the development team. While I can’t promise that we’ll act on every piece of feedback, we will take everything that you submit seriously, and we will use the data to better understand your development priorities.

Back to the Future

Do we really need another 2D API? To answer this question, we need to backtrack a little bit and discuss some ancient graphics history. Windows applications continue to rely overwhelmingly on GDI/GDI+ 2D graphics technologies that were designed for hardware that shipped in the 1990’s. Hardware in that era was optimized largely for simple, fixed-function scenarios (eg. BitBlt, StretchBlt, DrawRect , etc). Modern graphics hardware has evolved dramatically since that time. Much of the processing that used to occur in software has now migrated down to the video card’s Graphics Processing Unit (GPU) in the form of programmable pixel and vertex shaders; which increase performance by moving pixel data closer to where it will be manipulated & consumed, in massively parallel (SIMD) fashion. These changes have staggering implications for graphics applications. Expensive pixel-processing operations can be offloaded from the CPU to the GPU which, in turn, frees the CPU to take on other useful tasks, such as creating rich UI, driving animations, doing computations, etc. It also allows applications to scale up primitive counts dramatically with minimal CPU impact.

One of the first proposals on the table was to update GDI/GDI+ to take advantage of these technologies; however, as we surveyed the requirements, we ran into some fundamental limitations that would have made the effort very difficult. For example, GDI/GDI+ are limited to 32 bits-per-pixel, and there’s a ton of stuff – both public and internal – that would need to be revamped or extended (eg. RGBQUAD, COLORREF, PALETTEENTRY) to support high dynamic range pixel formats beyond 32 bits-per-pixel. Similarly, there are quality and performance issues: modulo ClearType text, GDI can only produce aliased graphics (jaggies) and, while GDI+ can render anti-aliased graphics, it can only do so in software. GDI uses an integer coordinate system, so it can't take advantage of improvements related to sub-pixel positioning. Another fundamental problem is that GDI/GDI+, and Direct3D are wholly separate graphics subsystems, with their own formats, memory structures, and synchronization constructs. Getting all of these moving parts to work in unison would have been a huge challenge, to say the least, so we went back to the drawing board to consider an alternative proposal:  to create a new 2D graphics stack on top of Direct3D -- which would interoperate with the latest Direct3D hardware -- while also providing a migration path for GDI and GDI+ applications.

When we compared the development costs of these two proposals, it became clear that creating a new graphics stack would take far less time, would avoid destabilizing the huge number of GDI and GDI+ applications, and would enable us to provide a more cohesive, interoperable, and forward-thinking API. So, we embarked on building the new API, which went through several geeky name changes, until it emerged from the primordial acronym-soup as Direct2D. This isn’t surprising, given that my team is part of the same group that produces Direct3D. It was a natural fit.

Basic Goals

 

We started with some fundamental goals for Direct2D:

 

·         Native Code – Should be accessible to the widest possible community of developers. Minimal footprint for native code callers, and also callable by managed code.

·         Lightweight COM – Should use C++ style interfaces which model Direct3D usage. No support for proxies, cross-process remoting, BSTRs, VARIANTs, COM registration (e.g. the heavyweight stuff).

·         Immediate Mode – Simple BeginDraw/Draw/EndDraw semantic. No expensive retained tree structures.

·        Hardware – Should leverage available hardware for rendering.

·         Scalable – Pay-for-Play. Performance and memory usage should scale as linearly as possible while primitive counts increase. No hidden costs. Hardware improvements should scale performance accordingly.

·         Policy-Free – Should impose as little policy as possible on callers; that is, it should seek to do no more (and no less) than what the caller expects it to do. Minimal amount of abstraction.

·         Software Fallback – Should automatically fall back to software when hardware isn’t available (eg. session 0, server rendering scenarios).

·         High Quality Output – Should produce superb anti-aliased and aliased content. ClearType for text.

·         High Performance – Should leverage GPU hardware as much as possible and minimize CPU usage.

·         Interoperable – Should permit rendering to and from a Direct3D surface, as well as to and from a GDI/GDI+ device context (HDC). Serialization of content to and from surfaces and device contexts must be explicit and predictable. Should work seamlessly with other native Windows technologies (DirectWrite, Windows Imaging Codecs, etc).

·         Direct3D 10.1 – Should utilize D3D10.1 (and/or D3D10Level9) for hardware support.

·         Device-Independent Coordinate System – Should allow applications to be written that automatically handle DPI changes and differences.

·         Rich Geometry – Should provide a rich set of functions for both defining geometries and performing common geometric operations (eg. combining, intersecting)

 

 

 

PerfDemo Chomp

ChartDemo

 

Direct2D Team Members

I want to thank the following folks for their tireless passion and dedication to making D2D possible:

Mark Lawrence, Chris Raubacher, Tom Mulcahy, Anthony Hodsdon, Miles Cohen, Ben Constable, Leonardo Blanco, Alexander Stevenson, Megha Jain, Kam VedBrat, Andy Precious, Brett Bloomquist, Bilgem Cakir, Chris Chui, Bob Brown, Samrach Tun, Sriya Blanco, Jason Hartman

Furthermore, I’d like to acknowledge the following folks for understanding the importance of this new technology and funding the effort:

Anuj Gosalia, Anantha Kacherla, Jeff Norris, Todd Frost

Additional Materials

Watch the Platform Overview PDC session: http://channel9.msdn.com/pdc2008/PC04/

Watch the Direct2D and DirectWrite PDC session: http://channel9.msdn.com/pdc2008/PC18/

Also, I'm posting a Direct2D whitepaper that was distributed at the PDC. Future posts will drilldown into interesting code examples.
 

More Direct2D Blogs

Tom Mulcahy -- Tom is a Software Design Engineer on the Direct2D team, and owns a good swathe of infrastructure (bitmaps and texture management, WIC interop, clipping, etc). Prior to Direct2D, Tom worked on WPF and is widely regarded as our resident video guru.
http://blogs.msdn.com/tmulcahy/default.aspx


Mark Lawrence -- Mark is a Senior Software Design Engineer on the Direct2D team, and driving force behind the design and philosophy of the Direct2D API. He brings a ton of experience from his previous work on WPF, Windows Print architecture, and private industry.
http://blogs.technet.com/MarkLawrence/

 

Ben Constable -- Ben is a Senior Software Design Engineer on the Direct2D team, and implemented all of the Direct3D and GDI Interop functionality within Direct2D. He is a self-described "graphics nerd" who brings  considerable experience in 2D and 3D rendering to the team, and has contributed to numerous Microsoft products (Visual Studio, Windows, Office, SQL, etc).

http://blogs.msdn.com/bencon/

 

 
Page view tracker