Techneck/code/source-c/main.c

326 lines
9.9 KiB
C

#include <state.h>
#include <utility/math.h>
#include <glad/glad.h>
#include <SDL2/SDL.h>
#include <linmath.h>
void tc_move_viewer_to(float x, float y, float z)
{
if(tc_game_state_g.viewer == NULL) return;
tc_set_float_for_entity(tc_game_state_g.viewer, "pos_x", x);
tc_set_float_for_entity(tc_game_state_g.viewer, "pos_y", y);
tc_set_float_for_entity(tc_game_state_g.viewer, "pos_z", z);
}
void tc_rotate_viewer_to(float x, float y, float z)
{
if(tc_game_state_g.viewer == NULL) return;
tc_set_float_for_entity(tc_game_state_g.viewer, "rot_x", x);
tc_set_float_for_entity(tc_game_state_g.viewer, "rot_y", y);
tc_set_float_for_entity(tc_game_state_g.viewer, "rot_z", z);
}
void tc_get_viewer_position(float *x, float *y, float *z)
{
if(tc_game_state_g.viewer == NULL) return;
if(x != NULL) (*x) = tc_get_float_from_entity(tc_game_state_g.viewer, "pos_x");
if(y != NULL) (*y) = tc_get_float_from_entity(tc_game_state_g.viewer, "pos_y");
if(z != NULL) (*z) = tc_get_float_from_entity(tc_game_state_g.viewer, "pos_z");
}
void tc_get_viewer_rotation(float *x, float *y, float *z)
{
if(tc_game_state_g.viewer == NULL) return;
if(x != NULL) (*x) = tc_get_float_from_entity(tc_game_state_g.viewer, "rot_x");
if(y != NULL) (*y) = tc_get_float_from_entity(tc_game_state_g.viewer, "rot_y");
if(z != NULL) (*z) = tc_get_float_from_entity(tc_game_state_g.viewer, "rot_z");
}
void render()
{
float color[4] = { 0.12f, 0.5f, 0.8f, 1.0f };
glClearBufferfv(GL_COLOR, 0, color);
float depth = 1000.0f;
glClearBufferfv(GL_DEPTH, 0, &depth);
int fb_width = 0;
int fb_height = 0;
SDL_GetWindowSize(tc_game_state_g.renderer.window, &fb_width, &fb_height);
glViewport(0, 0, fb_width, fb_height);
tc_vec3f_s camera_rotation;
tc_vec3f_s camera_position;
tc_get_viewer_rotation(&camera_rotation.x, &camera_rotation.y, &camera_rotation.z);
tc_get_viewer_position(&camera_position.x, &camera_position.y, &camera_position.z);
tc_vec3f_s camera_offset;
camera_offset.z = camera_position.z;
camera_offset.y = -camera_position.y;
camera_offset.x = -camera_position.x;
tc_mat4f_s view_matrix = tc_mat4f_identity();
tc_mat4f_s projection_matrix =
tc_mat4f_perspective(120,
((float) fb_width) / ((float) fb_height),
0.0001f, 1000.0f
);
view_matrix = tc_mat4f_translate(view_matrix, camera_offset);
view_matrix = tc_mat4_rotate_z(view_matrix, tc_deg_to_rad(camera_rotation.z));
view_matrix = tc_mat4_rotate_y(view_matrix, tc_deg_to_rad(camera_rotation.y));
view_matrix = tc_mat4_rotate_x(view_matrix, tc_deg_to_rad(camera_rotation.x));
glUseProgram(tc_game_state_g.renderer.draw_shader.program_id);
tc_shader_uniform_mat4f(&tc_game_state_g.renderer.draw_shader, "projection_matrix", projection_matrix);
tc_shader_uniform_mat4f(&tc_game_state_g.renderer.draw_shader, "view_matrix", view_matrix);
tc_draw_world(tc_game_state_g.main_world);
SDL_GL_SwapWindow(tc_game_state_g.renderer.window);
}
bool shift_pressed = false;
bool go_up = false;
bool go_left = false;
bool go_right = false;
bool go_forward = false;
bool go_backwards = false;
bool rotate_left = false;
bool rotate_right = false;
uint64_t tc_last_update = 0;
bool update()
{
tc_vec3f_s camera_rotation;
tc_get_viewer_rotation(&camera_rotation.x, &camera_rotation.y, &camera_rotation.z);
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_QUIT:
SDL_HideWindow(tc_game_state_g.renderer.window);
return false;
break;
case SDL_WINDOWEVENT:
{
if(event.window.event == SDL_WINDOWEVENT_RESIZED)
{
}
} break;
case SDL_KEYDOWN:
if(event.key.keysym.scancode == SDL_SCANCODE_Q)
{
rotate_left = true;
}
if(event.key.keysym.scancode == SDL_SCANCODE_E)
{
rotate_right = true;
}
if(event.key.keysym.scancode == SDL_SCANCODE_W)
{
go_forward = true;
}
if(event.key.keysym.scancode == SDL_SCANCODE_S)
{
go_backwards = true;
}
if(event.key.keysym.scancode == SDL_SCANCODE_A)
{
go_left = true;
}
if(event.key.keysym.scancode == SDL_SCANCODE_D)
{
go_right = true;;
}
if(event.key.keysym.scancode == SDL_SCANCODE_SPACE)
{
go_up = true;
}
if(event.key.keysym.scancode == SDL_SCANCODE_LSHIFT)
{
shift_pressed = true;
}
break;
case SDL_KEYUP:
if(event.key.keysym.scancode == SDL_SCANCODE_Q)
{
rotate_left = false;
}
if(event.key.keysym.scancode == SDL_SCANCODE_E)
{
rotate_right = false;
}
if(event.key.keysym.scancode == SDL_SCANCODE_W)
{
go_forward = false;
}
if(event.key.keysym.scancode == SDL_SCANCODE_S)
{
go_backwards = false;
}
if(event.key.keysym.scancode == SDL_SCANCODE_A)
{
go_left = false;
}
if(event.key.keysym.scancode == SDL_SCANCODE_D)
{
go_right = false;;
}
if(event.key.keysym.scancode == SDL_SCANCODE_SPACE)
{
go_up = false;
}
if(event.key.keysym.scancode == SDL_SCANCODE_LSHIFT)
{
shift_pressed = false;
}
break;
case SDL_MOUSEMOTION:
{
if(!(event.motion.state & SDL_BUTTON_LMASK)) break;
camera_rotation.y += event.motion.xrel / 10.0f;
camera_rotation.x += event.motion.yrel / 10.0f;
if(camera_rotation.x > 90)
camera_rotation.x = 90;
if(camera_rotation.x < -90)
camera_rotation.x = -90;
} break;
}
}
tc_vec3f_s camera_position;
tc_get_viewer_position(&camera_position.x, &camera_position.y, &camera_position.z);
if(shift_pressed)
{
camera_position.y -= 0.25;
}
if(go_up)
{
camera_position.y += 0.25;
}
tc_vec3f_s difference_in_perspective;
difference_in_perspective.x = 0.0f;
difference_in_perspective.y = 0.0f;
difference_in_perspective.z = 0.0f;
if(go_left)
{
difference_in_perspective.x -= 0.45f;
}
if(go_right)
{
difference_in_perspective.x += 0.45f;
}
if(go_forward)
{
difference_in_perspective.z += 0.4f;
}
if(go_backwards)
{
difference_in_perspective.z -= 0.4f;
}
mat4x4 position_matrix;
mat4x4_identity(position_matrix);
mat4x4_translate(position_matrix, difference_in_perspective.x, 0.0f, difference_in_perspective.z);
mat4x4_rotate_Z(position_matrix, position_matrix, tc_deg_to_rad(camera_rotation.z));
mat4x4_rotate_Y(position_matrix, position_matrix, tc_deg_to_rad(camera_rotation.y));
mat4x4_rotate_X(position_matrix, position_matrix, tc_deg_to_rad(camera_rotation.x));
vec4 viewed_difference = { difference_in_perspective.x, 0.0f, difference_in_perspective.z };
vec4 raw_difference = { 0.0f, 0.0f, 0.0f };
mat4x4_mul_vec4(raw_difference, position_matrix, viewed_difference);
camera_position.x += raw_difference[0];
camera_position.z += raw_difference[2];
tc_move_viewer_to(camera_position.x, camera_position.y, camera_position.z);
tc_rotate_viewer_to(camera_rotation.x, camera_rotation.y, camera_rotation.z);
tc_game_state_g.main_world->spawn_loader->center.x = ((int32_t) camera_position.x) / 32 - UPDATE_DISTANCE;
tc_game_state_g.main_world->spawn_loader->center.y = ((int32_t) camera_position.y) / 32 - UPDATE_DISTANCE;
tc_game_state_g.main_world->spawn_loader->center.z = - ((int32_t) camera_position.z) / 32 - UPDATE_DISTANCE;
tc_update_world(tc_game_state_g.main_world);
return true;
}
int main(int argc, char **argv)
{
tc_init();
int64_t frame_index = 1;
while(frame_index > 0)
{
if(!update())
{
frame_index = -1;
}
tc_tick_intervals();
render();
if(frame_index == 1)
{
SDL_ShowWindow(tc_game_state_g.renderer.window);
}
++frame_index;
SDL_Delay(2);
}
tc_cleanup();
SDL_Quit();
return 0;
}