Making Your Own 2.5D Renderer Thing In C++ For Fun
Friday, September 27, 2019
I had an old Blog and want to get the posts on here:
From February 2018:
So I like to program. And I guess I like the idea of making a game. I really haven’t finised many. Previously most of my attempts have been in Javacript using canvas I made some library/engine thing even. I mean it isn’t very good is it?
Anyway, I think writing low level code makes you cool. And I want to be cool like Casey Muratori or Jonathan Blow I also think old school engines like Build, Doom, or Wolfenstien 3D are cool. Which makes me want to eschew all better ideas and do one similar to those. However, since I don’t hate myself completely. I do use SDL for the platform layer.
In the rest of this post I will go over some cool things I think I do.
Raycasting
I don’t really want to explain what ray casting is. I just want to say what I do. It’s probably stupid but I like it.
Instead of just sending out a ray and following its path to see what it hits (I tried this). I do something a little different. I have a list of line segments that are the walls. They contain a start position, end position, texture index, and if they are transparent or not. For every ray I spit out (on each column of the screen) I also make a line segment the start is the player position and the end is some place like 2000 units away. Then every ray checks itself against every wall. Checking if it
- Hits the wall
- Where it hits the wall
To know if a wall is already occulded I keep a buffer of every column and the largest height of the wall drawn there. If the height is smaller it doesn’t get drawn. If the wall is transparent the drawing gets deffered until after all the rays have finished their checks then those walls are drawn back to front. Again checking the height buffer.
In terms of rendering that’s about what I have so far. Nothing too exciting but I think it’s cool I even did it. I’m working on floors and ceilings now. It’s pretty tough.
Hot reloading.
I learned this one from Casey Muratori. On his stream Handmade Hero
If you separate your game into two parts. A platform layer and game layer. You can compile your platform layer as an EXE and your game layer as a DLL. As long as the platform layer holds the gamestate and passes it to the game layer. Anytime the DLL is rebuilt you can reload it in your platform layer and see your code changes on the fly without having to close and reopen the exe.
Here is my shitty SDL code to do that.
Oh and, we copy the DLL to a temp file so our game doesn’t keep a file lock on the DLL and keep us from reloading it.
char *LockFileName = "../build/lock.tmp";
char *TempDLLName = "../build/temp.seville.dll";
char *SourceDLLName = "../build/seville.dll";
stat(SourceDLLName, &buff);
if(modified < buff.st_mtime){
if(GameCodeDLL){
SDL_UnloadObject(GameCodeDLL);
UpdateAndRender = NULL;
}
SDL_RWops *f = SDL_RWFromFile(LockFileName, "rb");
if(!f)
{
if(!stb_copyfile(SourceDLLName, TempDLLName)){
err = SDL_GetError();
}
GameCodeDLL = SDL_LoadObject(TempDLLName);
if(GameCodeDLL)
{
UpdateAndRender = (game_update_and_render *)
SDL_LoadFunction(GameCodeDLL, "GameUpdateAndRender");
modified = buff.st_mtime;
} else {
int var = 1+1;
err = SDL_GetError();
}
}
if(f){
SDL_RWclose(f);
}
}
if(UpdateAndRender){
UpdateAndRender(Renderer, keysHeld, &state);
} else {
err = SDL_GetError();
int var = 1+1;
}
So that’s where I’m at.