Sun, 01 Aug 2021 10:00:12 +0300
* Enum definition for Placement enum
Source/Gorgon/Graphics.h | file | annotate | diff | comparison | revisions |
--- a/Source/Gorgon/Graphics.h Wed Jul 21 10:39:37 2021 +0300 +++ b/Source/Gorgon/Graphics.h Sun Aug 01 10:00:12 2021 +0300 @@ -17,63 +17,63 @@ namespace Gorgon { - /// Contains generic 2D graphics related data structures and functions. These functions are tied to - /// underlying GL system through textures. - namespace Graphics { + /// Contains generic 2D graphics related data structures and functions. These functions are tied to + /// underlying GL system through textures. + namespace Graphics { - /// Initializes Graphics module, should be performed after an OpenGL context is - /// created. There is a mechanism to ensure initialization is performed once. - void Initialize(); + /// Initializes Graphics module, should be performed after an OpenGL context is + /// created. There is a mechanism to ensure initialization is performed once. + void Initialize(); - /// Details which directions a texture should tile. If its not tiled for that direction, it will - /// be stretched. If the target size is smaller, tiling causes partial draw instead of shrinking. - /// @todo Should be fitted to String::Enum - enum class Tiling { - None = 0, - Horizontal = 1, - Vertical = 2, - Both = 3, - }; + /// Details which directions a texture should tile. If its not tiled for that direction, it will + /// be stretched. If the target size is smaller, tiling causes partial draw instead of shrinking. + /// @todo Should be fitted to String::Enum + enum class Tiling { + None = 0, + Horizontal = 1, + Vertical = 2, + Both = 3, + }; - /// 2D orientation constants - enum class Orientation { - Horizontal = 1, - Vertical = 2 - }; + /// 2D orientation constants + enum class Orientation { + Horizontal = 1, + Vertical = 2 + }; - /// Creates a Tiling class from the given horizontal, vertical tiling info. - inline Tiling Tile(bool horizontal, bool vertical) { - return (horizontal ? - (vertical ? Tiling::Both : Tiling::Horizontal) : - (vertical ? Tiling::Vertical : Tiling::None) - ); - } + /// Creates a Tiling class from the given horizontal, vertical tiling info. + inline Tiling Tile(bool horizontal, bool vertical) { + return (horizontal ? + (vertical ? Tiling::Both : Tiling::Horizontal) : + (vertical ? Tiling::Vertical : Tiling::None) + ); + } - /// Defines how an object is aligned - enum class Alignment { - /// Placed at the start of the axis - Start = 1, + /// Defines how an object is aligned + enum class Alignment { + /// Placed at the start of the axis + Start = 1, - /// Centered along the axis - Center = 4, + /// Centered along the axis + Center = 4, - /// Placed at the end of the axis - End = 2, - }; + /// Placed at the end of the axis + End = 2, + }; - /// Defines how a text is aligned. Justification should be used as an independent - /// flag as a text could both be justified and centered (for partial lines). - enum class TextAlignment { - /// Text is aligned to left - Left = 8, + /// Defines how a text is aligned. Justification should be used as an independent + /// flag as a text could both be justified and centered (for partial lines). + enum class TextAlignment { + /// Text is aligned to left + Left = 8, - /// Text is aligned to center - Center = 32, + /// Text is aligned to center + Center = 32, - /// Text is aligned to right - Right = 16, - }; + /// Text is aligned to right + Right = 16, + }; DefineEnumStrings(TextAlignment, { {TextAlignment::Left, "Left"}, @@ -81,769 +81,452 @@ {TextAlignment::Right, "Right"}, }); - /// Defines how an object is placed in a 2D axis system - enum class Placement { - /// Placed at top left - TopLeft = 9, + /// Defines how an object is placed in a 2D axis system + enum class Placement { + /// Placed at top left + TopLeft = 9, + + /// Placed at top center + TopCenter = 33, - /// Placed at top center - TopCenter = 33, + /// Placed at top right + TopRight = 17, + - /// Placed at top right - TopRight = 17, + /// Placed at middle left + MiddleLeft = 12, + + /// Placed at the center + MiddleCenter = 36, + + /// Placed at middle right + MiddleRight = 20, - /// Placed at middle left - MiddleLeft = 12, - - /// Placed at the center - MiddleCenter = 36, + /// Placed at bottom + BottomLeft = 10, - /// Placed at middle right - MiddleRight = 20, + /// Placed at bottom center + BottomCenter = 34, - - /// Placed at bottom - BottomLeft = 10, + /// Placed at bottom right + BottomRight = 18, + }; - /// Placed at bottom center - BottomCenter = 34, - - /// Placed at bottom right - BottomRight = 18, - }; + DefineEnumStrings(Placement, { + {Placement::TopLeft, "Top left"}, + {Placement::TopCenter, "Top center"}, + {Placement::TopRight, "Top right"}, + {Placement::MiddleLeft, "Middle left"}, + {Placement::MiddleCenter, "Middle center"}, + {Placement::MiddleRight, "Middle right"}, + {Placement::BottomLeft, "Bottom left"}, + {Placement::BottomCenter, "Bottom center"}, + {Placement::BottomRight, "Bottom right"}, + }); - /// Returns horizontal alignment from a placement - inline Alignment GetHorizontal(Placement placement) { - return Alignment(((int)placement & 56)>>3); - } + /// Returns horizontal alignment from a placement + inline Alignment GetHorizontal(Placement placement) { + return Alignment(((int)placement & 56)>>3); + } - /// Returns vertical alignment from a placement - inline Alignment GetVertical(Placement placement) { - return Alignment((int)placement & 7); - } + /// Returns vertical alignment from a placement + inline Alignment GetVertical(Placement placement) { + return Alignment((int)placement & 7); + } - /// Returns the offset of the object according to the given placement rule when there is the given - /// remainder between object size and the area its being drawn on. Typical usage: - /// `CalculateOffset(Placement::MiddleCenter, areasize - objectsize)` - inline Geometry::Point CalculateOffset(Placement place, Geometry::Size remainder) { - switch(GetHorizontal(place)) { - case Alignment::Start: - remainder.Width=0; - break; - case Alignment::Center: - remainder.Width/=2; - break; - case Alignment::End: - break; + /// Returns the offset of the object according to the given placement rule when there is the given + /// remainder between object size and the area its being drawn on. Typical usage: + /// `CalculateOffset(Placement::MiddleCenter, areasize - objectsize)` + inline Geometry::Point CalculateOffset(Placement place, Geometry::Size remainder) { + switch(GetHorizontal(place)) { + case Alignment::Start: + remainder.Width=0; + break; + case Alignment::Center: + remainder.Width/=2; + break; + case Alignment::End: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - switch(GetVertical(place)) { - case Alignment::Start: - remainder.Height=0; - break; - case Alignment::Center: - remainder.Height/=2; - break; - case Alignment::End: - break; + switch(GetVertical(place)) { + case Alignment::Start: + remainder.Height=0; + break; + case Alignment::Center: + remainder.Height/=2; + break; + case Alignment::End: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - return (Geometry::Point)remainder; - } + return (Geometry::Point)remainder; + } - /// This class allows control over a sizable object - class SizeController { - public: - /// Controls how a direction is tiled - enum Tiling { - /// The drawing is drawn only once with its original size. The placement of this single - /// drawing will be determined by the alignment. - Single = 0, + /// This class allows control over a sizable object + class SizeController { + public: + /// Controls how a direction is tiled + enum Tiling { + /// The drawing is drawn only once with its original size. The placement of this single + /// drawing will be determined by the alignment. + Single = 0, - /// The drawing is stretched along this axis to cover the given size. If the given drawing - /// object is truly scalable, this value acts same as Tile. - Stretch = 2, + /// The drawing is stretched along this axis to cover the given size. If the given drawing + /// object is truly scalable, this value acts same as Tile. + Stretch = 2, - /// The drawing is tiled along this axis to cover the given size. If the area is smaller, - /// drawing will be cut from the given size. If the area is larger, drawing will be repeated - /// as necessary. While repeating, it is possible for drawing not to cover the area exactly, - /// In this case, alignment determines which side will be incomplete. If center alignment - /// is selected, both sides will have same amount of incomplete drawing. - Tile = 1, + /// The drawing is tiled along this axis to cover the given size. If the area is smaller, + /// drawing will be cut from the given size. If the area is larger, drawing will be repeated + /// as necessary. While repeating, it is possible for drawing not to cover the area exactly, + /// In this case, alignment determines which side will be incomplete. If center alignment + /// is selected, both sides will have same amount of incomplete drawing. + Tile = 1, - /// The drawing is tiled along this axis to cover the given size. In this mode, the drawing will - /// never placed incomplete. Instead, it will be repeated to cover as much area as possible without - /// exceeding the given size. Any area that is left will be distributed to the edges according to - /// the selected alignment. - Integral_Smaller = 13, + /// The drawing is tiled along this axis to cover the given size. In this mode, the drawing will + /// never placed incomplete. Instead, it will be repeated to cover as much area as possible without + /// exceeding the given size. Any area that is left will be distributed to the edges according to + /// the selected alignment. + Integral_Smaller = 13, - /// The drawing is tiled along this axis to cover the given size. In this mode, the drawing will - /// never placed incomplete. Instead, it will be repeated to cover entire area. Excess drawing - /// will be aligned depending on the selected alignment. - Integral_Fill = 21, + /// The drawing is tiled along this axis to cover the given size. In this mode, the drawing will + /// never placed incomplete. Instead, it will be repeated to cover entire area. Excess drawing + /// will be aligned depending on the selected alignment. + Integral_Fill = 21, - /// The drawing is tiled along this axis to cover the given size. In this mode, the drawing will - /// never placed incomplete. Instead, it will be repeated to cover entire area. If the last drawing - /// that will be partial is more than 50% of the size of the original drawing, it will be drawn. Excess - /// drawing or the area left empty is distributed according to the selected alignment. - Integral_Best = 45, - }; + /// The drawing is tiled along this axis to cover the given size. In this mode, the drawing will + /// never placed incomplete. Instead, it will be repeated to cover entire area. If the last drawing + /// that will be partial is more than 50% of the size of the original drawing, it will be drawn. Excess + /// drawing or the area left empty is distributed according to the selected alignment. + Integral_Best = 45, + }; - /// Creates a default size controller which tiles the object from top-left - SizeController() : Horizontal(Tile), Vertical(Tile), Place(Placement::TopLeft) { } + /// Creates a default size controller which tiles the object from top-left + SizeController() : Horizontal(Tile), Vertical(Tile), Place(Placement::TopLeft) { } - /// Creates a size controller that places a single object to the given placement. This is an implicit conversion - /// constructor. - SizeController(Placement p) : Horizontal(Single), Vertical(Single), Place(p) { } + /// Creates a size controller that places a single object to the given placement. This is an implicit conversion + /// constructor. + SizeController(Placement p) : Horizontal(Single), Vertical(Single), Place(p) { } - /// Creates a new size controller with the given tiling options and placement - SizeController(Tiling h, Tiling v, Placement p=Placement::TopLeft) : Horizontal(h), Vertical(v), Place(p) { } + /// Creates a new size controller with the given tiling options and placement + SizeController(Tiling h, Tiling v, Placement p=Placement::TopLeft) : Horizontal(h), Vertical(v), Place(p) { } - /// Creates a new size controller with the given tiling options and placement - SizeController(Graphics::Tiling tile, Placement p=Placement::TopLeft) : - Horizontal(int(tile)&int(Graphics::Tiling::Horizontal) ? Tile : Stretch), - Vertical (int(tile)&int(Graphics::Tiling::Vertical) ? Tile : Stretch), - Place(p) - { } + /// Creates a new size controller with the given tiling options and placement + SizeController(Graphics::Tiling tile, Placement p=Placement::TopLeft) : + Horizontal(int(tile)&int(Graphics::Tiling::Horizontal) ? Tile : Stretch), + Vertical (int(tile)&int(Graphics::Tiling::Vertical) ? Tile : Stretch), + Place(p) + { } - /// Calculates the size of the object according to the tiling rules - Geometry::Size CalculateSize(Geometry::Size objectsize, const Geometry::Size &area) const { - switch(Horizontal) { - case Integral_Smaller: - objectsize.Width=(area.Width/objectsize.Width)*objectsize.Width; - break; - case Integral_Fill: - objectsize.Width=int(std::ceil(float(area.Width)/objectsize.Width))*objectsize.Width; - break; - case Integral_Best: - objectsize.Width=int(std::round(float(area.Width)/objectsize.Width))*objectsize.Width; - break; - case Stretch: - case Tile: - objectsize.Width=area.Width; - break; - case Single: - break; + /// Calculates the size of the object according to the tiling rules + Geometry::Size CalculateSize(Geometry::Size objectsize, const Geometry::Size &area) const { + switch(Horizontal) { + case Integral_Smaller: + objectsize.Width=(area.Width/objectsize.Width)*objectsize.Width; + break; + case Integral_Fill: + objectsize.Width=int(std::ceil(float(area.Width)/objectsize.Width))*objectsize.Width; + break; + case Integral_Best: + objectsize.Width=int(std::round(float(area.Width)/objectsize.Width))*objectsize.Width; + break; + case Stretch: + case Tile: + objectsize.Width=area.Width; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - switch(Vertical) { - case Integral_Smaller: - objectsize.Width=(area.Width/objectsize.Width)*objectsize.Width; - break; - case Integral_Fill: - objectsize.Width=int(std::ceil(float(area.Width)/objectsize.Width))*objectsize.Width; - break; - case Integral_Best: - objectsize.Width=int(std::round(float(area.Width)/objectsize.Width))*objectsize.Width; - break; - case Stretch: - case Tile: - objectsize.Height=area.Height; - break; - case Single: - break; + switch(Vertical) { + case Integral_Smaller: + objectsize.Width=(area.Width/objectsize.Width)*objectsize.Width; + break; + case Integral_Fill: + objectsize.Width=int(std::ceil(float(area.Width)/objectsize.Width))*objectsize.Width; + break; + case Integral_Best: + objectsize.Width=int(std::round(float(area.Width)/objectsize.Width))*objectsize.Width; + break; + case Stretch: + case Tile: + objectsize.Height=area.Height; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - return objectsize; - } + return objectsize; + } - /// Calculates the size of the object according to the tiling rules - Geometry::Sizef CalculateSize(Geometry::Sizef objectsize, const Geometry::Sizef &area) const { - switch(Horizontal) { - case Integral_Smaller: - objectsize.Width=floor(area.Width/objectsize.Width)*objectsize.Width; - break; - case Integral_Fill: - objectsize.Width=ceil(area.Width/objectsize.Width)*objectsize.Width; - break; - case Integral_Best: - objectsize.Width=round(area.Width/objectsize.Width)*objectsize.Width; - break; - case Stretch: - case Tile: - objectsize.Width=area.Width; - break; - case Single: - break; + /// Calculates the size of the object according to the tiling rules + Geometry::Sizef CalculateSize(Geometry::Sizef objectsize, const Geometry::Sizef &area) const { + switch(Horizontal) { + case Integral_Smaller: + objectsize.Width=floor(area.Width/objectsize.Width)*objectsize.Width; + break; + case Integral_Fill: + objectsize.Width=ceil(area.Width/objectsize.Width)*objectsize.Width; + break; + case Integral_Best: + objectsize.Width=round(area.Width/objectsize.Width)*objectsize.Width; + break; + case Stretch: + case Tile: + objectsize.Width=area.Width; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - switch(Vertical) { - case Integral_Smaller: - objectsize.Height=floor(area.Height/objectsize.Height)*objectsize.Height; - break; - case Integral_Fill: - objectsize.Height=ceil(area.Height/objectsize.Height)*objectsize.Height; - break; - case Integral_Best: - objectsize.Height=round(area.Height/objectsize.Height)*objectsize.Height; - break; - case Stretch: - case Tile: - objectsize.Height=area.Height; - break; - case Single: - break; + switch(Vertical) { + case Integral_Smaller: + objectsize.Height=floor(area.Height/objectsize.Height)*objectsize.Height; + break; + case Integral_Fill: + objectsize.Height=ceil(area.Height/objectsize.Height)*objectsize.Height; + break; + case Integral_Best: + objectsize.Height=round(area.Height/objectsize.Height)*objectsize.Height; + break; + case Stretch: + case Tile: + objectsize.Height=area.Height; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - return objectsize; - } + return objectsize; + } - /// Calculates the size of the object according to the tiling and placement rules - Geometry::Point CalculateOffset(const Geometry::Size &objectsize, const Geometry::Size &area) const { - return Graphics::CalculateOffset(Place, area-CalculateSize(objectsize, area)); - } + /// Calculates the size of the object according to the tiling and placement rules + Geometry::Point CalculateOffset(const Geometry::Size &objectsize, const Geometry::Size &area) const { + return Graphics::CalculateOffset(Place, area-CalculateSize(objectsize, area)); + } - /// Calculates the size of the object according to the tiling and placement rules - Geometry::Pointf CalculateOffset(const Geometry::Sizef &objectsize, const Geometry::Sizef &area) const { - return Graphics::CalculateOffset(Place, area-CalculateSize(objectsize, area)); - } + /// Calculates the size of the object according to the tiling and placement rules + Geometry::Pointf CalculateOffset(const Geometry::Sizef &objectsize, const Geometry::Sizef &area) const { + return Graphics::CalculateOffset(Place, area-CalculateSize(objectsize, area)); + } - /// Calculates the drawing area of the object according to the tiling and placement rules - Geometry::Rectangle CalculateArea(const Geometry::Size &objectsize, const Geometry::Size &area) const { - auto size=CalculateSize(objectsize, area); - return{Graphics::CalculateOffset(Place, area-size), size}; - } + /// Calculates the drawing area of the object according to the tiling and placement rules + Geometry::Rectangle CalculateArea(const Geometry::Size &objectsize, const Geometry::Size &area) const { + auto size=CalculateSize(objectsize, area); + return{Graphics::CalculateOffset(Place, area-size), size}; + } - /// Calculates the drawing area of the object according to the tiling and placement rules - Geometry::Rectanglef CalculateArea(const Geometry::Sizef &objectsize, const Geometry::Sizef &area) const { - auto size=CalculateSize(objectsize, area); - return{Graphics::CalculateOffset(Place, area-size), size}; - } + /// Calculates the drawing area of the object according to the tiling and placement rules + Geometry::Rectanglef CalculateArea(const Geometry::Sizef &objectsize, const Geometry::Sizef &area) const { + auto size=CalculateSize(objectsize, area); + return{Graphics::CalculateOffset(Place, area-size), size}; + } - /// Calculates the size of the object according to the tiling rules - Geometry::Size CalculateSize(Geometry::Size repeatingsize, const Geometry::Size &fixedsize, const Geometry::Size &area) const { - switch(Horizontal) { - case Integral_Smaller: - repeatingsize.Width=((area.Width-fixedsize.Width)/repeatingsize.Width)*repeatingsize.Width+fixedsize.Width; - break; - case Integral_Fill: - repeatingsize.Width=int(std::ceil(float(area.Width-fixedsize.Width)/repeatingsize.Width))*repeatingsize.Width+fixedsize.Width; - break; - case Integral_Best: - repeatingsize.Width=int(std::round(float(area.Width-fixedsize.Width)/repeatingsize.Width))*repeatingsize.Width+fixedsize.Width; - break; - case Stretch: - case Tile: - repeatingsize.Width=area.Width; - break; - case Single: - break; + /// Calculates the size of the object according to the tiling rules + Geometry::Size CalculateSize(Geometry::Size repeatingsize, const Geometry::Size &fixedsize, const Geometry::Size &area) const { + switch(Horizontal) { + case Integral_Smaller: + repeatingsize.Width=((area.Width-fixedsize.Width)/repeatingsize.Width)*repeatingsize.Width+fixedsize.Width; + break; + case Integral_Fill: + repeatingsize.Width=int(std::ceil(float(area.Width-fixedsize.Width)/repeatingsize.Width))*repeatingsize.Width+fixedsize.Width; + break; + case Integral_Best: + repeatingsize.Width=int(std::round(float(area.Width-fixedsize.Width)/repeatingsize.Width))*repeatingsize.Width+fixedsize.Width; + break; + case Stretch: + case Tile: + repeatingsize.Width=area.Width; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - switch(Vertical) { - case Integral_Smaller: - repeatingsize.Height=((area.Height-fixedsize.Height)/repeatingsize.Height)*repeatingsize.Height+fixedsize.Height; - break; - case Integral_Fill: - repeatingsize.Height=int(std::ceil(float(area.Height-fixedsize.Height)/repeatingsize.Height))*repeatingsize.Height+fixedsize.Height; - break; - case Integral_Best: - repeatingsize.Height=int(std::round(float(area.Height-fixedsize.Height)/repeatingsize.Height))*repeatingsize.Height+fixedsize.Height; - break; - case Stretch: - case Tile: - repeatingsize.Height=area.Height; - break; - case Single: - break; + switch(Vertical) { + case Integral_Smaller: + repeatingsize.Height=((area.Height-fixedsize.Height)/repeatingsize.Height)*repeatingsize.Height+fixedsize.Height; + break; + case Integral_Fill: + repeatingsize.Height=int(std::ceil(float(area.Height-fixedsize.Height)/repeatingsize.Height))*repeatingsize.Height+fixedsize.Height; + break; + case Integral_Best: + repeatingsize.Height=int(std::round(float(area.Height-fixedsize.Height)/repeatingsize.Height))*repeatingsize.Height+fixedsize.Height; + break; + case Stretch: + case Tile: + repeatingsize.Height=area.Height; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - return repeatingsize; - } + return repeatingsize; + } - /// Calculates the size of the object according to the tiling rules - Geometry::Sizef CalculateSize(Geometry::Sizef repeatingsize, const Geometry::Sizef &fixedsize, const Geometry::Sizef &area) const { - switch(Horizontal) { - case Integral_Smaller: - repeatingsize.Width=((area.Width-fixedsize.Width)/repeatingsize.Width)*repeatingsize.Width+fixedsize.Width; - break; - case Integral_Fill: - repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; - break; - case Integral_Best: - repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; - break; - case Stretch: - case Tile: - repeatingsize.Width=area.Width; - break; - case Single: - break; + /// Calculates the size of the object according to the tiling rules + Geometry::Sizef CalculateSize(Geometry::Sizef repeatingsize, const Geometry::Sizef &fixedsize, const Geometry::Sizef &area) const { + switch(Horizontal) { + case Integral_Smaller: + repeatingsize.Width=((area.Width-fixedsize.Width)/repeatingsize.Width)*repeatingsize.Width+fixedsize.Width; + break; + case Integral_Fill: + repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; + break; + case Integral_Best: + repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; + break; + case Stretch: + case Tile: + repeatingsize.Width=area.Width; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - switch(Vertical) { - case Integral_Smaller: - repeatingsize.Width=((area.Width-fixedsize.Width)/repeatingsize.Width)*repeatingsize.Width+fixedsize.Width; - break; - case Integral_Fill: - repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; - break; - case Integral_Best: - repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; - break; - case Stretch: - case Tile: - repeatingsize.Height=area.Height; - break; - case Single: - break; + switch(Vertical) { + case Integral_Smaller: + repeatingsize.Width=((area.Width-fixedsize.Width)/repeatingsize.Width)*repeatingsize.Width+fixedsize.Width; + break; + case Integral_Fill: + repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; + break; + case Integral_Best: + repeatingsize.Width=area.Width-fixedsize.Width/repeatingsize.Width*repeatingsize.Width+fixedsize.Width; + break; + case Stretch: + case Tile: + repeatingsize.Height=area.Height; + break; + case Single: + break; #ifndef NDEBUG - default: - throw std::runtime_error("Unknown mode"); - break; + default: + throw std::runtime_error("Unknown mode"); + break; #endif - } + } - return repeatingsize; - } + return repeatingsize; + } - /// Calculates the size of the object according to the tiling and placement rules - Geometry::Point CalculateOffset(const Geometry::Size &repeatingsize, const Geometry::Size &fixedsize, const Geometry::Size &area) const { - return Graphics::CalculateOffset(Place, area-CalculateSize(repeatingsize, fixedsize, area)); - } + /// Calculates the size of the object according to the tiling and placement rules + Geometry::Point CalculateOffset(const Geometry::Size &repeatingsize, const Geometry::Size &fixedsize, const Geometry::Size &area) const { + return Graphics::CalculateOffset(Place, area-CalculateSize(repeatingsize, fixedsize, area)); + } - /// Calculates the size of the object according to the tiling and placement rules - Geometry::Pointf CalculateOffset(const Geometry::Sizef &repeatingsize, const Geometry::Sizef &fixedsize, const Geometry::Sizef &area) const { - return Graphics::CalculateOffset(Place, area-CalculateSize(repeatingsize, fixedsize, area)); - } + /// Calculates the size of the object according to the tiling and placement rules + Geometry::Pointf CalculateOffset(const Geometry::Sizef &repeatingsize, const Geometry::Sizef &fixedsize, const Geometry::Sizef &area) const { + return Graphics::CalculateOffset(Place, area-CalculateSize(repeatingsize, fixedsize, area)); + } - /// Calculates the drawing area of the object according to the tiling and placement rules - Geometry::Rectangle CalculateArea(const Geometry::Size &repeatingsize, const Geometry::Size &fixedsize, const Geometry::Size &area) const { - auto size=CalculateSize(repeatingsize, fixedsize, area); - return{Graphics::CalculateOffset(Place, area-size), size}; - } + /// Calculates the drawing area of the object according to the tiling and placement rules + Geometry::Rectangle CalculateArea(const Geometry::Size &repeatingsize, const Geometry::Size &fixedsize, const Geometry::Size &area) const { + auto size=CalculateSize(repeatingsize, fixedsize, area); + return{Graphics::CalculateOffset(Place, area-size), size}; + } - /// Calculates the drawing area of the object according to the tiling and placement rules - Geometry::Rectangle CalculateArea(const Geometry::Sizef &repeatingsize, const Geometry::Sizef &fixedsize, const Geometry::Sizef &area) const { - auto size=CalculateSize(repeatingsize, fixedsize, area); - return{Graphics::CalculateOffset(Place, area-size), size}; - } + /// Calculates the drawing area of the object according to the tiling and placement rules + Geometry::Rectangle CalculateArea(const Geometry::Sizef &repeatingsize, const Geometry::Sizef &fixedsize, const Geometry::Sizef &area) const { + auto size=CalculateSize(repeatingsize, fixedsize, area); + return{Graphics::CalculateOffset(Place, area-size), size}; + } - Graphics::Tiling GetTiling() const { - return Graphics::Tile(Horizontal!=Single && Horizontal!=Stretch, Vertical!=Single && Vertical!=Stretch); - } + Graphics::Tiling GetTiling() const { + return Graphics::Tile(Horizontal!=Single && Horizontal!=Stretch, Vertical!=Single && Vertical!=Stretch); + } - /// Horizontal tiling mode - Tiling Horizontal; + /// Horizontal tiling mode + Tiling Horizontal; - /// Vertical tiling mode - Tiling Vertical; + /// Vertical tiling mode + Tiling Vertical; - /// Placement method - Placement Place; - }; + /// Placement method + Placement Place; + }; - /// This interface represents a GL texture source. - class TextureSource { - public: - /// Should return GL::Texture to be drawn. This could be 0 to denote no texture is to be used. - virtual GL::Texture GetID() const = 0; + /// This interface represents a GL texture source. + class TextureSource { + public: + /// Should return GL::Texture to be drawn. This could be 0 to denote no texture is to be used. + virtual GL::Texture GetID() const = 0; virtual ColorMode GetMode() const = 0; - /// Should return the size of the image stored in texture. Not the whole texture size. - virtual Geometry::Size GetImageSize() const = 0; - - /// Should return the coordinates of the texture to be used - virtual const Geometry::Pointf *GetCoordinates() const = 0; - - /// Returns whether this texture uses only a part of the GL::Texture. This indicates that the tiling - /// operations should be performed without texture repeating method. - bool IsPartial() const { - return memcmp(GetCoordinates(), fullcoordinates, sizeof(fullcoordinates))!=0; - } + /// Should return the size of the image stored in texture. Not the whole texture size. + virtual Geometry::Size GetImageSize() const = 0; - protected: - /// Coordinates that selects the entire texture to be used - static const Geometry::Pointf fullcoordinates[4]; - }; - - namespace internal { - - - extern GL::Texture LastTexture; - - void ActivateQuadVertices(); - void DrawQuadVertices(); - - } - } -} - - + /// Should return the coordinates of the texture to be used + virtual const Geometry::Pointf *GetCoordinates() const = 0; -#ifdef fnonona -#pragma once - -#include "GGE.h" -#include "OS.h" - -#include <GL/gl.h> -#include <assert.h> -#include <stdexcept> -#include <string> -#include <array> - -#ifdef WIN32 -# undef APIENTRY -# undef WINGDIAPI -#endif + /// Returns whether this texture uses only a part of the GL::Texture. This indicates that the tiling + /// operations should be performed without texture repeating method. + bool IsPartial() const { + return memcmp(GetCoordinates(), fullcoordinates, sizeof(fullcoordinates))!=0; + } -#include "../Utils/ManagedBuffer.h" -#include "../Utils/Point2D.h" -#include "../Utils/Bounds2D.h" -#include "../Utils/Rectangle2D.h" -#include "../Utils/Size2D.h" -#include "../Utils/Logging.h" -#include "External/glutil/MatrixStack.h" + protected: + /// Coordinates that selects the entire texture to be used + static const Geometry::Pointf fullcoordinates[4]; + }; -#ifndef GL_BGR -# define GL_BGR 0x80E0 -# define GL_BGRA 0x80E1 -#endif - -#ifndef PI -# define PI 3.1415926535898f -#endif + namespace internal { -////Namespace for Gorgon Game Engine -namespace gge { namespace graphics { - - extern gge::utils::Logger log; - - extern glutil::MatrixStack ModelViewMatrixStack; - extern glutil::MatrixStack ProjectionMatrixStack; - - - class TextureAttachment { - public: - ////Coordinates of texture rectangle - TexturePosition *TextureCoords; - ////Whether this surface has its own texture coordinates - bool HasOwnTextureCoords; - const GLTexture *Texture; - - TextureAttachment() : HasOwnTextureCoords(false), TextureCoords(NULL), Texture(NULL) {} - - ////Deletes texture coordinate information - void DeleteTextureCoords() { - if(HasOwnTextureCoords) { - HasOwnTextureCoords=false; - delete[] TextureCoords; - } - } - - ////Changes current texture to the given one - void SetTexture(const GLTexture *texture) { - DeleteTextureCoords(); - - this->Texture=texture; - TextureCoords=const_cast<TexturePosition*>((const TexturePosition*)texture->ImageCoord); - } - - ////Returns current texture - const GLTexture *GetTexture() const { - return Texture; - } - - ////Creates texture coordinate information, - /// should be called before modifying texture - /// coordinates - void CreateTextureCoords() { - if(!HasOwnTextureCoords) { - HasOwnTextureCoords=true; - TextureCoords=new TexturePosition[4]; - } - } - - ~TextureAttachment() { - DeleteTextureCoords(); - } - }; - - ////This class can be used to store basic surface information. - /// It has also support for modifiable texture coordinates. - class BasicSurface { - public: - ////Coordinates of vertices - VertexPosition VertexCoords[4]; - ////Coordinates of texture rectangle, prefer not to modify manually - TexturePosition *TextureCoords; - ////Whether this surface has its own texture coordinates - bool HasOwnTextureCoords; - - enum DrawMode { - Normal, - OffscreenAlphaOnly, - Offscreen, - SetAlpha - } Mode; - - ////Empty constructor - BasicSurface() : Mode(Normal) { - Texture=NULL; - Alpha=NULL; - HasOwnTextureCoords=false; - TextureCoords=NULL; - VertexCoords[0].z=0; - VertexCoords[1].z=0; - VertexCoords[2].z=0; - VertexCoords[3].z=0; - } - - ////Filling constructor that sets texture - BasicSurface(GLTexture *texture) { - this->Texture=texture; - TextureCoords=texture->ImageCoord; - - HasOwnTextureCoords=false; - } - - ////Deletes texture coordinate information - void DeleteTextureCoords() { - if(HasOwnTextureCoords) { - HasOwnTextureCoords=false; - delete[] TextureCoords; - } - } - - ////Changes current texture to the given one - void SetTexture(const GLTexture *texture) { - DeleteTextureCoords(); - - this->Texture=texture; - TextureCoords=const_cast<TexturePosition*>((const TexturePosition*)texture->ImageCoord); - - if(Alpha) { - delete Alpha; - Alpha=NULL; - } - } - - ////Returns current texture - const GLTexture *GetTexture() const { - return Texture; - } - - ////Creates texture coordinate information, - /// should be called before modifying texture - /// coordinates - void CreateTextureCoords() { - if(!HasOwnTextureCoords) { - HasOwnTextureCoords=true; - TextureCoords=new TexturePosition[4]; - } - } - - ////Clears any unneeded data - ~BasicSurface() { - if(HasOwnTextureCoords && TextureCoords) - delete[] TextureCoords; - } - - TextureAttachment *Alpha; - - protected: - ////The texture to be used - const GLTexture *Texture; - }; - - std::array<float,24> GetVertexData(const BasicSurface& surface); - - + extern GL::Texture LastTexture; - class SizeController2D { - public: - - enum TilingType { - //Should work as Continous if object is sizable - Single = B8(00000000), - //Should work as Continous if object is sizable - Stretch = B8(00000010), - - /* - Integral = B8(00000100), - Smaller = B8(00001000), - Closest = B8(00010000), - Best = B8(00100000), - */ - - //An object can either be sizable or tilable, - // Careful! there is code to be updated if - // integrals and tiles are changed to be different - Continous = B8(00000001), - Integral_Smaller = B8(00001101), - Integral_Fill = B8(00010101), - Integral_Best = B8(00100101), - - Tile_Continous = B8(00000001), - Tile_Integral_Smaller = B8(00001101), - Tile_Integral_Fill = B8(00010101), - Tile_Integral_Best = B8(00100101), - } HorizontalTiling, VerticalTiling; - - - explicit SizeController2D(TilingType HorizontalTiling=Single, TilingType VerticalTiling=Single, Alignment::Type Align=Alignment::Middle_Center) : - HorizontalTiling(HorizontalTiling), VerticalTiling(VerticalTiling), Align(Align) - { } - Alignment::Type Align; - - static const SizeController2D TileFit; - static const SizeController2D StretchFit; - static const SizeController2D SingleTopLeft; - static const SizeController2D SingleBottomRight; - static const SizeController2D SingleMiddleCenter; - - int CalculateWidth(int W, int Increment) const { - if(HorizontalTiling==SizeController2D::Tile_Integral_Best) { - return (int)utils::Round((double)W/Increment)*Increment; - } - else if(HorizontalTiling==SizeController2D::Tile_Integral_Smaller) { - return (int)std::floor((double)W/Increment)*Increment; - } - else if(HorizontalTiling==SizeController2D::Tile_Integral_Fill) { - return (int)std::ceil((double)W/Increment)*Increment; - } - else - return W; - } - - int CalculateWidth(int W, int Increment, int Overhead) const { - if(HorizontalTiling==SizeController2D::Integral_Best) { - return (int)utils::Round((double)(W-Overhead)/Increment)*Increment+Overhead; - } - else if(HorizontalTiling==SizeController2D::Integral_Smaller) { - return (int)std::floor((double)(W-Overhead)/Increment)*Increment+Overhead; - } - else if(HorizontalTiling==SizeController2D::Integral_Fill) { - return (int)std::ceil((double)(W-Overhead)/Increment)*Increment+Overhead; - } - else - return W; - } + void ActivateQuadVertices(); + void DrawQuadVertices(); - int CalculateHeight(int H, int Increment) const { - if(VerticalTiling==SizeController2D::Tile_Integral_Best) { - return (int)utils::Round((double)H/Increment)*Increment; - } - else if(VerticalTiling==SizeController2D::Tile_Integral_Smaller) { - return (int)std::floor((double)H/Increment)*Increment; - } - else if(VerticalTiling==SizeController2D::Tile_Integral_Fill) { - return (int)std::ceil((double)H/Increment)*Increment; - } - else - return H; - } - - int CalculateHeight(int H, int Increment, int Overhead) const { - if(VerticalTiling==SizeController2D::Integral_Best) { - return (int)utils::Round((double)(H-Overhead)/Increment)*Increment+Overhead; - } - else if(VerticalTiling==SizeController2D::Integral_Smaller) { - return (int)std::floor((double)(H-Overhead)/Increment)*Increment+Overhead; - } - else if(VerticalTiling==SizeController2D::Integral_Fill) { - return (int)std::ceil((double)(H-Overhead)/Increment)*Increment+Overhead; - } - else - return H; - } - }; - - - - ////Initializes OpenGL graphics with the given parameters, - /// returns created device context - ///@hWnd : Handle for the target window - ///@BitDepth : Used if fullscreen, changed bitdepth of screen - os::DeviceHandle Initialize(os::WindowHandle hWnd, int BitDepth, int Width, int Height); - - namespace system { - - ////Creates rectangle structure based on give parameters - //RECT makerect(int x, int y, int w, int h); - ////Converts Alpha only image to Alpha and Luminance (grayscale) image. - /// Destination array should be allocated. This algorithm is optimized - /// for speed. - ///@Source : Source data array, no justification is needed, - /// should be 1 byte/pix - ///@Destination : Destination data array, data is copied without - /// any justification, should be allocated for 2 byte/pix - void A8ToA8L8(int Width, int Height, Byte *Source, Byte *Destination); - ////This function sets the current texture to given data - void SetTexture(Byte *data, int cx, int cy, ColorMode::Type mode); - ////This function creates a texture from the given data and - /// returns texture information in a structure - ///@Image : Image data - ///@Mode : Color mode - GLTexture GenerateTexture(Byte *Image,int Width,int Height,ColorMode::Type Mode); - void UpdateTexture(GLTexture TextureID, Byte *Image,ColorMode::Type Mode); - void DestroyTexture(GLTexture &texture); - ////Returns equivalent OpenGL color mode constant - ///@Mode : GGE color mode constant - GLenum getGLColorMode(ColorMode::Type Mode); - ////Cleans render buffer and prepares for rendering - void PreRender(); - ////Performs post render tasks - ///@hDC : Device context that is created by - /// initialize graphics function - void PostRender(os::DeviceHandle Device, os::WindowHandle win); - - void ResizeGL(int Width, int Height); - } - - extern utils::Size ScreenSize; -} } - -#endif + } + } +}