73 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
e95ef9d127 Fix: encoding for n-cube faces 2024-11-27 17:21:59 -06:00
PedroEdiaz
4840b0c8ba Merge branch 'main' into experimental 2024-11-27 10:58:58 -06:00
PedroEdiaz
8d1f54604e Optimize and work with dim=2 2024-11-27 00:20:51 -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
alan
805ff18e21 expandiendo a Rn avance 2024-11-26 22:21:56 -06:00
PedroEdiaz
e4a4a8c603 Add riemman surfaces family 2024-11-21 18:57:13 -06:00
PedroEdiaz
8811c4e0b7 Prepare for Rn -> Rm surfaces 2024-11-20 11:38:23 -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
PedroEdiaz
61b014a803 Port to web for free 2024-11-19 21:54:22 -06:00
roberto.mc
793c11757d aiura pedro 2024-11-18 23:14:54 -06:00
PedroEdiaz
c4016d239a Merge: roberto -> main 2024-11-16 13:12:16 -06:00
roberto.mc
4bc45f4eea aiuda con el blinn-phong 2024-11-15 20:20:33 -06:00
PedroEdiaz
6dbc758cc3 xd 2024-11-14 21:18:13 -06:00
PedroEdiaz
569a8d0f42 Fix: specular
Muy bien!!, nada mas habian 2 errores por mi parte,
'Normal' no estaba normalizado, lo que afectaba las potencias con 'pow'.
Ademas habia un error con los buffers del shader lo que afectaba toda la iluminacion.
Sin embargo lo hiciste muy bien, solo que te falto definir viewPos.
2024-11-14 20:11:30 -06:00
roberto.mc
52ef897137 Specular ya deberia furula 2024-11-14 16:47:14 -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
PedroEdiaz
88495c1068 Setup Manigraph for glad 2024-10-30 22:42:13 -06:00
PedroEdiaz
303f16d155 Separate Wayland and x11 2024-10-29 20:02:36 -06:00
PedroEdiaz
8c565ffd25 Fix #17, Add nuklear, Unified linux compilation 2024-10-27 16:09:29 -06:00
PedroEdiaz
3fa4eed366 Fix: Palette 2024-10-24 12:21:14 -06:00
PedroEdiaz
3e27f0d165 Add .clang-format and .gitignore 2024-10-24 11:21:07 -06:00
PedroEdiaz
2a5a101080 Change projection w/keyboard 2024-10-22 23:07:30 -06:00
PedroEdiaz
6727c5fa9a Clean code for MVP Release 2024-10-22 19:54:55 -06:00
PedroEdiaz
7787daa2da Merge: roberto -> main 2024-10-22 19:26:10 -06:00
PedroEdiaz
74f4f7c7eb Finall G-S
Observaciones:
	* Agregé CGLM_ALL_UNALIGNED para evitar el Segfault.
	* Cambie la estructura de G-S a una más ordenada.
	* Cambié el nombre de las variables a unas más intuitivas.
	* Cambié lado3, a uno que garantiza G-S.

En lo general muy bien!!, Felicidades.
2024-10-22 18:58:15 -06:00
Your Name
c513320714 xd, la restanostaba guena 2024-10-22 12:53:44 -06:00
Your Name
96df57fc90 Ya deberia funcionar n==4, pero por alguna razon no corre con make run, iura 2024-10-22 12:18:38 -06:00
PedroEdiaz
b50fbf9d2d rm: glfw.dll manigraph.exe 2024-10-22 11:46:30 -06:00
PedroEdiaz
6eedd09e2c Merge: crisel -> main 2024-10-22 11:45:51 -06:00
PedroEdiaz
17e1cf8804 Document code, and clean up 2024-10-21 16:50:49 -06:00
PedroEdiaz
fe3b99d480 Setup for test on R4 2024-10-18 20:26:53 -06:00
PedroEdiaz
b164d15927 Fix: compile 2024-10-18 19:14:51 -06:00
Your Name
e79c4abe83 la funcion calc_normal ahora toma vectores R4 via alg. G-S 2024-10-18 18:35:21 -06:00
PedroEdiaz
6e54aa9fea Merge: alan -> main 2024-10-18 17:06:19 -06:00
PedroEdiaz
0552616bf9 Wait for Multidimentional struct 2024-10-18 14:01:25 -06:00
PedroEdiaz
7c8cfcbfce Combine Illumination w/ Mouse rotation 2024-10-18 11:54:12 -06:00
PedroEdiaz
7c1f691b46 Merge: roberto -> main 2024-10-17 22:30:55 -06:00
PedroEdiaz
03d446cdaf Correct faces of axis 2024-10-17 22:28:22 -06:00
PedroEdiaz
9dabea34d2 Final: Illumination 2024-10-17 22:24:54 -06:00
PedroEdiaz
5fc19db1a9 Eliminar los .o 2024-10-17 19:44:44 -06:00
PedroEdiaz
7c76e3901a Fix illumination 2024-10-17 19:42:16 -06:00
Your Name
fda999bfb1 PPP 2024-10-17 17:58:55 -06:00
PedroEdiaz
3137c23479 Fix: not linking of math lib 2024-10-17 13:03:35 -06:00
PedroEdiaz
6218c5d576 Fix: Wayland compilation 2024-10-17 12:56:33 -06:00
PedroEdiaz
502ff0daeb Corrección 2024-10-17 11:48:14 -06:00
Your Name
c2adfc2bda aiuda 2024-10-17 11:30:36 -06:00
Your Name
29ab40e33d pinshegitfeo 2024-10-16 23:41:32 -06:00
25 changed files with 6437 additions and 396 deletions

19
.clang-format Normal file
View File

@@ -0,0 +1,19 @@
---
PointerAlignment: Right
AllowShortBlocksOnASingleLine: Never
UseTab: Always
IndentWidth: 4
TabWidth: 4
ColumnLimit: 80
AlignAfterOpenBracket: false
AlignOperands: AlignAfterOperator
AlwaysBreakBeforeMultilineStrings: true
BreakBeforeBraces: Allman
BreakStringLiterals: true
IndentCaseLabels: false
IndentGotoLabels: false
InsertBraces: false
...

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
manigraph
**.o
**.so
**.exe
**.dll

3
.gitmodules vendored
View File

@@ -4,3 +4,6 @@
[submodule "ext/glfw"]
path = ext/glfw
url = https://github.com/glfw/glfw
[submodule "ext/nuklear"]
path = ext/nuklear
url = https://github.com/Immediate-Mode-UI/Nuklear

