|
发表于 2019-7-23 10:07:39
|
显示全部楼层
看了下代码,是这么实现的:
- static int ShadeImage16(GUI_MAPPING_CONTEXT * pContext, int xPosLight, int yPosLight) {
- U16 * pBmData;
- int Offset;
- U8 CLight;
- U8 r, g, b;
- U16 Color;
- U16 * pNMap;
- U16 * pData;
- const U8 * pLight;
- U32 LightHalf;
- int y;
- int x;
- int xSizeLight;
- int ySizeLight;
- GUI_RECT Rect;
- int NoLight;
- //
- // Set up variables
- //
- pData = (U16 *)GUI_MEMDEV_GetDataPtr(pContext->hMemDest);
- if (pData == NULL) {
- return 1;
- }
- if (pContext->pBmImage) {
- pBmData = (U16 *)pContext->pBmImage->pData;
- } else {
- pBmData = (U16 *)GUI_MEMDEV_GetDataPtr(pContext->hMemImage);
- if (pBmData == NULL) {
- return 1;
- }
- }
- if (pContext->pbmLight) {
- pLight = (const U8 *)pContext->pbmLight->pData;
- xSizeLight = pContext->pbmLight->XSize;
- ySizeLight = pContext->pbmLight->YSize;
- NoLight = 0;
- } else {
- pLight = NULL;
- xSizeLight = 0;
- ySizeLight = 0;
- NoLight = 1;
- }
- LightHalf = LIGHT_MAX >> 1;
- Offset = 0;
- //
- // Wihtout light the rectangle has the size of the image
- //
- if (NoLight) {
- Rect.x0 = 0;
- Rect.y0 = 0;
- Rect.x1 = pContext->xSize;
- Rect.y1 = pContext->ySize;
- } else {
- //
- // With light only the light area needs to be touched
- //
- _CalcRect(&Rect, pContext, xPosLight, yPosLight);
- }
- //
- // Itterate over the image
- //
- for (y = 0; y < pContext->ySize; y++) {
- for (x = 0; x < pContext->xSize; x += 1, Offset += 1) {
- //
- // Get pixel data from the normal map and the image to be shaded
- //
- pNMap = ((U16 *)pContext->pNMap) + Offset;
- Color = *(pBmData + Offset);
- CLight = _GetLightCoefficient(NoLight, Rect, x, y, pNMap, pLight, xPosLight, yPosLight, xSizeLight, ySizeLight);
- //
- // Grap the colors from the current pixel
- //
- r = (Color & 0xF800) >> 11;
- g = (Color & 0x07E0) >> 5;
- b = Color & 0x001F;
- //
- // Apply coefficient
- //
- if (CLight == 0) {
- //
- // No light, darken pixel
- //
- r = (r >> 2);
- g = (g >> 2);
- b = (b >> 2);
- } else if ((U32)CLight <= LightHalf) {
- //
- // Apply a bit of light to pixels which are outside half of hte light radius
- //
- r = (r >> 2) + ((r - (r >> 2)) * CLight) / LightHalf;
- g = (g >> 2) + ((g - (g >> 2)) * CLight) / LightHalf;
- b = (b >> 2) + ((b - (b >> 2)) * CLight) / LightHalf;
- } else {
- //
- // Apply light to those within range
- //
- r = r + (((0x1F ^ r) * (CLight - LightHalf)) / LightHalf);
- g = g + (((0x3F ^ g) * (CLight - LightHalf)) / LightHalf);
- b = b + (((0x1F ^ b) * (CLight - LightHalf)) / LightHalf);
- }
- //
- // Shift colors bytes into order
- //
- Color = (r << 11) | (g << 5) | b;
- //
- // And write the pixel
- //
- *(pData + y * pContext->xSize + x) = Color;
- }
- }
- return 0;
- }
复制代码
|
|