Este artículo proviene de un motor de traducción automática.

Windows con C++

Introducción a Direct2D

Kenny Kerr

Esta columna se basa en una versión preliminar de Windows 7.Detalles están sujetos a cambios.

Contenido

Arquitectura Y los principales
Las fábricas Y recursos
Representan objetivos
Los pinceles Y comandos de dibujo

Con la introducción de Windows Vista hace unos años, era evidente que la era de Windows Graphics Device Interface (GDI) se llega al final.GDI, incluso con la ayuda de GDI +, tenía se mostrando su edad especialmente cuando se compara con las funciones de gráficos superiores de Windows Presentation Foundation (WPF).Como si no hay suficiente, GDI pierde la aceleración de hardware mientras WPF aprovechó abundancia de Direct3D de aceleración de hardware.

Sin embargo, si desea desarrollar aplicaciones comerciales de alto rendimiento y de alta calidad, le busque aún a C++ y código nativo para ofrecer esa capacidad.Eso algunas cosas excitarme más sobre Windows 7 de la introducción de Direct2D y DirectWrite.Direct2D es una API ha diseñado para admitir las aplicaciones de escritorio más exigentes y visualmente enriquecidas con el mejor rendimiento posible de gráficos 2D completamente nuevo.DirectWrite también es una API nueva que complementa Direct2D y proporciona el texto de aceleración de hardware, cuando se utiliza con Direct2D, diseño de texto de alta calidad representación con compatibilidad avanzada para OpenType tipografía y representación de texto ClearType.

En este artículo, explorará estas nuevas tecnologías y darle una idea de por qué es lo importante y cómo puede comenzar a utilizarlas hoy en día.

Arquitectura Y los principales

En Windows XP, GDI y Direct3D tenían igual situación lo que el sistema operativo se respecta.Las partes de modo de usuario de GDI y Direct3D relacionó directamente con sus homólogos de modo kernel.Como resultado, ambos podría ser directamente hardware acelerado, dados los controladores de pantalla adecuada.Con Windows Vista, Microsoft delegar la responsabilidad de control de hardware de vídeo exclusivamente a Direct3D.GDI pronto se convirtió la API que se admite predominantemente a través representación basado en software en la parte superior de Direct3D de gráficos heredados.

¿Por lo GDI es inactivo y Direct3D es el futuro, pero que esto deja nos y cómo se hace esto todas relacionadas con Direct2D y WPF?Bueno, lo primero que tenga en cuenta es que Direct3D es eficazmente la unidad de procesamiento de gráficos de Windows (GPU) API, si desea representar gráficos o hotwire los procesadores de gráficos de energía informático agregado.Omitir OpenGL (que aún se admite), Direct3D es la canalización de gráficos de nivel inferior para controlar directamente un adaptador de pantalla de gráficos desde una aplicación de modo de usuario.

Direct3D es lo que se conoce como una API de gráficos el modo inmediato.Esto significa simplemente que la API proporciona una capa delgada sobre cualquier hardware de gráficos, proporcionando acceso a características del hardware al rellenar en algunos de los espacios en blanco debe estar limitado el hardware de alguna manera.Cada vez que desee representar o actualizar la presentación, con eficacia tiene que saber Direct3D que está va a representar, proporcione la canalización de Direct3D con todo lo que necesita para representar un marco y, a continuación, indique lo que haya terminado, y hará que la pantalla para actualizarse.Aunque Direct3D proporciona muchas funciones 3D avanzadas, es hasta que todos ellos controlar directamente y tiene relativamente pocos primitivas 3D.No hace falta decir que esto no es una tarea trivial.

Anteriores a Windows Vista, Direct3D también incluye un nivel superior mantienen de modo API de gráficos que se crea encima de la API de inmediato de modo.Esta API proporciona compatibilidad directa para manipular objetos 3D, llama al segundo plano, una jerarquía de marcos con objetos y la iluminación.Se llamó modo conserva porque la API conserva una copia del gráfico de escena completa, así que decirlo.Aplicaciones actualización simplemente la escena y la API de automáticamente se encarga de procesar y actualizar la pantalla.El problema, por supuesto, es que todo esto incluye a un costo; si el costo es demasiado alto o las abstracciones bastante no satisfacen sus requisitos, deberá que descartar completamente esta técnica, confiar en el modo inmediato API directamente y proporcionar sus propios algoritmos de geometría.

