summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authortalha <talha@talhaamir.xyz>2025-12-29 13:45:53 +0500
committertalha <talha@talhaamir.xyz>2025-12-29 13:45:53 +0500
commit9044db4794e95ef9dbc2d5bfde4215ddc82d6ae8 (patch)
treea63784ac600579006a650c49f30d6d2f94b6905f /source
parent0b3d69976819219e71350b6a988d1704fd5f0746 (diff)
added 2d "meshes"HEADmain
Diffstat (limited to 'source')
-rw-r--r--source/calcify.h42
-rw-r--r--source/core.h4
-rw-r--r--source/game/game.cpp144
-rw-r--r--source/game/game.h22
-rw-r--r--source/sdlmain.cpp187
5 files changed, 317 insertions, 82 deletions
diff --git a/source/calcify.h b/source/calcify.h
index d0c3499..0814df7 100644
--- a/source/calcify.h
+++ b/source/calcify.h
@@ -22,6 +22,15 @@ typedef int8_t b8;
#define ABS(x) ((x) > 0 ? (x) : -(x))
#define MIN(x, y) ((x) < (y) ? (y) : (x))
#define MAX(x, y) ((x) > (y) ? (y) : (x))
+#define CLAMP(x, lo, hi) ((x) <= (lo) ? (lo) : ((x) >= (hi) ? (hi) : (x)))
+
+union Vec2 {
+ struct {
+ r32 x;
+ r32 y;
+ };
+ r32 buffer[2];
+};
union Vec3 {
struct {
@@ -53,6 +62,7 @@ union Mat4 {
r32 buffer[16];
};
+Vec3 calcify_normalize3v(Vec3 v);
Mat4 calcify_init4m(void);
Mat4 calcify_ident4m(void);
Mat4 calcify_multiply4mv(Mat4 a, Mat4 b);
@@ -60,6 +70,14 @@ Mat4 calcify_multiply4m(Mat4 a, Mat4 b);
Mat4 calcify_translation_matrix4m(r32 x, r32 y, r32 z);
Mat4 calcify_ortho4m(r32 left, r32 right, r32 top, r32 bot, r32 near, r32 far);
+Vec3 calcify_normalize3v(Vec3 v) {
+ Vec3 res = {};
+ r32 len = sqrt((v.x*v.x) + (v.y*v.y) + (v.z*v.z));
+ res = (Vec3){v.x/len, v.y/len, v.z/len};
+
+ return res;
+}
+
Mat4 calcify_init4m(void) {
Mat4 res;
memset(&res, 0, sizeof(Mat4));
@@ -132,6 +150,30 @@ Mat4 calcify_scaling_matrix4m(r32 x, r32 y) {
return scale;
}
+Mat4 calcify_rotation_matrix4m(r32 angle_radians, Vec3 axis)
+{
+ Mat4 res = calcify_ident4m();
+ axis = calcify_normalize3v(axis);
+
+ r32 cos_theta = cosf(angle_radians);
+ r32 sin_theta = sinf(angle_radians);
+ r32 cos_value = 1.0f - cos_theta;
+
+ res.array[0][0] = (axis.x * axis.x * cos_value) + cos_theta;
+ res.array[0][1] = (axis.x * axis.y * cos_value) + (axis.z * sin_theta);
+ res.array[0][2] = (axis.x * axis.z * cos_value) - (axis.y * sin_theta);
+
+ res.array[1][0] = (axis.x * axis.y * cos_value) - (axis.z * sin_theta);
+ res.array[1][1] = (axis.y * axis.y * cos_value) + cos_theta;
+ res.array[1][2] = (axis.y * axis.z * cos_value) + (axis.x * sin_theta);
+
+ res.array[2][0] = (axis.x * axis.z * cos_value) + (axis.y * sin_theta);
+ res.array[2][1] = (axis.y * axis.z * cos_value) - (axis.x * sin_theta);
+ res.array[2][2] = (axis.z * axis.z * cos_value) + cos_value;
+
+ return res;
+}
+
Mat4 calcify_ortho4m(r32 left, r32 right, r32 bottom, r32 top, r32 near, r32 far) {
Mat4 res = calcify_init4m();
res.array[0][0] = 2.0f/(right - left);
diff --git a/source/core.h b/source/core.h
index fe9daf9..0befdfc 100644
--- a/source/core.h
+++ b/source/core.h
@@ -24,8 +24,12 @@ struct GameState {
u32 triangle_sp;
u32 triangle_vao;
u32 triangle_vbo;
+ u32 line_sp;
+ u32 line_vao;
+ u32 line_vbo;
i32 width;
i32 height;
+ r32 run_i;
};
enum GameEventType {
diff --git a/source/game/game.cpp b/source/game/game.cpp
index 337fe11..4229483 100644
--- a/source/game/game.cpp
+++ b/source/game/game.cpp
@@ -1,25 +1,86 @@
#include "game.h"
-void game_setup(GameState *state) {
- glUseProgram(state->triangle_sp);
+Cloth game_cloth = {
+ .width = 32,
+ .elasticity = 10.0f,
+ .padding = 30.0f,
+};
+
+void game_init(GameState *state) {
+ i32 cloth_rows = NUM_POINTS / game_cloth.width;
+ Vec2 start_pos = {
+ .x = state->width / 4.0f,
+ .y = state->height - state->height/4.0f
+ };
+
+ i32 max_rows = NUM_POINTS / game_cloth.width;
+ i32 max_cols = game_cloth.width;
+ i32 curr_row = 0, curr_col = 0;
+ Vec2 running_pos = start_pos;
+ for (i32 i = 0; i < NUM_POINTS; i++) {
+ Point p = {
+ .id = i,
+ .active = 1,
+ .prev_pos = running_pos,
+ .curr_pos = running_pos,
+ .force = {0.0f,0.0f}
+ };
+ {
+ // @fixme
+ i32 left_ind = i%max_cols == 0 ? -1 : i-1;
+ i32 right_ind = i%max_cols == max_cols - 1 ? -1 : i+1;
+ i32 top_ind = i/max_cols == 0 ? -1 : i - max_cols;
+ i32 bot_ind = i/max_cols == max_rows-1 ? -1 : i + max_cols;
+ p.constraints[0] = left_ind;
+ p.constraints[1] = top_ind;
+ p.constraints[2] = right_ind;
+ p.constraints[3] = bot_ind;
+ }
+ game_cloth.points[i] = p;
+
+ // next position
+ i32 next_row = (i+1)/max_cols;
+ i32 next_col = (i+1)%max_cols;
+ Vec2 next_pos = {
+ start_pos.x + game_cloth.padding*next_col,
+ start_pos.y - game_cloth.padding*next_row
+ };
+ running_pos = next_pos;
+ }
+}
+
+void game_shader_init_uniforms(GameState *state) {
Mat4 projection = calcify_ortho4m(0.0f, state->width, 0.0f, state->height, 0.1f, 10.0f);
+
+ glUseProgram(state->triangle_sp);
i32 triangle_proj_loc = glGetUniformLocation(state->triangle_sp, "Projection");
glUniformMatrix4fv(triangle_proj_loc, 1, 0, projection.buffer);
+
+ glUseProgram(state->line_sp);
+ i32 line_proj_loc = glGetUniformLocation(state->line_sp, "Projection");
+ glUniformMatrix4fv(line_proj_loc, 1, 0, projection.buffer);
+
glUseProgram(0);
};
void game_handle_event(GameState *state, GameEventType type) {
switch (type) {
case GAME_EVENT_RESIZE: {
- glUseProgram(state->triangle_sp);
glViewport(0, 0, state->width, state->height);
-
Mat4 projection = calcify_ortho4m(0.0f, state->width, 0.0f, state->height, 1.0f, 10.0f);
+
+ glUseProgram(state->triangle_sp);
+ // @step: update triangle sp
i32 triangle_proj_loc = glGetUniformLocation(state->triangle_sp, "Projection");
glUniformMatrix4fv(triangle_proj_loc,
1, 0,
projection.buffer);
- glUseProgram(0);
+ glUseProgram(state->line_sp);
+ // @step: update line sp
+ i32 line_proj_loc = glGetUniformLocation(state->line_sp, "Projection");
+ glUniformMatrix4fv(line_proj_loc,
+ 1, 0,
+ projection.buffer);
} break;
default:
@@ -27,30 +88,61 @@ void game_handle_event(GameState *state, GameEventType type) {
}
}
-void game_update_and_render(GameState *state) {
- glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
- glClear(GL_COLOR_BUFFER_BIT);
+void draw_line(GameState *state, Vec3 position, Vec2 size, r32 rotation, Vec3 color) {
+ glUseProgram(state->line_sp);
- glUseProgram(state->triangle_sp);
Mat4 model = calcify_ident4m();
- Mat4 scale = calcify_scaling_matrix4m(105.0f, 95.0f);
- model = calcify_multiply4m(scale, model);
+ Mat4 rotate = calcify_rotation_matrix4m(rotation, {.x=0,.y=0,.z=1});
+ Mat4 origin_set = calcify_translation_matrix4m(size.x/2.0f,
+ 0.0f,
+ 0.0f);
+ Mat4 scale = calcify_scaling_matrix4m(size.x, size.y);
+ Mat4 pos = calcify_translation_matrix4m(position.x,
+ position.y,
+ position.z);
- Mat4 pos = calcify_translation_matrix4m(350.0f, 950.0f, -1.0f);
+ model = calcify_multiply4m(scale, model);
+ model = calcify_multiply4m(origin_set, model);
+ model = calcify_multiply4m(rotate, model);
model = calcify_multiply4m(pos, model);
- i32 model_loc = glGetUniformLocation(state->triangle_sp,
+
+ i32 model_loc = glGetUniformLocation(state->line_sp,
"Model");
- glUniformMatrix4fv(
- model_loc,
- 1, 0,
- model.buffer
- );
-
- Vec3 Color = (Vec3){.r=0.4,.g=0.9,.b=0.7};
- glUniform3f(glGetUniformLocation(state->triangle_sp,
- "Color"),
- Color.r, Color.g, Color.b);
- glBindVertexArray(state->triangle_vao);
- glDrawArrays(GL_TRIANGLES, 0, 3);
- glBindVertexArray(0);
+ glUniformMatrix4fv(model_loc,
+ 1, 0,
+ model.buffer);
+ i32 color_loc = glGetUniformLocation(state->line_sp,
+ "Color");
+ glUniform3f(color_loc, color.x, color.y, color.z);
+
+ glBindVertexArray(state->line_vao);
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ glUseProgram(0);
+}
+
+void game_update_and_render(GameState *state) {
+ glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ for (int i = 0; i < NUM_POINTS; i++) {
+ Point p = game_cloth.points[i];
+ if (!p.active) continue;
+
+ for (int c = 2; c < 4; c++) {
+ i32 ci = p.constraints[c];
+ if (ci == -1) continue;
+ Point constraint = game_cloth.points[ci];
+ Vec2 a = p.curr_pos;
+ Vec2 b = constraint.curr_pos;
+ Vec2 dir_vector = {b.x - a.x, b.y - a.y};
+ r32 line_length = sqrt(dir_vector.x*dir_vector.x +
+ dir_vector.y*dir_vector.y);
+ r32 rot_angle = atan2(dir_vector.y,dir_vector.x);
+ draw_line(state,
+ {a.x, a.y, -1.0f},
+ {line_length, 3.0f},
+ rot_angle,
+ {0.4f, 0.5f, 0.7f});
+ }
+ }
}
diff --git a/source/game/game.h b/source/game/game.h
index 4c6f1f2..6cd5d56 100644
--- a/source/game/game.h
+++ b/source/game/game.h
@@ -12,9 +12,29 @@
#endif
extern "C" {
+ EXPORT void game_init(GameState *state);
+ EXPORT void game_shader_init_uniforms(GameState *state);
EXPORT void game_handle_event(GameState *state, GameEventType type);
- EXPORT void game_setup(GameState *state);
EXPORT void game_update_and_render(GameState *state);
}
+struct Point {
+ i32 id;
+ b8 active;
+ Vec2 prev_pos;
+ Vec2 curr_pos;
+ Vec2 force;
+ i32 constraints[4];
+};
+typedef struct Point Point;
+
+#define NUM_POINTS 1024
+struct Cloth {
+ i32 width;
+ r32 elasticity;
+ r32 padding;
+ Point points[NUM_POINTS];
+};
+typedef struct Cloth Cloth;
+
#endif // AMR_GAME_H
diff --git a/source/sdlmain.cpp b/source/sdlmain.cpp
index 372758a..bc269c9 100644
--- a/source/sdlmain.cpp
+++ b/source/sdlmain.cpp
@@ -18,14 +18,16 @@
#endif
// GAME LIBRARY FUNCTIONS
+typedef void (*GameInit)(GameState*);
+typedef void (*GameShaderInitUniforms)(GameState*);
typedef void (*GameHandleEvent)(GameState*, GameEventType);
-typedef void (*GameSetup)(GameState*);
typedef void (*GameUpdateAndRender)(GameState*);
struct GameLayer {
void *lib;
+ GameInit init;
+ GameShaderInitUniforms shader_init_uniforms;
GameHandleEvent handle_event;
- GameSetup setup;
GameUpdateAndRender update_and_render;
};
internal GameLayer game_layer;
@@ -40,12 +42,15 @@ bool load_game_layer()
if (game_layer.lib == NULL) {
return false;
}
+ game_layer.init =
+ (GameInit)SDL_LoadFunction(game_layer.lib,
+ "game_init");
+ game_layer.shader_init_uniforms =
+ (GameShaderInitUniforms)SDL_LoadFunction(game_layer.lib,
+ "game_shader_init_uniforms");
game_layer.handle_event =
(GameHandleEvent)SDL_LoadFunction(game_layer.lib,
"game_handle_event");
- game_layer.setup =
- (GameSetup)SDL_LoadFunction(game_layer.lib,
- "game_setup");
game_layer.update_and_render =
(GameUpdateAndRender)SDL_LoadFunction(game_layer.lib,
"game_update_and_render");
@@ -53,19 +58,6 @@ bool load_game_layer()
return true;
}
-bool game_file_update(fswatcher_event_handler *handler,
- fswatcher_event_type evtype,
- const char *src,
- const char *dst) {
- return load_game_layer();
-}
-
-//bool game_shader_update(fswatcher_event_handler *handler,
-// fswatcher_event_type evtype,
-// const char *src,
-// const char *dst) {
-//}
-
u32 gl_shader_program(char *vs, char *fs)
{
//==============
@@ -166,8 +158,112 @@ u32 gl_shader_program_from_path(const char *vspath, const char *fspath)
return shader_program;
}
+void setup_shaders(GameState *state, bool reinit=false) {
+ if (reinit) {
+ // we have to delete previous state
+ glDeleteVertexArrays(1, &state->triangle_vao);
+ glDeleteBuffers(1, &state->triangle_vbo);
+ glDeleteProgram(state->triangle_sp);
+
+ glDeleteVertexArrays(1, &state->line_vao);
+ glDeleteBuffers(1, &state->line_vbo);
+ glDeleteProgram(state->line_sp);
+ }
+ // triangle shader program
+ u32 triangle_shader_program = gl_shader_program_from_path("./shaders/quad.vs.glsl",
+ "./shaders/quad.fs.glsl");
+
+ state->triangle_sp = triangle_shader_program;
+ glUseProgram(state->triangle_sp);
+
+ // @func: gl_setup_triangle
+ {
+ GLfloat vertices[9] = {
+ -0.5f, -0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ 0.0f, 0.5f, 0.0f
+ };
+
+ GLuint VBO, VAO;
+ glGenVertexArrays(1, &VAO);
+ glGenBuffers(1, &VBO);
+
+ glBindVertexArray(VAO);
+
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
+ glEnableVertexAttribArray(0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+
+ state->triangle_vao = VAO;
+ state->triangle_vbo = VBO;
+ }
+ glUseProgram(0);
+
+ // line shader program
+ u32 line_shader_program = gl_shader_program_from_path("./shaders/quad.vs.glsl",
+ "./shaders/quad.fs.glsl");
+ state->line_sp = line_shader_program;
+ glUseProgram(state->line_sp);
+
+ // @func: gl_setup_line
+ {
+ GLfloat vertices[12] = {
+ -0.5f, 0.5f, 0.0f,
+ 0.5f, 0.5f, 0.0f,
+ -0.5f, -0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ };
+
+ GLuint VBO, VAO;
+ glGenVertexArrays(1, &VAO);
+ glGenBuffers(1, &VBO);
+
+ glBindVertexArray(VAO);
+
+ glBindBuffer(GL_ARRAY_BUFFER, VBO);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
+
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
+ glEnableVertexAttribArray(0);
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
+
+ state->line_vao = VAO;
+ state->line_vbo = VBO;
+
+ }
+}
+
+bool game_file_update(fswatcher_event_handler *handler,
+ fswatcher_event_type evtype,
+ const char *src,
+ const char *dst) {
+ GameState *state = (GameState*)handler->custom_data;
+ load_game_layer();
+ game_layer.init(state);
+ return 1;
+}
+
+bool shader_file_update(fswatcher_event_handler *handler,
+ fswatcher_event_type evtype,
+ const char *src,
+ const char *dst) {
+ GameState *state = (GameState*)handler->custom_data;
+ setup_shaders(state, true);
+ game_layer.shader_init_uniforms(state);
+ return 1;
+}
+
int main(int argc, char *argv[])
{
+ GameState state = {};
+
i32 raw_width = 1920;
i32 raw_height = 1080;
i32 dpi_width;
@@ -177,8 +273,6 @@ int main(int argc, char *argv[])
i32 width;
i32 height;
- GameState state = {};
-
if (SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("Error initialising SDL2: %s\n", SDL_GetError());
@@ -225,52 +319,29 @@ int main(int argc, char *argv[])
SDL_GL_SetSwapInterval(1);
- u32 shader_program = gl_shader_program_from_path("./shaders/quad.vs.glsl",
- "./shaders/quad.fs.glsl");
-
- state.triangle_sp = shader_program;
- glUseProgram(state.triangle_sp);
-
- // @func: gl_setup_triangle
- {
- GLfloat vertices[9] = {
- -0.5f, -0.5f, 0.0f,
- 0.5f, -0.5f, 0.0f,
- 0.0f, 0.5f, 0.0f
- };
-
- GLuint VBO, VAO;
- glGenVertexArrays(1, &VAO);
- glGenBuffers(1, &VBO);
-
- glBindVertexArray(VAO);
-
- glBindBuffer(GL_ARRAY_BUFFER, VBO);
- glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
-
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
- glEnableVertexAttribArray(0);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
-
- state.triangle_vao = VAO;
- state.triangle_vbo = VBO;
- }
- glUseProgram(0);
+ setup_shaders(&state);
+ // add shader watcher
+ fswatcher_t shader_watcher = fswatcher_create(FSWATCHER_CREATE_DEFAULT,
+ FSWATCHER_EVENT_MODIFY,
+ "shaders", NULL);
+ fswatcher_event_handler shader_file_update_handler;
+ shader_file_update_handler.callback = shader_file_update;
+ shader_file_update_handler.custom_data = &state;
// add file watcher
fswatcher_t game_watcher = fswatcher_create(FSWATCHER_CREATE_DEFAULT,
FSWATCHER_EVENT_MODIFY,
"source/game", NULL);
fswatcher_event_handler game_file_update_handler;
game_file_update_handler.callback = game_file_update;
+ game_file_update_handler.custom_data = &state;
// load game layer
if (!load_game_layer()) {
return -1;
}
- game_layer.setup(&state);
+ game_layer.init(&state);
+ game_layer.shader_init_uniforms(&state);
for(;;)
{
@@ -296,16 +367,22 @@ int main(int argc, char *argv[])
}
}
fswatcher_poll(game_watcher, &game_file_update_handler, NULL);
+ fswatcher_poll(shader_watcher, &shader_file_update_handler, NULL);
- // opengl rendering code here
game_layer.update_and_render(&state);
+
SDL_GL_SwapWindow(window);
}
// filewatcher
fswatcher_destroy(game_watcher);
+ fswatcher_destroy(shader_watcher);
// opengl free calls
+ glDeleteVertexArrays(1, &state.line_vao);
+ glDeleteBuffers(1, &state.line_vbo);
+ glDeleteProgram(state.line_sp);
+
glDeleteVertexArrays(1, &state.triangle_vao);
glDeleteBuffers(1, &state.triangle_vbo);
glDeleteProgram(state.triangle_sp);