0.1 Graph cube

This commit is contained in:
PedroEdiaz
2024-09-04 22:35:31 +00:00
commit cce685d90c
12 changed files with 675 additions and 0 deletions

268
doc/DESIGN.ms Normal file
View File

@@ -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.

14
doc/Makefile Normal file
View File

@@ -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 > $@

31
src/Makefile Normal file
View File

@@ -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)

13
src/color.c Normal file
View File

@@ -0,0 +1,13 @@
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#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 );
}

32
src/data/cube.h Normal file
View File

@@ -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
};

23
src/data/shaders.h Normal file
View File

@@ -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 );"
"}";

60
src/main.c Normal file
View File

@@ -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;
}

40
src/main.h Normal file
View File

@@ -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 );

26
src/matrix.c Normal file
View File

@@ -0,0 +1,26 @@
#include "main.h"
#define inline
#include <cglm/cglm.h>
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 );
}

50
src/mesh.c Executable file
View File

@@ -0,0 +1,50 @@
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <stdlib.h>
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 );
}

67
src/shader.c Normal file
View File

@@ -0,0 +1,67 @@
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#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 );
}

51
src/window.c Normal file
View File

@@ -0,0 +1,51 @@
#include <GLFW/glfw3.h>
#include "main.h"
void window_callback( GLFWwindow * window, int w, int h )
{
int m = ( w<h )? w: h;
glViewport( (w-m)/2, (h-m)/2, m, m );
}
window_t init_window( unsigned int w, unsigned int h, const char * name )
{
void * window;
if( !glfwInit() )
return NULL;
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
window = glfwCreateWindow( w, h, name, NULL, NULL );
if( !window )
{
glfwTerminate();
return NULL;
}
glfwSetWindowSizeCallback( window, window_callback );
return window;
}
void use_window( window_t window )
{
glfwMakeContextCurrent( (void*)window );
}
int is_open_window( window_t window )
{
glfwSwapBuffers( (void*)window );
glfwPollEvents();
return !glfwWindowShouldClose( (void*)window );
}
void close_window( window_t window )
{
glfwDestroyWindow( (void*)window );
glfwTerminate();
}