From cce685d90c3c4abaa6effe291def4d2c42bb6db2 Mon Sep 17 00:00:00 2001 From: PedroEdiaz Date: Wed, 4 Sep 2024 22:35:31 +0000 Subject: [PATCH] 0.1 Graph cube --- doc/DESIGN.ms | 268 +++++++++++++++++++++++++++++++++++++++++++++ doc/Makefile | 14 +++ src/Makefile | 31 ++++++ src/color.c | 13 +++ src/data/cube.h | 32 ++++++ src/data/shaders.h | 23 ++++ src/main.c | 60 ++++++++++ src/main.h | 40 +++++++ src/matrix.c | 26 +++++ src/mesh.c | 50 +++++++++ src/shader.c | 67 ++++++++++++ src/window.c | 51 +++++++++ 12 files changed, 675 insertions(+) create mode 100644 doc/DESIGN.ms create mode 100644 doc/Makefile create mode 100644 src/Makefile create mode 100644 src/color.c create mode 100644 src/data/cube.h create mode 100644 src/data/shaders.h create mode 100644 src/main.c create mode 100644 src/main.h create mode 100644 src/matrix.c create mode 100755 src/mesh.c create mode 100644 src/shader.c create mode 100644 src/window.c diff --git a/doc/DESIGN.ms b/doc/DESIGN.ms new file mode 100644 index 0000000..adbb563 --- /dev/null +++ b/doc/DESIGN.ms @@ -0,0 +1,268 @@ +.TL +manigraph: Manual de Diseno ( ver 1.0 ) +.AU +Diaz Camacho Pedro Emilio + +.SH +Resumen +.PP +manigraph es un graficador de variedades que lee archivos binarios con un forma +to espacial, este viene con un manual explicando como correr el programa, como +interactuar con el programa y las especificaciones del archivo binario. + +.SH +Tabla de contenidos + +.QS + .IP 1 + Tecnologias + .QS + .IP 1 + Lenguajes. + .IP 2 + Librerias. + .QE + .IP 2 + Glosario + .IP 3 + Archivos + .QS + .IP 1 + Ejecutable + .IP 2 + Ejemplo + .IP 3 + Manual + .QE + .IP 4 + Objetivos + .QS + .IP 1 + Prioridad Alta + .IP 2 + Prioridad Media + .IP 3 + Prioridad Baja + .QE + .IP 5 + Camino + .IP 6 + Problemas +.QE + +.NH +Tecnologias +.NH 2 +Lenguajes: +.QS + .IP \(bu + C89 +.QE + +.NH 2 +Librerias: +.QS + .IP \(bu + OpenGL + .IP \(bu + GLFW + .IP \(bu + cglm +.QE + +.NH +Glosario +.IP variedad +Llamaremos variedad al archivo binario con la informacion para graficar +la variedad matematica. + +.NH +Archivos +.QS + .IP \(bu + Ejecutable. + .IP \(bu + Ejemplo. + .QS + .IP \(bu + Una libreria tipo STB, con las funciones para hacer variedades con una + funcion parametrizadora. + .IP \(bu + LA PARAMETRIZACION DEBE SER CONTINUA. + .IP \(bu + El codigo fuente de un programa que cree la variedad de una botella + de klein usando esta libreria. + .QE + .IP \(bu + Manual + .QS + .IP \(bu + Explicando como correr el programa desde la terminal. + .IP \(bu + Explicando como interactuar con el programa con el teclado y mouse. + .IP \(bu + Explicando el formato binario de las variedaedes. + .IP \(bu + Explicando la libreria STB. + .QE +.QE + +.NH +Objetivos +.NH 2 +Prioridad alta +.QS + .IP _ + El programa debe actualizarse cuando interactuan con el. + .IP _ + El usuario quiere: + .QS + .IP _ + Ver 3 ejes en todo momento. + .IP _ + Ver que ejes esta viendo. + .IP _ + Ver cuantos ejes hay. + .QE + .IP _ + El usuario quiere: + .QS + .IP _ + Rotar estos ejes, + .IP _ + Ver donde quedan los ejes despues de la rotados. + .QE + .IP _ + El usuario experimentado quiere ejecutar el programa y pasar la variedad: + .QS + .IP _ + Como argumento del programa. + .IP _ + Desde la entrada standar del programa. + .QE +.QE + +.NH 2 +Prioridad media + +.QS + .IP _ + El usuario quiere: + .QS + .IP _ + Cambiar los ejes que se ven por pares. + .IP _ + Cambiar los ejes donde esta la informacion de los ejes. + .QE + .IP _ + El usuario quiere interactuar con el programa: + .QS + .IP _ + Usando solo el mouse. + .IP _ + Usando solo el teclado. + .QE +.QE + +.NH 2 +Prioridad baja +.QS + .IP _ + El usuario quiere guardar las transformaciones como un archivo GIF. +.QE + +.NH +Camino + +.QS + .IP 0 + Graficadora de un cubo. + .QS + .IP 1 + Se hace un programa que muestre un cubo. + .IP 2 + Se muestran los 3 ejes del cubo + .IP 2 + Se rota el cubo en sus 3 ejes usando el teclado. + .IP 3 + Se rota el cubo en sus 3 ejes usando el mouse. + .IP 4 + Se muestran la etiqueta de los ejes. + .QE + .IP 1 + Formato. + .QS + .IP 1 + Se hace el formato de las variedades. + .IP 2 + Se hace el codigo fuente ejemplo. + .QS + .IP 1 + Libreria STB. + .IP 2 + Codigo fuente para hacer la variedad de la botella de klein. + .QE + .QE + + .IP 2 + Graficadora de variedades + .QS + .IP 1 + Se generaliza el programa para usar este formato. + .IP 2 + Se muestran la informacion de los ejes mostrados y cuantos hay. + .IP 3 + Se pueden cambiar los ejes por pares + .QS + .IP 1 + Usando el mouse. + .IP 2 + Usando el teclado. + .QE + .QE + + .IP 3 + Detalles. + .QS + .IP 1 + Se anima el cambio de eje. + .IP 2 + Se hace el generador de GIF. + .IP 3 + Se puede cambiar el shader + .IP 4 + Documentacion + .QE + +.QE + +.NH +Problemas +.NH 2 +OpenGL esperan objetos tridimensionales, no de n dimensiones. +.PP +Usando glVertexAttribPointer podemos pasar las coordenadas que +queramos de los puntos de las variedades, y con ello usar objetos 3D en +el shader. + +.NH 2 +Rotar ejes por pares en una animacion continua. +.PP +.QS + .IP 1 + Con glVertexAttribPointer podemos pasar las coordenadas del eje + seleccionado, al shader. + .IP 2 + Con la funcion mix del shader y bloqueando el input, podemos hacer + una animacion pasando una variable con la cpu. + .IP 3 + Cuando la animacion termine intercambiar los indices del layout, + usando glVertexAttribPointer otra vez. +.QE + +.NH 2 +Volumen de la variedad. +.PP +Dado que la funcion parametrizadora es continua, mandamos la frontera +de un n-cubo a la frontera de una variedad, por lo que solo basta +graficar la frontera de la variedad. diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..95d820b --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,14 @@ +OBJ = \ + DESIGN.pdf + +all: $(OBJ) + +clean: + rm $(OBJ) + +.SUFFIXES: .ms .pdf + +.ms.pdf: + cat $< | sed -e "s/^\s*//g" -e "/^$$/d" | groff -Tpdf -fC -ms > $@ + + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..f0d74bb --- /dev/null +++ b/src/Makefile @@ -0,0 +1,31 @@ +BIN = ./manigraph +LIBGLFW=./libglfw.so + +LIB= $(LIBGLFW) + +OBJ = \ + window.o \ + matrix.o \ + shader.o \ + color.o \ + mesh.o \ + main.o + +CFLAGS= \ + -I../ext/cglm/include \ + -I../ext/glfw/include \ + -Wall -Wno-unused-function -std=c89 + + +$(BIN): $(OBJ) $(LIB) + $(CC) -lGL -lglfw -L. -o $(BIN) $(OBJ) + + +$(LIBGLFW): + $(CC) -fPIC -shared -D_GLFW_X11 -D_GLFW_BUILD_DLL ../ext/glfw/src/*.c -o $@ + +run: + LD_LIBRARY_PATH=. $(BIN) + +clean: + rm $(BIN) $(OBJ) $(LIB) diff --git a/src/color.c b/src/color.c new file mode 100644 index 0000000..bc94e86 --- /dev/null +++ b/src/color.c @@ -0,0 +1,13 @@ +#define GL_GLEXT_PROTOTYPES +#include +#include "main.h" + +void set_color( unsigned char r, unsigned char g, unsigned char b ) +{ + glClearColor( (float)r/0xff, (float)g/0xff, (float)b/0xff, 1.0 ); +} + +void draw_color( void ) +{ + glClear( GL_COLOR_BUFFER_BIT ); +} diff --git a/src/data/cube.h b/src/data/cube.h new file mode 100644 index 0000000..8290e04 --- /dev/null +++ b/src/data/cube.h @@ -0,0 +1,32 @@ +#define A -1,-1,-1,0, +#define B -1,-1, 1,0, +#define C -1, 1,-1,0, +#define D -1, 1, 1,0, +#define E 1,-1,-1,0, +#define F 1,-1, 1,0, +#define G 1, 1,-1,0, +#define H 1, 1, 1,0, + +int cube[] = +{ + 4*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 + +}; diff --git a/src/data/shaders.h b/src/data/shaders.h new file mode 100644 index 0000000..652896b --- /dev/null +++ b/src/data/shaders.h @@ -0,0 +1,23 @@ +const char * vs = + "#version 330 core\n" + + "layout (location = 0) in vec3 aPos;" + + "uniform mat4 cam;" + "uniform mat4 pry;" + "uniform mat4 rotx;" + "uniform mat4 roty;" + "uniform mat4 rotz;" + + "void main()" + "{" + " gl_Position = pry * cam * rotx * roty * rotz * vec4( aPos, 1.0 );\n" + "}"; + +const char * fs = + "#version 330 core\n" + "out vec4 FragColor;" + "void main()" + "{" + " FragColor = vec4( 1.0, 0.5, 0.2, 1.0 );" + "}"; diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..c9beb3e --- /dev/null +++ b/src/main.c @@ -0,0 +1,60 @@ +#include "main.h" +#include "data/cube.h" +#include "data/shaders.h" + +#define WIDTH 512 +#define HEIGHT 512 + +const char * wname = "manigraph: manifold grapher"; + +int main( void ) +{ + unsigned char rot[3] = {0,0,0}; + + int shader; + void * mesh; + window_t window; + + if( !( window = init_window( WIDTH, HEIGHT, wname ) ) ) + goto error_window; + + use_window( window ); + set_color( 51, 76, 76 ); + + 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( !( mesh = create_mesh( cube ) ) ) + goto error_mesh; + + while( is_open_window( window ) ) + { + load_rot_matrix( shader, rot[0], 0 ); + load_rot_matrix( shader, rot[1], 1 ); + load_rot_matrix( shader, rot[2], 2 ); + + ++rot[1]; + + draw_color(); + draw_mesh( mesh ); + } + + destroy_mesh( mesh ); + destroy_shader( shader ); + close_window( window ); + return 0; + + destroy_mesh( mesh ); +error_mesh: + destroy_shader( shader ); +error_shader: + close_window( window ); +error_window: + return 1; +} diff --git a/src/main.h b/src/main.h new file mode 100644 index 0000000..bd2f7da --- /dev/null +++ b/src/main.h @@ -0,0 +1,40 @@ +typedef const void * window_t; + +enum +{ + VERTEX, FRAGMENT +}; + +window_t init_window( unsigned int w, unsigned int h, const char * name ); + +void use_window( window_t window ); + +int is_open_window( window_t window ); + +void close_window( window_t window ); + +void * create_mesh( int * mesh ); + +void destroy_mesh( void * p ); + +void draw_mesh( void * p ); + +void set_color( unsigned char, unsigned char, unsigned char ); + +void draw_color( void ); + +void destroy_shader( unsigned int shader ); + +unsigned int create_shader( void ); + +void use_shader( unsigned int program ); + +unsigned char gload_program( unsigned int program, const char * src, unsigned int type ); + +void gload_float( unsigned int program, char * var, float f ); + +void gload_mat4( unsigned int program, char * var, float * m ); + +void load_fix_matrix( unsigned int shader, float ratio ); + +void load_rot_matrix( unsigned int shader, char angle, unsigned char i ); diff --git a/src/matrix.c b/src/matrix.c new file mode 100644 index 0000000..e412fc3 --- /dev/null +++ b/src/matrix.c @@ -0,0 +1,26 @@ +#include "main.h" +#define inline +#include + +void load_fix_matrix( unsigned int shader, float ratio ) +{ + mat4 m; + + glm_lookat( (vec3){0,0,-5}, (vec3){0,0,0}, (vec3){0,1,0}, m ); + gload_mat4( shader, "cam", (float*)m ); + + glm_perspective( 45.0, ratio, 3, 7, m ); + gload_mat4( shader, "pry", (float*)m ); +} + +void load_rot_matrix( unsigned int shader, char angle, unsigned char i ) +{ + mat4 m; + char * name[] = {"rotx", "roty", "rotz"}; + vec3 axis = {0,0,0}; + + axis[(int)i]=1; + + glm_rotate_make( m, (float)angle/0xff*GLM_PI, axis ); + gload_mat4( shader, name[(int)i], (float*)m ); +} diff --git a/src/mesh.c b/src/mesh.c new file mode 100755 index 0000000..9f97c4c --- /dev/null +++ b/src/mesh.c @@ -0,0 +1,50 @@ +#define GL_GLEXT_PROTOTYPES +#include +#include + +struct obj +{ + unsigned int vertex, vao, vbo; +}; + +void * create_mesh( int * mesh ) +{ + struct obj * p; + + p=malloc(sizeof(struct obj)); + + p->vertex=(*mesh)/4; + + glGenVertexArrays( 1, &p->vao ); + glGenBuffers( 1, &p->vbo ); + + glBindVertexArray( p->vao ); + glBindBuffer( GL_ARRAY_BUFFER, p->vbo ); + glBufferData( GL_ARRAY_BUFFER, (p->vertex*4)*sizeof(int), mesh+1, + GL_STATIC_DRAW ); + + glVertexAttribPointer( 0,3,GL_INT, 0, 4*sizeof(int), NULL ); + glEnableVertexAttribArray(0); + + glVertexAttribPointer( 1,1,GL_INT, 0, 4*sizeof(int), + (void*)(3*sizeof(int)) ); + glEnableVertexAttribArray(1); + return p; +} + +void destroy_mesh( void * p ) +{ + struct obj * obj ; + obj = p; + glDeleteVertexArrays( 1, &obj->vao ); + glDeleteBuffers( 1, &obj->vbo ); + free( p ); +} + +void draw_mesh( void * p ) +{ + struct obj * obj=p; + + glBindVertexArray( obj->vao ); + glDrawArrays(GL_TRIANGLES, 0, obj->vertex ); +} diff --git a/src/shader.c b/src/shader.c new file mode 100644 index 0000000..b68d330 --- /dev/null +++ b/src/shader.c @@ -0,0 +1,67 @@ +#define GL_GLEXT_PROTOTYPES +#include +#include "main.h" + +#define NULL ((void*)0) + +void destroy_shader( unsigned int shader ) +{ + return glDeleteProgram( shader ); +} + +unsigned int create_shader( void ) +{ + return glCreateProgram(); +} + +void use_shader( unsigned int program ) +{ + return glUseProgram( program ); +} + +unsigned char gload_program( unsigned int program, const char * src, + unsigned int i ) +{ + int shader, status; + unsigned int type[] = + { + [VERTEX]=GL_VERTEX_SHADER, + [FRAGMENT]=GL_FRAGMENT_SHADER + }; + + + if( !src ) + return 0; + + shader = glCreateShader(type[i]); + glShaderSource( shader, 1, (const GLchar **)&src, NULL); + glCompileShader(shader); + glGetShaderiv( shader, GL_COMPILE_STATUS, &status ); + + + if( !status ) + { +#ifdef DEBUG + char log[256]; + glGetShaderInfoLog( shader, 256, NULL, log ); +#endif + return 0; + } + + glAttachShader(program, shader); + glDeleteShader(shader); + glLinkProgram(program); + return 1; +} + +void gload_float( unsigned int program, char * var, float f ) +{ + glUseProgram( program ); + glUniform1f( glGetUniformLocation( program, var ), f ); +} + +void gload_mat4( unsigned int program, char * var, float * mat ) +{ + glUseProgram( program ); + glUniformMatrix4fv( glGetUniformLocation( program, var ), 1, 0, mat ); +} diff --git a/src/window.c b/src/window.c new file mode 100644 index 0000000..44c70a1 --- /dev/null +++ b/src/window.c @@ -0,0 +1,51 @@ +#include +#include "main.h" + +void window_callback( GLFWwindow * window, int w, int h ) +{ + int m = ( w