You should made proper question naming as your question is about Direct2D not the DirectDraw - different technologies. Anyway here is the simple workable example implementation of what you need. It trigger repaint event each second and update buffer with the random color.
#include <windows.h>
#include <conio.h>
#include <atlbase.h>
#include <assert.h>
#include <d2d1.h>
#pragma comment (lib, "d2d1.lib")
HANDLE g_hQuit = NULL;
HANDLE g_hReady = NULL;
CComPtr<ID2D1HwndRenderTarget> m_pRenderTarget = nullptr;
CComPtr<ID2D1Factory> m_pFactory = nullptr;
CComPtr<ID2D1Bitmap> m_pBitmap = nullptr;
uint8_t * m_frame_buffer = nullptr;
SIZE Resolution = {640,480};
BOOL WINAPI ConsoleHandlerRoutine(_In_ DWORD dwCtrlType)
{
if (dwCtrlType == CTRL_CLOSE_EVENT || dwCtrlType == CTRL_LOGOFF_EVENT
|| dwCtrlType == CTRL_SHUTDOWN_EVENT)
{
SetEvent(g_hQuit);
WaitForSingleObject(g_hReady,INFINITE);
}
return TRUE;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_SIZE) {
if (m_pRenderTarget) {
D2D1_SIZE_U size = D2D1::SizeU(LOWORD(lParam), HIWORD(lParam));
m_pRenderTarget->Resize(size);
}
}
if (uMsg == WM_CLOSE) {
SetEvent(g_hQuit);
}
if (uMsg == WM_PAINT) {
if (m_pRenderTarget && m_pBitmap) {
DWORD ticks = GetTickCount();
DWORD color = (DWORD)(sin(ticks * 3.1456 / 180) * 0x00ffffff)
| 0xff000000;
uint32_t * p = (uint32_t *)m_frame_buffer;
for (int y = 0; y < Resolution.cy; y++) {
for (int x = 0; x < Resolution.cx; x++) {
*p++ = color;
}
}
HRESULT hr;
hr = m_pBitmap->CopyFromMemory(NULL,
m_frame_buffer,Resolution.cx * 4);
assert(hr == S_OK);
m_pRenderTarget->BeginDraw();
D2D1_RECT_F rect_dest = {
0,
0,
Resolution.cx,
Resolution.cy
};
m_pRenderTarget->DrawBitmap(m_pBitmap,
rect_dest,1.0f,D2D1_BITMAP_INTERPOLATION_MODE_LINEAR,NULL);
hr = m_pRenderTarget->EndDraw();
assert(hr == S_OK);
}
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
int main(int argc, char* argv[]) {
g_hQuit = CreateEvent(NULL, TRUE, FALSE, NULL);
g_hReady = CreateEvent(NULL, TRUE, FALSE, NULL);
CoInitializeEx(0, COINIT_MULTITHREADED);
static WCHAR szClassName[100];
WNDCLASSW wc;
HINSTANCE hInstance = GetModuleHandle(NULL);
swprintf_s(szClassName, _countof(szClassName), L"%s%d",
L"TempClass", GetTickCount());
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = szClassName;
RegisterClassW(&wc);
HRESULT hr = S_OK;
HWND hwnd = CreateWindowExW(
WS_EX_OVERLAPPEDWINDOW | WS_EX_APPWINDOW
, szClassName, L"Rendering",
WS_OVERLAPPEDWINDOW,
0, 0,
(UINT)(640),
(UINT)(480),
NULL, NULL, hInstance, NULL);
assert(IsWindow(hwnd));
if (!IsWindow(hwnd)) goto exit;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &m_pFactory);
assert(hr == S_OK);
if (hr != S_OK) goto exit;
{
m_frame_buffer = (uint8_t *)malloc(
Resolution.cx * Resolution.cy * 4);
uint32_t * p = (uint32_t *)m_frame_buffer;
for (int y = 0; y < Resolution.cy; y++) {
for (int x = 0; x < Resolution.cx; x++) {
*p++ = 0xff000000;
}
}
}
{
RECT rc;
GetClientRect(hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(
rc.right - rc.left,
rc.bottom - rc.top
);
hr = m_pFactory->CreateHwndRenderTarget(
D2D1::RenderTargetProperties(),
D2D1::HwndRenderTargetProperties(hwnd, size),
&m_pRenderTarget
);
assert(hr == S_OK);
if (hr != S_OK) goto exit;
}
{
D2D1_SIZE_U size = {0};
D2D1_BITMAP_PROPERTIES props;
m_pRenderTarget->GetDpi(&props.dpiX,&props.dpiY);
D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat(
DXGI_FORMAT_B8G8R8A8_UNORM,
D2D1_ALPHA_MODE_IGNORE
);
props.pixelFormat = pixelFormat;
size.width = Resolution.cx;
size.height = Resolution.cy;
hr = m_pRenderTarget->CreateBitmap(size,
m_frame_buffer,
size.width * 4,
props,
&m_pBitmap);
assert(hr == S_OK);
if (hr != S_OK) goto exit;
}
ShowWindow(hwnd,SW_SHOWNORMAL);
UpdateWindow(hwnd);
SetTimer(hwnd,(UINT_PTR)m_pBitmap.p,1000,NULL);
HANDLE hConsole = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hHandles[] = {hConsole,g_hQuit};
bool bQuit = false;
while (!bQuit) {
DWORD result = 0;
if (hwnd) {
result = MsgWaitForMultipleObjects(_countof(hHandles),hHandles,
FALSE,INFINITE,QS_ALLEVENTS);
}
else {
result = WaitForMultipleObjects(_countof(hHandles),hHandles,
FALSE,INFINITE);
}
if (result == WAIT_OBJECT_0 + _countof(hHandles)) {
MSG msg = { 0 };
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if (msg.message == WM_QUIT) {
bQuit = true;
break;
}
if (msg.message == WM_TIMER) {
InvalidateRect(hwnd,NULL,FALSE);
}
if (msg.message == WM_KEYDOWN) {
if (msg.wParam == VK_ESCAPE) {
bQuit = true;
break;
}
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
if (result == WAIT_OBJECT_0) {
DWORD Events = 0;
DWORD temp;
GetNumberOfConsoleInputEvents(hConsole,&Events);
while (Events--) {
INPUT_RECORD rec = { 0 };
if (!ReadConsoleInput(hConsole,&rec,1,&temp)) break;
if (rec.EventType == KEY_EVENT) {
if ((rec.Event.KeyEvent.bKeyDown)
&& (rec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)) {
bQuit = true;
break;
}
}
}
}
if (WAIT_OBJECT_0 == WaitForSingleObject(g_hQuit, 0)) {
bQuit = true;
}
}
exit:
if (IsWindow(hwnd)) {
DestroyWindow(hwnd);
}
SetEvent(g_hReady);
SetConsoleCtrlHandler(ConsoleHandlerRoutine, FALSE);
m_pRenderTarget.Release();
m_pBitmap.Release();
m_pFactory.Release();
CoUninitialize();
if (m_frame_buffer) {
free(m_frame_buffer);
}
CloseHandle(g_hQuit);
CloseHandle(g_hReady);
}