Add rendering to screen using win32 blits
This commit is contained in:
parent
076f5977a3
commit
1c4c6d3dca
@ -83,6 +83,7 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
|
<AdditionalDependencies>msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
@ -41,7 +41,7 @@ REM Include directories
|
|||||||
set IncludeFlags=
|
set IncludeFlags=
|
||||||
|
|
||||||
REM Link libraries
|
REM Link libraries
|
||||||
set LinkLibraries=user32.lib gdi32.lib
|
set LinkLibraries=user32.lib gdi32.lib msimg32.lib
|
||||||
|
|
||||||
REM incrmenetal:no, turn incremental builds off
|
REM incrmenetal:no, turn incremental builds off
|
||||||
REM opt:ref, try to remove functions from libs that are referenced at all
|
REM opt:ref, try to remove functions from libs that are referenced at all
|
||||||
|
123
src/dchip-8.cpp
123
src/dchip-8.cpp
@ -9,6 +9,15 @@
|
|||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
FILE_SCOPE HBITMAP bitmap;
|
||||||
|
FILE_SCOPE BITMAPINFO bitmapInfo;
|
||||||
|
|
||||||
|
const i32 WIDTH = 64;
|
||||||
|
const i32 HEIGHT = 32;
|
||||||
|
const i32 RESOLUTION = WIDTH * HEIGHT;
|
||||||
|
FILE_SCOPE void *bitmapMemory;
|
||||||
|
|
||||||
FILE_SCOPE bool globalRunning = false;
|
FILE_SCOPE bool globalRunning = false;
|
||||||
|
|
||||||
@ -52,13 +61,14 @@ inline FILE_SCOPE LARGE_INTEGER getWallClock()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ErrorBox(text, title) MessageBox(nullptr, text, title, MB_OK);
|
||||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||||
LPSTR lpCmdLine, int nShowCmd)
|
LPSTR lpCmdLine, int nShowCmd)
|
||||||
{
|
{
|
||||||
WNDCLASSEX wc =
|
WNDCLASSEX wc =
|
||||||
{
|
{
|
||||||
sizeof(WNDCLASSEX),
|
sizeof(WNDCLASSEX),
|
||||||
CS_HREDRAW | CS_VREDRAW,
|
CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||||
mainWindowProcCallback,
|
mainWindowProcCallback,
|
||||||
0, // int cbClsExtra
|
0, // int cbClsExtra
|
||||||
0, // int cbWndExtra
|
0, // int cbWndExtra
|
||||||
@ -72,34 +82,34 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!RegisterClassEx(&wc)) {
|
if (!RegisterClassEx(&wc)) {
|
||||||
// TODO(doyle): Logging, couldn't register class
|
ErrorBox(L"RegisterClassEx() failed.", nullptr);
|
||||||
ASSERT(INVALID_CODE_PATH);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
globalRunning = true;
|
||||||
|
|
||||||
// NOTE: Regarding Window Sizes
|
// NOTE: Regarding Window Sizes
|
||||||
// If you specify a window size, e.g. 800x600, Windows regards the 800x600
|
// If you specify a window size, e.g. 800x600, Windows regards the 800x600
|
||||||
// region to be inclusive of the toolbars and side borders. So in actuality,
|
// region to be inclusive of the toolbars and side borders. So in actuality,
|
||||||
// when you blit to the screen blackness, the area that is being blitted to
|
// when you blit to the screen blackness, the area that is being blitted to
|
||||||
// is slightly smaller than 800x600. Windows provides a function to help
|
// is slightly smaller than 800x600. Windows provides a function to help
|
||||||
// calculate the size you'd need by accounting for the window style.
|
// calculate the size you'd need by accounting for the window style.
|
||||||
RECT r = {};
|
RECT rect = {};
|
||||||
r.right = 450;
|
rect.right = 128;
|
||||||
r.bottom = 200;
|
rect.bottom = 64;
|
||||||
|
|
||||||
DWORD windowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
|
DWORD windowStyle =
|
||||||
AdjustWindowRect(&r, windowStyle, FALSE);
|
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||||
|
AdjustWindowRect(&rect, windowStyle, FALSE);
|
||||||
|
|
||||||
globalRunning = true;
|
|
||||||
HWND mainWindow = CreateWindowEx(
|
HWND mainWindow = CreateWindowEx(
|
||||||
WS_EX_COMPOSITED, wc.lpszClassName, L"dchip-8", windowStyle,
|
WS_EX_COMPOSITED, wc.lpszClassName, L"dchip-8", windowStyle,
|
||||||
CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top,
|
CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left,
|
||||||
nullptr, nullptr, hInstance, nullptr);
|
rect.bottom - rect.top, nullptr, nullptr, hInstance, nullptr);
|
||||||
|
|
||||||
if (!mainWindow)
|
if (!mainWindow)
|
||||||
{
|
{
|
||||||
// TODO(doyle): Logging, couldn't create root window
|
ErrorBox(L"CreateWindowEx() failed.", nullptr);
|
||||||
ASSERT(INVALID_CODE_PATH);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +119,66 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
f32 targetSecondsPerFrame = 1 / targetFramesPerSecond;
|
f32 targetSecondsPerFrame = 1 / targetFramesPerSecond;
|
||||||
f32 frameTimeInS = 0.0f;
|
f32 frameTimeInS = 0.0f;
|
||||||
|
|
||||||
|
{
|
||||||
|
BITMAPINFOHEADER header = {};
|
||||||
|
header.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
header.biWidth = WIDTH;
|
||||||
|
header.biHeight = HEIGHT;
|
||||||
|
header.biPlanes = 1;
|
||||||
|
header.biBitCount = 32;
|
||||||
|
header.biCompression = BI_RGB; // uncompressed bitmap
|
||||||
|
header.biSizeImage = 0;
|
||||||
|
header.biXPelsPerMeter = 0;
|
||||||
|
header.biYPelsPerMeter = 0;
|
||||||
|
header.biClrUsed = 0;
|
||||||
|
header.biClrImportant = 0;
|
||||||
|
|
||||||
|
bitmapInfo.bmiHeader = header;
|
||||||
|
|
||||||
|
const i32 numPixels = header.biWidth * header.biHeight;
|
||||||
|
const i32 bytesPerPixel = header.biBitCount / 8;
|
||||||
|
#if 0
|
||||||
|
bitmapMemory = calloc(1, numPixels * bytesPerPixel);
|
||||||
|
|
||||||
|
if (!bitmapMemory)
|
||||||
|
{
|
||||||
|
ErrorBox(L"malloc() failed.", nullptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
HDC deviceContext = GetDC(mainWindow);
|
||||||
|
bitmap = CreateDIBSection(deviceContext, &bitmapInfo, DIB_RGB_COLORS,
|
||||||
|
&bitmapMemory, NULL, NULL);
|
||||||
|
ReleaseDC(mainWindow, deviceContext);
|
||||||
|
|
||||||
|
if (!bitmapMemory)
|
||||||
|
{
|
||||||
|
ErrorBox(L"CreateDIBSection() failed.", nullptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
u32 *bitmapBuffer = (u32 *)bitmapMemory;
|
||||||
|
for (i32 i = 0; i < numPixels; i++)
|
||||||
|
{
|
||||||
|
// NOTE: Win32 AlphaBlend requires the RGB components to be
|
||||||
|
// premultiplied with alpha.
|
||||||
|
f32 normA = 1.0f;
|
||||||
|
f32 normR = (normA * 0.0f);
|
||||||
|
f32 normG = (normA * 0.0f);
|
||||||
|
f32 normB = (normA * 1.0f);
|
||||||
|
|
||||||
|
u8 r = (u8)(normR * 255.0f);
|
||||||
|
u8 g = (u8)(normG * 255.0f);
|
||||||
|
u8 b = (u8)(normB * 255.0f);
|
||||||
|
u8 a = (u8)(normA * 255.0f);
|
||||||
|
|
||||||
|
u32 color = (a << 24) | (r << 16) | (g << 8) | (b << 0);
|
||||||
|
bitmapBuffer[i] = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
while (globalRunning)
|
while (globalRunning)
|
||||||
{
|
{
|
||||||
@ -119,10 +189,35 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
|||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RECT clientRect = {};
|
||||||
|
GetClientRect(mainWindow, &clientRect);
|
||||||
|
|
||||||
|
LONG clientWidth = clientRect.right - clientRect.left;
|
||||||
|
LONG clientHeight = clientRect.bottom - clientRect.top;
|
||||||
|
|
||||||
|
BLENDFUNCTION blend = {};
|
||||||
|
blend.BlendOp = AC_SRC_OVER;
|
||||||
|
blend.SourceConstantAlpha = 255;
|
||||||
|
blend.AlphaFormat = AC_SRC_ALPHA;
|
||||||
|
|
||||||
|
HDC deviceContext = GetDC(mainWindow);
|
||||||
|
HDC alphaBlendDC = CreateCompatibleDC(deviceContext);
|
||||||
|
SelectObject(alphaBlendDC, bitmap);
|
||||||
|
|
||||||
|
AlphaBlend(deviceContext, 0, 0, WIDTH, HEIGHT, alphaBlendDC, 0, 0,
|
||||||
|
WIDTH, HEIGHT, blend);
|
||||||
|
StretchBlt(deviceContext, 0, 0, clientWidth, clientHeight,
|
||||||
|
deviceContext, 0, 0, WIDTH, HEIGHT, SRCCOPY);
|
||||||
|
|
||||||
|
DeleteDC(alphaBlendDC);
|
||||||
|
ReleaseDC(mainWindow, deviceContext);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
// Frame Limiting
|
||||||
|
////////////////////////////////////////////////////////////////////////
|
||||||
LARGE_INTEGER endWorkTime = getWallClock();
|
LARGE_INTEGER endWorkTime = getWallClock();
|
||||||
f32 workTimeInS =
|
f32 workTimeInS =
|
||||||
getTimeFromQueryPerfCounter(startFrameTime, endWorkTime);
|
getTimeFromQueryPerfCounter(startFrameTime, endWorkTime);
|
||||||
|
|
||||||
if (workTimeInS < targetSecondsPerFrame)
|
if (workTimeInS < targetSecondsPerFrame)
|
||||||
{
|
{
|
||||||
DWORD remainingTimeInMs =
|
DWORD remainingTimeInMs =
|
||||||
|
Loading…
Reference in New Issue
Block a user