View File

@@ -1,64 +1,78 @@
BIN = manigraph
OBJ = \
ext/glad/glad.o \
src/surface.o \
src/context.o \
src/texture.o \
src/window.o \
src/matrix.o \
src/load.o \
src/shader.o \
src/input.o \
src/mesh.o \
src/alan.o \
src/main.o
CFLAGS = \
-I./ext/cglm/include \
-I./ext/glfw/include \
-Wall -Wno-unused-function -std=c99 \
-I./ext/glad \
-Wall -Wno-unused-function -std=c99 -D_GNU_SOURCE \
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
help:
@echo "Para compilar el proyecto a tu sistema operativo"
@echo "porfavor usa uno de los siguientes comandos:"
@echo "Usage:"
@echo " $(MAKE) windows"
@echo " $(MAKE) linux-x11"
@echo " $(MAKE) linux-wayland"
@echo " $(MAKE) cocoa"
@echo "Para limpiar los archivos compilados se puede usar"
@echo " $(MAKE) CC=emcc wasm"
@echo "Clean"
@echo " $(MAKE) clean"
@echo "Para ejecturar el programa sin instalarlos se puede usar:"
@echo " $(MAKE) run-linux"
# WINDOWS
windows: $(OBJ) glfw.dll
$(CC) $(CFLAGS) $(OBJ) -o $(BIN) -L. -lglfw -lopengl32 -lglew32
src/main.o: src/data/axis.h src/data/shaders.h
windows: $(OBJ)
cd ext; $(MAKE) -f glfw.mk windows; cd -
$(CC) $(CFLAGS) $(OBJ) -o $(BIN) -L. -lglfw -lopengl32
glfw.dll:
$(CC) -fPIC -shared -D_GLFW_WIN32 -D_GLFW_BUILD_DLL ./ext/glfw/src/*.c -o $@ -lgdi32
# LINUX
linux-x11: $(OBJ)
$(MAKE) BKN=_GLFW_X11 libglfw.so
$(CC) -o $(BIN) $(OBJ) -L. -lGLEW -lGL -lglfw
linux-wayland: $(OBJ)
$(MAKE) BKN=_GLFW_WAYLAND libglfw.so
$(CC) -o $(BIN) $(OBJ) -L. -lGLEW -lGL -lglfw
cd ext; $(MAKE) -f glfw.mk linux-wayland; cd -
$(CC) -o $(BIN) $(OBJ) ext/libglfw.a -lGL -lm
run-linux:
LD_LIBRARY_PATH=. ./$(BIN)
linux-x11: $(OBJ)
cd ext; $(MAKE) -f glfw.mk linux-x11; cd -
$(CC) -o $(BIN) $(OBJ) ext/libglfw.a -lGL -lm
# COCOA
cocoa: $(OBJ)
$(MAKE) BKN=_GLFW_COCOA libglfw.so
$(CC) -framework OpenGL -o $(BIN) $(OBJ) -L. -lGLEW -lGL -lglfw
cd ext; $(MAKE) -f glfw.mk cocoa; cd -
$(CC) -framework OpenGL -o $(BIN) $(OBJ) ext/glfw.a -lGL -lglfw
wasm: $(OBJ)
$(CC) -sUSE_WEBGL2=1 -sUSE_GLFW=3 -o $(BIN).html $(OBJ)
chmod -x $(BIN).wasm
libglfw.so:
$(CC) -fPIC -shared -D$(BKN) -D_GLFW_BUILD_DLL ./ext/glfw/src/*.c -o $@
$(CC) -fPIC -shared $(DFLAGS) -D_GLFW_BUILD_DLL -Iext/glfw/deps/wayland ./ext/glfw/src/*.c -o $@
clean:
rm $(OBJ) $(BIN)
cd ext; $(MAKE) -f glfw.mk clean; cd -
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) -c -o $@ $<
$(CC) -Wno-implicit-function-declaration $(CFLAGS) -c -o $@ $<

View File

@@ -18,7 +18,7 @@ Para poder compilar el proyecto hace falta lo siguiente.
- `glfw`: A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input.
- `cglm`: Highly Optimized 2D / 3D Graphics Math (glm) for C.
### Linux
Para compilar `glfw` en linux hacen falta las siguientes librerías según el caso. (no incluidas)
Para compilar `glfw` en linux hacen falta las siguientes librerías. (no incluidas)
- `x11`: libXcursor-devel libXi-devel libXinerama-devel libXrandr-devel
- `wayland`: libwayland-dev libxkbcommon-dev wayland-protocols

3
compile.bat Normal file
View File

@@ -0,0 +1,3 @@
:: git submodule update --init --recursive
:: gcc -fPIC -shared -Iext/glfw/deps/MinGW -D_GLFW_WIN32 -D_GLFW_BUILD_DLL ./ext/glfw/src/*.c -o glfw.dll -lgdi32
gcc -I ext/cglm/include -I ext/glfw/include src/*.c -o manigraph -L . -lglfw -lopengl32 -lglew32

1641
ext/glad/glad.c Normal file

File diff suppressed because it is too large Load Diff

3191
ext/glad/glad.h Normal file

File diff suppressed because it is too large Load Diff

311
ext/glad/khrplatform.h Normal file
View File

@@ -0,0 +1,311 @@
#ifndef __khrplatform_h_
#define __khrplatform_h_
/*
** Copyright (c) 2008-2018 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
** "Materials"), to deal in the Materials without restriction, including
** without limitation the rights to use, copy, modify, merge, publish,
** distribute, sublicense, and/or sell copies of the Materials, and to
** permit persons to whom the Materials are furnished to do so, subject to
** the following conditions:
**
** The above copyright notice and this permission notice shall be included
** in all copies or substantial portions of the Materials.
**
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
/* Khronos platform-specific types and definitions.
*
* The master copy of khrplatform.h is maintained in the Khronos EGL
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
* The last semantic modification to khrplatform.h was at commit ID:
* 67a3e0864c2d75ea5287b9f3d2eb74a745936692
*
* Adopters may modify this file to suit their platform. Adopters are
* encouraged to submit platform specific modifications to the Khronos
* group so that they can be included in future versions of this file.
* Please submit changes by filing pull requests or issues on
* the EGL Registry repository linked above.
*
*
* See the Implementer's Guidelines for information about where this file
* should be located on your system and for more details of its use:
* http://www.khronos.org/registry/implementers_guide.pdf
*
* This file should be included as
* #include <KHR/khrplatform.h>
* by Khronos client API header files that use its types and defines.
*
* The types in khrplatform.h should only be used to define API-specific types.
*
* Types defined in khrplatform.h:
* khronos_int8_t signed 8 bit
* khronos_uint8_t unsigned 8 bit
* khronos_int16_t signed 16 bit
* khronos_uint16_t unsigned 16 bit
* khronos_int32_t signed 32 bit
* khronos_uint32_t unsigned 32 bit
* khronos_int64_t signed 64 bit
* khronos_uint64_t unsigned 64 bit
* khronos_intptr_t signed same number of bits as a pointer
* khronos_uintptr_t unsigned same number of bits as a pointer
* khronos_ssize_t signed size
* khronos_usize_t unsigned size
* khronos_float_t signed 32 bit floating point
* khronos_time_ns_t unsigned 64 bit time in nanoseconds
* khronos_utime_nanoseconds_t unsigned time interval or absolute time in
* nanoseconds
* khronos_stime_nanoseconds_t signed time interval in nanoseconds
* khronos_boolean_enum_t enumerated boolean type. This should
* only be used as a base type when a client API's boolean type is
* an enum. Client APIs which use an integer or other type for
* booleans cannot use this as the base type for their boolean.
*
* Tokens defined in khrplatform.h:
*
* KHRONOS_FALSE, KHRONOS_TRUE Enumerated boolean false/true values.
*
* KHRONOS_SUPPORT_INT64 is 1 if 64 bit integers are supported; otherwise 0.
* KHRONOS_SUPPORT_FLOAT is 1 if floats are supported; otherwise 0.
*
* Calling convention macros defined in this file:
* KHRONOS_APICALL
* KHRONOS_APIENTRY
* KHRONOS_APIATTRIBUTES
*
* These may be used in function prototypes as:
*
* KHRONOS_APICALL void KHRONOS_APIENTRY funcname(
* int arg1,
* int arg2) KHRONOS_APIATTRIBUTES;
*/
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
# define KHRONOS_STATIC 1
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APICALL
*-------------------------------------------------------------------------
* This precedes the return type of the function in the function prototype.
*/
#if defined(KHRONOS_STATIC)
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
* header compatible with static linking. */
# define KHRONOS_APICALL
#elif defined(_WIN32)
# define KHRONOS_APICALL __declspec(dllimport)
#elif defined (__SYMBIAN32__)
# define KHRONOS_APICALL IMPORT_C
#elif defined(__ANDROID__)
# define KHRONOS_APICALL __attribute__((visibility("default")))
#else
# define KHRONOS_APICALL
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIENTRY
*-------------------------------------------------------------------------
* This follows the return type of the function and precedes the function
* name in the function prototype.
*/
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
/* Win32 but not WinCE */
# define KHRONOS_APIENTRY __stdcall
#else
# define KHRONOS_APIENTRY
#endif
/*-------------------------------------------------------------------------
* Definition of KHRONOS_APIATTRIBUTES
*-------------------------------------------------------------------------
* This follows the closing parenthesis of the function prototype arguments.
*/
#if defined (__ARMCC_2__)
#define KHRONOS_APIATTRIBUTES __softfp
#else
#define KHRONOS_APIATTRIBUTES
#endif
/*-------------------------------------------------------------------------
* basic type definitions
*-----------------------------------------------------------------------*/
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
/*
* Using <stdint.h>
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
/*
* To support platform where unsigned long cannot be used interchangeably with
* inptr_t (e.g. CHERI-extended ISAs), we can use the stdint.h intptr_t.
* Ideally, we could just use (u)intptr_t everywhere, but this could result in
* ABI breakage if khronos_uintptr_t is changed from unsigned long to
* unsigned long long or similar (this results in different C++ name mangling).
* To avoid changes for existing platforms, we restrict usage of intptr_t to
* platforms where the size of a pointer is larger than the size of long.
*/
#if defined(__SIZEOF_LONG__) && defined(__SIZEOF_POINTER__)
#if __SIZEOF_POINTER__ > __SIZEOF_LONG__
#define KHRONOS_USE_INTPTR_T
#endif
#endif
#elif defined(__VMS ) || defined(__sgi)
/*
* Using <inttypes.h>
*/
#include <inttypes.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
/*
* Win32
*/
typedef __int32 khronos_int32_t;
typedef unsigned __int32 khronos_uint32_t;
typedef __int64 khronos_int64_t;
typedef unsigned __int64 khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif defined(__sun__) || defined(__digital__)
/*
* Sun or Digital
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#if defined(__arch64__) || defined(_LP64)
typedef long int khronos_int64_t;
typedef unsigned long int khronos_uint64_t;
#else
typedef long long int khronos_int64_t;
typedef unsigned long long int khronos_uint64_t;
#endif /* __arch64__ */
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#elif 0
/*
* Hypothetical platform with no float or int64 support
*/
typedef int khronos_int32_t;
typedef unsigned int khronos_uint32_t;
#define KHRONOS_SUPPORT_INT64 0
#define KHRONOS_SUPPORT_FLOAT 0
#else
/*
* Generic fallback
*/
#include <stdint.h>
typedef int32_t khronos_int32_t;
typedef uint32_t khronos_uint32_t;
typedef int64_t khronos_int64_t;
typedef uint64_t khronos_uint64_t;
#define KHRONOS_SUPPORT_INT64 1
#define KHRONOS_SUPPORT_FLOAT 1
#endif
/*
* Types that are (so far) the same on all platforms
*/
typedef signed char khronos_int8_t;
typedef unsigned char khronos_uint8_t;
typedef signed short int khronos_int16_t;
typedef unsigned short int khronos_uint16_t;
/*
* Types that differ between LLP64 and LP64 architectures - in LLP64,
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
* to be the only LLP64 architecture in current use.
*/
#ifdef KHRONOS_USE_INTPTR_T
typedef intptr_t khronos_intptr_t;
typedef uintptr_t khronos_uintptr_t;
#elif defined(_WIN64)
typedef signed long long int khronos_intptr_t;
typedef unsigned long long int khronos_uintptr_t;
#else
typedef signed long int khronos_intptr_t;
typedef unsigned long int khronos_uintptr_t;
#endif
#if defined(_WIN64)
typedef signed long long int khronos_ssize_t;
typedef unsigned long long int khronos_usize_t;
#else
typedef signed long int khronos_ssize_t;
typedef unsigned long int khronos_usize_t;
#endif
#if KHRONOS_SUPPORT_FLOAT
/*
* Float type
*/
typedef float khronos_float_t;
#endif
#if KHRONOS_SUPPORT_INT64
/* Time types
*
* These types can be used to represent a time interval in nanoseconds or
* an absolute Unadjusted System Time. Unadjusted System Time is the number
* of nanoseconds since some arbitrary system event (e.g. since the last
* time the system booted). The Unadjusted System Time is an unsigned
* 64 bit value that wraps back to 0 every 584 years. Time intervals
* may be either signed or unsigned.
*/
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
typedef khronos_int64_t khronos_stime_nanoseconds_t;
#endif
/*
* Dummy value used to pad enum types to 32 bits.
*/
#ifndef KHRONOS_MAX_ENUM
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
#endif
/*
* Enumerated boolean type
*
* Values other than zero should be considered to be true. Therefore
* comparisons should not be made against KHRONOS_TRUE.
*/
typedef enum {
KHRONOS_FALSE = 0,
KHRONOS_TRUE = 1,
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
} khronos_boolean_enum_t;
#endif /* __khrplatform_h_ */

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

