aboutsummaryrefslogtreecommitdiffstats
path: root/faqe.c
diff options
context:
space:
mode:
authorTomasz Kramkowski <tk@the-tk.com>2018-04-27 20:56:00 +0100
committerTomasz Kramkowski <tk@the-tk.com>2018-04-27 20:56:00 +0100
commitbab0824608498d1079d4e9522f3014d3d538aabe (patch)
tree932f082b58fd48f85fbbdfa3f7419d2b3b03eedb /faqe.c
parent3d73622dbd5a9ddc687fe6f42268c760695d7226 (diff)
downloadfaqe-bab0824608498d1079d4e9522f3014d3d538aabe.tar.gz
faqe-bab0824608498d1079d4e9522f3014d3d538aabe.tar.xz
faqe-bab0824608498d1079d4e9522f3014d3d538aabe.zip
Implement basic model loading of FMD format.
The FMD (Faqe Model Data) format is a format designed for faqe. It stores vertex, element and material information and mesh information. This patch provides the basic implementation and use of this format. This patch also implements perspective projection, depth testing and view and model matrices. An example fmd file is provided.
Diffstat (limited to 'faqe.c')
-rw-r--r--faqe.c96
1 files changed, 52 insertions, 44 deletions
diff --git a/faqe.c b/faqe.c
index ddcff69..bc5bd2f 100644
--- a/faqe.c
+++ b/faqe.c
@@ -11,33 +11,37 @@
#include "glprog.h"
#include "linmath.h"
#include "nelem.h"
+#include "model.h"
enum {
WIDTH = 800,
HEIGHT = 600,
};
+# define PI 3.14159265358979323846
+#define FOV (PI * 0.5)
+
+void viewport(GLuint proj, int width, int height)
+{
+ mat4x4 pers;
+ gl_viewport(0, 0, width, height);
+ mat4x4_perspective(pers, FOV, (float)width / (float)height, 0.1, 100);
+ gl_uni_setm4fv(proj, 1, GL_FALSE, pers[0]);
+}
+
int main(int argc, char **argv)
{
bool running = true;
SDL_Window *win;
SDL_GLContext *glc;
- GLuint ebo, vbo, vao, prog;
- GLint ucolor;
- struct vertex {
- vec3 pos;
- vec3 col;
- vec2 uv;
- } verts[] = {
- {{ 0.5, 0.5, 0.0 }, { 1.0, 0.0, 0.0 }, { 1.0, 1.0 }},
- {{ 0.5, -0.5, 0.0 }, { 0.0, 1.0, 0.0 }, { 1.0, 0.0 }},
- {{ -0.5, -0.5, 0.0 }, { 0.0, 0.0, 1.0 }, { 0.0, 0.0 }},
- {{ -0.5, 0.5, 0.0 }, { 1.0, 1.0, 0.0 }, { 0.0, 1.0 }},
- };
- GLuint idxs[] = {
- 0, 1, 3,
- 1, 2, 3,
- };
+ GLuint prog;
+ struct {
+ GLint model, view, proj;
+ } uni;
+ mat4x4 view;
+ FILE *cube_file;
+ struct fmd cube_fmd;
+ struct model cube_model;
setprogname(argc >= 1 && argv[0] != NULL ? argv[0] : "faqe");
@@ -62,37 +66,37 @@ int main(int argc, char **argv)
gl_load((gl_loadfunc *)SDL_GL_GetProcAddress);
- gl_viewport(0, 0, WIDTH, HEIGHT);
-
- gl_buf_gen(1, &vbo);
- gl_buf_gen(1, &ebo);
- gl_va_gen(1, &vao);
-
- gl_va_bind(vao);
-
- gl_buf_bind(GL_ARRAY_BUFFER, vbo);
- gl_buf_data(GL_ARRAY_BUFFER, sizeof verts, verts, GL_STATIC_DRAW);
-
- gl_buf_bind(GL_ELEMENT_ARRAY_BUFFER, ebo);
- gl_buf_data(GL_ELEMENT_ARRAY_BUFFER, sizeof idxs, idxs, GL_STATIC_DRAW);
-
- gl_va_define(0, NELEM(verts[0].pos), GL_FLOAT, GL_FALSE, sizeof *verts, (void *)offsetof(struct vertex, pos));
- gl_va_enable(0);
- gl_va_define(1, NELEM(verts[0].col), GL_FLOAT, GL_FALSE, sizeof *verts, (void *)offsetof(struct vertex, col));
- gl_va_enable(1);
- gl_va_define(2, NELEM(verts[0].uv), GL_FLOAT, GL_FALSE, sizeof *verts, (void *)offsetof(struct vertex, uv));
- gl_va_enable(2);
+ cube_file = fopen("cube.fmd", "rb");
+ if (cube_file == NULL)
+ eprintf("Could not open 'cube.fmd':");
+ fmd_load(&cube_fmd, cube_file);
+ model_load(&cube_model, &cube_fmd);
+ fmd_free(&cube_fmd);
+ fclose(cube_file);
prog = glprog_load(2, (struct shdrdat []){
{ GL_VERTEX_SHADER, vert_glsl.data, vert_glsl.size },
{ GL_FRAGMENT_SHADER, frag_glsl.data, frag_glsl.size },
},
- 1, &(struct unidat){ "ucolor", &ucolor });
+ 3, (struct unidat []){
+ { "model", &uni.model },
+ { "view", &uni.view },
+ { "proj", &uni.proj },
+ });
- gl_poly_mode(GL_FRONT_AND_BACK, GL_LINE);
+ viewport(uni.proj, WIDTH, HEIGHT);
+
+ gl_enable(GL_DEPTH_TEST);
while (running) {
+ mat4x4 model;
SDL_Event ev;
+ float secs;
+
+ secs = SDL_GetTicks() * 0.0001;
+
+ mat4x4_look_at(view, (vec3){ 0, 0, 3 }, (vec3){ 0, 0, 0 }, (vec3){ 0, 1, 0 });
+ gl_uni_setm4fv(uni.view, 1, GL_FALSE, view[0]);
while (SDL_PollEvent(&ev)) {
switch (ev.type) {
@@ -108,19 +112,23 @@ int main(int argc, char **argv)
case SDL_WINDOWEVENT:
switch (ev.window.event) {
case SDL_WINDOWEVENT_SIZE_CHANGED:
- gl_viewport(0, 0,
- ev.window.data1,
- ev.window.data2);
+ viewport(uni.proj,
+ ev.window.data1,
+ ev.window.data2);
}
break;
}
}
gl_clearcolor(0.2, 0.3, 0.3, 1.0);
- gl_clear(GL_COLOR_BUFFER_BIT);
+ gl_clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
gl_prog_use(prog);
- gl_va_bind(vao);
- gl_draw_elems(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
+ mat4x4_identity(model);
+ mat4x4_rotate_X(model, model, secs * 3);
+ mat4x4_rotate_Y(model, model, secs * 2);
+ mat4x4_rotate_Z(model, model, secs * 4);
+ gl_uni_setm4fv(uni.model, 1, GL_TRUE, model[0]);
+ model_render(&cube_model);
gl_va_bind(0);
SDL_GL_SwapWindow(win);