Si está familiarizado en absoluto con WPF, a continuación, la descripción anterior de un gráficos conservan-modo API debe sonido muy familiar.Aunque Direct3D había suspendido su API mantienen de modo, WPF incluye su propia interna conserva-modo de API, conocido como el nivel de integración de Media (MIL).MIL se encuentra entre WPF y Direct3D y conserva una copia del gráfico escena definido por WPF, permitir que el código administrado interactuar con objetos visuales mientras permanece en el fondo, coordinar con MIL para asegurarse de que los cambios se reflejen en el gráfico de la escena que conserva.Esto permite WPF ofrecer una experiencia muy enriquecida e interactiva para los desarrolladores, pero se trata con un precio.

Dicho todo esto, debe ser bastante obvio donde Direct2D entra en.Direct2D proporciona compatibilidad de procesamiento enriquecido para geometries simples y complejos, mapas de bits y creada directamente por encima de inmediato modo API de gráficos de Direct3D para el rendimiento inigualables de texto.El resultado es un enfoque de alto rendimiento y baja sobrecarga para producir contenido gráficos de alta calidad para las aplicaciones.Proporciona una API mucho más sencilla para producir contenido 2D comparado con mediante Direct3D directamente al agregar poca sobrecarga en la mayoría de los casos.De hecho, de con la excepción unas específicas operaciones de, como por cada tipo primitivo de alisado, que se difícil presionado para mejoran Direct2D con Direct3D.Direct2D debe mejoran también fácilmente los likes de MIL y Quartz2DE.

Como si no hay suficiente, va aún más allá y que proporciona muchas características adicionales, tales como procesamiento remoto a través de remoto Protocolo de escritorio (RDP), software de reserva para la representación de servidor o para compensar la falta de hardware, admitir para representar texto ClearType e interoperabilidad inigualables con GDI y Direct3D.Supongamos que sólo hay ninguno de este corrupto "airspace" de WPF.

Ahora vamos a llegar hacia abajo al escribir algún código!Para mantener los ejemplos centrados, voy a utilizar Active Template Library (ATL) y la biblioteca de plantillas de Windows (WTL) para controlar todo el código de ventanas repetitivo para mí.Recuerde, Direct2D es sobre la representación.Si desea representar en una ventana, todavía deberá administrar dicha ventana.Si desea que la entrada del mouse (ratón), todavía deberá responder a mensajes de ventana de forma habitual.Obtendrá la idea.la figura 1 contiene un esquema de una ventana que se rellenan durante el resto de este artículo.

La figura 1 ventana esqueleto

#define HR(_hr_expr) { hr = _hr_expr; if (FAILED(hr)) return hr; }
class Window : public CWindowImpl<Window, CWindow, CWinTraits<WS_OVERLAPPEDWINDOW>>
{
public:
    BEGIN_MSG_MAP(Window)
        MSG_WM_DESTROY(OnDestroy)
    END_MSG_MAP()

    HRESULT Create()
    {
        VERIFY(__super::Create(0)); // top-level
        VERIFY(SetWindowText(L"Direct2D Sample"));

        VERIFY(SetWindowPos(0, // z-order
                            100, // x
                            100, // y
                            600, // pixel width,
                            400, // pixel height,
                            SWP_NOZORDER | SWP_SHOWWINDOW));

        VERIFY(UpdateWindow());
        return S_OK;
    }
private:
    void OnDestroy()
    {
        ::PostQuitMessage(1);
    }
};

Las fábricas Y recursos

Como con varias otros API como Direct3D y XmlLite, Direct2D utiliza una versión ligera de la especificación de COM para administrar la vida de objeto mediante las interfaces derivado de IUnknown. No hay ninguna necesidad de inicializar la hora de COM ejecutar y preocuparse apartamentos o servidores proxy. Es simplemente una convención para simplificar la administración de recursos y permitir que las API y las aplicaciones exponen y consumen objetos de forma bien definida. Tenga en cuenta que sólo porque Direct2D utiliza interfaces de COM no significa que puede proporcionar sus propias implementaciones de esas interfaces. A menos que se indique lo contrario, Direct2D funcionará sólo con sus propias implementaciones. Podría sugiero que utilice CComPtr puntero inteligente clase de ATL para administrar los punteros de interfaz, como haría en los ejemplos de este artículo.

