diff options
author | pryazha <pryadeiniv@mail.ru> | 2025-03-19 08:46:04 +0500 |
---|---|---|
committer | pryazha <pryadeiniv@mail.ru> | 2025-03-19 08:46:04 +0500 |
commit | b1389bad67cccd3da6815c2d5a436c177f09594b (patch) | |
tree | 393dee77b5faef3cfd6e78eda8ac07273cdcc85e | |
parent | 34821e9fefb0d7cbf9e72a2457b2901edbbe03bb (diff) |
window, texture, model, camera and gui (silly button)
-rw-r--r-- | prge.h | 19 | ||||
-rw-r--r-- | prge_camera.c | 103 | ||||
-rw-r--r-- | prge_camera.h | 12 | ||||
-rw-r--r-- | prge_gui.c | 43 | ||||
-rw-r--r-- | prge_gui.h | 7 | ||||
-rw-r--r-- | prge_input.c | 21 | ||||
-rw-r--r-- | prge_mesh.c | 65 | ||||
-rw-r--r-- | prge_mesh.h | 9 | ||||
-rw-r--r-- | prge_model.c | 212 | ||||
-rw-r--r-- | prge_model.h | 18 | ||||
-rw-r--r-- | prge_shader.c | 83 | ||||
-rw-r--r-- | prge_shader.h | 15 | ||||
-rw-r--r-- | prge_texture.c | 69 | ||||
-rw-r--r-- | prge_texture.h | 6 | ||||
-rw-r--r-- | prge_types.h | 128 | ||||
-rw-r--r-- | prge_window.c | 10 | ||||
-rw-r--r-- | prge_window.h | 6 |
17 files changed, 684 insertions, 142 deletions
@@ -5,13 +5,28 @@ #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_texture.h" +#include "prge_texture.c" + #include "prge_shader.h" #include "prge_shader.c" -#include "prge_mesh.h" -#include "prge_mesh.c" +#include "prge_model.h" +#include "prge_model.c" + +#include "prge_camera.h" +#include "prge_camera.c" + +#include "prge_gui.h" +#include "prge_gui.c" #endif /* PRGE_H */ diff --git a/prge_camera.c b/prge_camera.c new file mode 100644 index 0000000..242b33d --- /dev/null +++ b/prge_camera.c @@ -0,0 +1,103 @@ +Camera camera_init(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; + + return c; +} + +MAT4 camera_get_view_matrix_first_person(Camera *c) +{ + MAT4 v; + + v = mat4transl(MAT4_IDENTITY, v3inv(c->pos)); + v = mat4rotate(v, v3(c->pitch, c->yaw, c->roll)); + + return v; +} + +void camera_get_vectors_first_person(Camera *c, V3 *r, 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); + + *r = 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) +{ + V3 f, r, u; + MAT4 transl, rotate, res; + + f = v3norm(v3sub(c.pos, t)); + r = v3norm(v3cross(wup, f)); + u = v3cross(f, r); + + transl = mat4transl(MAT4_IDENTITY, v3inv(c.pos)); + rotate = mat4transp(mat4_change_basis(r, u, f)); + res = mat4mul(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 new file mode 100644 index 0000000..33957e5 --- /dev/null +++ b/prge_camera.h @@ -0,0 +1,12 @@ +#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); +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_gui.c b/prge_gui.c new file mode 100644 index 0000000..f1d03d7 --- /dev/null +++ b/prge_gui.c @@ -0,0 +1,43 @@ +B32 in_rect(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; +} + +B32 button(Window *wnd, U32 shader, Input *input, Arena *arena, + Str8 name, V2 center, F32 w, F32 h) +{ + B32 res; + Mesh *quad; + V2 start, end; + MAT4 model; + Str8 info; + + res = 0; + + quad = mesh_gen_quad(arena, v3fromv2(center), V3_ZERO, w, h); + + shader_set_4fv(shader, "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; + } + + model = mat4transl(MAT4_IDENTITY, v3(center.x, wnd->height-center.y, 0.0f)); + + shader_set_mat4fv(shader, "model", model); + + mesh_draw(quad); + + mesh_clear(quad); + + return res; +} diff --git a/prge_gui.h b/prge_gui.h new file mode 100644 index 0000000..72fc11a --- /dev/null +++ b/prge_gui.h @@ -0,0 +1,7 @@ +#ifndef PRGE_GUI_H +#define PRGE_GUI_H + +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); + +#endif /* PRGE_GUI_H */ diff --git a/prge_input.c b/prge_input.c index e295ebc..b841d6a 100644 --- a/prge_input.c +++ b/prge_input.c @@ -3,12 +3,15 @@ Input input_init() Input input = {0}; input.first_mouse = 1; input.is_running = 1; - return(input); + return input; } void input_update(Input *input) { + 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; @@ -26,20 +29,20 @@ void input_update(Input *input) B32 key_is_pressed(Key key) { - B32 result = (key.state == KeyState_PRESS); - return(result); + B32 r = (key.state == KeyState_PRESS); + return r; } B32 key_first_press(Key key) { - B32 result = ((key.last == KeyState_RELEASE) && - (key.state == KeyState_PRESS)); - return(result); + B32 r = ((key.last == KeyState_RELEASE) && + (key.state == KeyState_PRESS)); + return r; } B32 key_was_pressed(Key key) { - B32 result = ((key.last == KeyState_PRESS) && - (key.state == KeyState_RELEASE)); - return(result); + B32 r = ((key.last == KeyState_PRESS) && + (key.state == KeyState_RELEASE)); + return r; } diff --git a/prge_mesh.c b/prge_mesh.c deleted file mode 100644 index dc2c2da..0000000 --- a/prge_mesh.c +++ /dev/null @@ -1,65 +0,0 @@ -Vertex vertex(V3 pos) -{ - Vertex v = { pos }; - return v; -} - -void mesh_init_buffers(Mesh *mesh) -{ - Assert(mesh->verts); - Assert(mesh->nverts > 0); - - 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); - - 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); - } - - glEnableVertexAttribArray(PRGE_SHADER_POS_LOC); - glVertexAttribPointer(PRGE_SHADER_POS_LOC, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0); - glBindVertexArray(0); -} - -Mesh *mesh(Arena *arena, Vertex *verts, U32 nverts, U32 *indices, U32 nindices) -{ - Mesh *mesh = arena_push(arena, sizeof(Mesh)); - mesh->verts = verts; - mesh->nverts = nverts; - mesh->indices = indices; - mesh->nindices = nindices; - mesh_init_buffers(mesh); - return mesh; -} - -void mesh_clear(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 mesh_draw(Mesh mesh) -{ - Assert(mesh.vao); - glBindVertexArray(mesh.vao); - if (mesh.ebo) - glDrawElements(GL_TRIANGLES, mesh.nindices, GL_UNSIGNED_INT, 0); - else - glDrawArrays(GL_TRIANGLES, 0, mesh.nverts); - glBindVertexArray(0); -} diff --git a/prge_mesh.h b/prge_mesh.h deleted file mode 100644 index 1f70809..0000000 --- a/prge_mesh.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef PRGE_MESH_H -#define PRGE_MESH_H - -#define PRGE_SHADER_POS_LOC 0 - -Vertex vertex(V3 pos); -Mesh *mesh(Arena *arena, Vertex *verts, U32 nverts, U32 *indices, U32 nindices); - -#endif /* PRGE_MESH_H */ diff --git a/prge_model.c b/prge_model.c new file mode 100644 index 0000000..44ded76 --- /dev/null +++ b/prge_model.c @@ -0,0 +1,212 @@ +Vertex vert(V3 pos, V2 texc) +{ + Vertex v; + + v.pos = pos; + v.texc = texc; + + return v; +} + +void mesh_init_buffers(Mesh *mesh) +{ + Assert(mesh->verts); + Assert(mesh->nverts > 0); + + 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); + + 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); + } + + glEnableVertexAttribArray(PRGE_SHADER_POS_LOC); + glVertexAttribPointer(PRGE_SHADER_POS_LOC, 3, GL_FLOAT, GL_FALSE, + sizeof(Vertex), OffsetOfMember(Vertex, pos)); + glEnableVertexAttribArray(PRGE_SHADER_TEXC_LOC); + glVertexAttribPointer(PRGE_SHADER_TEXC_LOC, 2, GL_FLOAT, GL_FALSE, + sizeof(Vertex), (void *)OffsetOfMember(Vertex, texc)); + glBindVertexArray(0); +} + +Mesh *mesh_init(Arena *arena, V3 origin, V3 rotate, Vertex *verts, U32 nverts, U32 *indices, U32 nindices) +{ + Mesh *mesh; + + mesh = arena_push(arena, sizeof(Mesh)); + + mesh->origin = origin; + mesh->rotate = rotate; + + mesh->verts = verts; + mesh->nverts = nverts; + + mesh->indices = indices; + mesh->nindices = nindices; + + mesh->ntextures = 0; + MemoryZeroArray(mesh->textures); + + mesh_init_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) +{ + 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 mesh_draw(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); +} + +Mesh *mesh_gen_quad(Arena *arena, V3 origin, V3 rotate, F32 w, F32 h) +{ + Mesh *m; + Vertex *verts; + U32 *indices; + U32 nverts, nindices; + + 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)); + + nindices = 6; + indices = arena_push(arena, nindices*sizeof(U32)); + indices[0] = 0; + indices[1] = 1; + indices[2] = 3; + indices[3] = 0; + indices[4] = 2; + indices[5] = 3; + + m = mesh_init(arena, origin, rotate, verts, nverts, indices, nindices); + + return m; +} + +Mesh *mesh_gen_circle(Arena *arena, V3 origin, V3 rotate, F32 r, U32 nverts) +{ + Mesh *m; + Vertex *verts; + U32 *indices; + U32 nindices; + F32 angle, dangle; + U32 i, vi; + + if (nverts < 3) + nverts = 3; + + verts = arena_push(arena, nverts*sizeof(Vertex)); + + dangle = 2*F32_PI/(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); + + nindices = nverts*3; + indices = arena_push(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; + + res = arena_push(arena, sizeof(Model)); + + res->origin = origin; + res->rotate = rotate; + res->meshes = meshes; + res->nmeshes = nmeshes; + + return res; +} + +Model *model_load(Arena *arena, V3 origin, V3 rotate, Str8 filename) +{ + Model *res; + + res = 0; + + /* TODO(pryazha): Load models with assimp? */ + + return res; +} + +void model_draw(U32 shader, MAT4 *proj, MAT4 *view, Model *model) +{ + 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); + + modelmat = mat4rotate(MAT4_IDENTITY, model->rotate); + modelmat = mat4transl(modelmat, model->origin); + + for (i = 0; i < model->nmeshes; i++) { + meshmodelmat = mat4rotate(MAT4_IDENTITY, model->meshes[i].rotate); + meshmodelmat = mat4transl(meshmodelmat, model->meshes[i].origin); + + resmodelmat = mat4mul(modelmat, meshmodelmat); + + shader_set_mat4fv(shader, PRGE_SHADER_MODEL_MAT, resmodelmat); + mesh_draw(&model->meshes[i]); + } + + glUseProgram(0); +} diff --git a/prge_model.h b/prge_model.h new file mode 100644 index 0000000..d747232 --- /dev/null +++ b/prge_model.h @@ -0,0 +1,18 @@ +#ifndef PRGE_MODEL_H +#define PRGE_MODEL_H + +#define MAX_TEXTURE 5 + +Vertex vert_init(V3 pos, V2 texc); + +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 */ diff --git a/prge_shader.c b/prge_shader.c index 21a91f3..96b50f1 100644 --- a/prge_shader.c +++ b/prge_shader.c @@ -1,28 +1,33 @@ U32 compile_shader(GLenum type, Str8 filename) { - Arena *tmp = arena_alloc(0); + Arena *tmp; + Str8 src; + U32 id; + S32 status; + const char *csrc; - Str8 src = str8_read_entire_file(tmp, filename); + tmp = arena_alloc(0); + + src = str8_read_entire_file(tmp, filename); if (!src.ptr || !src.length) { - str8print(str8_pushf(tmp, "[ERROR] : Failed to read \"%.*s\"\n", str8expand(filename))); + str8print(str8pushf(tmp, "[ERROR] : Failed to read \"%.*s\"\n", str8expand(filename))); arena_release(tmp); return 0; } - const char *csrc = str8_to_cstr(tmp, src); + csrc = str8tocstr(tmp, src); - U32 id = glCreateShader(type); + id = glCreateShader(type); glShaderSource(id, 1, &csrc, 0); glCompileShader(id); - S32 status; glGetShaderiv(id, GL_COMPILE_STATUS, &status); if (status == GL_FALSE) { - char log[512]; + char log[512]; glGetShaderInfoLog(id, 512, 0, log); - str8print(str8_pushf(tmp, "[ERROR] : Failed to compile : \"%.*s\"\n%s", str8expand(filename), log)); + str8print(str8pushf(tmp, "[ERROR] : Failed to compile : \"%.*s\"\n%s", str8expand(filename), log)); } else { - str8print(str8_pushf(tmp, "[INFO] : \"%.*s\" compiled successfully.\n", str8expand(filename))); + str8print(str8pushf(tmp, "[INFO] : \"%.*s\" compiled successfully.\n", str8expand(filename))); } arena_release(tmp); @@ -30,36 +35,66 @@ U32 compile_shader(GLenum type, Str8 filename) return id; } -U32 create_shader_program(Str8 vert_filename, Str8 frag_filename) +U32 load_shader(char *vert_filename, char *geom_filename, char *frag_filename) { - U32 vert = compile_shader(GL_VERTEX_SHADER, vert_filename); - U32 frag = compile_shader(GL_FRAGMENT_SHADER, frag_filename); + U32 vert, geom, frag, id; + Arena *tmp; + 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)); - Arena *tmp = arena_alloc(0); + tmp = arena_alloc(0); - U32 id = glCreateProgram(); - glAttachShader(id, vert); - glAttachShader(id, frag); + id = glCreateProgram(); + if (vert_filename) + glAttachShader(id, vert); + if (geom_filename) + glAttachShader(id, geom); + if (frag_filename) + glAttachShader(id, frag); glLinkProgram(id); - S32 success; glGetProgramiv(id, GL_LINK_STATUS, &success); if (success == GL_FALSE) { - char log[512]; + char log[512]; glGetProgramInfoLog(id, 512, 0, log); - str8print(str8_pushf(tmp, "[ERROR]: Failed to link shader program:\n%s", log)); + str8print(str8pushf(tmp, "[ERROR] : Failed to link shader program:\n%s", log)); } else { - str8print(str8_pushf(tmp, "[INFO]: Shader program linked successfuly.\n\n")); + str8print(str8pushf(tmp, "[INFO] : Shader linked successfuly.\n\n")); } - glDeleteShader(vert); - glDeleteShader(frag); + if (vert_filename) + glDeleteShader(vert); + if (geom_filename) + glDeleteShader(geom); + if (frag_filename) + glDeleteShader(frag); arena_release(tmp); return id; } -void shader_set_mat4fv(U32 id, char *name, Mat4 m) +void shader_set_3fv(U32 id, char *name, V3 v) +{ + S32 loc; + loc = glGetUniformLocation(id, name); + glUniform3fv(loc, 1, (F32 *)&v); +} + +void shader_set_4fv(U32 id, char *name, V4 v) +{ + S32 loc; + loc = glGetUniformLocation(id, name); + glUniform4fv(loc, 1, (F32 *)&v); +} + +void shader_set_mat4fv(U32 id, char *name, MAT4 m) { - S32 loc = glGetUniformLocation(id, name); + S32 loc; + loc = glGetUniformLocation(id, name); glUniformMatrix4fv(loc, 1, 0, (F32 *)&m); } diff --git a/prge_shader.h b/prge_shader.h index 1e065a5..9a399d4 100644 --- a/prge_shader.h +++ b/prge_shader.h @@ -1,8 +1,17 @@ #ifndef PRGE_SHADER_H #define PRGE_SHADER_H -U32 compile_shader(GLenum type, Str8 filename); -U32 create_shader_program(Str8 vert_filename, Str8 frag_filename); -void shader_set_mat4fv(U32 id, char *name, Mat4 m); +#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_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 */ diff --git a/prge_texture.c b/prge_texture.c new file mode 100644 index 0000000..cce3374 --- /dev/null +++ b/prge_texture.c @@ -0,0 +1,69 @@ +Texture load_texture(Arena *arena, char *filename, B32 gamma_correction) +{ + U8 *data; + + 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); + + stbi_set_flip_vertically_on_load(1); + data = stbi_load(cfilename, &texture.width, &texture.height, &nchannels, 0); + + if (!data) { + str = str8pushf(temparena, "[ERROR] : Texture : %s : Failed to load\n", cfilename); + 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_correction) ? GL_SRGB : GL_RGB; + data_format = GL_RGB; + break; + case 4: + texture.type = TextureType_RGBA; + internal_format = (gamma_correction) ? GL_SRGB_ALPHA : GL_RGBA; + data_format = GL_RGBA; + break; + default: + str = str8pushf(temparena, "[ERROR] : Texture : %s : Unsupported type\n", cfilename); + goto end; + } + + 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); + 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); + + str = str8pushf(temparena, "[INFO] : Texture : %s : Loaded successfully\n", cfilename); + +end: + str8print(str); + stbi_image_free(data); + arena_release(temparena); + return texture; +} diff --git a/prge_texture.h b/prge_texture.h new file mode 100644 index 0000000..cb4c4cc --- /dev/null +++ b/prge_texture.h @@ -0,0 +1,6 @@ +#ifndef PRGE_TEXTURE_H +#define PRGE_TEXTURE_H + +Texture texture_load(Arena *arena, Str8 filename); + +#endif /* PRGE_TEXTURE_H */ diff --git a/prge_types.h b/prge_types.h index ff5b860..1799870 100644 --- a/prge_types.h +++ b/prge_types.h @@ -1,50 +1,118 @@ #ifndef PRGE_TYPES_H #define PRGE_TYPES_H -enum KeyState_Enum { - KeyState_RELEASE = 0, - KeyState_PRESS = 1 -}; +#define MAX_TEXTURE 5 typedef struct { - enum KeyState_Enum last; - enum KeyState_Enum state; + S32 width; + S32 height; + Str8 name; +} Window; + +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; + V2 mouse_pos; + V2 last_mouse_pos; + V2 mouse_offset; + B32 first_mouse; + B32 capture_mouse; + Key mouse_left; + Key mouse_right; - B32 is_running; + B32 is_running; - F32 dt; + 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; + 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 { - V3 pos; + U32 id; + Str8 name; + + TextureTypeEnum type; + + S32 width; + S32 height; + + void *data; +} Texture; + +typedef struct { + V3 pos; + V2 texc; } Vertex; typedef struct { - Vertex *verts; - U32 nverts; - U32 *indices; - U32 nindices; - U32 vao, vbo, ebo; + V3 origin; + V3 rotate; + + U32 nverts; + Vertex *verts; + + U32 nindices; + U32 *indices; + + U32 ntextures; + Texture textures[MAX_TEXTURE]; + + U32 vao, vbo, ebo; } Mesh; +typedef struct { + V3 origin; + V3 rotate; + + U32 nmeshes; + Mesh *meshes; +} Model; + +typedef struct { + V3 pos; + + F32 fov; + + F32 near; + F32 far; + + F32 yaw; + F32 pitch; + F32 roll; +} Camera; + +typedef struct { + U32 nmodels; + Model *models; + + Camera camera; + + Str8 bindir; +} PRGEState; + #endif /* PRGE_TYPES_H */ diff --git a/prge_window.c b/prge_window.c new file mode 100644 index 0000000..444866c --- /dev/null +++ b/prge_window.c @@ -0,0 +1,10 @@ +Window window_init(S32 width, S32 height, Str8 name) +{ + Window wnd; + + wnd.width = width; + wnd.height = height; + wnd.name = name; + + return wnd; +} diff --git a/prge_window.h b/prge_window.h new file mode 100644 index 0000000..e79ee86 --- /dev/null +++ b/prge_window.h @@ -0,0 +1,6 @@ +#ifndef PRGE_WINDOW_H +#define PRGE_WINDOW_H + +Window window_init(S32 width, S32 height, Str8 name); + +#endif /* PRGE_WINDOW_H */ |