31 Commits

Author SHA1 Message Date
islas
1d254eade5 Actualizar src/surface.c 2024-12-01 22:50:15 +00:00
PedroEdiaz
904d686c6e Clean up codebase, rm texture, matrix -> load 2024-12-01 16:12:17 -06:00
PedroEdiaz
a293008137 Fix size with variable grid 2024-12-01 13:43:27 -06:00
PedroEdiaz
0729388291 Set up struct surface, and use variable grid 2024-12-01 13:23:29 -06:00
PedroEdiaz
b19100424d Clean 2024-12-01 12:21:29 -06:00
PedroEdiaz
0db8ed60ac Assert Style 2024-12-01 12:20:59 -06:00
PedroEdiaz
6c322a9759 Avoid bottle-neck while drwing lines, fix surface 2024-12-01 12:19:53 -06:00
PedroEdiaz
8be2052c45 Merge branch 'roberto' into experimental 2024-12-01 00:24:52 -06:00
PedroEdiaz
1a0b804b57 Fix: cube, add test for cube generation 2024-12-01 00:13:26 -06:00
alan
468f9f951d Número de caras agregado 2024-11-30 22:48:29 -06:00
PedroEdiaz
df5ae70aa2 Use G-S on all dimentions 2024-11-30 22:27:57 -06:00
PedroEdiaz
565afe2f7d Merge branch 'main' into roberto 2024-11-30 22:22:48 -06:00
alan
23f98687fe Cubo arreglado 2024-11-30 21:10:43 -06:00
PedroEdiaz
465d7acb3a Merge branch 'experimental' 2024-11-29 23:44:11 -06:00
PedroEdiaz
590fa22658 Better use of viewport 2024-11-28 18:52:53 -06:00
PedroEdiaz
6c7c22ce50 Fix: rotations on R4 2024-11-28 16:23:39 -06:00
PedroEdiaz
1e009d5bdf Fix gamma, add Glad, error if glad is compiled with emscripten 2024-11-28 09:55:48 -06:00
roberto.mc
814f0c94a4 ya son puros for loops xd 2024-11-27 23:22:31 -06:00
PedroEdiaz
2c8795bd9f Ejemplo: de cambiar cglm por for-loops 2024-11-27 19:26:28 -06:00
roberto.mc
7888c06c41 aiura con R^n 2024-11-27 19:08:57 -06:00
PedroEdiaz
61388252ae Merge branch 'alan2' into experimental 2024-11-27 17:40:16 -06:00
PedroEdiaz
8a4e95fdd3 Fix: compilation error 2024-11-27 17:31:47 -06:00
PedroEdiaz
4840b0c8ba Merge branch 'main' into experimental 2024-11-27 10:58:58 -06:00
PedroEdiaz
589721a953 WIP: Rotations in R4, and change colors 2024-11-26 23:51:30 -06:00
PedroEdiaz
a8ae6aaef6 Add gamma correction, change illumination values 2024-11-26 23:49:49 -06:00
PedroEdiaz
6c5e2a9a29 Merge branch 'main' into roberto 2024-11-20 11:14:59 -06:00
PedroEdiaz
d967550dd8 Fix Compilation errors 2024-11-20 11:08:07 -06:00
roberto.mc
793c11757d aiura pedro 2024-11-18 23:14:54 -06:00
PedroEdiaz
583c0cb92f Use modern scrolling for better UX 2024-11-04 20:56:50 -06:00
PedroEdiaz
c37614ae52 default: GLAD 2024-10-30 22:44:58 -06:00
PedroEdiaz
fb2cbe20db glew -> glad & libglfw.so -> libglfw.a 2024-10-30 22:43:10 -06:00
13 changed files with 658 additions and 434 deletions

View File

