Added: - Updated `.gitignore` to ignore the `[Bb]uild/` directory. - Additional tasks added to the roadmap in `README.md` for light unit standardization and GPU backend support. Changed: - Removed line in `settings.json` that disabled error squiggles for C/C++ code. - Modified `Triangle.h` to include `material_id` in `triangle_t` and reorganized properties. - Reordered parameters in `triangle_collection_init` for clarity. - Updated `shading_context_t` in `Material.h` and added size parameter to `material_create`. - Streamlined initialization in `scene_init` and updated `scene_free` for proper resource management. - Updated `window_create` in `Window.h` to accept a `render_job_t` parameter. - Introduced `renderer_start` in `Renderer.c` to handle rendering jobs and optimized pixel rendering logic.
126 lines
3.9 KiB
C
126 lines
3.9 KiB
C
#include "Window.h"
|
|
|
|
static LRESULT CALLBACK wndow_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_CREATE:
|
|
{
|
|
HDC hdc = GetDC(hwnd);
|
|
bitmap_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
bitmap_info.bmiHeader.biWidth = window_width;
|
|
bitmap_info.bmiHeader.biHeight = -window_height; // Negative to flip the image
|
|
bitmap_info.bmiHeader.biPlanes = 1;
|
|
bitmap_info.bmiHeader.biBitCount = 32; // 32 bits per pixel (RGBA)
|
|
bitmap_info.bmiHeader.biCompression = BI_RGB;
|
|
|
|
bitmap = CreateDIBSection(hdc, &bitmap_info, DIB_RGB_COLORS, (void**)&pixel_buffer, NULL, 0);
|
|
hdc_mem = CreateCompatibleDC(hdc);
|
|
SelectObject(hdc_mem, bitmap);
|
|
|
|
ReleaseDC(hwnd, hdc);
|
|
return 0;
|
|
}
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hdc = BeginPaint(hwnd, &ps);
|
|
HDC hdc_mem = CreateCompatibleDC(hdc);
|
|
HGDIOBJ old_bitmap = SelectObject(hdc_mem, bitmap);
|
|
|
|
BitBlt(hdc, 0, 0, window_width, window_height, hdc_mem, 0, 0, SRCCOPY);
|
|
|
|
SelectObject(hdc_mem, old_bitmap);
|
|
DeleteDC(hdc_mem);
|
|
EndPaint(hwnd, &ps);
|
|
return 0;
|
|
}
|
|
case WM_DESTROY:
|
|
{
|
|
DeleteDC(hdc_mem);
|
|
DeleteObject(bitmap);
|
|
SetWindowLongPtr(hwnd, GWLP_USERDATA, 0);
|
|
PostQuitMessage(0);
|
|
return 0;
|
|
}
|
|
default:
|
|
return DefWindowProc(hwnd, msg, wparam, lparam);
|
|
}
|
|
}
|
|
|
|
static DWORD WINAPI RenderThreadProc(LPVOID lpParameter) {
|
|
render_job_t* job = (render_job_t*)lpParameter;
|
|
renderer_start(job);
|
|
return 0;
|
|
}
|
|
|
|
bool window_create(const char* title, HINSTANCE hInst, int width, int height, render_job_t* render_job)
|
|
{
|
|
RECT rect = {0, 0, width, height};
|
|
AdjustWindowRect(&rect, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, FALSE);
|
|
|
|
window_width = rect.right - rect.left;
|
|
window_height = rect.bottom - rect.top;
|
|
|
|
WNDCLASS wc = {0};
|
|
wc.lpfnWndProc = wndow_proc;
|
|
wc.hInstance = hInst;
|
|
wc.lpszClassName = title;
|
|
wc.hCursor = LoadCursor(hInst, IDC_ARROW);
|
|
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
|
|
|
RegisterClass(&wc);
|
|
|
|
int screen_width = GetSystemMetrics(SM_CXSCREEN);
|
|
int screen_height = GetSystemMetrics(SM_CYSCREEN);
|
|
int pos_x = (screen_width - window_width) / 2;
|
|
int pos_y = (screen_height - window_height) / 2;
|
|
|
|
hwnd = CreateWindowEx(0, title, title, WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE, pos_x, pos_y,
|
|
window_width, window_height, NULL, NULL, wc.hInstance, NULL);
|
|
|
|
if (!hwnd)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
ShowWindow(hwnd, SW_SHOW);
|
|
|
|
render_thread = CreateThread(NULL, 0, RenderThreadProc, render_job, 0, NULL);
|
|
if (render_thread == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void window_update_pixel(vec4s color, int pixel_x, int pixel_y)
|
|
{
|
|
int pixel_index = (pixel_y * window_width + pixel_x) * 4;
|
|
|
|
float alpha = fminf(fmaxf(color.w, 0.0f), 1.0f);
|
|
|
|
// NOTE: The pixel buffer is in BGRA format, so we need to swap the channels
|
|
pixel_buffer[pixel_index] = COLOR_CLAMP(color.z * alpha * 255.0f);
|
|
pixel_buffer[pixel_index + 1] = COLOR_CLAMP(color.y * alpha * 255.0f);
|
|
pixel_buffer[pixel_index + 2] = COLOR_CLAMP(color.x * alpha * 255.0f);
|
|
pixel_buffer[pixel_index + 3] = COLOR_CLAMP(alpha * 255.0f);
|
|
}
|
|
|
|
void window_refresh_region(int pixel_x, int pixel_y, int region_width, int region_height)
|
|
{
|
|
HDC hdc = GetDC(hwnd);
|
|
BitBlt(hdc, pixel_x, pixel_y, region_width, region_height, hdc_mem, pixel_x, pixel_y, SRCCOPY);
|
|
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
|
|
void window_close()
|
|
{
|
|
PostMessage(hwnd, WM_DESTROY, 0, 0);
|
|
WaitForSingleObject(render_thread, INFINITE);
|
|
CloseHandle(render_thread);
|
|
DestroyWindow(hwnd);
|
|
}
|