all biome tinting is now handled in rendermode-normal.c.
Note that the case when there isn't any biome data available is not yet properly handled.
This commit is contained in:
@@ -45,6 +45,9 @@ rendermode_normal_start(void *data, RenderState *state, PyObject *options) {
|
|||||||
self->white_color = PyObject_GetAttrString(state->chunk, "white_color");
|
self->white_color = PyObject_GetAttrString(state->chunk, "white_color");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* biome-compliant grass mask (includes sides!) */
|
||||||
|
self->grass_texture = PyObject_GetAttrString(state->textures, "biome_grass_texture");
|
||||||
|
|
||||||
chunk_x_py = PyObject_GetAttrString(state->self, "chunkX");
|
chunk_x_py = PyObject_GetAttrString(state->self, "chunkX");
|
||||||
chunk_y_py = PyObject_GetAttrString(state->self, "chunkY");
|
chunk_y_py = PyObject_GetAttrString(state->self, "chunkY");
|
||||||
|
|
||||||
@@ -68,45 +71,21 @@ rendermode_normal_start(void *data, RenderState *state, PyObject *options) {
|
|||||||
Py_DECREF(world);
|
Py_DECREF(world);
|
||||||
|
|
||||||
if (PyObject_IsTrue(use_biomes)) {
|
if (PyObject_IsTrue(use_biomes)) {
|
||||||
PyObject *facemasks_py;
|
|
||||||
|
|
||||||
self->biome_data = PyObject_CallMethod(state->textures, "getBiomeData", "OOO",
|
self->biome_data = PyObject_CallMethod(state->textures, "getBiomeData", "OOO",
|
||||||
worlddir, chunk_x_py, chunk_y_py);
|
worlddir, chunk_x_py, chunk_y_py);
|
||||||
if (self->biome_data == Py_None) {
|
if (self->biome_data == Py_None) {
|
||||||
|
Py_DECREF(self->biome_data);
|
||||||
self->biome_data = NULL;
|
self->biome_data = NULL;
|
||||||
self->foliagecolor = NULL;
|
self->foliagecolor = NULL;
|
||||||
self->grasscolor = NULL;
|
self->grasscolor = NULL;
|
||||||
|
|
||||||
self->leaf_texture = NULL;
|
|
||||||
self->grass_texture = NULL;
|
|
||||||
self->tall_grass_texture = NULL;
|
|
||||||
self->facemask_top = NULL;
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
self->foliagecolor = PyObject_GetAttrString(state->textures, "foliagecolor");
|
self->foliagecolor = PyObject_GetAttrString(state->textures, "foliagecolor");
|
||||||
self->grasscolor = PyObject_GetAttrString(state->textures, "grasscolor");
|
self->grasscolor = PyObject_GetAttrString(state->textures, "grasscolor");
|
||||||
|
|
||||||
self->leaf_texture = PyObject_GetAttrString(state->textures, "biome_leaf_texture");
|
|
||||||
self->grass_texture = PyObject_GetAttrString(state->textures, "biome_grass_texture");
|
|
||||||
self->tall_grass_texture = PyObject_GetAttrString(state->textures, "biome_tall_grass_texture");
|
|
||||||
self->tall_fern_texture = PyObject_GetAttrString(state->textures, "biome_tall_fern_texture");
|
|
||||||
|
|
||||||
facemasks_py = PyObject_GetAttrString(state->chunk, "facemasks");
|
|
||||||
/* borrowed reference, needs to be incref'd if we keep it */
|
|
||||||
self->facemask_top = PyTuple_GetItem(facemasks_py, 0);
|
|
||||||
Py_INCREF(self->facemask_top);
|
|
||||||
Py_DECREF(facemasks_py);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self->biome_data = NULL;
|
self->biome_data = NULL;
|
||||||
self->foliagecolor = NULL;
|
self->foliagecolor = NULL;
|
||||||
self->grasscolor = NULL;
|
self->grasscolor = NULL;
|
||||||
|
|
||||||
self->leaf_texture = NULL;
|
|
||||||
self->grass_texture = NULL;
|
|
||||||
self->tall_grass_texture = NULL;
|
|
||||||
self->tall_fern_texture = NULL;
|
|
||||||
self->facemask_top = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(use_biomes);
|
Py_DECREF(use_biomes);
|
||||||
@@ -124,11 +103,7 @@ rendermode_normal_finish(void *data, RenderState *state) {
|
|||||||
Py_XDECREF(self->biome_data);
|
Py_XDECREF(self->biome_data);
|
||||||
Py_XDECREF(self->foliagecolor);
|
Py_XDECREF(self->foliagecolor);
|
||||||
Py_XDECREF(self->grasscolor);
|
Py_XDECREF(self->grasscolor);
|
||||||
Py_XDECREF(self->leaf_texture);
|
|
||||||
Py_XDECREF(self->grass_texture);
|
Py_XDECREF(self->grass_texture);
|
||||||
Py_XDECREF(self->tall_grass_texture);
|
|
||||||
Py_XDECREF(self->tall_fern_texture);
|
|
||||||
Py_XDECREF(self->facemask_top);
|
|
||||||
Py_XDECREF(self->black_color);
|
Py_XDECREF(self->black_color);
|
||||||
Py_XDECREF(self->white_color);
|
Py_XDECREF(self->white_color);
|
||||||
}
|
}
|
||||||
@@ -162,61 +137,64 @@ rendermode_normal_hidden(void *data, RenderState *state, int x, int y, int z) {
|
|||||||
static void
|
static void
|
||||||
rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
|
rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
|
||||||
RenderModeNormal *self = (RenderModeNormal *)data;
|
RenderModeNormal *self = (RenderModeNormal *)data;
|
||||||
unsigned char data_byte;
|
|
||||||
|
|
||||||
/* first, check to see if we should use biome-compatible src, mask */
|
|
||||||
if (self->biome_data) {
|
|
||||||
if (state->block == 18) {
|
|
||||||
src = mask = self->leaf_texture;
|
|
||||||
} else if (state->block == 31) {
|
|
||||||
data_byte = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z);
|
|
||||||
if (data_byte == 1) {
|
|
||||||
src = mask = self->tall_grass_texture;
|
|
||||||
} else if (data_byte == 2) {
|
|
||||||
src = mask = self->tall_fern_texture;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* draw the block! */
|
/* draw the block! */
|
||||||
alpha_over(state->img, src, mask, state->imgx, state->imgy, 0, 0);
|
alpha_over(state->img, src, mask, state->imgx, state->imgy, 0, 0);
|
||||||
|
|
||||||
if (self->biome_data) {
|
/* check for biome-compatible blocks
|
||||||
|
*
|
||||||
|
* NOTES for maintainers:
|
||||||
|
*
|
||||||
|
* To add a biome-compatible block, add an OR'd condition to this
|
||||||
|
* following if block, a case to the first switch statement to handle when
|
||||||
|
* biome info IS available, and another case to the second switch
|
||||||
|
* statement for when biome info ISN'T available.
|
||||||
|
*
|
||||||
|
* Make sure that in textures.py, the generated textures are the
|
||||||
|
* biome-compliant ones! The tinting is now all done here.
|
||||||
|
*/
|
||||||
|
if (/* grass, but not snowgrass */
|
||||||
|
(state->block == 2 && !(state->z < 127 && getArrayByte3D(state->blocks, state->x, state->y, state->z+1) == 78)) ||
|
||||||
|
/* leaves */
|
||||||
|
state->block == 18 ||
|
||||||
|
/* tallgrass, but not dead shrubs */
|
||||||
|
(state->block == 31 && getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z) != 0) ||
|
||||||
|
/* vines */
|
||||||
|
state->block == 106)
|
||||||
|
{
|
||||||
/* do the biome stuff! */
|
/* do the biome stuff! */
|
||||||
unsigned int index;
|
PyObject *facemask = mask;
|
||||||
PyObject *color = NULL, *facemask = NULL;
|
|
||||||
unsigned char r, g, b;
|
unsigned char r, g, b;
|
||||||
|
|
||||||
|
if (state->block == 2) {
|
||||||
|
/* grass needs a special facemask */
|
||||||
|
facemask = self->grass_texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->biome_data) {
|
||||||
|
/* we have data, so use it! */
|
||||||
|
unsigned int index;
|
||||||
|
PyObject *color = NULL;
|
||||||
|
|
||||||
index = ((self->chunk_y * 16) + state->y) * 16 * 32 + (self->chunk_x * 16) + state->x;
|
index = ((self->chunk_y * 16) + state->y) * 16 * 32 + (self->chunk_x * 16) + state->x;
|
||||||
index = big_endian_ushort(getArrayShort1D(self->biome_data, index));
|
index = big_endian_ushort(getArrayShort1D(self->biome_data, index));
|
||||||
|
|
||||||
switch (state->block) {
|
switch (state->block) {
|
||||||
case 2:
|
case 2:
|
||||||
/* grass -- skip for snowgrass */
|
/* grass */
|
||||||
if (state->z < 127 && getArrayByte3D(state->blocks, state->x, state->y, state->z+1) == 78)
|
|
||||||
break;
|
|
||||||
color = PySequence_GetItem(self->grasscolor, index);
|
color = PySequence_GetItem(self->grasscolor, index);
|
||||||
facemask = self->grass_texture;
|
|
||||||
alpha_over(state->img, self->grass_texture, self->grass_texture, state->imgx, state->imgy, 0, 0);
|
|
||||||
break;
|
break;
|
||||||
case 18:
|
case 18:
|
||||||
/* leaves */
|
/* leaves */
|
||||||
color = PySequence_GetItem(self->foliagecolor, index);
|
color = PySequence_GetItem(self->foliagecolor, index);
|
||||||
facemask = mask;
|
|
||||||
break;
|
break;
|
||||||
case 31:
|
case 31:
|
||||||
/* tall grass */
|
/* tall grass */
|
||||||
if ( getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z) != 0 )
|
|
||||||
{ /* do not tint dead shrubs */
|
|
||||||
color = PySequence_GetItem(self->grasscolor, index);
|
color = PySequence_GetItem(self->grasscolor, index);
|
||||||
facemask = mask;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 106:
|
case 106:
|
||||||
/* vines */
|
/* vines */
|
||||||
color = PySequence_GetItem(self->grasscolor, index);
|
color = PySequence_GetItem(self->grasscolor, index);
|
||||||
facemask = mask;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -230,10 +208,18 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *
|
|||||||
g = PyInt_AsLong(PyTuple_GET_ITEM(color, 1));
|
g = PyInt_AsLong(PyTuple_GET_ITEM(color, 1));
|
||||||
b = PyInt_AsLong(PyTuple_GET_ITEM(color, 2));
|
b = PyInt_AsLong(PyTuple_GET_ITEM(color, 2));
|
||||||
Py_DECREF(color);
|
Py_DECREF(color);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* manual tinting required */
|
||||||
|
|
||||||
|
/* FIXME */
|
||||||
|
r = 255;
|
||||||
|
g = 255;
|
||||||
|
b = 255;
|
||||||
|
}
|
||||||
|
|
||||||
tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx, state->imgy, 0, 0);
|
tint_with_mask(state->img, r, g, b, 255, facemask, state->imgx, state->imgy, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (self->height_fading) {
|
if (self->height_fading) {
|
||||||
/* do some height fading */
|
/* do some height fading */
|
||||||
|
|||||||
@@ -127,9 +127,7 @@ typedef struct {
|
|||||||
/* grasscolor and foliagecolor lookup tables */
|
/* grasscolor and foliagecolor lookup tables */
|
||||||
PyObject *grasscolor, *foliagecolor;
|
PyObject *grasscolor, *foliagecolor;
|
||||||
/* biome-compatible grass/leaf textures */
|
/* biome-compatible grass/leaf textures */
|
||||||
PyObject *grass_texture, *leaf_texture, *tall_grass_texture, *tall_fern_texture;
|
PyObject *grass_texture;
|
||||||
/* top facemask for grass biome tinting */
|
|
||||||
PyObject *facemask_top;
|
|
||||||
|
|
||||||
/* black and white colors for height fading */
|
/* black and white colors for height fading */
|
||||||
PyObject *black_color, *white_color;
|
PyObject *black_color, *white_color;
|
||||||
|
|||||||
@@ -532,8 +532,8 @@ def generate_special_texture(blockID, data):
|
|||||||
side_img = terrain_images[68]
|
side_img = terrain_images[68]
|
||||||
img = _build_block(terrain_images[0], side_img, 2)
|
img = _build_block(terrain_images[0], side_img, 2)
|
||||||
if not data & 0x10:
|
if not data & 0x10:
|
||||||
colored = tintTexture(biome_grass_texture, (115, 175, 71))
|
global biome_grass_texture
|
||||||
composite.alpha_over(img, colored, (0, 0), colored)
|
composite.alpha_over(img, biome_grass_texture, (0, 0), biome_grass_texture)
|
||||||
return generate_texture_tuple(img, blockID)
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
|
|
||||||
@@ -615,7 +615,7 @@ def generate_special_texture(blockID, data):
|
|||||||
|
|
||||||
|
|
||||||
if blockID == 18: # leaves
|
if blockID == 18: # leaves
|
||||||
t = tintTexture(terrain_images[52], (37, 118, 25))
|
t = terrain_images[52]
|
||||||
img = _build_block(t, t, 18)
|
img = _build_block(t, t, 18)
|
||||||
return generate_texture_tuple(img, blockID)
|
return generate_texture_tuple(img, blockID)
|
||||||
|
|
||||||
@@ -670,11 +670,9 @@ def generate_special_texture(blockID, data):
|
|||||||
if data == 0: # dead shrub
|
if data == 0: # dead shrub
|
||||||
texture = terrain_images[55]
|
texture = terrain_images[55]
|
||||||
elif data == 1: # tall grass
|
elif data == 1: # tall grass
|
||||||
texture = terrain_images[39].copy()
|
texture = terrain_images[39]
|
||||||
texture = tintTexture(texture, (115, 175, 71))
|
|
||||||
elif data == 2: # fern
|
elif data == 2: # fern
|
||||||
texture = terrain_images[56].copy()
|
texture = terrain_images[56]
|
||||||
texture = tintTexture(texture, (115, 175, 71))
|
|
||||||
|
|
||||||
img = _build_block(texture, texture, blockID)
|
img = _build_block(texture, texture, blockID)
|
||||||
return generate_texture_tuple(img,31)
|
return generate_texture_tuple(img,31)
|
||||||
@@ -2182,15 +2180,22 @@ special_blocks = set([ 2, 6, 9, 17, 18, 20, 26, 23, 27, 28, 29, 31, 33,
|
|||||||
|
|
||||||
special_map = {}
|
special_map = {}
|
||||||
|
|
||||||
|
# 0x10 means SNOW sides
|
||||||
|
special_map[2] = range(11) + [0x10,] # grass, grass has not ancildata but is
|
||||||
|
# used in the mod WildGrass, and this
|
||||||
|
# small fix shows the map as expected,
|
||||||
|
# and is harmless for normal maps
|
||||||
special_map[6] = range(16) # saplings: usual, spruce, birch and future ones (rendered as usual saplings)
|
special_map[6] = range(16) # saplings: usual, spruce, birch and future ones (rendered as usual saplings)
|
||||||
special_map[9] = range(32) # water: spring,flowing, waterfall, and others (unknown) ancildata values, uses pseudo data
|
special_map[9] = range(32) # water: spring,flowing, waterfall, and others (unknown) ancildata values, uses pseudo data
|
||||||
special_map[17] = range(3) # wood: normal, birch and pine
|
special_map[17] = range(3) # wood: normal, birch and pine
|
||||||
|
special_map[18] = range(16) # leaves, birch, normal or pine leaves (not implemented)
|
||||||
special_map[20] = range(32) # glass, used to only render the exterior surface, uses pseudo data
|
special_map[20] = range(32) # glass, used to only render the exterior surface, uses pseudo data
|
||||||
special_map[26] = range(12) # bed, orientation
|
special_map[26] = range(12) # bed, orientation
|
||||||
special_map[23] = range(6) # dispensers, orientation
|
special_map[23] = range(6) # dispensers, orientation
|
||||||
special_map[27] = range(14) # powered rail, orientation/slope and powered/unpowered
|
special_map[27] = range(14) # powered rail, orientation/slope and powered/unpowered
|
||||||
special_map[28] = range(6) # detector rail, orientation/slope
|
special_map[28] = range(6) # detector rail, orientation/slope
|
||||||
special_map[29] = (0,1,2,3,4,5,8,9,10,11,12,13) # sticky piston body, orientation, pushed in/out
|
special_map[29] = (0,1,2,3,4,5,8,9,10,11,12,13) # sticky piston body, orientation, pushed in/out
|
||||||
|
special_map[31] = range(3) # tall grass, dead shrub, fern and tall grass itself
|
||||||
special_map[33] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal piston body, orientation, pushed in/out
|
special_map[33] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal piston body, orientation, pushed in/out
|
||||||
special_map[34] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal and sticky piston extension, orientation, sticky/normal
|
special_map[34] = (0,1,2,3,4,5,8,9,10,11,12,13) # normal and sticky piston extension, orientation, sticky/normal
|
||||||
special_map[35] = range(16) # wool, colored and white
|
special_map[35] = range(16) # wool, colored and white
|
||||||
@@ -2232,26 +2237,11 @@ special_map[106] = (1,2,4,8) # vine, orientation
|
|||||||
special_map[108]= range(4) # red stairs, orientation
|
special_map[108]= range(4) # red stairs, orientation
|
||||||
special_map[109]= range(4) # stonebrick stairs, orientation
|
special_map[109]= range(4) # stonebrick stairs, orientation
|
||||||
|
|
||||||
# grass and leaves are graysacle in terrain.png
|
|
||||||
# we treat them as special so we can manually tint them
|
|
||||||
# it is unknown how the specific tint (biomes) is calculated
|
|
||||||
# also, 0x10 means SNOW sides
|
|
||||||
special_map[2] = range(11) + [0x10,] # grass, grass has not ancildata but is
|
|
||||||
# used in the mod WildGrass, and this
|
|
||||||
# small fix shows the map as expected,
|
|
||||||
# and is harmless for normal maps
|
|
||||||
special_map[18] = range(16) # leaves, birch, normal or pine leaves (not implemented)
|
|
||||||
special_map[31] = range(3) # tall grass, dead shrub, fern and tall grass itself
|
|
||||||
|
|
||||||
# placeholders that are generated in generate()
|
# placeholders that are generated in generate()
|
||||||
bgcolor = None
|
bgcolor = None
|
||||||
terrain_images = None
|
terrain_images = None
|
||||||
blockmap = None
|
blockmap = None
|
||||||
biome_grass_texture = None
|
biome_grass_texture = None
|
||||||
biome_tall_grass_texture = None
|
|
||||||
biome_tall_fern_texture = None
|
|
||||||
biome_leaf_texture = None
|
|
||||||
biome_vine_texture = None
|
|
||||||
specialblockmap = None
|
specialblockmap = None
|
||||||
|
|
||||||
def generate(path=None,texture_size=24,bgc = (26,26,26,0),north_direction='lower-left'):
|
def generate(path=None,texture_size=24,bgc = (26,26,26,0),north_direction='lower-left'):
|
||||||
@@ -2273,13 +2263,9 @@ def generate(path=None,texture_size=24,bgc = (26,26,26,0),north_direction='lower
|
|||||||
blockmap = _build_blockimages()
|
blockmap = _build_blockimages()
|
||||||
load_water()
|
load_water()
|
||||||
|
|
||||||
# generate biome (still grayscale) leaf, grass textures
|
# generate biome grass mask
|
||||||
global biome_grass_texture, biome_leaf_texture, biome_tall_grass_texture, biome_tall_fern_texture, biome_vine_texture
|
global biome_grass_texture
|
||||||
biome_grass_texture = _build_block(terrain_images[0], terrain_images[38], 2)
|
biome_grass_texture = _build_block(terrain_images[0], terrain_images[38], 2)
|
||||||
biome_leaf_texture = _build_block(terrain_images[52], terrain_images[52], 18)
|
|
||||||
biome_tall_grass_texture = _build_block(terrain_images[39], terrain_images[39], 31)
|
|
||||||
biome_tall_fern_texture = _build_block(terrain_images[56], terrain_images[56], 31)
|
|
||||||
biome_vine_texture = _build_block(terrain_images[143], terrain_images[143], 106)
|
|
||||||
|
|
||||||
# generate the special blocks
|
# generate the special blocks
|
||||||
global specialblockmap, special_blocks
|
global specialblockmap, special_blocks
|
||||||
@@ -2291,10 +2277,6 @@ def generate(path=None,texture_size=24,bgc = (26,26,26,0),north_direction='lower
|
|||||||
if texture_size != 24:
|
if texture_size != 24:
|
||||||
# rescale biome textures.
|
# rescale biome textures.
|
||||||
biome_grass_texture = biome_grass_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
biome_grass_texture = biome_grass_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
||||||
biome_leaf_texture = biome_leaf_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
|
||||||
biome_tall_grass_texture = biome_tall_grass_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
|
||||||
biome_tall_fern_texture = biome_tall_fern_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
|
||||||
biome_vine_texture = biome_vine_texture.resize(texture_dimensions, Image.ANTIALIAS)
|
|
||||||
|
|
||||||
# rescale the normal block images
|
# rescale the normal block images
|
||||||
for i in range(len(blockmap)):
|
for i in range(len(blockmap)):
|
||||||
|
|||||||
Reference in New Issue
Block a user