Cada aplicación Direct2D comienza creando un objeto generador. La función D2D1CreateFactory devuelve una implementación de la interfaz ID2D1Factory:

CComPtr<ID2D1Factory> factory;
HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &factory));

Por supuesto, antes de poder utilizar cualquiera de estos tipos, deberá incluir d2d1.h, el archivo de encabezado Direct2D, que se declara las diversas interfaces Direct2D, estructuras y constantes así como la función D2D1CreateFactory. El archivo d2d1.lib se proporciona para importar la función D2D1CreateFactory. El archivo de encabezado d2d1helper.h también proporciona una gran muchas funciones útiles y clases a simplemente el uso de Direct2D de C++. Normalmente Direct2D incluya en un proyecto agregando las siguientes directivas en encabezado precompilado el proyecto:

#include <d2d1.h>
#include <d2d1helper.h>
#pragma comment(lib, "d2d1.lib")

Como he mencionado, Direct2D no depende de COM, pero el primer parámetro a D2D1CreateFactory podría llevarle a creer lo contrario.La enumeración D2D1_FACTORY_TYPE define constantes D2D1_FACTORY_TYPE_SINGLE_THREADED y D2D1_FACTORY_TYPE_MULTI_THREADED, pero éstas no tienen nada que ver con COM apartamentos y no supone ninguna afinidad de subprocesos.La constante de D2D1_FACTORY_TYPE_SINGLE_THREADED simplemente especifica en la que el objeto generador, así como cualquiera de los objetos raíz en la que fábrica, puede obtener acceso a sólo un subproceso único a la vez.Los objetos creados de esta manera proporcionará el mejor rendimiento para tener acceso un único subproceso, lo que evita cualquier serialización innecesario dentro y fuera de las llamadas de representación.La constante D2D1_FACTORY_TYPE_MULTI_THREADED, por otro lado, se especifica que el objeto generador, así como cualquiera de los objetos raíz en dicha fábrica, pueden tener acceso a varios subprocesos simultáneamente.Direct2D proporciona la sincronización necesaria con el recuento de referencias de bloqueo.Resulta útil para representar a destinos distintos simultáneamente al uso compartido de determinados recursos.Tenga en importa que esta paralelismo es específica de la CPU y instrucciones que se envían a los procesadores de gráficos todavía puede serializar y finalmente parallelized de forma independiente.

BUENO, por lo tanto ¿qué se el objeto generador utiliza para?Bueno, es responsable de crear todos los recursos independientes del dispositivo, predominantemente geometries, así como la creación de representa los destinos que representan dispositivos.El destino de representación, a continuación, tiene la responsabilidad de creación de recursos dependientes del dispositivo.La distinción entre los recursos dependientes del dispositivo y independientes del dispositivo es fundamental para utilizar Direct2D correctamente.Una de las ventajas de un gráficos conservan-modo API como WPF es que generalmente se encarga la capa intermedia entre el hardware y el modelo de programación de escenarios donde el dispositivo de pantalla pueden perderse.Esto puede suceder por diversos motivos.Puede cambiar la resolución en segundo plano, es posible que se quita un adaptador de pantalla como cuando un usuario undocks un equipo portátil, pueden perderse, una sesión de conexión a escritorio remoto y así sucesivamente.Una API de gráficos inmediato modo como Direct2D debe tener en cuenta estos eventos.Por supuesto, la ventaja es que recursos utilizados para representar en un dispositivo determinado pueden estar físicamente presente en el dispositivo y, por tanto, proporcionar rendimiento mucho mejor.

Por estos motivos, es conveniente para separar claramente la creación de recursos independientes del dispositivo de recursos dependientes del dispositivo.Para adaptarse a esto, en la figura 2 agregar que estos dos métodos para la ventana de clase de Figura 1.

La Figura 2 Crear independiente de dispositivos y recursos dependiente del dispositivo independientemente

HRESULT CreateDeviceIndependentResources()
{
    HRESULT hr;
    HR(D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_factory));
    // TODO: Create device-independent resources here
    return S_OK;
}
HRESULT CreateDeviceResources()
{
    HRESULT hr;
    // TODO: Create device resources here
    return S_OK;
}