@@ -1,11 +1,11 @@
BIN = manigraph BIN = manigraph
OBJ = \ OBJ = \
ext/glad/glad.o \
src/surface.o \ src/surface.o \
src/context.o \ src/context.o \
src/texture.o \
src/window.o \ src/window.o \
src/matrix.o \ src/load.o \
src/shader.o \ src/shader.o \
src/input.o \ src/input.o \
src/mesh.o \ src/mesh.o \
@@ -14,6 +14,7 @@ OBJ = \
CFLAGS = \ CFLAGS = \
-I./ext/cglm/include \ -I./ext/cglm/include \
-I./ext/glfw/include \ -I./ext/glfw/include \
-I./ext/glad \
-Wall -Wno-unused-function -std=c99 -D_GNU_SOURCE \ -Wall -Wno-unused-function -std=c99 -D_GNU_SOURCE \
WAYLAND-LIB = \ WAYLAND-LIB = \
@@ -28,61 +29,50 @@ WAYLAND-LIB = \
wayland wayland
help: help:
@echo "Para compilar el proyecto a tu sistema operativo" @echo "Usage:"
@echo "porfavor usa uno de los siguientes comandos:"
@echo " $(MAKE) windows" @echo " $(MAKE) windows"
@echo " $(MAKE) linux-x11" @echo " $(MAKE) linux-x11"
@echo " $(MAKE) linux-wayland" @echo " $(MAKE) linux-wayland"
@echo " $(MAKE) cocoa" @echo " $(MAKE) cocoa"
@echo " $(MAKE) CC=emcc wasm" @echo " $(MAKE) CC=emcc wasm"
@echo "Para limpiar los archivos compilados se puede usar" @echo "Clean"
@echo " $(MAKE) clean" @echo " $(MAKE) clean"
@echo "Para ejecturar el programa sin instalarlos se puede usar:"
@echo " $(MAKE) run-linux"
src/main.o: src/data/axis.h src/data/shaders.h src/main.o: src/data/axis.h src/data/shaders.h
# WINDOWS windows: $(OBJ)
windows: $(OBJ) glfw.dll cd ext; $(MAKE) -f glfw.mk windows; cd -
$(CC) $(CFLAGS) $(OBJ) -o $(BIN) -L. -lglfw -lopengl32 -lglew32 $(CC) $(CFLAGS) $(OBJ) -o $(BIN) -L. -lglfw -lopengl32
glfw.dll: glfw.dll:
$(CC) -fPIC -shared -D_GLFW_WIN32 -D_GLFW_BUILD_DLL ./ext/glfw/src/*.c -o $@ -lgdi32 $(CC) -fPIC -shared -D_GLFW_WIN32 -D_GLFW_BUILD_DLL ./ext/glfw/src/*.c -o $@ -lgdi32
src/main.o: src/data/shaders.h src/data/axis.h
# LINUX # LINUX
linux-wayland: $(OBJ) linux-wayland: $(OBJ)
for i in $(WAYLAND-LIB); \ cd ext; $(MAKE) -f glfw.mk linux-wayland; cd -
do \ $(CC) -o $(BIN) $(OBJ) ext/libglfw.a -lGL -lm
wayland-scanner client-header ext/glfw/deps/wayland/$$i.xml ext/glfw/deps/wayland/$$i-client-protocol.h; \
wayland-scanner private-code ext/glfw/deps/wayland/$$i.xml ext/glfw/deps/wayland/$$i-client-protocol-code.h; \
done
$(MAKE) DFLAGS="-D_GLFW_WAYLAND" libglfw.so
$(CC) -o $(BIN) $(OBJ) -L. -lGLEW -lGL -lglfw -lm
linux-x11: $(OBJ) linux-x11: $(OBJ)
$(MAKE) DFLAGS="-D_GLFW_X11" libglfw.so cd ext; $(MAKE) -f glfw.mk linux-x11; cd -
$(CC) -o $(BIN) $(OBJ) -L. -lGLEW -lGL -lglfw -lm $(CC) -o $(BIN) $(OBJ) ext/libglfw.a -lGL -lm
run-linux:
LD_LIBRARY_PATH=. ./$(BIN)
# COCOA
cocoa: $(OBJ) cocoa: $(OBJ)
$(MAKE) DFLAGS="-D_GLFW_COCOA" libglfw.so cd ext; $(MAKE) -f glfw.mk cocoa; cd -
$(CC) -framework OpenGL -o $(BIN) $(OBJ) -L. -lGLEW -lGL -lglfw $(CC) -framework OpenGL -o $(BIN) $(OBJ) ext/glfw.a -lGL -lglfw
wasm: $(OBJ) wasm: $(OBJ)
$(CC) -sUSE_WEBGL2=1 -sUSE_GLFW=3 -o mani.html $(OBJ) $(CC) -sUSE_WEBGL2=1 -sUSE_GLFW=3 -o $(BIN).html $(OBJ)
chmod -x $(BIN).wasm
libglfw.so: libglfw.so:
$(CC) -fPIC -shared $(DFLAGS) -D_GLFW_BUILD_DLL -Iext/glfw/deps/wayland ./ext/glfw/src/*.c -o $@ $(CC) -fPIC -shared $(DFLAGS) -D_GLFW_BUILD_DLL -Iext/glfw/deps/wayland ./ext/glfw/src/*.c -o $@
clean: clean:
rm $(OBJ) $(BIN) ext/glfw/deps/wayland/*.h rm $(OBJ) $(BIN)
cd ext; $(MAKE) -f glfw.mk clean; cd -
.SUFFIXES: .c .o .SUFFIXES: .c .o
.c.o: src/main.h .c.o:
$(CC) $(CFLAGS) -c -o $@ $< $(CC) -Wno-implicit-function-declaration $(CFLAGS) -c -o $@ $<

71
ext/glfw.mk Normal file
View File

@@ -0,0 +1,71 @@
BIN = libglfw.a
OBJ = \
glfw/src/context.o \
glfw/src/egl_context.o \
glfw/src/glx_context.o \
glfw/src/init.o \
glfw/src/input.o \
glfw/src/linux_joystick.o \
glfw/src/monitor.o \
glfw/src/null_init.o \
glfw/src/null_joystick.o \
glfw/src/null_monitor.o \
glfw/src/null_window.o \
glfw/src/osmesa_context.o \
glfw/src/platform.o \
glfw/src/posix_module.o \
glfw/src/posix_poll.o \
glfw/src/posix_thread.o \
glfw/src/posix_time.o \
glfw/src/vulkan.o \
glfw/src/wgl_context.o \
glfw/src/win32_init.o \
glfw/src/win32_joystick.o \
glfw/src/win32_module.o \
glfw/src/win32_monitor.o \
glfw/src/win32_thread.o \
glfw/src/win32_time.o \
glfw/src/win32_window.o \
glfw/src/window.o \
glfw/src/wl_init.o \
glfw/src/wl_monitor.o \
glfw/src/wl_window.o \
glfw/src/x11_init.o \
glfw/src/x11_monitor.o \
glfw/src/x11_window.o \
glfw/src/xkb_unicode.o
WAYLAND-LIB = \
xdg-shell \
relative-pointer-unstable-v1 \
xdg-decoration-unstable-v1 \
pointer-constraints-unstable-v1 \
viewporter \
idle-inhibit-unstable-v1 \
fractional-scale-v1 \
xdg-activation-v1 \
wayland
windows:
$(MAKE) $(OBJ) CFLAGS="-D_GLFW_WIN32 -Iglfw/deps/wayland"
$(AR) rsc $(BIN) $(OBJ)
linux-x11:
$(MAKE) $(OBJ) CFLAGS="-D_GLFW_X11 -Iglfw/deps/wayland"
$(AR) rsc $(BIN) $(OBJ)
linux-wayland:
for i in $(WAYLAND-LIB); \
do \
wayland-scanner client-header glfw/deps/wayland/$$i.xml glfw/deps/wayland/$$i-client-protocol.h; \
wayland-scanner private-code glfw/deps/wayland/$$i.xml glfw/deps/wayland/$$i-client-protocol-code.h; \
done
$(MAKE) $(OBJ) CFLAGS="-D_GLFW_WAYLAND -fPIC -Iglfw/deps/wayland"
$(AR) rsc $(BIN) $(OBJ)
clean:
rm $(OBJ) $(BIN)
rm glfw/deps/wayland/*.h

View File

@@ -3,18 +3,13 @@
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
#include <GL/gl.h> #include <GL/gl.h>
#else #else
#ifdef GLAD
#include <GLFW/glfw3.h>
#include <glad.h> #include <glad.h>
#else #include <GLFW/glfw3.h>
#include <GL/glew.h>
#endif
#endif #endif
void set_clean_color_context(unsigned char r, unsigned char g, unsigned char b) void set_clean_color_context(unsigned char r, unsigned char g, unsigned char b)
{ {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glClearColor((float)r / 0xff, (float)g / 0xff, (float)b / 0xff, 1.0); glClearColor((float)r / 0xff, (float)g / 0xff, (float)b / 0xff, 1.0);
} }
@@ -23,12 +18,7 @@ int init_context(void)
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
return 1; return 1;
#else #else
#ifdef GLAD
return gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); return gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
#else
return glewInit();
#endif
#endif #endif
} }

View File

@@ -1,4 +1,4 @@
const char * vs = const char *vs =
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
"#version 300 es\n" "#version 300 es\n"
"precision highp float;" "precision highp float;"
@@ -15,79 +15,84 @@ const char * vs =
"layout (location = 6) in float aNormal_z;" "layout (location = 6) in float aNormal_z;"
"layout (location = 7) in float aNormal_w;" "layout (location = 7) in float aNormal_w;"
"uniform float idx;" "uniform float angle;"
"uniform float i;"
"uniform vec4 color;"
"uniform mat4 fix;" "uniform mat4 fix;"
"uniform mat4 rot;" "uniform mat4 rot;"
"uniform mat4 mdl;"
"out float index;"
"out vec3 Normal;" "out vec3 Normal;"
"out vec3 FragPos;" "out vec3 FragPos;"
"out vec4 Color;"
"mat2 rotate2d( float angle )"
"{"
"return mat2( cos(angle), sin(angle), -sin(angle), cos(angle) );"
"}"
"void main()" "void main()"
"{" "{"
" index=idx;" " Color=color;"
" vec3 aNormal = vec3(aNormal_x,aNormal_y,aNormal_z);" " vec3 aNormal = vec3(aNormal_x,aNormal_y,aNormal_z);"
" vec3 aPos = vec3(aPos_x,aPos_y,aPos_z);" " vec3 aPos = vec3(aPos_x,aPos_y,aPos_z);"
" Normal = mat3(transpose(inverse(rot*mdl))) * aNormal;"
" gl_Position = fix * rot * mdl * vec4( aPos, 1.0 );\n" " aNormal[int(i)] = (vec2(aNormal[int(i)], aNormal_w) * "
" FragPos = vec3( rot * mdl * vec4(aPos, 1.0));" "rotate2d(angle))[0];"
" aPos[int(i)] = (vec2(aPos[int(i)], aPos_w) * rotate2d(angle))[0];"
" Normal = mat3(transpose(inverse(rot))) * aNormal;"
" gl_Position = fix * rot * vec4( aPos, 1.0 );\n"
" FragPos = vec3( rot * vec4(aPos, 1.0));"
"}"; "}";
const char *fs_plain =
const char * fs_plain =
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
"#version 300 es\n" "#version 300 es\n"
"precision highp float;" "precision highp float;"
"precision highp sampler2DArray;"
#else #else
"#version 330 core\n" "#version 330 core\n"
#endif #endif
"uniform sampler2DArray palette;"
"in float index;"
"out vec4 FragColor;" "out vec4 FragColor;"
"in vec3 Normal;" "in vec3 Normal;"
"in vec3 FragPos;" "in vec3 FragPos;"
"in vec4 Color;"
"void main()" "void main()"
"{" "{"
" FragColor = texture( palette, vec3( 0, 0, index ) ).rgba;" " FragColor = vec4(pow(vec3(Color),vec3(1.0/2.2)),Color.a);"
"}"; "}";
const char * fs = const char *fs =
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
"#version 300 es\n" "#version 300 es\n"
"precision highp float;" "precision highp float;"
"precision highp sampler2DArray;"
#else #else
"#version 330 core\n" "#version 330 core\n"
#endif #endif
"uniform sampler2DArray palette;" "in vec3 Normal;"
"in vec3 FragPos;"
"in vec4 Color;"
"in float index;" "out vec4 FragColor;"
"in vec3 Normal;"
"in vec3 FragPos;"
"out vec4 FragColor;" "void main()"
"{"
"void main()" " vec3 viewPos = vec3(0, 0, -15);\n"
"{" " vec3 viewDir = normalize(viewPos - FragPos);\n"
" vec4 color = texture(palette, vec3(0, 0, index));\n"
" vec3 viewPos = vec3(0, 0, -15);\n" " vec3 lightPos = viewPos;\n"
" vec3 viewDir = normalize(viewPos - FragPos);\n" " vec3 lightDir = normalize(lightPos - FragPos);\n"
" vec3 lightPos = viewPos;\n" " vec3 halfwayDir = normalize(lightDir + viewDir);\n"
" vec3 lightDir = normalize(lightPos - FragPos);\n"
" vec3 halfwayDir = normalize(lightDir + viewDir);\n" " float specular = pow(abs(dot(normalize(Normal), halfwayDir)), 32.0);\n"
" float diffuse = abs(dot(normalize(Normal), lightDir));\n"
" float specular = pow(max(dot(normalize(Normal), halfwayDir), 0.0), 16.0);\n" " vec3 result = pow((0.5 + 0.5*diffuse + 1.5*specular) * Color.rgb, "
" float diffuse = max(dot(normalize(Normal), lightDir), 0.0);\n" "vec3(1.0/2.2));\n"
" FragColor = vec4(result, Color.a);\n"
" vec3 result = (0.5 + 0.5 * diffuse + specular) * color.rgb;\n" "}";
" FragColor = vec4(result, color.a);\n"
"}";

View File

@@ -9,6 +9,8 @@ unsigned char selected_axis = 0;
int window_width; int window_width;
int window_height; int window_height;
unsigned char animate_index=0;
versor q = GLM_QUAT_IDENTITY_INIT; versor q = GLM_QUAT_IDENTITY_INIT;
vec3 axis[3] = { vec3 axis[3] = {
@@ -49,25 +51,28 @@ void __key_callback_input(
switch (key) switch (key)
{ {
unsigned char tmp; unsigned char tmp;
case GLFW_KEY_I:
case GLFW_KEY_P:
tmp = projection.w; tmp = projection.w;
projection.w = projection.x; projection.w = projection.x;
projection.x = tmp; projection.x = tmp;
animate_index=1;
break; break;
case GLFW_KEY_O: case GLFW_KEY_O:
tmp = projection.w; tmp = projection.w;
projection.w = projection.y; projection.w = projection.y;
projection.y = tmp; projection.y = tmp;
animate_index=2;
break; break;
case GLFW_KEY_I: case GLFW_KEY_P:
tmp = projection.w; tmp = projection.w;
projection.w = projection.z; projection.w = projection.z;
projection.z = tmp; projection.z = tmp;
animate_index=3;
break; break;
} }
set_projection_mesh(projection);
return; return;
} }
@@ -107,13 +112,21 @@ void __mouse_callback_input(
void __scroll_callback_input(GLFWwindow *window, double xoffset, double yoffset) void __scroll_callback_input(GLFWwindow *window, double xoffset, double yoffset)
{ {
versor p = GLM_QUAT_IDENTITY_INIT; versor p = GLM_QUAT_IDENTITY_INIT;
versor r = GLM_QUAT_IDENTITY_INIT;
glm_quatv(p, yoffset * ANGLE, axis[selected_axis]); //glm_quatv(p, yoffset * ANGLE, axis[selected_axis]);
glm_quatv(p, yoffset * ANGLE * 2, (vec3){-1,0,0});
glm_quatv(r, xoffset * ANGLE * 2, (vec3){0,1,0});
glm_quat_mul(p, q, q); glm_quat_mul(p, q, q);
glm_quat_mul(r, q, q);
glm_quat_rotatev(p, axis[0], axis[0]); glm_quat_rotatev(p, axis[0], axis[0]);
glm_quat_rotatev(p, axis[1], axis[1]); glm_quat_rotatev(p, axis[1], axis[1]);
glm_quat_rotatev(p, axis[2], axis[2]); glm_quat_rotatev(p, axis[2], axis[2]);
glm_quat_rotatev(r, axis[0], axis[0]);
glm_quat_rotatev(r, axis[1], axis[1]);
glm_quat_rotatev(r, axis[2], axis[2]);
} }
quat_t poll_input(window_t window) quat_t poll_input(window_t window)
@@ -157,5 +170,13 @@ end:
glm_quat_rotatev(p, axis[1], axis[1]); glm_quat_rotatev(p, axis[1], axis[1]);
glm_quat_rotatev(p, axis[2], axis[2]); glm_quat_rotatev(p, axis[2], axis[2]);
glm_quat_normalize(q); glm_quat_normalize(q);
// LOG INFO
if(0)
{
printf("QUAT: %2.5f %2.5f %2.5f %2.5f\n", q[0], q[1], q[2], q[3]);
printf("PROY: %3d %3d %3d (%3d)\n", projection.x, projection.y, projection.z, projection.w );
printf("\n");
}
return q; return q;
} }

34
src/load.c Normal file
View File

@@ -0,0 +1,34 @@
#include "main.h"
#include <cglm/cam.h>
#include <cglm/mat4.h>
#include <cglm/quat.h>
void fix_matrix_load(id_t shader, float ratio)
{
mat4 m, n;
const int d = 7;
glm_lookat((vec3){0, 0, -d}, (vec3){0, 0, 0}, (vec3){0, 1, 0}, m);
glm_perspective(CGLM_PI / 6, ratio, d - 3, d + 3, n);
glm_mat4_mul(n, m, m);
load_mat4_to_shader(shader, "fix", (mat4_t)m);
}
void rot_matrix_load(id_t shader, quat_t q)
{
mat4 m;
glm_quat_mat4(q, m);
load_mat4_to_shader(shader, "rot", (mat4_t)m);
}
void color_load(id_t shader, unsigned char color[4])
{
float res[4];
res[0] = (float)color[0] / 0xff;
res[1] = (float)color[1] / 0xff;
res[2] = (float)color[2] / 0xff;
res[3] = (float)color[3] / 0xff;
load_float4_to_shader(shader, "color", res);
}

View File

@@ -1,5 +1,4 @@
#include "main.h" #include "main.h"
#include "data/axis.h"
#include "data/shaders.h" #include "data/shaders.h"
#include <stdio.h> #include <stdio.h>
@@ -12,19 +11,18 @@
#include <emscripten.h> #include <emscripten.h>
#endif #endif
float *generate_data_surface(unsigned int, unsigned char *); #ifndef M_PI
float *generate_normals_surface(float *, unsigned char); #define M_PI 3.14159
#endif
const char *wname = "manigraph: manifold grapher"; float *generate_data_surface(unsigned char *, unsigned long *);
float *generate_normals_surface(float *, unsigned char, unsigned long);
struct projection projection = {.x = 0, .y = 1, .z = 2, .w = 3}; struct projection projection = {.x = 0, .y = 1, .z = 2, .w = 3};
unsigned char palette[][4] = { const char *wname = "manigraph: manifold grapher";
{0xEB, 0xD3, 0xF8, 0xff},
{0xEB, 0xD4, 0xF8, 0xff}, unsigned char color[4] = {0x2F, 0x3C, 0x7E, 0xff};
{0xEB, 0xD5, 0xF8, 0xff},
{0x7A, 0x1C, 0xAC, 0xff},
};
void mlog(char *msg) void mlog(char *msg)
{ {
@@ -34,39 +32,58 @@ void mlog(char *msg)
} }
window_t window; window_t window;
mesh_t m_surface, m_axis; mesh_t m_surface;
id_t shader, shader_plain; id_t shader, shader_plain;
extern volatile unsigned char animate_index;
#ifndef EMSCRIPTEN #ifndef EMSCRIPTEN
static inline static inline
#endif #endif
void main_loop(void)
void
main_loop(void)
{ {
quat_t q; quat_t q;
q = poll_input(window); q = poll_input(window);
load_rot_matrix(shader, q);
load_rot_matrix(shader_plain, q);
rot_matrix_load(shader, q);
rot_matrix_load(shader_plain, q);
color_load(shader, color);
color_load(shader_plain, color);
{
static float angle = 0;
if (angle > M_PI / 2)
{
animate_index = 0;
angle = 0;
load_float_to_shader(shader, "angle", angle);
load_float_to_shader(shader_plain, "angle", angle);
set_projection_mesh(projection);
}
if (animate_index)
{
load_float_to_shader(shader, "i", animate_index - 1);
load_float_to_shader(shader_plain, "i", animate_index - 1);
angle += 0.01;
load_float_to_shader(shader, "angle", angle);
load_float_to_shader(shader_plain, "angle", angle);
}
}
clean_context(); clean_context();
#ifndef DEBUG draw_mesh(shader, m_surface);
load_mdl_matrix(shader_plain, 0, 0); draw_mesh_lines(shader_plain, m_surface);
draw_mesh(m_axis);
load_mdl_matrix(shader_plain, 1, 1);
draw_mesh(m_axis);
load_mdl_matrix(shader_plain, 2, 2);
draw_mesh(m_axis);
load_mdl_matrix(shader, 0, 3);
#else
load_mdl_matrix(shader_plain, 0, 3);
#endif
draw_mesh(m_surface);
} }
int main(void) int main(void)
{ {
id_t texture;
mlog("[VENTANA] Inicializando...\n"); mlog("[VENTANA] Inicializando...\n");
{ {
@@ -86,13 +103,7 @@ int main(void)
mlog("[CONTEXT] Error al inicializar...\n"); mlog("[CONTEXT] Error al inicializar...\n");
goto error_context; goto error_context;
} }
set_clean_color_context(0x2E, 0x07, 0x3F); set_clean_color_context(0xFF, 0xFF, 0xFF);
}
mlog("[TEXTURE] Inicializando...\n");
{
texture = create_palette_texture(palette, 4);
use_texture(texture);
} }
mlog("[SHADER] Inicializando...\n"); mlog("[SHADER] Inicializando...\n");
@@ -104,7 +115,7 @@ int main(void)
} }
load_program_to_shader(shader, vs, VERTEX); load_program_to_shader(shader, vs, VERTEX);
load_program_to_shader(shader, fs, FRAGMENT); load_program_to_shader(shader, fs, FRAGMENT);
load_fix_matrix(shader, (float)WIDTH / HEIGHT); fix_matrix_load(shader, (float)WIDTH / HEIGHT);
} }
mlog("[SHADER] Inicializando...\n"); mlog("[SHADER] Inicializando...\n");
@@ -116,65 +127,53 @@ int main(void)
} }
load_program_to_shader(shader_plain, vs, VERTEX); load_program_to_shader(shader_plain, vs, VERTEX);
load_program_to_shader(shader_plain, fs_plain, FRAGMENT); load_program_to_shader(shader_plain, fs_plain, FRAGMENT);
load_fix_matrix(shader_plain, (float)WIDTH / HEIGHT); fix_matrix_load(shader_plain, (float)WIDTH / HEIGHT);
} }
mlog("[MESH] Inicializando...\n"); mlog("[MESH] Inicializando...\n");
{ {
unsigned char m; struct surface surface;
float *n_surface, *d_surface;
d_surface = generate_data_surface(16, &m);
n_surface = generate_normals_surface(d_surface, m);
projection.m = m; surface.data = generate_data_surface(&surface.dim, &surface.vertex);
surface.norm =
generate_normals_surface(surface.data, surface.dim, surface.vertex);
if (!(m_surface = create_mesh(d_surface, n_surface, m))) if (!(m_surface = create_mesh(surface)))
{ {
mlog("[MESH] Error al inicializar...\n"); mlog("[MESH] Error al inicializar...\n");
goto error_mesh_surface; goto error_mesh_surface;
} }
projection.m = surface.dim;
projection.mesh = m_surface; projection.mesh = m_surface;
free(n_surface); set_projection_mesh(projection);
free(d_surface);
}
mlog("[MESH] Inicializando...\n"); free(surface.norm);
{ free(surface.data);
if (!(m_axis = create_mesh(d_axis, NULL, 3)))
{
mlog("[MESH] Error al inicializar...\n");
goto error_mesh_axis;
}
} }
mlog("[MAIN LOOP] Inicializando...\n"); mlog("[MAIN LOOP] Inicializando...\n");
#ifdef EMSCRIPTEN #ifdef EMSCRIPTEN
emscripten_set_main_loop(&main_loop, 0, 1); emscripten_set_main_loop(&main_loop, 60, 1);
return 0;
#else #else
while (is_open_window(window)) while (is_open_window(window))
main_loop(); main_loop();
#endif #endif
mlog("[MAIN LOOP] Terminando...\n"); mlog("[MAIN LOOP] Terminando...\n");
mlog("[MESH] Destruyendo...\n");
destroy_mesh(m_axis);
mlog("[MESH] Destruyendo...\n"); mlog("[MESH] Destruyendo...\n");
destroy_mesh(m_surface); destroy_mesh(m_surface);
mlog("[SHADER] Destruyendo...\n"); mlog("[SHADER] Destruyendo...\n");
destroy_shader(shader_plain); destroy_shader(shader_plain);
mlog("[SHADER] Destruyendo...\n"); mlog("[SHADER] Destruyendo...\n");
destroy_shader(shader); destroy_shader(shader);
mlog("[TEXTURE] Destruyendo...\n");
destroy_texture(texture);
mlog("[WINDOW] Destruyendo...\n"); mlog("[WINDOW] Destruyendo...\n");
close_window(window); close_window(window);
return 0; return 0;
mlog("[MESH] Destruyendo...\n"); error_context:
destroy_mesh(m_axis);
error_mesh_axis:
mlog("[MESH] Destruyendo...\n"); mlog("[MESH] Destruyendo...\n");
destroy_mesh(m_surface); destroy_mesh(m_surface);
error_mesh_surface: error_mesh_surface:
@@ -184,9 +183,6 @@ error_shader_plain:
mlog("[SHADER] Destruyendo...\n"); mlog("[SHADER] Destruyendo...\n");
destroy_shader(shader); destroy_shader(shader);
error_shader: error_shader:
mlog("[TEXTURE] Destruyendo...\n");
destroy_texture(texture);
error_context:
mlog("[WINDOW] Destruyendo...\n"); mlog("[WINDOW] Destruyendo...\n");
close_window(window); close_window(window);
error_window: error_window:

View File

@@ -4,16 +4,15 @@
error of the shaders. error of the shaders.
*/ */
/* #define DEBUG */ #define DEBUG
/* #define GLAD */
typedef const void * window_t; typedef const void *window_t;
typedef unsigned int id_t; typedef unsigned int id_t;
typedef void * mesh_t; typedef void *mesh_t;
typedef float * quat_t; typedef float *quat_t;
typedef float * mat4_t; typedef float *mat4_t;
/* /*
This struct represent the proyection, where: This struct represent the proyection, where:
mesh: data of surface. mesh: data of surface.
m: the dimention of the surface. m: the dimention of the surface.
@@ -29,14 +28,29 @@ struct projection
unsigned char m, x, y, z, w; unsigned char m, x, y, z, w;
}; };
/* /*
this structure has all the information to generate
a mesh, where:
data: the buffer with the vertex coords
norm: the buffer with the norm coords
vertex: the number of vertex
dim: the dimentions of the surface
*/
struct surface
{
float *data, *norm;
unsigned long vertex;
unsigned char dim;
};
/*
Init window: Init window:
w: default width; w: default width;
h: default height; h: default height;
name: Name of the window. name: Name of the window.
*/ */
window_t init_window(unsigned int w, unsigned int h, const char * name); window_t init_window(unsigned int w, unsigned int h, const char *name);
void use_window(window_t window); void use_window(window_t window);
@@ -44,20 +58,22 @@ int is_open_window(window_t window);
void close_window(window_t window); void close_window(window_t window);
/* /*
Create mesh: Create mesh:
d: array of floats with the vertex data. d: array of floats with the vertex data.
n: array of floats with the normal data. n: array of floats with the normal data.
m: Dimention of mesh m: Dimention of mesh
*/ */
mesh_t create_mesh( float * d, float * n, unsigned char m ); mesh_t create_mesh(struct surface);
void set_projection_mesh( struct projection ); void set_projection_mesh(struct projection);
void destroy_mesh(mesh_t p); void destroy_mesh(mesh_t p);
void draw_mesh(mesh_t p); void draw_mesh(id_t, mesh_t p);
void draw_mesh_lines(id_t, mesh_t p);
/* /*
Set background color: Set background color:
@@ -70,7 +86,7 @@ void set_clean_color_context(unsigned char r, unsigned char g, unsigned char b);
void clean_context(void); void clean_context(void);
int init_context( void ); int init_context(void);
void destroy_shader(id_t shader); void destroy_shader(id_t shader);
@@ -80,7 +96,8 @@ void use_shader(id_t shader);
enum enum
{ {
VERTEX, FRAGMENT VERTEX,
FRAGMENT
}; };
/* /*
@@ -89,7 +106,8 @@ enum
type: VERTEX or FRAGMENT type: VERTEX or FRAGMENT
*/ */
unsigned char load_program_to_shader(id_t shader, const char * src, unsigned int type); unsigned char load_program_to_shader(
id_t shader, const char *src, unsigned int type);
/* /*
load float to shader: load float to shader:
@@ -97,7 +115,23 @@ unsigned char load_program_to_shader(id_t shader, const char * src, unsigned int
f: float to load f: float to load
*/ */
void load_float_to_shader(id_t shader, char * var, float f); void load_float_to_shader(id_t shader, char *var, float f);
/*
load unsigned int to shader:
var: name of glsl variable.
u: unsigned int to load
*/
void load_uint_to_shader(id_t shader, char *var, unsigned int u);
/*
load float[4] to shader:
var: name of glsl variable.
f: float[4] to load
*/
void load_float4_to_shader(id_t shader, char *var, float f[4]);
/* /*
load matrix 4 to shader: load matrix 4 to shader:
@@ -105,32 +139,28 @@ void load_float_to_shader(id_t shader, char * var, float f);
m: Matrix to load m: Matrix to load
*/ */
void load_mat4_to_shader(id_t shader, char * var, mat4_t m); void load_mat4_to_shader(id_t shader, char *var, mat4_t m);
/* /*
Generate and load fix matrix, this matrix Generate and load fix matrix, this matrix
has the information of the perspective and has the information of the perspective and
camera information. camera information.
ratio: default ratio of window. ratio: default ratio of window.
*/ */
void load_fix_matrix(id_t shader, float ratio); void fix_matrix_load(id_t shader, float ratio);
/*
Generate and load model matrix, it also sets the color
to draw.
i: From {0,1,2} select one of 3 ortogonal rotations,
One for each axis.
c: Color index of the pallete.
*/
void load_mdl_matrix(id_t shader, unsigned char i, unsigned char c);
/* /*
Generate and load rotation matrix. Generate and load rotation matrix.
q: quaterinon describing the rotation. q: quaterinon describing the rotation.
*/ */
void load_rot_matrix(id_t shader, quat_t q); void rot_matrix_load(id_t shader, quat_t q);
/*
*/
void color_load(id_t shader, unsigned char color[4]);
id_t config_texture(unsigned short type); id_t config_texture(unsigned short type);
@@ -143,6 +173,12 @@ void destroy_texture(id_t texture);
colors: array of color values (rgba in hex ). colors: array of color values (rgba in hex ).
n: number of color on colors. n: number of color on colors.
*/ */
id_t create_palette_texture(const unsigned char colors[][4], unsigned char n ); id_t create_palette_texture(const unsigned char colors[][4], unsigned char n);
quat_t poll_input(window_t window); quat_t poll_input(window_t window);
#ifdef EMSCRIPTEN
#ifdef GLAD
#error undefine GLAD on src/main.h please
#endif
#endif

