diff --git a/assets/shaders/shader.frag b/assets/shaders/shader.frag index 18facea..9df6582 100644 --- a/assets/shaders/shader.frag +++ b/assets/shaders/shader.frag @@ -7,7 +7,7 @@ out vec4 output; void main() { vec4 norm = normalize(frag_normal); - // vec4 ambient = vec4(0.0, 0.2, 0.46, 1.0); + vec4 ambient = vec4(0.7, 0.7788, 0.46, 1.0); vec4 light_color = vec4(0.7, 0.7, 0.7, 1.0); vec4 color = vec4(object_color.xyz, 1.0f); diff --git a/main.c b/main.c index 5825269..b342e39 100644 --- a/main.c +++ b/main.c @@ -1,7 +1,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -9,20 +10,36 @@ #include #include +#define MAX_PATHS 250 + float frand48(void) { - return (float) rand() / (float) (RAND_MAX + 1.0); + float number = (float) rand() / (float) (RAND_MAX + 1.0); + float side = rand() % 2; + if (side == 0) { + number = -number; + } + + return number; } -float fov = 45.0f; // default fov +float fov = 80.0f; // default fov float fov_change = 1.0f; +vec3 camera_pos = { 0.0f, 0.0f, 100.0f, }; +vec3 camera_front = { 0.0f, 0.0f, -1.0f }; +vec3 camera_up = { 0.0f, 1.0f, 0.0f }; +float camera_yaw; // x rotation +float camera_pitch; // y rotation +float camera_sensitivity = 0.01f; +float movement_speed = 2.0f; +GLint screen_viewport[4]; // viewport: x,y,width,height unsigned int shader_program; unsigned int vertex_shader; unsigned int fragment_shader; // shaders -const char *vertex_shader_location = "assets/shaders/shader.vert"; -const char *fragment_shader_location = "assets/shaders/shader.frag"; +const char *object_vertex_shader_location = "assets/shaders/shader.vert"; +const char *object_fragment_shader_location = "assets/shaders/shader.frag"; // structs struct object { @@ -34,6 +51,11 @@ struct object { float mass; void *next; + float *paths; + int paths_num; + int paths_index; + int paths_max; + float *vertices; unsigned int *indices; float *normals; @@ -41,10 +63,13 @@ struct object { long indices_num; long normals_num; - unsigned int vao; + unsigned int vao; // array object for the actual object unsigned int vbo; // buffer for vertices unsigned int ebo; // buffer for indices unsigned int nbo; // buffer for normals + + unsigned int pvao; // array object for paths + unsigned int pbo; // buffer for paths }; // global objects information @@ -96,7 +121,6 @@ int load_shader(const char *path, unsigned int shader) { return -1; } - // RUD free(ftext); return 0; @@ -168,14 +192,15 @@ int load_shaders() { vertex_shader = glCreateShader(GL_VERTEX_SHADER); fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); - if (load_shader(vertex_shader_location, vertex_shader) == -1) { + if (load_shader(object_vertex_shader_location, vertex_shader) == -1) { return -1; } - if (load_shader(fragment_shader_location, fragment_shader) == -1) { + if (load_shader(object_fragment_shader_location, fragment_shader) == -1) { return -1; } + // compile object shader program glAttachShader(shader_program, vertex_shader); glAttachShader(shader_program, fragment_shader); glLinkProgram(shader_program); @@ -190,7 +215,7 @@ int load_shaders() { char log[log_length]; glGetProgramInfoLog(shader_program, log_length, NULL, log); - fprintf(stderr, "Shader Compilation Error: %s\n", log); + fprintf(stderr, "[object program] Shader Compilation Error: %s\n", log); return -1; } @@ -235,39 +260,61 @@ void calculate_gravity(struct object *src, struct object *target, vec3 force) { } //force[i] = mass_area * (top_vec[i] / (distance[i] + (1 / (target->mass / mass_area)))); - force[i] = (top_vec[i] / (h2 / (target->position[i] - src->position[i]))); + force[i] = (top_vec[i] / (h2 / (target->position[i] - src->position[i]))) * 4; //force[i] = (top_vec[i] / distance[i]); } } +// records the latest obj position to the path ring +int record_path(struct object *obj) { + if (obj->paths_num <= obj->paths_max) { + obj->paths = (float *) reallocarray(obj->paths, (obj->paths_num+1)*3, sizeof(float)); + } + + if (obj->paths == NULL) { + fprintf(stderr, "Error: failed allocating memory for paths of object\n"); + return -1; + } + + memcpy(obj->paths+(obj->paths_num*3), obj->position, 3*sizeof(float)); + + if (obj->paths_num < obj->paths_max) { + obj->paths_num++; + return 0; + } + + // pop first element + memmove(obj->paths, &obj->paths[3], (obj->paths_num)*3*sizeof(float)); + + return 0; +} + void display() { mat4 view; mat4 projection; - vec3 view_translate = {0.0f, 0.0f, -3.0f}; - GLint viewport[4]; // viewport: x,y,width,height GLint translation_uniform; - GLint rotation_uniform; GLint view_uniform; GLint projection_uniform; GLint color_uniform; glClearColor(0.13f, 0.13f, 0.13f, 0.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glGetIntegerv(GL_VIEWPORT, viewport); + glGetIntegerv(GL_VIEWPORT, screen_viewport); glUseProgram(shader_program); glm_mat4_identity(view); - glm_translate(view, view_translate); + vec3 camera_center; + glm_vec3_add(camera_pos, camera_front, camera_center); + glm_lookat(camera_pos, camera_center, camera_up, view); glm_mat4_identity(projection); - glm_perspective(glm_rad(fov), (float) viewport[2]/(float) viewport[3], 0.01f, 10000.0f, projection); + glm_perspective(glm_rad(fov), (float) screen_viewport[2]/(float) screen_viewport[3], 0.01f, 10000.0f, projection); view_uniform = glGetUniformLocation(shader_program, "view"); projection_uniform = glGetUniformLocation(shader_program, "projection"); translation_uniform = glGetUniformLocation(shader_program, "translation"); - rotation_uniform = glGetUniformLocation(shader_program, "rotation"); glUniformMatrix4fv(view_uniform, 1, GL_FALSE, (float *) view); glUniformMatrix4fv(projection_uniform, 1, GL_FALSE, (float *) projection); @@ -276,7 +323,6 @@ void display() { mat4 translation_matrix; glm_mat4_identity(translation_matrix); - // calculate gravity for (struct object *target = objects; target != NULL; target = target->next) { if (target == obj) { @@ -301,6 +347,12 @@ void display() { } glm_vec4_add(obj->position, obj->translation_force, obj->position); + + // record path + if (record_path(obj) == -1) { + exit(EXIT_FAILURE); + } + glm_translate(translation_matrix, obj->position); glUniformMatrix4fv(translation_uniform, 1, GL_FALSE, (float *) translation_matrix); @@ -308,6 +360,19 @@ void display() { glBindVertexArray(obj->vao); glDrawElements(GL_TRIANGLES, obj->indices_num, GL_UNSIGNED_INT, (void *) 0); + + glBindVertexArray(obj->pvao); + + glBindBuffer(GL_ARRAY_BUFFER, obj->pbo); + glBufferData(GL_ARRAY_BUFFER, obj->paths_num*3*sizeof(float),obj->paths, GL_STATIC_DRAW); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void *) 0); + glEnableVertexAttribArray(0); + + glm_mat4_identity(translation_matrix); + glUniformMatrix4fv(translation_uniform, 1, GL_FALSE, (float *) translation_matrix); + + glDrawArrays(GL_LINE_STRIP, 0, obj->paths_num); } glutSwapBuffers(); @@ -331,6 +396,40 @@ void keyboard(unsigned char key, int x, int y) { fprintf(stdout, "Status: successfully reloaded shaders\n"); break; + case 'a': + case 'A': { + vec3 side_scalar = { movement_speed, movement_speed, movement_speed }; + vec3 camera_side; + glm_cross(camera_front, camera_up, camera_side); + glm_normalize(camera_side); + glm_vec3_mul(camera_side, side_scalar, camera_side); + glm_vec3_sub(camera_pos, camera_side, camera_pos); + break; + } + case 'd': + case 'D': { + vec3 side_scalar = {movement_speed, movement_speed, movement_speed}; + vec3 camera_side; + glm_cross(camera_front, camera_up, camera_side); + glm_normalize(camera_side); + glm_vec3_mul(camera_side, side_scalar, camera_side); + glm_vec3_add(camera_pos, camera_side, camera_pos); + break; + } + case 's': + case 'S': { + vec3 front_scalar = {movement_speed, movement_speed, movement_speed}; + glm_vec3_mul(front_scalar, camera_front, front_scalar); + glm_vec3_sub(camera_pos, front_scalar, camera_pos); + break; + } + case 'w': + case 'W': { + vec3 front_scalar = {movement_speed, movement_speed, movement_speed}; + glm_vec3_mul(front_scalar, camera_front, front_scalar); + glm_vec3_add(camera_pos, front_scalar, camera_pos); + break; + } default: break; } @@ -349,12 +448,48 @@ void mouse(int button, int state, int x, int y) { } } +int warped_pointer = 0; +void mouse_motion(int x, int y) { + if (warped_pointer == 1) { + warped_pointer = 0; + return; + } + + warped_pointer = 1; + glutWarpPointer((screen_viewport[2]/2), screen_viewport[3]/2); + fprintf(stdout, "Position of mouse %d,%d\n", x, y); + float offset_x = (float) (x - (screen_viewport[2]/2)) * camera_sensitivity; + float offset_y = (float) (y - (screen_viewport[3]/2)) * camera_sensitivity; + + camera_yaw += offset_x; + camera_pitch -= offset_y; + + // limit view rotation + if (camera_pitch < -89.9f) { + camera_pitch = -89.9f; + } + if (camera_pitch > 89.9f) { + camera_pitch = 89.9f; + } + + vec3 view_direction; + view_direction[0] = cos(glm_rad(camera_yaw)) * cos(glm_rad(camera_pitch)); + view_direction[1] = sin(glm_rad(camera_pitch)); + view_direction[2] = sin(glm_rad(camera_yaw)) * cos(glm_rad(camera_pitch)); + glm_normalize_to(view_direction, camera_front); +} + void setup() { + // setup default mouse position + glGetIntegerv(GL_VIEWPORT_BIT, screen_viewport); + for (struct object *obj = objects; obj != NULL; obj = obj->next) { glGenVertexArrays(1, &obj->vao); + glGenVertexArrays(1, &obj->pvao); glGenBuffers(1, &obj->vbo); glGenBuffers(1, &obj->ebo); glGenBuffers(1, &obj->nbo); + glGenBuffers(1, &obj->pbo); glBindVertexArray(obj->vao); @@ -401,11 +536,15 @@ struct object *create_object(float mass, const char *model) { new_object->indices = NULL; new_object->normals = NULL; new_object->next = NULL; + new_object->paths = NULL; + new_object->paths_num = 0; + new_object->paths_index = 0; + new_object->paths_max = MAX_PATHS; glm_vec3_one(new_object->color); // choose random color for (int i = 0; i < 3; i++) { - new_object->color[i] = frand48(); + new_object->color[i] = 0.5 + (fabs(frand48()) / 2); fprintf(stdout, "New color part set: %f\n", new_object->color[i]); } @@ -444,6 +583,7 @@ int main(int argc, char **argv) { glutKeyboardFunc(&keyboard); glutMouseFunc(&mouse); + glutPassiveMotionFunc(&mouse_motion); glutDisplayFunc(&display); if (load_shaders() != 0) { @@ -452,55 +592,34 @@ int main(int argc, char **argv) { } // objects - /*for (int i = 0; i < 100; i++) { - struct object *planet = create_object(rand()%100, "assets/models/sphere.obj"); + struct object *a = create_object(1000.0f, "assets/models/sphere.obj"); + struct object *c = create_object(10000000.0f, "assets/models/sphere.obj"); + struct object *d = create_object(100000.0f, "assets/models/sphere.obj"); + struct object *e = create_object(6969699.0f, "assets/models/sphere.obj"); + float distance = -200.0f; - int x_limit = 50; - int y_limit = 50; - float random_x = (float) -x_limit+(rand() % (x_limit*2)); - float random_y = (float) -y_limit+(rand() % (y_limit*2)); - - // give random force as well - vec3 initial_boost; - glm_vec3_zero(initial_boost); - - for (int j = 0; j < 3; j++) { - initial_boost[j] = 1/(rand() % 2); - } - - vec4 planet_position = {random_x, random_y, (float) -1000.0f, 0.0f}; - glm_vec4_add(planet->position, planet_position, planet->position); - glm_vec3_add(planet->translation_force, initial_boost, planet->translation_force); - }*/ - float distance = -1000.0f; - struct object *a = create_object(1000000000.0f, "assets/models/sphere.obj"); - struct object *b = create_object(10000000.0f, "assets/models/sphere.obj"); -// struct object *c = create_object(1000000000.0f, "assets/models/sphere.obj"); - //struct object *d = create_object(10.0f, "assets/models/sphere.obj"); - - vec4 a_pos = {0.0f, 0.0f, distance, 0.0f}; + vec4 a_pos = {0.0f, 50.0f, distance, 0.0f}; glm_vec4_add(a->position, a_pos, a->position); - vec4 b_pos = {50.0f, -50.0f, distance, 0.0f}; - glm_vec4_add(b->position, b_pos, b->position); + vec4 c_pos = {0.0f, -20.0f, distance, 0.0f}; + glm_vec4_add(c->position, c_pos, c->position); -// vec4 c_pos = {0.0f, -20.0f, distance, 0.0f}; -// glm_vec4_add(c->position, c_pos, c->position); + vec4 d_pos = {20.0f, -100.0f, distance, 0.0f}; + glm_vec4_add(d->position, d_pos, d->position); - //vec4 d_pos = {0.0f, 20.0f, distance, 0.0f}; - //glm_vec4_add(d->position, d_pos, d->position); + vec4 e_pos = {-50.0f, 100.0f, distance, 0.0f}; + glm_vec4_add(e->position, e_pos, e->position); - //struct object *cube = create_object(1000.0f, "assets/models/kub.obj"); - //vec4 cube_location = {-2.0f, 0.0f, -10.0f, 0.0f}; - //glm_vec4_add(cube->position, cube_location, cube->position); + float n = 0.05f; - float n = 0.1f; + vec3 a_boost = {-10*n, 0.0f, 0.0f}; + glm_vec3_add(a->translation_force, a_boost, a->translation_force); - //vec3 a_boost = {10*n, 0.0f, 0.0f}; - //glm_vec3_add(a->translation_force, a_boost, a->translation_force); + vec3 d_boost = {-2*n, -5*n, 0.0f}; + glm_vec3_add(d->translation_force, d_boost, d->translation_force); - vec3 b_boost = {-100*n, 0.0f, 0.0f}; - glm_vec3_add(b->translation_force, b_boost, b->translation_force); + vec3 e_boost = {5*n, 5*n, 0.0f}; + glm_vec3_add(e->translation_force, e_boost, e->translation_force); setup();