win_d2d: port to C

This commit is contained in:
David Hrdlička
2019-12-12 23:04:03 +01:00
parent 2cb6c73555
commit 042d9228ea
2 changed files with 119 additions and 63 deletions

View File

@@ -8,7 +8,7 @@
*
* Rendering module for Microsoft Direct2D.
*
* Version: @(#)win_d2d.cpp 1.0.6 2019/12/10
* Version: @(#)win_d2d.c 1.0.7 2019/12/13
*
* Authors: David Hrdlička, <hrdlickadavid@outlook.com>
*
@@ -18,6 +18,7 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <initguid.h>
#define UNICODE
#define BITMAP WINDOWS_BITMAP
#include <windows.h>
@@ -40,22 +41,25 @@ static HWND d2d_hwnd, old_hwndMain;
static ID2D1Factory *d2d_factory;
static ID2D1HwndRenderTarget *d2d_target;
static ID2D1Bitmap *d2d_buffer;
static int d2d_width, d2d_height, d2d_screen_width, d2d_screen_height, d2d_fs;
static int d2d_width, d2d_height, d2d_screen_width,
d2d_screen_height, d2d_fs;
static volatile int d2d_enabled = 0;
/* Pointers to the real functions. */
static HRESULT (*D2D1_CreateFactory)(D2D1_FACTORY_TYPE facType,
REFIID riid,
CONST D2D1_FACTORY_OPTIONS *pFacOptions,
void **ppIFactory);
static HRESULT WINAPI (*D2D1_CreateFactory)(
D2D1_FACTORY_TYPE facType,
REFIID riid,
const D2D1_FACTORY_OPTIONS *pFacOptions,
void **ppIFactory);
static dllimp_t d2d_imports[] = {
{ "D2D1CreateFactory", &D2D1_CreateFactory },
{ NULL, NULL }
};
static volatile void *d2d_handle; /* handle to WinPcap DLL */
static volatile void *d2d_handle; /* handle to Direct2D DLL */
#ifdef ENABLE_D2D_LOG
@@ -68,9 +72,9 @@ d2d_log(const char *fmt, ...)
va_list ap;
if (d2d_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
@@ -152,13 +156,8 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h)
{
HRESULT hr = S_OK;
D2D1_RECT_U rectU;
float fs_x, fs_y;
float fs_w = w;
float fs_h = h;
d2d_log("Direct2D: d2d_blit(x=%d, y=%d, y1=%d, y2=%d, w=%d, h=%d)\n", x, y, y1, y2, w, h);
d2d_log("Direct2D: d2d_blit(x=%d, y=%d, y1=%d, y2=%d, w=%d, h=%d)\n",
x, y, y1, y2, w, h);
if (!d2d_enabled) {
video_blit_complete();
@@ -167,7 +166,8 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h)
if ((w != d2d_width || h != d2d_height) && !d2d_fs)
{
hr = d2d_target->Resize(D2D1::SizeU(w, h));
D2D1_SIZE_U size = { .width = w, .height = h };
hr = ID2D1HwndRenderTarget_Resize(d2d_target, &size);
if (SUCCEEDED(hr))
{
@@ -189,17 +189,40 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h)
/* Create a bitmap to store intermediate data */
if (d2d_buffer == NULL) {
if (SUCCEEDED(hr)) {
hr = d2d_target->CreateBitmap(
D2D1::SizeU(render_buffer->w, render_buffer->h),
D2D1::BitmapProperties(D2D1::PixelFormat(DXGI_FORMAT_B8G8R8A8_UNORM, D2D1_ALPHA_MODE_IGNORE)),
D2D1_SIZE_U size = {
.width = render_buffer->w,
.height = render_buffer->h };
D2D1_BITMAP_PROPERTIES bitmap_props = {
.pixelFormat = {
.format = DXGI_FORMAT_B8G8R8A8_UNORM,
.alphaMode = D2D1_ALPHA_MODE_IGNORE
},
.dpiX = 96.0f,
.dpiY = 96.0f
};
hr = ID2D1HwndRenderTarget_CreateBitmap(
d2d_target,
size,
NULL,
0,
&bitmap_props,
&d2d_buffer);
}
}
/* Copy data from render_buffer */
if (SUCCEEDED(hr)) {
rectU = D2D1::RectU(x, y + y1, x + w, y + y2);
hr = d2d_buffer->CopyFromMemory(
D2D1_RECT_U rectU = {
.left = x,
.top = y + y1,
.right = x + w,
.bottom = y + y2
};
hr = ID2D1Bitmap_CopyFromMemory(
d2d_buffer,
&rectU,
&(render_buffer->line[y + y1][x]),
render_buffer->w << 2);
@@ -209,23 +232,53 @@ d2d_blit(int x, int y, int y1, int y2, int w, int h)
/* Draw! */
if (SUCCEEDED(hr)) {
d2d_target->BeginDraw();
D2D1_RECT_F destRect;
ID2D1HwndRenderTarget_BeginDraw(d2d_target);
if (d2d_fs) {
d2d_target->Clear(
D2D1::ColorF(D2D1::ColorF::Black));
float fs_x = 0, fs_y = 0, fs_w = 0, fs_h = 0;
D2D1_COLOR_F black = {
.r = 0.0, .g = 0.0, .b = 0.0, .a = 1.0 };
ID2D1HwndRenderTarget_Clear(
d2d_target,
&black
);
d2d_stretch(&fs_w, &fs_h, &fs_x, &fs_y);
destRect = (D2D1_RECT_F) {
.left = fs_x,
.top = fs_y,
.right = fs_x + fs_w,
.bottom = fs_y + fs_h
};
} else {
destRect = (D2D1_RECT_F) {
.left = 0,
.top = 0,
.right = w,
.bottom = h
};
}
d2d_target->DrawBitmap(
D2D1_RECT_F srcRect = {
.left = x,
.top = y,
.right = x + w,
.bottom = y + h
};
ID2D1HwndRenderTarget_DrawBitmap(
d2d_target,
d2d_buffer,
d2d_fs ? D2D1::RectF(fs_x, fs_y, fs_x + fs_w, fs_y + fs_h) : D2D1::RectF(0, 0, w, h),
&destRect,
1.0f,
D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,
D2D1::RectF(x, y, x + w, y + h));
&srcRect);
hr = d2d_target->EndDraw();
hr = ID2D1HwndRenderTarget_EndDraw(d2d_target, NULL, NULL);
}
if (FAILED(hr))
@@ -248,19 +301,19 @@ d2d_close(void)
if (d2d_buffer)
{
d2d_buffer->Release();
ID2D1Bitmap_Release(d2d_buffer);
d2d_buffer = NULL;
}
if (d2d_target)
{
d2d_target->Release();
ID2D1HwndRenderTarget_Release(d2d_target);
d2d_target = NULL;
}
if (d2d_factory)
{
d2d_factory->Release();
ID2D1Factory_Release(d2d_factory);
d2d_factory = NULL;
}
@@ -286,7 +339,6 @@ d2d_init_common(int fs)
{
HRESULT hr = S_OK;
WCHAR title[200];
D2D1_HWND_RENDER_TARGET_PROPERTIES props;
d2d_log("Direct2D: d2d_init_common(fs=%d)\n", fs);
@@ -319,30 +371,43 @@ d2d_init_common(int fs)
plat_set_input(d2d_hwnd);
SetFocus(d2d_hwnd);
SetWindowPos(d2d_hwnd, HWND_TOPMOST, 0, 0, d2d_screen_width, d2d_screen_height, SWP_SHOWWINDOW);
SetWindowPos(
d2d_hwnd, HWND_TOPMOST,
0, 0, d2d_screen_width, d2d_screen_height,
SWP_SHOWWINDOW);
}
hr = D2D1_CreateFactory(D2D1_FACTORY_TYPE_MULTI_THREADED, __uuidof(ID2D1Factory),
NULL, reinterpret_cast <void **>(&d2d_factory));
if (fs)
{
props = D2D1::HwndRenderTargetProperties(d2d_hwnd,
D2D1::SizeU(d2d_screen_width, d2d_screen_height));
}
else
{
// HwndRenderTarget will get resized appropriately by d2d_blit,
// so it's fine to let D2D imply size of 0x0 for now
props = D2D1::HwndRenderTargetProperties(hwndRender);
}
hr = D2D1_CreateFactory(
D2D1_FACTORY_TYPE_MULTI_THREADED,
&IID_ID2D1Factory, NULL, (void **) &d2d_factory);
if (SUCCEEDED(hr))
{
hr = d2d_factory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
props,
&d2d_target);
D2D1_HWND_RENDER_TARGET_PROPERTIES hwnd_props;
if (fs)
{
hwnd_props = (D2D1_HWND_RENDER_TARGET_PROPERTIES) {
.hwnd = d2d_hwnd,
.pixelSize = {
.width = d2d_screen_width,
.height = d2d_screen_height
}
};
}
else
{
// HwndRenderTarget will get resized appropriately by d2d_blit,
// so it's fine to let D2D imply size of 0x0 for now
hwnd_props = (D2D1_HWND_RENDER_TARGET_PROPERTIES) {
.hwnd = hwndRender
};
}
D2D1_RENDER_TARGET_PROPERTIES target_props = { 0 };
hr = ID2D1Factory_CreateHwndRenderTarget(
d2d_factory, &target_props, &hwnd_props, &d2d_target);
}
if (SUCCEEDED(hr))

View File

@@ -8,7 +8,7 @@
*
* Definitions for the Direct2D rendering module.
*
* Version: @(#)win_d2d.h 1.0.1 2019/10/12
* Version: @(#)win_d2d.h 1.0.2 2019/12/13
*
* Authors: David Hrdlička, <hrdlickadavid@outlook.com>
*
@@ -17,19 +17,10 @@
#ifndef WIN_D2D_H
# define WIN_D2D_H
#ifdef __cplusplus
extern "C" {
#endif
extern void d2d_close(void);
extern int d2d_init(HWND h);
extern int d2d_init_fs(HWND h);
extern int d2d_pause(void);
extern void d2d_enable(int enable);
#ifdef __cplusplus
}
#endif
#endif /*WIN_D2D_H*/