View File

@@ -1,50 +0,0 @@
#include "main.h"
#include <cglm/cam.h>
#include <cglm/mat4.h>
#include <cglm/quat.h>
mat4 ortho[] = {
{
{1, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
},
{
{0, 1, 0, 0},
{-1, 0, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
},
{
{0, 0, 1, 0},
{0, 1, 0, 0},
{-1, 0, 0, 0},
{0, 0, 0, 1},
},
};
void load_fix_matrix(id_t shader, float ratio)
{
mat4 m, n;
const int d = 7;
glm_lookat((vec3){0, 0, -d}, (vec3){0, 0, 0}, (vec3){0, 1, 0}, m);
glm_perspective(CGLM_PI / 4, ratio, d - 3, d + 3, n);
glm_mat4_mul(n, m, m);
load_mat4_to_shader(shader, "fix", (mat4_t)m);
}
void load_mdl_matrix(id_t shader, unsigned char i, unsigned char c)
{
load_float_to_shader(shader, "idx", c);
load_mat4_to_shader(shader, "mdl", (mat4_t)ortho[i]);
}
void load_rot_matrix(id_t shader, quat_t q)
{
mat4 m;
glm_quat_mat4(q, m);
load_mat4_to_shader(shader, "rot", (mat4_t)m);
}

View File

@@ -1,9 +1,11 @@
#include "main.h" #include "main.h"
#ifdef GLAD
#include <glad.h> #ifdef EMSCRIPTEN
#include <GL/gl.h>
#else #else
#include <GL/glew.h> #include <glad.h>
#endif #endif
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -47,49 +49,34 @@ void set_projection_mesh(struct projection projection)
This trick can be done with glVertexAttribPointer. This trick can be done with glVertexAttribPointer.
*/ */
mesh_t create_mesh(float *d, float *n, unsigned char m) mesh_t create_mesh(struct surface surface)
{ {
unsigned char i; unsigned char i;
struct obj *p; struct obj *p;
p = malloc(sizeof(struct obj)); p = malloc(sizeof(struct obj));
p->vertex = (*d) / m; p->vertex = surface.vertex;
glGenVertexArrays(1, &p->vao); glGenVertexArrays(1, &p->vao);
glBindVertexArray(p->vao); glBindVertexArray(p->vao);
glGenBuffers(1, &p->d_vbo); glGenBuffers(1, &p->d_vbo);
glBindBuffer(GL_ARRAY_BUFFER, p->d_vbo); glBindBuffer(GL_ARRAY_BUFFER, p->d_vbo);
glBufferData( glBufferData(GL_ARRAY_BUFFER, p->vertex * surface.dim * sizeof(float),
GL_ARRAY_BUFFER, p->vertex * m * sizeof(float), d + 1, GL_STATIC_DRAW); surface.data, GL_STATIC_DRAW);
if (n) if (surface.norm)
{ {
glGenBuffers(1, &p->n_vbo); glGenBuffers(1, &p->n_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p->n_vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p->n_vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, p->vertex * m * sizeof(float), glBufferData(GL_ELEMENT_ARRAY_BUFFER,
n + 1, GL_STATIC_DRAW); p->vertex * surface.dim * sizeof(float), surface.norm,
GL_STATIC_DRAW);
} }
for (i = 0; i < 4; ++i) for (i = 0; i < 8; ++i)
{
glEnableVertexAttribArray(i); glEnableVertexAttribArray(i);
glEnableVertexAttribArray(i + 4);
}
{
struct projection projection = {
.x = 0,
.y = 1,
.z = 2,
.w = 3,
};
projection.m = m;
projection.mesh = p;
set_projection_mesh(projection);
}
return p; return p;
} }
@@ -104,18 +91,27 @@ void destroy_mesh(mesh_t p)
free(p); free(p);
} }
void draw_mesh(mesh_t p) void draw_mesh(id_t shader, mesh_t p)
{ {
struct obj *obj = p; struct obj *obj = p;
glUseProgram(shader);
glBindVertexArray(obj->vao); glBindVertexArray(obj->vao);
#ifdef DEBUG #ifndef EMSCRIPTEN
{ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
int i; #endif
for (i = 0; i < obj->vertex; i += 3)
glDrawArrays(GL_LINE_LOOP, i, 3);
}
#else
glDrawArrays(GL_TRIANGLES, 0, obj->vertex); glDrawArrays(GL_TRIANGLES, 0, obj->vertex);
}
void draw_mesh_lines(id_t shader, mesh_t p)
{
struct obj *obj = p;
glUseProgram(shader);
glBindVertexArray(obj->vao);
#ifndef EMSCRIPTEN
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDrawArrays(GL_TRIANGLES, 0, obj->vertex);
#else
glDrawArrays(GL_LINES, 0, obj->vertex);
#endif #endif
} }