1
ext/nuklear Submodule

Submodule ext/nuklear added at 6566d9075d

View File

@@ -1,5 +1,11 @@
#include "main.h"
#ifdef EMSCRIPTEN
#include <GL/gl.h>
#else
#include <glad.h>
#include <GLFW/glfw3.h>
#endif
void set_clean_color_context(unsigned char r, unsigned char g, unsigned char b)
{
@@ -7,7 +13,13 @@ void set_clean_color_context( unsigned char r, unsigned char g, unsigned char b
glClearColor((float)r / 0xff, (float)g / 0xff, (float)b / 0xff, 1.0);
}
void clean_context( void )
int init_context(void)
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
#ifdef EMSCRIPTEN
return 1;
#else
return gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
#endif
}
void clean_context(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); }

View File

@@ -7,39 +7,34 @@
#undef G
#undef H
const float X = 2.0;
const float Y = 0.05;
const float Z = 0.05;
#define A -2.0,-0.05,-0.05,
#define B -2.0,-0.05, 0.05,
#define C -2.0, 0.05,-0.05,
#define D -2.0, 0.05, 0.05,
#define E 2.0,-0.05,-0.05,
#define F 2.0,-0.05, 0.05,
#define G 2.0, 0.05,-0.05,
#define H 2.0, 0.05, 0.05,
#define A -X,-Y,-Z,
#define B -X,-Y, Z,
#define C -X, Y,-Z,
#define D -X, Y, Z,
#define E X,-Y,-Z,
#define F X,-Y, Z,
#define G X, Y,-Z,
#define H X, Y, Z,
narray_float_t d_axis =
float d_axis[] =
{
3*3*2*6,
A C E
C E G
G E C
E G F
G F H
H F G
F H B
H B D
D B H
B D A
D A C
C A D
C D G
D G H
H G D
A B E
E B A
B E F
};