Le desarrollarles fuera en las secciones algunas siguientes, pero por el momento, se puede llamar a CreateDeviceIndependentResources desde el método Create de la clase de ventana porque recursos independientes del dispositivo deben crearse sólo una vez. Obtendrá CreateDeviceResources, sin embargo, llamarse a petición para crear los recursos de dispositivos como sea necesario. También deseará agregar la variable de miembro m_factory manera:

CComPtr<ID2D1Factory> m_factory;

Representan objetivos

Un destino de representación se utiliza para representar un dispositivo y es en sí misma depende del dispositivo subyacente.Con un destino de representación, puede crear varios recursos, como los pinceles y realizar las operaciones de dibujo reales.Direct2D admite una serie de distintos tipos de destinos de representación.Si está creando una aplicación Direct2D desde el principio, puede crear un destino de representación para representar contenido en una ventana (HWND).También puede crear un destino de representación para representar a un contexto de dispositivo (DC) de GDI o a una superficie de infraestructura de gráficos de DirectX (DXGI) para su uso en una aplicación Direct3D.Puede incluso crear un destino de representación para distintos tipos de recursos de mapa de bits para representar fuera de la pantalla.

Se proporcionan varios métodos de fábrica para crear los distintos tipos de destinos de representación.Los propios métodos son bastante obvios.Por ejemplo, el método CreateHwndRenderTarget crea un destino de representación de ventana, y el método CreateDxgiSurfaceRenderTarget crea un destino de representación superficie DXGI.Para representar a la ventana, se va a necesita actualizar el método CreateDeviceResources para crear el destino de representación de ventana.Como mínimo, lo puede parecerse a figura 3.Tenga en cuenta que este ejemplo no es PPP, tenga en cuenta, pero es un tema para otro artículo.

Figura 3 crear el destino de representación de Windows

HRESULT CreateDeviceResources()
{
    HRESULT hr;
    if (0 == m_target)
    {
        CRect rect;
        VERIFY(GetClientRect(&rect));
        D2D1_SIZE_U size = D2D1::SizeU(rect.Width(), rect.Height());
        HR(m_factory->CreateHwndRenderTarget(D2D1::RenderTargetProperties(),
                        D2D1::HwndRenderTargetProperties(m_hWnd, size), &m_target));
    }
    return S_OK;
}

También deseará agregar la variable de miembro m_target:

CComPtr<ID2D1HwndRenderTarget> m_target;

El método CreateDeviceResources crea los recursos del dispositivo sólo si todavía no se ha creado el destino de representación o, tal como se se observa en breve, si el dispositivo se pierde y el destino de representación necesita que vuelve a crear.

Primer parámetro el método CreateHwndRenderTarget realmente es de tipo D2D1_RENDER_TARGET_PROPERTIES.Este parámetro es común a todas las representación destino creación de funciones.La función RenderTargetProperties es realmente una función auxiliar definida en el archivo de encabezado d2d1helper.h.Representa un modelo común para muchas de las estructuras de datos utilizadas por Direct2D inicializar y ayuda a simplificar considerablemente el código.La función de Ayudante RenderTargetProperties tiene parámetros con valores predeterminados para cuenta para la inicialización más comunes de la estructura resultante.Se pueden reemplazar estos valores para ajustar el formato de píxel y información de PPP, así como características adicionales del destino de representación, como si desea forzar basadas en hardware o software de procesamiento y si se debe admitir la interoperabilidad GDI.

Asimismo, segundo parámetro del CreateHwndRenderTarget es realmente una estructura de D2D1_HWND_RENDER_TARGET_PROPERTIES y proporciona información específica de la ventana.

Necesidad de crear el destino de representación, ahora puede realizar algún procesamiento real.Para ello, agregue un método Render a la clase de ventana con el esquema básico que se muestra en la figura 4.

Representación de la figura 4

void Render()
{
    if (SUCCEEDED(CreateDeviceResources()))
    {
        if (0 == (D2D1_WINDOW_STATE_OCCLUDED & m_target->CheckWindowState()))
        {
            m_target->BeginDraw();
            m_target->SetTransform(D2D1::Matrix3x2F::Identity());
            m_target->Clear(D2D1::ColorF(D2D1::ColorF::Red));
            // TODO: add drawing code here

            if (D2DERR_RECREATE_TARGET == m_target->EndDraw())
            {
                DiscardDeviceResources();
            }
        }
    }
}

