diff --git a/src/composite.c b/src/composite.c index b7454c8..3400453 100644 --- a/src/composite.c +++ b/src/composite.c @@ -59,33 +59,42 @@ imaging_python_to_c(PyObject *obj) } /** - * img should be an Image object, type 'L' + * img should be an Image object, type 'L' or 'RGBA' + * for RGBA images, operates on the alpha only * factor should be between 0 and 1, inclusive */ -PyObject *brightness(PyObject *img, double factor) { +PyObject *brightness(PyObject *img, float factor) { Imaging imDest; imDest = imaging_python_to_c(img); - assert(imDest); + if (!imDest) + return NULL; + if (strcmp(imDest->mode, "RGBA") != 0 && strcmp(imDest->mode, "L") != 0) { + PyErr_SetString(PyExc_ValueError, + "given image does not have mode \"RGBA\" or \"L\""); + return NULL; + } + + /* how far into image the first alpha byte resides */ + int offset = (imDest->pixelsize == 4 ? 3 : 0); + /* how many bytes to skip to get to the next alpha byte */ + int stride = imDest->pixelsize; + int x, y; int xsize = imDest->xsize; int ysize = imDest->ysize; for (y = 0; y < ysize; y++) { - UINT8 *out = (UINT8 *)imDest->image[y]; - //UINT8 *outmask = (UINT8 *)imDest->image[y] + 3; + UINT8 *out = (UINT8 *)imDest->image[y] + offset; for (x = 0; x < xsize; x++) { - //printf("old out: %d\n", *out); *out *= factor; - //printf("new out: %d\n", *out); - out++; + out += stride; } } return NULL; - } /* the alpha_over function, in a form that can be called from C */ diff --git a/src/overviewer.h b/src/overviewer.h index 5ae9079..d704a83 100644 --- a/src/overviewer.h +++ b/src/overviewer.h @@ -41,7 +41,7 @@ Imaging imaging_python_to_c(PyObject *obj); PyObject *alpha_over(PyObject *dest, PyObject *src, PyObject *mask, int dx, int dy, int xsize, int ysize); PyObject *alpha_over_wrap(PyObject *self, PyObject *args); -PyObject *brightness(PyObject *img, double factor); +PyObject *brightness(PyObject *img, float factor); /* in iterate.c */ typedef struct { diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index e9b5aae..10d5bcd 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -133,8 +133,8 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, /* shades the drawn block with the given facemask/black_color, based on the lighting results from (x, y, z) */ static inline void -do_shading_for_face(RenderModeLighting *self, RenderState *state, - int x, int y, int z, PyObject *facemask) { +do_shading_with_mask(RenderModeLighting *self, RenderState *state, + int x, int y, int z, PyObject *facemask) { /* first, check for occlusion if the block is in the local chunk */ if (x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 128) { unsigned char block = getArrayByte3D(state->blocks, x, y, z); @@ -220,10 +220,15 @@ rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject RenderModeLighting* self = (RenderModeLighting *)data; int x = state->x, y = state->y, z = state->z; - // TODO whole-block shading for transparent blocks - do_shading_for_face(self, state, x, y, z+1, self->facemasks[0]); - do_shading_for_face(self, state, x-1, y, z, self->facemasks[1]); - do_shading_for_face(self, state, x, y+1, z, self->facemasks[2]); + if (is_transparent(state->block)) { + /* transparent: do shading on whole block */ + do_shading_with_mask(self, state, x, y, z, mask); + } else { + /* opaque: do per-face shading */ + do_shading_with_mask(self, state, x, y, z+1, self->facemasks[0]); + do_shading_with_mask(self, state, x-1, y, z, self->facemasks[1]); + do_shading_with_mask(self, state, x, y+1, z, self->facemasks[2]); + } } RenderModeInterface rendermode_lighting = {