View File

@@ -1,32 +0,0 @@
#define A -1,-1,-1,
#define B -1,-1, 1,
#define C -1, 1,-1,
#define D -1, 1, 1,
#define E 1,-1,-1,
#define F 1,-1, 1,
#define G 1, 1,-1,
#define H 1, 1, 1,
narray_float_t d_cube =
{
3*3*2*6,
A C E
C E G
E G F
G F H
F H B
H B D
B D A
D A C
C D G
D G H
A B E
B E F
};

View File

@@ -1,30 +1,98 @@
const char *vs =
#ifdef EMSCRIPTEN
"#version 300 es\n"
"precision highp float;"
#else
"#version 330 core\n"
#endif
"layout (location = 0) in float aPos_x;"
"layout (location = 1) in float aPos_y;"
"layout (location = 2) in float aPos_z;"
"layout (location = 3) in float aPos_w;"
"layout (location = 0) in vec3 aPos;"
"layout (location = 4) in float aNormal_x;"
"layout (location = 5) in float aNormal_y;"
"layout (location = 6) in float aNormal_z;"
"layout (location = 7) in float aNormal_w;"
"uniform float angle;"
"uniform float i;"
"uniform vec4 color;"
"uniform float idx;"
"uniform mat4 fix;"
"uniform mat4 rot;"
"uniform mat4 mdl;"
"out float index;"
"out vec3 Normal;"
"out vec3 FragPos;"
"out vec4 Color;"
"mat2 rotate2d( float angle )"
"{"
"return mat2( cos(angle), sin(angle), -sin(angle), cos(angle) );"
"}"
"void main()"
"{"
" index=idx;"
" gl_Position = fix * rot * mdl * vec4( aPos, 1.0 );\n"
" Color=color;"
" vec3 aNormal = vec3(aNormal_x,aNormal_y,aNormal_z);"
" vec3 aPos = vec3(aPos_x,aPos_y,aPos_z);"
" aNormal[int(i)] = (vec2(aNormal[int(i)], aNormal_w) * "
"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 =
#ifdef EMSCRIPTEN
"#version 300 es\n"
"precision highp float;"
#else
"#version 330 core\n"
#endif
"out vec4 FragColor;"
"in vec3 Normal;"
"in vec3 FragPos;"
"in vec4 Color;"
"void main()"
"{"
" FragColor = vec4(pow(vec3(Color),vec3(1.0/2.2)),Color.a);"
"}";
const char *fs =
#ifdef EMSCRIPTEN
"#version 300 es\n"
"precision highp float;"
#else
"#version 330 core\n"
#endif
"uniform sampler2DArray palette;"
"in vec3 Normal;"
"in vec3 FragPos;"
"in vec4 Color;"
"in float index;"
"out vec4 FragColor;"
"void main()"
"{"
" FragColor = texture( palette, vec3( 0, 0, index ) ).rgba;"
" vec3 viewPos = vec3(0, 0, -15);\n"
" vec3 viewDir = normalize(viewPos - FragPos);\n"
" vec3 lightPos = viewPos;\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"
" vec3 result = pow((0.5 + 0.5*diffuse + 1.5*specular) * Color.rgb, "
"vec3(1.0/2.2));\n"
" FragColor = vec4(result, Color.a);\n"
"}";

View File

