diff --git a/chunk.py b/chunk.py index 9a25195..1155f40 100644 --- a/chunk.py +++ b/chunk.py @@ -550,10 +550,7 @@ class ChunkRenderer(object): if not img: img = Image.new("RGBA", (384, 1728), (38,92,255,0)) - if self.quadtree.lighting: - c_overviewer.render_loop_lighting(self, img, xoff, yoff, blockData_expanded) - else: - c_overviewer.render_loop(self, img, xoff, yoff, blockData_expanded) + c_overviewer.render_loop(self, img, xoff, yoff, blockData_expanded) for entity in tileEntities: if entity['id'] == 'Sign': diff --git a/src/iterate.c b/src/iterate.c index 4b3a0de..a2478c1 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -19,8 +19,8 @@ #include -/* macro for getting blockID from a chunk of memory */ -#define getBlock(blockThing, x,y,z) (*(unsigned char *)(PyArray_GETPTR3(blockThing, (x), (y), (z)))) +/* macro for getting a value out of a 3D numpy byte array */ +#define getArrayByte3D(array, x,y,z) (*(unsigned char *)(PyArray_GETPTR3((array), (x), (y), (z)))) static PyObject *textures = NULL; static PyObject *chunk_mod = NULL; @@ -50,8 +50,6 @@ int init_chunk_render(void) { return 1; } - Py_DECREF(textures); - Py_DECREF(chunk_mod); return 0; } @@ -79,248 +77,37 @@ texture_alpha_over(PyObject *dest, PyObject *t, int imgx, int imgy) return alpha_over(dest, src, mask, imgx, imgy, 0, 0); } -PyObject* -chunk_render_lighting(PyObject *self, PyObject *args) { - - PyObject *chunk; - PyObject *blockdata_expanded; - int xoff, yoff; - PyObject *img; +/* 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(PyObject *chunk, int x, int y, int z, PyObject *facemask, PyObject *black_color, + PyObject *img, int imgx, int imgy) +{ + // returns new references + PyObject* light_tup = PyObject_CallMethod(chunk, "get_lighting_coefficient", "iii", x, y, z); + PyObject *black_coeff_py = PySequence_GetItem(light_tup, 0); + double black_coeff = PyFloat_AsDouble(black_coeff_py); + Py_DECREF(black_coeff_py); - PyObject *imgsize, *imgsize0_py, *imgsize1_py; - int imgsize0, imgsize1; + PyObject *face_occlude_py = PySequence_GetItem(light_tup, 1); + int face_occlude = PyInt_AsLong(face_occlude_py); + Py_DECREF(face_occlude_py); - PyObject *blocks_py; - PyObject *textures, *blockmap, *special_blocks, *specialblockmap, *chunk_mod, *transparent_blocks; - - int imgx, imgy; - int x, y, z; - - if (!PyArg_ParseTuple(args, "OOiiO", &chunk, &img, &xoff, &yoff, &blockdata_expanded)) - return Py_BuildValue("i", "-1"); - - /* tuple */ - imgsize = PyObject_GetAttrString(img, "size"); - - imgsize0_py = PySequence_GetItem(imgsize, 0); - imgsize1_py = PySequence_GetItem(imgsize, 1); - Py_DECREF(imgsize); - - imgsize0 = PyInt_AsLong(imgsize0_py); - imgsize1 = PyInt_AsLong(imgsize1_py); - Py_DECREF(imgsize0_py); - Py_DECREF(imgsize1_py); - - - /* get the block data directly from numpy: */ - blocks_py = PyObject_GetAttrString(chunk, "blocks"); - - /* - PyObject *left_blocks = PyObject_GetAttrString(chunk, "left_blocks"); - PyObject *right_blocks = PyObject_GetAttrString(chunk, "right_blocks"); - */ - - textures = PyImport_ImportModule("textures"); - chunk_mod = PyImport_ImportModule("chunk"); - - /* TODO can these be global static? these don't change during program execution */ - blockmap = PyObject_GetAttrString(textures, "blockmap"); - special_blocks = PyObject_GetAttrString(textures, "special_blocks"); - specialblockmap = PyObject_GetAttrString(textures, "specialblockmap"); - transparent_blocks = PyObject_GetAttrString(chunk_mod, "transparent_blocks"); - if (transparent_blocks == NULL) { - PyErr_SetString(PyExc_ValueError, - "transparent_blocks is NULL"); - return NULL; - } - PyObject *black_color = PyObject_GetAttrString(chunk_mod, "black_color"); - PyObject *facemasks_py = PyObject_GetAttrString(chunk_mod, "facemasks"); - PyObject *facemasks[3]; - //assert(PyTuple_Check(facemasks_py)); - facemasks[0] = PyTuple_GetItem(facemasks_py, 0); - facemasks[1] = PyTuple_GetItem(facemasks_py, 1); - facemasks[2] = PyTuple_GetItem(facemasks_py, 2); + if (!face_occlude) { + //#composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff)) - - Py_DECREF(textures); - Py_DECREF(chunk_mod); - - - - for (x = 15; x > -1; x--) { - for (y = 0; y < 16; y++) { - imgx = xoff + x*12 + y*12; - /* 128*12 -- offset for z direction, 15*6 -- offset for x */ - imgy = yoff - x*6 + y*6 + 128*12 + 15*6; - for (z = 0; z < 128; z++) { - unsigned char block; - PyObject *blockid; - - imgy -= 12; - - if ((imgx >= imgsize0 + 24) || (imgx <= -24)) { - continue; - } - if ((imgy >= imgsize1 + 24) || (imgy <= -24)) { - continue; - } - - /* get blockid - note the order: x, z, y */ - block = getBlock(blocks_py, x, y, z); - if (block == 0) { - continue; - } - - /* TODO figure out how to DECREF this easily, instead of at - every continue */ - blockid = PyInt_FromLong(block); - - - if ( (x != 0) && (y != 15) && (z != 127) && - !isTransparent(transparent_blocks, getBlock(blocks_py, x-1, y, z)) && - !isTransparent(transparent_blocks, getBlock(blocks_py, x, y, z+1)) && - !isTransparent(transparent_blocks, getBlock(blocks_py, x, y+1, z))) { - continue; - } - - //# top face - //black_coeff, face_occlude = self.get_lighting_coefficient(x, y, z + 1) - - - PyObject *t = NULL; - if (!PySequence_Contains(special_blocks, blockid)) { - /* t = textures.blockmap[blockid] */ - PyObject *t = PyList_GetItem(blockmap, block); - /* PyList_GetItem returns borrowed ref */ - - /* note that this version of alpha_over has a different signature than the - version in _composite.c */ - texture_alpha_over(img, t, imgx, imgy ); - } else { - PyObject *tmp; - - /* this should be a pointer to a unsigned char */ - void* ancilData_p = PyArray_GETPTR3(blockdata_expanded, x, y, z); - unsigned char ancilData = *((unsigned char*)ancilData_p); - if (block == 85) { - /* fence. skip the generate_pseudo_ancildata for now */ - continue; - } - - tmp = PyTuple_New(2); - - Py_INCREF(blockid); /* because SetItem steals */ - PyTuple_SetItem(tmp, 0, blockid); - PyTuple_SetItem(tmp, 1, PyInt_FromLong(ancilData)); - - /* this is a borrowed reference. no need to decref */ - t = PyDict_GetItem(specialblockmap, tmp); - Py_DECREF(tmp); - - } - if ((t != NULL) && (t != Py_None)) - texture_alpha_over(img, t, imgx, imgy ); - - { - // returns new references - PyObject* light_tup = PyObject_CallMethod(chunk, "get_lighting_coefficient", "iii", x, y, z+1); - PyObject *black_coeff_py = PySequence_GetItem(light_tup, 0); - double black_coeff = PyFloat_AsDouble(black_coeff_py); - Py_DECREF(black_coeff_py); - - PyObject *face_occlude_py = PySequence_GetItem(light_tup, 1); - int face_occlude = PyInt_AsLong(face_occlude_py); - Py_DECREF(face_occlude_py); - - - if (!face_occlude) { - //#composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff)) - - PyObject *mask = PyObject_CallMethod(facemasks[0], "copy", NULL); // new ref - //printf("black_coeff: %f\n", black_coeff); - brightness(mask, black_coeff); - //printf("done with brightness\n"); - alpha_over(img, black_color, mask, imgx, imgy, 0, 0); - //printf("done with alpha_over\n"); - Py_DECREF(mask); - - } - } - - - { - // returns new references - PyObject* light_tup = PyObject_CallMethod(chunk, "get_lighting_coefficient", "iii", x-1, y, z); - PyObject *black_coeff_py = PySequence_GetItem(light_tup, 0); - double black_coeff = PyFloat_AsDouble(black_coeff_py); - Py_DECREF(black_coeff_py); - - PyObject *face_occlude_py = PySequence_GetItem(light_tup, 1); - int face_occlude = PyInt_AsLong(face_occlude_py); - Py_DECREF(face_occlude_py); - - - if (!face_occlude) { - //#composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff)) - /* for now, we are lazy and call Image.blend to change the brightness of facemask - * TODO find some faster way? - */ - - PyObject *mask = PyObject_CallMethod(facemasks[1], "copy", NULL); // new ref - //printf("black_coeff: %f\n", black_coeff); - brightness(mask, black_coeff); - //printf("done with brightness\n"); - alpha_over(img, black_color, mask, imgx, imgy, 0, 0); - //printf("done with alpha_over\n"); - Py_DECREF(mask); - - } - } - - - { - // returns new references - PyObject* light_tup = PyObject_CallMethod(chunk, "get_lighting_coefficient", "iii", x, y+1, z); - PyObject *black_coeff_py = PySequence_GetItem(light_tup, 0); - double black_coeff = PyFloat_AsDouble(black_coeff_py); - Py_DECREF(black_coeff_py); - - PyObject *face_occlude_py = PySequence_GetItem(light_tup, 1); - int face_occlude = PyInt_AsLong(face_occlude_py); - Py_DECREF(face_occlude_py); - - - if (!face_occlude) { - //#composite.alpha_over(img, over_color, (imgx, imgy), ImageEnhance.Brightness(facemasks[0]).enhance(black_coeff)) - - PyObject *mask = PyObject_CallMethod(facemasks[2], "copy", NULL); // new ref - //printf("black_coeff: %f\n", black_coeff); - brightness(mask, black_coeff); - //printf("done with brightness\n"); - alpha_over(img, black_color, mask, imgx, imgy, 0, 0); - //printf("done with alpha_over\n"); - Py_DECREF(mask); - - } - } - - - - } - } - } - - Py_DECREF(facemasks_py); - Py_DECREF(blocks_py); - Py_DECREF(blockmap); - Py_DECREF(special_blocks); - Py_DECREF(specialblockmap); - - return Py_BuildValue("i",2); - + PyObject *mask = PyObject_CallMethod(facemask, "copy", NULL); // new ref + //printf("black_coeff: %f\n", black_coeff); + brightness(mask, black_coeff); + //printf("done with brightness\n"); + alpha_over(img, black_color, mask, imgx, imgy, 0, 0); + //printf("done with alpha_over\n"); + Py_DECREF(mask); + + } } + /* TODO triple check this to make sure reference counting is correct */ PyObject* @@ -363,6 +150,19 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *right_blocks = PyObject_GetAttrString(chunk, "right_blocks"); */ + PyObject *quadtree = PyObject_GetAttrString(chunk, "quadtree"); + PyObject *lighting_py = PyObject_GetAttrString(quadtree, "lighting"); + int lighting = PyObject_IsTrue(lighting_py); + Py_DECREF(lighting_py); + Py_DECREF(quadtree); + + PyObject *black_color = PyObject_GetAttrString(chunk_mod, "black_color"); + PyObject *facemasks_py = PyObject_GetAttrString(chunk_mod, "facemasks"); + PyObject *facemasks[3]; + // borrowed references, don't need to be decref'd + facemasks[0] = PyTuple_GetItem(facemasks_py, 0); + facemasks[1] = PyTuple_GetItem(facemasks_py, 1); + facemasks[2] = PyTuple_GetItem(facemasks_py, 2); for (x = 15; x > -1; x--) { for (y = 0; y < 16; y++) { @@ -384,7 +184,7 @@ chunk_render(PyObject *self, PyObject *args) { /* get blockid note the order: x, z, y */ - block = getBlock(blocks_py, x, y, z); + block = getArrayByte3D(blocks_py, x, y, z); if (block == 0) { continue; } @@ -395,9 +195,9 @@ chunk_render(PyObject *self, PyObject *args) { if ( (x != 0) && (y != 15) && (z != 127) && - !isTransparent(transparent_blocks, getBlock(blocks_py, x-1, y, z)) && - !isTransparent(transparent_blocks, getBlock(blocks_py, x, y, z+1)) && - !isTransparent(transparent_blocks, getBlock(blocks_py, x, y+1, z))) { + !isTransparent(transparent_blocks, getArrayByte3D(blocks_py, x-1, y, z)) && + !isTransparent(transparent_blocks, getArrayByte3D(blocks_py, x, y, z+1)) && + !isTransparent(transparent_blocks, getArrayByte3D(blocks_py, x, y+1, z))) { continue; } @@ -435,12 +235,24 @@ chunk_render(PyObject *self, PyObject *args) { Py_DECREF(tmp); if (t != NULL) texture_alpha_over(img, t, imgx, imgy ); - continue; + } + + if (lighting) + { + // FIXME whole-block shading for transparent blocks + do_shading_for_face(chunk, x, y, z+1, facemasks[0], black_color, + img, imgx, imgy); + do_shading_for_face(chunk, x-1, y, z, facemasks[1], black_color, + img, imgx, imgy); + do_shading_for_face(chunk, x, y+1, z, facemasks[2], black_color, + img, imgx, imgy); } } } } + Py_DECREF(black_color); + Py_DECREF(facemasks_py); Py_DECREF(blocks_py); return Py_BuildValue("i",2); diff --git a/src/main.c b/src/main.c index 3157b8a..8bdd91d 100644 --- a/src/main.c +++ b/src/main.c @@ -24,8 +24,6 @@ static PyMethodDef COverviewerMethods[] = { "alpha over composite function"}, {"render_loop", chunk_render, METH_VARARGS, "Renders stuffs"}, - {"render_loop_lighting", chunk_render_lighting, METH_VARARGS, - "Renders stuffs, lighting"}, {NULL, NULL, 0, NULL} /* Sentinel */ }; diff --git a/src/overviewer.h b/src/overviewer.h index 903fcde..1321481 100644 --- a/src/overviewer.h +++ b/src/overviewer.h @@ -37,7 +37,6 @@ PyObject *brightness(PyObject *img, double factor); /* in iterate.c */ PyObject *chunk_render(PyObject *self, PyObject *args); -PyObject *chunk_render_lighting(PyObject *self, PyObject *args); int init_chunk_render(void); #endif /* __OVERVIEWER_H_INCLUDED__ */