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);
}
Полупрозрачные непрямоугольные спрайты
Читал статью "Прозрачность - это просто" про применение библиотеки msimg32.dll и функций TransparentBlt, AlphaBlend. Автор внятно объяснил, как нарисовать непрямоугольный спрайт и полупрозрачный прямоугольный спрайт, но как нарисовать полупрозрачный непрямоугольный спрайт объяснил как-то путано и непонятно. При этом ссылается на какие-то недокументированные константы и функции, что немного настораживает.
На мой взгляд, вполне логично было б, если бы была какая-то гибридная функция, типа TransparentBlt, но с указанием коэффициента прозрачности. То есть, часть спрайта с определенным цветом прорисовывалась бы полностью прозрачной, а часть полупрозрачной. Это вполне могло бы пригодиться для рисования теней, приведений (духов), или, например, создания эффекта объема путем наложения полупрозрачной маски на стандартные объекты, разные по цвету. И при этом, не потребовалось бы трудиться над созданием растров с альфа-каналом.
Однако подобной функции я не нашел, поэтому изобрел свою (c++, Win32 API):
Код:
Вполне вероятно, что это очередной мой "велосипед" и не самый оптимальный, но с поставленной задачей справляется. Масштабирования в этой моей функции нет (мне оно не требуется), но, вероятно, его легко вернуть, если использовать StretchBlt, вместо BitBlt.