231 lines
5.4 KiB
C
231 lines
5.4 KiB
C
#define SDL_MAIN_USE_CALLBACKS 1
|
|
#include <SDL3/SDL.h>
|
|
#include <SDL3/SDL_main.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "chunk/chunkmesh.h"
|
|
#include "state.h"
|
|
#include "flags.h"
|
|
#include "camera.h"
|
|
#include "mesh.h"
|
|
#include "resources.h"
|
|
|
|
/* TODO: switch back to cglm.h, since it's faster or something */
|
|
|
|
static SDL_Window *window = NULL;
|
|
static SDL_GLContext context = NULL;
|
|
|
|
extern GameState game_state;
|
|
extern GameFlags game_flags;
|
|
extern Resources resources;
|
|
|
|
static ChunkMesh test_chunkmesh;
|
|
static Camera camera;
|
|
|
|
SDL_AppResult
|
|
SDL_AppInit (void **appstate, int argc, char **argv)
|
|
{
|
|
(void) appstate; (void) argc; (void) argv;
|
|
|
|
SDL_SetAppMetadata (GAME_NAME, GAME_VERSION, "eur.chopininteractive.wschod-game");
|
|
|
|
if (!SDL_Init (SDL_INIT_VIDEO))
|
|
{
|
|
FATAL ("Couldn't initialize SDL: %s", SDL_GetError ());
|
|
}
|
|
|
|
window = SDL_CreateWindow (GAME_NAME, 640, 480, SDL_WINDOW_OPENGL);
|
|
|
|
if (!window)
|
|
{
|
|
FATAL ("Couldn't create window: %s", SDL_GetError ());
|
|
}
|
|
|
|
/* We use OpenGL ES 2.0. It should support everything, and it's more
|
|
than enough for the game. */
|
|
SDL_GL_SetAttribute (SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
|
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
|
SDL_GL_SetAttribute (SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
|
|
|
context = SDL_GL_CreateContext (window);
|
|
|
|
if (!context)
|
|
{
|
|
FATAL ("Couldn't create OpenGL context: %s", SDL_GetError ());
|
|
}
|
|
|
|
SDL_GL_MakeCurrent (window, context);
|
|
SDL_SetWindowRelativeMouseMode (window, true);
|
|
|
|
INFO ("Renderer: %s", glGetString (GL_RENDERER));
|
|
INFO ("OpenGL version: %s", glGetString (GL_VERSION));
|
|
INFO ("GLSL version: %s", glGetString (GL_SHADING_LANGUAGE_VERSION));
|
|
INFO ("Max vertex attributes: %d", GL_MAX_VERTEX_ATTRIBS);
|
|
|
|
glViewport(0, 0, 640, 480);
|
|
glClearColor (0, 0.3, 0.8, 1);
|
|
|
|
glEnable (GL_CULL_FACE);
|
|
glEnable (GL_DEPTH_TEST);
|
|
|
|
/* Initialize and load resources. */
|
|
Resources_init ();
|
|
noise_seed (1337);
|
|
|
|
/* Generate a test chunk. */
|
|
Chunk chunk = Chunk_new ();
|
|
Chunk_noise (&chunk, 0, 0);
|
|
test_chunkmesh = ChunkMesh_from_Chunk_and_neighbors (&chunk, NULL, NULL, NULL);
|
|
|
|
program_use (resources.programs[1]);
|
|
int arr[4] = { 0, 1, 2, 3 };
|
|
program_set_int_array (resources.programs[1], "materials", 4, arr);
|
|
|
|
/* Set up game state. */
|
|
game_state.last_time = SDL_GetTicks ();
|
|
|
|
/* Set some basic game flags for testing. */
|
|
game_flags.can_free_look = 1;
|
|
game_flags.wireframe_enabled = 0;
|
|
|
|
/* Initialize the default camera. */
|
|
camera = Camera_default ();
|
|
camera.position.z = -1.0;
|
|
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
SDL_AppResult
|
|
SDL_AppEvent (void *appstate, SDL_Event *event)
|
|
{
|
|
(void) appstate;
|
|
|
|
if (event->type == SDL_EVENT_QUIT)
|
|
{
|
|
return SDL_APP_SUCCESS;
|
|
}
|
|
|
|
if (event->type == SDL_EVENT_MOUSE_MOTION && game_flags.can_free_look)
|
|
{
|
|
camera.rotation.x -= event->motion.xrel / 100.f;
|
|
camera.rotation.y -= event->motion.yrel / 100.f;
|
|
camera.rotation.y =
|
|
CLAMP (camera.rotation.y, -M_PI / 2 + 0.025, M_PI / 2 - 0.025);
|
|
}
|
|
|
|
if (event->type == SDL_EVENT_KEY_DOWN)
|
|
{
|
|
switch (event->key.key)
|
|
{
|
|
case SDLK_W:
|
|
game_flags.moving_forward = 1;
|
|
break;
|
|
case SDLK_A:
|
|
game_flags.moving_left = 1;
|
|
break;
|
|
case SDLK_S:
|
|
game_flags.moving_backward = 1;
|
|
break;
|
|
case SDLK_D:
|
|
game_flags.moving_right = 1;
|
|
break;
|
|
case SDLK_F1:
|
|
game_flags.wireframe_enabled = !game_flags.wireframe_enabled;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (event->type == SDL_EVENT_KEY_UP)
|
|
{
|
|
switch (event->key.key)
|
|
{
|
|
case SDLK_W:
|
|
game_flags.moving_forward = 0;
|
|
break;
|
|
case SDLK_A:
|
|
game_flags.moving_left = 0;
|
|
break;
|
|
case SDLK_S:
|
|
game_flags.moving_backward = 0;
|
|
break;
|
|
case SDLK_D:
|
|
game_flags.moving_right = 0;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
SDL_AppResult
|
|
SDL_AppIterate (void *appstate)
|
|
{
|
|
(void) appstate;
|
|
|
|
/* Caluclate stuff per frame. */
|
|
int now = SDL_GetTicks ();
|
|
game_state.delta_time = (now - game_state.last_time) / 1000.0;
|
|
game_state.last_time = now;
|
|
|
|
if (game_flags.moving_forward)
|
|
{
|
|
camera.position = v3_add
|
|
(camera.position, v3_muls
|
|
(Camera_get_direction (&camera), game_state.delta_time));
|
|
}
|
|
|
|
if (game_flags.moving_backward)
|
|
{
|
|
camera.position = v3_sub
|
|
(camera.position, v3_muls
|
|
(Camera_get_direction (&camera), game_state.delta_time));
|
|
}
|
|
|
|
if (game_flags.moving_right)
|
|
{
|
|
camera.position = v3_add
|
|
(camera.position, v3_muls
|
|
(Camera_get_right (&camera), game_state.delta_time));
|
|
}
|
|
|
|
if (game_flags.moving_left)
|
|
{
|
|
camera.position = v3_sub
|
|
(camera.position, v3_muls
|
|
(Camera_get_right (&camera), game_state.delta_time));
|
|
}
|
|
|
|
/* Render stuff. */
|
|
|
|
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
|
|
|
mat4_t view = Camera_get_view (&camera);
|
|
mat4_t projection = Camera_get_projection (&camera, 640.0 / 480.0);
|
|
|
|
program_use (resources.programs[1]);
|
|
|
|
for (size_t i = 0; i < resources.textures_len; ++i)
|
|
{
|
|
glActiveTexture (GL_TEXTURE0 + i);
|
|
glBindTexture (GL_TEXTURE_2D, resources.textures[i]);
|
|
}
|
|
|
|
program_set_mat4 (resources.programs[1], "view", view);
|
|
program_set_mat4 (resources.programs[1], "projection", projection);
|
|
ChunkMesh_render (&test_chunkmesh);
|
|
|
|
SDL_GL_SwapWindow (window);
|
|
|
|
return SDL_APP_CONTINUE;
|
|
}
|
|
|
|
void
|
|
SDL_AppQuit (void *appstate, SDL_AppResult result)
|
|
{
|
|
(void) appstate; (void) result;
|
|
Resources_free ();
|
|
SDL_GL_DestroyContext (context);
|
|
SDL_DestroyWindow (window);
|
|
}
|