diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-03-19 08:40:27 +0500 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-03-19 08:40:27 +0500 |
commit | 7890db46928c9f1d4c4652c8dc007370cb897468 (patch) | |
tree | acb39a102bb6ada3bdab6c3e59e82181573f7247 /src | |
parent | 60bd06ced6de9f1272e31da323996db2d8b8a531 (diff) |
some changes and textures
Diffstat (limited to 'src')
-rwxr-xr-x | src/build.sh | 32 | ||||
-rw-r--r-- | src/data/textures/grid.png | bin | 0 -> 10801 bytes | |||
-rw-r--r-- | src/engine/sdl_linux.c | 180 | ||||
-rw-r--r-- | src/game/game.c | 126 | ||||
-rw-r--r-- | src/game/game.h | 17 | ||||
-rw-r--r-- | src/perf.data | bin | 0 -> 110468 bytes | |||
-rwxr-xr-x | src/prge_game_example | bin | 88904 -> 634504 bytes | |||
-rw-r--r-- | src/shaders/default.frag | 10 | ||||
-rw-r--r-- | src/shaders/default.vert | 11 | ||||
-rw-r--r-- | src/shaders/ui.frag | 10 | ||||
-rw-r--r-- | src/shaders/ui.vert | 10 |
11 files changed, 284 insertions, 112 deletions
diff --git a/src/build.sh b/src/build.sh index 9a18dff..1591c14 100755 --- a/src/build.sh +++ b/src/build.sh @@ -1,7 +1,29 @@ #!/bin/sh -CFLAGS='-g -Wall -Wextra' -INCLUDE='-I../lib/prge -I../lib/prb -Igame' -LIBS='-lm -lSDL2 -lGL -lGLEW' -TARGET=prge_game_example + +CFLAGS=' +-g +-Wall +-Wextra +-DSTBI_NO_SIMD +' + +INCLUDE=' +-I../lib +-I../lib/prge +-I../lib/prb +-Igame +' + +LFLAGS='' +LIBS=' +-lm +-lSDL3 +-lGL +-lGLEW +' + +TARGET='prge_game_example' + set -x -gcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS engine/sdl_linux.c $LIBS && ./$TARGET + +time tcc -o $TARGET $CFLAGS $INCLUDE $LFLAGS $LIBS engine/sdl_linux.c && ./$TARGET diff --git a/src/data/textures/grid.png b/src/data/textures/grid.png Binary files differnew file mode 100644 index 0000000..eb951c3 --- /dev/null +++ b/src/data/textures/grid.png diff --git a/src/engine/sdl_linux.c b/src/engine/sdl_linux.c index 76851df..806b718 100644 --- a/src/engine/sdl_linux.c +++ b/src/engine/sdl_linux.c @@ -1,91 +1,101 @@ #include "GL/glew.h" -#include "SDL2/SDL.h" +#include "SDL3/SDL.h" #include "prge.h" #include "game.h" #include "game.c" -void process_mouse_pos(Input *input, S32 x, S32 y) +void process_mouse_pos(Input *input, SDL_MouseMotionEvent *mouseev) { - V2 pos = v2((F32)x, (F32)y); - if (input->first_mouse) { - input->mouse_pos = pos; + V2 offset; + + input->mouse_pos = v2((F32)mouseev->x, (F32)mouseev->y); + + if (input->first_mouse) input->first_mouse = 0; - } - input->last_mouse_pos = input->mouse_pos; - input->mouse_pos = pos; - input->mouse_offset = v2sub(input->mouse_pos, - input->last_mouse_pos); -} -void process_window_resize() -{ + offset = v2((F32)mouseev->xrel, (F32)mouseev->yrel); + input->mouse_offset = v2add(input->mouse_offset, offset); } -void process_key(U8 state, Key *key) +void process_key(B32 down, Key *key) { - key->state = (state == SDL_PRESSED) ? KeyState_PRESS : KeyState_RELEASE; + key->state = (down ? KeyState_PRESS : KeyState_RELEASE); } -void process_keyboard(Input *input, SDL_KeyboardEvent *key) +void process_keyboard(Input *input, SDL_KeyboardEvent *keyev) { - switch (key->keysym.scancode) { + switch (keyev->scancode) { case SDL_SCANCODE_D: - process_key(key->state, &input->move_right); + process_key(keyev->down, &input->move_right); break; case SDL_SCANCODE_W: - process_key(key->state, &input->move_forward); + process_key(keyev->down, &input->move_forward); break; case SDL_SCANCODE_A: - process_key(key->state, &input->move_left); + process_key(keyev->down, &input->move_left); break; case SDL_SCANCODE_S: - process_key(key->state, &input->move_backward); + process_key(keyev->down, &input->move_backward); break; case SDL_SCANCODE_E: - process_key(key->state, &input->move_up); + process_key(keyev->down, &input->move_up); break; case SDL_SCANCODE_Q: - process_key(key->state, &input->move_down); + process_key(keyev->down, &input->move_down); break; case SDL_SCANCODE_SPACE: - process_key(key->state, &input->jump); + process_key(keyev->down, &input->jump); break; case SDL_SCANCODE_RIGHT: - process_key(key->state, &input->action_right); + process_key(keyev->down, &input->action_right); break; case SDL_SCANCODE_UP: - process_key(key->state, &input->action_up); + process_key(keyev->down, &input->action_up); break; case SDL_SCANCODE_LEFT: - process_key(key->state, &input->action_left); + process_key(keyev->down, &input->action_left); break; case SDL_SCANCODE_DOWN: - process_key(key->state, &input->action_down); + process_key(keyev->down, &input->action_down); break; case SDL_SCANCODE_ESCAPE: - process_key(key->state, &input->exit); + process_key(keyev->down, &input->exit); break; default: break; } } -void handle_events(Input *input) +void process_mouse_buttons(Input *input, SDL_MouseButtonEvent *buttonev) { - SDL_Event event; + if (buttonev->button == SDL_BUTTON_LEFT) + process_key(buttonev->down, &input->mouse_left); + else if (buttonev->button == SDL_BUTTON_RIGHT) + process_key(buttonev->down, &input->mouse_right); +} + +void handle_events(Window *wnd, Input *input) +{ + SDL_Event event; + while (SDL_PollEvent(&event)) { switch (event.type) { - case SDL_KEYDOWN: - case SDL_KEYUP: + case SDL_EVENT_KEY_DOWN: + case SDL_EVENT_KEY_UP: process_keyboard(input, &event.key); break; - case SDL_MOUSEMOTION: - process_mouse_pos(input, event.motion.x, event.motion.y); + case SDL_EVENT_MOUSE_MOTION: + process_mouse_pos(input, &event.motion); + break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + case SDL_EVENT_MOUSE_BUTTON_UP: + process_mouse_buttons(input, &event.button); break; - case SDL_WINDOWEVENT_RESIZED: - process_window_resize(); + case SDL_EVENT_WINDOW_RESIZED: + wnd->width = event.window.data1; + wnd->height = event.window.data2; break; default: break; @@ -95,65 +105,73 @@ void handle_events(Input *input) F32 get_elapsed_seconds(U64 cur, U64 last) { - F32 result = ((F32)cur-(F32)last)/1000.0f; - return result; + F32 res; + res = ((F32)cur-(F32)last)/1000.0f; + return res; } F32 lock_framerate(U64 last, F32 target) { - F32 target_mspf = 1000.0f/target; + F32 target_mspf, elapsed, sleep, dt; - F32 elapsed = get_elapsed_seconds(SDL_GetTicks64(), last)*1000.0f; + elapsed = get_elapsed_seconds(SDL_GetTicks(), last)*1000.0f; + target_mspf = 1000.0f/target; if (elapsed < target_mspf) { - /* F32 sleep = target_mspf-elapsed-1.0f; */ - F32 sleep = target_mspf-elapsed; + sleep = target_mspf-elapsed; if (sleep > 0.0f) SDL_Delay(sleep); /* do { - elapsed = get_elapsed_seconds(SDL_GetTicks64(), last)*1000.0f; + elapsed = get_elapsed_seconds(SDL_GetTicks(), last)*1000.0f; } while (elapsed < target_mspf); */ } - F32 dt = get_elapsed_seconds(SDL_GetTicks64(), last); + dt = get_elapsed_seconds(SDL_GetTicks(), last); return dt; } -B32 sdl_init(S32 width, S32 height, - SDL_Window **window, - SDL_GLContext **context) +B32 sdl_init(Window *wnd, SDL_Window **sdl_window, SDL_GLContext *context) { - if (SDL_Init(SDL_INIT_VIDEO)) { + U32 flags; + GLenum error; + Arena *tmpar; + char *wname; + + if (!SDL_Init(SDL_INIT_VIDEO)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, - SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + + tmpar = arena_alloc(0); + wname = str8tocstr(tmpar, wnd->name); + + flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; - U32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE; - (*window) = SDL_CreateWindow("prge game example", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - width, height, flags); + (*sdl_window) = SDL_CreateWindow(wname, wnd->width, wnd->height, flags); + + arena_release(tmpar); - if (!(*window)) { + if (!(*sdl_window)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } - (*context) = SDL_GL_CreateContext((*window)); + SDL_GetWindowSize(*sdl_window, &wnd->width, &wnd->height); + + (*context) = SDL_GL_CreateContext((*sdl_window)); if (!(*context)) { SDL_Log("[ERROR] : SDL : %s\n", SDL_GetError()); return 0; } - GLenum error = glewInit(); + error = glewInit(); if (error != GLEW_OK) { SDL_Log("[ERROR] : GLEW : %s\n", glewGetErrorString(error)); return 0; @@ -165,39 +183,51 @@ B32 sdl_init(S32 width, S32 height, int main(void) { /* NOTE(pryazha): Engine init */ - Input input = input_init(); - S32 width = 800, height = 600; + Input input; + Window wnd; + + input = input_init(); + wnd = window_init(800, 600, str8lit("PRGE example")); - /* NOTE(pryazha): SDL init */ - SDL_Window *window; - SDL_GLContext *context; - if (!sdl_init(width, height, &window, &context)) { + /* NOTE(pryazha): SDL and OpenGL init */ + SDL_Window *sdl_window; + SDL_GLContext context; + U64 last; + + if (!sdl_init(&wnd, &sdl_window, &context)) { SDL_Quit(); return 1; } + glEnable(GL_DEPTH_TEST); + /* NOTE(pryazha): Game init */ - State state = {0}; - game_init(&state); + State state; + MemoryZero(&state, sizeof(State)); + + init(&state); + + last = SDL_GetTicks(); - U64 last = SDL_GetTicks64(); while (input.is_running) { - handle_events(&input); + SDL_SetWindowRelativeMouseMode(sdl_window, input.capture_mouse); + + handle_events(&wnd, &input); input.dt = lock_framerate(last, 60.0f); - last = SDL_GetTicks64(); + last = SDL_GetTicks(); - game_update_and_render(&state, &input); + update_and_render(&wnd, &state, &input); input_update(&input); - SDL_GL_SwapWindow(window); + SDL_GL_SwapWindow(sdl_window); } - game_clear(&state); + clear(&state); - SDL_GL_DeleteContext(context); - SDL_DestroyWindow(window); + SDL_GL_DestroyContext(context); + SDL_DestroyWindow(sdl_window); SDL_Quit(); return 0; } diff --git a/src/game/game.c b/src/game/game.c index 25c71fa..47d70eb 100644 --- a/src/game/game.c +++ b/src/game/game.c @@ -1,41 +1,117 @@ -void game_init(State *state) +void init(State *state) { - U64 persistent_size = Megabytes(1); - state->persistent_arena = arena_alloc(persistent_size); - state->shader = create_shader_program(str8lit("shaders/default.vert"), - str8lit("shaders/default.frag")); - Vertex verts[] = { - vertex(v3(-0.5f, -0.5f, 0.0f)), - vertex(v3(0.0f, 0.5f, 0.0f)), - vertex(v3(0.5f, -0.5f, 0.0f)) - }; - - U32 indices[] = { 0, 1, 2 }; - - state->the_mesh = mesh(state->persistent_arena, verts, ArrayCount(verts), indices, ArrayCount(indices)); + U32 nmeshes; + Mesh *meshes; + + state->parena = arena_alloc(Kilobytes(256)); + + state->camera = camera_init(v3(0.0f, 0.0f, 3.0f), + 90.0f, 0.1f, 100.0f, + 0.0f, 0.0f, 0.0f); + state->camera_dp = V3_ZERO; + + state->mesh_shader = load_shader("shaders/default.vert", 0, "shaders/default.frag"); + state->ui_shader = load_shader("shaders/ui.vert", 0, "shaders/ui.frag"); + + state->texture = load_texture(state->parena, str8lit("data/textures/grid.png"), 0); + + nmeshes = 2; + meshes = arena_push(state->parena, nmeshes*sizeof(Mesh)); + meshes[0] = *mesh_gen_circle(state->parena, v3(0.0f, 0.0f, 2.0f), V3_ZERO, 3.0f, 6); + meshes[1] = *mesh_gen_quad(state->parena, V3_ZERO, v3(0.0f, 90.0f, 0.0f), 2.0f, 2.0f); + + mesh_add_texture(&meshes[0], state->texture); + + state->model = model_init(state->parena, V3_ZERO, V3_ZERO, meshes, nmeshes); } -void game_update_and_render(State *state, Input *input) +void update_camera_first_person(State *state, Input *input, F32 speed, F32 mouse_sens) +{ + V3 ddp, r, u, f; + + camera_get_vectors_first_person(&state->camera, &r, &u, &f); + ddp = V3_ZERO; + if (key_is_pressed(input->move_forward)) + ddp = v3add(ddp, v3inv(f)); + if (key_is_pressed(input->move_backward)) + ddp = v3add(ddp, f); + if (key_is_pressed(input->move_right)) + ddp = v3add(ddp, r); + if (key_is_pressed(input->move_left)) + ddp = v3add(ddp, v3inv(r)); + if (key_is_pressed(input->move_up)) + ddp = v3add(ddp, u); + if (key_is_pressed(input->move_down)) + ddp = v3add(ddp, v3inv(u)); + ddp = v3norm(ddp); + + state->camera.pos = v3add(state->camera.pos, state->camera_dp); + state->camera_dp = v3scalef(v3add(state->camera_dp, v3scalef(ddp, input->dt*speed)), 0.8f); + + /* NOTE(pryazha): Camera angles */ + if (input->capture_mouse) { + state->camera.yaw += input->mouse_offset.x*mouse_sens; + state->camera.pitch += input->mouse_offset.y*mouse_sens; + if (state->camera.pitch > 89.0f) + state->camera.pitch = 89.0f; + if (state->camera.pitch < -89.0f) + state->camera.pitch = -89.0f; + } +} + +void update_and_render(Window *wnd, State *state, Input *input) { /* NOTE(pryazha): Update */ - if (key_is_pressed(input->exit)) - input->is_running = 0; + if (key_first_press(input->exit)) { + if (input->capture_mouse) { + input->capture_mouse = 0; + } else { + input->is_running = 0; + } + } + + /* NOTE(pryazha): Camera movement */ + update_camera_first_person(state, input, 1.0f, 0.3f); + + state->model->rotate.z += 20.0f*input->dt; + state->model->rotate.x += 20.0f*input->dt; /* NOTE(pryazha): Render */ + MAT4 proj, view; + F32 ar; + Arena *ui_arena; + + glViewport(0, 0, wnd->width, wnd->height); + glClearColor(0.15f, 0.15f, 0.15f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + + ar = (F32)wnd->width/(F32)wnd->height; + proj = camera_persp(state->camera, ar); + view = camera_get_view_matrix_first_person(&state->camera); + + model_draw(state->mesh_shader, &proj, &view, state->model); + + glUseProgram(state->ui_shader); + proj = ortho(0.0f, (F32)wnd->width, 0.0f, (F32)wnd->height, -1.0f, 1.0f); + shader_set_mat4fv(state->ui_shader, "proj", proj); + ui_arena = arena_alloc(0); + glDisable(GL_DEPTH_TEST); + + if (button(wnd, state->ui_shader, input, ui_arena, str8lit("some name"), + v2(wnd->width/8.0f, wnd->height/8.0f), 50.0f, 30.0f)) + { + input->capture_mouse = 1; + } - glUseProgram(state->shader); - F32 angle = 20.0f*state->t; - Mat4 model = mat4rotate(MAT4_IDENTITY, v3(0.0f, 0.0f, angle)); - shader_set_mat4fv(state->shader, "model", model); - mesh_draw(*state->the_mesh); + glEnable(GL_DEPTH_TEST); glUseProgram(0); + arena_release(ui_arena); state->t += input->dt; } -void game_clear(State *state) +void clear(State *state) { - arena_release(state->persistent_arena); + arena_release(state->parena); } diff --git a/src/game/game.h b/src/game/game.h index b37798d..bd98e7e 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -2,10 +2,19 @@ #define GAME_H typedef struct { - Arena *persistent_arena; - U32 shader; - Mesh *the_mesh; - F32 t; + Arena *parena; + + Texture texture; + + Camera camera; + V3 camera_dp; + + Model *model; + + U32 mesh_shader; + U32 ui_shader; + + F32 t; } State; #endif /* GAME_H */ diff --git a/src/perf.data b/src/perf.data Binary files differnew file mode 100644 index 0000000..deca599 --- /dev/null +++ b/src/perf.data diff --git a/src/prge_game_example b/src/prge_game_example Binary files differindex bbf178d..0d82072 100755 --- a/src/prge_game_example +++ b/src/prge_game_example diff --git a/src/shaders/default.frag b/src/shaders/default.frag index 9a5018d..d5d37c7 100644 --- a/src/shaders/default.frag +++ b/src/shaders/default.frag @@ -1,8 +1,14 @@ #version 330 core -out vec4 frag_color; +in VSOUT { + vec2 texc; +} vsout; + +out vec4 fcolor; + +uniform sampler2D tex0; void main(void) { - frag_color = vec4(1.0); + fcolor = texture(tex0, vsout.texc); } diff --git a/src/shaders/default.vert b/src/shaders/default.vert index 637c7c1..a7b5e08 100644 --- a/src/shaders/default.vert +++ b/src/shaders/default.vert @@ -1,9 +1,18 @@ #version 330 core layout(location = 0) in vec3 apos; +layout(location = 1) in vec2 atexc; +out VSOUT { + vec2 texc; +} vsout; + +uniform mat4 proj; +uniform mat4 view; uniform mat4 model; void main(void) { - gl_Position = model*vec4(apos, 1.0); + vsout.texc = atexc; + + gl_Position = proj*view*model*vec4(apos, 1.0); } diff --git a/src/shaders/ui.frag b/src/shaders/ui.frag new file mode 100644 index 0000000..bd0bc85 --- /dev/null +++ b/src/shaders/ui.frag @@ -0,0 +1,10 @@ +#version 330 core + +out vec4 fcolor; + +uniform vec4 color; + +void main(void) +{ + fcolor = color; +} diff --git a/src/shaders/ui.vert b/src/shaders/ui.vert new file mode 100644 index 0000000..ad5d46a --- /dev/null +++ b/src/shaders/ui.vert @@ -0,0 +1,10 @@ +#version 330 core +layout(location = 0) in vec3 apos; + +uniform mat4 proj; +uniform mat4 model; + +void main(void) +{ + gl_Position = proj*model*vec4(apos, 1.0); +} |