aboutsummaryrefslogtreecommitdiff
path: root/08-august/src/main.c
diff options
context:
space:
mode:
authorThomas Guillermo Albers Raviola <thomas@thomaslabs.org>2026-01-16 23:02:32 +0100
committerThomas Guillermo Albers Raviola <thomas@thomaslabs.org>2026-01-16 23:02:32 +0100
commit6b8af9cf83851c075c6c9514b1deaa931c2b19a4 (patch)
tree428986b49c32e21d3f7a3c2dfa41858ae0153209 /08-august/src/main.c
Initial commit
Diffstat (limited to '08-august/src/main.c')
-rw-r--r--08-august/src/main.c290
1 files changed, 290 insertions, 0 deletions
diff --git a/08-august/src/main.c b/08-august/src/main.c
new file mode 100644
index 0000000..41fc253
--- /dev/null
+++ b/08-august/src/main.c
@@ -0,0 +1,290 @@
+#include "game.h"
+#include "math/vector3f.h"
+#include "math/vector2f.h"
+#include "math/matrix4x4.h"
+#include "input.h"
+#include "util/util.h"
+#include "util/util_time.h"
+#include "light.h"
+#include "renderer/renderer.h"
+#include <SDL2/SDL.h>
+
+/**
+ TODO: Shadows
+ Texture Atlases
+ Memory management
+
+ +improve skybox
+ |
+ +->fog
+ +->day/night
+
+ +mouse picking (is it working perfectly?)
+
+ +add cell shading?
+
+ improve math package
+ repair gui on renderer.c
+ improve shape loading (tangent generation) (normal generation)
+ improve normal mapping
+**/
+
+void LoadResources(game_t *game);
+void Draw(game_t *game);
+void ProcessInput(game_t *game);
+void CleanUp(game_t *game);
+
+int main(int argc, char *argv[])
+{
+ SDL_Init(SDL_INIT_EVERYTHING);
+
+ game_t game;
+ game.gameState = RUNNING;
+ game.window = Window_Create("Test", WINDOW_WIDTH, WINDOW_HEIGHT);
+
+ GLenum err = glewInit();
+ if(err != GLEW_OK) {
+ fputs(glewGetErrorString(err), stderr);
+ Util_FatalError("Glew could no be started!");
+ }
+
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ SDL_GL_SetSwapInterval(1);
+ // glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
+
+ game.shaderProgram.ID = Shader_CompileShaders("resources/shaders/shader.vert",
+ "resources/shaders/shader.frag");
+
+ game.terrainProgram.ID = Shader_CompileShaders("resources/shaders/terrainShader.vert",
+ "resources/shaders/terrainShader.frag");
+
+ game.skyboxProgram.ID = Shader_CompileShaders("resources/shaders/skyboxShader.vert",
+ "resources/shaders/skyboxShader.frag");
+ glUseProgram(game.shaderProgram.ID);
+
+ Camera_Init(&game.camera);
+ game.camera.projectionMatrix = mat4_perspective(60.0f, WINDOW_ASPECT_RATIO, 0.1f, 900.0f);
+
+ LoadResources(&game);
+ glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
+
+ Time_Init();
+ Time_SetMaxFramesPerSecond(60);
+ while(game.gameState != EXIT)
+ {
+ Time_Begin();
+ ProcessInput(&game);
+ Player_Update(&game.player, game.terrain);
+ Draw(&game);
+
+ float FPS = Time_End();
+
+ if( !( Time_GetCountedFrames() % (int)FPS ) )
+ fprintf(stderr, "FPS: %.4f\n", FPS);
+ }
+
+ Window_Destroy(game.window);
+ CleanUp(&game);
+ SDL_Quit();
+ return 0;
+}
+
+void CleanUp(game_t *game)
+{
+ Shape_Free(game->entsShape);
+ Shape_Free(game->sky.cube);
+
+ Texture_Destroy(game->entsTexture);
+ Texture_Destroy(game->sky.texture);
+
+ Texture_Destroy(game->normalMap);
+ Texture_Destroy(game->defaultNormalMap);
+
+ Terrain_Destroy(game->terrain);
+
+ Shader_Destroy(game->shaderProgram.ID);
+ Shader_Destroy(game->terrainProgram.ID);
+ Shader_Destroy(game->skyboxProgram.ID);
+
+ Render_Quit();
+}
+
+void LoadResources(game_t *game)
+{
+ Render_Init();
+ Uint32 start = SDL_GetTicks();
+
+ game->entsShape = Shape_LoadOBJ("resources/barrel.obj");
+ game->entsTexture = Texture_Create2D("resources/textures/barrel.png");
+
+ Player_Init(&game->player);
+ game->player.entity.texture = game->entsTexture;
+ game->player.entity.shape = game->entsShape;
+
+ {
+ vec3_t position = { 0.0f, 3.0f, 0.0f };
+ float rotation[3] = { 0.0f, 0.0f, 0.0f };
+ game->ents[0].position = position;
+ game->ents[0].rotX = rotation[0];
+ game->ents[0].rotY = rotation[1];
+ game->ents[0].rotZ = rotation[2];
+ game->ents[0].shape = game->entsShape;
+ game->ents[0].texture = game->entsTexture;
+ }
+
+ {
+ vec3_t position = { -400.0f, 0.0f, -400.0f };
+ GLuint blendmap = Texture_Create2D("resources/textures/blendmap.png");
+ TerrainTexturePack pack =
+ {
+ {
+ Texture_Create2D("resources/textures/soil1.png"),
+ Texture_Create2D("resources/textures/soil2.png"),
+ Texture_Create2D("resources/textures/soil4.png"),
+ Texture_Create2D("resources/textures/soil3.png"),
+ }
+ };
+ game->terrain = Terrain_Create(800, 800, "resources/textures/heightmap.png", blendmap, &pack);
+ game->terrain->position = position;
+ }
+
+ {
+ game->sky.rotation = 0.0f;
+ game->sky.cube = Shape_MakeSkyBox(500.0f);
+ const char *paths[6] =
+ {
+ "resources/textures/right.png",
+ "resources/textures/left.png",
+ "resources/textures/top.png",
+ "resources/textures/bottom.png",
+ "resources/textures/back.png",
+ "resources/textures/front.png"
+ };
+ game->sky.texture = Texture_CreateCubeMap(paths);
+ }
+
+ /* Shader Layouts */
+
+ Shader_Layout *layout = &game->shaderProgram;
+ layout->Texture = Shader_GetUniformLocation(layout->ID, "Texture");
+ layout->modelToWorld = Shader_GetUniformLocation(layout->ID, "M_model");
+ layout->totalTransform = Shader_GetUniformLocation(layout->ID, "M_MVP");
+ layout->lightPosition = Shader_GetUniformLocation(layout->ID, "lightPosition");
+ layout->lightColor = Shader_GetUniformLocation(layout->ID, "lightColor");
+ layout->lightAttenuation = Shader_GetUniformLocation(layout->ID, "attenuation");
+ layout->Normal_Map = Shader_GetUniformLocation(layout->ID, "normalMap");
+
+ layout = &game->terrainProgram;
+ layout->modelToWorld = Shader_GetUniformLocation(layout->ID, "M_model");
+ layout->totalTransform = Shader_GetUniformLocation(layout->ID, "M_MVP");
+ layout->lightPosition = Shader_GetUniformLocation(layout->ID, "lightPosition");
+ layout->lightColor = Shader_GetUniformLocation(layout->ID, "lightColor");
+ layout->lightAttenuation = Shader_GetUniformLocation(layout->ID, "attenuation");
+
+ layout->extra0 = Shader_GetUniformLocation(layout->ID, "Texture_Background");
+ layout->extra1 = Shader_GetUniformLocation(layout->ID, "Texture_R");
+ layout->extra2 = Shader_GetUniformLocation(layout->ID, "Texture_G");
+ layout->extra3 = Shader_GetUniformLocation(layout->ID, "Texture_B");
+ layout->extra4 = Shader_GetUniformLocation(layout->ID, "Texture_BlendMap");
+
+ layout = &game->skyboxProgram;
+ layout->totalTransform = Shader_GetUniformLocation(layout->ID, "M_MVP");
+ layout->Texture = Shader_GetUniformLocation(layout->ID, "cubeMap");
+
+ game->normalMap = Texture_Create2D("resources/textures/normal_map.png");
+ game->defaultNormalMap = Texture_Create2D("resources/textures/default_normal_map.png");
+
+ fprintf(stderr, "Loading time: %u (ms)\n", SDL_GetTicks() - start);
+}
+
+void Draw(game_t *game)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ /*We upload all the light vectors*/
+ static const light_t diffuseLight[1] =
+ {
+ /* Sun Light */
+ { {5.0f, 40.0f, 2.0f}, {1.0f, 1.0f, 1.0f, 1.0f}, {1.0f, 0.0f, 0.0f} },
+ /* Other lights
+ { {10.0f, 20.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {1.0f, 0.01f, 0.002f} },
+ { {20.0f, 20.0f, 0.0f}, {0.0f, 0.0f, 1.0f, 1.0f}, {1.0f, 0.01f, 0.002f} },
+ { {30.0f, 20.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 0.01f, 0.002f} },*/
+ };
+
+ Shader_SetUniformVec3(game->shaderProgram.ID, "World_eyePosition", (float*)&game->camera.position);
+ Render_LoadLights(&game->shaderProgram, diffuseLight, 1);
+
+ glActiveTexture(GL_TEXTURE13);
+ glBindTexture(GL_TEXTURE_2D, game->normalMap);
+
+ glUniform1i(game->shaderProgram.Normal_Map, 13);
+
+ mat4_t viewMatrix, projectedViewMatrix;
+
+ viewMatrix = Camera_GetModelToViewMatrix(&game->camera);
+ projectedViewMatrix = mat4_mul(&game->camera.projectionMatrix, &viewMatrix);
+
+ Render_DrawEntity(&game->shaderProgram, &projectedViewMatrix, &game->player.entity);
+ Render_DrawEntity(&game->shaderProgram, &projectedViewMatrix, &game->ents[0]);
+
+ glUseProgram(game->terrainProgram.ID);
+
+ Shader_SetUniformVec3(game->terrainProgram.ID, "World_eyePosition", (float*)&game->camera.position);
+ Render_LoadLights(&game->terrainProgram, diffuseLight, 1);
+
+ Render_DrawTerrain(&game->terrainProgram, &projectedViewMatrix, game->terrain);
+
+ glUseProgram(game->skyboxProgram.ID);
+ Render_DrawSky(&game->skyboxProgram, &viewMatrix, &game->camera.projectionMatrix, &game->sky);
+
+ glUseProgram(game->shaderProgram.ID);
+
+ Window_Update(game->window);
+}
+
+void ProcessInput(game_t *game)
+{
+ static vec2_t mousePosition;
+ SDL_Event e;
+ while(SDL_PollEvent(&e))
+ {
+ switch(e.type)
+ {
+ case SDL_QUIT:
+ game->gameState = EXIT;
+ break;
+
+ case SDL_MOUSEMOTION:
+ mousePosition.x = (GLfloat) e.motion.x;
+ mousePosition.y = (GLfloat) e.motion.y;
+ Camera_MouseUpdate(&game->camera, &mousePosition);
+ break;
+
+ case SDL_KEYDOWN:
+ Input_PressKey(e.key.keysym.scancode);
+ break;
+
+ case SDL_KEYUP:
+ Input_ReleaseKey(e.key.keysym.scancode);
+ break;
+ }
+
+ if(Input_isKeyPressed(SDL_SCANCODE_UP))
+ Camera_Move_Foward(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_DOWN))
+ Camera_Move_Backward(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_LEFT))
+ Camera_Move_Left(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_RIGHT))
+ Camera_Move_Right(&game->camera);
+
+ if(Input_isKeyPressed(SDL_SCANCODE_ESCAPE))
+ game->gameState = EXIT;
+ }
+}