aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles <sircharlesaze@gmail.com>2020-05-12 14:14:06 +0200
committerCharles <sircharlesaze@gmail.com>2020-05-12 14:14:06 +0200
commit7b214503608550dc2853b9e01526723f8c65baf3 (patch)
treeddbc37eb2627b43eb33774bd2bf205336cd1a9e6
parentd07d87964f13d3c1e6ad8c2f6d7db21101f1ef34 (diff)
downloadscop-7b214503608550dc2853b9e01526723f8c65baf3.tar.gz
scop-7b214503608550dc2853b9e01526723f8c65baf3.tar.bz2
scop-7b214503608550dc2853b9e01526723f8c65baf3.zip
Added mat4 in libftm, can rotate, scale and translate vector
-rw-r--r--Makefile26
-rw-r--r--inc/scop.h18
-rw-r--r--shader/fragment.glsl2
-rw-r--r--shader/vertex.glsl6
-rw-r--r--src/gl.c23
-rw-r--r--src/glfw.c11
-rw-r--r--src/helper.c21
-rw-r--r--src/main.c82
-rw-r--r--src/parse.c13
-rw-r--r--src/shader.c10
-rw-r--r--src/texture.c44
m---------vendor/libft0
-rw-r--r--vendor/libftm/Makefile4
-rw-r--r--vendor/libftm/inc/libftm.h20
-rw-r--r--vendor/libftm/inc/libftm_mat4.h35
-rw-r--r--vendor/libftm/inc/libftm_vec3.h23
-rw-r--r--vendor/libftm/src/ftm_radian.c18
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4get.c18
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4init_eye.c23
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4init_fill.c26
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4mul.c40
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4rotate.c70
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4scale.c25
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4set.c19
-rw-r--r--vendor/libftm/src/mat4/ftm_mat4translate.c25
-rw-r--r--vendor/libftm/src/vec3/ftm_vec3init.c21
26 files changed, 574 insertions, 49 deletions
diff --git a/Makefile b/Makefile
index 78b3453..94a2bb6 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@
# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/05/09 10:24:52 by charles #+# #+# #
-# Updated: 2020/05/11 01:55:58 by charles ### ########.fr #
+# Updated: 2020/05/12 14:04:16 by charles ### ########.fr #
# #
# **************************************************************************** #
@@ -15,15 +15,16 @@ RM = rm -f
VENDOR_DIR = vendor
LIBFT_DIR = $(VENDOR_DIR)/libft
+LIBFTM_DIR = $(VENDOR_DIR)/libftm
SRC_DIR = src
INC_DIR = inc
OBJ_DIR = obj
CC = gcc
-CCFLAGS = -I$(LIBFT_DIR)/include -I$(INC_DIR) \
+CCFLAGS = -I$(LIBFT_DIR)/include -I$(INC_DIR) -I$(LIBFTM_DIR)/inc \
-Wall -Wextra #-Werror
-LDFLAGS = -L$(LIBFT_DIR) -lft
+LDFLAGS = -L$(LIBFT_DIR) -lft -L$(LIBFTM_DIR) -lftm -lm
ifeq ($(shell uname),Linux)
LDFLAGS += -lglfw -lGL -lglut -lGLEW
@@ -34,13 +35,13 @@ SRC = $(shell find $(SRC_DIR) -type f -name '*.c')
OBJ = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
INC = $(shell find $(INC_DIR) -type f -name '*.h')
-all: prebuild libft_all $(NAME)
+all: prebuild $(NAME)
prebuild:
mkdir -p $(OBJ_DIR)
-$(NAME): $(OBJ)
- $(CC) -o $@ $^ $(LDFLAGS)
+$(NAME): $(OBJ) libft_all libftm_all
+ $(CC) -o $@ $(OBJ) $(LDFLAGS)
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(INC)
$(CC) $(CCFLAGS) -c -o $@ $<
@@ -53,9 +54,9 @@ fcleanloc: cleanloc
reloc: fcleanloc all
-clean: libft_clean cleanloc
+clean: libft_clean libftm_fclean cleanloc
-fclean: libft_fclean fcleanloc
+fclean: libft_fclean libftm_fclean fcleanloc
re: fclean all
@@ -67,3 +68,12 @@ libft_clean:
libft_fclean:
$(MAKE) -C $(LIBFT_DIR) fclean
+
+libftm_all:
+ $(MAKE) -C $(LIBFTM_DIR) all
+
+libftm_clean:
+ $(MAKE) -C $(LIBFTM_DIR) clean
+
+libftm_fclean:
+ $(MAKE) -C $(LIBFTM_DIR) fclean
diff --git a/inc/scop.h b/inc/scop.h
index 3c16af8..ef5a8b3 100644
--- a/inc/scop.h
+++ b/inc/scop.h
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/05/09 10:41:44 by charles #+# #+# */
-/* Updated: 2020/05/11 10:33:29 by charles ### ########.fr */
+/* Updated: 2020/05/12 13:39:34 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -19,8 +19,12 @@
# include <stdlib.h>
# include <GL/glew.h>
# include <GLFW/glfw3.h>
+
# include "libft.h"
# include "libft_vec.h"
+# include "libftm.h"
+# include "libftm_mat4.h"
+# include "libftm_vec3.h"
typedef struct
{
@@ -36,6 +40,7 @@ typedef struct
unsigned int index_buf;
unsigned int vertex_array;
unsigned int shader;
+ int mvp_location;
} t_gl_state;
/*
@@ -50,6 +55,7 @@ int parse(char *filepath, t_object *object);
int gl_state_init(t_gl_state *state, t_object *object);
void gl_state_quit(t_gl_state *state, t_object *object);
+void gl_state_set_mvp(t_gl_state *state, t_ftmmat4 *mvp);
/*
** error.c
@@ -74,4 +80,14 @@ GLFWwindow *glfw_init(int width, int height);
unsigned int shader_new(void);
+/*
+** texture.c
+*/
+
+/*
+** helper.c
+*/
+
+bool has_extension(char *filepath, char *extension);
+
#endif
diff --git a/shader/fragment.glsl b/shader/fragment.glsl
index 6c34349..3fbeac5 100644
--- a/shader/fragment.glsl
+++ b/shader/fragment.glsl
@@ -1,4 +1,4 @@
-#version 400
+#version 400 core
out vec4 out_color;
diff --git a/shader/vertex.glsl b/shader/vertex.glsl
index a71ad4e..0e7b04d 100644
--- a/shader/vertex.glsl
+++ b/shader/vertex.glsl
@@ -1,8 +1,10 @@
-#version 400
+#version 400 core
layout (location = 0) in vec3 v_position;
+uniform mat4 u_mvp;
+
void main()
{
- gl_Position = vec4(v_position, 1.0);
+ gl_Position = u_mvp * vec4(v_position, 1.0);
}
diff --git a/src/gl.c b/src/gl.c
index 82e33a9..557cb63 100644
--- a/src/gl.c
+++ b/src/gl.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/05/11 01:31:10 by charles #+# #+# */
-/* Updated: 2020/05/11 10:42:42 by charles ### ########.fr */
+/* Updated: 2020/05/12 14:07:04 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -16,20 +16,26 @@ int gl_state_init(t_gl_state *state, t_object *object)
{
if ((state->shader = shader_new()) == 0)
return (-1);
+ GL_CALL(state->mvp_location = glGetUniformLocation(state->shader, "u_mvp"));
+ if (state->mvp_location == -1)
+ return (-1);
+
+ GL_CALL(glGenVertexArrays(1, &state->vertex_array));
GL_CALL(glGenBuffers(1, &state->vertex_buf));
+ GL_CALL(glGenBuffers(1, &state->index_buf));
+
+ GL_CALL(glBindVertexArray(state->vertex_array));
+
GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, state->vertex_buf));
GL_CALL(glBufferData(GL_ARRAY_BUFFER, sizeof(float) * object->vertices_len,
object->vertices, GL_STATIC_DRAW));
- GL_CALL(glGenBuffers(1, &state->index_buf));
GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state->index_buf));
- GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(float) * object->indices_len,
+ GL_CALL(glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * object->indices_len,
object->indices, GL_STATIC_DRAW));
- GL_CALL(glGenVertexArrays(1, &state->vertex_array));
- GL_CALL(glBindVertexArray(state->vertex_array));
+ GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (void*)0));
GL_CALL(glEnableVertexAttribArray(0));
- GL_CALL(glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3, (const void*)0));
return (0);
}
@@ -42,3 +48,8 @@ void gl_state_quit(t_gl_state *state, t_object *object)
free(object->vertices);
free(object->indices);
}
+
+void gl_state_set_mvp(t_gl_state *state, t_ftmmat4 *mvp)
+{
+ GL_CALL(glUniformMatrix4fv(state->mvp_location, 1, GL_TRUE, mvp->m));
+}
diff --git a/src/glfw.c b/src/glfw.c
index a492c08..1071ae0 100644
--- a/src/glfw.c
+++ b/src/glfw.c
@@ -6,12 +6,18 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/05/11 01:58:00 by charles #+# #+# */
-/* Updated: 2020/05/11 09:41:51 by charles ### ########.fr */
+/* Updated: 2020/05/12 13:58:51 by charles ### ########.fr */
/* */
/* ************************************************************************** */
#include "scop.h"
+void st_resize_callback(GLFWwindow *window, int width, int height)
+{
+ (void)window;
+ glViewport(0, 0, width, height);
+}
+
GLFWwindow *glfw_init(int width, int height)
{
GLFWwindow *window;
@@ -28,6 +34,7 @@ GLFWwindow *glfw_init(int width, int height)
return (NULL);
}
glfwMakeContextCurrent(window);
+ glfwSetFramebufferSizeCallback(window, st_resize_callback);
if (glewInit() != GLEW_OK)
{
glfwDestroyWindow(window);
@@ -35,6 +42,6 @@ GLFWwindow *glfw_init(int width, int height)
return (NULL);
}
glfwSwapInterval(1);
- glViewport(0, 0, width, height);
+ /* glViewport(0, 0, width, height); */
return (window);
}
diff --git a/src/helper.c b/src/helper.c
new file mode 100644
index 0000000..34fd560
--- /dev/null
+++ b/src/helper.c
@@ -0,0 +1,21 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* helper.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/11 14:55:27 by charles #+# #+# */
+/* Updated: 2020/05/11 14:57:29 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "scop.h"
+
+bool has_extension(char *filepath, char *extension)
+{
+ char *match;
+
+ match = ft_strstr(filepath, extension);
+ return (match != NULL && ft_strlen(match) == ft_strlen(extension));
+}
diff --git a/src/main.c b/src/main.c
index 1dcc36c..5685478 100644
--- a/src/main.c
+++ b/src/main.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/05/09 10:20:09 by charles #+# #+# */
-/* Updated: 2020/05/11 10:49:17 by charles ### ########.fr */
+/* Updated: 2020/05/12 14:10:09 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -18,36 +18,86 @@ int main(int argc, char **argv)
t_object object;
t_gl_state state;
- if (argc != 2)
- {
- ft_putstr("Usage: ");
- ft_putstr(argv[0]);
- ft_putendl(" [obj file]");
- return (1);
- }
- if (parse(argv[1], &object) == -1)
- {
- ft_putstr("Error: couldn't parse ");
- ft_putendl(argv[1]);
- return (1);
- }
+ /* if (argc != 2) */
+ /* { */
+ /* ft_putstr("Usage: "); */
+ /* ft_putstr(argv[0]); */
+ /* ft_putendl(" [obj file]"); */
+ /* return (1); */
+ /* } */
+ /* if (parse(argv[1], &object) == -1) */
+ /* { */
+ /* ft_putstr("Error: couldn't parse "); */
+ /* ft_putendl(argv[1]); */
+ /* return (1); */
+ /* } */
+ float positions[] = {
+ 0.5f, 0.5f, 0.0f,
+ 0.5f, -0.5f, 0.0f,
+ -0.5f, -0.5f, 0.0f,
+ -0.5f, 0.5f, 0.0f
+ };
+ unsigned int index[] = {
+ 0, 1, 3,
+ 1, 2, 3
+ };
+
+ object.vertices = malloc(sizeof(positions));
+ ft_memcpy(object.vertices, positions, sizeof(positions));
+ object.indices = malloc(sizeof(index));
+ ft_memcpy(object.indices, index, sizeof(index));
+ object.vertices_len = 12;
+ object.indices_len = 6;
/* for (size_t i = 0; i < object.indices_len; i++) */
/* printf("%u\n", object.indices[i]); */
/* for (size_t i = 0; i < object.vertices_len; i++) */
/* printf("%f\n", object.vertices[i]); */
/* printf("%lu\n", object.indices_len); */
+ t_ftmmat4 trans;
+ t_ftmvec3 vec;
+
+ ftm_mat4init_eye(&trans, 1.0);
+ /* ftm_mat4translate(&trans, 0.5, 0.5, 0.0); */
+
+ ftm_mat4rotate(&trans, ftm_radian(45.0), ftm_vec3init(&vec, 0.0, 0.0, 1.0));
+
+ /* ftm_mat4scale(&trans, 0.5, 0.5, 0.5); */
+
+ for (int i = 0; i < 4; i++)
+ {
+ for (int j = 0; j < 4; j++)
+ {
+ printf("%f, ", trans.m[i * 4 + j]);
+ }
+ printf("\n");
+ }
+
if ((window = glfw_init(400, 400)) == NULL
|| gl_state_init(&state, &object) == -1)
return (1);
+
+ GL_CALL(glBindBuffer(GL_ARRAY_BUFFER, 0));
+ GL_CALL(glBindVertexArray(0));
+
+ GL_CALL(glPolygonMode(GL_FRONT_AND_BACK, GL_LINE));
+
+ GL_CALL(glUseProgram(state.shader));
+ gl_state_set_mvp(&state, &trans);
+
while (!glfwWindowShouldClose(window))
{
+ GL_CALL(glClearColor(0.2f, 0.3f, 0.3f, 1.0f));
GL_CALL(glClear(GL_COLOR_BUFFER_BIT));
+
GL_CALL(glUseProgram(state.shader));
+ ftm_mat4rotate(&trans, ftm_radian(1.0), ftm_vec3init(&vec, 0.0, 0.0, 1.0));
+ gl_state_set_mvp(&state, &trans);
+
GL_CALL(glBindVertexArray(state.vertex_array));
- GL_CALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, state.index_buf));
- GL_CALL(glDrawElements(GL_TRIANGLES, object.vertices_len, GL_UNSIGNED_INT, (const void*)0));
+ GL_CALL(glDrawElements(GL_TRIANGLES, object.indices_len, GL_UNSIGNED_INT, (void*)0));
+
glfwSwapBuffers(window);
glfwPollEvents();
}
diff --git a/src/parse.c b/src/parse.c
index b83d9e8..6290b1a 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/05/09 11:02:00 by charles #+# #+# */
-/* Updated: 2020/05/11 01:29:13 by charles ### ########.fr */
+/* Updated: 2020/05/11 15:55:44 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -21,7 +21,7 @@ static int st_parse_face(char **indexes_strs, t_ftvec *indices)
unsigned int first;
unsigned int tmp;
- len = ft_split_len(indexes_strs);
+ len = ft_strslen(indexes_strs);
first = ft_atoi(indexes_strs[0]);
/* if (ft_vecpush(indices, *(void**)&first) == NULL) */
/* return (-1); */
@@ -64,11 +64,11 @@ static int st_parse_line(char *line, t_ftvec *vertices, t_ftvec *indices)
if ((split = ft_split(line + 1, ' ')) == NULL)
return (-1);
ret = -1;
- if (*line == 'v' && ft_split_len(split) == 3)
+ if (*line == 'v' && ft_strslen(split) == 3)
ret = st_parse_vertex(split, vertices);
- if (*line == 'f' && ft_split_len(split) >= 3)
+ if (*line == 'f' && ft_strslen(split) >= 3)
ret = st_parse_face(split, indices);
- ft_split_destroy(split);
+ ft_strsdestroy(split);
return (ret);
}
@@ -101,7 +101,8 @@ int parse(char *filepath, t_object *object)
t_ftvec *vertices;
t_ftvec *indices;
- if ((fd = open(filepath, O_RDONLY)) == -1)
+ if (!has_extension(filepath, ".obj")
+ || (fd = open(filepath, O_RDONLY)) == -1)
return (-1);
if ((vertices = ft_vecnew(SCOP_VEC_DEFAULT_SIZE)) == NULL)
return (-1);
diff --git a/src/shader.c b/src/shader.c
index 2e12a3e..dac76c8 100644
--- a/src/shader.c
+++ b/src/shader.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/05/11 09:35:54 by charles #+# #+# */
-/* Updated: 2020/05/11 12:25:16 by charles ### ########.fr */
+/* Updated: 2020/05/11 21:30:29 by charles ### ########.fr */
/* */
/* ************************************************************************** */
@@ -17,17 +17,17 @@
static unsigned int st_compile(char *filepath, unsigned int type)
{
- char *src;
+ t_ftmem file;
unsigned int id;
int result;
int len;
char *msg;
- if ((src = ft_getfile(open(filepath, O_RDONLY))) == NULL)
+ if (ft_getfile(open(filepath, O_RDONLY), &file) == -1)
return (0);
GL_CALL(id = glCreateShader(type));
- GL_CALL(glShaderSource(id, 1, (const char**)&src, NULL));
- free(src);
+ GL_CALL(glShaderSource(id, 1, (const char**)&file.data, NULL));
+ free(file.data);
GL_CALL(glCompileShader(id));
GL_CALL(glGetShaderiv(id, GL_COMPILE_STATUS, &result));
if (result == GL_FALSE)
diff --git a/src/texture.c b/src/texture.c
new file mode 100644
index 0000000..e499af6
--- /dev/null
+++ b/src/texture.c
@@ -0,0 +1,44 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* texture.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/11 14:27:34 by charles #+# #+# */
+/* Updated: 2020/05/11 16:19:56 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "scop.h"
+
+uint8_t *st_read_bmp(char *filepath, size_t *width, size_t *height)
+{
+ t_ftmem file;
+
+ if (ft_getfile(open(filepath, O_RDONLY), &file) == -1)
+ return (NULL);
+ *width = 0;
+ *height = 0;
+ return (file.data);
+}
+
+unsigned int texture_new(char *filepath)
+{
+ uint8_t *data;
+ unsigned int texture;
+ size_t width;
+ size_t height;
+
+ if ((data = st_read_bmp(filepath, &width, &height)) == NULL)
+ return (0);
+ GL_CALL(glGenTextures(1, &texture));
+ GL_CALL(glBindTexture(GL_TEXTURE_2D, texture));
+ GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
+ GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
+ GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
+ GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
+ free(data);
+ return (texture);
+}
diff --git a/vendor/libft b/vendor/libft
-Subproject a4b9cda7d6733f2b077f8586e3b3e69351e7dfb
+Subproject b9f000a80cbba38b8f21c9737a42f07573ec7b9
diff --git a/vendor/libftm/Makefile b/vendor/libftm/Makefile
index 2348458..10b2bbd 100644
--- a/vendor/libftm/Makefile
+++ b/vendor/libftm/Makefile
@@ -6,7 +6,7 @@
# By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2020/05/09 20:44:53 by charles #+# #+# #
-# Updated: 2020/05/09 21:20:08 by charles ### ########.fr #
+# Updated: 2020/05/12 11:43:06 by charles ### ########.fr #
# #
# **************************************************************************** #
@@ -21,7 +21,7 @@ CC = gcc
OFLAG ?= -O0
CCFLAGS = $(OFLAG) -I$(INC_DIR) -Wall -Wextra -Werror
-NAME = libft.a
+NAME = libftm.a
SRC = $(shell find $(SRC_DIR) -type f -name '*.c')
INC = $(shell find $(INC_DIR) -type f -name '*.h')
diff --git a/vendor/libftm/inc/libftm.h b/vendor/libftm/inc/libftm.h
new file mode 100644
index 0000000..9755d68
--- /dev/null
+++ b/vendor/libftm/inc/libftm.h
@@ -0,0 +1,20 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* libftm.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:07:32 by charles #+# #+# */
+/* Updated: 2020/05/12 13:42:27 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef LIBFTM_H
+# define LIBFTM_H
+
+# include <math.h>
+
+float ftm_radian(float degree);
+
+#endif
diff --git a/vendor/libftm/inc/libftm_mat4.h b/vendor/libftm/inc/libftm_mat4.h
new file mode 100644
index 0000000..f69d7e6
--- /dev/null
+++ b/vendor/libftm/inc/libftm_mat4.h
@@ -0,0 +1,35 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* libftm_mat4.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:04:59 by charles #+# #+# */
+/* Updated: 2020/05/12 13:53:40 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef LIBFTM_MAT4_H
+# define LIBFTM_MAT4_H
+
+# include <stddef.h>
+# include <math.h>
+# include "libftm_vec3.h"
+
+typedef struct
+{
+ float m[4 * 4];
+} t_ftmmat4;
+
+t_ftmmat4 *ftm_mat4init_eye(t_ftmmat4 *mat4, float x);
+t_ftmmat4 *ftm_mat4init_fill(t_ftmmat4 *mat4, float x);
+t_ftmmat4 *ftm_mat4translate(t_ftmmat4 *mat4, float x, float y, float z);
+t_ftmmat4 *ftm_mat4rotate(t_ftmmat4 *mat4, float radian, t_ftmvec3 *axis);
+t_ftmmat4 *ftm_mat4scale(t_ftmmat4 *mat4, float x, float y, float z);
+t_ftmmat4 *ftm_mat4mul(t_ftmmat4 *dst, t_ftmmat4 *other);
+t_ftmmat4 *ftm_mat4set(t_ftmmat4 *mat4, size_t y, size_t x, float value);
+float ftm_mat4get(t_ftmmat4 *mat4, size_t y, size_t x);
+
+
+#endif
diff --git a/vendor/libftm/inc/libftm_vec3.h b/vendor/libftm/inc/libftm_vec3.h
new file mode 100644
index 0000000..e9df2c7
--- /dev/null
+++ b/vendor/libftm/inc/libftm_vec3.h
@@ -0,0 +1,23 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* libftm_vec3.h :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:02:29 by charles #+# #+# */
+/* Updated: 2020/05/12 11:04:08 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#ifndef LIBFTM_VEC3_H
+# define LIBFTM_VEC3_H
+
+typedef struct
+{
+ float v[3];
+} t_ftmvec3;
+
+t_ftmvec3 *ftm_vec3init(t_ftmvec3 *vec3, float x, float y, float z);
+
+#endif
diff --git a/vendor/libftm/src/ftm_radian.c b/vendor/libftm/src/ftm_radian.c
new file mode 100644
index 0000000..6e1e380
--- /dev/null
+++ b/vendor/libftm/src/ftm_radian.c
@@ -0,0 +1,18 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_radian.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:08:29 by charles #+# #+# */
+/* Updated: 2020/05/12 11:19:17 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm.h"
+
+float ftm_radian(float degree)
+{
+ return ((degree / 180.0) * M_PI);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4get.c b/vendor/libftm/src/mat4/ftm_mat4get.c
new file mode 100644
index 0000000..3223788
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4get.c
@@ -0,0 +1,18 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4get.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 13:54:08 by charles #+# #+# */
+/* Updated: 2020/05/12 13:54:09 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+float ftm_mat4get(t_ftmmat4 *mat4, size_t y, size_t x)
+{
+ return (mat4->m[y * 4 + x]);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4init_eye.c b/vendor/libftm/src/mat4/ftm_mat4init_eye.c
new file mode 100644
index 0000000..d32f075
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4init_eye.c
@@ -0,0 +1,23 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4init_eye.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:10:44 by charles #+# #+# */
+/* Updated: 2020/05/12 12:17:21 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+t_ftmmat4 *ftm_mat4init_eye(t_ftmmat4 *mat4, float x)
+{
+ ftm_mat4init_fill(mat4, 0.0);
+ ftm_mat4set(mat4, 0, 0, x);
+ ftm_mat4set(mat4, 1, 1, x);
+ ftm_mat4set(mat4, 2, 2, x);
+ ftm_mat4set(mat4, 3, 3, x);
+ return (mat4);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4init_fill.c b/vendor/libftm/src/mat4/ftm_mat4init_fill.c
new file mode 100644
index 0000000..d7b0b3a
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4init_fill.c
@@ -0,0 +1,26 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4init_fill.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 12:16:59 by charles #+# #+# */
+/* Updated: 2020/05/12 12:18:01 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+t_ftmmat4 *ftm_mat4init_fill(t_ftmmat4 *mat4, float x)
+{
+ size_t i;
+
+ i = 0;
+ while (i < 4 * 4)
+ {
+ mat4->m[i] = x;
+ i++;
+ }
+ return (mat4);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4mul.c b/vendor/libftm/src/mat4/ftm_mat4mul.c
new file mode 100644
index 0000000..553e47c
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4mul.c
@@ -0,0 +1,40 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4mul.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:22:20 by charles #+# #+# */
+/* Updated: 2020/05/12 14:03:19 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+static float st_dot(t_ftmmat4 *a, t_ftmmat4 *b, int y, int x)
+{
+ return (ftm_mat4get(a, y, 0) * ftm_mat4get(b, 0, x) +
+ ftm_mat4get(a, y, 1) * ftm_mat4get(b, 1, x) +
+ ftm_mat4get(a, y, 2) * ftm_mat4get(b, 2, x) +
+ ftm_mat4get(a, y, 3) * ftm_mat4get(b, 3, x));
+}
+
+t_ftmmat4 *ftm_mat4mul(t_ftmmat4 *dst, t_ftmmat4 *other)
+{
+ t_ftmmat4 tmp;
+ int i;
+ int j;
+
+ i = -1;
+ while (++i < 4)
+ {
+ j = -1;
+ while (++j < 4)
+ ftm_mat4set(&tmp, i, j, st_dot(dst, other, i, j));
+ }
+ i = -1;
+ while (++i < 4 * 4)
+ dst->m[i] = tmp.m[i];
+ return (dst);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4rotate.c b/vendor/libftm/src/mat4/ftm_mat4rotate.c
new file mode 100644
index 0000000..0a39c16
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4rotate.c
@@ -0,0 +1,70 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4rotate.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:44:18 by charles #+# #+# */
+/* Updated: 2020/05/12 14:05:18 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+/*
+** Rotation axis/vector [x, y, z]
+**
+** 1st column:
+** | cos(θ) + x^2 (1 − cos(θ)) |
+** | y x (1 − cos(θ)) + z sin(θ) |
+** | z x (1 − cos(θ)) − y sin(θ) |
+** | 0 |
+**
+** 2nd column:
+** | x y (1 − cos(θ)) − z sin(θ) |
+** | cos(θ) + y^2 (1 − cos(θ)) |
+** | z y (1 − cos(θ)) + x sin(θ) |
+** | 0 |
+**
+** 3rd column:
+** | x z (1 − cos(θ)) + y sin(θ) |
+** | y z (1 − cos(θ)) − x sin(θ) |
+** | cos(θ) + z^2 (1 − cos(θ)) |
+** | 0 |
+*/
+
+t_ftmmat4 *ftm_mat4rotate(t_ftmmat4 *mat4, float theta, t_ftmvec3 *axis)
+{
+ float x;
+ float y;
+ float z;
+ float sin_t;
+ float cos_t;
+ t_ftmmat4 rot;
+
+ x = axis->v[0];
+ y = axis->v[1];
+ z = axis->v[2];
+ sin_t = sin(theta);
+ cos_t = cos(theta);
+ ftm_mat4init_fill(&rot, 0.0);
+ ftm_mat4set(&rot, 0, 0, cos_t + x * x * (1 - cos_t));
+ ftm_mat4set(&rot, 1, 0, y * x * (1 - cos_t) + z * sin_t);
+ ftm_mat4set(&rot, 2, 0, z * x * (1 - cos_t) + y * sin_t);
+ ftm_mat4set(&rot, 3, 0, 0.0);
+
+ ftm_mat4set(&rot, 0, 1, x * y * (1 - cos_t) - z * sin_t);
+ ftm_mat4set(&rot, 1, 1, cos_t + y * y * (1 - cos_t));
+ ftm_mat4set(&rot, 2, 1, z * y * (1 - cos_t) + x * sin_t);
+ ftm_mat4set(&rot, 3, 1, 0);
+
+ ftm_mat4set(&rot, 0, 2, x * z * (1 - cos_t) + y * sin_t);
+ ftm_mat4set(&rot, 1, 2, y * z * (1 - cos_t) - x * sin_t);
+ ftm_mat4set(&rot, 2, 2, cos_t + z * z * (1 - cos_t));
+ ftm_mat4set(&rot, 3, 2, 0);
+
+ ftm_mat4set(&rot, 3, 3, 1.0);
+ ftm_mat4mul(mat4, &rot);
+ return (mat4);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4scale.c b/vendor/libftm/src/mat4/ftm_mat4scale.c
new file mode 100644
index 0000000..a278c83
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4scale.c
@@ -0,0 +1,25 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4scale.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:16:19 by charles #+# #+# */
+/* Updated: 2020/05/12 11:18:38 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+t_ftmmat4 *ftm_mat4scale(t_ftmmat4 *mat4, float x, float y, float z)
+{
+ t_ftmmat4 scale;
+
+ ftm_mat4init_eye(&scale, 1.0);
+ ftm_mat4set(&scale, 0, 0, x);
+ ftm_mat4set(&scale, 1, 1, y);
+ ftm_mat4set(&scale, 2, 2, z);
+ ftm_mat4mul(mat4, &scale);
+ return (mat4);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4set.c b/vendor/libftm/src/mat4/ftm_mat4set.c
new file mode 100644
index 0000000..55e8125
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4set.c
@@ -0,0 +1,19 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4set.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:21:20 by charles #+# #+# */
+/* Updated: 2020/05/12 11:21:58 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+t_ftmmat4 *ftm_mat4set(t_ftmmat4 *mat4, size_t y, size_t x, float value)
+{
+ mat4->m[y * 4 + x] = value;
+ return (mat4);
+}
diff --git a/vendor/libftm/src/mat4/ftm_mat4translate.c b/vendor/libftm/src/mat4/ftm_mat4translate.c
new file mode 100644
index 0000000..38a44d9
--- /dev/null
+++ b/vendor/libftm/src/mat4/ftm_mat4translate.c
@@ -0,0 +1,25 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_mat4translate.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:12:21 by charles #+# #+# */
+/* Updated: 2020/05/12 11:19:05 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_mat4.h"
+
+t_ftmmat4 *ftm_mat4translate(t_ftmmat4 *mat4, float x, float y, float z)
+{
+ t_ftmmat4 trans;
+
+ ftm_mat4init_eye(&trans, 1.0);
+ ftm_mat4set(&trans, 0, 3, x);
+ ftm_mat4set(&trans, 1, 3, y);
+ ftm_mat4set(&trans, 2, 3, z);
+ ftm_mat4mul(mat4, &trans);
+ return (mat4);
+}
diff --git a/vendor/libftm/src/vec3/ftm_vec3init.c b/vendor/libftm/src/vec3/ftm_vec3init.c
new file mode 100644
index 0000000..ff5047c
--- /dev/null
+++ b/vendor/libftm/src/vec3/ftm_vec3init.c
@@ -0,0 +1,21 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* ftm_vec3init.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/05/12 11:19:55 by charles #+# #+# */
+/* Updated: 2020/05/12 11:20:53 by charles ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "libftm_vec3.h"
+
+t_ftmvec3 *ftm_vec3init(t_ftmvec3 *vec3, float x, float y, float z)
+{
+ vec3->v[0] = x;
+ vec3->v[1] = y;
+ vec3->v[2] = z;
+ return (vec3);
+}