View File

@@ -1,20 +1,20 @@
#include "main.h" #include "main.h"
#ifdef GLAD #ifndef EMSCRIPTEN
#include <glad.h> #include <glad.h>
#else #else
#include <GL/glew.h> #include <GL/gl.h>
#endif #endif
#ifdef DEBUG #ifdef DEBUG
#include <stdio.h> #include <stdio.h>
#endif #endif
void destroy_shader(unsigned int shader) { return glDeleteProgram(shader); } void destroy_shader(unsigned int shader) { glDeleteProgram(shader); }
unsigned int create_shader(void) { return glCreateProgram(); } unsigned int create_shader(void) { return glCreateProgram(); }
void use_shader(unsigned int program) { return glUseProgram(program); } void use_shader(unsigned int program) { glUseProgram(program); }
unsigned char load_program_to_shader( unsigned char load_program_to_shader(
unsigned int program, const char *src, unsigned int i) unsigned int program, const char *src, unsigned int i)
@@ -59,3 +59,10 @@ void load_mat4_to_shader(unsigned int program, char *var, float *mat)
glUseProgram(program); glUseProgram(program);
glUniformMatrix4fv(glGetUniformLocation(program, var), 1, 0, mat); glUniformMatrix4fv(glGetUniformLocation(program, var), 1, 0, mat);
} }
void load_float4_to_shader(unsigned int program, char *var, float float4[4])
{
glUseProgram(program);
glUniform4f(glGetUniformLocation(program, var), float4[0], float4[1],
float4[2], float4[3]);
}

