TXUtils - это библиотека с открытым исходным кодом, написанная мною для себя облегчения и удобства работы с графикой, используя TXLib.
Библиотека совместима с MSVC (Microsoft Visual Studio) и с MinGW (Скорее всего, установлена вами вместе с CodeBlocks).
Я очень постарался, чтобы моя библиотека как можно меньше влияла на TXLib: на данный момент, включение TXUtils в программу никак не скажется её работе. Вы можете использовать TXLib как обычно.
Вообще я за здоровый образ жизни. Однако, разумеется, для работы TXUtils необходим TXLib. Так же, рекомендуется установить libpng, если у вас её нет. Библиотека может работать и без неё, но тогда вы не сможете работать с форматом png используя txu::Context.
Достаточно скачать репозиторий
git clone https://github.com/Smok1e/TXUtils
А затем подключить файл TXU.h к вашей программе после подключения TXLIb:
#include <TXLib.h>
#include "C:\path\to\txutils\TXU.h"
Готово!
Примечание: я гарантирую работу библиотеки только с компилятороми MSVC и MinGW. Я не отвечаю за совместимость с другими компиляторами.
- void txu::WasExitButtonPressed()
- int txu::GetMouseWheel()
- void txu::SetConsoleOutputEnabled(bool enable)
- bool txu::IsConsoleOutputEnabled()
- bool txu::SetWindowIcon(const char* filename)
- void txu::SetWindowCursor(HCURSOR cursor)
- void txu::SetCursorVisible(bool visible)
- void txu::IsCursorVisible()
- void txu::SetWindowResizingEnabled
- bool txu::IsWindowResizingEnabled
- bool txu::WasWindowResized
- bool txu::GetNewWindowSize(POINT* size)
Возвращает true, если был нажат крестик в меню окна, иначе false, для того чтобы программист сам мог отреагировать на нажатие крестика. Например так:
txCreateWindow(800, 800);
while (!GetAsyncKeyState(VK_ESCAPE))
{
if (txu::WasExitButtonPressed())
MessageBox(txWindow(), "THERE IS NO EXIT!", "NO!", MB_OK | MB_ICONERROR);
txSleep(10);
}
Возвращает сторону, в которую повернулось колесо мыши. Если колесо повернулось вниз, функция вернёт -1, если вверх, 1, а если колесо не было повёрнуто - функция вернёт 0. Значение стороны, в которую было повёрнуто колёсико, хранится и не изменяется до тех пор, пока оно не повернётся снова или не будет вызвана эта функция.
Разрешает или запрещает дублирование вывода stdout поверх окна txlib. В результате тестов я выясненио, что рисование вывода поверх окна снижает производительность программы.
Возвращает true, если рисование консоли поверх окна разрешено.
Вам не надоела иконка TXLib'а, которую дед повесил на все ваши окна? Мне да, поэтому я и сделал эту функцию. Она устанавливает окну TXLib иконку, загруженную из файла, указанного в параметрах. Если картинка загружена успешно, функция вернёт true. В обратном случае - false. Иконка должна быть в формате .ico
Я нарисовал такую иконку для своей программы:
И вызвал функцию txu::SetWindowIcon:
txCreateWindow (800, 800);
txu::SetWindowIcon ("icon.ico");
Теперь в заголовке окна висит моя собственная иконка:
Так же, советую вам плагин для фотошопа, позволяющий сохранять картинки в формате ico.
И напоследок, если вам не нравится то, что TXLib устанавливает своё имя в заголовке окна, используйте функцию SetWindowText из WinApi.
Устанавливает курсор, переданный в качестве параметра, в окно TXLib. Если в качестве параметра передать нулевой указатель, обработка курсора прекратится, то есть установится стандартный курсор, определённый системой.
Устанавливает видимость курсора внутри окна TXLib. false - курсор не будет видно, true - курсор будет видно.
Возвращает состояние видимости курсора.
Разрешает или запрещает пользователю изменять размер окна.
Возвращает true, если изменение размера окна разрешено.
Возвращает true, если размер окна TXLib был изменён пользователем, но функция GetNewWindowSize или WasWindowResized ещё не была вызвана.
Переменная, на которую ссылается указатель size получает последний изменённый пользователем размер окна. Возвращает true, если пользователь изменил размер окна, но функция GetNewWindowSize или WasWindowResized ещё не была вызвана. TXUtils автоматически изменяет размер нужных буферов окна, когда его размер меняется. Вот небольшой пример обработки изменения размера окна:
txCreateWindow(800, 800);
txu::SetWindowResizingEnabled (true);
while (!txu::WasExitButtonPressed())
{
POINT size = {};
if (txu::GetNewWindowSize(&size))
{
printf("New window size: {%d, %d}\n", size.x, size.y);
// ...
}
}
Стиль окна без заголовка и рамок.
_txWindowStyle = WS_NOFRAME;
txCreateWindow (800, 800);
Класс, предназначеный для хранения цвета и операций с ним. Вы можете пользоваться txu::Color так же, как и COLORREF, поскольку класс содержит соответствующий оператор. Например:
COLORREF colorref = txu::Color(0, 130, 255);
или
txSetFillColor(txu::Color (24, 24, 24));
Класс содержит публичные поля r
, g
, b
и a
для хранения значений красного, зелёного, синего и калфа-канала соответственно.
Класс содержит 24 предопределённых статических цвета, которые можно получить, подобно txu::Color::White
. Ниже представлен список названий и соответствующих им цветов всех статических экземпляров:
- txu::Color(int r, int g, int b, int a)
- txu::Color(int r, int g, int b)
- txu::Color(const Color& that)
- txu::Color(RGBQUAD rgbquad)
- txu::Color(COLORREF colorref)
- txu::Color()
- static Color Interpolate(Color a, Color b, double t)
- static Color Interpolate(const std::initializer_list <Color>& list, double t)
- static Color Random()
- static Color Choose(Color def = Black)
- operator RGBQUAD()
- operator COLORREF()
- Color operator!()
- Color& operator=(const Color& that)
- static Color HSV(int h, int s, int v)
- int hue()
- int saturation()
- int value()
- int average()
- txu::Color Blend(Color a, Color b)
- txu::Color operator<<=(Color a, Color b)
- bool operator==(const Color& a, const Color& b)
- bool operator!=(const Color& a, const COlor& b)
Эта статическая функция позволяет создавать плавный переход между цветами в зависимости от параметра t. При t == 0 функция вернёт цвет A, при t == 1 функция вернёт цвет B, а при t == 0.5 функция вернёт средний цвет между A и B. Например:
int size_x = 800;
int size_y = 100;
txCreateWindow(size_x, size_y);
for (int x = 0; x < size_x; x++)
{
double t = static_cast<double>(x) / size_x;
txSetColor(txu::Color::Interpolate(txu::Color::DarkCyan, txu::Color::DarkPink, t));
txRectangle(x, 0, x+1, size_y);
}
нарисует на экране плавный градиент от синего к розовому:
Тоже самое что и txu::Color::Interpolate (Color a, Color b, double t), но может принять произвольное количество цветов. Например:
int size_x = 800;
int size_y = 100;
txCreateWindow(size_x, size_y);
for (int x = 0; x < size_x; x++)
{
double t = static_cast<double>(x) / size_x;
txu::Color color = txu::Color::Interpolate({txu::Color::DarkCyan, txu::Color::DarkPink, txu::Color::Green}, t);
txSetColor(color);
txRectangle(x, 0, x+1, size_y);
}
нарисует плавный переход от синего к розовому, а от розового к зелёному:
Статическая функция. Возвращает случайный цвет.
Статическая функция. Вызывает стандартное диалоговое окно выбора цвета windows и возвращает выбранный пользователем цвет, если была нажата кнопка ОК. Если пользователь отменил выбор цвета, функция вернёт цвет, переданный в опциональном параметре (по умолчанию - чёрный).
Оператор преобразования к RGBQUAD
Оператор преобразования к COLORREF. Обратите внимание, что если альфа-канал цвета равен нулю, то оператор COLORREF вернёт TX_TRANSPARENT. В остальных же случаях альфа-канал не учитывается. К сожалению, хоть размер COLORREF и равен четырём байтам, в одном из которых, в теории, можно быль бы хранить значение альфа-канала, GDI windows не позволяет оперировать полу-прозрачными цветами нативно, а младший байт COLORREF'a считается зарезервированным.
Возвращает инвертированный цвет:
txu::Color black (0, 0, 0)
txu::Color white = !black //Белый цвет
Оператор присваивания
Возвращает цвет, созданный на основе системы HSV. Значения h, s и v должны быть в диапазоне от 0 до 255. Эта функция является статической, то есть её можно вызвать не создавая экземпляра класса Color. Например:
int size_x = 800;
int size_y = 100;
txCreateWindow(size_x, size_y);
for (int x = 0; x < size_x; x++)
{
double t = static_cast<double>(x) / size_x;
int hue = t * 255;
txSetColor(txu::Color::HSV(hue, 255, 255));
txRectangle(x, 0, x+1, size_y);
}
нарисует в окне плавный переход между всеми цветами радуги:
Преобразует цвет в формат HSV и возвращает значение hue (цветовой тон). См. Цветовая модель HSV.
Преобразует цвет в формат HSV и возвращает значение saturatuion (насыщеность). См. Цветовая модель HSV.
Преобразует цвет в формат HSV и возвращает значение value (яркость). См. Цветовая модель HSV.
Возвращает среднее значение каналов r, g и b. Альфа-канал не учитывается.
Функция смешивания цветов с учётом альфа-канала. Например:
int size_x = 400;
int size_y = 400;
txCreateWindow(size_x, size_y);
txSetFillColor(txu::Color(24, 24, 24));
txClear();
txSetFillColor(txu::Color::White);
txRectangle(50, 75, 200, 150);
for (int x = 100; x < 300; x++)
for (int y = 100; y < 300; y++)
txSetPixel(x, y, txu::Blend(txu::Color (0, 130, 255, 100), txGetPixel(x, y)));
нарисует полу-прозрачный синий квадрат:
Примечание: функция Blend учитывает альфа-канал только первого цвета.
Делает то же, что и Blend, однако цвета повёрнуты местами. То есть:
txu::Color color = txu::Blend(a, b);
эквивалентно
txu::Color color = b <<= a;
Оператор сравнения двух цветов: возвращает true только если a.r == b.r, и a.g == b.g, и a.b == b.b. Альфа-канал не учтён.
Оператор сравнения двух цветов: возвращает true, если a.r != b.r, или a.g != b.g, или a.b != b.b. Альфа-канал не учтён.
Класс, предназначенный для хранения информации о шрифте и установки шрифта в HDC. Класс txu::Font позволяет загружать шрифты непосредственно из файла.
Пример использования:
int size_x = 400;
int size_y = 400;
const char* text = "Hello World!";
txCreateWindow(size_x, size_y);
txSetFillColor(txu::Color(24, 24, 24));
txClear();
txu::Font font("consolas", 25, 50, FW_BOLD);
font.setItalicEnabled (true);
font.setUnderlineEnabled(true);
font.select();
txSetColor(txu::Color::White);
txTextOut(size_x/2 - txGetTextExtentX(text)/2, size_y/2 - txGetTextExtentY(text)/2, text);
выведет на экран надпись:
- Font()
- Font(const char* name, int size_x, int size_y, int weight = FW_DONTCARE, bool italic = false, bool underline = false, bool strikeout = false)
- Font(const Font& that)
- bool txu::Font::create()
- bool txu::Font::create(const char* name, int size_x, int size_y, int weight = FW_DONTCARE, bool italic = false, bool underline = false, bool strikeout = false)
- bool txu::Font::create(const Font& that)
- bool txu::Font::loadFromFile(const char* filename)
- void txu::Font::setSize(Coord2D size)
- void txu::Font::setSize(int size_x, int size_y)
- Coord2D txu::Font::getSize()
- int txu::Font::getSizeX()
- int txu::Font::getSizeY()
- void txu::Font::setWeight(int weight)
- int txu::Font::getWeight()
- void txu::Font::setItalicEnabled(bool enable)
- bool txu::Font::getItalicEnabled()
- void txu::Font::setUnderlineEnabled(bool enable)
- bool txu::Font::getUnderlineEnabled()
- void txu::Font::setStrikeoutEnabled(bool enable)
- bool txu::Font::getStrikeoutEnabled()
- void setName (const char* name)
- const char* getName()
- HFONT getSystemHandle()
- operator HFONT()
- void select(HDC dc = txDC())
Заново инициализирует шрифт с указанными параметрами. Возвращает true в случае успеха, иначе false.
Позволяет загрузить шрифт из файла. Вы не сможете загрузить шрифт, используя только TXLib или WinApi, поскольку эти библиотеки не предоставляют средств для чтения внутреннего имени шрифта, необходимого для его использования. Мне удалось решить эту проблему, написав собственную функцию чтения файла .ttf, однако, к сожалению, некоторые шрифты всё равно не загружаются, даже если loadFromFile вернёт true.
Я написал небольшой пример:
int size_x = 400;
int size_y = 400;
_txWindowStyle = WS_NOFRAME;
txCreateWindow(size_x, size_y);
txDisableAutoPause();
txu::SetConsoleOutputEnabled(false);
txu::Context context(size_x, size_y);
txu::Font font;
font.loadFromFile("font.ttf");
font.setSize(25, 50);
const char* text = "Hello World!";
double hue = 0;
txBegin();
while (!GetAsyncKeyState(VK_ESCAPE) && !txu::WasExitButtonPressed())
{
context.clear(txu::Color(24, 24, 24));
txu::Color color = txu::Color::HSV(hue, 255, 255);
context.setColor (color);
context.setFillColor(color);
context.setFont (font);
int x = size_x/2 - strlen(text)*font.getSizeX() / 2;
int y = size_y/2 - font.getSizeY() / 2;
txTextOut(x, y, text, context);
hue += 0.02;
if (hue > 255) hue = 0;
context.render();
txSleep(0);
}
Этот код загружает шрифт из файла "font.ttf", а затем выводит надпись "Hello world!" переливающимся цветом. О том, что такое txu::Context сказанно чуть-чуть ниже.
Устанавливает размер шрифта.
Устанавливает размер шрифта.
Возвращает размер шрифта.
Возвращает ширину шрифта.
Возвращает высоту шрифта.
Устанавливает толщину шрифта. См. CreateFont
Возвращает толщину шрифта.
Включает или отключает прописной шрифт.
Возвращает true если прописной шрифт включён, false в обратном случае.
Включает или отключает подчёркивание текста.
Возвращает true если подчёркивание текста включено, в обратном случае false.
Включает или отключает зачёркивание текста.
Возвращает true если зачёркивание текста включено, в обратном случае false.
Устанавливает имя шрифта.
Возвращает имя шрифта.
Возвращает дескриптор шрифта winapi.
Оператор преобразования к HFONT.
Устанавливает шрифт к HDC указанному в параметре. По умолчанию это txDC ().
Скорее всего, вы уже сталкивались со структурой POINT из WinApi. Класс Coord2D представляет из себя тоже самое, но с некоторыми преимуществами. Во первых, POINT способна хранить исключительно целые числа, в то время как Coord2D оперирует с double. А во вторых, для Coord2D определены всевозможные математические операторы. Кроме того, разумеется, вы можете преобразовать POINT к Coord2D, и обратно.
Представьте ситуацию. У вас есть графический интерфейс и область рисования, которая смещена относительно этого интерфейса. Вам необходимо получить относительные координаты мыши этой области рисования. Это очень легко сделать при помощи Coord2D.
Я накодил такой пример:
int size_x = 800;
int size_y = 800;
txCreateWindow(size_x, size_y);
txDisableAutoPause();
txu::Coord2D drawfield_offset(150, 0);
txu::Context drawfield(size_x - drawfield_offset.x, size_y - drawfield_offset.y);
drawfield.clear(txu::Color (24, 24, 24));
txBegin();
while (!GetAsyncKeyState(VK_ESCAPE) && !txu::WasExitButtonPressed())
{
txSetFillColor(txu::Color (32, 32, 32));
txClear();
txSetFillColor(txu::Color::White);
txSelectFont("consolas", 20, 10, FW_BOLD);
txTextOut(0, size_y/2, "Some ui here!");
if (txMouseButtons() == 1)
{
txu::Coord2D mouse = txMousePos();
mouse -= drawfield_offset;
drawfield.setColor (txu::Color::White);
drawfield.setFillColor(txu::Color::White);
txEllipse(txCoord(mouse - 5), txCoord(mouse + 5), drawfield);
}
drawfield.render(txDC(), txCoord(drawfield_offset));
txSleep(0);
}
О том, что такое txu::Context, я расскажу чуть позже. В этом примере слева находится меню, а справа от него область рисования. Если нажать на поле рисования, на нём остаются белые кружки.
- txu::Coord2D(double x, double y)
- txu::Coord2D(const Coord2D& that)
- txu::Coord2D(POINT point)
- txu::Coord2D()
- static txu::Coord2D txu::Coord2D::Screen()
- txu::Coord2D::operator POINT()
- Coord2D txu::Coord2D::operator-()
- Coord2D& txu::Coord2D::operator+=(const Coord2D& that)
- Coord2D& txu::Coord2D::operator-=(const Coord2D& that)
- Coord2D& txu::Coord2D::operator*=(const Coord2D& that)
- Coord2D& txu::Coord2D::operator/=(const Coord2D& that)
- Coord2D& txu::Coord2D::operator+=(double scalar)
- Coord2D& txu::Coord2D::operator-=(double scalar)
- Coord2D& txu::Coord2D::operator*=(double scalar)
- Coord2D& txu::Coord2D::operator/=(double scalar)
- txu::Coord operator+(const Coord2D& a, const Coord2D& b)
- txu::Coord operator-(const Coord2D& a, const Coord2D& b)
- txu::Coord operator*(const Coord2D& a, const Coord2D& b)
- txu::Coord operator/(const Coord2D& a, const Coord2D& b)
- txu::Coord operator+(const Coord2D& coord, double scalar)
- txu::Coord operator-(const Coord2D& coord, double scalar)
- txu::Coord operator*(const Coord2D& coord, double scalar)
- txu::Coord operator/(const Coord2D& coord, double scalar)
- bool operator==(const Coord2D& a, const Coord2D& b)
- bool operator!=(const Coord2D& a, const Coord2D& b)
- double Coord2Distance(const Coor2D& a, const Coord2D& b)
- double Coord2DSqrDistance(const Coord2D& a, const Coord2D& b)
Статическая функция. Возвращает экземпляр класса Coord2D с размерами основного экрана. Вот небольшой пример использования:
txu::Coord2D screen = txu::Coord2D::Screen();
_txWindowStyle = WS_NOFRAME;
txCreateWindow(txCoord(screen));
В результате откроется полноэкранное окно.
Оператор преобразования к POINT.
Возвращает отрицательный Coord2D. То есть
Coord2D a(-5, -2);
Coord2D b( 5, 2);
a == -b //true
Позволяют производить над каждой координатой экземпляра класса стандартные арифметические операции. При этом операции производятся над x левого и x правого операнда и над y левого и y правого операнда по отдельности. То есть
Coord2D a(1, 5);
Coord2D b(2, 3);
Coord2D c = a + b; // c == {3, 8}
или
Coord2D a(1, 5);
Coord2D b(2, 3);
Coord2D c = a * b; // c == {2, 15}
Позволяют производить над каждой координатой экземпляра класса стандартные арифметические операции со скалярным значеним. Операция производится с каждой координатой по отдельности. То есть
Coord2D coord(1, 5);
double scalar = 5;
Coord2D result = coord + scalar; // result == {6, 10}
или
Coord2D coord(1, 5);
double scalar = 5;
Coord2D result = coord * scalar; // result == {5, 25}
Оператор сравнения для Coord2D. Возвращает true, если a.x == b.x и a.y == b.y, иначе false.
Оператор сравнения для Coord2D. Возвращает true, если a.x != b.x, или a.y != b.y, иначе false.
Возвращает численное расстояние между точками a и b согласно теореме Пифагора (или длине вектора, если угодно).
Возвращает численное расстояние между точками a и b, возведённое в квадрат. Советую использовать это функцию вместо txu::Coord2Distance, если вам не нужно точное расстояние (например для сравнения расстояния a и расстояния b), поскольку последней приходится извлекать квадратный корень, что может снижать производительность программы.
Это макрос для удобства указания координат в функции, принимающие отдельно координату x и y. Например:
txu::Coord2D position(100, 100);
txu::Coord2D size (25, 50 );
txRectangle(position.x, position.y, position.x + size.x, position.y + size.y);
эквивалентно
txu::Coord2D position(100, 100);
txu::Coord2D size (25, 50 );
txRectangle(txCoord(position), txCoord(position + size));
И ещё один пример:
txu::Coord2D position(100, 100);
double radius = 5;
txEllipse(position.x - radius, position.y - radius, position.x + radius, position.y + radius);
эквивалентно
txu::Coord2D position(100, 100);
double radius = 5;
txEllipse(txCoord(position-radius), txCoord(position+radius));
Основной инструмент библиотеки. Забудьте о ежедневном геморрое с HDC!
Context обеспечивает удобную и надёжную работу с изображениями. Его не надо освобождать с помощью txDeleteDC, за вас это сделает деструктор.
Пример:
txu::Context source("image.bmp");
int size_x = source.getSizeX();
int size_y = source.getSizeY();
txu::Context result(size_x, size_y);
for (int x = 0; x < size_x; x++)
{
for (int y = 0; y < size_y; y++)
{
txu::Color color = source.getPixel (x, y);
int h = color.hue ();
int s = color.saturation();
int v = color.value ();
result.setPixel(x, y, txu::Color::HSV((h + 140) % 255, s, v));
}
}
txCreateWindow(size_x, size_y);
result.render();
загрузит картинку из файла "image.bmp" в txu::Context, затем конвертирует цвет каждого пикселя в систему HSV, прибавит к hue 140 и конвертирует цвет обратно в RGB:
Или вот пример посложнее:
void Blur(txu::Context* source, txu::Context* result, int radius)
{
int size_x = source->getSizeX();
int size_y = source->getSizeY();
result -> resize(size_x, size_y);
for (int x = 0; x < size_x; x++)
{
for (int y = 0; y < size_y; y++)
{
int r = 0, g = 0, b = 0;
int n = 0;
for (int _x = x-radius; _x < x+radius; _x++)
{
for (int _y = y-radius; _y < y+radius; _y++)
{
if (_x < 0 || _x >= size_x || _y < 0 || _y >= size_y) continue;
txu::Color color = source->getPixel(_x, _y);
r += color.r, g += color.g, b += color.b;
n++;
}
}
if (n == 0)
continue;
txu::Color color(r/n, g/n, b/n);
result->setPixel(x, y, color);
}
}
}
Эта функция размывает картинку. Вызовем её с радиусом в 5 пикселей:
txu::Context source("image.bmp");
txu::Context result;
Blur(&source, &result, 5);
txCreateWindow(result.getSizeX(), result.getSizeY());
result.render();
И получим размытое изображение на экране:
Экземпляром класса можно пользоваться так же, как и HDC. Для этого в нём есть соответствующий оператор.
- txu::Context()
- txu::Context(int size_x, int size_y)
- txu::Context(const Context& that)
- txu::Context(const HDC& dc)
- txu::Context(const char* filename)
- bool txu::Context::create()
- bool txu::Context::create(int size_x, int size_y)
- bool txu::Context::create(const Context& that)
- bool txu::Context::create(const HDC& dc)
- bool txu::Context::create(const char* filename)
- bool txu::Context::loadFromFile(const char* filename)
- bool txu::Context::saveToFile(const char* filename)
- Coord2D txu::Context::getSize()
- int txu::Context::getSizeX()
- int txu::Context::getSizeY()
- void txu::Context::resize(int new_size_x, int new_size_y)
- void txu::Context::render(HDC dc = txDC (), int x = 0, int y = 0, int width = 0, int height = 0)
- void txu::Context::clear(txu::Color color)
- void txu::Context::capture(HWND wnd = nullptr)
- txu::Context::operator HDC&()
- RGBQUAD* txu::Context::getBuffer()
- size_t txu::Context::getBufferLength()
- RGBQUAD* txu::Context::access(size_t index)
- RGBQUAD* txu::Context::access(int x, int y)
- void txu::Context::setPixel(int x, int y, txu::Color color, bool blend = false)
- txu::Color txu::Context::getPixel(int x, int y)
- void txu::Context::setColor(txu::Color color, int thikness = 0)
- void txu::Context::setFillColor(txu::Color color)
- void txu::Context::setFont(HFONT font)
- void txu::Context::setFont(const char* name, int sy, int sx = -1, int bold = FW_DONTCARE, bool italic = false, bool underline = false, bool strikeout = false, double angle = 0)
Заново инициализирует изображение в соответствии с указанными параметрами. Возвращает true в случае успеха.
Загружает изображение из файла, указанного в параметрах. Помимо .bmp я реализовал загрузку изображений формата png посредством libpng.
Для того, чтобы загрузить файл формата png, убедитесь, что у вас установлена библиотека libpng, а перед включением TXU.h вы объявили макрос TXU_USE_PNG. Возможно, библиотека libpng у вас уже установлена (по крайней мере у меня она уже была), а если нет, вы можете установить > её при помощи vcpkg
Функция вернёт true если изображение загружено успешно, или false - в обратном случае.
Вот небольшой пример загрузки изображения из png-файла:
#define TXU_USE_PNG
//-------------------
#include <TXLib.h>
#include <TXU.h>
//-------------------
int main ()
{
txu::Context image;
image.loadFromFile("image.png");
int size_x = image.getSizeX();
int size_y = image.getSizeY();
_txWindowStyle = WS_NOFRAME;
txCreateWindow(size_x, size_y);
image.render();
return 0;
}
В результате на экране кошка.
Сохраняет изображение в файл, указанный в параметрах. По умолчанию сохраняет в формате .bmp, однако, если вы подключили использование libpng (см bool txu::Context::loadFromFile (const char* filename)), функция автоматически определит его расширение по строке имени файла. То есть, если в конце имени файла указано ".png", и при этом подключён libpng, то изображение сохранится в формате png. В любых других случаях, изображение будет сохранено в формате bmp.
Возвращает размер изображения.
Возвращает ширину изображения.
Возвращает высоту изображения.
Меняет размер изображения в соответствии с параметрами, при этом сохраняя исходное изображение.
Копирует изображение в HDC, указанный в параметрах. Если HDC не указан, изображение копируется в окно TXLib. В параметрах также можно указать позицию и размер копируемого изображения.
Очищает изображение указанным в параметрах цветом.
Захватывает изображения окна. По умолчанию дексриптор окна равен nullptr, что означает, что захвачен будет весь экран.
Оператор преобразования к HDC.
Возвращает указатель на начало буфера изображения в формате RGBQUAD.
Возвращает размер буфера изображения.
Возвращает указатель на пиксель изорбажения под индексом, указанным в параметрах. Внутри функции существует проверка индекса, благодаря которой функция вернёт nullptr если индекс вышел за границы массива. Обратите внимание, что эта проверка работает только в debug сборке. Если выйти за границы в сборке release, может произойти исключение access violation.
Делает то же, что и txu::Context::access (size_t index), но вместа индекса принимает координаты пикселя.
Устанавливает пиксель в точке, указанной параметрами x и y с учётом альфа-канала входного цвета. Если в качестве последнего параметра передан false, альфа-канал не будет учтён, то есть в буфер изображения передастся цвет без изменений.
Возвращает цвет пикселя по указанным координатам. Если координаты выходят за рамки изображения, функция вернёт txu::Color::Black.
Устанавливает цвет и толщину обводки для внутреннего HDC. Тоже самое, что и txSetColor.
Устанавливает цвет заливки для внутреннего HDC. Тоже самое, что и txSetFillColor.
Устанавливает шрифт для внутреннего HDC, указанный в параметрах. В качестве параметра используйте txu::Font.
void txu::Context::setFont(const char* name, int sy, int sx = -1, int bold = FW_DONTCARE, bool italic = false, bool underline = false, bool strikeout = false, double angle = 0)
Устанавливает шрифт для внутреннего HDC по указанным параметрам. То же самое, что и txSelectFont.
Класс, предназначенный для представления единиц времени в удобном формате. Поначалу, может показаться, что эта вещь бесполезна. Ведь время это же просто величина, как расстояние и скорость? В простых случаях - так и есть. Программист заводит переменную, к примеру, int timeout и вызвает абстрактную функцию Sleep (timeout). Как правило, для представления времени в программировании используются милисекунды, а значит timeout - время (в милисекундах). Но что если надо представить время не в милисекундах, а, например, в секундах? Тогда значение придётся умножить на 1000, а значит вызов Sleep будет происходить как Sleep (timeout * 1000). Но любой человек, посмотревший на такой код может сказать: А что это за "магическое" число 1000? Магическими числами называют численные выражения, не пояснённые и не обозначенные никакой переменной, из за чего сложно понять для чего они предназначаются. Все эти проблемы и решает класс txu::Time. С его использованием, предыдущий пример будет выглядеть так:
txu::Time timeout = txu::Time::seconds (1);
Sleep (timeout);
Всё, теперь ничего пояснять не нужно. Вы можете инициализировать класс пятью разными способами из микросекунд, милисекунд, секунд, минут и часов.
txu::Time::microseconds (1000000) ==
txu::Time::milliseconds (1000) ==
txu::Time::seconds (1) ==
txu::Time::minutes (1/60) ==
txu::Time::hours (1/3600);
Все эти записи эквивалентны и равняются одной секунде.
Но даже это не предел удобства! Помните эти буквы после чисел, обозначающие тип числа? 10u 10f 10l и.т.д. Эти постификсы называются литеральными операторами. И разумеется, c++ был бы не ++, если бы в нём нельзя было определить пользовательские литеральные операторы. И в классе Time они тоже есть.
Хотите вызвать txSleep на 8 часов? зачем... Да без проблем!
txSleep (8_hours);
Для класса определены следующие литеральные операторы:
- _mcsec | время из микросекунд
- _msec | время из миллисекунд
- _sec | время из секунд
- _min | время из минут
- _hours | время из часов
Все они возвращают объект типа txu::Time, с которым вы уже можете делать всё что душе угодно.
Разумеется, после создания переменной типа Time, вы можете достать из неё значения в любом удобном формате с помощью Time::getMicroseconds, Time::getMilliseconds, и.т.д.
По умолчанию, время присваевается в милисекундах, то есть:
txu::Time time = 1000; // переменная time будет равна 1000 милисекундам
Ну и разумеется, в классе предусмотрен оператор приведения к double:
double milliseconds = 1_sec; // переменная milliseconds будет равна 1000
Оператор так же возвращает значение в милисекундах. Поэтому, вы можете использовать Time как обычное число в функциях, принимающих время в милисекундах.
- txu::Time::Time (Time::time_t time)
- txu::Time::Time (const Time& that)
- txu::Time::Time ()
- txu::Time::time_t txu::Time::getMicroseconds ()
- txu::Time::time_t txu::Time::getMilliseconds ()
- txu::Time::time_t txu::Time::getSeconds ()
- txu::Time::time_t txu::Time::getMinutes ()
- txu::Time::time_t txu::Time::getHours ()
- txu::Time txu::Time::microseconds (Time::time_t microseconds)
- txu::Time txu::Time::milliseconds (Time::time_t millisedonds)
- txu::Time txu::Time::seconds (Time::time_t seconds)
- txu::time txu::Time::minutes (Time::time_t minutes)
- txu::Time txu::Time::hours (Time::time_t hours)
- txu::Time operator double ()
- txu::Time operator = (const Time& that)
- txu::Time::operator - ()
- txu::Time::operator += (const Time& that)
- txu::Time::operator -= (const Time& that)
- bool operator == (const txu::Time& a, const txu::Time& b)
- bool operator != (const txu::Time& a, const txu::Time& b)
- txu::Time operator + (const txu::Time& a, const txu::Time& b)
- txu::Time operator - (const txu::Time& b, const txu::Time& b)
- txu::Time operator "" _mcsec (long long unsigned microseconds)
- txu::Time operator "" _msec (long long unsigned milliseconds)
- txu::Time operator "" _sec (long long unsigned seconds)
- txu::Time operator "" _min (long long unsigned minutes)
- txu::Time operator "" _hours (long long unsigned hours)
- txu::Time operator "" _mcsec (long double microseconds)
- txu::Time operator "" _msec (long double milliseconds)
- txu::Time operator "" _sec (long double seconds)
- txu::Time operator "" _min (long double minutes)
- txu::Time operator "" _hours (long double hours)
Это тип абстрактной единицы времени. По сути представляет из себя знаковое число с плавающей точкой.
Возвращают время в указанных единицах. getMicroseconds вернёт микросекунды, getMilliseconds - милисекунды, и так далее.
Возвращает время в милисекундах.
Функции txu::Time::milliseconds, txu::Time::seconds и другие без префикса get - являются статическими (то есть их можно вызвать, не создавая переменную типа Time) и возвращают объект типа txu::Time, созданный в указанной еденице времени из числа, указанного в параметре.
Оператор присваивания.
Возвращает объект класса с отрицательным значением времени.
Операторы, такие как += и -= - выполняют то же, что и математические += и -=.
Возвращает true, если значение времени левого операнда равно значению правого.
Возвращает true, если значения операндов не равны.
Операторы, такие как + и - - выполняют то же, что и математические + и -.
Возвращают объект типа txu::Time, в зависимости от оператора. _mcsec возвращает микросекунды, _msec - миллисекунды, _sec - секунды, _min - минуты, и _hours - часы. Литеральный оператор нужно писать сразу после числа, без пробелов. Синтаксис выглядит так:
txu::Time time = 1400_msec;
Тогда time будер равна 1400 миллисекундам.
Это сопутствующий txu::Time класс. Он выполняет функцию таймера, как несложно догадаться из названия. Класс очень простой, в нём всего 2 функции, но полезный. Он считает время не в милисекундах, как например примитывный GetTickCount (), а в микросекундах, используя для работы значения частоты и тиков процессора, так что он позволяет выявить даже самые незначительные различия во времени.
Его использование крайне простое, например, для измерения времени, которое занимает функция test, подойдёт следующий код:
txu::Timer timer;
timer.start ();
test ();
txu::Time elapsed = timer.getTime ();
printf ("Function call elapsed %lf microseconds\n", elapsed.getMicroseconds ());
Для начала отсчёта нужно вызвать функцию start. Дальше, для получения прошедшего времени на текущий момент - вызвовите функцию getTime (), которая вернёт объект типа txu::Time.
- txu::Timer::Timer (const Timer& that)
- txu::Timer::Timer ()
Начинает отсчёт времени с текущего момента.
Возвращает прошедшее с момента вызва функции start время в виде объекта txu::Time.
Простой класс, предназначенный для хранения и воспроизведения звуков формата wav. С его помощью нельзя редактировать или записывать звуки, он предназначен только для хранения данных wav-файла и их воспроизведения. Это нужно для того чтобы не подгружать один и тот же файл каждый раз при его проигрывании, что довольно сильно экономит ресурсы, если звук проигрывается часто. В целом, воспроизводить звуки из буффера сэмплов сам winapi позволяет, а загрузку и сохранение вполне реально реализовать самостоятельно. Но задача эта не самая простая, так что скорее всего я реализую бóльшие возможности позже, когда возникнет необходимость.
Обращаться с классом очень просто. Вот пример кода, который загружает и проигрывает звук из файла "sound.wav":
txu::Sound sound ("sound.wav");
sound.play ();
- txu::Sound::Sound ()
- txu::Sound::Sound (const char* filename)
- txu::Sound::Sound (Sound& copy)
- txu::Sound::Sound (Sound&& copy)
- bool txu::Sound::loadFromFile (const char* filename)
- void txu::Sound::play ()
- void txu::Sound::playAsync ()
Загружает звук из файла. В случае, если формат файла не соответствует wav, функция вернёт false и не станет его загружать. Если файл загрузится успешно, возвращает true.
Проигрывает звук, останавливая программу на время воспроизведения.
Проигрывает звук параллельно с работой программы.
Я буду рад ответить на ваши вопросы и предложения. В будущем я собираюсь добавить ещё множество удобных фич!