Files
SimpleRayTracing/source/Window.c
Misaki 17872804c5 Update project files and enhance rendering system
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.
2025-04-23 22:24:02 +09:00

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);
}