Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Полупрозрачные непрямоугольные спрайты

87
26 мая 2008 года
Kogrom
2.7K / / 02.02.2008
Цель данной темы – не решение какого-то вопроса, а рассуждение на счет реализации прорисовки полупрозрачных непрямоугольных спрайтов.

Читал статью "Прозрачность - это просто" про применение библиотеки msimg32.dll и функций TransparentBlt, AlphaBlend. Автор внятно объяснил, как нарисовать непрямоугольный спрайт и полупрозрачный прямоугольный спрайт, но как нарисовать полупрозрачный непрямоугольный спрайт объяснил как-то путано и непонятно. При этом ссылается на какие-то недокументированные константы и функции, что немного настораживает.

На мой взгляд, вполне логично было б, если бы была какая-то гибридная функция, типа TransparentBlt, но с указанием коэффициента прозрачности. То есть, часть спрайта с определенным цветом прорисовывалась бы полностью прозрачной, а часть полупрозрачной. Это вполне могло бы пригодиться для рисования теней, приведений (духов), или, например, создания эффекта объема путем наложения полупрозрачной маски на стандартные объекты, разные по цвету. И при этом, не потребовалось бы трудиться над созданием растров с альфа-каналом.

Однако подобной функции я не нашел, поэтому изобрел свою (c++, Win32 API):

Код:
void AlphaTransparent(
    HDC hdcDest, // handle to destination DC
    int xDest, // x-coord of upper-left corner
    int yDest, // y-coord of upper-left corner
    int widthSrc, // source width
    int heightSrc, // source height
    HDC hdcSrc, // handle to source DC
    int xSrc, // x-coord of upper-left corner
    int ySrc, // y-coord of upper-left corner
    UINT crTransparent,   // color to make transparent
    BYTE SourceConstantAlpha // alpha transparency value
)
{
    BLENDFUNCTION blend;
    blend.BlendOp = AC_SRC_OVER;
    blend.BlendFlags = 0;
    blend.AlphaFormat = 0;
    blend.SourceConstantAlpha = SourceConstantAlpha;

    HDC tempDC = CreateCompatibleDC(hdcDest);
    HBITMAP tempBitMap = CreateCompatibleBitmap(hdcDest, widthSrc, heightSrc);
    SelectObject(tempDC, tempBitMap);
    BitBlt(tempDC, 0, 0, widthSrc, heightSrc, hdcDest, xDest, yDest, SRCCOPY);

    TransparentBlt(tempDC, 0, 0, widthSrc, heightSrc, hdcSrc, xSrc, ySrc, widthSrc, heightSrc, crTransparent);
    AlphaBlend(hdcDest, xDest, yDest, widthSrc, heightSrc, tempDC, 0, 0, widthSrc, heightSrc, blend);

    DeleteObject(tempBitMap);
    DeleteDC(tempDC);
}


Вполне вероятно, что это очередной мой "велосипед" и не самый оптимальный, но с поставленной задачей справляется. Масштабирования в этой моей функции нет (мне оно не требуется), но, вероятно, его легко вернуть, если использовать StretchBlt, вместо BitBlt.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог