summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--prge.h47
-rw-r--r--prge_audio.c75
-rw-r--r--prge_audio.h6
-rw-r--r--prge_camera.c48
-rw-r--r--prge_camera.h13
-rw-r--r--prge_draw.c78
-rw-r--r--prge_draw.h8
-rw-r--r--prge_gui.c59
-rw-r--r--prge_gui.h9
-rw-r--r--prge_input.c63
-rw-r--r--prge_input.h15
-rw-r--r--prge_model.c209
-rw-r--r--prge_model.h23
-rw-r--r--prge_shader.c97
-rw-r--r--prge_shader.h15
-rw-r--r--prge_texture.c50
-rw-r--r--prge_texture.h7
-rw-r--r--prge_types.h100
-rw-r--r--prge_window.c14
-rw-r--r--prge_window.h8
20 files changed, 559 insertions, 385 deletions
diff --git a/prge.h b/prge.h
index 3629d8b..90271b3 100644
--- a/prge.h
+++ b/prge.h
@@ -3,30 +3,45 @@
#include "prb.h"
-#include "prge_types.h"
-
-#include "prge_window.h"
-#include "prge_window.c"
-
-#include "prge_input.h"
-#include "prge_input.c"
-
#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_texture.c"
-
#include "prge_shader.h"
-#include "prge_shader.c"
-
#include "prge_model.h"
-#include "prge_model.c"
-
#include "prge_camera.h"
-#include "prge_camera.c"
-
+#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);
+}
#endif /* PRGE_H */
diff --git a/prge_audio.c b/prge_audio.c
new file mode 100644
index 0000000..08fb67c
--- /dev/null
+++ b/prge_audio.c
@@ -0,0 +1,75 @@
+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
new file mode 100644
index 0000000..5f07a2c
--- /dev/null
+++ b/prge_audio.h
@@ -0,0 +1,6 @@
+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
index 242b33d..0a79a74 100644
--- a/prge_camera.c
+++ b/prge_camera.c
@@ -1,30 +1,26 @@
-Camera camera_init(V3 pos, F32 fov, F32 near, F32 far,
- F32 yaw, F32 pitch, F32 roll)
+Camera initcam(V3 pos, F32 fov, F32 near, F32 far, F32 yaw, F32 pitch, F32 roll)
{
- Camera c;
-
- c.pos = pos;
- c.fov = fov;
- c.near = near;
- c.far = far;
- c.yaw = yaw;
- c.pitch = pitch;
- c.roll = roll;
-
+ Camera c = {
+ .pos = pos,
+ .fov = fov,
+ .near = near,
+ .far = far,
+ .yaw = yaw,
+ .pitch = pitch,
+ .roll = roll,
+ };
return c;
}
-MAT4 camera_get_view_matrix_first_person(Camera *c)
+MAT4 getfpviewmat(Camera *c)
{
MAT4 v;
-
- v = mat4transl(MAT4_IDENTITY, v3inv(c->pos));
- v = mat4rotate(v, v3(c->pitch, c->yaw, c->roll));
-
+ v = translmat4(MAT4_IDENTITY, invv3(c->pos));
+ v = rotatemat4(v, v3(c->pitch, c->yaw, c->roll));
return v;
}
-void camera_get_vectors_first_person(Camera *c, V3 *r, V3 *u, V3 *f)
+void getfpvecs(Camera *c, V3 *l, V3 *u, V3 *f)
{
F32 angle, cp, sp, cy, sy, cr, sr;
@@ -38,23 +34,23 @@ void camera_get_vectors_first_person(Camera *c, V3 *r, V3 *u, V3 *f)
cr = f32cos(angle);
sr = f32sin(angle);
- *r = v3(cy*cr, -cy*sr, sy);
+ *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 camera_look_at(Camera c, V3 t, V3 wup)
+MAT4 lookat(Camera c, V3 t, V3 wup)
{
V3 f, r, u;
MAT4 transl, rotate, res;
- f = v3norm(v3sub(c.pos, t));
- r = v3norm(v3cross(wup, f));
- u = v3cross(f, r);
+ f = normv3(subv3(c.pos, t));
+ r = normv3(crossv3(wup, f));
+ u = crossv3(f, r);
- transl = mat4transl(MAT4_IDENTITY, v3inv(c.pos));
- rotate = mat4transp(mat4_change_basis(r, u, f));
- res = mat4mul(rotate, transl);
+ transl = translmat4(MAT4_IDENTITY, invv3(c.pos));
+ rotate = transpmat4(rotateaxismat4(r, u, f));
+ res = mulmat4(rotate, transl);
return res;
}
diff --git a/prge_camera.h b/prge_camera.h
index 33957e5..f938b8b 100644
--- a/prge_camera.h
+++ b/prge_camera.h
@@ -1,12 +1,7 @@
-#ifndef PRGE_CAMERA_H
-#define PRGE_CAMERA_H
-
-Camera camera_init(V3 pos, F32 fov, F32 near, F32 far, F32 yaw, F32 pitch, F32 roll);
-MAT4 camera_get_view_matrix_first_person(Camera *c);
-void camera_get_vectors_first_person(Camera *c, V3 *l, V3 *u, V3 *f);
-MAT4 camera_look_at(Camera c, V3 t, V3 wup);
+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);
-
-#endif /* PRGE_CAMERA_H */
diff --git a/prge_draw.c b/prge_draw.c
new file mode 100644
index 0000000..4228d68
--- /dev/null
+++ b/prge_draw.c
@@ -0,0 +1,78 @@
+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
new file mode 100644
index 0000000..087b5ac
--- /dev/null
+++ b/prge_draw.h
@@ -0,0 +1,8 @@
+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
index f1d03d7..b4be331 100644
--- a/prge_gui.c
+++ b/prge_gui.c
@@ -1,4 +1,4 @@
-B32 in_rect(V2 pos, V2 start, V2 end)
+B32 inrect(V2 pos, V2 start, V2 end)
{
B32 res;
res = ((pos.x > start.x) && (pos.x < end.x) &&
@@ -6,38 +6,55 @@ B32 in_rect(V2 pos, V2 start, V2 end)
return res;
}
-B32 button(Window *wnd, U32 shader, Input *input, Arena *arena,
- Str8 name, V2 center, F32 w, F32 h)
+void beginui(Shader shader, PRGEWindow wnd)
{
- B32 res;
- Mesh *quad;
+ 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;
- Str8 info;
- res = 0;
+ MAT4 model;
+ V4 color;
- quad = mesh_gen_quad(arena, v3fromv2(center), V3_ZERO, w, h);
+ pressed = 0;
- shader_set_4fv(shader, "color", v4(1.0f, 0.0f, 0.0f, 1.0f));
+ 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 (in_rect(input->mouse_pos, start, end) &&
- !input->capture_mouse)
- {
- shader_set_4fv(shader, "color", v4(0.0f, 0.0f, 1.0f, 1.0f));
- if (key_first_press(input->mouse_left))
- res = 1;
+
+ 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 = mat4transl(MAT4_IDENTITY, v3(center.x, wnd->height-center.y, 0.0f));
+ model = translmat4(MAT4_IDENTITY, v3(center.x, prgectx->wnd.h-center.y, 0.0f));
- shader_set_mat4fv(shader, "model", model);
+ setmat4fv(shader.id, "model", model);
+ set4fv(shader.id, "color", color);
- mesh_draw(quad);
+ draw_mesh(quad);
- mesh_clear(quad);
+ clear_mesh(&quad);
- return res;
+ return pressed;
}
diff --git a/prge_gui.h b/prge_gui.h
index 72fc11a..c267466 100644
--- a/prge_gui.h
+++ b/prge_gui.h
@@ -1,7 +1,6 @@
-#ifndef PRGE_GUI_H
-#define PRGE_GUI_H
+B32 inrect(V2 pos, V2 start, V2 end);
-B32 in_rect(V2 pos, V2 start, V2 end);
-B32 button(Window *wnd, U32 shader, Input *input, Arena *arena, Str8 name, V2 center, F32 w, F32 h);
+void beginui(Shader shader, PRGEWindow wnd);
+void endui(void);
-#endif /* PRGE_GUI_H */
+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
index b841d6a..74de9e5 100644
--- a/prge_input.c
+++ b/prge_input.c
@@ -1,48 +1,51 @@
-Input input_init()
+Input init_input()
{
- Input input = {0};
- input.first_mouse = 1;
- input.is_running = 1;
- return input;
+ Input in;
+
+ MEM0STRUCT(&in);
+
+ in.first_mouse = 1;
+
+ return in;
}
-void input_update(Input *input)
+/* NOTE(pryazha): Updates the last states of keys, mouse position and offset.
+ * Should be called every frame */
+void update_input(Input *in)
{
- input->last_mouse_pos = 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;
+ 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 key_is_pressed(Key key)
+B32 is_key_down(Key key)
{
B32 r = (key.state == KeyState_PRESS);
return r;
}
-B32 key_first_press(Key key)
+B32 is_key_pressed(Key key)
{
- B32 r = ((key.last == KeyState_RELEASE) &&
- (key.state == KeyState_PRESS));
+ B32 r = ((key.last == KeyState_RELEASE) && (key.state == KeyState_PRESS));
return r;
}
-B32 key_was_pressed(Key key)
+B32 was_key_pressed(Key key)
{
- B32 r = ((key.last == KeyState_PRESS) &&
- (key.state == KeyState_RELEASE));
+ B32 r = ((key.last == KeyState_PRESS) && (key.state == KeyState_RELEASE));
return r;
}
diff --git a/prge_input.h b/prge_input.h
index a5a77c7..fe9c01f 100644
--- a/prge_input.h
+++ b/prge_input.h
@@ -1,10 +1,5 @@
-#ifndef PRGE_INPUT_H
-#define PRGE_INPUT_H
-
-Input input_init();
-void input_update(Input *input);
-B32 key_is_pressed(Key key);
-B32 key_first_press(Key key);
-B32 key_was_pressed(Key key);
-
-#endif /* PRGE_INPUT_H */
+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
index 44ded76..e2dc55f 100644
--- a/prge_model.c
+++ b/prge_model.c
@@ -1,70 +1,72 @@
-Vertex vert(V3 pos, V2 texc)
+Vertex init_vert(V3 pos, V2 texc)
{
- Vertex v;
-
- v.pos = pos;
- v.texc = texc;
-
+ Vertex v = {
+ .pos = pos,
+ .texc = texc,
+ };
return v;
}
-void mesh_init_buffers(Mesh *mesh)
+void init_mesh_buffers(Mesh *mesh)
{
- Assert(mesh->verts);
- Assert(mesh->nverts > 0);
-
+ 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, mesh->nverts*sizeof(Vertex), mesh->verts, GL_STATIC_DRAW);
+ 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, mesh->nindices*sizeof(U32), mesh->indices, GL_STATIC_DRAW);
+ 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), OffsetOfMember(Vertex, pos));
+ 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 *)OffsetOfMember(Vertex, texc));
+ glVertexAttribPointer(PRGE_SHADER_TEXC_LOC, 2,
+ GL_FLOAT, GL_FALSE, sizeof(Vertex),
+ (void *)OFFSETOF(Vertex, texc));
+
glBindVertexArray(0);
}
-Mesh *mesh_init(Arena *arena, V3 origin, V3 rotate, Vertex *verts, U32 nverts, U32 *indices, U32 nindices)
+Mesh init_mesh(V3 origin, V3 rotate, S32 nverts, Vertex *verts, S32 nindices, U32 *indices)
{
- Mesh *mesh;
-
- mesh = arena_push(arena, sizeof(Mesh));
-
- mesh->origin = origin;
- mesh->rotate = rotate;
+ Mesh mesh;
+
+ MEM0STRUCT(&mesh);
- mesh->verts = verts;
- mesh->nverts = nverts;
+ mesh.origin = origin;
+ mesh.rotate = rotate;
- mesh->indices = indices;
- mesh->nindices = nindices;
+ mesh.verts = verts;
+ mesh.nverts = nverts;
- mesh->ntextures = 0;
- MemoryZeroArray(mesh->textures);
+ mesh.indices = indices;
+ mesh.nindices = nindices;
- mesh_init_buffers(mesh);
+ init_mesh_buffers(&mesh);
return mesh;
}
-void mesh_add_texture(Mesh *mesh, Texture texture)
-{
- Assert(mesh->ntextures+1 <= MAX_TEXTURE);
- mesh->textures[mesh->ntextures++] = texture;
-}
-
-void mesh_clear(Mesh *mesh)
+void clear_mesh(Mesh *mesh)
{
glBindVertexArray(mesh->vao);
glDisableVertexAttribArray(PRGE_SHADER_POS_LOC);
@@ -79,43 +81,37 @@ void mesh_clear(Mesh *mesh)
glDeleteBuffers(1, &mesh->ebo);
}
-void mesh_draw(Mesh *mesh)
+void add_mesh_texture(Mesh *mesh, Texture texture)
{
- 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->ntextures+1 >= PRGE_MAX_TEXTURES) {
+ sys_printf("[WARNING] : Texture : \"%s\" : limit\n", texture.name);
+ return;
}
+ mesh->textures[mesh->ntextures++] = texture;
+}
- if (mesh->ebo)
- glDrawElements(GL_TRIANGLES, mesh->nindices, GL_UNSIGNED_INT, 0);
- else
- glDrawArrays(GL_TRIANGLES, 0, mesh->nverts);
-
- glBindVertexArray(0);
-}
-
-Mesh *mesh_gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h)
+Mesh gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h)
{
- Mesh *m;
+ Mesh mesh;
+
+ S32 nverts;
Vertex *verts;
+
+ S32 nindices;
U32 *indices;
- U32 nverts, nindices;
+
+ ASSERT(w > 0);
+ ASSERT(h > 0);
nverts = 4;
- verts = arena_push(arena, nverts*sizeof(Vertex));
- verts[0] = vert(v3(-w/2.0f, -h/2.0f, 0.0f), v2(0.0f, 0.0f));
- verts[1] = vert(v3(-w/2.0f, h/2.0f, 0.0f), v2(0.0f, 1.0f));
- verts[2] = vert(v3(w/2.0f, -h/2.0f, 0.0f), v2(1.0f, 0.0f));
- verts[3] = vert(v3(w/2.0f, h/2.0f, 0.0f), v2(1.0f, 1.0f));
+ 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 = arena_push(arena, nindices*sizeof(U32));
+ indices = push_arena(arena, nindices*sizeof(U32));
indices[0] = 0;
indices[1] = 1;
indices[2] = 3;
@@ -123,90 +119,69 @@ Mesh *mesh_gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h)
indices[4] = 2;
indices[5] = 3;
- m = mesh_init(arena, origin, rotate, verts, nverts, indices, nindices);
+ mesh = init_mesh(origin, rotate, nverts, verts, nindices, indices);
- return m;
+ return mesh;
}
-Mesh *mesh_gen_circle(Arena *arena, V3 origin, V3 rotate, F32 r, U32 nverts)
+Mesh gen_circle(Arena *arena, V3 origin, V3 rotate, F32 r, S32 nverts)
{
- Mesh *m;
+ Mesh mesh;
+
Vertex *verts;
+
+ S32 nindices;
U32 *indices;
- U32 nindices;
+
F32 angle, dangle;
- U32 i, vi;
+
+ S32 i, vi;
if (nverts < 3)
nverts = 3;
- verts = arena_push(arena, nverts*sizeof(Vertex));
+ verts = push_arena(arena, nverts*sizeof(Vertex));
- dangle = 2*F32_PI/(F32)nverts;
+ dangle = 2*F32PI/(F32)nverts;
for (i = 0, angle = 0.0f; i < nverts; i++, angle += dangle)
- verts[i] = vert(v3(f32cos(angle)*r, f32sin(angle)*r, 0.0f), V2_ZERO);
+ verts[i] = init_vert(v3(f32cos(angle)*r, f32sin(angle)*r, 0.0f), V2_ZERO);
nindices = nverts*3;
- indices = arena_push(arena, nindices*sizeof(U32));
+ 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));
}
- m = mesh_init(arena, origin, rotate, verts, nverts, indices, nindices);
-
- return m;
-}
-
-Model *model_init(Arena *arena, V3 origin, V3 rotate, Mesh *meshes, U32 nmeshes)
-{
- Model *res;
+ mesh = init_mesh(origin, rotate, nverts, verts, nindices, indices);
- res = arena_push(arena, sizeof(Model));
-
- res->origin = origin;
- res->rotate = rotate;
- res->meshes = meshes;
- res->nmeshes = nmeshes;
-
- return res;
+ return mesh;
}
-Model *model_load(Arena *arena, V3 origin, V3 rotate, Str8 filename)
+Model init_model(V3 origin, V3 rotate, S32 nmeshes, Mesh *meshes)
{
- Model *res;
-
- res = 0;
-
- /* TODO(pryazha): Load models with assimp? */
-
- return res;
+ Model model = {
+ .origin = origin,
+ .rotate = rotate,
+ .nmeshes = nmeshes,
+ .meshes = meshes,
+ };
+ return model;
}
-void model_draw(U32 shader, MAT4 *proj, MAT4 *view, Model *model)
+Model load_model(V3 origin, V3 rotate, const char *fname)
{
- U32 i;
- MAT4 modelmat, meshmodelmat, resmodelmat;
- V3 resorigin, resrotate;
-
- glUseProgram(shader);
-
- shader_set_mat4fv(shader, PRGE_SHADER_PROJ_MAT, *proj);
- shader_set_mat4fv(shader, PRGE_SHADER_VIEW_MAT, *view);
+ Model model;
- modelmat = mat4rotate(MAT4_IDENTITY, model->rotate);
- modelmat = mat4transl(modelmat, model->origin);
+ MEM0STRUCT(&model);
- for (i = 0; i < model->nmeshes; i++) {
- meshmodelmat = mat4rotate(MAT4_IDENTITY, model->meshes[i].rotate);
- meshmodelmat = mat4transl(meshmodelmat, model->meshes[i].origin);
+ model.origin = origin;
+ model.rotate = rotate;
- resmodelmat = mat4mul(modelmat, meshmodelmat);
+ sys_printf("[INFO] : PRGE : Trying to load %s\n", fname);
- shader_set_mat4fv(shader, PRGE_SHADER_MODEL_MAT, resmodelmat);
- mesh_draw(&model->meshes[i]);
- }
+ /* TODO(pryazha): Load models with assimp? */
- glUseProgram(0);
+ return model;
}
diff --git a/prge_model.h b/prge_model.h
index d747232..b2e6f1e 100644
--- a/prge_model.h
+++ b/prge_model.h
@@ -1,18 +1,11 @@
-#ifndef PRGE_MODEL_H
-#define PRGE_MODEL_H
+extern Vertex init_vert(V3 pos, V2 texc);
-#define MAX_TEXTURE 5
+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);
-Vertex vert_init(V3 pos, V2 texc);
+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);
-Mesh *mesh_init(Arena *arena, V3 origin, V3 rotate, Vertex *verts, U32 nverts, U32 *indices, U32 nindices);
-void mesh_add_texture(Mesh *mesh, Texture texture);
-Mesh *mesh_gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h);
-Mesh *mesh_gen_circle(Arena *arena, V3 origin, V3 rotate, F32 r, U32 nverts);
-void mesh_draw(Mesh *mesh);
-
-Model *model_init(Arena *arena, V3 origin, V3 rotate, Mesh *meshes, U32 nmeshes);
-Model *model_load(Arena *arena, V3 origin, V3 rotate, Str8 filename);
-void model_draw(U32 shader, MAT4 *proj, MAT4 *view, Model *model);
-
-#endif /* PRGE_MODEL_H */
+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
index 96b50f1..3aee9b5 100644
--- a/prge_shader.c
+++ b/prge_shader.c
@@ -1,21 +1,18 @@
-U32 compile_shader(GLenum type, Str8 filename)
+U32 compile_glsl_shader(U32 type, const char *fname)
{
- Arena *tmp;
- Str8 src;
+ Arena *tmpa;
+ FLS src;
+ const char *csrc;
U32 id;
S32 status;
- const char *csrc;
-
- tmp = arena_alloc(0);
- src = str8_read_entire_file(tmp, filename);
- if (!src.ptr || !src.length) {
- str8print(str8pushf(tmp, "[ERROR] : Failed to read \"%.*s\"\n", str8expand(filename)));
- arena_release(tmp);
+ 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 = str8tocstr(tmp, src);
+ csrc = (const char *)src.p;
id = glCreateShader(type);
glShaderSource(id, 1, &csrc, 0);
@@ -25,76 +22,72 @@ U32 compile_shader(GLenum type, Str8 filename)
if (status == GL_FALSE) {
char log[512];
glGetShaderInfoLog(id, 512, 0, log);
- str8print(str8pushf(tmp, "[ERROR] : Failed to compile : \"%.*s\"\n%s", str8expand(filename), log));
+ sys_printf("[ERROR] : Failed to compile : \"%s\"\n%s", fname, log);
} else {
- str8print(str8pushf(tmp, "[INFO] : \"%.*s\" compiled successfully.\n", str8expand(filename)));
+ sys_printf("[INFO] : \"%s\" compiled successfully.\n", fname);
}
- arena_release(tmp);
+ release_arena(tmpa);
return id;
}
-U32 load_shader(char *vert_filename, char *geom_filename, char *frag_filename)
+Shader load_shader(const char *vfname, const char *gfname, const char *ffname)
{
- U32 vert, geom, frag, id;
- Arena *tmp;
+ Shader shader;
+ U32 vert, geom, frag;
S32 success;
- if (vert_filename)
- vert = compile_shader(GL_VERTEX_SHADER, str8fromcstr(vert_filename));
- if (geom_filename)
- geom = compile_shader(GL_GEOMETRY_SHADER, str8fromcstr(geom_filename));
- if (frag_filename)
- frag = compile_shader(GL_FRAGMENT_SHADER, str8fromcstr(frag_filename));
+ shader.id = glCreateProgram();
- tmp = arena_alloc(0);
+ 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);
- id = glCreateProgram();
- if (vert_filename)
- glAttachShader(id, vert);
- if (geom_filename)
- glAttachShader(id, geom);
- if (frag_filename)
- glAttachShader(id, frag);
- glLinkProgram(id);
- glGetProgramiv(id, GL_LINK_STATUS, &success);
if (success == GL_FALSE) {
char log[512];
- glGetProgramInfoLog(id, 512, 0, log);
- str8print(str8pushf(tmp, "[ERROR] : Failed to link shader program:\n%s", log));
+ glGetProgramInfoLog(shader.id, 512, 0, log);
+ sys_printf("[ERROR] : Failed to link shader program:\n%s", log);
} else {
- str8print(str8pushf(tmp, "[INFO] : Shader linked successfuly.\n\n"));
+ sys_printf("[INFO] : Shader linked successfuly.\n\n");
}
- if (vert_filename)
+
+ if (vfname)
glDeleteShader(vert);
- if (geom_filename)
+ if (gfname)
glDeleteShader(geom);
- if (frag_filename)
+ if (ffname)
glDeleteShader(frag);
- arena_release(tmp);
-
- return id;
+ return shader;
}
-void shader_set_3fv(U32 id, char *name, V3 v)
+void set3fv(U32 id, const char *name, V3 v)
{
- S32 loc;
- loc = glGetUniformLocation(id, name);
+ S32 loc = glGetUniformLocation(id, name);
glUniform3fv(loc, 1, (F32 *)&v);
}
-void shader_set_4fv(U32 id, char *name, V4 v)
+void set4fv(U32 id, const char *name, V4 v)
{
- S32 loc;
- loc = glGetUniformLocation(id, name);
+ S32 loc = glGetUniformLocation(id, name);
glUniform4fv(loc, 1, (F32 *)&v);
}
-void shader_set_mat4fv(U32 id, char *name, MAT4 m)
+void setmat4fv(U32 id, const char *name, MAT4 m)
{
- S32 loc;
- loc = glGetUniformLocation(id, name);
+ S32 loc = glGetUniformLocation(id, name);
glUniformMatrix4fv(loc, 1, 0, (F32 *)&m);
}
diff --git a/prge_shader.h b/prge_shader.h
index 9a399d4..36e95ad 100644
--- a/prge_shader.h
+++ b/prge_shader.h
@@ -1,6 +1,3 @@
-#ifndef PRGE_SHADER_H
-#define PRGE_SHADER_H
-
#define PRGE_SHADER_POS_LOC 0
#define PRGE_SHADER_TEXC_LOC 1
@@ -8,10 +5,8 @@
#define PRGE_SHADER_VIEW_MAT "view"
#define PRGE_SHADER_MODEL_MAT "model"
-U32 compile_shader(GLenum type, Str8 fname);
-U32 load_shader(char *vert_filename, char *geom_filename, char *frag_filename);
-void shader_set_3fv(U32 id, char *name, V3 v);
-void shader_set_4fv(U32 id, char *name, V4 v);
-void shader_set_mat4fv(U32 id, char *name, MAT4 m);
-
-#endif /* PRGE_SHADER_H */
+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
index cce3374..e6c0820 100644
--- a/prge_texture.c
+++ b/prge_texture.c
@@ -1,31 +1,19 @@
-Texture load_texture(Arena *arena, char *filename, B32 gamma_correction)
+Texture load_texture(Arena *arena, const char *fname, B32 gamma)
{
- U8 *data;
+ Texture texture;
+ U8 *data;
+ S32 nchannels;
+ GLenum internal_format;
+ GLenum data_format;
+ S32 size;
- S32 nchannels;
- GLenum internal_format;
- GLenum data_format;
-
- Texture texture;
-
- Arena *temparena;
-
- char *cfilename;
- Str8 str;
-
- Assert(arena);
-
- MemoryZeroStruct(&texture);
-
- temparena = arena_alloc(0);
-
- cfilename = str8tocstr(arena, filename);
+ MEM0STRUCT(&texture);
stbi_set_flip_vertically_on_load(1);
- data = stbi_load(cfilename, &texture.width, &texture.height, &nchannels, 0);
+ data = stbi_load(fname, &texture.w, &texture.h, &nchannels, 0);
if (!data) {
- str = str8pushf(temparena, "[ERROR] : Texture : %s : Failed to load\n", cfilename);
+ sys_printf("[ERROR] : Texture : %s : Failed to load\n", fname);
goto end;
}
@@ -36,22 +24,27 @@ Texture load_texture(Arena *arena, char *filename, B32 gamma_correction)
break;
case 3:
texture.type = TextureType_RGB;
- internal_format = (gamma_correction) ? GL_SRGB : GL_RGB;
+ internal_format = (gamma) ? GL_SRGB : GL_RGB;
data_format = GL_RGB;
break;
case 4:
texture.type = TextureType_RGBA;
- internal_format = (gamma_correction) ? GL_SRGB_ALPHA : GL_RGBA;
+ internal_format = (gamma) ? GL_SRGB_ALPHA : GL_RGBA;
data_format = GL_RGBA;
break;
default:
- str = str8pushf(temparena, "[ERROR] : Texture : %s : Unsupported type\n", cfilename);
+ 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.width, texture.height, 0, data_format, GL_UNSIGNED_BYTE, data);
+ 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);
@@ -59,11 +52,8 @@ Texture load_texture(Arena *arena, char *filename, B32 gamma_correction)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
- str = str8pushf(temparena, "[INFO] : Texture : %s : Loaded successfully\n", cfilename);
-
+ sys_printf("[INFO] : Texture : %s : Loaded successfully\n", fname);
end:
- str8print(str);
stbi_image_free(data);
- arena_release(temparena);
return texture;
}
diff --git a/prge_texture.h b/prge_texture.h
index cb4c4cc..d8fe72f 100644
--- a/prge_texture.h
+++ b/prge_texture.h
@@ -1,6 +1 @@
-#ifndef PRGE_TEXTURE_H
-#define PRGE_TEXTURE_H
-
-Texture texture_load(Arena *arena, Str8 filename);
-
-#endif /* PRGE_TEXTURE_H */
+Texture load_texture(Arena *arena, const char *fname, B32 gamma);
diff --git a/prge_types.h b/prge_types.h
index 1799870..a41d110 100644
--- a/prge_types.h
+++ b/prge_types.h
@@ -1,13 +1,9 @@
-#ifndef PRGE_TYPES_H
-#define PRGE_TYPES_H
-
-#define MAX_TEXTURE 5
-
typedef struct {
- S32 width;
- S32 height;
- Str8 name;
-} Window;
+ S32 w;
+ S32 h;
+ const char *name;
+ U32 flags;
+} PRGEWindow;
typedef enum {
KeyState_RELEASE = 0,
@@ -28,21 +24,23 @@ typedef struct {
Key mouse_left;
Key mouse_right;
- B32 is_running;
-
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;
@@ -54,14 +52,14 @@ typedef enum {
typedef struct {
U32 id;
- Str8 name;
+ const char *name;
TextureTypeEnum type;
- S32 width;
- S32 height;
+ S32 w;
+ S32 h;
- void *data;
+ U8 *data;
} Texture;
typedef struct {
@@ -69,27 +67,44 @@ typedef struct {
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;
- U32 nverts;
+ S32 nverts;
Vertex *verts;
- U32 nindices;
+ S32 nindices;
U32 *indices;
- U32 ntextures;
- Texture textures[MAX_TEXTURE];
+ S32 ntextures;
+ Texture textures[PRGE_MAX_TEXTURES];
U32 vao, vbo, ebo;
} Mesh;
typedef struct {
+ U32 id;
+
V3 origin;
V3 rotate;
- U32 nmeshes;
+ S32 nmeshes;
Mesh *meshes;
} Model;
@@ -106,13 +121,46 @@ typedef struct {
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 {
- U32 nmodels;
- Model *models;
+ B32 should_close;
+
+ Arena *pa;
+ Arena *tmpa;
+
+ Input in;
- Camera camera;
+ /* TODO(pryazha): Probably a bad idea to have only one window 🙃*/
+ PRGEWindow wnd;
- Str8 bindir;
-} PRGEState;
+ Sound snds[PRGE_MAX_SOUNDS_LOADED];
+ SoundQueueNode nodes[PRGE_MAX_SOUNDS_PLAYING];
+ SoundQueue sndq;
-#endif /* PRGE_TYPES_H */
+ const char *bindir;
+} PRGEContext;
diff --git a/prge_window.c b/prge_window.c
index 444866c..f132102 100644
--- a/prge_window.c
+++ b/prge_window.c
@@ -1,10 +1,10 @@
-Window window_init(S32 width, S32 height, Str8 name)
+PRGEWindow init_window(S32 w, S32 h, const char *name, U32 flags)
{
- Window wnd;
-
- wnd.width = width;
- wnd.height = height;
- wnd.name = name;
-
+ PRGEWindow wnd = {
+ .w = w,
+ .h = h,
+ .name = name,
+ .flags = flags
+ };
return wnd;
}
diff --git a/prge_window.h b/prge_window.h
index e79ee86..5d9d086 100644
--- a/prge_window.h
+++ b/prge_window.h
@@ -1,6 +1,4 @@
-#ifndef PRGE_WINDOW_H
-#define PRGE_WINDOW_H
+#define PRGE_WINDOW_DEPTH_TEST 0x1
+#define PRGE_WINDOW_MULTISAMPLE 0x10
-Window window_init(S32 width, S32 height, Str8 name);
-
-#endif /* PRGE_WINDOW_H */
+PRGEWindow init_window(S32 w, S32 h, const char *name, U32 flags);