Added Win32 support
This commit is contained in:
@@ -38,8 +38,8 @@ PluginUpdateAndRender(plugin_offscreen_buffer *Buffer)
|
||||
float r = float(X) / float(Buffer->Width);
|
||||
float g = float(Y) / float(Buffer->Height);
|
||||
float b = 0.2;
|
||||
int ir = int(255.99 * r);
|
||||
int ig = int(255.99 * g);
|
||||
int ig = int(255.99 * r);
|
||||
int ir = int(255.99 * g);
|
||||
int ib = int(255.99 * b);
|
||||
|
||||
*Pixel++ = (ir << 24) + (ig << 16) + (ib << 8) + 0xFF;
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#define local_persist static
|
||||
#define global_variable static
|
||||
|
||||
#define Assert(Expression) if(!(Expression)) { *(int *)0 = 0; }
|
||||
|
||||
// Services that are being provided to the platform layer
|
||||
|
||||
struct plugin_offscreen_buffer
|
||||
|
||||
276
code/win32_platform.cpp
Normal file
276
code/win32_platform.cpp
Normal file
@@ -0,0 +1,276 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#define SDL_MAIN_HANDLED
|
||||
#include "rt_weekend.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "win32_platform.h"
|
||||
|
||||
const char *WindowTitle = "Ray Tracing in a Weekend";
|
||||
|
||||
const uint32_t TARGET_FRAME_RATE = 30;
|
||||
const uint32_t TICKS_PER_FRAME = 1000 / TARGET_FRAME_RATE;
|
||||
const uint32_t WINDOW_WIDTH = 500;
|
||||
const uint32_t WINDOW_HEIGHT = 250;
|
||||
|
||||
global_variable bool Running = true;
|
||||
global_variable sdl_offscreen_buffer GlobalBackbuffer;
|
||||
|
||||
void PluginUpdateAndRenderStub(plugin_offscreen_buffer *Buffer)
|
||||
{
|
||||
}
|
||||
|
||||
internal sdl_window_dimension
|
||||
SDLGetWindowDimension(SDL_Window *Window)
|
||||
{
|
||||
sdl_window_dimension Result;
|
||||
SDL_GetWindowSize(Window, &Result.Width, &Result.Height);
|
||||
|
||||
return(Result);
|
||||
}
|
||||
|
||||
internal void
|
||||
SDLResizeTexture(sdl_offscreen_buffer *Buffer,
|
||||
SDL_Renderer *Renderer,
|
||||
int Width, int Height)
|
||||
{
|
||||
const int BytesPerPixel = 4;
|
||||
|
||||
if(Buffer->Memory)
|
||||
{
|
||||
VirtualFree(Buffer->Memory, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
if(Buffer->Texture)
|
||||
{
|
||||
SDL_DestroyTexture(Buffer->Texture);
|
||||
}
|
||||
|
||||
Buffer->Texture = SDL_CreateTexture(Renderer,
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
Width, Height);
|
||||
Buffer->Width = Width;
|
||||
Buffer->Height = Height;
|
||||
Buffer->Pitch = Width * BytesPerPixel;
|
||||
Buffer->Memory = VirtualAlloc(0, Width * Height * BytesPerPixel,
|
||||
MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||
}
|
||||
|
||||
internal void
|
||||
SDLUpdateWindow(SDL_Renderer *Renderer,
|
||||
sdl_offscreen_buffer Buffer)
|
||||
{
|
||||
SDL_UpdateTexture(Buffer.Texture,
|
||||
0,
|
||||
Buffer.Memory,
|
||||
Buffer.Pitch);
|
||||
|
||||
SDL_RenderCopy(Renderer, Buffer.Texture, 0, 0);
|
||||
|
||||
SDL_RenderPresent(Renderer);
|
||||
}
|
||||
|
||||
internal void
|
||||
HandleEvent(SDL_Event *Event)
|
||||
{
|
||||
switch(Event->type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
{
|
||||
Running = false;
|
||||
} break;
|
||||
|
||||
case SDL_WINDOWEVENT:
|
||||
{
|
||||
switch (Event->window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
{
|
||||
SDL_Window *Window = SDL_GetWindowFromID(Event->window.windowID);
|
||||
SDL_Renderer *Renderer = SDL_GetRenderer(Window);
|
||||
SDLUpdateWindow(Renderer, GlobalBackbuffer);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline FILETIME
|
||||
Win32GetLastWriteTime(char *Filename)
|
||||
{
|
||||
FILETIME LastWriteTime = {};
|
||||
|
||||
WIN32_FILE_ATTRIBUTE_DATA Data;
|
||||
if (GetFileAttributesEx(Filename, GetFileExInfoStandard, &Data))
|
||||
{
|
||||
LastWriteTime = Data.ftLastWriteTime;
|
||||
}
|
||||
|
||||
return LastWriteTime;
|
||||
}
|
||||
|
||||
internal sdl_plugin_code
|
||||
SDLLoadPluginCode(char *SourceDLLName, char *TempDLLName)
|
||||
{
|
||||
sdl_plugin_code Result = {};
|
||||
|
||||
Result.DLLLastWriteTime = Win32GetLastWriteTime(SourceDLLName);
|
||||
|
||||
CopyFile(SourceDLLName, TempDLLName, FALSE);
|
||||
|
||||
Result.PluginCodeDLL = LoadLibraryA(TempDLLName);
|
||||
if (Result.PluginCodeDLL)
|
||||
{
|
||||
Result.UpdateAndRender = (plugin_update_and_render *)
|
||||
GetProcAddress(Result.PluginCodeDLL, "PluginUpdateAndRender");
|
||||
Result.IsValid = Result.UpdateAndRender;
|
||||
}
|
||||
Assert(Result.IsValid);
|
||||
|
||||
|
||||
if (!Result.IsValid)
|
||||
{
|
||||
Result.UpdateAndRender = 0;
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
internal void
|
||||
SDLUnloadPluginCode(sdl_plugin_code *PluginCode)
|
||||
{
|
||||
if (PluginCode->PluginCodeDLL)
|
||||
{
|
||||
FreeLibrary(PluginCode->PluginCodeDLL);
|
||||
PluginCode->PluginCodeDLL = 0;
|
||||
}
|
||||
|
||||
PluginCode->IsValid = false;
|
||||
PluginCode->UpdateAndRender = 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// Variables required to calculate framerate
|
||||
#define FPS_INTERVAL 1.0
|
||||
uint32_t LastFrameEndTime = SDL_GetTicks();
|
||||
uint32_t CurrentFPS = 0;
|
||||
uint32_t FramesElapsed = 0;
|
||||
uint32_t FramesMissed = 0;
|
||||
|
||||
// Initialize SDL
|
||||
SDL_Window *Window = NULL;
|
||||
SDL_Renderer *Renderer = NULL;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||
{
|
||||
SDL_Log("Unable to initialize SDL: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create window
|
||||
Window = SDL_CreateWindow(WindowTitle,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
WINDOW_WIDTH,
|
||||
WINDOW_HEIGHT,
|
||||
SDL_WINDOW_OPENGL);
|
||||
if (Window == NULL)
|
||||
{
|
||||
printf("Could not create window: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create renderer
|
||||
Renderer = SDL_CreateRenderer(Window, -1, SDL_RENDERER_ACCELERATED);
|
||||
|
||||
if (Renderer == NULL)
|
||||
{
|
||||
printf("Could not create renderer: %s\n", SDL_GetError());
|
||||
SDL_DestroyWindow(Window);
|
||||
SDL_Quit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Create texture
|
||||
sdl_window_dimension Dimension = SDLGetWindowDimension(Window);
|
||||
SDLResizeTexture(&GlobalBackbuffer, Renderer, Dimension.Width, Dimension.Height);
|
||||
|
||||
// Load plugin code
|
||||
sdl_plugin_code Plugin = SDLLoadPluginCode("rt_weekend.dll", "rt_weekend_temp.dll");
|
||||
|
||||
// Main loop
|
||||
while (Running)
|
||||
{
|
||||
uint32_t FrameStartTime = SDL_GetTicks();
|
||||
|
||||
// Live reloading
|
||||
FILETIME NewDLLWriteTime = Win32GetLastWriteTime("rt_weekend.dll");
|
||||
if (CompareFileTime(&NewDLLWriteTime, &Plugin.DLLLastWriteTime) != 0)
|
||||
{
|
||||
SDLUnloadPluginCode(&Plugin);
|
||||
Plugin = SDLLoadPluginCode("rt_weekend.dll", "rt_weekend_temp.dll");
|
||||
}
|
||||
|
||||
SDL_Event Event;
|
||||
while (SDL_PollEvent(&Event))
|
||||
{
|
||||
HandleEvent(&Event);
|
||||
}
|
||||
|
||||
// Display rendering information in Window title
|
||||
char WindowTitleBuffer[512];
|
||||
sprintf(WindowTitleBuffer,
|
||||
"%s - %d x %d - %u fps - %d frames missed",
|
||||
WindowTitle,
|
||||
WINDOW_WIDTH,
|
||||
WINDOW_HEIGHT,
|
||||
CurrentFPS,
|
||||
FramesMissed);
|
||||
|
||||
SDL_SetWindowTitle(Window, WindowTitleBuffer);
|
||||
|
||||
plugin_offscreen_buffer Buffer = {};
|
||||
Buffer.Memory = GlobalBackbuffer.Memory;
|
||||
Buffer.Width = GlobalBackbuffer.Width;
|
||||
Buffer.Height = GlobalBackbuffer.Height;
|
||||
Buffer.Pitch = GlobalBackbuffer.Pitch;
|
||||
Plugin.UpdateAndRender(&Buffer);
|
||||
|
||||
SDLUpdateWindow(Renderer, GlobalBackbuffer);
|
||||
|
||||
uint32_t FrameEndTime = SDL_GetTicks();
|
||||
// Calculate framerate
|
||||
if (LastFrameEndTime < FrameEndTime - FPS_INTERVAL * 1000)
|
||||
{
|
||||
LastFrameEndTime = FrameEndTime;
|
||||
CurrentFPS = FramesElapsed;
|
||||
FramesElapsed = 0;
|
||||
}
|
||||
FramesElapsed++;
|
||||
|
||||
// Cap framerate
|
||||
uint32_t FrameTicks = FrameEndTime - FrameStartTime;
|
||||
|
||||
if (FrameTicks < TICKS_PER_FRAME)
|
||||
{
|
||||
// Wait remaining time
|
||||
SDL_Delay(TICKS_PER_FRAME - FrameTicks);
|
||||
}
|
||||
else
|
||||
{
|
||||
FramesMissed++;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_DestroyRenderer(Renderer);
|
||||
SDL_DestroyWindow(Window);
|
||||
SDL_Quit();
|
||||
return 0;
|
||||
}
|
||||
29
code/win32_platform.h
Normal file
29
code/win32_platform.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef WIN32_PLATFORM_H
|
||||
#define WIN32_PLATFORM_H
|
||||
|
||||
typedef void plugin_update_and_render(plugin_offscreen_buffer *Buffer);
|
||||
|
||||
struct sdl_plugin_code
|
||||
{
|
||||
HMODULE PluginCodeDLL;
|
||||
FILETIME DLLLastWriteTime;
|
||||
plugin_update_and_render *UpdateAndRender;
|
||||
bool IsValid;
|
||||
};
|
||||
|
||||
struct sdl_offscreen_buffer
|
||||
{
|
||||
SDL_Texture *Texture;
|
||||
void *Memory;
|
||||
int Width;
|
||||
int Height;
|
||||
int Pitch;
|
||||
};
|
||||
|
||||
struct sdl_window_dimension
|
||||
{
|
||||
int Width;
|
||||
int Height;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user