#include <mil.h>
void PrintHeader()
{
MosPrintf(MIL_TEXT("[EXAMPLE NAME]\n")
MIL_TEXT("AlphaBlending\n\n")
MIL_TEXT("[SYNOPSIS]\n")
MIL_TEXT("This program demonstrates how to combine MimArithMultiple and \n")
MIL_TEXT("MbufClearCond to create a constant alpha-blended overlay.\n\n")
MIL_TEXT("[MODULES USED]\n")
MIL_TEXT("Modules used: application, system, display, buffer,\n")
MIL_TEXT("graphic, image processing.\n\n"));
MosPrintf(MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
}
static MIL_CONST_TEXT_PTR COLOR_IMAGE_FILE = M_IMAGE_PATH MIL_TEXT("BaboonRGB.mim");
static MIL_CONST_TEXT_PTR ALPHA_OVERLAY_IMAGE = M_IMAGE_PATH MIL_TEXT("imaginglogo.mim");
static const MIL_INT USER_TRANSPARENT_COLOR = M_COLOR_WHITE;
static const MIL_INT INITIAL_ALPHA_VALUE = 160;
static const MIL_INT ALPHA_INCREMENT = 5;
static const MIL_INT COLOR_SPACING = 5;
static const MIL_INT SQUARE_SIZE = 50;
static const MIL_INT NB_COLORS = 5;
static const MIL_INT PALETTE_COLORS[NB_COLORS] =
{
M_RGB888(192, 0, 0),
M_RGB888(0, 192, 0),
M_RGB888(0, 0, 192),
M_RGB888(192, 0, 192),
M_RGB888(192, 192, 0)
};
static const MIL_INT BRUSH_RADIUS = 5;
struct SHookData
{
MIL_ID MilDisplay;
MIL_ID MilGraContext;
MIL_ID MilGraList;
MIL_ID MilDisplayedImage;
MIL_ID MilOverlay;
MIL_ID MilUserOverlay;
MIL_INT DrawingColor;
MIL_INT OverlayTransparentColor;
MIL_INT Alpha;
MIL_INT MinusAlphaLabel;
MIL_INT PlusAlphaLabel;
};
void AlphaBlend(MIL_ID MilDisplayedImage, MIL_ID MilOverlay, MIL_ID MilUserOverlay,
MIL_INT UserTransparentColor, MIL_INT OverlayTransparentColor, MIL_INT Alpha);
void DrawAlphaString(MIL_ID MilGraContext, MIL_ID MilGraList, MIL_INT Alpha);
MIL_INT MFTYPE MouseMove(MIL_INT HookType, MIL_ID MilEvent, void *pUserData);
MIL_INT MFTYPE GraphicSelected(MIL_INT HookType, MIL_ID MilEvent, void *pUserData);
int MosMain(void)
{
PrintHeader();
MIL_ID MilApplication = MappAlloc(M_DEFAULT, M_NULL);
MIL_ID MilSystem = MsysAlloc(M_DEFAULT, M_SYSTEM_DEFAULT, M_DEFAULT, M_DEFAULT, M_NULL);
MIL_ID MilDisplay;
MdispAlloc(MilSystem, M_DEFAULT, MIL_TEXT("M_DEFAULT"), M_WINDOWED, &MilDisplay);
MIL_ID MilGraContext = MgraAlloc(MilSystem, M_NULL);
MIL_ID MilImage = MbufRestore(COLOR_IMAGE_FILE, MilSystem, M_NULL);
MIL_INT ColorImageSizeX = MbufInquire(MilImage, M_SIZE_X, M_NULL);
MIL_INT ColorImageSizeY = MbufInquire(MilImage, M_SIZE_Y, M_NULL);
MdispSelect(MilDisplay, MilImage);
MIL_ID MilUserOverlay = MbufAllocColor(MilSystem, 3, ColorImageSizeX, ColorImageSizeY,
8 + M_UNSIGNED, M_IMAGE + M_PROC + M_BGR32 + M_PACKED, M_NULL);
MbufClear(MilUserOverlay, (MIL_DOUBLE)USER_TRANSPARENT_COLOR);
MIL_INT AlphaImageSizeX = MbufDiskInquire(ALPHA_OVERLAY_IMAGE, M_SIZE_X, M_NULL);
MIL_INT AlphaImageSizeY = MbufDiskInquire(ALPHA_OVERLAY_IMAGE, M_SIZE_Y, M_NULL);
MIL_ID MilTransparentImageChild = MbufChild2d(MilUserOverlay,
ColorImageSizeX - AlphaImageSizeX,
0,
AlphaImageSizeX,
AlphaImageSizeY,
M_NULL);
MbufLoad(ALPHA_OVERLAY_IMAGE, MilTransparentImageChild);
MbufFree(MilTransparentImageChild);
MIL_ID MilOverlay = MdispInquire(MilDisplay, M_OVERLAY_ID, M_NULL);
MIL_INT OverlayTransparentColor = MdispInquire(MilDisplay, M_TRANSPARENT_COLOR, M_NULL);
AlphaBlend(MilImage, MilOverlay, MilUserOverlay,
USER_TRANSPARENT_COLOR, OverlayTransparentColor, INITIAL_ALPHA_VALUE);
MosPrintf(MIL_TEXT("The user overlay image has been alpha blended with the displayed\n")
MIL_TEXT("image. Only the non-transparent pixels have been copied on the\n")
MIL_TEXT("display's overlay.\n\n")
MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MIL_ID MilGraList = MgraAllocList(MilSystem, M_DEFAULT, M_NULL);
MgraColor(MilGraContext, (MIL_DOUBLE)PALETTE_COLORS[0]);
MgraArcFill(MilGraContext, MilGraList, -BRUSH_RADIUS, -BRUSH_RADIUS,
BRUSH_RADIUS, BRUSH_RADIUS, 0, 360);
MgraControl(MilGraContext, M_INPUT_UNITS, M_DISPLAY);
MgraControlList(MilGraList, M_GRAPHIC_INDEX(0), M_DEFAULT, M_SELECTABLE, M_DISABLE);
MgraColor(MilGraContext, M_COLOR_BLACK);
MgraRectAngle(MilGraContext, MilGraList,
0,
0,
SQUARE_SIZE + 2 * COLOR_SPACING,
(NB_COLORS+1) * (SQUARE_SIZE + COLOR_SPACING) + COLOR_SPACING,
0, M_FILLED);
MgraControlList(MilGraList, M_GRAPHIC_INDEX(1), M_DEFAULT, M_SELECTABLE, M_DISABLE);
for(MIL_INT c = 0; c < NB_COLORS; c++)
{
MgraColor(MilGraContext, (MIL_DOUBLE)PALETTE_COLORS[c]);
MgraRectAngle(MilGraContext, MilGraList,
COLOR_SPACING,
COLOR_SPACING + c * (SQUARE_SIZE + COLOR_SPACING),
SQUARE_SIZE,
SQUARE_SIZE,
0, M_FILLED);
}
MgraColor(MilGraContext, M_COLOR_WHITE);
MgraRectAngle(MilGraContext, MilGraList,
COLOR_SPACING,
COLOR_SPACING + NB_COLORS * (SQUARE_SIZE + COLOR_SPACING),
SQUARE_SIZE/2,
SQUARE_SIZE,
0, M_FILLED);
MIL_INT MinusLabel = MgraInquireList(MilGraList, M_LIST, M_DEFAULT, M_LAST_LABEL, M_NULL);
MgraRectAngle(MilGraContext, MilGraList,
COLOR_SPACING + SQUARE_SIZE/2,
COLOR_SPACING + NB_COLORS * (SQUARE_SIZE + COLOR_SPACING),
SQUARE_SIZE/2,
SQUARE_SIZE,
0, M_FILLED);
MIL_INT PlusLabel = MgraInquireList(MilGraList, M_LIST, M_DEFAULT, M_LAST_LABEL, M_NULL);
MgraControl(MilGraContext, M_TEXT_ALIGN_HORIZONTAL, M_CENTER);
MgraControl(MilGraContext, M_TEXT_ALIGN_VERTICAL, M_CENTER);
MgraControl(MilGraContext, M_BACKGROUND_MODE, M_TRANSPARENT);
MgraControl(MilGraContext, M_SELECTABLE, M_DISABLE);
MgraColor(MilGraContext, M_COLOR_BLACK);
MgraText(MilGraContext, MilGraList,
COLOR_SPACING + SQUARE_SIZE/2,
COLOR_SPACING + SQUARE_SIZE/3 + NB_COLORS * (SQUARE_SIZE + COLOR_SPACING),
MIL_TEXT("- a +"));
DrawAlphaString(MilGraContext, MilGraList, INITIAL_ALPHA_VALUE);
MdispControl(MilDisplay, M_ASSOCIATED_GRAPHIC_LIST_ID, MilGraList);
SHookData HookData;
HookData.MilDisplay = MilDisplay;
HookData.MilGraContext = MilGraContext;
HookData.MilGraList = MilGraList;
HookData.DrawingColor = PALETTE_COLORS[0];
HookData.MilDisplayedImage = MilImage;
HookData.MilOverlay = MilOverlay;
HookData.MilUserOverlay = MilUserOverlay;
HookData.OverlayTransparentColor = OverlayTransparentColor;
HookData.Alpha = INITIAL_ALPHA_VALUE;
HookData.MinusAlphaLabel = MinusLabel;
HookData.PlusAlphaLabel = PlusLabel;
MdispHookFunction(MilDisplay, M_MOUSE_MOVE, MouseMove, &HookData);
MgraControlList(MilGraList, M_LIST, M_DEFAULT, M_MULTIPLE_SELECTION, M_DISABLE);
MgraHookFunction(MilGraList, M_GRAPHIC_SELECTION_MODIFIED,
GraphicSelected, &HookData);
MdispControl(MilDisplay, M_GRAPHIC_LIST_INTERACTIVE, M_ENABLE);
MosPrintf(MIL_TEXT("You can now interact with the display to modify the alpha-blended\n")
MIL_TEXT("overlay with your mouse:\n")
MIL_TEXT(" - Left click to select a brush color from the palette.\n")
MIL_TEXT(" - Left click on the plus or minus to change the alpha value.\n")
MIL_TEXT(" - Left click and move the mouse to draw some lines.\n")
MIL_TEXT(" - Right click and move the mouse to erase areas.\n\n")
MIL_TEXT("Press <Enter> to continue.\n\n"));
MosGetch();
MgraHookFunction(MilGraList, M_GRAPHIC_SELECTION_MODIFIED + M_UNHOOK,
GraphicSelected, &HookData);
MdispHookFunction(MilDisplay, M_MOUSE_MOVE + M_UNHOOK,
MouseMove, &HookData);
MbufFree(MilUserOverlay);
MbufFree(MilImage);
MgraFree(MilGraList);
MgraFree(MilGraContext);
MdispFree(MilDisplay);
MsysFree(MilSystem);
MappFree(MilApplication);
return 0;
}
void AlphaBlend(MIL_ID MilDisplayedImage, MIL_ID MilOverlay, MIL_ID MilUserOverlay,
MIL_INT UserTransparentColor, MIL_INT OverlayTransparentColor, MIL_INT Alpha)
{
if(Alpha > 0)
{
MimArithMultiple(MilDisplayedImage, 256-Alpha, MilUserOverlay, (MIL_DOUBLE)Alpha, 256,
MilOverlay, M_MULTIPLY_ACCUMULATE_2, M_DEFAULT);
MbufClearCond(MilOverlay,
M_RGB888_R(OverlayTransparentColor),
M_RGB888_G(OverlayTransparentColor),
M_RGB888_B(OverlayTransparentColor),
MilUserOverlay, M_EQUAL, (MIL_DOUBLE)UserTransparentColor);
}
else
MbufClear(MilOverlay, (MIL_DOUBLE)OverlayTransparentColor);
}
MIL_INT MFTYPE MouseMove(MIL_INT HookType, MIL_ID MilEvent, void *pUserData)
{
SHookData* pHookData = (SHookData*) pUserData;
MIL_INT ArcToDrawColor = -1;
MIL_INT CombinationKeys;
MdispGetHookInfo(MilEvent, M_COMBINATION_KEYS, &CombinationKeys);
if((CombinationKeys & M_MOUSE_LEFT_BUTTON) == M_MOUSE_LEFT_BUTTON)
ArcToDrawColor = pHookData->DrawingColor;
else if((CombinationKeys & M_MOUSE_RIGHT_BUTTON) == M_MOUSE_RIGHT_BUTTON)
ArcToDrawColor = USER_TRANSPARENT_COLOR;
MIL_DOUBLE MousePosBufX;
MIL_DOUBLE MousePosBufY;
MdispGetHookInfo(MilEvent, M_MOUSE_POSITION_BUFFER_X, &MousePosBufX);
MdispGetHookInfo(MilEvent, M_MOUSE_POSITION_BUFFER_Y, &MousePosBufY);
if(ArcToDrawColor != -1)
{
MgraColor(pHookData->MilGraContext, (MIL_DOUBLE)ArcToDrawColor);
MgraArcFill(pHookData->MilGraContext, pHookData->MilUserOverlay, MousePosBufX,
MousePosBufY, BRUSH_RADIUS, BRUSH_RADIUS, 0, 360);
MdispControl(pHookData->MilDisplay, M_UPDATE, M_DISABLE);
AlphaBlend(pHookData->MilDisplayedImage, pHookData->MilOverlay,
pHookData->MilUserOverlay, USER_TRANSPARENT_COLOR,
pHookData->OverlayTransparentColor, pHookData->Alpha);
MdispControl(pHookData->MilDisplay, M_UPDATE, M_ENABLE);
}
MgraControlList(pHookData->MilGraList, M_GRAPHIC_INDEX(0), M_DEFAULT,
M_POSITION_X, MousePosBufX);
MgraControlList(pHookData->MilGraList, M_GRAPHIC_INDEX(0), M_DEFAULT,
M_POSITION_Y, MousePosBufY);
return 0;
}
MIL_INT MFTYPE GraphicSelected(MIL_INT HookType, MIL_ID MilEvent, void *pUserData)
{
SHookData* pHookData = (SHookData*) pUserData;
MIL_INT GraphicSelected;
MgraGetHookInfo(MilEvent, M_GRAPHIC_LABEL_VALUE, &GraphicSelected);
MIL_ID MilGraList;
MgraGetHookInfo(MilEvent, M_GRAPHIC_LIST_ID, &MilGraList);
if(GraphicSelected != M_NO_LABEL)
{
bool UpdateAlpha = true;
if(GraphicSelected == pHookData->MinusAlphaLabel)
pHookData->Alpha -= pHookData->Alpha > 4 ? ALPHA_INCREMENT : 0;
else if(GraphicSelected == pHookData->PlusAlphaLabel)
pHookData->Alpha += pHookData->Alpha < 251 ? ALPHA_INCREMENT : 0;
else
{
MgraInquireList(MilGraList, M_GRAPHIC_LABEL(GraphicSelected), M_DEFAULT,
M_COLOR + M_TYPE_MIL_INT, &pHookData->DrawingColor);
MgraControlList(MilGraList, M_GRAPHIC_INDEX(0), M_DEFAULT,
M_COLOR, pHookData->DrawingColor);
UpdateAlpha = false;
}
MgraControlList(MilGraList, M_GRAPHIC_LABEL(GraphicSelected), M_DEFAULT,
M_GRAPHIC_SELECTED, M_FALSE);
if(UpdateAlpha)
{
MdispControl(pHookData->MilDisplay, M_UPDATE, M_DISABLE);
MIL_INT NbGraphics = MgraInquireList(MilGraList, M_LIST, M_DEFAULT,
M_NUMBER_OF_GRAPHICS, M_NULL);
MgraControlList(MilGraList, M_GRAPHIC_INDEX(NbGraphics-1), M_DEFAULT,
M_DELETE, M_DEFAULT);
AlphaBlend(pHookData->MilDisplayedImage, pHookData->MilOverlay,
pHookData->MilUserOverlay, USER_TRANSPARENT_COLOR,
pHookData->OverlayTransparentColor, pHookData->Alpha);
DrawAlphaString(pHookData->MilGraContext, MilGraList, pHookData->Alpha);
MdispControl(pHookData->MilDisplay, M_UPDATE, M_ENABLE);
}
}
return 0;
}
void DrawAlphaString(MIL_ID MilGraContext, MIL_ID MilGraList, MIL_INT Alpha)
{
MIL_TEXT_CHAR AlphaString[6];
MosSprintf(AlphaString, 6, MIL_TEXT(" %i "), Alpha);
MgraColor(MilGraContext, M_COLOR_BLACK);
MgraText(MilGraContext, MilGraList,
COLOR_SPACING + SQUARE_SIZE/2,
COLOR_SPACING + 2*SQUARE_SIZE/3 + NB_COLORS * (SQUARE_SIZE + COLOR_SPACING),
AlphaString);
}