Ich lerne derzeit C für ein Hobby-Projekt, für das ich versuche, eine einfache Benutzeroberfläche mit Direct2D-Grafik zu erstellen. Mit den Anweisungen unter DirectX in C konnte ich ein leeres Fenster erfolgreich öffnen. Da meine Benutzeroberfläche nur wenige Rechtecke benötigt, habe ich den Direct3D-Code in diesem Tutorial nicht verwendet. Stattdessen versuche ich ein gefülltes Rechteck mit Direct2D API zu zeichnen, aber es funktioniert nicht. Ich habe viele Codezeilen viele Male durchlaufen und viele Dinge ausprobiert, aber ich konnte einfach nicht funktionieren. Unten ist meine komplette C-Datei eingefügt.Direct2D mit C. FillRectangle funktioniert nicht
In meiner Render() -Funktion scheint ID2D1HwndRenderTarget_Clear(window->renderTarget, &whiteColor);
zu funktionieren, aber das FillRectangle funktioniert nicht. Kann jemand bitte sagen, wie man dieses Problem beheben kann?
#include <windows.h>
#include <malloc.h>
#include <d2d1.h>
#pragma comment(lib, "d2d1.lib")
const int WIDTH = 400;
const int HEIGHT = 400;
typedef struct {
HWND hWnd;
BOOL bDone;
ID2D1Factory* direct2dFactory;
ID2D1HwndRenderTarget* renderTarget;
ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
ID2D1SolidColorBrush* m_pCornflowerBlueBrush;
} WindowObject;
static LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
static void FreeWindowObject(WindowObject *window);
HRESULT CreateDeviceIndependentResources(WindowObject *window)
{
HRESULT hr = S_OK;
ID2D1Factory* pFactory = NULL;
const D2D1_FACTORY_OPTIONS opts = { D2D1_DEBUG_LEVEL_INFORMATION };
// Create a Direct2D factory.
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
&IID_ID2D1Factory, &opts, (void**)&pFactory);
window->direct2dFactory = pFactory;
return hr;
}
HRESULT CreateDeviceResources(WindowObject *window)
{
HRESULT hr = S_OK;
if (!window->renderTarget)
{
RECT rc;
GetClientRect(window->hWnd, &rc);
D2D1_SIZE_U size;
size.width = rc.right - rc.left;
size.height = rc.bottom - rc.top;
D2D1_RENDER_TARGET_PROPERTIES renderProps;
D2D1_HWND_RENDER_TARGET_PROPERTIES hwndRenderProps;
D2D1_PIXEL_FORMAT pixFmt = { DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_UNKNOWN };
renderProps.type = D2D1_RENDER_TARGET_TYPE_DEFAULT;
renderProps.pixelFormat = pixFmt;
renderProps.minLevel = D2D1_FEATURE_LEVEL_DEFAULT;
renderProps.usage = D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE;
renderProps.dpiX = renderProps.dpiY = 0.f;
hwndRenderProps.hwnd = window->hWnd;
hwndRenderProps.pixelSize = size;
hwndRenderProps.presentOptions = D2D1_PRESENT_OPTIONS_NONE;
// Create a Direct2D render target.
if (FAILED(hr = ID2D1Factory_CreateHwndRenderTarget(window->direct2dFactory,
&renderProps, &hwndRenderProps, &window->renderTarget)))
{
OutputDebugStringA("Failed to create render target, err = %#x\n", hr);
return 0;
}
D2D1_COLOR_F redColor = { 51, 51, 255 };
if (SUCCEEDED(hr))
{
// Create a gray brush.
hr = ID2D1HwndRenderTarget_CreateSolidColorBrush(window->renderTarget,
&redColor, NULL, &window->m_pLightSlateGrayBrush);
}
}
return hr;
}
void DiscardDeviceResources(WindowObject *window)
{
ID2D1HwndRenderTarget_Release(window->renderTarget);
ID2D1Factory_Release(window->direct2dFactory);
//ID2D1HwndRenderTarget_Release(window->m_pCornflowerBlueBrush);
//ID2D1HwndRenderTarget_Release(window->m_pLightSlateGrayBrush);
}
static WindowObject *CreateWindowObject(HINSTANCE hInstance)
{
WindowObject *window;
// Allocate the window data and create the window.
window = malloc(sizeof(WindowObject));
ZeroMemory(window, sizeof(WindowObject));
HRESULT hr = CreateDeviceIndependentResources(window);
const char *name = "Simple";
int x, y, width, height;
RECT rect;
DWORD dwStyle = WS_VISIBLE | WS_OVERLAPPEDWINDOW;
DWORD dwExStyle = WS_EX_CLIENTEDGE;
WNDCLASS wndClass = {
CS_HREDRAW | CS_VREDRAW, WinProc, 0, 0, hInstance,
0, LoadCursor(0, IDC_ARROW),
1, 0, name
};
RegisterClass(&wndClass);
window->hWnd = CreateWindowEx(
dwExStyle, name, name, dwStyle,
CW_USEDEFAULT,
CW_USEDEFAULT, WIDTH, HEIGHT,
0, 0, hInstance, 0
);
SetWindowLongPtr(window->hWnd, GWLP_USERDATA, window);
hr = window->hWnd ? S_OK : E_FAIL;
return window;
}
HRESULT render(WindowObject *window)
{
HRESULT hr = S_OK;
hr = CreateDeviceResources(window);
if (!SUCCEEDED(hr))
{
return hr;
}
ID2D1HwndRenderTarget_BeginDraw(window->renderTarget);
D2D1_COLOR_F whiteColor = { 255, 255,255 };
ID2D1HwndRenderTarget_Clear(window->renderTarget, &whiteColor);
// Draw rectangle.
D2D1_RECT_F rectangle1 = { 10, 10,100,100 };
ID2D1HwndRenderTarget_FillRectangle(window->renderTarget, &rectangle1, window->m_pLightSlateGrayBrush);
hr = ID2D1HwndRenderTarget_EndDraw(window->renderTarget, NULL, NULL);
if (hr == D2DERR_RECREATE_TARGET)
{
hr = S_OK;
DiscardDeviceResources(window);
}
return hr;
}
static LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
WindowObject *window = (WindowObject *)GetWindowLongPtr(hWnd, GWLP_USERDATA);
switch (uMsg) {
case WM_KEYUP:
if (wParam == VK_ESCAPE)
SendMessage(hWnd, WM_CLOSE, 0, 0);
break;
case WM_PAINT:
render(window);
ValidateRect(hWnd, NULL);
return 0;
break;
case WM_CLOSE:
window->bDone = TRUE;
return 0;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WindowObject *window = CreateWindowObject(hInstance);
while (!window->bDone) {
MSG msg;
if (PeekMessage(&msg, window->hWnd, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else {
render(window);
ValidateRect(window->hWnd, NULL);
}
}
FreeWindowObject(window);
return 0;
}
static void FreeWindowObject(WindowObject *window)
{
DiscardDeviceResources(window);
free(window);
}
Welchen Wert gibt 'ID2D1HwndRenderTarget_FillRectangle' zurück? –
@ JonathanPotter Zeichenoperationen geben 'void' zurück und verschieben einen Fehler auf' EndPaint() ', was ein' HRESULT' zurückgibt, das anzeigt, was der Fehler ist. – andlabs