La lógica aquí es muy importante porque permite actualizar muy eficaz, gracias a la reutilización de los recursos de dispositivos y porque debe prever pérdida del dispositivo. El método Render inicia mediante una llamada al método de CreateDeviceResources que acabo de describir. Por supuesto no tendrá que hacer nada si los recursos de dispositivos están todavía disponibles. Como una optimización comprobar el estado de ventana para asegurarse de que no se occluded, que es simplemente un término elaborado que indica la ventana se obstruida desde la vista y cualquier dibujo sólo sería una pérdida de valiosos recursos de CPU y procesadores de gráficos. Aunque esto rara vez ocurre cuando el administrador de escritorio de Windows (DWM) está controlando la composición de escritorio, no perjudicial y es una optimización interesante cuando la composición de escritorio está deshabilitada.

Dibujo real debe ser sandwiched entre las llamadas a métodos de BeginDraw y EndDraw del destino de representación. La mayoría de métodos del destino de representación tienen un tipo de valor devuelto void. Puesto que están por lotes las operaciones de dibujo, los errores se detectará sólo cuando las operaciones de dibujo se vacía y representar en el dispositivo. El método de EndDraw, por tanto, tiene un tipo de valor devuelto de HRESULT. Utiliza la constante D2DERR_RECREATE_TARGET para indicar que el destino de representación se invalidó y debe crearse. A continuación, llama a DiscardDeviceResources, que deben liberar todos los recursos de dispositivos.

void DiscardDeviceResources()
{
    m_target.Release();
}

También sólo deben mencionar las llamadas a SetTransform y borrar los métodos del destino de representación. SetTransform en este caso especifica que las operaciones de dibujo posteriores deben transformarse mediante una matriz de identidad. Por supuesto, una matriz identidad es realmente no hay traducción en absoluto, por lo que esto sólo garantiza que las operaciones de dibujo utilizan el espacio de coordenadas literal en píxeles independientes del dispositivo. Puede, llamar sin embargo, al SetTransform varias veces durante la representación para cambiar la transformación sobre la marcha. El método Clear borra simplemente el área de dibujo para las operaciones subsiguientes de dibujo y en este caso facilita rojo.

Por supuesto, si desea crear la ventana en este punto, se verá que la ventana permanece en blanco. Algo aún necesita llamar al método Render para actualizar la pantalla. Para ello, puede agregar controladores de mensaje para los mensajes de ventana WM_PAINT y WM_DISPLAYCHANGE. Puede hacerlo agregando lo siguiente a la asignación de mensaje:

MSG_WM_PAINT(OnPaint)
MSG_WM_DISPLAYCHANGE(OnDisplayChange)

Responder a WM_PAINT es obvio, pero controla WM_DISPLAYCHANGE es igualmente importante para asegurarse de que la ventana se actualiza correctamente, debe la resolución de pantalla o profundidad de color cambiar (consulte laLa figura 5).

Figura 5 actualización

void OnPaint(CDCHandle /*dc*/)
{
    PAINTSTRUCT paint;
    VERIFY(BeginPaint(&paint));
    Render();
    EndPaint(&paint);
}
void OnDisplayChange(UINT /*bpp*/, CSize /*resolution*/)
{
    Render();
}

Tenga en cuenta que el controlador de dominio devuelto por BeginPaint no se utiliza en absoluto. Crear la ventana ahora generará una ventana con un fondo rojo, como se esperaba. Cambiar el tamaño se de la ventana sin embargo, revelar algunos parpadeo. Lo que sucede es que el fondo de la ventana se aún se borra automáticamente con el pincel de fondo de clase de ventana debido del control predeterminado del mensaje WM_ERASEBKGND de. Para evitar esto, simplemente administrar este mensaje y devolver TRUE en el método de OnEraseBackground para indicar que se ocupará de borrado del fondo de la ventana. Puede cambiar el ahora tamaño la ventana al evitar cualquier parpadeo.

Mientras estás en él, probablemente deseará controlar el cambio de tamaño de ventana. Para ello, agrega un controlador de mensajes para el mensaje de ventana WM_SIZE, los siguientes:

