Example #1
0
void BufferStoreRectangle(GG::GL2DVertexBuffer& buffer,
                          const GG::Rect& area,
                          const GG::Rect& border_thickness)
{
        GG::X inner_x1(area.ul.x + border_thickness.ul.x);
        GG::Y inner_y1(area.ul.y + border_thickness.ul.y);
        GG::X inner_x2(area.lr.x - border_thickness.lr.x);
        GG::Y inner_y2(area.lr.y - border_thickness.lr.y);

        buffer.reserve(14);
        buffer.store(inner_x2, inner_y1);
        buffer.store(area.lr.x, area.ul.y);
        buffer.store(inner_x1, inner_y1);
        buffer.store(area.ul.x, area.ul.y);
        buffer.store(inner_x1, inner_y2);
        buffer.store(area.ul.x, area.lr.y);
        buffer.store(inner_x2, inner_y2);
        buffer.store(area.lr.x, area.lr.y);
        buffer.store(inner_x2, inner_y1);
        buffer.store(area.lr.x, area.ul.y);

        buffer.store(inner_x2, inner_y1);
        buffer.store(inner_x1, inner_y1);
        buffer.store(inner_x1, inner_y2);
        buffer.store(inner_x2, inner_y2);
}
    void DrawArrow(GG::Pt begin, GG::Pt end) {
        double head_width = 5.0;
        // A vector (math) of the arrow we wish to draw
        GG::Pt direction = end - begin;
        double length = sqrt(1.0*(Value(direction.x)*Value(direction.x) +
                                  Value(direction.y)*Value(direction.y)));
        if (length == 0) {
            return;
        }

        // The point in the main line of the arrow,
        // paraller to which the head ends
        //          \.
        //           \.
        // --------h-->
        //           /.
        //          /.
        // h is at the handle
        GG::Pt handle;
        // How much to move off the handle to get to
        // the end point of one of the head lines
        GG::X delta_x;
        GG::Y delta_y;

        if (direction.x != 0 && direction.y != 0) {
            // In a skewed arrow we need
            // a bit of geometry to figure out the head
            double x = Value(direction.x);
            double y = Value(direction.y);
            double normalizer = head_width / sqrt(1 + x*x / (y*y));
            delta_x = GG::X(normalizer);
            delta_y = GG::Y(- x / y * normalizer);

            handle = end - GG::Pt((head_width / length) * direction.x, (head_width / length) * direction.y);
        } else if (direction.x == 0) {
            // Vertical arrow
            handle = end;
            handle.y -= boost::math::sign(Value(direction.y))*GG::Y(head_width);
            delta_x = GG::X(head_width);
            delta_y = GG::Y0;
        } else {
            //horizontal arrow
            handle = end;
            handle.x -= boost::math::sign(Value(direction.x)) * GG::X(head_width);
            delta_x = GG::X0;
            delta_y = GG::Y(head_width);
        }

        GG::Pt left_head = handle;
        GG::Pt right_head = handle;

        left_head.x += delta_x;
        left_head.y += delta_y;
        // The other line is on the opposite side of the handle
        right_head.x -=  delta_x;
        right_head.y -= delta_y;

        GG::glColor(GG::CLR_WHITE);
        glLineWidth(2);
        glDisable(GL_TEXTURE_2D);

        GG::GL2DVertexBuffer verts;
        verts.reserve(6);
        verts.store(Value(begin.x),     Value(begin.y));
        verts.store(Value(end.x),       Value(end.y));
        verts.store(Value(end.x),       Value(end.y));
        verts.store(Value(left_head.x), Value(left_head.y));
        verts.store(Value(end.x),       Value(end.y));
        verts.store(Value(right_head.x),Value(right_head.y));
        verts.activate();

        glDrawArrays(GL_LINES, 0, verts.size());

        glEnable(GL_TEXTURE_2D);
    }