187 lines
4.1 KiB
C
187 lines
4.1 KiB
C
#include "e_efx_private.h"
|
|
#include <math.h>
|
|
|
|
#define DATA8 unsigned char
|
|
#define A_VAL(p) (((DATA8 *)(p))[3])
|
|
#define R_VAL(p) (((DATA8 *)(p))[2])
|
|
#define G_VAL(p) (((DATA8 *)(p))[1])
|
|
#define B_VAL(p) (((DATA8 *)(p))[0])
|
|
|
|
typedef struct E_Efx_Bumpmap_Data
|
|
{
|
|
E_EFX *e;
|
|
int x;
|
|
int y;
|
|
int z;
|
|
int depth;
|
|
int red;
|
|
int green;
|
|
int blue;
|
|
int ambient;
|
|
unsigned int *img_data;
|
|
} E_Efx_Bumpmap_Data;
|
|
|
|
static void
|
|
_bumpmap(E_Efx_Bumpmap_Data *ebd)
|
|
{
|
|
Evas_Object *o;
|
|
int w;
|
|
int h;
|
|
int i, j;
|
|
|
|
int x;
|
|
int y;
|
|
int z;
|
|
int depth;
|
|
int red;
|
|
int green;
|
|
int blue;
|
|
int ambient;
|
|
|
|
int z_2, lightx, lighty;
|
|
int mx;
|
|
int my;
|
|
unsigned int *d1;
|
|
unsigned int *src;
|
|
unsigned int *mp;
|
|
unsigned int *mpy;
|
|
unsigned int *mpp;
|
|
|
|
x = ebd->x;
|
|
y = ebd->y;
|
|
z = ebd->z;
|
|
|
|
red = ebd->red / 0x100;
|
|
green = ebd->green / 0x100;
|
|
blue = ebd->blue / 0x100;
|
|
ambient = ebd->ambient / 0x100;
|
|
depth = ebd->depth / 0x100;
|
|
depth /= (255 * (255 + 255 + 255));
|
|
z_2 = z * z;
|
|
|
|
o = ebd->e->obj;
|
|
evas_object_image_size_get(o, &w, &h);
|
|
if ((!w) || (!h)) return;
|
|
|
|
d1 = malloc(w * h * sizeof(int));
|
|
memcpy(d1, ebd->img_data, w * h * sizeof(int));
|
|
src = d1;
|
|
|
|
mpp = ebd->img_data;
|
|
|
|
my = h;
|
|
lighty = -y;
|
|
for (j = h; --j >= 0;)
|
|
{
|
|
mp = mpp;
|
|
mpp += w;
|
|
if (--my <= 0)
|
|
{
|
|
mpp -= w * h;
|
|
my = h;
|
|
}
|
|
mpy = mpp;
|
|
mx = w;
|
|
lightx = -x;
|
|
i = w - 1;
|
|
do
|
|
{
|
|
double v;
|
|
int r, g, b, gr, x1, y_1;
|
|
|
|
gr = A_VAL(mp) * (R_VAL(mp) + G_VAL(mp) + B_VAL(mp));
|
|
y_1 = depth * (A_VAL(mpy) * (R_VAL(mpy) +
|
|
G_VAL(mpy) +
|
|
B_VAL(mpy)) - gr);
|
|
mp++;
|
|
mpy++;
|
|
if (--mx <= 0)
|
|
{
|
|
mp -= w;
|
|
mpy -= w;
|
|
mx = w;
|
|
}
|
|
x1 = depth * (A_VAL(mp) * (R_VAL(mp) +
|
|
G_VAL(mp) + B_VAL(mp)) - gr);
|
|
v = x1 * lightx + y_1 * lighty + z;
|
|
v /= sqrt(((x1 * x1) + (y_1 * y_1) + 1) * ((lightx * lightx) + (lighty * lighty) + z_2));
|
|
v += ambient;
|
|
r = v * R_VAL(src) * red;
|
|
g = v * G_VAL(src) * green;
|
|
b = v * B_VAL(src) * blue;
|
|
if (r < 0)
|
|
r = 0;
|
|
else if (r > 255)
|
|
r = 255;
|
|
if (g < 0)
|
|
g = 0;
|
|
else if (g > 255)
|
|
g = 255;
|
|
if (b < 0)
|
|
b = 0;
|
|
else if (b > 255)
|
|
b = 255;
|
|
R_VAL(src) = r;
|
|
G_VAL(src) = g;
|
|
B_VAL(src) = b;
|
|
|
|
lightx++;
|
|
src++;
|
|
} while (--i >= 0);
|
|
lighty++;
|
|
}
|
|
|
|
evas_object_image_data_set(o, d1);
|
|
evas_object_image_data_update_add(o, 0, 0, w, h);
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
e_efx_bumpmap(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
|
|
{
|
|
E_EFX *e;
|
|
E_Efx_Bumpmap_Data *ebd;
|
|
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(obj, EINA_FALSE);
|
|
|
|
e = evas_object_data_get(obj, "e_efx-data");
|
|
if (!e)
|
|
e = e_efx_new(obj);
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(e, EINA_FALSE);
|
|
|
|
if (!e->bumpmap_data)
|
|
e->bumpmap_data = calloc(1, sizeof(E_Efx_Bumpmap_Data));
|
|
EINA_SAFETY_ON_NULL_RETURN_VAL(e->bumpmap_data, EINA_FALSE);
|
|
ebd = e->bumpmap_data;
|
|
ebd->e = e;
|
|
ebd->x = x;
|
|
ebd->y = y;
|
|
ebd->z = 30;
|
|
ebd->depth = 0x200;
|
|
ebd->red = 0x200;
|
|
ebd->green = 0x200;
|
|
ebd->blue = 0x200;
|
|
ebd->ambient = 0;
|
|
if (!ebd->img_data)
|
|
{
|
|
unsigned int *m;
|
|
int w;
|
|
int h;
|
|
|
|
evas_object_image_size_get(obj, &w, &h);
|
|
m = (unsigned int *)evas_object_image_data_get(obj, 1);
|
|
ebd->img_data = (unsigned int *)malloc(w * h * sizeof(unsigned int));
|
|
if (!ebd->img_data)
|
|
{
|
|
free(ebd);
|
|
return EINA_FALSE;
|
|
}
|
|
printf("memcpy\n");
|
|
memcpy(ebd->img_data, m, (w * h * sizeof(unsigned int)));
|
|
}
|
|
|
|
_bumpmap(ebd);
|
|
|
|
return EINA_TRUE;
|
|
(void)e_efx_speed_str;
|
|
}
|