diff --git a/Makefile b/Makefile index 2c23c49..02e579d 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ help: @echo "Para ejecturar el programa sin instalarlos se puede usar:" @echo " $(MAKE) run-linux" -src/main.o: src/data/axis.h src/data/cube.h src/data/shaders.h +src/main.o: src/data/axis.h src/data/shaders.h # WINDOWS windows: $(OBJ) glfw.dll @@ -48,8 +48,6 @@ windows: $(OBJ) glfw.dll glfw.dll: $(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/cube.h src/data/axis.h - # LINUX linux-x11: $(OBJ) $(MAKE) BKN=_GLFW_X11 libglfw.so diff --git a/src/context.c b/src/context.c index 32b1f18..f252203 100644 --- a/src/context.c +++ b/src/context.c @@ -1,15 +1,17 @@ #include "main.h" -#include +#include void set_clean_color_context( unsigned char r, unsigned char g, unsigned char b ) { glEnable( GL_DEPTH_TEST ); - glEnable( GL_CULL_FACE ); - glCullFace( GL_BACK ); - glClearColor( (float)r/0xff, (float)g/0xff, (float)b/0xff, 1.0 ); } +int init_context( void ) +{ + return glewInit() == GLEW_OK; +} + void clean_context( void ) { glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); diff --git a/src/data/cube.h b/src/data/cube.h deleted file mode 100644 index bfa2756..0000000 --- a/src/data/cube.h +++ /dev/null @@ -1,31 +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, - -float d_cube[] = -{ - 3*3*2*6, - - A C E - G E C - - E G F - H F G - - F H B - D B H - - B D A - C A D - - C D G - H G D - - E B A - B E F -}; diff --git a/src/data/shaders.h b/src/data/shaders.h index 8d8da0c..bec67eb 100644 --- a/src/data/shaders.h +++ b/src/data/shaders.h @@ -62,7 +62,12 @@ const char * fs = " vec3 lightPos = vec3(0,0,-15);" " vec3 lightDir = normalize(lightPos - FragPos);" - " float diffuse = max(dot(Normal, lightDir), 0.0);" +/* + We use the absoulute value, insted of the traditional "max(...,0.0);" + so we can ignore the orientation of the triangles in openGL. +*/ + " float diffuse = abs(dot(Normal, lightDir)); " + " float ambient = 0.5;" " FragColor = (ambient + diffuse)*color;" "}"; diff --git a/src/input.c b/src/input.c index 5b80e03..1956640 100644 --- a/src/input.c +++ b/src/input.c @@ -18,7 +18,7 @@ vec3 axis[3] = {0, 0, 1}, }; -void __key_callback(GLFWwindow * window, int key, int scancode, int action, int mods ) +void __key_callback_input(GLFWwindow * window, int key, int scancode, int action, int mods ) { if( action != GLFW_PRESS) return; @@ -29,7 +29,7 @@ void __key_callback(GLFWwindow * window, int key, int scancode, int action, int } } -void __window_callback(GLFWwindow * window, int w, int h) +void __window_callback_input(GLFWwindow * window, int w, int h) { int m; @@ -40,7 +40,7 @@ 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; @@ -61,7 +61,7 @@ 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; diff --git a/src/main.c b/src/main.c index 47e7f0c..b172d50 100755 --- a/src/main.c +++ b/src/main.c @@ -1,10 +1,8 @@ #include "main.h" #include "data/axis.h" #include "data/shaders.h" -#include -#include -#include +#include #include #define WIDTH 512 @@ -14,7 +12,6 @@ unsigned char coordanate[4] = {0,1,2,3}; unsigned char palette[] = { - 16, 0xEB,0xD3,0xF8,0xff, 0xEB,0xD4,0xF8,0xff, 0xEB,0xD5,0xF8,0xff, @@ -35,8 +32,10 @@ void calc_normal(float* v1, float* v2, float* v3, float* normal) float * fill_normal( float * d ) { float * n; - n = malloc( (*d+1)*sizeof(float)); + + n = malloc((*d+1)*sizeof(float)); *n = *d; + for (int i = 0; i < *d; i += 9) { @@ -50,99 +49,116 @@ float * fill_normal( float * d ) } const char * wname = "manigraph: manifold grapher"; -float * generate_surface(); +float * generate_surface(unsigned int, unsigned char *m); int main( void ) { id_t shader, texture, shader_plain; - mesh_t m_cube, m_axis; + mesh_t m_surface, m_axis; window_t window; - if( !( window = init_window( WIDTH, HEIGHT, wname ) ) ) - goto error_window; - - use_window( window ); - set_clean_color_context( 0x2E, 0x07, 0x3F ); - - glewInit(); - - texture=create_palette_texture( palette ); - use_texture( texture ); - - if( !( shader = create_shader() ) ) - goto error_shader; - gload_program( shader, vs, VERTEX ); - gload_program( shader, fs, FRAGMENT ); - - if( !( shader_plain = create_shader() ) ) - goto error_shader_plain; - gload_program( shader_plain, vs, VERTEX ); - gload_program( shader_plain, fs_plain, FRAGMENT ); - - load_fix_matrix( shader, (float)WIDTH/HEIGHT ); - load_fix_matrix( shader_plain, (float)WIDTH/HEIGHT ); - - /* Fill m_cube */ + /* Setup window */ { - float * n_cube, *d_cube; - d_cube = generate_surface(16); - n_cube = fill_normal( d_cube ); - if( !( m_cube = create_mesh( d_cube, n_cube, coordanate ) ) ) - goto error_mesh_cube; - free( n_cube ); - free( d_cube); + if(!(window = init_window(WIDTH, HEIGHT, wname))) + goto error_window; + + use_window(window); + set_clean_color_context(0x2E, 0x07, 0x3F); } - /* Fill m_axis */ + /* Setup context */ + { + if(!(init_context())) + goto error_context; + } + + /* Setup color texture */ + { + texture=create_palette_texture(palette, 4); + use_texture(texture); + } + + /* Setup shader */ + { + if(!(shader = create_shader())) + goto error_shader; + load_program_to_shader(shader, vs, VERTEX); + load_program_to_shader(shader, fs, FRAGMENT); + load_fix_matrix(shader, (float)WIDTH/HEIGHT); + } + + /* Setup shader w/out illumination */ + { + if(!(shader_plain = create_shader())) + goto error_shader_plain; + load_program_to_shader(shader_plain, vs, VERTEX); + load_program_to_shader(shader_plain, fs_plain, FRAGMENT); + load_fix_matrix(shader_plain, (float)WIDTH/HEIGHT); + } + + /* Fill mesh of surface */ + { + unsigned char m; + float * n_surface, *d_surface; + d_surface = generate_surface(16,&m); + n_surface = fill_normal(d_surface); + if( !(m_surface = create_mesh(d_surface, n_surface, coordanate))) + goto error_mesh_surface; + free(n_surface); + free(d_surface); + } + + /* Fill mesh of axis */ { float * n_axis; - n_axis = fill_normal( d_axis ); - if( !( m_axis = create_mesh( d_axis, n_axis, coordanate ) ) ) + n_axis = fill_normal(d_axis); + if(!(m_axis = create_mesh(d_axis, n_axis, coordanate))) goto error_mesh_axis; - free( n_axis ); + free(n_axis); } - while( is_open_window( window ) ) + while(is_open_window(window)) { quat_t q; - q=poll_input( window ); - load_rot_matrix( shader, q ); - load_rot_matrix( shader_plain, q ); + q=poll_input(window); + load_rot_matrix(shader, q); + load_rot_matrix(shader_plain, q); clean_context(); - #ifndef DEBUG - load_mdl_matrix( shader_plain, 0, 0 ); - 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_plain, 0, 0); + 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 - - load_mdl_matrix( shader, 0, 3 ); - draw_mesh( m_cube ); + draw_mesh(m_surface); } - destroy_mesh( m_axis ); - destroy_mesh( m_cube ); - destroy_shader( shader_plain ); - destroy_shader( shader ); - destroy_texture( texture ); - close_window( window ); + destroy_mesh(m_axis); + destroy_mesh(m_surface); + destroy_shader(shader_plain); + destroy_shader(shader); + destroy_texture(texture); + close_window(window); return 0; error_mesh_axis: - destroy_mesh( m_cube ); -error_mesh_cube: - destroy_shader( shader_plain ); + destroy_mesh(m_surface); +error_mesh_surface: + destroy_shader(shader_plain); error_shader_plain: - destroy_shader( shader ); + destroy_shader(shader); error_shader: - close_window( window ); - destroy_texture( texture ); + close_window(window); + destroy_texture(texture); +error_context: error_window: return 1; } diff --git a/src/main.h b/src/main.h index 155af45..d51bc7d 100644 --- a/src/main.h +++ b/src/main.h @@ -1,5 +1,10 @@ -#include -#include +/* + 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,12 +12,12 @@ typedef void * mesh_t; typedef float * quat_t; typedef float * mat4_t; -typedef unsigned char narray_u8_t[]; - -enum -{ - VERTEX, FRAGMENT -}; +/* + 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); @@ -22,32 +27,90 @@ int is_open_window(window_t window); void close_window(window_t window); +/* + Create mesh: + d: array of floats with the vertex data. + n: array of floats with the normal data. + coordanate: the number of the 3 axis that we are displaying. +*/ + mesh_t create_mesh( float * d, float * n, unsigned char * coordanate ); void destroy_mesh(mesh_t p); void draw_mesh(mesh_t p); -void set_clean_color_context(unsigned char, unsigned char, unsigned char); +/* + 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); +/* + load float to shader: + var: name of glsl variable. + f: float to load +*/ + +void load_float_to_shader(id_t shader, char * var, float f); + +/* + 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 load_fix_matrix(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. + q: quaterinon describing the rotation. +*/ + void load_rot_matrix(id_t shader, quat_t q); id_t config_texture(unsigned short type); @@ -56,6 +119,11 @@ 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, unsigned char n ); quat_t poll_input(window_t window); diff --git a/src/matrix.c b/src/matrix.c index 10a097a..7cee023 100644 --- a/src/matrix.c +++ b/src/matrix.c @@ -34,18 +34,18 @@ void load_fix_matrix( id_t shader, float ratio ) glm_perspective( CGLM_PI/4, ratio, d-3, d+3, n ); glm_mat4_mul( n, m, m ); - gload_mat4( shader, "fix", (mat4_t) m ); + load_mat4_to_shader( 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] ); + 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 ); - gload_mat4( shader, "rot", (mat4_t)m ); + load_mat4_to_shader( shader, "rot", (mat4_t)m ); } diff --git a/src/mesh.c b/src/mesh.c index da44e3b..b16cab5 100755 --- a/src/mesh.c +++ b/src/mesh.c @@ -7,8 +7,15 @@ struct obj unsigned int vertex, vao, n_vbo, d_vbo; }; +/* + In this function we load all the vertex and normal 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( float * d, float * n, unsigned char * coordanate ) { + unsigned char i; struct obj * p; p=malloc(sizeof(struct obj)); @@ -22,27 +29,25 @@ mesh_t create_mesh( float * d, float * n, unsigned char * coordanate ) glBindBuffer( GL_ARRAY_BUFFER, p->d_vbo ); glBufferData( GL_ARRAY_BUFFER, p->vertex*3*sizeof(float), d+1, GL_STATIC_DRAW ); - glVertexAttribPointer( 0,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[0]*sizeof(float)) ); - glEnableVertexAttribArray(0); - glVertexAttribPointer( 1,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[1]*sizeof(float)) ); - glEnableVertexAttribArray(1); - glVertexAttribPointer( 2,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[2]*sizeof(float)) ); - glEnableVertexAttribArray(2); - glVertexAttribPointer( 3,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[3]*sizeof(float)) ); - glEnableVertexAttribArray(3); + + for( i=0; i<4; ++i ) + { + glVertexAttribPointer( i,1,GL_FLOAT, 0, 3*sizeof(float), + (float*)(coordanate[i]*sizeof(float)) ); + glEnableVertexAttribArray(i); + } glGenBuffers( 1, &p->n_vbo ); glBindBuffer( GL_ARRAY_BUFFER, p->n_vbo ); glBufferData( GL_ARRAY_BUFFER, p->vertex*3*sizeof(float), n+1, GL_STATIC_DRAW ); - glVertexAttribPointer( 4,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[0]*sizeof(float)) ); - glEnableVertexAttribArray(4); - glVertexAttribPointer( 5,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[1]*sizeof(float)) ); - glEnableVertexAttribArray(5); - glVertexAttribPointer( 6,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[2]*sizeof(float)) ); - glEnableVertexAttribArray(6); - glVertexAttribPointer( 7,1,GL_FLOAT, 0, 3*sizeof(float), (float*)(coordanate[3]*sizeof(float)) ); - glEnableVertexAttribArray(7); + + for( i=0; i<4; ++i ) + { + glVertexAttribPointer( i+4,1,GL_FLOAT, 0, 3*sizeof(float), + (float*)(coordanate[i]*sizeof(float)) ); + glEnableVertexAttribArray(i+4); + } return p; } diff --git a/src/shader.c b/src/shader.c index f7b8b41..6b267c6 100644 --- a/src/shader.c +++ b/src/shader.c @@ -20,7 +20,7 @@ void use_shader( unsigned int program ) return glUseProgram( program ); } -unsigned char gload_program( unsigned int program, const char * src, +unsigned char load_program_to_shader( unsigned int program, const char * src, unsigned int i ) { int shader, status; @@ -56,13 +56,13 @@ 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 ); diff --git a/src/surface.c b/src/surface.c index 89cec8c..8bac07b 100644 --- a/src/surface.c +++ b/src/surface.c @@ -19,7 +19,7 @@ void mobius(float *d_surface, int i, int j, int grid_size) d_surface[2] = v * sin(u / 2); } -void toro(float *d_surface, int i, int j, int grid_size) +void torus(float *d_surface, int i, int j, int grid_size) { float u = (2*M_PI) * ((float)i/grid_size ); float v = (2*M_PI) * ((float)j/grid_size ); @@ -40,51 +40,39 @@ void klein(float *d_surface, int i, int j, int grid_size) //d_surface[2] = sin(v)*sin(u/2); } -float * generate_surface(int grid_size) +float * generate_surface(int grid_size, unsigned char * m) { - long size = grid_size*grid_size*2*3*3*2; - function_t f = klein; float * d_surface; - int k=0; + function_t f; + int i,j,k=0; + long size; + + *m = 3; + f = klein; + size = grid_size*grid_size*2*3*(*m); d_surface = malloc((size+1)*sizeof(float)); d_surface[0] = size; - for (int i = 0; i < grid_size; i++) + for( i = 0; i < grid_size; i++) { - for (int j = 0; j < grid_size; j++) + for( j = 0; j < grid_size; j++) { - // triangle 1, front + // triangle 1 f(&d_surface[k + 1], i, j, grid_size); - k+=3; + k+=*m; f(&d_surface[k + 1], i + 1, j, grid_size); - k+=3; + k+=*m; f(&d_surface[k + 1], i + 1, j + 1, grid_size); - k+=3; + k+=*m; - // triangle 1, back + // triangle 2 f(&d_surface[k + 1], i + 1, j + 1, grid_size); - k+=3; - f(&d_surface[k + 1], i + 1, j, grid_size); - k+=3; - f(&d_surface[k + 1], i, j, grid_size); - k+=3; - - // triangle 2, font - f(&d_surface[k + 1], i, j, grid_size); - k+=3; + k+=*m; f(&d_surface[k + 1], i, j + 1, grid_size); - k+=3; - f(&d_surface[k + 1], i + 1, j + 1, grid_size); - k+=3; - - // triangle 2, back - f(&d_surface[k + 1], i + 1, j + 1, grid_size); - k+=3; - f(&d_surface[k + 1], i, j + 1, grid_size); - k+=3; + k+=*m; f(&d_surface[k + 1], i, j, grid_size); - k+=3; + k+=*m; } } diff --git a/src/texture.c b/src/texture.c index e32d006..748c60c 100644 --- a/src/texture.c +++ b/src/texture.c @@ -3,7 +3,8 @@ #define TYPE GL_TEXTURE_2D_ARRAY -id_t config_texture( unsigned short type ) +static +id_t __config_texture( unsigned short type ) { id_t texture; @@ -28,10 +29,10 @@ void destroy_texture( unsigned int texture ) return glDeleteTextures( 1, &texture ); } -id_t create_palette_texture( const unsigned char * colors ) +id_t create_palette_texture( const unsigned char * colors, unsigned char n ) { - id_t texture = config_texture( TYPE ); + id_t texture = __config_texture( TYPE ); glTexImage3D( TYPE, 0, GL_RGBA, - 1, 1, (*colors)/4, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors+1); + 1, 1, n, 0, GL_RGBA, GL_UNSIGNED_BYTE, colors); return texture; } diff --git a/src/window.c b/src/window.c index 1ac027a..392729a 100644 --- a/src/window.c +++ b/src/window.c @@ -1,10 +1,10 @@ #include "main.h" #include -void __window_callback(GLFWwindow *, int, int); -void __mouse_callback(GLFWwindow *, int, int, int); -void __scroll_callback(GLFWwindow *, double, double); -void __key_callback(GLFWwindow *, int, int, int, int); +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) { @@ -25,12 +25,12 @@ window_t init_window(unsigned int w, unsigned int h, const char * name) return NULL; } - glfwSetWindowSizeCallback(window, __window_callback); - glfwSetMouseButtonCallback((GLFWwindow*)window, __mouse_callback); - glfwSetScrollCallback((GLFWwindow*)window, __scroll_callback); - glfwSetKeyCallback((GLFWwindow*)window, __key_callback); + glfwSetWindowSizeCallback(window, __window_callback_input); + glfwSetMouseButtonCallback((GLFWwindow*)window, __mouse_callback_input); + glfwSetScrollCallback((GLFWwindow*)window, __scroll_callback_input); + glfwSetKeyCallback((GLFWwindow*)window, __key_callback_input); - __window_callback( window, w, h ); + __window_callback_input( window, w, h ); return window; }