This was a group project (2 people) for a university exam. The game is inspired by 80-90's Dungeon Crawlers and by the upcoming Vampire Crawlers.
It was made entirely in C++ with OpenGL.
I implemented everything related to the rendering, the text system, collisions and game states (paused, unpaused, main menu),
I was also responsible for the code structure.
out vec4 FragColor;
in vec2 TexCoords;
in vec3 WorldPos;
in vec3 Normal;
in vec4 FragPosLightSpace;
in vec3 Tangent;
in vec3 Bitangent;
// material textures parameters
uniform sampler2D albedoMap;
uniform sampler2D normalMap;
uniform sampler2D metallicMap;
uniform sampler2D roughnessMap;
uniform sampler2D aoMap;
// shadows
uniform sampler2D shadowMap;
uniform samplerCube depthCubeMap[10];
// lights
uniform vec3 lightPositions[10];
uniform vec3 lightColors[10];
uniform int lightTypes[10];
uniform vec3 camPos;
uniform int numLights;
uniform float far_plane;
uniform bool bRenderAsShadows;
In this code block we can see all the uniforms and input parameters used by the pbr shader. The magic number 10 is used to set a limit on how many lights we can put in the scene, because we didn't need more and, most importantly, because we didn't implement a system to dynamically load/unload portions of the map.
For collisions management I tried first to use axis aligned bounding boxes (AABB),
this approach couldn't work because of the theory behind them, they cannot be used for precise collision against diagonal walls, what I was trying to do was achievable through Oriented Bounding Boxes (OBB).
Due to time reasons instead of learning how to implement OBB I used a simple sphere to plane collision system (discussed in the next paragraphs).
(In the gif the AABB are shown in green).
The collision in the game is calculated with the CheckCollision(...) function, for each wall in the scene it checks if the player position is close enough to the wall center in the direction of the wall normal, if so it controls if the projected point to the wall reside inside it (with the statement on half width and half height). Because the player doesn't move smoothly but with a step of 10 units at a time, I used the RayCastCollision(...) that checks the collision i times from the start position to the targeted step position, if a collision is detected the target position is set to the last valid one so the player stops.
In order to check the collision with the walls, I needed, for each of them, to create a plane that could represent them and store them, the image shows how the wall construction is done and how the wall entities are handled (by the wallsManager). To represent the wall plane in the space we need only 4 vertices, from those we can calculate the right and bottom side and the center, all of them used in the CheckCollision(...) functions seen previously. The walls .obj are loaded from files, at first they were one single model, but for this approach to work, unfortunately, we needed to divide them.