bool picking_sphere_click_event(const struct Camera* camera, size_t n, struct PickingSphere** spheres, SDL_Event event) { log_assert( camera != NULL ); log_assert( spheres != NULL ); log_assert( n < INT32_MAX ); bool clicked = false; if( event.type == SDL_MOUSEBUTTONDOWN && event.button.button == INPUT_MOUSE_PICKING_CLICK ) { SDL_MouseButtonEvent mouse = event.button; Vec4f click_ray; camera_ray(camera, CAMERA_PERSPECTIVE, mouse.x, mouse.y, click_ray); for( size_t i = 0; i < n; i++ ) { struct PickingSphere* sphere = spheres[i]; Vec4f sphere_position; vec_add(sphere->pivot.parent->position, sphere->pivot.position, sphere_position); if( intersect_ray_sphere(camera->pivot.position, click_ray, sphere_position, sphere->radius, &sphere->front, &sphere->back) ) { sphere->picked = true; clicked = true; } } } return clicked; }
/******* Fonction à écrire par les etudiants ******/ void compute_image () { /** * \todo : main rendering loop * * Le calcul d'une image de synthèse consiste à calculer une couleur pour tous les pixels d'une image en fonction * d'une modélisation d'un capteur virtuel. * Ce capteur est ici représenté par une Camera qui permet, à partir des coordonnées (x,y) d'un pixel d'une image, * de créer le rayon passant par ce pixel. La manière dont est créé ce rayon dépend de la Camera. * La scène étant crée avec une caméra par défaut de type \b pinhole, la fonction camera_ray() * devra être utilisée afin de créer le rayon primaire. * Ce rayon est ensuite tracé dans la scène (par la fonction trace_ray()) * et la couleur calculée à l'aide de ce rayon doit être stockée sur le pixel (x,y). */ int i,j, img_height, img_width; Ray ray_; Color col_; get_image_resolution(&img_width, &img_height); for(i=0; i<img_width; i++){ for(j=0; j<img_height; j++){ ray_ = camera_ray(i,j); col_ = trace_ray (ray_); set_pixel_color (i, j, col_); } } }
int main(int argc, char *argv[]) { Uint32 *screen; //This pointer will reference the backbuffer screen = InitVideo(SCREEN_WIDTH, SCREEN_HEIGH); if (screen == nullptr) exit(SCREEN_INIT_ERROR); LightRay camera_ray(Position(0, 0, -3), Direction(0, 0, 1)); World world; Sphere* mov = new Sphere(Position(3, 3, 10), 5, Material::glass()); world.elements.push_back(mov); world.elements.push_back(new Sphere(Position(-3, 3, 10), 5, Material::RedPlastic())); world.elements.push_back(new Sphere(Position(-3, -3, 10), 4, Material::silver())); world.elements.push_back(new Plane()); while (1) { SDL_Event event; while (SDL_PollEvent(&event)) { if (event.type == SDL_MOUSEMOTION) { world.globalLight.direction[0] += 0.01f * (event.motion.xrel); world.globalLight.direction[1] += 0.01f * (event.motion.yrel); } if (event.type == SDL_KEYDOWN) { exit(RETURN_OK); } if (event.type == SDL_QUIT) { exit(RETURN_OK); } } Uint32 t1 = SDL_GetTicks(); mov->translate(Direction(0.f, 0.f, 0.1f * (1 - 2 * (((int) (t1 / 2000.0f)) % 2)))); for (int x = 0; x < SCREEN_WIDTH; x++) for (int y = 0; y < SCREEN_HEIGH; y++) { screenPixelDirection(camera_ray.direction, static_cast<float> (x), static_cast<float> (y)); Light value = world.rayTracing(camera_ray, nullptr); setPixelValue(screen, x, y, lightToPixel(value)); } showImage(screen); printf("time: %1ums\n", SDL_GetTicks() - t1); } freeRenderer(screen); return RETURN_OK; }
int main(int argc, char **argv) { Timer *render_timer; Sdl *sdl; FILE *out; Colour *buffer; Pixel *pixels; int num_pixels; SDL_Event event = {0}; if (argc < 2) return 1; sdl = sdl_load(argv[1]); if (sdl == NULL) return 1; if (!init_SDL()) return 1; num_pixels = config->width * config->height; buffer = calloc(num_pixels, sizeof(Colour)); pixels = calloc(num_pixels, sizeof(Pixel)); for (int j = 0; j < config->height; j++) for (int i = 0; i < config->width; i++) { pixels[j*config->width + i].x = i; pixels[j*config->width + i].y = j; } srand(time(NULL)); shuffle_pixels(pixels, config->width, config->height); srand(0x20071208); /* START */ render_timer = timer_start("Rendering"); for (int i = 0; i < num_pixels; i++) { Camera *cam = scene->camera; Colour c; Ray r; int x = pixels[i].x, y = pixels[i].y; /* The last parameter is the near plane, which is irrelevant for * the moment. */ r = camera_ray(cam, x, y, 1); c = ray_colour(r, 0); buffer[config->width*y + x] = c; put_pixel(display_surface, x, y, c); if (i % config->width == 0) { SDL_Flip(display_surface); while (SDL_PollEvent(&event)) if (event.type == SDL_QUIT) return 0; } } /* STOP */ timer_stop(render_timer); timer_diff_print(render_timer); printf("%.2f kilopixels per second\n", num_pixels/1000./(timer_diff(render_timer))); out = fopen("ray.ppm", "w"); ppm_write(buffer, config->width, config->height, out); free(buffer); fclose(out); SDL_Flip(display_surface); while(1) { while (SDL_WaitEvent(&event)) if (event.type == SDL_QUIT) return 0; else if (event.type == SDL_VIDEOEXPOSE) SDL_Flip(display_surface); } return 0; }
int32_t main(int32_t argc, char *argv[]) { printf("<<watchlist//>>\n"); if( init_sdl2() ) { return 1; } int32_t width = 1280; int32_t height = 720; SDL_Window* window; sdl2_window("cute3d: " __FILE__, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, &window); SDL_GLContext* context; sdl2_glcontext(3, 2, window, &context); if( init_shader() ) { return 1; } if( init_vbo() ) { return 1; } if( init_canvas(1280,720) ) { return 1; } canvas_create("global_dynamic_canvas", &global_dynamic_canvas); canvas_create("global_static_canvas", &global_static_canvas); struct Vbo vbo = {0}; vbo_create(&vbo); vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX, 3, GL_FLOAT, GL_STATIC_DRAW); vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX_NORMAL, 3, GL_FLOAT, GL_STATIC_DRAW); vbo_add_buffer(&vbo, SHADER_ATTRIBUTE_VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_STATIC_DRAW); struct Ibo ibo = {0}; ibo_create(GL_TRIANGLES, GL_UNSIGNED_INT, GL_STATIC_DRAW, &ibo); struct CollisionEntity entity_a = {0}; entity_create("red", (Color){ 255, 0, 0, 255 }, &vbo, &ibo, &entity_a); /* quat_mul_axis_angle(entity_a.pivot.orientation, (Vec4f)UP_AXIS, PI/4, entity_a.pivot.orientation); */ /* quat_mul_axis_angle(entity_a.pivot.orientation, (Vec4f)RIGHT_AXIS, PI/2 + 0.2, entity_a.pivot.orientation); */ vec_add(entity_a.pivot.position, (Vec4f){0.2, 0.15, 0.8, 1.0}, entity_a.pivot.position); struct CollisionEntity entity_b = {0}; entity_create("green", (Color){ 0, 255, 0, 255 }, &vbo, &ibo, &entity_b); quat_mul_axis_angle(entity_b.pivot.orientation, (Vec4f)RIGHT_AXIS, PI/4 - 0.2, entity_b.pivot.orientation); quat_mul_axis_angle(entity_b.pivot.orientation, (Vec4f)UP_AXIS, PI/2 + 0.0, entity_b.pivot.orientation); struct Shader flat_shader = {0}; shader_create(&flat_shader); shader_attach(&flat_shader, GL_VERTEX_SHADER, "prefix.vert", 1, "flat_shading.vert"); shader_attach(&flat_shader, GL_FRAGMENT_SHADER, "prefix.frag", 1, "flat_shading.frag"); shader_make_program(&flat_shader, SHADER_DEFAULT_NAMES, "flat_shader"); Vec4f light_direction = { 0.2, -0.5, -1.0 }; shader_set_uniform_3f(&flat_shader, flat_shader.program, SHADER_UNIFORM_LIGHT_DIRECTION, 3, GL_FLOAT, light_direction); Color ambiance = { 65, 25, 50, 255 }; shader_set_uniform_4f(&flat_shader, flat_shader.program, SHADER_UNIFORM_AMBIENT_LIGHT, 4, GL_UNSIGNED_BYTE, ambiance); struct Arcball arcball = {0}; arcball_create(width, height, (Vec4f){5.0, 3.0, 5.0, 1.0}, (Vec4f){0.0, 0.0, 0.0, 1.0}, 1.0, 1000.0, &arcball); size_t num_entities = 2; struct PickingSphere* picking_spheres[2]; picking_spheres[0] = &entity_a.picking_sphere; picking_spheres[1] = &entity_b.picking_sphere; struct CollisionEntity* picking_entities[2]; picking_entities[0] = &entity_a; picking_entities[1] = &entity_b; struct GameTime time = {0}; gametime_create(1.0f / 60.0f, &time); draw_grid(&global_static_canvas, 0, (Mat)IDENTITY_MAT, (Color){127, 127, 127, 127}, 0.01f, 12.0f, 12.0f, 12); while (true) { SDL_Event event; while( sdl2_poll_event(&event) ) { if( sdl2_handle_quit(event) ) { goto done; } sdl2_handle_resize(event); if( picking_sphere_drag_event(&arcball.camera, num_entities, picking_spheres, event) ) { struct CollisionEntity* selected_entity = NULL; float nearest = -FLT_MIN; for( size_t i = 0; i < num_entities; i++ ) { if( picking_spheres[i]->picked && ( picking_spheres[i]->front < nearest || nearest < 0.0f ) ) { nearest = picking_spheres[i]->front; selected_entity = picking_entities[i]; } } static int32_t last_x = -1; static int32_t last_y = -1; if( selected_entity != NULL ) { if( last_x > -1 && last_y > -1 ) { float distance = selected_entity->picking_sphere.front; Vec4f a = {0}; camera_ray(&arcball.camera, CAMERA_PERSPECTIVE, last_x, last_y, a); vec_mul1f(a, distance, a); Vec4f b = {0}; camera_ray(&arcball.camera, CAMERA_PERSPECTIVE, event.motion.x, event.motion.y, b); vec_mul1f(b, distance, b); Vec4f move = {0}; vec_sub(b, a, move); float length = vec_length(move); move[1] = 0.0f; vec_normalize(move, move); vec_mul1f(move, length, move); vec_add(selected_entity->pivot.position, move, selected_entity->pivot.position); } last_x = event.motion.x; last_y = event.motion.y; } if( event.type == SDL_MOUSEBUTTONUP ) { last_x = -1; last_y = -1; } } else { arcball_handle_resize(&arcball, event); arcball_handle_mouse(&arcball, event); } } sdl2_gl_set_swap_interval(0); gametime_advance(&time, sdl2_time_delta()); ogl_debug( glClearDepth(1.0f); glClearColor(.0f, .0f, .0f, 1.0f); glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); ); Mat projection_mat = {0}; Mat view_mat = {0}; camera_matrices(&arcball.camera, CAMERA_PERSPECTIVE, projection_mat, view_mat); Mat identity = {0}; mat_identity(identity); Mat transform_a = {0}; pivot_world_transform(&entity_a.pivot, transform_a); //vbo_mesh_render(&entity_a.vbo_mesh, &flat_shader, &arcball.camera, transform_a); draw_halfedgemesh_wire(&global_dynamic_canvas, 0, transform_a, (Color){255, 0, 0, 255}, 0.02f, &entity_a.hemesh); Mat transform_b = {0}; pivot_world_transform(&entity_b.pivot, transform_b); //vbo_mesh_render(&entity_b.vbo_mesh, &flat_shader, &arcball.camera, transform_b); draw_halfedgemesh_wire(&global_dynamic_canvas, 0, transform_b, (Color){0, 255, 0, 255}, 0.02f, &entity_b.hemesh); Mat between_transform = {0}; pivot_between_transform(&entity_a.pivot, &entity_b.pivot, between_transform); Vec3f foo = {0}; mat_mul_vec(between_transform, entity_a.hemesh.vertices.array[0].position, foo); struct CollisionConvexConvex collision = {0}; struct CollisionParameter collision_parameter = { .face_tolerance = 0.9, .edge_tolerance = 0.95, .absolute_tolerance = 0.025 }; collision_create_convex_convex(&entity_a.hemesh, &entity_a.pivot, &entity_b.hemesh, &entity_b.pivot, collision_parameter, &collision); if( collision_test_convex_convex(&collision) ) { collision_contact_convex_convex(&collision); //printf("//collision: %d\n", collision_counter); const struct Contacts* contacts = &collision.contacts; VecP* m = contacts->points[contacts->num_contacts-1]; for( int32_t i = 0; i < contacts->num_contacts; i++ ) { VecP* n = contacts->points[i]; draw_line(&global_dynamic_canvas, 0, transform_b, (Color){255, 255, 255, 255}, 0.08f, m, n); m = n; } } gametime_integrate(&time); Vec4f screen_cursor = {0,0,0,1}; text_show_fps(&global_dynamic_canvas, 0, screen_cursor, 0, 0, (Color){255, 255, 255, 255}, 20.0, "default_font", time.frame); canvas_render_layers(&global_static_canvas, 0, 0, &arcball.camera, (Mat)IDENTITY_MAT); canvas_render_layers(&global_dynamic_canvas, 0, 0, &arcball.camera, (Mat)IDENTITY_MAT); canvas_clear(&global_dynamic_canvas); sdl2_gl_swap_window(window); } done: SDL_Quit(); printf("done\n"); return 0; }