MSG_WM_SIZE(OnSize)

A continuación el OnSize identificador, necesita sencillo informan al destino de representación que ha cambiado el tamaño:

void OnSize(UINT /*type*/, CSize size)
{
    if (0 != m_target)
    {
        if (FAILED(m_target->Resize(D2D1::SizeU(size.cx, size.cy))))
        {
            DiscardDeviceResources();
            VERIFY(Invalidate(FALSE));
        }
    }
}

Si no puede cambiar el tamaño, simplemente descarta los recursos de dispositivos, y se volverá a automáticamente crear la próxima vez que se representa la ventana. Observe cómo el método Resize acepta el nuevo tamaño en píxeles del dispositivo dado que el mensaje WM_SIZE comunica el tamaño del área cliente en píxeles. Aunque Direct2D utiliza un sistema de coordenadas independientes del dispositivo, el destino de representación ventana entiende que, en última instancia, necesita asignar a píxeles del dispositivo.

Los pinceles Y comandos de dibujo

Para realizar cualquier dibujo significativa, se desea crear algunos pinceles. Necesitará los pinceles para dibujar varias formas geométricas, así como texto. Los pinceles se celebre en la categoría de recursos dependientes del dispositivo, por lo que su creación debería ir en el método CreateDeviceResources. Como puede imaginar, Direct2D proporciona sólida y pinceles de mapa de bits, así como los pinceles de degradado lineales y radiales. Para crear un pincel de color sólido, puede agregar la siguiente llamada de método justo después de crear el destino de representación. Vuelve a ese modo, es crear sólo cuando se vuelve a crear el destino de representación.

HR(m_target->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::Black), &m_brush));

No olvide liberar también el pincel en el método DiscardDeviceResources manera:

m_brush.Release();

También deseará agregar la variable de miembro m_brush manera:

CComPtr<ID2D1SolidColorBrush> m_brush;

fig02.gif

La figura 7 dibujo básico

Ahora puede agregar algunos comandos básicos de dibujo al método Render entre los métodos Clear y EndDraw.El código en la figura 6 produce un círculo con una línea diagonal a través de él.Aunque dejaremos una explicación completa de los pinceles de un artículo futuro, es merece la pena mencionar que Direct2D permite eficazmente cambiar el color de un pincel durante la representación, obviando la necesidad de crear varios pinceles de colores diferentes.

Círculo de la figura 6 con línea diagonal

m_target->DrawLine(D2D1::Point2(10.0f, 10.0f), // start
                   D2D1::Point2(200.0f, 200.0f), // end
                   m_brush,
                   10.0f); // stroke width

const D2D1_POINT_2F center = D2D1::Point2(105.0f, 105.0f);

const D2D1_ELLIPSE ellipse = D2D1::Ellipse(center,
                                           95.0f, // radius X
                                           95.0f); // radius Y

m_target->DrawEllipse(&ellipse,
                      m_brush,
                      5.0f); // stroke width

Como he ha mencionado, Direct2D utiliza un sistema independiente del dispositivo coordenadas para las coordenadas expresadas no asignan necesariamente a mostrar píxeles pero en su lugar respetan la configuración de PPP para el dispositivo de destino.la figura 7 muestra el resultado de los comandos del dibujo.

Aunque haya utiliza sólo un pincel opaco, también puede especificar un valor alfa al crear el pincel y el alfa de mezcla al contenido de su centro.

Desgraciadamente, ha completamente quedado sin espacio, pero debe ahora tiene una buena idea de la posibilidad que Direct2D y DirectWrite tendrán en aplicaciones nativas adelante.Hay muchos motivos más para encanta estas nuevas tecnologías que espero cavar en una columna próxima, incluyendo geometries enriquecidos y las operaciones así como todas las capacidades de DirectWrite.Mientras tanto, iniciar experimentar con Direct2D.Estoy seguro de que lo encontrará impresionante.

Perspectivas: representación de Direct2D

muchas personas se estar tentados a Compare el rendimiento de las aplicaciones Direct2D y Direct3D.Esto es algo de un manzanas a naranjas comparación que Direct2D proporciona un conjunto de elementos primitivos mucho más comparables a la otra representación 2D API como GDI o GDI + o WPF.También es mucho más sencillo utilizar.Sin embargo, podría ser sorprendente de algunos clientes que Direct2D puede out-perform realmente una aplicación de Direct3D simple, o naïve, en un número de escenarios diferentes.Por ejemplo, Direct2D puede mejoran una aplicación naïve Direct3D cuando un gran número de líneas con distintos colores de dibujo o cuando se mezcla repetidamente de un mapa de bits.

