From bab0824608498d1079d4e9522f3014d3d538aabe Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Fri, 27 Apr 2018 20:56:00 +0100 Subject: 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. --- faqe.c | 96 ++++++++++++++++++++++++++++++++++++------------------------------ 1 file changed, 52 insertions(+), 44 deletions(-) (limited to 'faqe.c') 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); -- cgit v1.2.3-70-g09d2