From f30a4eba44c77d5c743fe9308dc697a3225e8dd8 Mon Sep 17 00:00:00 2001 From: pryazha Date: Sun, 15 Jun 2025 16:07:54 +0500 Subject: i don't even know --- audio.h | 68 ++++++++++++++++ camera.h | 69 ++++++++++++++++ ctx.h | 39 +++++++++ draw.h | 92 +++++++++++++++++++++ gui.h | 67 ++++++++++++++++ input.h | 46 +++++++++++ model.h | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ phys.h | 95 ++++++++++++++++++++++ prge.h | 51 +++--------- prge_audio.c | 75 ------------------ prge_audio.h | 6 -- prge_camera.c | 99 ----------------------- prge_camera.h | 7 -- prge_draw.c | 78 ------------------ prge_draw.h | 8 -- prge_gui.c | 60 -------------- prge_gui.h | 6 -- prge_input.c | 51 ------------ prge_input.h | 5 -- prge_model.c | 187 ------------------------------------------- prge_model.h | 11 --- prge_shader.c | 93 ---------------------- prge_shader.h | 12 --- prge_texture.c | 59 -------------- prge_texture.h | 1 - prge_types.h | 166 -------------------------------------- prge_window.c | 10 --- prge_window.h | 4 - shader.h | 105 ++++++++++++++++++++++++ texture.h | 55 +++++++++++++ types.h | 231 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 31 files changed, 1124 insertions(+), 978 deletions(-) create mode 100644 audio.h create mode 100644 camera.h create mode 100644 ctx.h create mode 100644 draw.h create mode 100644 gui.h create mode 100644 input.h create mode 100644 model.h create mode 100644 phys.h delete mode 100644 prge_audio.c delete mode 100644 prge_audio.h delete mode 100644 prge_camera.c delete mode 100644 prge_camera.h delete mode 100644 prge_draw.c delete mode 100644 prge_draw.h delete mode 100644 prge_gui.c delete mode 100644 prge_gui.h delete mode 100644 prge_input.c delete mode 100644 prge_input.h delete mode 100644 prge_model.c delete mode 100644 prge_model.h delete mode 100644 prge_shader.c delete mode 100644 prge_shader.h delete mode 100644 prge_texture.c delete mode 100644 prge_texture.h delete mode 100644 prge_types.h delete mode 100644 prge_window.c delete mode 100644 prge_window.h create mode 100644 shader.h create mode 100644 texture.h create mode 100644 types.h diff --git a/audio.h b/audio.h new file mode 100644 index 0000000..96dd11e --- /dev/null +++ b/audio.h @@ -0,0 +1,68 @@ +extern i32 load_vorbis(arena_t *arena, sound_t *sounds, const char *filename); +extern void play_sound(sound_t *sounds, sound_queue_t *queue, sound_queue_node_t *nodes, i32 id); + +i32 find_sound(sound_t *sounds, const char *name) +{ + for (i32 i = 0; i < MAX_SOUNDS_LOADED; i++) { + sound_t *sound = sounds+i; + if (streq(sound->name, name)) + return i; + } + return -1; +} + +i32 load_sound(sound_t *sounds, sound_t new_sound) +{ + assert(sounds); + + i32 i; + sound_t *sound; + for (i = 0; i < MAX_SOUNDS_LOADED; ++i) { + sound = sounds+i; + if (!sound->data) + break; + } + + if (i == MAX_SOUNDS_LOADED) { + printf("warning: max sounds loaded\n"); + return -1; + } + + *sound = new_sound; + + return i; +} + +i32 enqueue_sound(sound_queue_t *queue, sound_queue_node_t *nodes, sound_t *sound) +{ + if (queue->count == MAX_SOUNDS_PLAYING) + return 0; + + sound_queue_node_t *node; + for (i32 i = 0; i < MAX_SOUNDS_PLAYING; ++i) { + node = nodes+i; + if (!node->sound) + break; + } + + node->sound = sound; + + dllpushfront(queue->first, queue->last, node); + + queue->count++; + + return 1; +} + +sound_t *dequeue_sound(sound_queue_t *queue) +{ + if (queue->count == 0) + return 0; + + sound_t *sound = queue->first->sound; + queue->first->sound = 0; + dllremove(queue->first, queue->last, queue->first); + queue->count--; + + return sound; +} diff --git a/camera.h b/camera.h new file mode 100644 index 0000000..0dad35d --- /dev/null +++ b/camera.h @@ -0,0 +1,69 @@ +mat4 camera_get_view_mat(camera_t camera) +{ + mat4 view = mat4_make_transl(v3_inv(camera.position)); + view = mat4_rotate(view, camera.angles); + return view; +} + +void camera_get_vecs(camera_t camera, v3 *left, v3 *up, v3 *front) +{ + f32 angle = deg2rad(camera.angles.x); + f32 cp = fcos(angle); + f32 sp = fsin(angle); + + angle = deg2rad(camera.angles.y); + f32 cy = fcos(angle); + f32 sy = fsin(angle); + + angle = deg2rad(camera.angles.z); + f32 cr = fcos(angle); + f32 sr = fsin(angle); + + *left = (v3){cy*cr, -cy*sr, sy}; + *up = (v3){sp*sy*cr+cp*sr, -sp*sy*sr+cp*cr, -sp*cy}; + *front = (v3){-cp*sy*cr+sp*sr, cp*sy*sr+sp*cr, cp*cy}; +} + +mat4 camera_lookat(camera_t camera, v3 target, v3 world_up) +{ + v3 front = v3_norm(v3_sub(camera.position, target)); + v3 right = v3_norm(v3_cross(world_up, front)); + v3 up = v3_cross(front, right); + + mat4 translate = mat4_make_transl(v3_inv(camera.position)); + mat4 rotate = mat4_transp(mat4_make_rotate(right, up, front)); + mat4 result = mat4_mul(rotate, translate); + + return result; +} + +mat4 ortho(f32 l, f32 r, f32 b, f32 t, f32 n, f32 f) +{ + mat4 ortho = MAT4_IDENTITY; + ortho.c0.x = 2.0f/(r-l); + ortho.c1.y = 2.0f/(t-b); + ortho.c2.z = -2.0f/(f-n); + ortho.c3.x = -(r+l)/(r-l); + ortho.c3.y = -(t+b)/(t-b); + ortho.c3.z = -(f+n)/(f-n); + return ortho; +} + +mat4 perspective(camera_t camera, f32 aspect_ratio) +{ + f32 n = camera.near; + f32 f = camera.far; + + f32 r = n*ftan(deg2rad(camera.fov/2.0f)); + f32 t = r/aspect_ratio; + + mat4 perspective = MAT4_IDENTITY; + perspective.c0.x = n/r; + perspective.c1.y = n/t; + perspective.c2.z = -(f+n)/(f-n); + perspective.c2.w = -1.0f; + perspective.c3.z = (-2.0f*f*n)/(f-n); + perspective.c3.w = 0.0f; + + return perspective; +} diff --git a/ctx.h b/ctx.h new file mode 100644 index 0000000..3bc93f9 --- /dev/null +++ b/ctx.h @@ -0,0 +1,39 @@ +prge_context_t init_prge(void) +{ + prge_context_t ctx = {0}; + ctx.arena = alloc_arena(ARENA_SIZE); + ctx.frame_arena = alloc_arena(FRAME_ARENA_SIZE); + ctx.input = init_input(); + ctx.dir = sys_getbindir(&ctx.arena); + assert(ctx.dir); + printf("[INFO]\tBinary dir\t\"%s\"\n", ctx.dir); + return ctx; +} + +texture_t prge_load_texture(prge_context_t *ctx, const char *filename, i32 gamma) +{ + char full_path[MAX_PATH]; + snprintf(full_path, sizeof(full_path), "%s/%s", ctx->dir, filename); + texture_t texture = load_texture(&ctx->arena, full_path, gamma); + return texture; +} + +model_t prge_load_model(prge_context_t *ctx, transform_t transform, const char *filename) +{ + char full_path[MAX_PATH]; + snprintf(full_path, sizeof(full_path), "%s/%s", ctx->dir, filename); + model_t model = load_model_obj(&ctx->arena, transform, full_path); + return model; +} + +i32 prge_load_sound_vorbis(prge_context_t *ctx, const char *filename) +{ + char full_path[MAX_PATH]; + snprintf(full_path, sizeof(full_path), "%s/%s", ctx->dir, filename); + return load_vorbis(&ctx->arena, ctx->sounds, full_path); +} + +void prge_play_sound(prge_context_t *ctx, i32 id) +{ + play_sound(ctx->sounds, &ctx->sound_queue, ctx->sound_queue_nodes, id); +} diff --git a/draw.h b/draw.h new file mode 100644 index 0000000..bb67639 --- /dev/null +++ b/draw.h @@ -0,0 +1,92 @@ +void clear_window(v3 color) +{ + glClearColor(color.x, color.y, color.z, 1.0f); + glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); +} + +void begin3d(prge_window_t window, shader_t shader, camera_t camera) +{ + f32 aspect_ratio = (f32)window.width/(f32)window.height; + mat4 projection = perspective(camera, aspect_ratio); + mat4 view = camera_get_view_mat(camera); + + glUseProgram(shader.id); + shader_set_mat4(shader, SHADER_PROJECTION_MATRIX, projection); + shader_set_mat4(shader, SHADER_VIEW_MATRIX, view); +} + +void end3d(void) +{ + glUseProgram(0); +} + +void begin3d_alpha(prge_window_t window, shader_t shader, camera_t camera) +{ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + begin3d(window, shader, camera); +} + +void end3d_alpha(void) +{ + end3d(); + glDisable(GL_BLEND); +} + +void draw_mesh(mesh_t mesh) +{ + if (!mesh.vao) { + printf("warning: trying to draw mesh that doesn't have vao\n"); + return; + } + + glBindVertexArray(mesh.vao); + + for (i32 i = 0; i < mesh.ntextures; i++) { + glActiveTexture(GL_TEXTURE0+i); + glBindTexture(GL_TEXTURE_2D, mesh.textures[i].id); + } + + if (mesh.ebo) + glDrawElements(GL_TRIANGLES, mesh.nindices, GL_UNSIGNED_INT, 0); + else + glDrawArrays(GL_TRIANGLES, 0, mesh.nvertices); + + glBindTexture(GL_TEXTURE_2D, 0); + + glBindVertexArray(0); +} + +void draw_model(shader_t shader, model_t model) +{ + mat4 modelmat = apply_transform(model.transform); + for (i32 i = 0; i < model.nmeshes; ++i) { + mat4 meshmat = apply_transform(model.meshes[i].transform); + mat4 resultmat = mat4_mul(modelmat, meshmat); + + shader_set_mat4(shader, SHADER_MODEL_MATRIX, resultmat); + draw_mesh(model.meshes[i]); + } +} + +void draw_entity(shader_t shader, entity_t entity) +{ + v3 position = entity.model.transform.position; + position = v3_add(position, entity.position); + entity.model.transform.position = position; + draw_model(shader, entity.model); +} + +void draw_entities(elist_t entities, shader_t shader) +{ + for (enode_t *node = entities.first; node; node = node->next) + if (!(node->entity.flags & ENTITY_ALPHA)) + draw_entity(shader, node->entity); +} + +void draw_entities_alpha(elist_t entities, shader_t shader) +{ + for (enode_t *node = entities.first; node; node = node->next) + if (node->entity.flags & ENTITY_ALPHA) + draw_entity(shader, node->entity); +} diff --git a/gui.h b/gui.h new file mode 100644 index 0000000..e94267a --- /dev/null +++ b/gui.h @@ -0,0 +1,67 @@ +ui_t beginui(prge_window_t window, input_t input, shader_t shader, rect_t rect, arena_t *arena, f32 padding) +{ + assert(arena); + assert(shader.id); + assert(window.width && window.height); + + v2 start = {rect.start.x, rect.end.y}; + ui_t ui = {window, input, shader, rect, ui_list, start, arena, padding}; + glUseProgram(ui.shader.id); + mat4 projection = ortho(0.0f, ui.window.width, 0.0f, ui.window.height, -1.0f, 1.0f); + shader_set_mat4(ui.shader, SHADER_PROJECTION_MATRIX, projection); + glDisable(GL_DEPTH_TEST); + + f32 width = rect.end.x - rect.start.x; + f32 height = rect.end.y - rect.start.y; + mesh_t background = gen_quad_mesh(ui.arena, DEFAULT_TRANSFORM, width, height); + v2 half_width_height = {width/2.0f, height/2.0f}; + start = v2_add(rect.start, half_width_height); + mat4 world = mat4_make_transl(v3_from_v2(start)); + shader_set_mat4(ui.shader, SHADER_MODEL_MATRIX, world); + v4 color = {0.149f, 0.4f, 0.42f, 1.0f}; + shader_set_v4(ui.shader, "color", color); + draw_mesh(background); + clear_mesh(&background); + + return ui; +} + +i32 button(ui_t *ui, const char *text, f32 width, f32 height) +{ + if (width <= 0.0f || height <= 0.0f) + return 0; + + v4 color = {0.075f, 0.525f, 0.549f, 1.0f}; + i32 pressed = 0; + + v2 last = {ui->last.x + ui->padding, ui->last.y - height - ui->padding}; + rect_t rect = {last, v2_add(last, (v2){width, height})}; + if (in_rect(ui->input.mouse.pos, rect) && !ui->input.mouse.capture) { + color = (v4){0.3f, 0.61f, 0.63f, 1.0f}; + if (is_key_pressed(ui->input.mouse.left)) { + pressed = 1; + printf("%s\n", text); + } + } + + v2 center = {width/2.0f, height/2.0f}; + v2 start = v2_add(last, center); + ui->last.x += width + 2.0f*ui->padding; + mat4 world = mat4_make_transl(v3_from_v2(start)); + + shader_set_mat4(ui->shader, SHADER_MODEL_MATRIX, world); + shader_set_v4(ui->shader, "color", color); + + mesh_t quad = gen_quad_mesh(ui->arena, DEFAULT_TRANSFORM, width, height); + + draw_mesh(quad); + clear_mesh(&quad); + + return pressed; +} + +void endui(void) +{ + glEnable(GL_DEPTH_TEST); + glUseProgram(0); +} diff --git a/input.h b/input.h new file mode 100644 index 0000000..28090e9 --- /dev/null +++ b/input.h @@ -0,0 +1,46 @@ +input_t init_input() +{ + input_t input = {0}; + input.mouse.first = 1; + return input; +} + +void update_input(input_t *input) +{ + input->mouse.last = input->mouse.pos; + input->mouse.offset = V2_ZERO; + input->mouse.left.last = input->mouse.left.state; + input->mouse.right.last = input->mouse.right.state; + + input->move_right.last = input->move_right.state; + input->move_forward.last = input->move_forward.state; + input->move_left.last = input->move_left.state; + input->move_backward.last = input->move_backward.state; + input->move_up.last = input->move_up.state; + input->move_down.last = input->move_down.state; + + input->jump.last = input->jump.state; + input->action_right.last = input->action_right.state; + input->action_up.last = input->action_up.state; + input->action_left.last = input->action_left.state; + input->action_down.last = input->action_down.state; + input->exit.last = input->exit.state; +} + +i32 is_key_down(prge_key_t key) +{ + i32 result = (key.state == key_state_press); + return result; +} + +i32 is_key_pressed(prge_key_t key) +{ + i32 result = ((key.last == key_state_release) && (key.state == key_state_press)); + return result; +} + +i32 was_key_pressed(prge_key_t key) +{ + i32 result = ((key.last == key_state_press) && (key.state == key_state_release)); + return result; +} diff --git a/model.h b/model.h new file mode 100644 index 0000000..e7a2843 --- /dev/null +++ b/model.h @@ -0,0 +1,246 @@ +#define TINYOBJ_LOADER_C_IMPLEMENTATION +#include "tinyobj_loader_c.h" + +mat4 apply_transform(transform_t transform) +{ + mat4 result = mat4_make_scale(transform.scale); + result = mat4_rotate(result, transform.rotation); + result = mat4_transl(result, transform.position); + return result; +} + +void init_mesh_buffers(mesh_t *mesh) +{ + assert(mesh->vertices); + assert(mesh->nvertices > 0); + + u32 vertices_size = mesh->nvertices*sizeof(vertex_t); + u32 indices_size = mesh->nindices*sizeof(u32); + + glGenVertexArrays(1, &mesh->vao); + glBindVertexArray(mesh->vao); + + glGenBuffers(1, &mesh->vbo); + glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); + glBufferData(GL_ARRAY_BUFFER, vertices_size, mesh->vertices, GL_STATIC_DRAW); + + if (mesh->indices && (mesh->nindices > 0)) { + glGenBuffers(1, &mesh->ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ebo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices_size, mesh->indices, GL_STATIC_DRAW); + } + + glEnableVertexAttribArray(SHADER_POSITION_LOCATION); + glVertexAttribPointer(SHADER_POSITION_LOCATION, 3, GL_FLOAT, GL_FALSE, + sizeof(vertex_t), (void *)offsetof(vertex_t, position)); + + glEnableVertexAttribArray(SHADER_NORMAL_LOCATION); + glVertexAttribPointer(SHADER_NORMAL_LOCATION, 3, GL_FLOAT, GL_FALSE, + sizeof(vertex_t), (void *)offsetof(vertex_t, normal)); + + glEnableVertexAttribArray(SHADER_TEXCOORDS_LOCATION); + glVertexAttribPointer(SHADER_TEXCOORDS_LOCATION, 2, GL_FLOAT, GL_FALSE, + sizeof(vertex_t), (void *)offsetof(vertex_t, texcoords)); + + glBindVertexArray(0); +} + +mesh_t init_mesh(transform_t transform, i32 nvertices, vertex_t *vertices, i32 nindices, u32 *indices) +{ + mesh_t mesh = {0}; + mesh.transform = transform; + mesh.nvertices = nvertices; + mesh.vertices = vertices; + mesh.nindices = nindices; + mesh.indices = indices; + init_mesh_buffers(&mesh); + return mesh; +} + +void clear_mesh(mesh_t *mesh) +{ + glBindVertexArray(mesh->vao); + glDisableVertexAttribArray(SHADER_POSITION_LOCATION); + glDisableVertexAttribArray(SHADER_NORMAL_LOCATION); + glDisableVertexAttribArray(SHADER_TEXCOORDS_LOCATION); + + glBindVertexArray(0); + glDeleteVertexArrays(1, &mesh->vao); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glDeleteBuffers(1, &mesh->vbo); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glDeleteBuffers(1, &mesh->ebo); +} + +void add_mesh_texture(mesh_t *mesh, texture_t texture) +{ + if (!mesh) { + printf("error: can't add texture to a null mesh :|\n"); + return; + } + + if (mesh->ntextures+1 >= MAX_TEXTURE_PER_MESH) { + printf("warning: \"%s\" texture limit reached: %d\n", texture.name, MAX_TEXTURE_PER_MESH); + return; + } + + mesh->textures[mesh->ntextures++] = texture; +} + +mesh_t gen_quad_mesh(arena_t *arena, transform_t transform, f32 width, f32 height) +{ + assert(width > 0); + assert(height > 0); + + i32 nvertices = 4; + vertex_t *vertices = push_arena(arena, nvertices*sizeof(vertex_t)); + vertices[0] = (vertex_t){{-width/2.0f, -height/2.0f, 0.0f}, V3_ZERO, {0.0f, 0.0f}}; + vertices[1] = (vertex_t){{-width/2.0f, height/2.0f, 0.0f}, V3_ZERO, {0.0f, height}}; + vertices[2] = (vertex_t){{ width/2.0f, -height/2.0f, 0.0f}, V3_ZERO, {width, 0.0f}}; + vertices[3] = (vertex_t){{ width/2.0f, height/2.0f, 0.0f}, V3_ZERO, {width, height}}; + + i32 nindices = 6; + u32 *indices = push_arena(arena, nindices*sizeof(u32)); + indices[0] = 0; + indices[1] = 1; + indices[2] = 3; + indices[3] = 0; + indices[4] = 2; + indices[5] = 3; + + mesh_t mesh = init_mesh(transform, nvertices, vertices, nindices, indices); + + return mesh; +} + +mesh_t gen_circle_mesh(arena_t *arena, transform_t transform, f32 radius, i32 nvertices) +{ + if (nvertices < 3) + nvertices = 3; + + vertex_t *vertices = push_arena(arena, nvertices*sizeof(vertex_t)); + + f32 angle = 0.0f; + f32 dangle = 2.0f*F_PI/nvertices; + for (i32 i = 0; i < nvertices; ++i, angle += dangle) + vertices[i] = (vertex_t){{fcos(angle)*radius, fsin(angle)*radius, 0.0f}, V3_ZERO, V2_ZERO}; + + i32 nindices = nvertices*3; + u32 *indices = push_arena(arena, nindices*sizeof(u32)); + for (i32 i = 0, vi = 1; i < nindices; i += 3, vi++) { + indices[i] = 0; + indices[i+1] = vi; + indices[i+2] = ((vi+1 == nvertices) ? 1 : vi+1); + } + + mesh_t mesh = init_mesh(transform, nvertices, vertices, nindices, indices); + + return mesh; +} + +model_t init_model(transform_t transform, i32 nmeshes, mesh_t *meshes) +{ + model_t model = { + transform, + nmeshes, + meshes, + }; + return model; +} + +void read_file_tinyobj(void* ctx, const char* filename, const i32 is_mtl, const char* obj_filename, char** data, u64* len) +{ + if (is_mtl) + printf("info: is_mtl is set (don't use it right now)\n"); + if (obj_filename) + printf("info: obj_filename is \"%s\"\n", obj_filename); + if (!filename) { + printf("error: obj filename is zero\n"); + *data = 0; + *len = 0; + return; + } + + arena_t *arena = (arena_t *)ctx; + *len = sys_read_file(arena, data, filename); +} + +model_t load_model_obj(arena_t *arena, transform_t transform, const char *filename) +{ + tinyobj_attrib_t attrib; + u64 nshapes; + tinyobj_shape_t *shapes; + u64 nmaterials; + tinyobj_material_t *materials; + + u32 flags = TINYOBJ_FLAG_TRIANGULATE; + i32 status = tinyobj_parse_obj(&attrib, &shapes, &nshapes, &materials, &nmaterials, + filename, read_file_tinyobj, arena, flags); + + model_t model = {0}; + if (status != TINYOBJ_SUCCESS) { + printf("error: failed to parse \"%s\"\n", filename); + return model; + } + + u64 ntriangles = attrib.num_face_num_verts; + u64 face_offset = 0; + + u64 nvertices = ntriangles*3; + vertex_t *vertices = push_arena(arena, sizeof(vertex_t)*nvertices); + + u64 nindices = ntriangles*3; + u32 *indices = push_arena(arena, sizeof(u32)*nindices); + + i32 vertex_count = 0, index_count = 0, index_index = 0; + for (u32 i = 0; i < attrib.num_face_num_verts; ++i) { + assert(attrib.face_num_verts[i]%3 == 0); + assert(attrib.face_num_verts[i]/3 > 0); + assert(attrib.num_texcoords); + + tinyobj_vertex_index_t idx; + for (i32 j = 0; j < 3; ++j) { + idx = attrib.faces[face_offset+j]; + assert(idx.v_idx >= 0); + v3 position = { + attrib.vertices[3*idx.v_idx+0], + attrib.vertices[3*idx.v_idx+1], + attrib.vertices[3*idx.v_idx+2] + }; + + assert(idx.vn_idx < (i32)attrib.num_normals); + v3 normal = { + attrib.normals[3*idx.vn_idx+0], + attrib.normals[3*idx.vn_idx+1], + attrib.normals[3*idx.vn_idx+2] + }; + + assert(idx.vt_idx < (i32)attrib.num_texcoords); + v2 texcoords = { + attrib.texcoords[2*idx.vt_idx+0], + attrib.texcoords[2*idx.vt_idx+1] + }; + + vertices[vertex_count++] = (vertex_t){position, normal, texcoords}; + indices[index_index++] = index_count++; + } + + face_offset += 3; + } + + i32 nmeshes = 1; + mesh_t *meshes = push_arena(arena, sizeof(mesh_t)*nmeshes); + *meshes = init_mesh(DEFAULT_TRANSFORM, nvertices, vertices, nindices, indices); + + tinyobj_attrib_free(&attrib); + tinyobj_shapes_free(shapes, nshapes); + tinyobj_materials_free(materials, nmaterials); + + model = init_model(transform, nmeshes, meshes); + + printf("info: \"%s\" loaded successfully\n", filename); + + return model; +} diff --git a/phys.h b/phys.h new file mode 100644 index 0000000..d7b3a76 --- /dev/null +++ b/phys.h @@ -0,0 +1,95 @@ +i32 add_entity(entity_t entity, elist_t *list) +{ + assert(list); + i32 i; + for (i = 0; i < MAX_ENTITIES; ++i) + if (!list->nodes[i].id) + break; + if (i == MAX_ENTITIES) { + printf("error: failed to add entity\n"); + return 0; + } + ++list->count; + enode_t *node = list->nodes+i; + node->id = list->count; + node->entity = entity; + dllpushback(list->first, list->last, node); + return node->id; +} + +void delete_entity(i32 id, elist_t *list) +{ + assert(list); + for (enode_t *node = list->first; node; node = node->next) { + if (node->id == id) { + dllremove(list->first, list->last, node); + memzero_struct(node); + list->count--; + printf("info: entity %d deleted\n", id); + return; + } + } + printf("error: entity %d failed to delete\n", id); +} + +entity_t *get_entity(elist_t list, i32 id) +{ + for (enode_t *node = list.first; node; node = node->next) + if (node->id == id) + return &node->entity; + return 0; +} + +i32 aabb3d(bbox_t a, bbox_t b) +{ + i32 result = ((b.start.x <= a.end.x) && (b.end.x >= a.start.x)) && + ((b.start.y <= a.end.y) && (b.end.y >= a.start.y)) && + ((b.start.z <= a.end.z) && (b.end.z >= a.start.z)); + return result; +} + +i32 check_collision(entity_t *a, entity_t *b) +{ + if (!(a->flags & ENTITY_COLLIDE) || !(b->flags & ENTITY_COLLIDE)) + return 0; + + bbox_t bboxa = { + v3_add(a->bbox.start, a->position), + v3_add(a->bbox.end, a->position) + }; + + bbox_t bboxb = { + v3_add(b->bbox.start, b->position), + v3_add(b->bbox.end, b->position) + }; + + i32 result = aabb3d(bboxa, bboxb); + + return result; +} + +entity_t move_entity(entity_t old, v3 acceleration, float dt) +{ + entity_t new = old; + new.position = v3_add(old.position, v3_scalef(old.velocity, dt)); + new.velocity = v3_add(old.velocity, v3_scalef(acceleration, dt*dt)); + new.velocity = v3_sub(new.velocity, v3_scalef(V3_UP, dt)); + return new; +} + +/* +void update_entities(elist_t list) +{ + for (enode_t *node = list.first; node; node = node->next) { + if (node->entity.flags & ENTITY_MOVE) + move_entity(node->entity, ); + if (node->entity.flags & ENTITY_COLLIDE) { + for (enode_t *test = list.first; test; test = test->next) { + if (check_collision(node->entity, test->entity)) { + + } + } + } + } +} +*/ diff --git a/prge.h b/prge.h index 90271b3..d9c664b 100644 --- a/prge.h +++ b/prge.h @@ -3,45 +3,16 @@ #include "prb.h" -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - -#include "prge_types.h" -#include "prge_window.h" -#include "prge_input.h" -#include "prge_texture.h" -#include "prge_shader.h" -#include "prge_model.h" -#include "prge_camera.h" -#include "prge_draw.h" -#include "prge_gui.h" -#include "prge_audio.h" - -#include "prge_window.c" -#include "prge_input.c" -#include "prge_texture.c" -#include "prge_shader.c" -#include "prge_model.c" -#include "prge_camera.c" -#include "prge_draw.c" -#include "prge_gui.c" -#include "prge_audio.c" - -#define PRGE_PERSARENA_SIZE MB(64) -#define PRGE_TMPARENA_SIZE MB(32) - -void init_prge(PRGEContext *ctx) -{ - MEM0STRUCT(ctx); - - ctx->pa = alloc_arena(PRGE_PERSARENA_SIZE); - ctx->tmpa = alloc_arena(PRGE_TMPARENA_SIZE); - - ctx->in = init_input(); - - ctx->bindir = sys_getbindir(ctx->pa); - if (ctx->bindir) - sys_printf("[INFO] : PRGE : Binary path : \"%s\"\n", ctx->bindir); -} +#include "types.h" +#include "input.h" +#include "texture.h" +#include "shader.h" +#include "model.h" +#include "phys.h" +#include "camera.h" +#include "audio.h" +#include "ctx.h" +#include "draw.h" +#include "gui.h" #endif /* PRGE_H */ diff --git a/prge_audio.c b/prge_audio.c deleted file mode 100644 index 08fb67c..0000000 --- a/prge_audio.c +++ /dev/null @@ -1,75 +0,0 @@ -S32 find_sound(PRGEContext *ctx, const char *name) -{ - S32 i; - Sound *snd; - - for (i = 0; i < PRGE_MAX_SOUNDS_LOADED; i++) { - snd = ctx->snds+i; - if (snd->name && (strcmp(snd->name, name) == 0)) - return i; - } - - return -1; -} - -S32 load_sound(PRGEContext *ctx, Sound newsnd) -{ - S32 i; - Sound *snd; - - for (i = 0; i < PRGE_MAX_SOUNDS_LOADED; i++) { - snd = ctx->snds+i; - if (!snd->data) - break; - } - - if (i == PRGE_MAX_SOUNDS_LOADED) { - sys_printf("[WARNING] : PRGE : Max sounds loaded\n"); - pop_arena(ctx->pa, newsnd.size); - return -1; - } - - *snd = newsnd; - - return i; -} - -B32 enqueue_sound(PRGEContext *ctx, Sound *snd) -{ - SoundQueueNode *node; - SoundQueue *sndq; - S32 i; - - ASSERT(snd); - - sndq = &ctx->sndq; - - if (sndq->cnt == PRGE_MAX_SOUNDS_PLAYING) - return 0; - - for (i = 0; i < PRGE_MAX_SOUNDS_PLAYING; i++) { - node = ctx->nodes+i; - if (!node->snd) - break; - } - - node->snd = snd; - - DLLPUSHFRONT(sndq->first, sndq->last, node); - - sndq->cnt++; - - return 1; -} - -Sound *dequeue_sound(SoundQueue *sndq) -{ - Sound *snd; - if (sndq->cnt == 0) - return 0; - snd = sndq->first->snd; - sndq->first->snd = 0; - DLLREMOVE(sndq->first, sndq->last, sndq->first); - sndq->cnt--; - return snd; -} diff --git a/prge_audio.h b/prge_audio.h deleted file mode 100644 index 5f07a2c..0000000 --- a/prge_audio.h +++ /dev/null @@ -1,6 +0,0 @@ -S32 find_sound(PRGEContext *ctx, const char *name); -S32 load_sound(PRGEContext *ctx, Sound snd); -S32 load_vorbis(PRGEContext *ctx, const char *fname); -S32 enqueue_sound(PRGEContext *ctx, Sound *snd); -Sound *dequeue_sound(SoundQueue *sndq); -void play_sound(PRGEContext *ctx, S32 id); diff --git a/prge_camera.c b/prge_camera.c deleted file mode 100644 index 0a79a74..0000000 --- a/prge_camera.c +++ /dev/null @@ -1,99 +0,0 @@ -Camera initcam(V3 pos, F32 fov, F32 near, F32 far, F32 yaw, F32 pitch, F32 roll) -{ - Camera c = { - .pos = pos, - .fov = fov, - .near = near, - .far = far, - .yaw = yaw, - .pitch = pitch, - .roll = roll, - }; - return c; -} - -MAT4 getfpviewmat(Camera *c) -{ - MAT4 v; - v = translmat4(MAT4_IDENTITY, invv3(c->pos)); - v = rotatemat4(v, v3(c->pitch, c->yaw, c->roll)); - return v; -} - -void getfpvecs(Camera *c, V3 *l, V3 *u, V3 *f) -{ - F32 angle, cp, sp, cy, sy, cr, sr; - - angle = DEG2RAD*c->pitch; - cp = f32cos(angle); - sp = f32sin(angle); - angle = DEG2RAD*c->yaw; - cy = f32cos(angle); - sy = f32sin(angle); - angle = DEG2RAD*c->roll; - cr = f32cos(angle); - sr = f32sin(angle); - - *l = v3(cy*cr, -cy*sr, sy); - *u = v3(sp*sy*cr+cp*sr, -sp*sy*sr+cp*cr, -sp*cy); - *f = v3(-cp*sy*cr+sp*sr, cp*sy*sr+sp*cr, cp*cy); -} - -MAT4 lookat(Camera c, V3 t, V3 wup) -{ - V3 f, r, u; - MAT4 transl, rotate, res; - - f = normv3(subv3(c.pos, t)); - r = normv3(crossv3(wup, f)); - u = crossv3(f, r); - - transl = translmat4(MAT4_IDENTITY, invv3(c.pos)); - rotate = transpmat4(rotateaxismat4(r, u, f)); - res = mulmat4(rotate, transl); - - return res; -} - -MAT4 ortho(F32 l, F32 r, F32 b, F32 t, F32 n, F32 f) -{ - MAT4 res; - - res = MAT4_IDENTITY; - res.m0.x = 2.0f/(r-l); - res.m1.y = 2.0f/(t-b); - res.m2.z = -2.0f/(f-n); - res.m3.x = -(r+l)/(r-l); - res.m3.y = -(t+b)/(t-b); - res.m3.z = -(f+n)/(f-n); - - return res; -} - -MAT4 persp(F32 fov, F32 ar, F32 n, F32 f) -{ - F32 r, t; - MAT4 res; - - r = n*f32tan(fov/2.0f*DEG2RAD); - t = r/ar; - - res = MAT4_IDENTITY; - res.m0.x = n/r; - res.m1.y = n/t; - res.m2.z = -(f+n)/(f-n); - res.m2.w = -1.0f; - res.m3.z = (-2.0f*f*n)/(f-n); - res.m3.w = 0.0f; - - return res; -} - -MAT4 camera_persp(Camera c, F32 ar) -{ - MAT4 res; - - res = persp(c.fov, ar, c.near, c.far); - - return res; -} diff --git a/prge_camera.h b/prge_camera.h deleted file mode 100644 index f938b8b..0000000 --- a/prge_camera.h +++ /dev/null @@ -1,7 +0,0 @@ -Camera initcam(V3 pos, F32 fov, F32 near, F32 far, F32 yaw, F32 pitch, F32 roll); -MAT4 getfpviewmat(Camera *c); -void getfpvecs(Camera *c, V3 *l, V3 *u, V3 *f); -MAT4 lookat(Camera c, V3 t, V3 wup); -MAT4 ortho(F32 l, F32 r, F32 b, F32 t, F32 n, F32 f); -MAT4 persp(F32 fov, F32 ar, F32 n, F32 f); -MAT4 camera_persp(Camera c, F32 ar); diff --git a/prge_draw.c b/prge_draw.c deleted file mode 100644 index 4228d68..0000000 --- a/prge_draw.c +++ /dev/null @@ -1,78 +0,0 @@ -void clear_window(PRGEWindow wnd, V3 clear_color) -{ - glClearColor(clear_color.x, clear_color.y, clear_color.z, 1.0f); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); -} - -void begin3d(PRGEWindow wnd, Shader shader, Camera camera) -{ - F32 ar; - MAT4 proj, view; - - ar = (F32)wnd.w/(F32)wnd.h; - proj = camera_persp(camera, ar); - view = getfpviewmat(&camera); - - glUseProgram(shader.id); - - setmat4fv(shader.id, PRGE_SHADER_PROJ_MAT, proj); - setmat4fv(shader.id, PRGE_SHADER_VIEW_MAT, view); -} - -void end3d(void) -{ - glUseProgram(0); -} - -void begin3d_alpha(PRGEWindow wnd, Shader shader, Camera camera) -{ - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - begin3d(wnd, shader, camera); -} - -void end3d_alpha(void) -{ - end3d(); - glDisable(GL_BLEND); -} - -void draw_mesh(Mesh mesh) -{ - S32 i; - - ASSERT(mesh.vao); - - glBindVertexArray(mesh.vao); - - for (i = 0; i < mesh.ntextures; i++) { - glActiveTexture(GL_TEXTURE0+i); - glBindTexture(GL_TEXTURE_2D, mesh.textures[i].id); - } - - if (mesh.ebo) - glDrawElements(GL_TRIANGLES, mesh.nindices, GL_UNSIGNED_INT, 0); - else - glDrawArrays(GL_TRIANGLES, 0, mesh.nverts); - - glBindVertexArray(0); -} - -void draw_model(Shader shader, Model model) -{ - MAT4 modelm, - meshm, - resm; - S32 i; - - modelm = rotatemat4(MAT4_IDENTITY, model.rotate); - modelm = translmat4(modelm, model.origin); - for (i = 0; i < model.nmeshes; i++) { - meshm = rotatemat4(MAT4_IDENTITY, model.meshes[i].rotate); - meshm = translmat4(meshm, model.meshes[i].origin); - resm = mulmat4(modelm, meshm); - - setmat4fv(shader.id, PRGE_SHADER_MODEL_MAT, resm); - draw_mesh(model.meshes[i]); - } -} diff --git a/prge_draw.h b/prge_draw.h deleted file mode 100644 index 087b5ac..0000000 --- a/prge_draw.h +++ /dev/null @@ -1,8 +0,0 @@ -void clear_window(PRGEWindow wnd, V3 clear_color); -void begin3d(PRGEWindow wnd, Shader shader, Camera camera); -void end3d(void); -void begin3d_alpha(PRGEWindow wnd, Shader shader, Camera camera); -void end3d_alpha(void); - -void draw_mesh(Mesh mesh); -void draw_model(Shader shader, Model model); diff --git a/prge_gui.c b/prge_gui.c deleted file mode 100644 index b4be331..0000000 --- a/prge_gui.c +++ /dev/null @@ -1,60 +0,0 @@ -B32 inrect(V2 pos, V2 start, V2 end) -{ - B32 res; - res = ((pos.x > start.x) && (pos.x < end.x) && - (pos.y > start.y) && (pos.y < end.y)); - return res; -} - -void beginui(Shader shader, PRGEWindow wnd) -{ - MAT4 proj; - - glUseProgram(shader.id); - proj = ortho(0.0f, (F32)wnd.w, 0.0f, (F32)wnd.h, -1.0f, 1.0f); - setmat4fv(shader.id, PRGE_SHADER_PROJ_MAT, proj); - glDisable(GL_DEPTH_TEST); -} - -void endui(void) -{ - glEnable(GL_DEPTH_TEST); - glUseProgram(0); -} - -B32 button(PRGEContext *prgectx, Shader shader, const char *name, V2 center, F32 w, F32 h) -{ - B32 pressed; - Mesh quad; - V2 start, end; - - MAT4 model; - V4 color; - - pressed = 0; - - quad = gen_quad(prgectx->tmpa, v3fromv2(center), V3_ZERO, w, h); - - color = v4(1.0f, 0.0f, 0.0f, 1.0f); - start = v2(center.x-w/2.0f, center.y-h/2.0f); - end = v2(center.x+w/2.0f, center.y+h/2.0f); - - if (inrect(prgectx->in.mouse_pos, start, end) && !prgectx->in.capture_mouse) { - color = v4(0.0f, 0.0f, 1.0f, 1.0f); - if (is_key_pressed(prgectx->in.mouse_left)) { - sys_printf("%s\n", name); - pressed = 1; - } - } - - model = translmat4(MAT4_IDENTITY, v3(center.x, prgectx->wnd.h-center.y, 0.0f)); - - setmat4fv(shader.id, "model", model); - set4fv(shader.id, "color", color); - - draw_mesh(quad); - - clear_mesh(&quad); - - return pressed; -} diff --git a/prge_gui.h b/prge_gui.h deleted file mode 100644 index c267466..0000000 --- a/prge_gui.h +++ /dev/null @@ -1,6 +0,0 @@ -B32 inrect(V2 pos, V2 start, V2 end); - -void beginui(Shader shader, PRGEWindow wnd); -void endui(void); - -B32 button(PRGEContext *prgectx, Shader shader, const char *name, V2 center, F32 w, F32 h); diff --git a/prge_input.c b/prge_input.c deleted file mode 100644 index 74de9e5..0000000 --- a/prge_input.c +++ /dev/null @@ -1,51 +0,0 @@ -Input init_input() -{ - Input in; - - MEM0STRUCT(&in); - - in.first_mouse = 1; - - return in; -} - -/* NOTE(pryazha): Updates the last states of keys, mouse position and offset. - * Should be called every frame */ -void update_input(Input *in) -{ - in->last_mouse_pos = in->mouse_pos; - in->mouse_offset = V2_ZERO; - in->mouse_left.last = in->mouse_left.state; - in->mouse_right.last = in->mouse_right.state; - - in->move_right.last = in->move_right.state; - in->move_forward.last = in->move_forward.state; - in->move_left.last = in->move_left.state; - in->move_backward.last = in->move_backward.state; - in->move_up.last = in->move_up.state; - in->move_down.last = in->move_down.state; - in->jump.last = in->jump.state; - in->action_right.last = in->action_right.state; - in->action_up.last = in->action_up.state; - in->action_left.last = in->action_left.state; - in->action_down.last = in->action_down.state; - in->exit.last = in->exit.state; -} - -B32 is_key_down(Key key) -{ - B32 r = (key.state == KeyState_PRESS); - return r; -} - -B32 is_key_pressed(Key key) -{ - B32 r = ((key.last == KeyState_RELEASE) && (key.state == KeyState_PRESS)); - return r; -} - -B32 was_key_pressed(Key key) -{ - B32 r = ((key.last == KeyState_PRESS) && (key.state == KeyState_RELEASE)); - return r; -} diff --git a/prge_input.h b/prge_input.h deleted file mode 100644 index fe9c01f..0000000 --- a/prge_input.h +++ /dev/null @@ -1,5 +0,0 @@ -Input init_input(); -void update_input(Input *in); -B32 is_key_down(Key key); -B32 is_key_pressed(Key key); -B32 was_key_pressed(Key key); diff --git a/prge_model.c b/prge_model.c deleted file mode 100644 index e2dc55f..0000000 --- a/prge_model.c +++ /dev/null @@ -1,187 +0,0 @@ -Vertex init_vert(V3 pos, V2 texc) -{ - Vertex v = { - .pos = pos, - .texc = texc, - }; - return v; -} - -void init_mesh_buffers(Mesh *mesh) -{ - ASSERT(mesh->verts); - ASSERT(mesh->nverts > 0); - - U32 sverts, - sindices; - - sverts = mesh->nverts*sizeof(Vertex); - sindices = mesh->nindices*sizeof(U32); - - glGenVertexArrays(1, &mesh->vao); - glBindVertexArray(mesh->vao); - - glGenBuffers(1, &mesh->vbo); - glBindBuffer(GL_ARRAY_BUFFER, mesh->vbo); - glBufferData(GL_ARRAY_BUFFER, sverts, - mesh->verts, GL_STATIC_DRAW); - - if (mesh->indices && (mesh->nindices > 0)) { - glGenBuffers(1, &mesh->ebo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh->ebo); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, sindices, - mesh->indices, GL_STATIC_DRAW); - } - - glEnableVertexAttribArray(PRGE_SHADER_POS_LOC); - glVertexAttribPointer(PRGE_SHADER_POS_LOC, 3, - GL_FLOAT, GL_FALSE, sizeof(Vertex), - (void *)OFFSETOF(Vertex, pos)); - - glEnableVertexAttribArray(PRGE_SHADER_TEXC_LOC); - glVertexAttribPointer(PRGE_SHADER_TEXC_LOC, 2, - GL_FLOAT, GL_FALSE, sizeof(Vertex), - (void *)OFFSETOF(Vertex, texc)); - - glBindVertexArray(0); -} - -Mesh init_mesh(V3 origin, V3 rotate, S32 nverts, Vertex *verts, S32 nindices, U32 *indices) -{ - Mesh mesh; - - MEM0STRUCT(&mesh); - - mesh.origin = origin; - mesh.rotate = rotate; - - mesh.verts = verts; - mesh.nverts = nverts; - - mesh.indices = indices; - mesh.nindices = nindices; - - init_mesh_buffers(&mesh); - - return mesh; -} - -void clear_mesh(Mesh *mesh) -{ - glBindVertexArray(mesh->vao); - glDisableVertexAttribArray(PRGE_SHADER_POS_LOC); - - glBindVertexArray(0); - glDeleteVertexArrays(1, &mesh->vao); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glDeleteBuffers(1, &mesh->vbo); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glDeleteBuffers(1, &mesh->ebo); -} - -void add_mesh_texture(Mesh *mesh, Texture texture) -{ - if (mesh->ntextures+1 >= PRGE_MAX_TEXTURES) { - sys_printf("[WARNING] : Texture : \"%s\" : limit\n", texture.name); - return; - } - mesh->textures[mesh->ntextures++] = texture; -} - -Mesh gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h) -{ - Mesh mesh; - - S32 nverts; - Vertex *verts; - - S32 nindices; - U32 *indices; - - ASSERT(w > 0); - ASSERT(h > 0); - - nverts = 4; - verts = push_arena(arena, nverts*sizeof(Vertex)); - verts[0] = init_vert(v3(-w/2.0f, -h/2.0f, 0.0f), v2(0.0f, 0.0f)); - verts[1] = init_vert(v3(-w/2.0f, h/2.0f, 0.0f), v2(0.0f, h)); - verts[2] = init_vert(v3(w/2.0f, -h/2.0f, 0.0f), v2(w, 0.0f)); - verts[3] = init_vert(v3(w/2.0f, h/2.0f, 0.0f), v2(w, h)); - - nindices = 6; - indices = push_arena(arena, nindices*sizeof(U32)); - indices[0] = 0; - indices[1] = 1; - indices[2] = 3; - indices[3] = 0; - indices[4] = 2; - indices[5] = 3; - - mesh = init_mesh(origin, rotate, nverts, verts, nindices, indices); - - return mesh; -} - -Mesh gen_circle(Arena *arena, V3 origin, V3 rotate, F32 r, S32 nverts) -{ - Mesh mesh; - - Vertex *verts; - - S32 nindices; - U32 *indices; - - F32 angle, dangle; - - S32 i, vi; - - if (nverts < 3) - nverts = 3; - - verts = push_arena(arena, nverts*sizeof(Vertex)); - - dangle = 2*F32PI/(F32)nverts; - for (i = 0, angle = 0.0f; i < nverts; i++, angle += dangle) - verts[i] = init_vert(v3(f32cos(angle)*r, f32sin(angle)*r, 0.0f), V2_ZERO); - - nindices = nverts*3; - indices = push_arena(arena, nindices*sizeof(U32)); - for (i = 0, vi = 1; i < nindices; i += 3, vi++) { - indices[i] = 0; - indices[i+1] = vi; - indices[i+2] = (((vi+1) == (nverts)) ? 1 : (vi+1)); - } - - mesh = init_mesh(origin, rotate, nverts, verts, nindices, indices); - - return mesh; -} - -Model init_model(V3 origin, V3 rotate, S32 nmeshes, Mesh *meshes) -{ - Model model = { - .origin = origin, - .rotate = rotate, - .nmeshes = nmeshes, - .meshes = meshes, - }; - return model; -} - -Model load_model(V3 origin, V3 rotate, const char *fname) -{ - Model model; - - MEM0STRUCT(&model); - - model.origin = origin; - model.rotate = rotate; - - sys_printf("[INFO] : PRGE : Trying to load %s\n", fname); - - /* TODO(pryazha): Load models with assimp? */ - - return model; -} diff --git a/prge_model.h b/prge_model.h deleted file mode 100644 index b2e6f1e..0000000 --- a/prge_model.h +++ /dev/null @@ -1,11 +0,0 @@ -extern Vertex init_vert(V3 pos, V2 texc); - -extern Mesh init_mesh(V3 origin, V3 rotate, S32 nverts, Vertex *verts, S32 nindices, U32 *indices); -extern void clear_mesh(Mesh *mesh); -extern void add_mesh_texture(Mesh *mesh, Texture texture); - -extern Mesh gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h); -extern Mesh gen_circle(Arena *arena, V3 origin, V3 rotate, F32 r, S32 nverts); - -extern Model init_model(V3 origin, V3 rotate, S32 nmeshes, Mesh *meshes); -extern Model load_model(V3 origin, V3 rotate, const char *fname); diff --git a/prge_shader.c b/prge_shader.c deleted file mode 100644 index 3aee9b5..0000000 --- a/prge_shader.c +++ /dev/null @@ -1,93 +0,0 @@ -U32 compile_glsl_shader(U32 type, const char *fname) -{ - Arena *tmpa; - FLS src; - const char *csrc; - U32 id; - S32 status; - - tmpa = alloc_arena(0); - src = sys_read_entire_file_fls(tmpa, fname); - if (!src.p) { - sys_printf("[ERROR] : Failed to read \"%s\"\n", fname); - return 0; - } - csrc = (const char *)src.p; - - id = glCreateShader(type); - glShaderSource(id, 1, &csrc, 0); - glCompileShader(id); - - glGetShaderiv(id, GL_COMPILE_STATUS, &status); - if (status == GL_FALSE) { - char log[512]; - glGetShaderInfoLog(id, 512, 0, log); - sys_printf("[ERROR] : Failed to compile : \"%s\"\n%s", fname, log); - } else { - sys_printf("[INFO] : \"%s\" compiled successfully.\n", fname); - } - - release_arena(tmpa); - - return id; -} - -Shader load_shader(const char *vfname, const char *gfname, const char *ffname) -{ - Shader shader; - U32 vert, geom, frag; - S32 success; - - shader.id = glCreateProgram(); - - if (vfname) { - vert = compile_glsl_shader(GL_VERTEX_SHADER, vfname); - glAttachShader(shader.id, vert); - } - if (gfname) { - geom = compile_glsl_shader(GL_GEOMETRY_SHADER, gfname); - glAttachShader(shader.id, geom); - } - if (ffname) { - frag = compile_glsl_shader(GL_FRAGMENT_SHADER, ffname); - glAttachShader(shader.id, frag); - } - - glLinkProgram(shader.id); - glGetProgramiv(shader.id, GL_LINK_STATUS, &success); - - if (success == GL_FALSE) { - char log[512]; - glGetProgramInfoLog(shader.id, 512, 0, log); - sys_printf("[ERROR] : Failed to link shader program:\n%s", log); - } else { - sys_printf("[INFO] : Shader linked successfuly.\n\n"); - } - - if (vfname) - glDeleteShader(vert); - if (gfname) - glDeleteShader(geom); - if (ffname) - glDeleteShader(frag); - - return shader; -} - -void set3fv(U32 id, const char *name, V3 v) -{ - S32 loc = glGetUniformLocation(id, name); - glUniform3fv(loc, 1, (F32 *)&v); -} - -void set4fv(U32 id, const char *name, V4 v) -{ - S32 loc = glGetUniformLocation(id, name); - glUniform4fv(loc, 1, (F32 *)&v); -} - -void setmat4fv(U32 id, const char *name, MAT4 m) -{ - S32 loc = glGetUniformLocation(id, name); - glUniformMatrix4fv(loc, 1, 0, (F32 *)&m); -} diff --git a/prge_shader.h b/prge_shader.h deleted file mode 100644 index 36e95ad..0000000 --- a/prge_shader.h +++ /dev/null @@ -1,12 +0,0 @@ -#define PRGE_SHADER_POS_LOC 0 -#define PRGE_SHADER_TEXC_LOC 1 - -#define PRGE_SHADER_PROJ_MAT "proj" -#define PRGE_SHADER_VIEW_MAT "view" -#define PRGE_SHADER_MODEL_MAT "model" - -U32 compile_glsl_shader(U32 type, const char *fname); -Shader load_shader(const char *vfname, const char *gfname, const char *ffname); -void set3fv(U32 id, const char *name, V3 v); -void set4fv(U32 id, const char *name, V4 v); -void setmat4fv(U32 id, const char *name, MAT4 m); diff --git a/prge_texture.c b/prge_texture.c deleted file mode 100644 index e6c0820..0000000 --- a/prge_texture.c +++ /dev/null @@ -1,59 +0,0 @@ -Texture load_texture(Arena *arena, const char *fname, B32 gamma) -{ - Texture texture; - U8 *data; - S32 nchannels; - GLenum internal_format; - GLenum data_format; - S32 size; - - MEM0STRUCT(&texture); - - stbi_set_flip_vertically_on_load(1); - data = stbi_load(fname, &texture.w, &texture.h, &nchannels, 0); - - if (!data) { - sys_printf("[ERROR] : Texture : %s : Failed to load\n", fname); - goto end; - } - - switch (nchannels) { - case 1: - texture.type = TextureType_R; - internal_format = data_format = GL_RED; - break; - case 3: - texture.type = TextureType_RGB; - internal_format = (gamma) ? GL_SRGB : GL_RGB; - data_format = GL_RGB; - break; - case 4: - texture.type = TextureType_RGBA; - internal_format = (gamma) ? GL_SRGB_ALPHA : GL_RGBA; - data_format = GL_RGBA; - break; - default: - sys_printf("[ERROR] : Texture : %s : Unsupported type\n", fname); - goto end; - } - - size = texture.type*texture.w*texture.h; - texture.data = push_arena(arena, size); - MEMCPY(texture.data, data, size); - - glGenTextures(1, &texture.id); - glBindTexture(GL_TEXTURE_2D, texture.id); - glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.w, texture.h, - 0, data_format, GL_UNSIGNED_BYTE, texture.data); - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glBindTexture(GL_TEXTURE_2D, 0); - - sys_printf("[INFO] : Texture : %s : Loaded successfully\n", fname); -end: - stbi_image_free(data); - return texture; -} diff --git a/prge_texture.h b/prge_texture.h deleted file mode 100644 index d8fe72f..0000000 --- a/prge_texture.h +++ /dev/null @@ -1 +0,0 @@ -Texture load_texture(Arena *arena, const char *fname, B32 gamma); diff --git a/prge_types.h b/prge_types.h deleted file mode 100644 index a41d110..0000000 --- a/prge_types.h +++ /dev/null @@ -1,166 +0,0 @@ -typedef struct { - S32 w; - S32 h; - const char *name; - U32 flags; -} PRGEWindow; - -typedef enum { - KeyState_RELEASE = 0, - KeyState_PRESS = 1 -} KeyStateEnum; - -typedef struct { - KeyStateEnum last; - KeyStateEnum state; -} Key; - -typedef struct { - V2 mouse_pos; - V2 last_mouse_pos; - V2 mouse_offset; - B32 first_mouse; - B32 capture_mouse; - Key mouse_left; - Key mouse_right; - - F32 dt; - - Key move_right; - Key move_forward; - Key move_left; - Key move_backward; - - Key move_up; - Key move_down; - - Key jump; - - Key action_right; - Key action_up; - Key action_left; - Key action_down; - - Key exit; -} Input; - -typedef enum { - TextureType_R = 1, - TextureType_RGB = 3, - TextureType_RGBA = 4 -} TextureTypeEnum; - -typedef struct { - U32 id; - const char *name; - - TextureTypeEnum type; - - S32 w; - S32 h; - - U8 *data; -} Texture; - -typedef struct { - V3 pos; - V2 texc; -} Vertex; - -#define PRGE_MAX_TEXTURES 2 -#define PRGE_MAX_MESHES 8 -#define PRGE_MAX_MODELS 8 - -typedef struct { - U32 id; - const char *name; -} Shader; - -typedef struct { - V3 transl; - V3 rotate; - V3 scale; -} Transform; - -typedef struct { - V3 origin; - V3 rotate; - - S32 nverts; - Vertex *verts; - - S32 nindices; - U32 *indices; - - S32 ntextures; - Texture textures[PRGE_MAX_TEXTURES]; - - U32 vao, vbo, ebo; -} Mesh; - -typedef struct { - U32 id; - - V3 origin; - V3 rotate; - - S32 nmeshes; - Mesh *meshes; -} Model; - -typedef struct { - V3 pos; - - F32 fov; - - F32 near; - F32 far; - - F32 yaw; - F32 pitch; - F32 roll; -} Camera; - -#define PRGE_MAX_SOUNDS_LOADED 4 -#define PRGE_MAX_SOUNDS_PLAYING 2 - -typedef struct { - S32 channels; - S32 sample_rate; - S32 bytes_per_sample; - - S32 size; - U8 *data; - - const char *name; -} Sound; - -typedef struct SoundQueueNode { - Sound *snd; - struct SoundQueueNode *next; - struct SoundQueueNode *prev; -} SoundQueueNode; - -typedef struct { - S32 cnt; - struct SoundQueueNode *first; - struct SoundQueueNode *last; -} SoundQueue; - -typedef struct { - B32 should_close; - - Arena *pa; - Arena *tmpa; - - Input in; - - /* TODO(pryazha): Probably a bad idea to have only one window 🙃*/ - PRGEWindow wnd; - - Sound snds[PRGE_MAX_SOUNDS_LOADED]; - SoundQueueNode nodes[PRGE_MAX_SOUNDS_PLAYING]; - SoundQueue sndq; - - const char *bindir; -} PRGEContext; diff --git a/prge_window.c b/prge_window.c deleted file mode 100644 index f132102..0000000 --- a/prge_window.c +++ /dev/null @@ -1,10 +0,0 @@ -PRGEWindow init_window(S32 w, S32 h, const char *name, U32 flags) -{ - PRGEWindow wnd = { - .w = w, - .h = h, - .name = name, - .flags = flags - }; - return wnd; -} diff --git a/prge_window.h b/prge_window.h deleted file mode 100644 index 5d9d086..0000000 --- a/prge_window.h +++ /dev/null @@ -1,4 +0,0 @@ -#define PRGE_WINDOW_DEPTH_TEST 0x1 -#define PRGE_WINDOW_MULTISAMPLE 0x10 - -PRGEWindow init_window(S32 w, S32 h, const char *name, U32 flags); diff --git a/shader.h b/shader.h new file mode 100644 index 0000000..189225a --- /dev/null +++ b/shader.h @@ -0,0 +1,105 @@ +shader_t compile_gl_shader(u32 type, char **src) +{ + shader_t shader = {0}; + shader.id = glCreateShader(type); + glShaderSource(shader.id, 1, (const char **)src, 0); + glCompileShader(shader.id); + + i32 status; + glGetShaderiv(shader.id, GL_COMPILE_STATUS, &status); + if (status == GL_FALSE) + glGetShaderInfoLog(shader.id, MAX_SHADER_LOG, 0, shader.log); + else + snprintf(shader.log, MAX_SHADER_LOG, "compiled successfully"); + + return shader; +} + +shader_t compile_gl_shader_file(u32 type, const char *filename) +{ + char *src; + shader_t shader = {0}; + + arena_t tmp = alloc_arena(0); + if (!sys_read_file(&tmp, &src, filename)) { + printf("error: failed to read: \"%s\"\n", filename); + release_arena(&tmp); + return shader; + } + shader = compile_gl_shader(type, &src); + release_arena(&tmp); + + if (!shader.id) + printf("error: \"%s\": ", filename); + else + printf("info: \"%s\": ", filename); + printf("%s", shader.log); + printf("\n"); + + return shader; +} + +shader_t load_gl_shader(const char *dir, const char *vert_filename, const char *geom_filename, const char *frag_filename) +{ + shader_t shader = {0}; + shader.id = glCreateProgram(); + + char full_path[MAX_PATH]; + shader_t vert; + if (vert_filename) { + snprintf(full_path, sizeof(full_path), "%s/%s", dir, vert_filename); + vert = compile_gl_shader_file(GL_VERTEX_SHADER, full_path); + glAttachShader(shader.id, vert.id); + } + + shader_t geom; + if (geom_filename) { + snprintf(full_path, sizeof(full_path), "%s/%s", dir, geom_filename); + geom = compile_gl_shader_file(GL_GEOMETRY_SHADER, full_path); + glAttachShader(shader.id, geom.id); + } + + shader_t frag; + if (frag_filename) { + snprintf(full_path, sizeof(full_path), "%s/%s", dir, frag_filename); + frag = compile_gl_shader_file(GL_FRAGMENT_SHADER, full_path); + glAttachShader(shader.id, frag.id); + } + + i32 status; + glLinkProgram(shader.id); + glGetProgramiv(shader.id, GL_LINK_STATUS, &status); + if (status == GL_FALSE) { + glGetProgramInfoLog(shader.id, MAX_SHADER_LOG, 0, shader.log); + printf("error: failed to link shader program:\n%s", shader.log); + } else { + printf("info: shader linked successfuly\n\n"); + } + + if (vert_filename) + glDeleteShader(vert.id); + if (geom_filename) + glDeleteShader(geom.id); + if (frag_filename) + glDeleteShader(frag.id); + + return shader; +} + +void shader_set_v3(shader_t shader, const char *name, v3 vec) +{ + i32 location = glGetUniformLocation(shader.id, name); + glUniform3fv(location, 1, (f32 *)&vec); +} + +void shader_set_v4(shader_t shader, const char *name, v4 vec) +{ + i32 location = glGetUniformLocation(shader.id, name); + glUniform4fv(location, 1, (f32 *)&vec); +} + +void shader_set_mat4(shader_t shader, const char *name, mat4 mat) +{ + i32 location = glGetUniformLocation(shader.id, name); + glUniformMatrix4fv(location, 1, 0, (f32 *)&mat); +} diff --git a/texture.h b/texture.h new file mode 100644 index 0000000..c51e411 --- /dev/null +++ b/texture.h @@ -0,0 +1,55 @@ +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +texture_t load_texture(arena_t *arena, const char *filename, i32 gamma) +{ + texture_t texture = {0}; + i32 nchannels; + stbi_set_flip_vertically_on_load(1); + u8 *data = stbi_load(filename, &texture.width, &texture.height, &nchannels, 0); + if (!data) { + printf("error: \"%s\" failed to load\n", filename); + return texture; + } + + u32 internal_format, data_format; + switch (nchannels) { + case 1: + texture.type = texture_type_r; + internal_format = data_format = GL_RED; + break; + case 3: + texture.type = texture_type_rgb; + internal_format = gamma ? GL_SRGB : GL_RGB; + data_format = GL_RGB; + break; + case 4: + texture.type = texture_type_rgba; + internal_format = gamma ? GL_SRGB_ALPHA : GL_RGBA; + data_format = GL_RGBA; + break; + default: + printf("error: \"%s\" unsupported type\n", filename); + goto end; + } + + u64 size = texture.type * texture.width * texture.height; + texture.data = push_arena(arena, size); + prb_memmove(texture.data, data, size); + + glGenTextures(1, &texture.id); + glBindTexture(GL_TEXTURE_2D, texture.id); + glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, + 0, data_format, GL_UNSIGNED_BYTE, texture.data); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glBindTexture(GL_TEXTURE_2D, 0); + + printf("info: \"%s\" loaded successfully\n", filename); +end: + stbi_image_free(data); + return texture; +} diff --git a/types.h b/types.h new file mode 100644 index 0000000..6fd5799 --- /dev/null +++ b/types.h @@ -0,0 +1,231 @@ +#define WINDOW_DEPTH_TEST 0x1 +#define WINDOW_MULTISAMPLE 0x10 + +typedef struct { + i32 width; + i32 height; + const char *name; + u32 flags; +} prge_window_t; + +typedef enum { + key_state_release = 0, + key_state_press = 1 +} key_state_enum; + +typedef struct { + key_state_enum last; + key_state_enum state; +} prge_key_t; + +typedef struct { + v2 pos; + v2 last; + v2 offset; + i32 first; + i32 capture; + prge_key_t left; + prge_key_t right; +} mouse_t; + +typedef struct { + mouse_t mouse; + + prge_key_t move_right; + prge_key_t move_forward; + prge_key_t move_left; + prge_key_t move_backward; + prge_key_t move_up; + prge_key_t move_down; + + prge_key_t jump; + prge_key_t action_right; + prge_key_t action_up; + prge_key_t action_left; + prge_key_t action_down; + prge_key_t exit; + + f32 dt; +} input_t; + +typedef enum { + texture_type_r = 1, + texture_type_rgb = 3, + texture_type_rgba = 4 +} texture_type_enum; + +typedef struct { + u32 id; + const char *name; + texture_type_enum type; + i32 width; + i32 height; + u8 *data; +} texture_t; + +#define SHADER_POSITION_LOCATION 0 +#define SHADER_NORMAL_LOCATION 1 +#define SHADER_TEXCOORDS_LOCATION 2 + +#define SHADER_PROJECTION_MATRIX "projection" +#define SHADER_VIEW_MATRIX "view" +#define SHADER_MODEL_MATRIX "model" + +#define MAX_SHADER_LOG 512 + +typedef struct { + u32 id; + char log[MAX_SHADER_LOG]; +} shader_t; + +typedef struct { + v3 position; + v3 normal; + v2 texcoords; +} vertex_t; + +#define DEFAULT_TRANSFORM (transform_t){V3_ZERO, V3_ZERO, V3_ONE} + +typedef struct { + v3 position; + v3 rotation; + v3 scale; +} transform_t; + +#define MAX_TEXTURE_PER_MESH 2 + +typedef struct { + transform_t transform; + + i32 nvertices; + vertex_t *vertices; + + i32 nindices; + u32 *indices; + + i32 ntextures; + texture_t textures[MAX_TEXTURE_PER_MESH]; + + u32 vao; + u32 vbo; + u32 ebo; +} mesh_t; + +typedef struct { + transform_t transform; + i32 nmeshes; + mesh_t *meshes; +} model_t; + +#define BBOX_UNIT (bbox_t){{-0.5f, -0.5f, -0.5f}, {0.5f, 0.5f, 0.5f}} +#define BBOX_ZERO (bbox_t){V3_ZERO, V3_ZERO} + +typedef struct { + v3 start; + v3 end; +} bbox_t; + +#define ENTITY_COLLIDE (1) +#define ENTITY_MOVE (1 << 1) +#define ENTITY_ALPHA (1 << 2) + +typedef struct { + u32 flags; + + model_t model; + + v3 position; + v3 velocity; + bbox_t bbox; +} entity_t; + +#define MAX_ENTITIES 4 + +typedef struct enode_t { + i32 id; + entity_t entity; + struct enode_t *next; + struct enode_t *prev; +} enode_t; + +typedef struct { + i32 count; + enode_t nodes[MAX_ENTITIES]; + struct enode_t *first; + struct enode_t *last; +} elist_t; + +#define DEFAULT_CAMERA (camera_t){v3_ZERO, 90.0f, 0.1f, 1000.0f, V3_ZERO} + +typedef struct { + v3 position; + + f32 fov; + + f32 near; + f32 far; + + v3 angles; +} camera_t; + +typedef struct { + i32 channels; + i32 freq; + i32 bps; + + i32 size; + unsigned char *data; + + const char *name; +} sound_t; + +typedef struct sound_queue_node_t { + sound_t *sound; + struct sound_queue_node_t *next; + struct sound_queue_node_t *prev; +} sound_queue_node_t; + +typedef struct { + i32 count; + struct sound_queue_node_t *first; + struct sound_queue_node_t *last; +} sound_queue_t; + +#define ARENA_SIZE megabytes(64) +#define FRAME_ARENA_SIZE megabytes(16) + +#define MAX_SOUNDS_LOADED 8 +#define MAX_SOUNDS_PLAYING 4 + +typedef struct { + i32 should_close; + + arena_t arena; + arena_t frame_arena; + + input_t input; + + /* TODO(pryazha): Probably a bad idea to have only one window 🙃*/ + prge_window_t window; + + sound_t sounds[MAX_SOUNDS_LOADED]; + sound_queue_node_t sound_queue_nodes[MAX_SOUNDS_PLAYING]; + sound_queue_t sound_queue; + + elist_t entities; + + const char *dir; +} prge_context_t; + +typedef enum {ui_list, ui_stack} ui_layout_enum; + +typedef struct { + prge_window_t window; + input_t input; + shader_t shader; + rect_t rect; + ui_layout_enum layout; + v2 last; + arena_t *arena; + f32 padding; +} ui_t; -- cgit v1.2.3-70-g09d2