summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpryazha <pryadeiniv@mail.ru>2025-03-19 08:40:27 +0500
committerpryazha <pryadeiniv@mail.ru>2025-03-19 08:40:27 +0500
commit7890db46928c9f1d4c4652c8dc007370cb897468 (patch)
treeacb39a102bb6ada3bdab6c3e59e82181573f7247 /src
parent60bd06ced6de9f1272e31da323996db2d8b8a531 (diff)
some changes and textures
Diffstat (limited to 'src')
-rwxr-xr-xsrc/build.sh32
-rw-r--r--src/data/textures/grid.pngbin0 -> 10801 bytes
-rw-r--r--src/engine/sdl_linux.c180
-rw-r--r--src/game/game.c126
-rw-r--r--src/game/game.h17
-rw-r--r--src/perf.databin0 -> 110468 bytes
-rwxr-xr-xsrc/prge_game_examplebin88904 -> 634504 bytes
-rw-r--r--src/shaders/default.frag10
-rw-r--r--src/shaders/default.vert11
-rw-r--r--src/shaders/ui.frag10
-rw-r--r--src/shaders/ui.vert10
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
new file mode 100644
index 0000000..eb951c3
--- /dev/null
+++ b/src/data/textures/grid.png
Binary files differ
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
new file mode 100644
index 0000000..deca599
--- /dev/null
+++ b/src/perf.data
Binary files differ
diff --git a/src/prge_game_example b/src/prge_game_example
index bbf178d..0d82072 100755
--- a/src/prge_game_example
+++ b/src/prge_game_example
Binary files differ
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);
+}