@@ -1,6 +1,7 @@
#include "main.h"
#include <cglm/quat.h>
#include <GLFW/glfw3.h>
#include <cglm/quat.h>
#include <stdio.h>
#define ANGLE ((float)0x01 / 0xff * 2 * GLM_PI)
@@ -8,16 +9,74 @@ unsigned char selected_axis = 0;
int window_width;
int window_height;
unsigned char animate_index=0;
versor q = GLM_QUAT_IDENTITY_INIT;
vec3 axis[3] =
{
vec3 axis[3] = {
{1, 0, 0},
{0, 1, 0},
{0, 0, 1},
};
void __window_callback(GLFWwindow * window, int w, int h)
extern struct projection projection;
void __key_callback_input(
GLFWwindow *window, int key, int scancode, int action, int mods)
{
if (action != GLFW_PRESS)
return;
if (GLFW_KEY_0 < key && key <= GLFW_KEY_9)
{
unsigned char selected_coord;
selected_coord = key - GLFW_KEY_0 - 1;
if (selected_coord >= projection.m)
return;
if (selected_coord == projection.x)
return;
if (selected_coord == projection.y)
return;
if (selected_coord == projection.z)
return;
selected_coord = projection.w;
}
if (projection.w >= projection.m)
return;
switch (key)
{
unsigned char tmp;
case GLFW_KEY_I:
tmp = projection.w;
projection.w = projection.x;
projection.x = tmp;
animate_index=1;
break;
case GLFW_KEY_O:
tmp = projection.w;
projection.w = projection.y;
projection.y = tmp;
animate_index=2;
break;
case GLFW_KEY_P:
tmp = projection.w;
projection.w = projection.z;
projection.z = tmp;
animate_index=3;
break;
}
return;
}
void __window_callback_input(GLFWwindow *window, int w, int h)
{
int m;
@@ -28,7 +87,8 @@ void __window_callback(GLFWwindow * window, int w, int h)
glViewport((w - m) / 2, (h - m) / 2, m, m);
}
void __mouse_callback(GLFWwindow* window, int button, int action, int mods)
void __mouse_callback_input(
GLFWwindow *window, int button, int action, int mods)
{
unsigned char green_value;
double xpos, ypos;
@@ -37,8 +97,8 @@ void __mouse_callback(GLFWwindow* window, int button, int action, int mods)
return;
glfwGetCursorPos(window, &xpos, &ypos);
glReadPixels((int)xpos, (int)(window_height - ypos), 1, 1, GL_GREEN, GL_UNSIGNED_BYTE, &green_value);
glReadPixels((int)xpos, (int)(window_height - ypos), 1, 1, GL_GREEN,
GL_UNSIGNED_BYTE, &green_value);
switch (green_value)
{
@@ -49,16 +109,24 @@ void __mouse_callback(GLFWwindow* window, int button, int action, int mods)
}
}
void __scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
void __scroll_callback_input(GLFWwindow *window, double xoffset, double yoffset)
{
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(r, q, q);
glm_quat_rotatev(p, axis[0], axis[0]);
glm_quat_rotatev(p, axis[1], axis[1]);
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)
@@ -102,6 +170,13 @@ end:
glm_quat_rotatev(p, axis[1], axis[1]);
glm_quat_rotatev(p, axis[2], axis[2]);
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;
}

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,87 +1,189 @@
#include "main.h"
#include "data/cube.h"
#include "data/axis.h"
#include "data/shaders.h"
#include <GL/glew.h>
#include <stdio.h>
#include <stdlib.h>
#define WIDTH 512
#define HEIGHT 512
unsigned char palette[] =
{
16,
0xEB,0xD3,0xF8,0xff,
0xEB,0xD4,0xF8,0xff,
0xEB,0xD5,0xF8,0xff,
0x7A,0x1C,0xAC,0xff,
};
#ifdef EMSCRIPTEN
#include <emscripten.h>
#endif
#ifndef M_PI
#define M_PI 3.14159
#endif
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};
const char *wname = "manigraph: manifold grapher";
int main( void )
unsigned char color[4] = {0x2F, 0x3C, 0x7E, 0xff};
void mlog(char *msg)
{
id_t shader, texture;
mesh_t m_cube, m_axis;
#ifdef DEBUG
printf(msg);
#endif
}
window_t window;
mesh_t m_surface;
id_t shader, shader_plain;
if( !( window = init_window( WIDTH, HEIGHT, wname ) ) )
goto error_window;
extern volatile unsigned char animate_index;
use_window( window );
set_clean_color_context( 0x2E, 0x07, 0x3F );
#ifndef EMSCRIPTEN
static inline
#endif
glewInit();
if( !( shader = create_shader() ) )
goto error_shader;
gload_program( shader, vs, VERTEX );
gload_program( shader, fs, FRAGMENT );
use_shader( shader );
load_fix_matrix( shader, (float)WIDTH/HEIGHT );
if( !( m_cube = create_mesh( d_cube ) ) )
goto error_mesh_cube;
if( !( m_axis = create_mesh( d_axis ) ) )
goto error_mesh_axis;
texture=create_palette_texture( palette );
use_texture( texture );
while( is_open_window( window ) )
void
main_loop(void)
{
quat_t q;
q = poll_input(window);
load_rot_matrix( shader, q );
clean_context();
#ifndef DEBUG
load_mdl_matrix( shader, 0, 0 );
draw_mesh( m_axis );
load_mdl_matrix( shader, 1, 1 );
draw_mesh( m_axis );
load_mdl_matrix( shader, 2, 2 );
draw_mesh( m_axis );
#endif
load_mdl_matrix( shader, 0, 3 );
draw_mesh( m_cube );
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);
}
destroy_texture( texture );
destroy_mesh( m_axis );
destroy_mesh( m_cube );
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();
draw_mesh(shader, m_surface);
draw_mesh_lines(shader_plain, m_surface);
}
int main(void)
{
mlog("[VENTANA] Inicializando...\n");
{
if (!(window = init_window(WIDTH, HEIGHT, wname)))
{
mlog("[VENTANA] Error al inicializar...\n");
goto error_window;
}
use_window(window);
}
mlog("[CONTEXT] Inicializando...\n");
{
if (!(init_context()))
{
mlog("[CONTEXT] Error al inicializar...\n");
goto error_context;
}
set_clean_color_context(0xFF, 0xFF, 0xFF);
}
mlog("[SHADER] Inicializando...\n");
{
if (!(shader = create_shader()))
{
mlog("[SHADER] Error al inicializar...\n");
goto error_shader;
}
load_program_to_shader(shader, vs, VERTEX);
load_program_to_shader(shader, fs, FRAGMENT);
fix_matrix_load(shader, (float)WIDTH / HEIGHT);
}
mlog("[SHADER] Inicializando...\n");
{
if (!(shader_plain = create_shader()))
{
mlog("[SHADER] Error al inicializar...\n");
goto error_shader_plain;
}
load_program_to_shader(shader_plain, vs, VERTEX);
load_program_to_shader(shader_plain, fs_plain, FRAGMENT);
fix_matrix_load(shader_plain, (float)WIDTH / HEIGHT);
}
mlog("[MESH] Inicializando...\n");
{
struct surface surface;
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(surface)))
{
mlog("[MESH] Error al inicializar...\n");
goto error_mesh_surface;
}
projection.m = surface.dim;
projection.mesh = m_surface;
set_projection_mesh(projection);
free(surface.norm);
free(surface.data);
}
mlog("[MAIN LOOP] Inicializando...\n");
#ifdef EMSCRIPTEN
emscripten_set_main_loop(&main_loop, 60, 1);
return 0;
#else
while (is_open_window(window))
main_loop();
#endif
mlog("[MAIN LOOP] Terminando...\n");
mlog("[MESH] Destruyendo...\n");
destroy_mesh(m_surface);
mlog("[SHADER] Destruyendo...\n");
destroy_shader(shader_plain);
mlog("[SHADER] Destruyendo...\n");
destroy_shader(shader);
mlog("[WINDOW] Destruyendo...\n");
close_window(window);
return 0;
error_mesh_axis:
destroy_mesh( m_cube );
error_mesh_cube:
error_context:
mlog("[MESH] Destruyendo...\n");
destroy_mesh(m_surface);
error_mesh_surface:
mlog("[SHADER] Destruyendo...\n");
destroy_shader(shader_plain);
error_shader_plain:
mlog("[SHADER] Destruyendo...\n");
destroy_shader(shader);
error_shader:
mlog("[WINDOW] Destruyendo...\n");
close_window(window);
error_window:
return 1;