View File

@@ -1,6 +1,9 @@
#include <complex.h> #include <complex.h>
#include <math.h> #include <math.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#define TEST
#define CGLM_ALL_UNALIGNED #define CGLM_ALL_UNALIGNED
#include <cglm/vec3.h> #include <cglm/vec3.h>
@@ -11,16 +14,87 @@
#endif #endif
#ifndef CMPLX #ifndef CMPLX
#define CMPLX(a,b) (a+I*b) #define CMPLX(a, b) (a + I * b)
#endif #endif
void riemman(float *d_surface, int * coords, int grid_size) #ifdef TEST
#include <assert.h>
#endif
#include <stdio.h>
typedef void (*function_t)(float *, int *, unsigned char *);
struct parm
{
unsigned char *grid;
unsigned char m, n;
function_t f;
} parm;
// Función para escribir el archivo .klein
void write_klein_file(const char *filename, unsigned char dim, unsigned long vertex, float *vertices, float *normals)
{
FILE *file = fopen(filename, "wb");
if (!file)
{
perror("Error al abrir el archivo");
exit(EXIT_FAILURE);
}
// Escribir encabezado
fwrite("KLEIN", 1, 5, file); // Los primeros 5 bytes son "KLEIN"
fputc(0, file); // Byte vacío
fwrite(&dim, 1, 1, file); // Dimensión de la superficie
fwrite(&vertex, sizeof(unsigned long), 1, file); // Número de vértices (8 bytes)
// Escribir dimensiones de la cuadrícula
fwrite(parm.grid, sizeof(unsigned char), dim, file);
// Debug info
for (int i = 0; i < dim; i++) {
printf("Grid[%d]: %u\n", i, parm.grid[i]);
}
// Escribir vértices (en float)
fwrite(vertices, sizeof(float), vertex * dim, file);
// Debug info
for (unsigned long i = 0; i < vertex * dim; i++) {
printf("Vertices[%lu]: %f\n", i, vertices[i]);
}
// Escribir normales (en float)
fwrite(normals, sizeof(float), vertex * dim, file);
// Debug info
for (unsigned long i = 0; i < vertex * dim; i++) {
printf("Normals[%lu]: %f\n", i, normals[i]);
}
fclose(file);
printf("Archivo %s escrito correctamente.\n", filename);
}
int factorial(int n)
{
if (n == 1)
return 1;
return n * factorial(n - 1);
}
int faces(int n)
{
if (n == 2)
return 1;
return (1 << (n - 3)) * factorial(n) / factorial(n - 2);
}
void riemman(float *d_surface, int *coords, unsigned char *grid)
{ {
complex double eq; complex double eq;
float u = 2 * ((float)coords[0] / grid_size) - 1; float u = 2 * ((float)coords[0] / grid[0]) - 1;
float v = 2 * ((float)coords[1] / grid_size) - 1; float v = 2 * ((float)coords[1] / grid[1]) - 1;
eq = csqrt(CMPLX(u,v)); eq = csqrt(CMPLX(u, v));
d_surface[0] = u; d_surface[0] = u;
d_surface[1] = v; d_surface[1] = v;
@@ -28,40 +102,42 @@ void riemman(float *d_surface, int * coords, int grid_size)
d_surface[3] = cimag(eq); d_surface[3] = cimag(eq);
} }
void cube(float *d_surface, int *coord, unsigned char *grid)
void cube( float *d_surface, int * coord, int grid_size )
{ {
unsigned char i; int i;
for(int i=0; i<4; i++ ) for (i = 0; i < parm.m; i++)
d_surface[i]=(float)coord[i]/grid_size; d_surface[i] = (2 * (float)coord[i] / grid[i]) - 1;
if (parm.m == 2)
d_surface[2] = 0;
} }
void mobius(float *d_surface, int * coord, int grid_size) void mobius(float *d_surface, int *coord, unsigned char *grid)
{ {
const float width = 0.5; const float width = 0.5;
float u = (2 * M_PI) * ((float)coord[0] / grid_size); float u = (2 * M_PI) * ((float)coord[0] / grid[0]);
float v = (2 * width) * ((float)coord[1] / grid_size) - width; float v = (2 * width) * ((float)coord[1] / grid[1]) - width;
d_surface[0] = cos(u) + v * cos(u / 2) * cos(u); d_surface[0] = cos(u) + v * cos(u / 2) * cos(u);
d_surface[1] = sin(u) + v * cos(u / 2) * sin(u); d_surface[1] = sin(u) + v * cos(u / 2) * sin(u);
d_surface[2] = v * sin(u / 2); d_surface[2] = v * sin(u / 2);
} }
void torus(float *d_surface, int * coord, int grid_size) void torus(float *d_surface, int *coord, unsigned char *grid)
{ {
float u = (2 * M_PI) * ((float)coord[0] / grid_size); float u = (2 * M_PI) * ((float)coord[0] / grid[0]);
float v = (2 * M_PI) * ((float)coord[1] / grid_size); float v = (2 * M_PI) * ((float)coord[1] / grid[1]);
d_surface[0] = (1 + 0.5 * cos(v)) * cos(u); d_surface[0] = (1 + 0.5 * cos(v)) * cos(u);
d_surface[1] = (1 + 0.5 * cos(v)) * sin(u); d_surface[1] = (1 + 0.5 * cos(v)) * sin(u);
d_surface[2] = 0.5 * sin(v); d_surface[2] = 0.5 * sin(v);
} }
void klein(float *d_surface, int * coord, int grid_size) void klein(float *d_surface, int *coord, unsigned char *grid)
{ {
float u = (2 * M_PI) * ((float)coord[0] / grid_size); float u = (2 * M_PI) * ((float)coord[0] / grid[0]);
float v = (2 * M_PI) * ((float)coord[1]/ grid_size); float v = (2 * M_PI) * ((float)coord[1] / grid[1]);
d_surface[0] = (0.5 * cos(v) + 0.5) * cos(u); d_surface[0] = (0.5 * cos(v) + 0.5) * cos(u);
d_surface[1] = (0.5 * cos(v) + 0.5) * sin(u); d_surface[1] = (0.5 * cos(v) + 0.5) * sin(u);
@@ -69,166 +145,256 @@ void klein(float *d_surface, int * coord, int grid_size)
d_surface[3] = sin(v) * sin(u / 2); d_surface[3] = sin(v) * sin(u / 2);
} }
typedef void (*function_t)(float *, int *, int); float *generate_data_surface(unsigned char *dim, unsigned long *vertex)
float *generate_data_surface(int grid_size, unsigned char *s)
{ {
unsigned int i, j, k, o, p, l, n, m; unsigned int i, j, k, o, p, n;
long size, q=0; unsigned long size, q = 0;
function_t f;
float *d_surface; float *d_surface;
int *cara;
const int dim =2; parm.f = cube;
int cara[dim]; parm.m = 4;
char bits[dim+1]; parm.n = 4;
bits[dim]=0; parm.grid = (char[]){16, 8, 4, 2, 1};
f =klein ; #ifdef TEST
*s = 4; assert(faces(2) == 1);
assert(faces(3) == 6);
assert(faces(4) == 24);
#endif
size = grid_size * grid_size * 6 * (*s) * 24; *dim = parm.n;
d_surface = malloc((size + 1) * sizeof(float)); *vertex = 0;
d_surface[0] = size;
{
for(o = 0; o < dim; o ++) unsigned char test = 0;
{ for (o = 0; o < parm.m; o++)
{
for (p = 0; p < o; p++)
{
test += 1;
*vertex += parm.grid[p] * parm.grid[o] * 6 * faces(parm.n);
}
}
*vertex /= test;
}
cara = malloc(parm.m * sizeof(int));
size = (*dim) * (*vertex);
d_surface = malloc(size * sizeof(float));
for (o = 0; o < parm.m; o++)
{
for (p = 0; p < o; p++) for (p = 0; p < o; p++)
{ {
for (k = 0; k < (1 << (dim-2)); k++) for (k = 0; k < (1 << (parm.m - 2)); k++)
{ {
unsigned char skip=0; unsigned char skip = 0;
for(n = 0; n < dim-2; n++) for (n = 0; n < parm.m; n++)
{ {
if( n==(o-1) || n==p ) if (n == o || n == p)
skip++; skip++;
cara[n+skip] = (k & (1<<n))?grid_size:0; cara[n] = (k & (1 << (n - skip))) ? parm.grid[n] : 0;
} }
for(i = 0; i < grid_size; i++) for (i = 0; i < parm.grid[p]; i++)
{ {
for (j = 0; j < grid_size; j++) for (j = 0; j < parm.grid[o]; j++)
{ {
cara[o] = i; cara[p] = i;
cara[p] = j; cara[o] = j;
f(&d_surface[q + 1], cara, grid_size); parm.f(&d_surface[q], cara, parm.grid);
q += *s; q += parm.n;
cara[o] = i + 1; cara[p] = i + 1;
cara[p] = j; cara[o] = j;
f(&d_surface[q + 1], cara, grid_size); parm.f(&d_surface[q], cara, parm.grid);
q += *s; q += parm.n;
cara[o] = i + 1; cara[p] = i + 1;
cara [p] = j + 1; cara[o] = j + 1;
f(&d_surface[q + 1], cara, grid_size); parm.f(&d_surface[q], cara, parm.grid);
q += *s; q += parm.n;
cara[o] = i; cara[p] = i;
cara [p] = j; cara[o] = j;
f(&d_surface[q + 1], cara, grid_size); parm.f(&d_surface[q], cara, parm.grid);
q += *s; q += parm.n;
cara[o] = i; cara[p] = i;
cara [p] = j + 1; cara[o] = j + 1;
f(&d_surface[q + 1], cara, grid_size); parm.f(&d_surface[q], cara, parm.grid);
q += *s; q += parm.n;
cara[o] = i + 1; cara[p] = i + 1;
cara [p] = j + 1; cara[o] = j + 1;
f(&d_surface[q + 1], cara, grid_size); parm.f(&d_surface[q], cara, parm.grid);
q += *s; q += parm.n;
} }
} }
} }
} }
} }
#ifdef TEST
assert(q == size);
#endif
return d_surface; return d_surface;
} }
static void __calculate_normal( static void __calculate_normal(
float *p1, float *p2, float *p3, float *normal, unsigned char n) float *p1, float *p2, float *p3, float *normal, unsigned char n)
{ {
unsigned char i;
float alpha; float alpha;
vec4 v1, v2, v3; float *v1, *v2, *v3;
vec4 u1, u2, u3; float *u1, *u2, *u3;
switch (n) v1 = malloc(n * sizeof(float));
v2 = malloc(n * sizeof(float));
v3 = malloc(n * sizeof(float));
u1 = malloc(n * sizeof(float));
u2 = malloc(n * sizeof(float));
u3 = malloc(n * sizeof(float));
/*
Calculate a normal vector of a plain using Gram-Schmidt process
*/
{ {
case 3: for (i = 0; i < n; ++i)
glm_vec3_sub(p2, p1, v1);
glm_vec3_sub(p3, p1, v2);
glm_vec3_cross(v1, v2, normal);
glm_vec3_normalize(normal);
return;
case 4:
/*
In Grant-Shmidth we need 3 linearly independian vector that forms a
basis, so we can have a ortonormal version of that basis, since, we
must have v1 = p3 - p1 v2 = p2 - p1 Then v3 = p1, will most certantly
be linerly independiant to v1 and v2.
*/
glm_vec4_sub(p2, p1, v1);
glm_vec4_sub(p3, p1, v2);
glm_vec4_copy(p1, v3);
/* Setup U1 */
{ {
glm_vec4_copy(v1, u1); v1[i] = p2[i] - p1[i];
v2[i] = p3[i] - p1[i];
v3[i] = p1[i];
} }
/* Setup U2 */ for (i = 0; i < n; ++i)
{ {
vec4 proj; u1[i] = v1[i];
alpha = glm_vec4_dot(v2, u1) / glm_vec4_dot(u1, u1);
glm_vec4_scale(u1, alpha, proj);
glm_vec4_sub(v2, proj, u2);
} }
/* Setup U3 */
{ {
vec4 proj1, proj2; float proj[n];
float dot_v2_u1 = 0.0f, dot_u1_u1 = 0.0f;
for (i = 0; i < n; ++i)
{
dot_v2_u1 += v2[i] * u1[i];
dot_u1_u1 += u1[i] * u1[i];
}
alpha = dot_v2_u1 / dot_u1_u1;
alpha = glm_vec4_dot(v3, u1) / glm_vec4_dot(u1, u1); for (i = 0; i < n; ++i)
glm_vec4_scale(u1, alpha, proj1); {
proj[i] = u1[i] * alpha;
alpha = glm_vec4_dot(v3, u2) / glm_vec4_dot(u2, u2); u2[i] = v2[i] - proj[i];
glm_vec4_scale(u2, alpha, proj2); }
glm_vec4_sub(v3, proj1, u3);
glm_vec4_sub(u3, proj2, u3);
} }
glm_vec4_copy(u3, normal); {
glm_vec4_normalize(normal); float proj1[n], proj2[n];
float dot_v3_u1 = 0.0f, dot_u1_u1 = 0.0f;
float dot_v3_u2 = 0.0f, dot_u2_u2 = 0.0f;
for (i = 0; i < n; ++i)
{
dot_v3_u1 += v3[i] * u1[i];
dot_u1_u1 += u1[i] * u1[i];
}
for (i = 0; i < n; ++i)
{
proj1[i] = u1[i] * (dot_v3_u1 / dot_u1_u1);
}
for (i = 0; i < n; ++i)
{
dot_v3_u2 += v3[i] * u2[i];
dot_u2_u2 += u2[i] * u2[i];
}
for (i = 0; i < n; ++i)
{
proj2[i] = u2[i] * (dot_v3_u2 / dot_u2_u2);
u3[i] = v3[i] - proj1[i] - proj2[i];
}
}
float magnitude = 0.0f;
for (i = 0; i < n; ++i)
{
magnitude += u3[i] * u3[i];
}
magnitude = sqrtf(magnitude);
for (i = 0; i < n; ++i)
{
normal[i] = u3[i] / magnitude;
}
free(v1);
free(v2);
free(v3);
free(u1);
free(u2);
free(u3);
return; return;
} }
} }
float *generate_normals_surface(float *d, unsigned char m) float *generate_normals_surface(float *d, unsigned char m, unsigned long vertex)
{ {
float *n; float *n;
n = malloc((*d + 1) * sizeof(float)); float *norm_vec;
*n = *d;
n = malloc((m * vertex) * sizeof(float));
norm_vec = malloc(m * sizeof(float));
for (int i = 0; i < *d; i += 3 * m) for (int i = 0; i < *d; i += 3 * m)
{ {
vec4 norm_vec; __calculate_normal(d + i, d + i + m, d + i + 2 * m, norm_vec, m);
glm_vec3_copy(norm_vec, n + i);
__calculate_normal( glm_vec3_copy(norm_vec, n + i + m);
(d + 1) + i, (d + 1) + i + m, (d + 1) + i + 2 * m, norm_vec, m); glm_vec3_copy(norm_vec, n + i + 2 * m);
glm_vec3_copy(norm_vec, (n + 1) + i);
glm_vec3_copy(norm_vec, (n + 1) + i + m);
glm_vec3_copy(norm_vec, (n + 1) + i + 2 * m);
} }
free(norm_vec);
return n; return n;
} }
int main()
{
unsigned char dim;
unsigned long vertex;
float *vertices, *normals;
// Generar datos de la superficie
vertices = generate_data_surface(&dim, &vertex);
// Verificar datos generados
if (vertices == NULL) {
printf("Error: vertices no generados.\n");
return 1;
}
printf("Dim: %u, Vertex: %lu\n", dim, vertex);
// Generar normales
normals = generate_normals_surface(vertices, dim, vertex);
// Verificar normales generadas
if (normals == NULL) {
printf("Error: normales no generadas.\n");
free(vertices);
return 1;
}
// Escribir el archivo
printf("Escribiendo archivo .klein\n");
write_klein_file("kingtin.klein", dim, vertex, vertices, normals);
free(vertices);
free(normals);
return 0;
}

View File

@@ -1,38 +0,0 @@
#include "main.h"
#ifdef GLAD
#include <glad.h>
#else
#include <GL/glew.h>
#endif
#define TYPE GL_TEXTURE_2D_ARRAY
static id_t __config_texture(unsigned short type)
{
id_t texture;
glGenTextures(1, &texture);
glBindTexture(TYPE, texture);
{
glTexParameteri(TYPE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(TYPE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
return texture;
}
void use_texture(id_t texture) { return glBindTexture(TYPE, texture); }
void destroy_texture(unsigned int texture)
{
return glDeleteTextures(1, &texture);
}
id_t create_palette_texture(const unsigned char colors[][4], unsigned char n)
{
id_t texture = __config_texture(TYPE);
glTexImage3D(
TYPE, 0, GL_RGBA, 1, 1, n, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors);
return texture;
}