float ai_wall_distance(Vector2 p, DArray geometry) { Segment* segments = DARRAY_DATA_PTR(geometry, Segment); float distance = 10000.0f; for(uint i = 0; i < geometry.size; ++i) { Segment seg = {segments[i].p2, segments[i].p1}; for(uint j = 0; j < 4; ++j) { float wraparound_d; Segment wraparound_seg = segment( vec2_add(seg.p1, wraparound_offsets[j]), vec2_add(seg.p2, wraparound_offsets[j])); wraparound_d = segment_point_dist(wraparound_seg, p); if(wraparound_d > 0.0f && wraparound_d < fabsf(distance)) distance = wraparound_d; } float d = segment_point_dist(seg, p); if(fabsf(d) < fabsf(distance)) distance = d; else if(distance < 0.0f && d > 0.0f && feql((fabsf(distance)), d)) distance = d; } return distance > 0.0f ? distance : 0.0f; }
void render_animated(vec3 color, vec2 offset, vec2 size, animation_state * animation){ UNUSED(size); u64 tex = get_animation_texture(animation->animation); if(tex == 0) return; animation_frame * frame = NULL; u64 * key = NULL; get_refs2_animation_frames(&animation->animation, &frame, &key, 1); if(frame == NULL || key == NULL) return; ASSERT(key[animation->frame] == animation->animation); while(animation->time > frame[animation->frame].time){ animation->time -= frame[animation->frame].time; animation->frame += 1; if(key[animation->frame] != animation->animation) animation->frame = 0; } texture_section sec[20]; u64 idx = 0; iter_texture_sections(tex, sec, 20, &idx); u64 ts = frame[animation->frame].section; i32 gltex = get_animation_gltexture(tex); vec2 render_size = vec2_scale(sec[ts].pixel_size, 3); vec2 center = vec2_add(offset, vec2_scale(size, 0.5)); vec2 offset2 = vec2_sub(center, vec2_scale(render_size, 0.5)); rect_render2(color, vec2_add(offset2, sec[ts].render_offset), render_size , gltex, sec[ts].uv_offset, sec[ts].uv_size); }
static bool powerup_help_render(float t) { if(t != 0.0f) game_update_empty(); UIElement* element = uidesc_get("powerup_help"); UIElement* text_elem2 = uidesc_get_child(element, "text2"); UIElement* text_elem3 = uidesc_get_child(element, "text3"); UIElement* star = uidesc_get_child(element, "star"); UIElement* item = uidesc_get_child(element, "item"); UIElement* button_quit = uidesc_get_child(element, "button_quit"); float state_alpha = 1.0f-fabsf(t); byte a = lrintf(255.0f * state_alpha); Color col = COLOR_RGBA(255, 255, 255, a); spr_draw("blue_shade", hud_layer-1, rectf(0.0f, 0.0f, v_width, v_height), col); static float xpos = 0.0f; static float inc = 600.0f; xpos = hud_scroll(xpos, inc, item_count, t); for(uint i = 0; i < item_count; ++i) { Vector2 off = vec2(xpos + i * inc, 0.0f); float d = normalize(fabsf(off.x), 0.0f, inc * (item_count-1)); float scroll_alpha = 1.0f / exp(PI*d); byte a2 = lrintf(255.0f * scroll_alpha * state_alpha); Color col2 = COLOR_RGBA(255, 255, 255, a2); // Star spr_draw_cntr_h(star->spr, hud_layer, vec2_add(off, star->vec2), time_s()/10.0f, 1.0f, col2); // Item const char* item_img = powerup_params[i].unlocked_spr; spr_draw_cntr(item_img, hud_layer, vec2_add(off, item->vec2), 0.0f, 1.0f, col2); // Description text const char* text3 = powerup_params[i].description; vfont_select(FONT_NAME, 32.0f); Vector2 half_size3 = vec2_scale(vfont_size(text3), 0.5f); vfont_draw(text3, hud_layer+1, vec2_add(off, vec2_sub(text_elem3->vec2,half_size3)), col2); // Item name const char* text2 = powerup_params[i].name; vfont_select(FONT_NAME, 48.0f); Vector2 half_size2 = vec2_scale(vfont_size(text2), 0.5f); vfont_draw(text2, hud_layer+1, vec2_add(off, vec2_sub(text_elem2->vec2,half_size2)), col2); } // Quit button if(hud_button(button_quit, col, t)) { malka_states_pop(); } return true; }
static void collision_detection_coins() { /* We simply check if the player intersects with the coins */ character* main_char = entity_get("main_char"); vec2 top_left = vec2_add(main_char->position, vec2_new(-TILE_SIZE, -TILE_SIZE)); vec2 bottom_right = vec2_add(main_char->position, vec2_new(TILE_SIZE, TILE_SIZE)); /* Again we collect pointers to all the coin type entities */ int num_coins = 0; coin* coins[COIN_COUNT]; entities_get(coins, &num_coins, coin); for(int i = 0; i < num_coins; i++) { /* Check if they are within the main char bounding box */ if ((coins[i]->position.x > top_left.x) && (coins[i]->position.x < bottom_right.x) && (coins[i]->position.y > top_left.y) && (coins[i]->position.y < bottom_right.y)) { /* Remove them from the entity manager and delete */ char* coin_name = entity_name(coins[i]); entity_delete(coin_name); /* Play a nice twinkle sound */ audio_sound_play(asset_get_as(P("./sounds/coin.wav"), sound), 0); /* Add some score! */ level_score += 10; /* Update the ui text */ ui_button* score = ui_elem_get("score"); sprintf(score->label->string, "Score %06i", level_score); ui_text_draw(score->label); } } ui_button* victory = ui_elem_get("victory"); /* if all the coins are gone and the victory rectangle isn't disaplayed then show it */ if ((entity_type_count(coin) == 0) && (!victory->active)) { ui_button* victory = ui_elem_get("victory"); ui_button* new_game = ui_elem_get("new_game"); victory->active = true; new_game->active = true; } }
Segment ai_shortest_path(Vector2 p1, Vector2 p2) { uint id = 5; float min_d = 10000000.0f; float d_sqr; for(uint i = 0; i < 5; ++i) { Vector2 wrap_p = vec2_add(p2, wraparound_offsets[i]); d_sqr = vec2_length_sq(vec2_sub(p1, wrap_p)); if(d_sqr < min_d) { min_d = d_sqr; id = i; } } return segment(p1, vec2_add(p2, wraparound_offsets[id])); }
static int _llfunc_vec2_add(lua_State *L) { vec2 *a = (vec2*)userdata_get_or_die(L, 1); vec2 *b = (vec2*)userdata_get_or_die(L, 2); vec2 *r = (vec2*)userdata_get_or_new(L, 3, sizeof(vec2)); vec2_add(a, b, r); return 1; }
static void _control_camera(Game* G, float delta_time) { if(G->num_points == 1) { Vec2 curr = G->points[0].pos; Vec2 delta = vec2_sub(curr, G->prev_single); /* L-R rotation */ Quaternion q = quat_from_axis_anglef(0, 1, 0, delta_time*delta.x*0.2f); G->camera.orientation = quat_multiply(G->camera.orientation, q); /* U-D rotation */ q = quat_from_axis_anglef(1, 0, 0, delta_time*delta.y*0.2f); G->camera.orientation = quat_multiply(q, G->camera.orientation); G->prev_single = curr; } else if(G->num_points == 2) { float camera_speed = 0.1f; Vec3 look = quat_get_z_axis(G->camera.orientation); Vec3 right = quat_get_x_axis(G->camera.orientation); Vec2 avg = vec2_add(G->points[0].pos, G->points[1].pos); Vec2 delta; avg = vec2_mul_scalar(avg, 0.5f); delta = vec2_sub(avg, G->prev_double); look = vec3_mul_scalar(look, -delta.y*camera_speed); right = vec3_mul_scalar(right, delta.x*camera_speed); G->camera.position = vec3_add(G->camera.position, look); G->camera.position = vec3_add(G->camera.position, right); G->prev_double = avg; } }
bool ai_split_path(Segment path, Segment* out_p1, Segment* out_p2) { assert(out_p1); assert(out_p2); for(uint i = 0; i < 4; ++i) { Vector2 middle; if(segment_intersect(path, bounds[i], &middle)) { *out_p1 = segment(path.p1, middle); Vector2 off = wraparound_offsets[i]; *out_p2 = segment(vec2_add(middle, off), vec2_add(path.p2, off)); return true; } } *out_p1 = path; return false; }
static struct AABB aabb_from_transform(vec2 center, vec2 size) { vec2 half_size = vec2_div(size, 2.0f); struct AABB aabb; aabb.min = vec2_sub(center, half_size); aabb.max = vec2_add(center, half_size); return aabb; }
static float perlin_noise2D(vec2 v) { vec2 amount = vec2_fmod(v,1.0); vec2 p1 = vec2_floor(v); vec2 p2 = vec2_add(p1, vec2_new(1,0) ); vec2 p3 = vec2_add(p1, vec2_new(0,1) ); vec2 p4 = vec2_add(p1, vec2_new(1,1) ); int h1 = vec2_mix_hash(p1); int h2 = vec2_mix_hash(p2); int h3 = vec2_mix_hash(p3); int h4 = vec2_mix_hash(p4); double result = bismootherstep_interp(h2, h1, h4, h3, amount.x, amount.y); return result / INT_MAX; }
static void _gen_ground(void){ SprHandle spr; int advance = 0; static float ground_x = 0; while(ground_x < page_width) { char sym = mchains_next(ground_chain, &rnd); mchains_symbol_info(ground_chain, sym, &advance, &spr); Vector2 pos = vec2(fg_page_cursor + ground_x, v_height); if(spr) { advance = (uint) sprsheet_get_size_h(spr).x; // no collision for grass_start1 and grass_end2 if(sym == 'a' || sym == 'h'){ objects_create(&obj_fg_deco_desc, pos, (void*)spr); objects_create(&obj_fall_trigger_desc, vec2_add(pos,vec2(0.0f,127.0f)), (void*)advance); } else { objects_create(&obj_ground_desc, pos, (void*)spr); //water speed trigger if( sym == 'j' || sym == 'k' || sym == 'l' || sym == 'm' || sym == 'n' || sym == 'o'){ ObjSpeedTrigger* t = (ObjSpeedTrigger*)objects_create(&obj_speed_trigger_desc, pos, (void*)spr); t->drag_coef = 1.9f; } } } else { spr = empty_spr; if(sym == '_' || sym == '-' || sym == '='){ // Fall trigger objects_create(&obj_fall_trigger_desc, pos, (void*)advance); // Coin arc over gap if(!tutorial_level){ for(uint i = 0; i < 5; ++i) { float x = pos.x + advance * (-0.3f + i * 0.4f); int d = MIN(i, 4 - i); float y = v_height - 293.0f; if(d) y -= (d+1) * 25.0f; objects_create( &obj_powerup_desc, vec2(x, y), (void*)&coin_powerup ); } } } } placement_interval(vec2(pos.x,pos.x + advance),spr); ground_x += (float)advance; } ground_x -= page_width; }
float _node_distance_sq(Vector2 p1, Vector2 p2) { float result = 10000000.0f; float d_sqr; for(uint i = 0; i < 5; ++i) { Vector2 wrap_p = vec2_add(p2, wraparound_offsets[i]); d_sqr = vec2_length_sq(vec2_sub(p1, wrap_p)); result = MIN(result, d_sqr); } return result; }
mat3 terrain_axis(terrain* ter, vec2 position) { float offset = terrain_height(ter, position); float offset_x = terrain_height(ter, vec2_add(position, vec2_new(1,0))); float offset_y = terrain_height(ter, vec2_add(position, vec2_new(0,1))); vec3 pos = vec3_new(position.x+0, offset, position.y+0); vec3 pos_xv = vec3_new(position.x+1, offset_x, position.y+0); vec3 pos_yv = vec3_new(position.x+0, offset_y, position.y+1); vec3 tangent = vec3_normalize(vec3_sub(pos_xv, pos)); vec3 binorm = vec3_normalize(vec3_sub(pos_yv, pos)); vec3 normal = vec3_cross(binorm, tangent); return mat3_new( tangent.x, tangent.y, tangent.z, normal.x, normal.y, normal.z, binorm.x, binorm.y, binorm.z); }
static bool is_visible(struct GameState *game_state, vec2 start, vec2 end, float edge_padding) { for (uint32 i = 0; i < game_state->building_count; ++i) { struct Building *building = &game_state->buildings[i]; struct AABB aabb = aabb_from_transform(building->position, vec2_add(building->size, vec2_scalar(edge_padding))); if (line_aabb_intersection(aabb, start, end)) return false; } return true; }
int game_update(int mousedx, int mousedy) { const uint8_t* keys = SDL_GetKeyboardState(NULL); double rot = mousedx*PLAYER_ROTSPEED; if (keys[SDL_SCANCODE_LEFT]) rot -= 10*PLAYER_ROTSPEED; if (keys[SDL_SCANCODE_RIGHT]) rot += 10*PLAYER_ROTSPEED; vec2_rotate(&player.dir, rot, &player.dir); vec2_t dir = {0, 0}; double spd = PLAYER_MOVESPEED; if (keys[SDL_SCANCODE_LCTRL]) spd *= .1; if (keys[SDL_SCANCODE_LSHIFT]) spd *= 10.; vec2_t dirCrossed = {player.dir.y, -player.dir.x}; if (keys[SDL_SCANCODE_W] || keys[SDL_SCANCODE_UP]) vec2_add(&dir, &player.dir, &dir); if (keys[SDL_SCANCODE_S] || keys[SDL_SCANCODE_DOWN]) vec2_addScale(&dir, &player.dir, -1, &dir); if (keys[SDL_SCANCODE_A]) vec2_addScale(&dir, &dirCrossed, -1, &dir); if (keys[SDL_SCANCODE_D]) vec2_add(&dir, &dirCrossed, &dir); if (vec2_lengthSq(&dir) > 0.00001) { vec2_normalize(&dir, &dir); camera_t cam = player; cam.dir = dir; raycast_travel(&cam, spd, &m); player.pos = cam.pos; } return keys[SDL_SCANCODE_ESCAPE]; }
int prim_rect_oriented(SDL_Renderer* renderer, Rect* rect, f32 rotation) { Vec2 corners[4]; Vec2 x = vec2_init(cosf(rotation), sinf(rotation)); Vec2 y = vec2_init(-sinf(rotation), cosf(rotation)); vec2_scale(&x, rect->width / 2.f, &x); vec2_scale(&y, rect->height / 2.f, &y); Vec2 center; center.x = rect->position.x + rect->width / 2.f; center.y = rect->position.y + rect->height / 2.f; for (u32 i = 0; i < 4; ++i) { vec2_copy_to(¢er, &corners[i]); } vec2_sub(&corners[0], &x, &corners[0]); vec2_sub(&corners[0], &y, &corners[0]); vec2_add(&corners[1], &x, &corners[1]); vec2_sub(&corners[1], &y, &corners[1]); vec2_add(&corners[2], &x, &corners[2]); vec2_add(&corners[2], &y, &corners[2]); vec2_sub(&corners[3], &x, &corners[3]); vec2_add(&corners[3], &y, &corners[3]); int result = 0; for (u32 i = 0; i < 4; ++i) { Vec2 c1 = corners[i]; Vec2 c2 = (i < 3) ? corners[i + 1] : corners[0]; result |= SDL_RenderDrawLine(renderer, (int)c1.x, (int)c1.y, (int)c2.x, (int)c2.y); } return result; }
static bool move_items(obs_scene_t scene, obs_sceneitem_t item, void *param) { vec2 *offset = reinterpret_cast<vec2*>(param); if (obs_sceneitem_selected(item)) { vec2 pos; obs_sceneitem_getpos(item, &pos); vec2_add(&pos, &pos, offset); obs_sceneitem_setpos(item, &pos); } UNUSED_PARAMETER(scene); return true; }
static void render_widget(AlWidget *widget, Vec2 translate, Box2 scissor) { widget->valid = true; if (!widget->visible) return; Vec2 location = vec2_add(widget->location, translate); Box2 bounds = box2_add_vec2(widget->bounds, location); scissor = box2_round(box2_intersect(scissor, bounds)); if (!box2_is_valid(scissor)) return; if (!widget->passThrough) { set_scissor(scissor); render_widget_main(widget, bounds); if (widget->border.width > 0) { scissor = box2_expand(scissor, -widget->border.width); set_scissor(scissor); } if (widget->model.model) { render_model(widget->model.model, vec2_add(widget->model.location, location), widget->model.scale); } if (widget->text.value) { render_text(widget->text.value, widget->text.colour, vec2_add(widget->text.location, location), widget->text.size); } } FOR_EACH_WIDGET(child, widget) { render_widget(child, location, scissor); }
static bool line_line_intersection(vec2 a0, vec2 a1, vec2 b0, vec2 b1) { #if 1 // Implemented based on http://stackoverflow.com/a/17198094/4354008 vec2 v = vec2_sub(a0, a1); vec2 normal = vec2_new(v.y, -v.x); vec2 v0 = vec2_sub(b0, a0); vec2 v1 = vec2_sub(b1, a0); float proj0 = vec2_dot(v0, normal); float proj1 = vec2_dot(v1, normal); if ((proj0 == 0) || (proj1 == 0)) return true; // TODO: float_sign() if ((proj0 > 0) && (proj1 < 0)) return true; if ((proj0 < 0) && (proj1 > 0)) return true; return false; #else vec2 intersection = vec2_zero(); vec2 b = vec2_sub(a1, a0); vec2 d = vec2_sub(b1, b0); float b_dot_p_perp = (b.x * d.y) - (b.y * d.x); if (b_dot_p_perp == 0) return false; vec2 c = vec2_sub(b0, a0); float t = ((c.x * d.y) - (c.y * d.x)) / b_dot_p_perp; if ((t < 0) || (t > 1)) return false; float u = ((c.x * b.y) - (c.y * b.x)) / b_dot_p_perp; if ((u < 0) || (u > 1)) return false; // TODO: make this an output parameter intersection = vec2_add(a0, vec2_mul(b, t)); return true; #endif }
void add_touch_points(Game* G, int num_touch_points, TouchPoint* points) { int ii; for(ii=0;ii<num_touch_points;++ii) { G->points[G->num_points++] = points[ii]; } if(G->num_points == 1) { G->prev_single = G->points[0].pos; G->tap_timer = 0.0f; } else if(G->num_points == 2) { Vec2 avg = vec2_add(G->points[0].pos, G->points[1].pos); avg = vec2_mul_scalar(avg, 0.5f); G->prev_double = avg; } }
void OBSBasicPreview::MoveItems(const vec2 &pos) { Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers(); OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow()); OBSScene scene = main->GetCurrentScene(); vec2 offset, moveOffset; vec2_sub(&offset, &pos, &startPos); vec2_sub(&moveOffset, &offset, &lastMoveOffset); if (!(modifiers & Qt::ControlModifier)) SnapItemMovement(moveOffset); vec2_add(&lastMoveOffset, &lastMoveOffset, &moveOffset); obs_scene_enum_items(scene, move_items, &moveOffset); }
DArray _gen_edges(DArray points, DArray geometry) { DArray edges = darray_create(sizeof(Edge), 0); Vector2* points_vec2 = DARRAY_DATA_PTR(points, Vector2); for(uint i = 0; i < points.size; ++i) { for(uint j = 0; j < points.size; ++j) { if(i >= j) continue; float sqr_dist = _node_distance_sq(points_vec2[i], points_vec2[j]); if(sqr_dist <= max_edge_distance*max_edge_distance) { Edge n = {i, j}; Segment s = ai_shortest_path(points_vec2[i], points_vec2[j]); Segment s1, s2; bool split = ai_split_path(s, &s1, &s2); // Check for wall intersection Segment* geometry_s = DARRAY_DATA_PTR(geometry, Segment); bool intersects_arena = false; for(uint k = 0; k < geometry.size; ++k) { if(segment_intersect(s1, geometry_s[k], NULL)) { intersects_arena = true; break; } if(split && segment_intersect(s2, geometry_s[k], NULL)) { intersects_arena = true; break; } } // Check distance to walls at midpoint Vector2 midpoint = vec2_scale(vec2_add(s1.p1, s1.p2), 0.5f); if(ai_wall_distance(midpoint, geometry) < min_wall_distance) intersects_arena = true; if(!intersects_arena) darray_append(&edges, (void*)&n); } } } return edges; }
void gravity_system_update(GravitySystem* self) { GET_SYSTEM_COMPONENTS(self); for (u32 i = 0; i < components->count; ++i) { Entity entity = GET_ENTITY(i); GravityComponent* gravity = (GravityComponent*)GET_SYSTEM_COMPONENT(i); MovementComponent* movement = (MovementComponent*)GET_COMPONENT(entity, COMPONENT_MOVEMENT); REQUIRED_COMPONENTS(gravity, movement); Vec2 gravScale; vec2_copy_to(&gravity->gravAccel, &gravScale); vec2_scale(&gravScale, globals.time.delta, &gravScale); vec2_add(&movement->velocity, &gravScale, &movement->velocity); //printf("%f\n", movement->velocity.y); } }
void remove_touch_points(Game* G, int num_touch_points, TouchPoint* points) { int orig_num_points = G->num_points; int ii, jj; for(ii=0;ii<orig_num_points;++ii) { for(jj=0;jj<num_touch_points;++jj) { if(G->points[ii].index == points[jj].index) { /* This is the removed touch, swap it with the end of the list */ G->points[ii] = G->points[--G->num_points]; break; } } } if(G->num_points == 1) { G->prev_single = G->points[0].pos; } else if(G->num_points == 2) { Vec2 avg = vec2_add(G->points[0].pos, G->points[1].pos); avg = vec2_mul_scalar(avg, 0.5f); G->prev_double = avg; } else { if(G->tap_timer < 0.5f) { if(G->prev_single.x < G->width/2) { if(G->prev_single.y < G->height/2) { // Top Left cycle_renderers(G->graphics); } else { // bottom left G->dynamic_lights = !G->dynamic_lights; } } else { if(G->prev_single.y < G->height/2) { // Top right } else { // bottom right } } } } }
// LINEAR BEZIER CURVES // =================================================== // B(t) = (1-t)P_0 + tP_1 void bezier2d_generate_linear ( vec2** pts, unsigned int count, unsigned int destct, vec2*** dest ) { *dest = malloc(sizeof(vec2*)*destct); double t = 0.0; double inc = (double)count/(double)destct; vec2 a, b, c; for(int i = 0, j=0; i < count-1; t += inc, j++) { if (t > 1.0) { t = t - 1.0; i++; } vec2_scale(&a, pts[i], 1.0-t); vec2_scale(&b, pts[i+1], t); vec2_add(&c, &a, &b); *dest[i] = vec2_copy(&c); } }
vec2 ui_rectangle_center(ui_rectangle* r) { return vec2_div(vec2_add(r->top_left, r->bottom_right), 2); }
void scotland_init() { graphics_viewport_set_dimensions(1280, 720); graphics_viewport_set_title("Scotland"); ui_button* loading = ui_elem_new("loading", ui_button); ui_button_move(loading, vec2_new(graphics_viewport_width() / 2 - 40,graphics_viewport_height() / 2 - 13)); ui_button_resize(loading, vec2_new(80,25)); ui_button_set_label(loading, "Loading..."); ui_button_disable(loading); ui_spinner* load_spinner = ui_elem_new("load_spinner", ui_spinner); load_spinner->color = vec4_white(); load_spinner->top_left = vec2_new(graphics_viewport_width() / 2 + 50, graphics_viewport_height() / 2 - 13); load_spinner->bottom_right = vec2_add(load_spinner->top_left, vec2_new(24,24)); ui_button* framerate = ui_elem_new("framerate", ui_button); ui_button_move(framerate, vec2_new(10,10)); ui_button_resize(framerate, vec2_new(30,25)); ui_button_set_label(framerate, "FRAMERATE"); ui_button_disable(framerate); framerate->active = false; ui_button* wireframe = ui_elem_new("wireframe", ui_button); ui_button_move(wireframe, vec2_new(50,10)); ui_button_resize(wireframe, vec2_new(80,25)); ui_button_set_label(wireframe, "wireframe"); wireframe->active = false; ui_elem_add_event("wireframe", toggle_wireframe); ui_button* freecam = ui_elem_new("freecam", ui_button); ui_button_move(freecam, vec2_new(140,10)); ui_button_resize(freecam, vec2_new(65,25)); ui_button_set_label(freecam, "freecam"); freecam->active = false; ui_elem_add_event("freecam", toggle_freecam); loading_resources = true; SDL_Thread* load_thread = SDL_GL_CreateThread(load_resources, NULL); /* New Camera and light */ camera* cam = entity_new("camera", camera); cam->position = vec3_new(512.0, 200.0, 512.0); cam->target = vec3_new(0.0, 0.0, 0.0); light* sun = entity_new("sun", light); light_set_type(sun, light_type_sun); sun->position = vec3_new(0, 512, 0); sun->target = vec3_new(512, 0, 512); /* Renderer Setup */ shadow_mapper_init(sun); forward_renderer_init(); forward_renderer_set_camera(cam); forward_renderer_set_shadow_light(sun); forward_renderer_set_shadow_texture( shadow_mapper_depth_texture() ); forward_renderer_add_light(sun); }
static image* perlin_noise_generate(int x_size, int y_size, int octaves) { unsigned char* data = malloc(sizeof(char) * x_size * y_size); int i, x, y; /* Clear data to average */ for(x = 0; x < x_size; x++) for(y = 0; y < y_size; y++) { data[x + (y * x_size)] = 128; } srand(time(NULL)); debug("Generating perlin noise."); for(i = 0; i < octaves; i++ ) { float wavelength = pow( 2, i); float amplitude = pow( 0.5, octaves-i ); vec2 seed = vec2_new(rand(),rand()); debug("Octave: %i Wavelength: %f Amplitude: %f", i, wavelength, amplitude); for(x = 0; x < x_size; x++) for(y = 0; y < y_size; y++) { /* Four positions are required for tiling behaviour */ vec2 pos, pos_x, pos_y, pos_xy; pos = vec2_div( vec2_new(x, y) , wavelength ); pos_x = vec2_div( vec2_new(x - x_size, y) , wavelength ); pos_y = vec2_div( vec2_new(x, y - y_size) , wavelength ); pos_xy = vec2_div( vec2_new(x - x_size, y - y_size) , wavelength ); pos = vec2_add( pos, seed ); pos_x = vec2_add( pos_x, seed ); pos_y = vec2_add( pos_y, seed ); pos_xy = vec2_add( pos_xy, seed ); float val = perlin_noise2D(pos) * amplitude; float val_x = perlin_noise2D(pos_x) * amplitude; float val_y = perlin_noise2D(pos_y) * amplitude; float val_xy = perlin_noise2D(pos_xy) * amplitude; val = bilinear_interp(val_x, val, val_xy, val_y, (float)x/x_size, (float)y/y_size); data[x + (y * x_size)] += val * 128; } } unsigned char* image_data = malloc(sizeof(char) * 4 * x_size * y_size); for(x = 0; x < x_size; x++) for(y = 0; y < y_size; y++) { int amount = data[x + y * x_size]; image_data[x * 4 + y * x_size * 4 + 0] = amount; image_data[x * 4 + y * x_size * 4 + 1] = amount; image_data[x * 4 + y * x_size * 4 + 2] = amount; image_data[x * 4 + y * x_size * 4 + 3] = 255; } free(data); return image_new(x_size, y_size, image_data); }
static inline void gen_infinity(CPoint* out, float width, float angle, int segment_count) { CPoint path[13]; path[0]=CPointMake(53,23); path[1]=CPointMake(49,31); path[2]=CPointMake(39,47); path[3]=CPointMake(22,47); path[4]=CPointMake(6,47); path[5]=CPointMake(0,31); path[6]=CPointMake(0,23); path[7]=CPointMake(0,16); path[8]=CPointMake(5,0); path[9]=CPointMake(23,0); path[10]=CPointMake(39,0); path[11]=CPointMake(48,15); path[12]=CPointMake(52,21); int offset=0; int seg; for (seg=0; seg<=segment_count; seg++) { float tt = ((float)seg/(float)segment_count)*angle; int q=4; float tstep=1./q; int n = floor(tt/tstep); if (seg >= segment_count) { //n=n-1;//q-1; } //printf("n>%d\n", n); CPoint a = path[0+3*n];; CPoint p1 = path[1+3*n]; CPoint p2 = path[2+3*n]; CPoint b = path[3+3*n]; float t=(tt-tstep*n)*q; float nt = 1.0f - t; vec2 p = {a.x * nt * nt * nt + 3.0 * p1.x * nt * nt * t + 3.0 * p2.x * nt * t * t + b.x * t * t * t, a.y * nt * nt * nt + 3.0 * p1.y * nt * nt * t + 3.0 * p2.y * nt * t * t + b.y * t * t * t }; vec2 tangent = {-3.0 * a.x * nt * nt + 3.0 * p1.x * (1.0 - 4.0 * t + 3.0 * t * t) + 3.0 * p2.x * (2.0 * t - 3.0 * t * t) + 3.0 * b.x * t * t, -3.0 * a.y * nt * nt + 3.0 * p1.y * (1.0 - 4.0 * t + 3.0 * t * t) + 3.0 * p2.y * (2.0 * t - 3.0 * t * t) + 3.0 * b.y * t * t }; vec2 tan_norm = {-tangent[1], tangent[0]}; vec2 norm; vec2_norm(norm, tan_norm); vec2 v; vec2 norm_scaled; vec2_scale(norm_scaled, norm, +width/2.); vec2_add(v, p, norm_scaled); out[offset] = CPointMake(v[0], v[1]); offset++; vec2_scale(norm_scaled, norm, -width/2.); vec2_add(v, p, norm_scaled); out[offset] = CPointMake(v[0], v[1]); offset++; } //printf("infinity_q>%d", offset); }
int main(int argc, char **argv) { #ifdef _WIN32 FILE* ctt = fopen("CON", "w" ); FILE* fout = freopen( "CON", "w", stdout ); FILE* ferr = freopen( "CON", "w", stderr ); #endif corange_init("../../assets_core"); graphics_viewport_set_size(1280, 720); graphics_viewport_set_title("Noise"); folder_load(P("./")); file_load(P("$CORANGE/textures/random.dds")); glClearColor(1.0, 0.0, 0.0, 1.0); ui_button* info_button = ui_elem_new("info_button", ui_button); ui_button_move(info_button, vec2_new(10, 10)); ui_button_resize(info_button, vec2_new(460,25)); ui_button_set_label(info_button, "Procedural texture from perlin noise and feedback functions"); ui_button* save_button = ui_elem_new("save_button", ui_button); ui_button_move(save_button, vec2_new(480, 10)); ui_button_resize(save_button, vec2_new(380,25)); ui_button_set_label(save_button, "Click Here to save tileable perlin noise to file"); ui_button_set_onclick(save_button, save_noise_to_file); ui_button* spinner_box = ui_elem_new("spinner_box", ui_button); ui_button_resize(spinner_box, vec2_new(32, 32)); ui_button_move(spinner_box, vec2_new(870, 7)); ui_button_set_label(spinner_box, ""); ui_spinner* save_spinner = ui_elem_new("save_spinner", ui_spinner); save_spinner->color = vec4_new(1,1,1,0); save_spinner->top_left = vec2_new(874, 11); save_spinner->bottom_right = vec2_add(save_spinner->top_left, vec2_new(24,24)); srand(time(NULL)); shader_time = (float)rand() / (RAND_MAX / 1000); bool running = true; while(running) { frame_begin(); SDL_Event event; while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_KEYDOWN: case SDL_KEYUP: if (event.key.keysym.sym == SDLK_ESCAPE) { running = 0; } if (event.key.keysym.sym == SDLK_PRINTSCREEN) { graphics_viewport_screenshot(); } break; case SDL_QUIT: running = 0; break; break; } ui_event(event); } shader_time += frame_time(); ui_update(); noise_render(); ui_render(); graphics_swap(); frame_end(); } SDL_WaitThread(save_thread, NULL); corange_finish(); return 0; }