View File

@@ -1,5 +1,10 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
/*
If DEBUG is set, we show the triangles of the mesh,
without illumination, and we write the compilation
error of the shaders.
*/
#define DEBUG
typedef const void *window_t;
typedef unsigned int id_t;
@@ -7,14 +12,44 @@ typedef void * mesh_t;
typedef float *quat_t;
typedef float *mat4_t;
typedef float narray_float_t[];
typedef unsigned char narray_u8_t[];
/*
This struct represent the proyection, where:
mesh: data of surface.
m: the dimention of the surface.
x: the coordanate of the x axis.
y: the coordanate of the y axis.
z: the coordanate of the z axis.
w: the coordanate of the w axis.
*/
enum
struct projection
{
VERTEX, FRAGMENT
mesh_t mesh;
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:
w: default width;
h: default height;
name: Name of the window.
*/
window_t init_window(unsigned int w, unsigned int h, const char *name);
void use_window(window_t window);
@@ -23,33 +58,109 @@ int is_open_window(window_t window);
void close_window(window_t window);
mesh_t create_mesh(narray_float_t mesh);
/*
Create mesh:
d: array of floats with the vertex data.
n: array of floats with the normal data.
m: Dimention of mesh
*/
mesh_t create_mesh(struct surface);
void set_projection_mesh(struct projection);
void destroy_mesh(mesh_t p);
void draw_mesh(mesh_t p);
void draw_mesh(id_t, mesh_t p);
void set_clean_color_context(unsigned char, unsigned char, unsigned char);
void draw_mesh_lines(id_t, mesh_t p);
/*
Set background color:
r: red value in hex.
g: green value in hex.
b: blue value in hex.
*/
void set_clean_color_context(unsigned char r, unsigned char g, unsigned char b);
void clean_context(void);
int init_context(void);
void destroy_shader(id_t shader);
id_t create_shader(void);
void use_shader(id_t program);
void use_shader(id_t shader);
unsigned char gload_program(id_t program, const char * src, unsigned int type);
enum
{
VERTEX,
FRAGMENT
};
void gload_float(id_t program, char * var, float f);
/*
Load program to shader:
src: GLSL source code as string.
type: VERTEX or FRAGMENT
*/
void gload_mat4(id_t program, char * var, mat4_t m);
unsigned char load_program_to_shader(
id_t shader, const char *src, unsigned int type);
void load_fix_matrix(id_t shader, float ratio);
/*
load float to shader:
var: name of glsl variable.
f: float to load
*/
void load_mdl_matrix(id_t shader, unsigned char i, unsigned char c);
void load_float_to_shader(id_t shader, char *var, float f);
void load_rot_matrix(id_t shader, quat_t q);
/*
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:
var: name of glsl variable.
m: Matrix to load
*/
void load_mat4_to_shader(id_t shader, char *var, mat4_t m);
/*
Generate and load fix matrix, this matrix
has the information of the perspective and
camera information.
ratio: default ratio of window.
*/
void fix_matrix_load(id_t shader, float ratio);
/*
Generate and load rotation matrix.
q: quaterinon describing the rotation.
*/
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);
@@ -57,6 +168,17 @@ void use_texture(id_t texture);
void destroy_texture(id_t texture);
id_t create_palette_texture(const narray_u8_t colors);
/*
Set color palette as texture:
colors: array of color values (rgba in hex ).
n: number of color on colors.
*/
id_t create_palette_texture(const unsigned char colors[][4], unsigned char n);
quat_t poll_input(window_t window);
#ifdef EMSCRIPTEN
#ifdef GLAD
#error undefine GLAD on src/main.h please
#endif
#endif

View File

@@ -1,51 +0,0 @@
#include "main.h"
#include <cglm/mat4.h>
#include <cglm/cam.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 );
gload_mat4( shader, "fix", (mat4_t) m );
}
void load_mdl_matrix( id_t shader, unsigned char i, unsigned char c )
{
gload_float( shader, "idx", c );
gload_mat4( shader, "mdl", (mat4_t)ortho[i] );
}
void load_rot_matrix( id_t shader, quat_t q )
{
mat4 m;
glm_quat_mat4( q, m );
gload_mat4( shader, "rot", (mat4_t)m );
}

102
src/mesh.c Executable file → Normal file
View File

