Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Direct2D es una API de modo inmediato y de código nativo para crear gráficos 2D. En este tema se muestra cómo usar Direct2D para dibujar en un Windows::UI::Core::CoreWindow.
Este tema contiene las secciones siguientes:
- dibujar un rectángulo simple
- Paso 1: Incluir la cabecera de Direct2D
- Paso 2: Crear una ID2D1Factory1
- Paso 3: Crear un ID2D1Device y un ID2D1DeviceContext
- Paso 4: Crear un pincel
- paso 5: Dibujar el rectángulo
- código de ejemplo
Dibujar un rectángulo simple
Para dibujar un rectángulo usando GDI, podría controlar el mensaje WM_PAINT, como se muestra en el código siguiente.
switch(message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
BeginPaint(hwnd, &ps);
// Obtain the size of the drawing area.
RECT rc;
GetClientRect(
hwnd,
&rc
);
// Save the original object
HGDIOBJ original = NULL;
original = SelectObject(
ps.hdc,
GetStockObject(DC_PEN)
);
// Create a pen.
HPEN blackPen = CreatePen(PS_SOLID, 3, 0);
// Select the pen.
SelectObject(ps.hdc, blackPen);
// Draw a rectangle.
Rectangle(
ps.hdc,
rc.left + 100,
rc.top + 100,
rc.right - 100,
rc.bottom - 100);
DeleteObject(blackPen);
// Restore the original object
SelectObject(ps.hdc, original);
EndPaint(hwnd, &ps);
}
return 0;
// Code for handling other messages.
El código para dibujar el mismo rectángulo con Direct2D es similar: crea recursos de dibujo, describe una forma para dibujar, dibuja la forma y, a continuación, libera los recursos de dibujo. En las secciones siguientes se describe cada uno de estos pasos con detalle.
Paso 1: Incluir la cabecera de Direct2D
Además de los encabezados necesarios para la aplicación, incluya los encabezados d2d1.h y d2d1_1.h.
Paso 2: Crear un ID2D1Factory1
Una de las primeras cosas que hace cualquier ejemplo de Direct2D es crear un ID2D1Factory1.
DX::ThrowIfFailed(
D2D1CreateFactory(
D2D1_FACTORY_TYPE_SINGLE_THREADED,
__uuidof(ID2D1Factory1),
&options,
&m_d2dFactory
)
);
La interfaz ID2D1Factory1 es el punto de partida para usar Direct2D; use una ID2D1Factory1 para crear recursos de Direct2D.
Cuando crea una fábrica, puede especificar si es multi o monohilo. (Para obtener más información sobre las factorías multiproceso, vea los comentarios de la página de referencia de ID2D1Factory). En este ejemplo se crea una fábrica de un solo subproceso.
En general, la aplicación debe crear la fábrica una vez y conservarla durante la vida útil de la aplicación.
Paso 3: Crear un ID2D1Device y un ID2D1DeviceContext
Después de crear una fábrica, utilízala para crear un dispositivo Direct2D y luego usa el dispositivo para crear un contexto de dispositivo Direct2D. Para crear estos objetos Direct2D, debe tener un dispositivo Direct3D 11 , un dispositivo DXGIy una cadena de intercambio DXGI . Consulte Dispositivos y contextos de dispositivo para obtener información sobre cómo crear los requisitos previos necesarios.
// Obtain the underlying DXGI device of the Direct3D11.1 device.
DX::ThrowIfFailed(
m_d3dDevice.As(&dxgiDevice)
);
// Obtain the Direct2D device for 2-D rendering.
DX::ThrowIfFailed(
m_d2dFactory->CreateDevice(dxgiDevice.Get(), &m_d2dDevice)
);
// And get its corresponding device context object.
DX::ThrowIfFailed(
m_d2dDevice->CreateDeviceContext(
D2D1_DEVICE_CONTEXT_OPTIONS_NONE,
&m_d2dContext
)
);
Un contexto de dispositivo es un dispositivo que puede realizar operaciones de dibujo y crear recursos de dibujo dependientes del dispositivo, como pinceles. También usas el contexto del dispositivo para vincular un ID2D1Bitmap a una superficie DXGI para usarla como destino de representación. El contexto del dispositivo puede representarse en diferentes tipos de destinos.
El código aquí declara las propiedades del mapa de bits que vinculan a una cadena de intercambio DXGI que se representa en un CoreWindow. El método ID2D1DeviceContext::CreateBitmapFromDxgiSurface obtiene una superficie Direct2D de la superficie DXGI. Esto provoca que todo lo que se represente en el destino ID2D1Bitmap se represente en la superficie de la cadena de conmutación.
Una vez que tenga la superficie direct2D, use el método ID2D1DeviceContext::SetTarget para establecerlo como destino de representación activo.
// Now we set up the Direct2D render target bitmap linked to the swapchain.
// Whenever we render to this bitmap, it will be directly rendered to the
// swapchain associated with the window.
D2D1_BITMAP_PROPERTIES1 bitmapProperties =
BitmapProperties1(
D2D1_BITMAP_OPTIONS_TARGET | D2D1_BITMAP_OPTIONS_CANNOT_DRAW,
PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED),
m_dpi,
m_dpi
);
// Direct2D needs the dxgi version of the backbuffer surface pointer.
ComPtr<IDXGISurface> dxgiBackBuffer;
DX::ThrowIfFailed(
m_swapChain->GetBuffer(0, IID_PPV_ARGS(&dxgiBackBuffer))
);
// Get a D2D surface from the DXGI back buffer to use as the D2D render target.
DX::ThrowIfFailed(
m_d2dContext->CreateBitmapFromDxgiSurface(
dxgiBackBuffer.Get(),
&bitmapProperties,
&m_d2dTargetBitmap
)
);
// So now we can set the Direct2D render target.
m_d2dContext->SetTarget(m_d2dTargetBitmap.Get());
Paso 4: Crear un pincel
Al igual que una fábrica, un contexto de dispositivo puede crear recursos de dibujo. En este ejemplo, el contexto del dispositivo crea un pincel.
ComPtr<ID2D1SolidColorBrush> pBlackBrush;
DX::ThrowIfFailed(
m_d2dContext->CreateSolidColorBrush(
D2D1::ColorF(D2D1::ColorF::Black),
&pBlackBrush
)
);
Un pincel es un objeto que pinta un área, como el trazo de una forma o el relleno de una geometría. El pincel de este ejemplo pinta un área con un color sólido predefinido, negro.
Direct2D también proporciona otros tipos de pinceles: pinceles degradados para pintar degradados lineales y radiales, un pincel de mapa de bits para pintar con mapas de bits y patrones, y a partir de Windows 8, un pincel de imagen para pintar con una imagen representada.
Algunas API de dibujo proporcionan lápices para dibujar contornos y pinceles para rellenar formas. Direct2D es diferente: no proporciona un objeto de lápiz, sino que usa un pincel para dibujar contornos y formas de relleno. Al dibujar esquemas, usa la interfaz de ID2D1StrokeStyle, o a partir de Windows 8, la interfaz de ID2D1StrokeStyle1, con un pincel para controlar las operaciones de trazado de rutas.
Un pincel solo se puede usar con el destino de representación que lo creó y con otros destinos de representación en el mismo dominio de recursos. En general, debería crear pinceles una vez y conservarlos durante toda la vida del objetivo de renderizado que los creó. ID2D1SolidColorBrush es la única excepción; dado que es relativamente económico de crear, puede crear un ID2D1SolidColorBrush cada vez que dibuje un fotograma, sin ningún impacto significativo en el rendimiento. También puede usar una sola ID2D1SolidColorBrush y simplemente cambiar su color o opacidad cada vez que lo use.
Paso 5: Dibujar el rectángulo
A continuación, use el contexto del dispositivo para dibujar el rectángulo.
m_d2dContext->BeginDraw();
m_d2dContext->DrawRectangle(
D2D1::RectF(
rc.left + 100.0f,
rc.top + 100.0f,
rc.right - 100.0f,
rc.bottom - 100.0f),
pBlackBrush);
DX::ThrowIfFailed(
m_d2dContext->EndDraw()
);
DX::ThrowIfFailed(
m_swapChain->Present1(1, 0, ¶meters);
);
El método DrawRectangle toma dos parámetros: el rectángulo que se va a dibujar y el pincel que se va a usar para pintar el contorno del rectángulo. Opcionalmente, también puede especificar el ancho del trazo, el patrón de guiones, la unión de líneas y las opciones de tapa final.
Debe llamar al método BeginDraw antes de emitir comandos de dibujo y debe llamar al método EndDraw después de haber terminado de emitir comandos de dibujo. El método EndDraw devuelve un HRESULT que indica si los comandos de dibujo se realizaron correctamente. Si no se ejecuta correctamente, la función auxiliar ThrowIfFailed producirá una excepción.
El método IDXGISwapChain::Present intercambia la superficie del búfer con la superficie en pantalla para mostrar el resultado.
Código de ejemplo
El código de este tema muestra los elementos básicos de una aplicación Direct2D. Por motivos de brevedad, el tema omite el marco de trabajo de la aplicación y el código de control de errores que es característica de una aplicación bien escrita.