Add rendering to screen using win32 blits
This commit is contained in:
parent
076f5977a3
commit
1c4c6d3dca
@ -83,6 +83,7 @@
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalDependencies>msimg32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
|
@ -41,7 +41,7 @@ REM Include directories
|
||||
set IncludeFlags=
|
||||
|
||||
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 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 <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;
|
||||
|
||||
@ -52,13 +61,14 @@ inline FILE_SCOPE LARGE_INTEGER getWallClock()
|
||||
return result;
|
||||
}
|
||||
|
||||
#define ErrorBox(text, title) MessageBox(nullptr, text, title, MB_OK);
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
LPSTR lpCmdLine, int nShowCmd)
|
||||
{
|
||||
WNDCLASSEX wc =
|
||||
{
|
||||
sizeof(WNDCLASSEX),
|
||||
CS_HREDRAW | CS_VREDRAW,
|
||||
CS_HREDRAW | CS_VREDRAW | CS_OWNDC,
|
||||
mainWindowProcCallback,
|
||||
0, // int cbClsExtra
|
||||
0, // int cbWndExtra
|
||||
@ -72,34 +82,34 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
};
|
||||
|
||||
if (!RegisterClassEx(&wc)) {
|
||||
// TODO(doyle): Logging, couldn't register class
|
||||
ASSERT(INVALID_CODE_PATH);
|
||||
ErrorBox(L"RegisterClassEx() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
globalRunning = true;
|
||||
|
||||
// NOTE: Regarding Window Sizes
|
||||
// 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,
|
||||
// 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
|
||||
// calculate the size you'd need by accounting for the window style.
|
||||
RECT r = {};
|
||||
r.right = 450;
|
||||
r.bottom = 200;
|
||||
RECT rect = {};
|
||||
rect.right = 128;
|
||||
rect.bottom = 64;
|
||||
|
||||
DWORD windowStyle = WS_OVERLAPPEDWINDOW | WS_VISIBLE;
|
||||
AdjustWindowRect(&r, windowStyle, FALSE);
|
||||
DWORD windowStyle =
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
|
||||
AdjustWindowRect(&rect, windowStyle, FALSE);
|
||||
|
||||
globalRunning = true;
|
||||
HWND mainWindow = CreateWindowEx(
|
||||
WS_EX_COMPOSITED, wc.lpszClassName, L"dchip-8", windowStyle,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, r.right - r.left, r.bottom - r.top,
|
||||
nullptr, nullptr, hInstance, nullptr);
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left,
|
||||
rect.bottom - rect.top, nullptr, nullptr, hInstance, nullptr);
|
||||
|
||||
if (!mainWindow)
|
||||
{
|
||||
// TODO(doyle): Logging, couldn't create root window
|
||||
ASSERT(INVALID_CODE_PATH);
|
||||
ErrorBox(L"CreateWindowEx() failed.", nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -109,6 +119,66 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
f32 targetSecondsPerFrame = 1 / targetFramesPerSecond;
|
||||
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;
|
||||
while (globalRunning)
|
||||
{
|
||||
@ -119,10 +189,35 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
|
||||
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();
|
||||
f32 workTimeInS =
|
||||
getTimeFromQueryPerfCounter(startFrameTime, endWorkTime);
|
||||
|
||||
if (workTimeInS < targetSecondsPerFrame)
|
||||
{
|
||||
DWORD remainingTimeInMs =
|
||||
|
Loading…
Reference in New Issue
Block a user