@@ -1,30 +1,82 @@
#include "main.h"
#include <GL/glew.h>
#ifdef EMSCRIPTEN
#include <GL/gl.h>
#else
#include <glad.h>
#endif
#include <stdio.h>
#include <stdlib.h>
struct obj
{
unsigned int vertex, vao, vbo;
unsigned int vertex, vao, n_vbo, d_vbo;
};
mesh_t create_mesh( narray_float_t mesh )
void set_projection_mesh(struct projection projection)
{
struct obj *p;
p = projection.mesh;
glBindVertexArray(p->vao);
glBindBuffer(GL_ARRAY_BUFFER, p->d_vbo);
glVertexAttribPointer(0, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.x * sizeof(float)));
glVertexAttribPointer(1, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.y * sizeof(float)));
glVertexAttribPointer(2, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.z * sizeof(float)));
glVertexAttribPointer(3, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.w * sizeof(float)));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p->n_vbo);
glVertexAttribPointer(4, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.x * sizeof(float)));
glVertexAttribPointer(5, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.y * sizeof(float)));
glVertexAttribPointer(6, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.z * sizeof(float)));
glVertexAttribPointer(7, 1, GL_FLOAT, 0, projection.m * sizeof(float),
(float *)(projection.w * sizeof(float)));
}
/*
In this function we load all the vertex and ELEMENT_ARRAY datas on two
diferents buffers, so we can access the coordanates that we want
to display using the layout location in GLSL.
This trick can be done with glVertexAttribPointer.
*/
mesh_t create_mesh(struct surface surface)
{
unsigned char i;
struct obj *p;
p = malloc(sizeof(struct obj));
p->vertex=(*mesh)/3;
p->vertex = surface.vertex;
glGenVertexArrays(1, &p->vao);
glGenBuffers( 1, &p->vbo );
glBindVertexArray(p->vao);
glBindBuffer( GL_ARRAY_BUFFER, p->vbo );
glBufferData( GL_ARRAY_BUFFER, (p->vertex*3)*sizeof(int), mesh+1,
GL_STATIC_DRAW );
glVertexAttribPointer( 0,3,GL_FLOAT, 0, 3*sizeof(int), NULL );
glEnableVertexAttribArray(0);
glGenBuffers(1, &p->d_vbo);
glBindBuffer(GL_ARRAY_BUFFER, p->d_vbo);
glBufferData(GL_ARRAY_BUFFER, p->vertex * surface.dim * sizeof(float),
surface.data, GL_STATIC_DRAW);
if (surface.norm)
{
glGenBuffers(1, &p->n_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, p->n_vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
p->vertex * surface.dim * sizeof(float), surface.norm,
GL_STATIC_DRAW);
}
for (i = 0; i < 8; ++i)
glEnableVertexAttribArray(i);
return p;
}
@@ -34,22 +86,32 @@ void destroy_mesh( mesh_t p )
struct obj *obj;
obj = p;
glDeleteVertexArrays(1, &obj->vao);
glDeleteBuffers( 1, &obj->vbo );
glDeleteBuffers(1, &obj->d_vbo);
glDeleteBuffers(1, &obj->n_vbo);
free(p);
}
void draw_mesh( mesh_t p )
void draw_mesh(id_t shader, mesh_t p)
{
struct obj *obj = p;
glUseProgram(shader);
glBindVertexArray(obj->vao);
#ifdef DEBUG
{
int i;
for( i=0; i<obj->vertex;i+=3 )
glDrawArrays(GL_LINE_LOOP, i, 3 );
}
#else
#ifndef EMSCRIPTEN
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
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
}

View File