La clave a cómo Direct2D hace esto es entender que Direct2D no mantiene una relación 1: 1 entre una dibujo solicitud emitida a ella y los elementos primitivos que emite en Direct3D.De hecho, Direct2D intenta agregar sus solicitudes a Direct3D en un número de formas diferentes.

Asignación de búfer de vértice reducido

Considere una aplicación Direct3D naïve.Crea un búfer de vértice, se asigna, escribe su geometría en el búfer, mapas de desinstalar y dibuja se.El problema con este enfoque es que si el búfer de vértice está en uso por el procesador de gráficos cuando llega la siguiente solicitud de asignación, la CPU tendrá que se detienen hasta que se realiza el procesador de gráficos con él y, a continuación, sólo se puede asignar en la memoria de aplicación.Esto puede reducir considerablemente el rendimiento de la aplicación.

Direct2D resuelve este problema, deje el búfer de vértice asignado en memoria y acumular geometría de muchos sucesivos primitivas en él.Sólo cuando el búfer de vértice está lleno, o la aplicación llama a Flush o EndDraw, y Direct2D después enviar el dibujo llama a hacia abajo en Direct3D.Esto reduce el número de retretes de procesador de gráficos porque considerablemente se reduce el número de llamadas de mapa y mapa de desinstalar.

Uso combinado de llamadas de dibujo

Incluso después de geometries pueden acumularse en el búfer de vértice, una aplicación Direct3D naïve tendría que emita una llamada de dibujo a Direct3D para llamadas de dibujo Direct2D la mayoría de los.Considere dos rectángulos diferentes representa con distintos colores, cada color es posible que requieren escribir sombreador diferentes constante datos representarlo.Cada vez que los datos de sombreadores. constante se actualiza, una llamada de dibujo diferente tiene que ser emitido.

Siempre y cuando algunos otros constantes no cambian.Por ejemplo, el mismo tipo de pincel se utiliza consecutivamente.O, si un pincel de mapa de bits, el mismo mapa de bits entrada se utiliza siempre.Direct2D puede utilice sus sombreadores de vértices para continuar se acumulan datos constante de sombreadores. y, a continuación, emita una llamada de dibujo de Direct3D para un gran número de llamadas de dibujo Direct2D.

Representación de texto de fuera de la orden

La canalización de procesamiento de texto Direct2D se ejecuta completamente en hardware, por tres fases.La primera etapa escribe los glifos en una textura, la siguiente fase bajo ejemplos estos glifos y la fase final realiza una operación de filtrado de tipo simple para transferir el texto en el destino de representación.Una aplicación naïve podría representar cada fase secuencialmente, cambiar el destino de representación tres veces y emitir un dibujo llamar a mover los datos entre cada textura.Direct2D procesará las primitivas de texto fuera de uso con otras primitivas.En primer lugar acumularán un gran número de glifos.A continuación, ejemplos hacia abajo todos ellos y el conjunto final de glifos en orden de mezcla con las otras primitivas de geométricas emitidas para Direct2D.Coalescing la representación de texto de este modo reduce el número de veces que los cambios de destino de representación, así como el número de cambios de estado de dispositivo Direct3D generales para representar el texto, incluso si otras primitivas están intercalados con el texto Direct2D representación llamadas.

De forma combinación por lotes de búfer de vértice, coalescing de llamada de dibujo y representación de fuera de la orden de texto, Direct2D es capaz de conseguir un rendimiento de representación que requieran una amplia cantidad de esfuerzo de desarrollo para que coincida con si la aplicación se en su lugar directamente Direct3D.

--Mark Lawrence, jefe ingeniero de desarrollo de software, Microsoft.

Envíe sus preguntas y comentarios ammwincpp@Microsoft.com

Kenny Kerr es un artesano del software especializado en desarrollo de software para Windows.Tiene una pasión por la escritura y enseñando a desarrolladores sobre el diseño de programación y software.Kenny enweblogs.asp.NET/kennykerr.