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;
    }
}
예제 #2
0
bool _get_touch(const Vector2* pos, float radius, Vector2* touch) {
	assert(pos);

	Touch* touches = touches_get();
	if(touches)
	{
		uint count = touches_count();
		for(uint i = 0; i < count; ++i) {
			if(vec2_length_sq(vec2_sub(*pos, touches[i].pos)) > radius*radius)
				continue;
			
			if(touch)
				*touch = touches[i].pos;
			
			return true;	
		}
	}
	
	if(mouse_pressed(MBTN_LEFT)) {
		uint x, y;
		mouse_pos(&x, &y);
		Vector2 mpos = {(float)x, (float)y};
		if(vec2_length_sq(vec2_sub(*pos, mpos)) <= radius*radius) {
			if(touch)
				*touch = mpos;
			return true;
		}
	}
	
	return false;
}
예제 #3
0
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;
}
예제 #4
0
파일: gesture.c 프로젝트: imeteora/goxel
static float get_angle(const float a0[2], const float a1[2],
                       const float b0[2], const float b1[2])
{
    float u[2], v[2], dot, det;
    vec2_sub(a1, a0, u);
    vec2_normalize(u, u);
    vec2_sub(b1, b0, v);
    vec2_normalize(v, v);
    dot = vec2_dot(u, v);
    det = vec2_cross(u, v);
    return atan2(det, dot);
}
예제 #5
0
float ai_navmesh_distance(NavMesh* navmesh, Vector2 p1, Vector2 p2) {
	assert(navmesh);

	uint navpoint1 = ai_nearest_navpoint(navmesh, p1);
	uint navpoint2 = ai_nearest_navpoint(navmesh, p2);

	float distance = vec2_length(vec2_sub(p1, navmesh->navpoints[navpoint1]));
	distance += vec2_length(vec2_sub(p2, navmesh->navpoints[navpoint2]));

	uint idx = IDX_2D(navpoint1, navpoint2, navmesh->n_nodes);
	distance += navmesh->distance[idx];

	return distance;
}
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);
}
예제 #7
0
파일: ll_math.c 프로젝트: tianye910208/vi3d
static int _llfunc_vec2_sub(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_sub(a, b, r);
	return 1;
}
예제 #8
0
Vector2 touch_joystick(TexHandle tex, uint layer, const RectF* back_src,
	const RectF* nub_src, const Vector2* pos) {
	assert(back_src);
	assert(nub_src);
	assert(pos);

	Color nub_color = COLOR_WHITE;

	float back_width = rectf_width(back_src);
	float back_height = rectf_height(back_src);

	// Draw static back
	RectF dest = {
		pos->x - back_width / 2.0f,
		pos->y - back_height / 2.0f, 
		0.0f, 0.0f
	};
	video_draw_rect(tex, layer, back_src, &dest, COLOR_WHITE);

	Vector2 touch;
	if(!_get_touch(pos, joystick_area_radius, &touch)) {
		touch = vec2(0.0f, 0.0f);	
	}	
	else {	
		touch = vec2_sub(touch, *pos);	
		nub_color = pressed_color;
	}	

	float nub_width = rectf_width(nub_src);
	float nub_height = rectf_width(nub_src);

	assert(feql(back_width, back_height) && feql(nub_width, nub_height));

	float back_radius = back_width / 2.0f;
	float nub_radius = nub_width / 2.0f;
	
	float move_radius = back_radius - nub_radius;

	assert(move_radius > 4.0f);
	
	float offset_len = vec2_length(touch);
	if(offset_len > move_radius) {
		touch = vec2_scale(touch, move_radius / offset_len);
		offset_len = move_radius;
		nub_color = COLOR_WHITE;
	}	
	
	// Draw nub
	dest.left = pos->x + touch.x - nub_width / 2.0f;
	dest.top = pos->y + touch.y - nub_height / 2.0f;
	video_draw_rect(tex, layer, nub_src, &dest, nub_color);

	if(offset_len < joystick_deadzone_radius)
		return vec2(0.0f, 0.0f);

	float norm_len = normalize(offset_len, 
		joystick_deadzone_radius, move_radius);	
	
	return vec2_scale(touch, norm_len / offset_len);
}	
예제 #9
0
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);
}
예제 #10
0
파일: gx.c 프로젝트: LWSS/gx
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;
}
예제 #11
0
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;
}
예제 #12
0
파일: primitives.c 프로젝트: tedajax/runner
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(&center, &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;
}
예제 #13
0
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])); 
}
예제 #14
0
파일: gx.c 프로젝트: LWSS/gx
static void fire_projectile(struct GameState *game_state, struct Ship *source, struct Ship *target, int32 damage)
{
    ASSERT(source != target);

    source->fire_cooldown_timer = source->fire_cooldown;

    struct Projectile *projectile = create_projectile(game_state);

    projectile->owner = source->id;
    projectile->team = source->team;
    projectile->damage = damage;

    projectile->position = source->position;
    projectile->size = vec2_new(0.1f, 0.1f);

    vec2 direction = vec2_normalize(vec2_sub(target->position, projectile->position));
    projectile->velocity = vec2_mul(direction, 5.0f);
}
예제 #15
0
파일: gx.c 프로젝트: LWSS/gx
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
}
예제 #16
0
void Boat_m_touch(Ent *ent1, Ent *ent2)
{
    Boat *boat = (Boat*)ent1;
    if(Ent_GET(flags, ent2) & EFLAGS_SOLID) {
        if(ent_class_is_subclass(ent2->eclass, &Enemy_CLASS)) {
            set_paused(1);
            set_game_over(1);
        } else {
            float dir_angle = vec2_to_angle(Ent_GET(move_direction, boat)),
                  coll_angle;
            vec2 boat_pos = *Ent_GET(position, boat),
                 coll_pos = *Ent_GET(position, ent2);
            vec2 coll_vec = coll_pos;
        
            vec2_sub(&coll_vec, &boat_pos);
            vec2_norm(&coll_vec);

            coll_angle = vec2_to_angle(&coll_vec);

            if(fabs(dir_angle - coll_angle) <= 45)
                Ent_SET(speed, boat, 0);
        }
    }
}
예제 #17
0
static bool _vis_query(NavMesh* navmesh, Vector2 p1, Vector2 p2) {
	int step_x, step_y, bmap_x, bmap_y, bmap_end_x, bmap_end_y;

	bmap_x = MIN(floorf(p1.x / vis_cell_width), vis_bitmap_width-1);
	bmap_y = MIN(floorf(p1.y / vis_cell_height), vis_bitmap_height-1);
	bmap_end_x = MIN(floorf(p2.x / vis_cell_width), vis_bitmap_width-1);
	bmap_end_y = MIN(floorf(p2.y / vis_cell_height), vis_bitmap_height-1);

	Vector2 dir = vec2_sub(p2, p1);
	dir = vec2_normalize(dir);

	Vector2 side_dist, delta_dist = vec2(
		sqrtf(1.0f + (dir.y * dir.y) / (dir.x * dir.x)) * vis_cell_width,
		sqrtf(1.0f + (dir.x * dir.x) / (dir.y * dir.y)) * vis_cell_height
	);

	if(dir.x > 0.0f) {
		step_x = 1;
		side_dist.x = (float)(bmap_x+1) * vis_cell_width - p1.x;
	}
	else {
		step_x = -1;
		side_dist.x = p1.x - (float)bmap_x * vis_cell_width;
	}
	side_dist.y *= delta_dist.x / vis_cell_width;
	if(dir.y > 0.0f) {
		step_y = 1;
		side_dist.y = (float)(bmap_y+1) * vis_cell_height - p1.y;
	}
	else {
		step_y = -1;
		side_dist.y = p1.y - (float)bmap_y * vis_cell_height;
	}
	side_dist.y *= delta_dist.y / vis_cell_height;

	// DDA
	while(!_query_vis_bitmap(navmesh, bmap_x, bmap_y)) {

		bool x_cond = 
			(step_x > 0 && bmap_x >= bmap_end_x) || 
			(step_x < 0 && bmap_x <= bmap_end_x);

		bool y_cond = 
			(step_y > 0 && bmap_y >= bmap_end_y) || 
			(step_y < 0 && bmap_y <= bmap_end_y);

		if(x_cond && y_cond)
			return true;

		if(side_dist.x < side_dist.y) {
			side_dist.x += delta_dist.x;
			bmap_x += step_x;
		}
		else {
			side_dist.y += delta_dist.y;
			bmap_y += step_y;
		}
	}

	return false;
}
예제 #18
0
파일: gx.c 프로젝트: LWSS/gx
static void tick_physics(struct GameState *game_state, float dt)
{
    // Projectile kinematics.
    for (uint32 i = 0; i < game_state->projectile_count; ++i)
    {
        struct Projectile *projectile = &game_state->projectiles[i];

        // r = r0 + (v*t) + (a*t^2)/2
        projectile->position = vec2_add(projectile->position, vec2_mul(projectile->velocity, dt));
    }

    // Ship kinematics.
    for (uint32 i = 0; i < game_state->ship_count; ++i)
    {
        struct Ship *ship = &game_state->ships[i];

        vec2 move_acceleration = vec2_zero();

        // v = v0 + (a*t)
        ship->move_velocity = vec2_add(ship->move_velocity, vec2_mul(move_acceleration, dt));

        // r = r0 + (v*t) + (a*t^2)/2
        ship->position = vec2_add(vec2_add(ship->position, vec2_mul(ship->move_velocity, dt)), vec2_div(vec2_mul(move_acceleration, dt * dt), 2.0f));
    }

    //
    // TODO: spatial hashing
    //

    // Projectile collision.
    for (uint32 i = 0; i < game_state->projectile_count; ++i)
    {
        struct Projectile *projectile = &game_state->projectiles[i];
        struct AABB projectile_aabb = aabb_from_transform(projectile->position, projectile->size);

        // Projectile-building collision.
        for (uint32 j = 0; j < game_state->building_count; ++j)
        {
            struct Building *building = &game_state->buildings[j];
            struct AABB building_aabb = aabb_from_transform(building->position, building->size);

            if (aabb_aabb_intersection(projectile_aabb, building_aabb))
            {
                // TODO: damage building if not friendly
                destroy_projectile(game_state, projectile);
                break;
            }
        }

        // NOTE: owner may be dead and destroyed at this point, so checking for NULL might be required.
        struct Ship *owner = get_ship_by_id(game_state, projectile->owner);

        // Projectile-ship collision.
        for (uint32 j = 0; j < game_state->ship_count; ++j)
        {
            struct Ship *ship = &game_state->ships[j];
            if (ship->id == projectile->owner)
                continue;

#if 0
            // Allow projectiles to pass through teammates.
            if (ship->team == projectile->team)
                continue;
#endif

            struct AABB ship_aabb = aabb_from_transform(ship->position, ship->size);

            if (aabb_aabb_intersection(projectile_aabb, ship_aabb))
            {
                // Disable friendly fire.
                if (ship->team != projectile->team)
                    damage_ship(game_state, ship, projectile->damage);

                destroy_projectile(game_state, projectile);
                break;
            }
        }
    }

    // TODO: optimize
    // Ship collision.
    if (game_state->ship_count >= 2)
    {
        for (uint32 i = 0; i < game_state->ship_count - 1; ++i)
        {
            struct Ship *a = &game_state->ships[i];
            struct AABB a_aabb = aabb_from_transform(a->position, a->size);
            vec2 a_center = vec2_div(vec2_add(a_aabb.min, a_aabb.max), 2.0f);
            vec2 a_half_extents = vec2_div(vec2_sub(a_aabb.max, a_aabb.min), 2.0f);

            // Ship-building collision.
            for (uint32 j = 0; j < game_state->building_count; ++j)
            {
                struct Building *building = &game_state->buildings[j];
                struct AABB b_aabb = aabb_from_transform(building->position, building->size);

                if (aabb_aabb_intersection(a_aabb, b_aabb))
                {
                    vec2 b_center = vec2_div(vec2_add(b_aabb.min, b_aabb.max), 2.0f);
                    vec2 b_half_extents = vec2_div(vec2_sub(b_aabb.max, b_aabb.min), 2.0f);

                    vec2 intersection = vec2_sub(vec2_abs(vec2_sub(b_center, a_center)), vec2_add(a_half_extents, b_half_extents));
                    if (intersection.x > intersection.y)
                    {
                        a->move_velocity.x = 0.0f;

                        if (a->position.x < building->position.x)
                            a->position.x += intersection.x/2.0f;
                        else
                            a->position.x -= intersection.x/2.0f;
                    }
                    else
                    {
                        a->move_velocity.y = 0.0f;

                        if (a->position.y < building->position.y)
                            a->position.y += intersection.y/2.0f;
                        else
                            a->position.y -= intersection.y/2.0f;
                    }
                }
            }

            // Ship-ship collision.
            for (uint32 j = i + 1; j < game_state->ship_count; ++j)
            {
                struct Ship *b = &game_state->ships[j];
                struct AABB b_aabb = aabb_from_transform(b->position, b->size);

                if (aabb_aabb_intersection(a_aabb, b_aabb))
                {
                    vec2 b_center = vec2_div(vec2_add(b_aabb.min, b_aabb.max), 2.0f);
                    vec2 b_half_extents = vec2_div(vec2_sub(b_aabb.max, b_aabb.min), 2.0f);

                    vec2 intersection = vec2_sub(vec2_abs(vec2_sub(b_center, a_center)), vec2_add(a_half_extents, b_half_extents));
                    if (intersection.x > intersection.y)
                    {
                        if (abs_float(a->move_velocity.x) > abs_float(b->move_velocity.x))
                            a->move_velocity.x = 0.0f;
                        else
                            b->move_velocity.x = 0.0f;

                        if (a->position.x < b->position.x)
                        {
                            a->position.x += intersection.x/2.0f;
                            b->position.x -= intersection.x/2.0f;
                        }
                        else
                        {
                            a->position.x -= intersection.x/2.0f;
                            b->position.x += intersection.x/2.0f;
                        }
                    }
                    else
                    {
                        if (abs_float(a->move_velocity.y) > abs_float(b->move_velocity.y))
                            a->move_velocity.y = 0.0f;
                        else
                            b->move_velocity.y = 0.0f;

                        if (a->position.y < b->position.y)
                        {
                            a->position.y += intersection.y/2.0f;
                            b->position.y -= intersection.y/2.0f;
                        }
                        else
                        {
                            a->position.y -= intersection.y/2.0f;
                            b->position.y += intersection.y/2.0f;
                        }
                    }
                }
            }
        }
    }
}
예제 #19
0
파일: gx.c 프로젝트: LWSS/gx
void tick_game(struct GameMemory *memory, struct Input *input, uint32 screen_width, uint32 screen_height, float dt)
{
    struct GameState *game_state = (struct GameState *)memory->game_memory;
    struct RenderBuffer *render_buffer = (struct RenderBuffer *)memory->render_memory;

    clear_render_buffer(render_buffer);

    for (uint32 i = 0; i < game_state->visibility_graph.vertex_count; ++i)
    {
        vec2 vertex = game_state->visibility_graph.vertices[i];
        draw_world_quad_buffered(render_buffer, vertex, vec2_scalar(0.1f), vec4_zero(), vec3_new(0, 1, 1));
    }

    for (uint32 i = 0; i < game_state->visibility_graph.edge_count; ++i)
    {
        uint32 *edge = &game_state->visibility_graph.edges[i][0];

        vec2 p0 = game_state->visibility_graph.vertices[edge[0]];
        vec2 p1 = game_state->visibility_graph.vertices[edge[1]];

        draw_world_line_buffered(render_buffer, p0, p1, vec3_new(1, 1, 0));
    }

    if (mouse_down(MOUSE_LEFT, input))
    {
        struct AABB box = calc_mouse_selection_box(input, MOUSE_LEFT);

        vec2 size = vec2_sub(box.max, box.min);
        vec2 bottom_left  = vec2_new(box.min.x, box.max.y);
        vec2 bottom_right = vec2_new(box.max.x, box.max.y);
        vec2 top_left     = vec2_new(box.min.x, box.min.y);
        vec2 top_right    = vec2_new(box.max.x, box.min.y);

        const uint32 outline_thickness = 1;

        draw_screen_quad_buffered(render_buffer, top_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, bottom_left, vec2_new(size.x, outline_thickness), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, top_left, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0));
        draw_screen_quad_buffered(render_buffer, top_right, vec2_new(outline_thickness, size.y), vec4_zero(), vec3_new(1, 1, 0));
    }

    if (mouse_released(MOUSE_LEFT, input))
    {
        // Clear previous selection.
        game_state->selected_ship_count = 0;

        struct AABB screen_selection_box = calc_mouse_selection_box(input, MOUSE_LEFT);

        // Because screen space y-values are inverted, these two results have conflicting
        // y-values, i.e. screen_to_world_min.y is actually the maximum y. These values
        // are then properly min/maxed and stored correctly in world_selection_box.
        vec2 screen_to_world_min = screen_to_world_coords(screen_selection_box.min, &game_state->camera, screen_width, screen_height);
        vec2 screen_to_world_max = screen_to_world_coords(screen_selection_box.max, &game_state->camera, screen_width, screen_height);

        struct AABB world_selection_box;
        world_selection_box.min = min_vec2(screen_to_world_min, screen_to_world_max);
        world_selection_box.max = max_vec2(screen_to_world_min, screen_to_world_max);

        // Add colliding ships to the selection list.
        // TODO: optimize, spatial grid hash?
        for (uint32 i = 0; i < game_state->ship_count; ++i)
        {
            struct Ship *ship = &game_state->ships[i];
            struct AABB ship_aabb = aabb_from_transform(ship->position, ship->size);

            vec2 center = vec2_div(vec2_add(ship_aabb.min, ship_aabb.max), 2.0f);

            if (aabb_aabb_intersection(world_selection_box, ship_aabb))
                game_state->selected_ships[game_state->selected_ship_count++] = ship->id;
        }

        if (game_state->selected_ship_count > 0)
            fprintf(stderr, "selected %u ships\n", game_state->selected_ship_count);
    }

    if (mouse_down(MOUSE_RIGHT, input))
    {
        vec2 target_position = screen_to_world_coords(input->mouse_position, &game_state->camera, screen_width, screen_height);

        for (uint32 i = 0; i < game_state->selected_ship_count; ++i)
        {
            uint32 id = game_state->selected_ships[i];
            struct Ship *ship = get_ship_by_id(game_state, id);

            ship->target_position = target_position;
            ship->move_order = true;
        }
    }

    // Outline selected ships.
    for (uint32 i = 0; i < game_state->selected_ship_count; ++i)
    {
        uint32 id = game_state->selected_ships[i];
        struct Ship *ship = get_ship_by_id(game_state, id);

        draw_world_quad_buffered(render_buffer, ship->position, vec2_mul(ship->size, 1.1f), vec4_zero(), vec3_new(0, 1, 0));

        if (ship->move_order)
            draw_world_quad_buffered(render_buffer, ship->target_position, vec2_new(0.5f, 0.5f), vec4_zero(), vec3_new(0, 1, 0));
    }

    // Handle move orders.
    for (uint32 i = 0; i < game_state->ship_count; ++i)
    {
        struct Ship *ship = &game_state->ships[i];
        if (ship->move_order)
        {
            vec2 direction = vec2_zero();
            /*
            if (vec2_length2(direction) < FLOAT_EPSILON)
                direction = vec2_normalize(vec2_sub(ship->target_position, ship->position));
                */
            ship->move_velocity = vec2_mul(direction, 2.0f);

            /*
            vec2 direction = vec2_normalize(vec2_sub(ship->target_position, ship->position));
            ship->move_velocity = vec2_mul(direction, 2.0f);
            */

            if (vec2_distance2(ship->position, ship->target_position) < 0.1f)
            {
                ship->move_velocity = vec2_zero();
                ship->move_order = false;
            }
        }
    }

    tick_camera(input, &game_state->camera, dt);

    tick_combat(game_state, dt);
    tick_physics(game_state, dt);
}
예제 #20
0
파일: main.c 프로젝트: larso0/PTGame
int main(int argc, char** argv)
{
    Settings settings;
    ConstructSettings(&settings);
    LoadSettingsFile(&settings, "settings.ini");
    if(Init(&settings) < 0) return -1;

    GLuint program;
    if(SetupProgram(&program) < 0) return -2;

    GLuint grid_vbuf = CreateGridVertexBuffer(settings.graphics.viewdistance);
    int grid_icount;
    GLuint grid_ibuf = CreateGridIndexBuffer(&grid_icount,
                                             settings.graphics.viewdistance);

    glUseProgram(program);
    GLint grid_pos_loc = glGetAttribLocation(program, "grid_pos");
    GLint grid_world_mat_loc = glGetUniformLocation(program, "world_mat");
    GLint grid_view_mat_loc = glGetUniformLocation(program, "view_mat");
    GLint grid_proj_mat_loc = glGetUniformLocation(program, "proj_mat");
    GLint grid_color_loc = glGetUniformLocation(program, "color");
    GLint grid_viewdistance_loc = glGetUniformLocation(program, "viewdistance");

    glUniform3f(grid_color_loc, 0.f, 0.6f, 0.f);
    glUniform1f(grid_viewdistance_loc, settings.graphics.viewdistance);

    GLuint grid_vao;
    glGenVertexArrays(1, &grid_vao);
    glBindVertexArray(grid_vao);
    glBindBuffer(GL_ARRAY_BUFFER, grid_vbuf);
    glEnableVertexAttribArray(grid_pos_loc);
    glVertexAttribPointer(grid_pos_loc, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, grid_ibuf);

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);
    glClearColor(0.5f, 0.5f, 0.5f, 1.f);
    glViewport(0, 0, settings.video.width, settings.video.height);

    Node grid_node;
    ConstructNode(&grid_node);
    Camera camera;
    ConstructCamera(&camera);
    mat4x4 projection_matrix;
    mat4x4_perspective(projection_matrix,
                       settings.video.pfov,
                       settings.video.width/(float)settings.video.height,
                       settings.video.pnear,
                       settings.video.pfar);
    glUniformMatrix4fv(grid_proj_mat_loc, 1, GL_FALSE,
                       (const float*)projection_matrix);

    float speed = 10.f;
    Uint32 ticks = SDL_GetTicks();
    State state = STATE_RUNNING | (settings.video.fullscreen ? STATE_FULLSCREEN : 0);
    while(state & STATE_RUNNING)
    {
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glUseProgram(program);
        glUniformMatrix4fv(grid_world_mat_loc, 1, GL_FALSE,
                           (const float*)grid_node.world_matrix);
        glUniformMatrix4fv(grid_view_mat_loc, 1, GL_FALSE,
                           (const float*)camera.view_matrix);
        glBindVertexArray(grid_vao);
        glDrawElements(GL_TRIANGLE_STRIP, grid_icount, GL_UNSIGNED_INT, NULL);
        SDL_GL_SwapWindow(window);

        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
            case SDL_QUIT:
                state &= ~STATE_RUNNING;
                break;
            case SDL_KEYUP:
                switch(event.key.keysym.scancode)
                {
                case SDL_SCANCODE_F11:
                    state ^= STATE_FULLSCREEN;
                    SDL_SetWindowFullscreen
                    (
                        window,
                        state & STATE_FULLSCREEN ?
                        SDL_WINDOW_FULLSCREEN_DESKTOP : 0
                    );
                    break;
                case SDL_SCANCODE_ESCAPE:
                    state ^= STATE_MOUSE_GRABBED;
                    SDL_SetRelativeMouseMode(state & STATE_MOUSE_GRABBED);
                    break;
                case SDL_SCANCODE_LSHIFT:
                    speed = settings.controls.speed1;
                    break;
                default:
                    break;
                }
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.scancode)
                {
                case SDL_SCANCODE_LSHIFT:
                    speed = settings.controls.speed2;
                    break;
                default:
                    break;
                }
                break;
            case SDL_WINDOWEVENT:
                if(event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED)
                {
                    int w = event.window.data1;
                    int h = event.window.data2;
                    glViewport(0, 0, w, h);
                    mat4x4_perspective(projection_matrix,
                                       settings.video.pfov,
                                       w/(float)h,
                                       settings.video.pnear,
                                       settings.video.pfar);
                    glUniformMatrix4fv(grid_proj_mat_loc, 1, GL_FALSE,
                                       (const float*)projection_matrix);
                }
                break;
            case SDL_MOUSEMOTION:
                if(state & STATE_MOUSE_GRABBED)
                {
                    camera.yaw -= settings.controls.xsensitivity *
                                  event.motion.xrel;
                    camera.pitch -= settings.controls.xsensitivity *
                                    event.motion.yrel;
                }
                break;
            default:
                break;
            }
        }
        Uint32 nticks = SDL_GetTicks();
        float delta = (nticks - ticks)/1000.f;
        ticks = nticks;

        const Uint8* keys = SDL_GetKeyboardState(NULL);
        vec3 movement;
        int i;
        for(i = 0; i < 3; i++) movement[i] = 0.f;
        SDL_bool moved = SDL_FALSE;
        if(keys[SDL_SCANCODE_W] && !keys[SDL_SCANCODE_S])
        {
            vec3_add(movement, movement, camera.direction);
            moved = SDL_TRUE;
        }
        else if(keys[SDL_SCANCODE_S] && !keys[SDL_SCANCODE_W])
        {
            vec3_sub(movement, movement, camera.direction);
            moved = SDL_TRUE;
        }
        if(keys[SDL_SCANCODE_A] && !keys[SDL_SCANCODE_D])
        {
            vec3_sub(movement, movement, camera.right);
            moved = SDL_TRUE;
        }
        else if(keys[SDL_SCANCODE_D] && !keys[SDL_SCANCODE_A])
        {
            vec3_add(movement, movement, camera.right);
            moved = SDL_TRUE;
        }
        if(keys[SDL_SCANCODE_Q] && !keys[SDL_SCANCODE_E])
        {
            vec3_sub(movement, movement, camera.up);
            moved = SDL_TRUE;
        }
        else if(keys[SDL_SCANCODE_E] && !keys[SDL_SCANCODE_Q])
        {
            vec3_add(movement, movement, camera.up);
            moved = SDL_TRUE;
        }

        if(moved)
        {
            vec3_norm(movement, movement);
            vec3_scale(movement, movement, delta * speed);
            vec3_add(camera.node.translation, camera.node.translation,
                     movement);
        }

        UpdateCamera(&camera);

        if(moved)
        {
            vec2 tmp1;
            tmp1[0] = camera.node.position[0];
            tmp1[1] = camera.node.position[2];
            vec2 tmp2;
            tmp2[0] = grid_node.position[0];
            tmp2[1] = grid_node.position[2];
            vec2_sub(tmp1, tmp1, tmp2);
            tmp1[0] = floor(tmp1[0]);
            tmp1[1] = floor(tmp1[1]);
            grid_node.translation[0] += tmp1[0];
            grid_node.translation[2] += tmp1[1];
            UpdateNode(&grid_node);
        }
    }

    glDeleteVertexArrays(1, &grid_vao);
    glDeleteBuffers(1, &grid_vbuf);
    glDeleteBuffers(1, &grid_ibuf);
    glDeleteProgram(program);

    return 0;
}
예제 #21
0
NavMesh ai_precalc_navmesh(DArray geometry, DArray platforms,
	float width, float height) {
	NavMesh res;

	ai_precalc_bounds(width, height);

	DArray navpoints = _gen_navpoints(geometry, platforms);
	DArray edges = _gen_edges(navpoints, geometry);

	Vector2* navpoints_v = DARRAY_DATA_PTR(navpoints, Vector2);
	Edge* edges_e = DARRAY_DATA_PTR(edges, Edge);

	uint n = navpoints.size;

	res.n_nodes = n;
	res.navpoints = MEM_ALLOC(sizeof(Vector2) * n);
	res.neighbour_count = MEM_ALLOC(sizeof(uint) * n);
	res.neighbours_start = MEM_ALLOC(sizeof(uint) * n);
	float* adjacency = MEM_ALLOC(sizeof(float) * n*n);
	res.distance = MEM_ALLOC(sizeof(float) * n*n);
	res.radius = MEM_ALLOC(sizeof(float) * n);
	res.nn_grid_count = MEM_ALLOC(sizeof(uint) * nn_grid_cells);
	res.nn_grid_start = MEM_ALLOC(sizeof(uint) * nn_grid_cells);

	memset(res.neighbour_count, 0, sizeof(uint) * n);
	memset(adjacency, 0, sizeof(float) * n*n);
	memset(res.distance, 0, sizeof(float) * n*n);
	memset(res.nn_grid_count, 0, sizeof(uint) * nn_grid_cells);
	memset(res.nn_grid_start, 0, sizeof(uint) * nn_grid_cells);
		
	for(uint i = 0; i < navpoints.size; ++i) {
		res.navpoints[i] = 	navpoints_v[i];
		res.radius[i] = ai_wall_distance(navpoints_v[i], geometry);
	}

	for(uint i = 0; i < edges.size; ++i) {
		float dist = vec2_length(vec2_sub(
			navpoints_v[edges_e[i].v1], navpoints_v[edges_e[i].v2]));
		adjacency[IDX_2D(edges_e[i].v1, edges_e[i].v2, n)] = dist;
		adjacency[IDX_2D(edges_e[i].v2, edges_e[i].v1, n)] = dist;
		res.neighbour_count[edges_e[i].v1]++;
		res.neighbour_count[edges_e[i].v2]++;
	}

	// Pracalc node neighbour lists
	uint total_neighbours = res.neighbour_count[0];
	res.neighbours_start[0] = 0;
	for(uint i = 1; i < n; ++i) {
		res.neighbours_start[i] = 
			res.neighbours_start[i-1] + res.neighbour_count[i-1];
		total_neighbours +=	res.neighbour_count[i];
	}		
	res.neighbours = MEM_ALLOC(sizeof(uint) * total_neighbours);
	for(uint i = 0; i < n; ++i) {
		uint idx = res.neighbours_start[i];
		for(uint j = 0; j < n; ++j) {
			if(adjacency[IDX_2D(i, j, n)] > 0.0f)
				res.neighbours[idx++] = j;
		}
		assert(idx == res.neighbours_start[i] + res.neighbour_count[i]);
	}

	memcpy(res.distance, adjacency, sizeof(float) * n*n);
	// Change zero distances to infinities
	for(uint i = 0; i < n*n; ++i)
		if(res.distance[i] == 0.0f)
			res.distance[i] = 10000000.0f;

	// Floyd-Warshall
	for(uint i = 0; i < n; ++i)
		for(uint j = 0; j < n; ++j)
			for(uint k = 0; k < n; ++k)
				res.distance[IDX_2D(j, k, n)] = MIN(res.distance[IDX_2D(j, k, n)],
					res.distance[IDX_2D(j, i, n)]+res.distance[IDX_2D(i, k, n)]);

	// Precalc nearest-navpoint grid
	DArray grid_cell;
	DArray nn_grid;

	res.nn_grid_start[0] = 0;

	nn_grid = darray_create(sizeof(uint), 0);
	for(uint i = 0; i < nn_grid_cells; ++i) {
		grid_cell = darray_create(sizeof(uint), 0);
		
		for(uint j = 0; j < nn_samples; ++j) {
			Vector2 p = _rand_point_in_nn_grid_cell(i);
			uint nearest_navpoint = _nearest_navpoint(p, geometry, navpoints);
			if(nearest_navpoint >= n) // Point was inside wall, skip
				continue;

			bool unique = true;

			uint* existing_navpoints = DARRAY_DATA_PTR(grid_cell, uint);
			for(uint k = 0; k < grid_cell.size; ++k)
				if(existing_navpoints[k] == nearest_navpoint)
					unique = false;
			
			if(unique)
				darray_append(&grid_cell, &nearest_navpoint);
		}

		res.nn_grid_count[i] = grid_cell.size;
		if(i > 0)
			res.nn_grid_start[i] = 
				res.nn_grid_start[i-1] + res.nn_grid_count[i-1];
		
		uint* cell_navpoints = DARRAY_DATA_PTR(grid_cell, uint);
		darray_append_multi(&nn_grid, cell_navpoints, grid_cell.size);
		darray_free(&grid_cell);
	}	

	// Hack, works properly as long as darray_free only does
	// MEM_FREE(darray.data);
	res.nn_grid = (uint*)nn_grid.data;

	darray_free(&navpoints);
	darray_free(&edges);
	MEM_FREE(adjacency);

	_precalc_vis(geometry, &res);

	return res;
}
예제 #22
0
vec2 ui_rectangle_size(ui_rectangle* r) {
    return vec2_sub(r->bottom_right, r->top_left);
}
예제 #23
0
void crop_rotate::crop_outline(PapayaMemory* mem)
{
    // TODO: Function lacks grace
    Vec2 mouse = mem->mouse.pos;
    Vec2 p[4];
    p[0] = mem->doc.canvas_pos + mem->crop_rotate.top_left * mem->doc.canvas_zoom;
    p[2] = mem->doc.canvas_pos + mem->crop_rotate.bot_right * mem->doc.canvas_zoom;
    p[1] = Vec2(p[0].x, p[2].y);
    p[3] = Vec2(p[2].x, p[0].y);

    // Only change vertex selection if the left mouse button is not down
    if (!mem->mouse.is_down[0]) {
        mem->crop_rotate.crop_mode = 0;

        // Vertex selection
        {
            float min_dist = FLT_MAX;
            int32 min_index;

            for (int32 i = 0; i < 4; i++) {
                float dist = math::distance(p[i], mouse);
                if (min_dist > dist) {
                    min_dist = dist;
                    min_index = i;
                }
            }

            if (min_dist < 10.f) {
                mem->crop_rotate.crop_mode = 1 << min_index;
                goto dragging;
            }
        }

        // Edge selecton
        {
            float min_dist = FLT_MAX;
            int32 min_index;

            for (int32 i = 0; i < 4; i++) {
                int32 j = (i + 1) % 4;
                vec2 v1 = { p[i].x  , p[i].y  };
                vec2 v2 = { p[j].x  , p[j].y  };
                vec2 m  = { mouse.x , mouse.y };
                vec2 a, b;
                vec2_sub(a, v2, v1);
                vec2_sub(b, m , v1);
                float dot = vec2_mul_inner(a, b);
                // Continue if projection of mouse doesn't lie on the edge v1-v2
                if (dot < 0 || dot > vec2_mul_inner(a, a)) { continue; }
                float dist = (i % 2 == 0) ? math::abs(p[i].x - mouse.x) // Vertical edge
                                          : math::abs(p[i].y - mouse.y);
                if (min_dist > dist) {
                    min_dist = dist;
                    min_index = i;
                }
            }

            if (min_dist < 10.f) {
                mem->crop_rotate.crop_mode = (1 << min_index) |
                                             (1 << (min_index + 1) % 4);
                goto dragging;
            }
        }

        // Entire rect selection
        {
            Vec2 v = (mouse - mem->doc.canvas_pos) / mem->doc.canvas_zoom;
            if (v.x >= mem->crop_rotate.top_left.x  &&
                v.x <= mem->crop_rotate.bot_right.x &&
                v.y >= mem->crop_rotate.top_left.y  &&
                v.y <= mem->crop_rotate.bot_right.y) {
                mem->crop_rotate.crop_mode = 15;
                mem->crop_rotate.rect_drag_position = v - mem->crop_rotate.top_left;
            }
        }
    }

dragging:
    if (mem->crop_rotate.crop_mode && mem->mouse.is_down[0]) {
        Vec2 v = (mouse - mem->doc.canvas_pos) / mem->doc.canvas_zoom;
        // TODO: Implement smart-bounds toggle for partial image rotational cropping
        //       while maintaining aspect ratio
        // Whole rect
        if (mem->crop_rotate.crop_mode == 15) {
            Vec2 v = ((mouse - mem->doc.canvas_pos) / mem->doc.canvas_zoom)
                     - mem->crop_rotate.top_left;
            Vec2 delta = v - mem->crop_rotate.rect_drag_position;
            delta.x = math::clamp((float)round(delta.x),
                                  -1.f * mem->crop_rotate.top_left.x,
                                  mem->doc.width - mem->crop_rotate.bot_right.x);
            delta.y = math::clamp((float)round(delta.y),
                                  -1.f * mem->crop_rotate.top_left.y,
                                  mem->doc.height - mem->crop_rotate.bot_right.y);
            mem->crop_rotate.top_left  += delta;
            mem->crop_rotate.bot_right += delta;
            goto drawing;
        }

        // Edges
        if      (mem->crop_rotate.crop_mode == 3)  { mem->crop_rotate.top_left.x = v.x;  }
        else if (mem->crop_rotate.crop_mode == 9)  { mem->crop_rotate.top_left.y = v.y;  }
        else if (mem->crop_rotate.crop_mode == 12) { mem->crop_rotate.bot_right.x = v.x; }
        else if (mem->crop_rotate.crop_mode == 6)  { mem->crop_rotate.bot_right.y = v.y; }
        else {
            // Vertices
            if (mem->crop_rotate.crop_mode & 3)  { mem->crop_rotate.top_left.x = v.x;  }
            if (mem->crop_rotate.crop_mode & 9)  { mem->crop_rotate.top_left.y = v.y;  }
            if (mem->crop_rotate.crop_mode & 12) { mem->crop_rotate.bot_right.x = v.x; }
            if (mem->crop_rotate.crop_mode & 6)  { mem->crop_rotate.bot_right.y = v.y; }
        }

        if (mem->crop_rotate.crop_mode & 3) {
            mem->crop_rotate.top_left.x =
                math::clamp((float)round(mem->crop_rotate.top_left.x),
                            0.f,
                            mem->crop_rotate.bot_right.x - 1);
        }
        if (mem->crop_rotate.crop_mode & 9) {
            mem->crop_rotate.top_left.y =
                math::clamp((float)round(mem->crop_rotate.top_left.y),
                            0.f,
                            mem->crop_rotate.bot_right.y - 1);
        }
        if (mem->crop_rotate.crop_mode & 12) {
            mem->crop_rotate.bot_right.x =
                math::clamp((float)round(mem->crop_rotate.bot_right.x),
                            mem->crop_rotate.top_left.x + 1,
                            (float)mem->doc.width);
        }
        if (mem->crop_rotate.crop_mode & 6) {
            mem->crop_rotate.bot_right.y =
                math::clamp((float)round(mem->crop_rotate.bot_right.y),
                            mem->crop_rotate.top_left.y + 1,
                            (float)mem->doc.height);
        }
    }

drawing:
    ImDrawVert verts[4];
    {
        glBindTexture(GL_TEXTURE_2D, 0);
        verts[0].pos = p[0];              
        verts[1].pos = p[1];
        verts[2].pos = p[2];              
        verts[3].pos = p[3];

        verts[0].uv = Vec2(0.0f, 0.0f);
        verts[1].uv = Vec2(0.0f, 1.0f);
        verts[2].uv = Vec2(1.0f, 1.0f);
        verts[3].uv = Vec2(1.0f, 0.0f);

        uint32 col1 = 0xffcc7a00;
        uint32 col2 = 0xff1189e6;
        uint32 col3 = 0xff36bb0a;
        uint8 Mode = mem->crop_rotate.crop_mode;
        if (Mode == 15) {
            verts[0].col = verts[1].col = verts[2].col = verts[3].col = col3;
        }
        else {
            verts[0].col = (Mode & 1) ? col2 : col1;
            verts[1].col = (Mode & 2) ? col2 : col1;
            verts[2].col = (Mode & 4) ? col2 : col1;
            verts[3].col = (Mode & 8) ? col2 : col1;
        }
    }
    GLCHK( glBindBuffer(GL_ARRAY_BUFFER, mem->meshes[PapayaMesh_CropOutline].vbo_handle) );
    GLCHK( glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts) );

    gl::draw_mesh(mem->meshes[PapayaMesh_CropOutline],
                 mem->shaders[PapayaShader_VertexColor], true,
                 1, UniformType_Matrix4, &mem->window.proj_mtx[0][0]);
}
예제 #24
0
void ui_rectangle_move(ui_rectangle* r, vec2 pos) {
    vec2 size = vec2_sub(r->bottom_right, r->top_left);
    r->top_left = pos;
    r->bottom_right = vec2_add(pos, size);
}