@@ -1,35 +1,27 @@
#include "main.h"
#include <GL/glew.h>
#ifndef EMSCRIPTEN
#include <glad.h>
#else
#include <GL/gl.h>
#endif
#ifdef DEBUG
#include <stdio.h>
#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 gload_program( unsigned int program, const char * src,
unsigned int i )
unsigned char load_program_to_shader(
unsigned int program, const char *src, unsigned int i)
{
int shader, status;
unsigned int type[] =
{
[VERTEX]=GL_VERTEX_SHADER,
[FRAGMENT]=GL_FRAGMENT_SHADER
};
unsigned int type[] = {
[VERTEX] = GL_VERTEX_SHADER, [FRAGMENT] = GL_FRAGMENT_SHADER};
if (!src)
return 0;
@@ -37,8 +29,8 @@ unsigned char gload_program( unsigned int program, const char * src,
shader = glCreateShader(type[i]);
glShaderSource(shader, 1, (const GLchar **)&src, ((void *)0));
glCompileShader(shader);
glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (!status)
{
@@ -56,14 +48,21 @@ unsigned char gload_program( unsigned int program, const char * src,
return 1;
}
void gload_float( unsigned int program, char * var, float f )
void load_float_to_shader(unsigned int program, char *var, float f)
{
glUseProgram(program);
glUniform1f(glGetUniformLocation(program, var), f);
}
void gload_mat4( unsigned int program, char * var, float * mat )
void load_mat4_to_shader(unsigned int program, char *var, float *mat)
{
glUseProgram(program);
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]);
}

400
src/surface.c Normal file
View File

@@ -0,0 +1,400 @@
#include <complex.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#define TEST
#define CGLM_ALL_UNALIGNED
#include <cglm/vec3.h>
#include <cglm/vec4.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#ifndef CMPLX
#define CMPLX(a, b) (a + I * b)
#endif
#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;
float u = 2 * ((float)coords[0] / grid[0]) - 1;
float v = 2 * ((float)coords[1] / grid[1]) - 1;
eq = csqrt(CMPLX(u, v));
d_surface[0] = u;
d_surface[1] = v;
d_surface[2] = creal(eq);
d_surface[3] = cimag(eq);
}
void cube(float *d_surface, int *coord, unsigned char *grid)
{
int i;
for (i = 0; i < parm.m; i++)
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, unsigned char *grid)
{
const float width = 0.5;
float u = (2 * M_PI) * ((float)coord[0] / grid[0]);
float v = (2 * width) * ((float)coord[1] / grid[1]) - width;
d_surface[0] = cos(u) + v * cos(u / 2) * cos(u);
d_surface[1] = sin(u) + v * cos(u / 2) * sin(u);
d_surface[2] = v * sin(u / 2);
}
void torus(float *d_surface, int *coord, unsigned char *grid)
{
float u = (2 * M_PI) * ((float)coord[0] / grid[0]);
float v = (2 * M_PI) * ((float)coord[1] / grid[1]);
d_surface[0] = (1 + 0.5 * cos(v)) * cos(u);
d_surface[1] = (1 + 0.5 * cos(v)) * sin(u);
d_surface[2] = 0.5 * sin(v);
}
void klein(float *d_surface, int *coord, unsigned char *grid)
{
float u = (2 * M_PI) * ((float)coord[0] / grid[0]);
float v = (2 * M_PI) * ((float)coord[1] / grid[1]);
d_surface[0] = (0.5 * cos(v) + 0.5) * cos(u);
d_surface[1] = (0.5 * cos(v) + 0.5) * sin(u);
d_surface[2] = sin(v) * cos(u / 2);
d_surface[3] = sin(v) * sin(u / 2);
}
float *generate_data_surface(unsigned char *dim, unsigned long *vertex)
{
unsigned int i, j, k, o, p, n;
unsigned long size, q = 0;
float *d_surface;
int *cara;
parm.f = cube;
parm.m = 4;
parm.n = 4;
parm.grid = (char[]){16, 8, 4, 2, 1};
#ifdef TEST
assert(faces(2) == 1);
assert(faces(3) == 6);
assert(faces(4) == 24);
#endif
*dim = parm.n;
*vertex = 0;
{
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 (k = 0; k < (1 << (parm.m - 2)); k++)
{
unsigned char skip = 0;
for (n = 0; n < parm.m; n++)
{
if (n == o || n == p)
skip++;
cara[n] = (k & (1 << (n - skip))) ? parm.grid[n] : 0;
}
for (i = 0; i < parm.grid[p]; i++)
{
for (j = 0; j < parm.grid[o]; j++)
{
cara[p] = i;
cara[o] = j;
parm.f(&d_surface[q], cara, parm.grid);
q += parm.n;
cara[p] = i + 1;
cara[o] = j;
parm.f(&d_surface[q], cara, parm.grid);
q += parm.n;
cara[p] = i + 1;
cara[o] = j + 1;
parm.f(&d_surface[q], cara, parm.grid);
q += parm.n;
cara[p] = i;
cara[o] = j;
parm.f(&d_surface[q], cara, parm.grid);
q += parm.n;
cara[p] = i;
cara[o] = j + 1;
parm.f(&d_surface[q], cara, parm.grid);
q += parm.n;
cara[p] = i + 1;
cara[o] = j + 1;
parm.f(&d_surface[q], cara, parm.grid);
q += parm.n;
}
}
}
}
}
#ifdef TEST
assert(q == size);
#endif
return d_surface;
}
static void __calculate_normal(
float *p1, float *p2, float *p3, float *normal, unsigned char n)
{
unsigned char i;
float alpha;
float *v1, *v2, *v3;
float *u1, *u2, *u3;
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
*/
{
for (i = 0; i < n; ++i)
{
v1[i] = p2[i] - p1[i];
v2[i] = p3[i] - p1[i];
v3[i] = p1[i];
}
for (i = 0; i < n; ++i)
{
u1[i] = v1[i];
}
{
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;
for (i = 0; i < n; ++i)
{
proj[i] = u1[i] * alpha;
u2[i] = v2[i] - proj[i];
}
}
{
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;
}
}
float *generate_normals_surface(float *d, unsigned char m, unsigned long vertex)
{
float *n;
float *norm_vec;
n = malloc((m * vertex) * sizeof(float));
norm_vec = malloc(m * sizeof(float));
for (int i = 0; i < *d; i += 3 * m)
{
__calculate_normal(d + i, d + i + m, d + i + 2 * m, norm_vec, m);
glm_vec3_copy(norm_vec, n + i);
glm_vec3_copy(norm_vec, n + i + m);
glm_vec3_copy(norm_vec, n + i + 2 * m);
}
free(norm_vec);
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,37 +0,0 @@
#include "main.h"
#include <GL/glew.h>
#define TYPE GL_TEXTURE_2D_ARRAY
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 )
{
id_t texture = config_texture( TYPE );
glTexImage3D( TYPE, 0, GL_RGBA,
1, 1, (*colors)/4, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors+1);
return texture;
}

View File

@@ -1,15 +1,48 @@
#include "main.h"
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <time.h>
void __window_callback(GLFWwindow *, int, int);
void __mouse_callback(GLFWwindow *, int, int, int);
void __scroll_callback(GLFWwindow *, double, double);
void __window_callback_input(GLFWwindow *, int, int);
void __mouse_callback_input(GLFWwindow *, int, int, int);
void __scroll_callback_input(GLFWwindow *, double, double);
void __key_callback_input(GLFWwindow *, int, int, int, int);
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);
/*
Limitamos los FPS, contando el tiempo en el que
se ejecuta el main loop, y esperando el tiempo restante
para lograr los fps deseados.
*/
static void __limit_fps_window(int max_fps)
{
void * window;
void __mouse_callback(GLFWwindow *window, int button, int action, int mods);
void __scroll_callback(GLFWwindow *window, double xoffset, double yoffset);
static double previous_time = 0.0;
double current_time;
double frame_time;
double elapsed_time;
current_time = glfwGetTime();
frame_time = 1.0 / max_fps;
elapsed_time = current_time - previous_time;
if (elapsed_time < frame_time)
{
struct timespec sleep_time;
sleep_time.tv_sec = 0;
sleep_time.tv_nsec = (long)((frame_time - elapsed_time) * 1e9);
nanosleep(&sleep_time, NULL);
current_time = glfwGetTime();
}
previous_time = current_time;
}
window_t init_window(unsigned int width, unsigned int height, const char *title)
{
window_t window;
if (!glfwInit())
return NULL;
@@ -18,38 +51,38 @@ window_t init_window(unsigned int w, unsigned int h, const char * name)
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(w, h, name, NULL, NULL);
if( !window )
window = (window_t)glfwCreateWindow(width, height, title, NULL, NULL);
if (!(window))
{
glfwTerminate();
return NULL;
}
glfwSetWindowSizeCallback(window, __window_callback);
glfwSetMouseButtonCallback((GLFWwindow*)window, __mouse_callback);
glfwSetScrollCallback((GLFWwindow*)window, __scroll_callback);
glfwMakeContextCurrent((GLFWwindow *)(window));
__window_callback( window, w, h );
glfwSetWindowSizeCallback((GLFWwindow *)window, __window_callback_input);
glfwSetMouseButtonCallback((GLFWwindow *)window, __mouse_callback_input);
glfwSetScrollCallback((GLFWwindow *)window, __scroll_callback_input);
glfwSetKeyCallback((GLFWwindow *)window, __key_callback_input);
__window_callback_input((GLFWwindow *)window, width, height);
return window;
}
void use_window(window_t window)
{
glfwMakeContextCurrent((void*)window);
}
void use_window(window_t window) { glfwMakeContextCurrent((void *)window); }
int is_open_window(window_t window)
{
glfwSwapBuffers((void *)window);
glfwPollEvents();
__limit_fps_window(60);
return !glfwWindowShouldClose((void *)window);
}
void close_window(window_t window)
{
glfwDestroyWindow((void*)window);
glfwDestroyWindow((GLFWwindow *)window);
glfwTerminate();
}