diff options
Diffstat (limited to '08-august/src/main.c')
| -rw-r--r-- | 08-august/src/main.c | 290 |
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; + } +} |
