From a58f23d128365a56487019d8eb83bf0ec1a949da Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sat, 28 May 2011 01:02:33 +0200 Subject: [PATCH 01/12] Fix bad looking waterfalls. --- src/iterate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index b55e3df..89ae0a2 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -160,13 +160,13 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { return ancilData; } else if (state->block == 9) { /* water */ /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */ - if ((ancilData == 0) || (ancilData >= 10)) { /* static water, only top, and unkown ancildata values */ + if (ancilData == 0) { /* static water, only top, and unkown ancildata values */ data = 16; return data; /* = 0b10000 */ } else if ((ancilData > 0) && (ancilData < 8)) { /* flowing water */ data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | 0x10; return data; - } else if ((ancilData == 8) || (ancilData == 9)) { /* falling water */ + } else if (ancilData >= 8) { /* falling water */ data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f); return data; } From e0a3f0c4ce31251db98f94a96e7cc1483f33739b Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sat, 28 May 2011 01:08:55 +0200 Subject: [PATCH 02/12] Make seas more like in-game (draw only the top surface). --- src/iterate.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index 89ae0a2..84de2d9 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -160,8 +160,12 @@ generate_pseudo_data(RenderState *state, unsigned char ancilData) { return ancilData; } else if (state->block == 9) { /* water */ /* an aditional bit for top is added to the 4 bits of check_adjacent_blocks */ - if (ancilData == 0) { /* static water, only top, and unkown ancildata values */ - data = 16; + if (ancilData == 0) { /* static water */ + if ((z != 127) && (getArrayByte3D(state->blocks, x, y, z+1) == 9)) { + data = 0; + } else { + data = 16; + } return data; /* = 0b10000 */ } else if ((ancilData > 0) && (ancilData < 8)) { /* flowing water */ data = (check_adjacent_blocks(state, x, y, z, state->block) ^ 0x0f) | 0x10; From 7ff6a4833b20c31f0c8a5a3b7ce3d9e8c99e1d58 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 29 May 2011 23:31:04 +0200 Subject: [PATCH 03/12] Add another element to the texture tuple with a mask for the lighting. Make needed changes in textures.py. Because some textures have garbage in the alpha channel, this new method has some problems. --- src/iterate.c | 7 +- src/rendermode-cave.c | 4 +- src/rendermode-lighting.c | 6 +- src/rendermode-night.c | 4 +- src/rendermode-normal.c | 2 +- src/rendermode-overlay.c | 2 +- src/rendermode-spawn.c | 4 +- src/rendermodes.h | 2 +- textures.py | 198 ++++++++++++++++---------------------- 9 files changed, 99 insertions(+), 130 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index 84de2d9..e829373 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -421,14 +421,15 @@ chunk_render(PyObject *self, PyObject *args) { /* if we found a proper texture, render it! */ if (t != NULL && t != Py_None) { - PyObject *src, *mask; + PyObject *src, *mask, *mask_light; src = PyTuple_GetItem(t, 0); mask = PyTuple_GetItem(t, 1); - + mask_light = PyTuple_GetItem(t, 2); + if (mask == Py_None) mask = src; - rendermode->draw(rm_data, &state, src, mask); + rendermode->draw(rm_data, &state, src, mask, mask_light); } } diff --git a/src/rendermode-cave.c b/src/rendermode-cave.c index f8334b2..c5a2e07 100644 --- a/src/rendermode-cave.c +++ b/src/rendermode-cave.c @@ -202,7 +202,7 @@ rendermode_cave_finish(void *data, RenderState *state) { } static void -rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeCave* self; int z, r, g, b; self = (RenderModeCave *)data; @@ -211,7 +211,7 @@ rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *ma r = 0, g = 0, b = 0; /* draw the normal block */ - rendermode_normal.draw(data, state, src, mask); + rendermode_normal.draw(data, state, src, mask, mask_light); /* get the colors and tint and tint */ /* TODO TODO for a nether mode there isn't tinting! */ diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index 83b38d3..e342c7d 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -206,19 +206,19 @@ rendermode_lighting_occluded(void *data, RenderState *state) { } static void -rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeLighting* self; int x, y, z; /* first, chain up */ - rendermode_normal.draw(data, state, src, mask); + rendermode_normal.draw(data, state, src, mask, mask_light); self = (RenderModeLighting *)data; x = state->x, y = state->y, z = state->z; if (is_transparent(state->block)) { /* transparent: do shading on whole block */ - do_shading_with_mask(self, state, x, y, z, mask); + do_shading_with_mask(self, state, x, y, z, mask_light); } else { /* opaque: do per-face shading */ do_shading_with_mask(self, state, x, y, z+1, self->facemasks[0]); diff --git a/src/rendermode-night.c b/src/rendermode-night.c index 46ca7c2..81fc38f 100644 --- a/src/rendermode-night.c +++ b/src/rendermode-night.c @@ -54,9 +54,9 @@ rendermode_night_occluded(void *data, RenderState *state) { } static void -rendermode_night_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_night_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { /* nothing special to do */ - rendermode_lighting.draw(data, state, src, mask); + rendermode_lighting.draw(data, state, src, mask, mask_light); } RenderModeInterface rendermode_night = { diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index b4118e3..0e06e0e 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -116,7 +116,7 @@ rendermode_normal_occluded(void *data, RenderState *state) { } static void -rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeNormal *self = (RenderModeNormal *)data; /* first, check to see if we should use biome-compatible src, mask */ diff --git a/src/rendermode-overlay.c b/src/rendermode-overlay.c index fb4e765..04c87bf 100644 --- a/src/rendermode-overlay.c +++ b/src/rendermode-overlay.c @@ -71,7 +71,7 @@ rendermode_overlay_occluded(void *data, RenderState *state) { } static void -rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { RenderModeOverlay *self = (RenderModeOverlay *)data; unsigned char r, g, b, a; PyObject *top_block_py, *block_py; diff --git a/src/rendermode-spawn.c b/src/rendermode-spawn.c index 498ed17..2781a2a 100644 --- a/src/rendermode-spawn.c +++ b/src/rendermode-spawn.c @@ -102,9 +102,9 @@ rendermode_spawn_occluded(void *data, RenderState *state) { } static void -rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask) { +rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { /* draw normally */ - rendermode_overlay.draw(data, state, src, mask); + rendermode_overlay.draw(data, state, src, mask, mask_light); } RenderModeInterface rendermode_spawn = { diff --git a/src/rendermodes.h b/src/rendermodes.h index fd0b479..d6de559 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -56,7 +56,7 @@ struct _RenderModeInterface { /* returns non-zero to skip rendering this block */ int (*occluded)(void *, RenderState *); /* last two arguments are img and mask, from texture lookup */ - void (*draw)(void *, RenderState *, PyObject *, PyObject *); + void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *); }; /* figures out the render mode to use from the given ChunkRenderer */ diff --git a/textures.py b/textures.py index 611353a..ad54a41 100644 --- a/textures.py +++ b/textures.py @@ -453,7 +453,7 @@ def _build_blockimages(): ## of the block or the texture ID img = _build_block(toptexture, sidetexture, blockID) - allimages.append((img.convert("RGB"), img.split()[3])) + allimages.append(generate_texture_tuple(img, blockID)) # Future block types: while len(allimages) < 256: @@ -472,15 +472,32 @@ def load_water(): watertexture = _load_image("water.png") w1 = _build_block(watertexture, None) - blockmap[9] = w1.convert("RGB"), w1 + blockmap[9] = generate_texture_tuple(w1,9) w2 = _build_block(watertexture, watertexture) - blockmap[8] = w2.convert("RGB"), w2 + blockmap[8] = generate_texture_tuple(w2,8) lavatexture = _load_image("lava.png") lavablock = _build_block(lavatexture, lavatexture) - blockmap[10] = lavablock.convert("RGB"), lavablock + blockmap[10] = generate_texture_tuple(lavablock,10) blockmap[11] = blockmap[10] +def generate_opaque_mask(img): + alpha = img.split()[3] + pixel = alpha.load() + + for x in range(img.size[0]): + for y in range(img.size[1]): + if pixel[x,y] != 0: + pixel[x,y] = 255 + + return alpha + +def generate_texture_tuple(img, blockid): + if blockid in (8,9,79,85): + return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) + else: + return (img.convert("RGB"), img.split()[3], img.split()[3]) + def generate_special_texture(blockID, data): """Generates a special texture, such as a correctly facing minecraft track""" #print "%s has ancillary data: %X" %(blockID, data) @@ -496,7 +513,7 @@ def generate_special_texture(blockID, data): if not data & 0x10: colored = tintTexture(biome_grass_texture, (115, 175, 71)) composite.alpha_over(img, colored, (0, 0), colored) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 6: # saplings @@ -520,7 +537,7 @@ def generate_special_texture(blockID, data): sidetexture = terrain_images[15] img = _build_block(toptexture, sidetexture, blockID) - return (img.convert("RGB"),img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 9: # spring water, flowing water and waterfall water @@ -548,9 +565,9 @@ def generate_special_texture(blockID, data): side4 = watertexture # bottom right else: side4 = None - img = _build_full_block(top,side1,side2,side3,side4) + img = _build_full_block(top,None,None,side3,side4) - return (img.convert("RGB"),img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 17: # wood: normal, birch and pines @@ -558,21 +575,20 @@ def generate_special_texture(blockID, data): if data == 0: side = terrain_images[20] img = _build_block(top, side, 17) - return (img.convert("RGB"), img.split()[3]) if data == 1: side = terrain_images[116] img = _build_block(top, side, 17) - return (img.convert("RGB"), img.split()[3]) if data == 2: side = terrain_images[117] img = _build_block(top, side, 17) - return (img.convert("RGB"), img.split()[3]) + + return generate_texture_tuple(img, blockID) if blockID == 18: # leaves t = tintTexture(terrain_images[52], (37, 118, 25)) img = _build_block(t, t, 18) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 26: # bed @@ -618,74 +634,45 @@ def generate_special_texture(blockID, data): top = (top, increment) img = _build_full_block(top, None, None, left_face, right_face) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 35: # wool if data == 0: # white top = side = terrain_images[64] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 1: # orange + elif data == 1: # orange top = side = terrain_images[210] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 2: # magenta + elif data == 2: # magenta top = side = terrain_images[194] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 3: # light blue + elif data == 3: # light blue top = side = terrain_images[178] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 4: # yellow + elif data == 4: # yellow top = side = terrain_images[162] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 5: # light green + elif data == 5: # light green top = side = terrain_images[146] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 6: # pink + elif data == 6: # pink top = side = terrain_images[130] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 7: # grey + elif data == 7: # grey top = side = terrain_images[114] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 8: # light grey + elif data == 8: # light grey top = side = terrain_images[225] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 9: # cyan + elif data == 9: # cyan top = side = terrain_images[209] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 10: # purple + elif data == 10: # purple top = side = terrain_images[193] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 11: # blue + elif data == 11: # blue top = side = terrain_images[177] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 12: # brown + elif data == 12: # brown top = side = terrain_images[161] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 13: # dark green + elif data == 13: # dark green top = side = terrain_images[145] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 14: # red + elif data == 14: # red top = side = terrain_images[129] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) - if data == 15: # black + elif data == 15: # black top = side = terrain_images[113] - img = _build_block(top, side, 35) - return (img.convert("RGB"), img.split()[3]) + + img = _build_block(top, side, 35) + return generate_texture_tuple(img, blockID) if blockID in (43,44): # slab and double-slab @@ -693,24 +680,16 @@ def generate_special_texture(blockID, data): if data == 0: # stone slab top = terrain_images[6] side = terrain_images[5] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) - if data == 1: # stone slab top = terrain_images[176] side = terrain_images[192] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) - if data == 2: # wooden slab top = side = terrain_images[4] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) - if data == 3: # cobblestone slab top = side = terrain_images[16] - img = _build_block(top, side, blockID) - return (img.convert("RGB"), img.split()[3]) + + img = _build_block(top, side, blockID) + return generate_texture_tuple(img, blockID) if blockID in (50,75,76): # torch, off redstone torch, on redstone torch @@ -763,7 +742,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, small_crop, (6,5)) composite.alpha_over(img, slice, (6,6)) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 51: # fire @@ -779,7 +758,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, side1, (0,6), side1) composite.alpha_over(img, side2, (12,6), side2) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (53,67): # wooden and cobblestone stairs. @@ -848,7 +827,7 @@ def generate_special_texture(blockID, data): # touch up a (horrible) pixel img.putpixel((18,3),(0,0,0,0)) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 54: # chests # First to bits of the pseudo data store if it's a single chest @@ -890,7 +869,7 @@ def generate_special_texture(blockID, data): else: img = _build_full_block(top, None, None, back, side) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 55: # redstone wire @@ -968,7 +947,7 @@ def generate_special_texture(blockID, data): img = _build_full_block(None,side1,side2,None,None,bottom) - return (img.convert("RGB"),img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 58: # crafting table @@ -977,7 +956,7 @@ def generate_special_texture(blockID, data): side4 = terrain_images[43+16+1] img = _build_full_block(top, None, None, side3, side4, None, 58) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 59: # crops @@ -990,7 +969,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, crop1, (0,12), crop1) composite.alpha_over(img, crop2, (6,3), crop2) composite.alpha_over(img, crop3, (6,3), crop3) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (61, 62, 23): #furnace and burning furnace @@ -1015,7 +994,7 @@ def generate_special_texture(blockID, data): else: # in any other direction the front can't be seen img = _build_full_block(top, None, None, side, side) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 63: # singposts @@ -1058,7 +1037,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, post2,(incrementx, -3),post2) composite.alpha_over(img, post, (0,-2), post) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (64,71): #wooden door, or iron door @@ -1110,10 +1089,11 @@ def generate_special_texture(blockID, data): tex = transform_image_side(raw_door.transpose(Image.FLIP_LEFT_RIGHT)) composite.alpha_over(img, tex, (0,6), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 65: # ladder + img = Image.new("RGBA", (24,24), (38,92,255,0)) raw_texture = terrain_images[83] #print "ladder is facing: %d" % data if data == 5: @@ -1121,28 +1101,25 @@ def generate_special_texture(blockID, data): # but since ladders can apparently be placed on transparent blocks, we # have to render this thing anyway. same for data == 2 tex = transform_image_side(raw_texture) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (0,6), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if data == 2: tex = transform_image_side(raw_texture).transpose(Image.FLIP_LEFT_RIGHT) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (12,6), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if data == 3: tex = transform_image_side(raw_texture).transpose(Image.FLIP_LEFT_RIGHT) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (0,0), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if data == 4: tex = transform_image_side(raw_texture) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, tex, (12,0), tex) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (27, 28, 66): # minetrack: - + img = Image.new("RGBA", (24,24), (38,92,255,0)) + if blockID == 27: # powered rail if data & 0x8 == 0: # unpowered raw_straight = terrain_images[163] @@ -1165,58 +1142,48 @@ def generate_special_texture(blockID, data): ## use transform_image to scale and shear if data == 0: track = transform_image(raw_straight, blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 6: track = transform_image(raw_corner, blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 7: track = transform_image(raw_corner.rotate(270), blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 8: # flip track = transform_image(raw_corner.transpose(Image.FLIP_TOP_BOTTOM).rotate(90), blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 9: track = transform_image(raw_corner.transpose(Image.FLIP_TOP_BOTTOM), blockID) + composite.alpha_over(img, track, (0,12), track) elif data == 1: track = transform_image(raw_straight.rotate(90), blockID) + composite.alpha_over(img, track, (0,12), track) #slopes elif data == 2: # slope going up in +x direction track = transform_image_slope(raw_straight,blockID) track = track.transpose(Image.FLIP_LEFT_RIGHT) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, track, (2,0), track) # the 2 pixels move is needed to fit with the adjacent tracks - return (img.convert("RGB"), img.split()[3]) elif data == 3: # slope going up in -x direction # tracks are sprites, in this case we are seeing the "side" of # the sprite, so draw a line to make it beautiful. - img = Image.new("RGBA", (24,24), (38,92,255,0)) ImageDraw.Draw(img).line([(11,11),(23,17)],fill=(164,164,164)) # grey from track texture (exterior grey). # the track doesn't start from image corners, be carefull drawing the line! - return (img.convert("RGB"), img.split()[3]) - elif data == 4: # slope going up in -y direction track = transform_image_slope(raw_straight,blockID) - img = Image.new("RGBA", (24,24), (38,92,255,0)) composite.alpha_over(img, track, (0,0), track) - return (img.convert("RGB"), img.split()[3]) - + elif data == 5: # slope going up in +y direction # same as "data == 3" - img = Image.new("RGBA", (24,24), (38,92,255,0)) ImageDraw.Draw(img).line([(1,17),(12,11)],fill=(164,164,164)) - return (img.convert("RGB"), img.split()[3]) - - else: # just in case - track = transform_image(raw_straight, blockID) - - img = Image.new("RGBA", (24,24), (38,92,255,0)) - composite.alpha_over(img, track, (0,12), track) - - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 68: # wall sign @@ -1254,7 +1221,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, sign2,(incrementx, 2),sign2) composite.alpha_over(img, sign, (0,3), sign) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 85: # fences # create needed images for Big stick fence @@ -1349,7 +1316,8 @@ def generate_special_texture(blockID, data): if (data & 0b0100) == 4: composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right - return (img.convert("RGB"),img.split()[3]) + img.save("fence" + str(data) + ".png") + return generate_texture_tuple(img, blockID) if blockID in (86,91): # pumpkins, jack-o-lantern @@ -1367,7 +1335,7 @@ def generate_special_texture(blockID, data): else: # in any other direction the front can't be seen img = _build_full_block(top, None, None, side, side) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 90: # portal @@ -1383,7 +1351,7 @@ def generate_special_texture(blockID, data): if data in (2,8): composite.alpha_over(img, otherside, (5,4), otherside) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID == 92: # cake! (without bites, at the moment) @@ -1408,7 +1376,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, otherside, (12,12), otherside) composite.alpha_over(img, top, (0,6), top) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) if blockID in (93, 94): # redstone repeaters, ON and OFF @@ -1526,7 +1494,7 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, torch, static_torch, torch) composite.alpha_over(img, torch, moving_torch, torch) - return (img.convert("RGB"), img.split()[3]) + return generate_texture_tuple(img, blockID) return None @@ -1612,7 +1580,7 @@ special_map = {} 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[17] = range(4) # wood: normal, birch and pine +special_map[17] = range(3) # wood: normal, birch and pine special_map[26] = range(12) # bed, orientation special_map[23] = range(6) # dispensers, orientation special_map[27] = range(14) # powered rail, orientation/slope and powered/unpowered From fb0a393c140dbf281ceb48e6a3f43b309245de2f Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Sun, 29 May 2011 23:46:22 +0200 Subject: [PATCH 04/12] Delete saving image... --- textures.py | 1 - 1 file changed, 1 deletion(-) diff --git a/textures.py b/textures.py index ad54a41..c585885 100644 --- a/textures.py +++ b/textures.py @@ -1316,7 +1316,6 @@ def generate_special_texture(blockID, data): if (data & 0b0100) == 4: composite.alpha_over(img,fence_small_side, pos_bottom_right,fence_small_side) # bottom right - img.save("fence" + str(data) + ".png") return generate_texture_tuple(img, blockID) From 4cc957c16b5b13da8e89da241d80c4fd734f10db Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Mon, 30 May 2011 00:48:58 +0200 Subject: [PATCH 05/12] Fix problem with fence textures. --- textures.py | 58 ++++++++++++++++++++++++++--------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/textures.py b/textures.py index c585885..f632472 100644 --- a/textures.py +++ b/textures.py @@ -1225,24 +1225,26 @@ def generate_special_texture(blockID, data): if blockID == 85: # fences # create needed images for Big stick fence - raw_texture = terrain_images[4] - raw_fence_top = Image.new("RGBA", (16,16), (38,92,255,0)) - raw_fence_side = Image.new("RGBA", (16,16), (38,92,255,0)) - fence_top_mask = Image.new("RGBA", (16,16), (38,92,255,0)) - fence_side_mask = Image.new("RGBA", (16,16), (38,92,255,0)) - - # generate the masks images for textures of the fence - ImageDraw.Draw(fence_top_mask).rectangle((6,6,9,9),outline=(0,0,0),fill=(0,0,0)) - ImageDraw.Draw(fence_side_mask).rectangle((6,1,9,15),outline=(0,0,0),fill=(0,0,0)) - # create textures top and side for fence big stick - composite.alpha_over(raw_fence_top,raw_texture,(0,0),fence_top_mask) - composite.alpha_over(raw_fence_side,raw_texture,(0,0),fence_side_mask) + fence_top = terrain_images[4].copy() + fence_side = terrain_images[4].copy() + + # generate the textures of the fence + ImageDraw.Draw(fence_top).rectangle((0,0,5,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_top).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_top).rectangle((0,0,15,5),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_top).rectangle((0,10,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + fence_top.save("fence_top.png") + + ImageDraw.Draw(fence_side).rectangle((0,0,15,0),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_side).rectangle((0,0,5,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_side).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + fence_side.save("fence_side.png") # Create the sides and the top of the big stick - fence_side = transform_image_side(raw_fence_side,85) + fence_side = transform_image_side(fence_side,85) fence_other_side = fence_side.transpose(Image.FLIP_LEFT_RIGHT) - fence_top = transform_image(raw_fence_top,85) + fence_top = transform_image(fence_top,85) # Darken the sides slightly. These methods also affect the alpha layer, # so save them first (we don't want to "darken" the alpha layer making @@ -1262,18 +1264,18 @@ def generate_special_texture(blockID, data): # Now render the small sticks. # Create needed images - raw_fence_small_side = Image.new("RGBA", (16,16), (38,92,255,0)) - fence_small_side_mask = Image.new("RGBA", (16,16), (38,92,255,0)) + fence_small_side = terrain_images[4].copy() # Generate mask - ImageDraw.Draw(fence_small_side_mask).rectangle((10,1,15,3),outline=(0,0,0),fill=(0,0,0)) - ImageDraw.Draw(fence_small_side_mask).rectangle((10,7,15,9),outline=(0,0,0),fill=(0,0,0)) - - # create the texture for the side of small sticks fence - composite.alpha_over(raw_fence_small_side,raw_texture,(0,0),fence_small_side_mask) - + ImageDraw.Draw(fence_small_side).rectangle((0,0,15,0),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((0,4,15,6),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((0,10,15,16),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((0,0,4,15),outline=(0,0,0,0),fill=(0,0,0,0)) + ImageDraw.Draw(fence_small_side).rectangle((11,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) + fence_small_side.save("fence_small_side.png") + # Create the sides and the top of the small sticks - fence_small_side = transform_image_side(raw_fence_small_side,85) + fence_small_side = transform_image_side(fence_small_side,85) fence_small_other_side = fence_small_side.transpose(Image.FLIP_LEFT_RIGHT) # Darken the sides slightly. These methods also affect the alpha layer, @@ -1286,18 +1288,16 @@ def generate_special_texture(blockID, data): fence_small_side = ImageEnhance.Brightness(fence_small_side).enhance(0.9) fence_small_side.putalpha(sidealpha) - # Create img to compose the fence - img = Image.new("RGBA", (24,24), (38,92,255,0)) # Position of fence small sticks in img. # These postitions are strange because the small sticks of the # fence are at the very left and at the very right of the 16x16 images - pos_top_left = (-2,0) - pos_top_right = (14,0) - pos_bottom_right = (6,4) - pos_bottom_left = (6,4) + pos_top_left = (2,3) + pos_top_right = (10,3) + pos_bottom_right = (10,7) + pos_bottom_left = (2,7) # +x axis points top right direction # +y axis points bottom right direction From 490e1f26103ef1c77c11e84a2114ace5fde3ec97 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 15:24:07 +0200 Subject: [PATCH 06/12] Clean and comment. --- textures.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/textures.py b/textures.py index f632472..54c713e 100644 --- a/textures.py +++ b/textures.py @@ -482,21 +482,23 @@ def load_water(): blockmap[11] = blockmap[10] def generate_opaque_mask(img): + """ Takes the alpha channel of the image and generates a mask + (used for lighting the block) that deprecates values of alpha + smallers than 50, and sets every other value to 255. """ + alpha = img.split()[3] pixel = alpha.load() - for x in range(img.size[0]): for y in range(img.size[1]): - if pixel[x,y] != 0: + if pixel[x,y] > 25: pixel[x,y] = 255 return alpha def generate_texture_tuple(img, blockid): - if blockid in (8,9,79,85): - return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) - else: - return (img.convert("RGB"), img.split()[3], img.split()[3]) + """ This takes a image and returns the needed tuple for the blockmap + list and specialblockmap dictionary.""" + return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) def generate_special_texture(blockID, data): """Generates a special texture, such as a correctly facing minecraft track""" @@ -1234,12 +1236,10 @@ def generate_special_texture(blockID, data): ImageDraw.Draw(fence_top).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_top).rectangle((0,0,15,5),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_top).rectangle((0,10,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) - fence_top.save("fence_top.png") ImageDraw.Draw(fence_side).rectangle((0,0,15,0),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_side).rectangle((0,0,5,15),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_side).rectangle((10,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) - fence_side.save("fence_side.png") # Create the sides and the top of the big stick fence_side = transform_image_side(fence_side,85) @@ -1272,7 +1272,6 @@ def generate_special_texture(blockID, data): ImageDraw.Draw(fence_small_side).rectangle((0,10,15,16),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_small_side).rectangle((0,0,4,15),outline=(0,0,0,0),fill=(0,0,0,0)) ImageDraw.Draw(fence_small_side).rectangle((11,0,15,15),outline=(0,0,0,0),fill=(0,0,0,0)) - fence_small_side.save("fence_small_side.png") # Create the sides and the top of the small sticks fence_small_side = transform_image_side(fence_small_side,85) From 87cd001b9130b8a79a59635ab9842c1fd6ce39c3 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 16:01:54 +0200 Subject: [PATCH 07/12] Add tall grass and dead shrubs. --- chunk.py | 8 ++++---- textures.py | 32 +++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/chunk.py b/chunk.py index 048b650..7eb61ab 100644 --- a/chunk.py +++ b/chunk.py @@ -114,10 +114,10 @@ def get_tileentity_data(level): return data # This set holds blocks ids that can be seen through, for occlusion calculations -transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 37, 38, 39, 40, - 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, 90, 92, - 93, 94]) +transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 31, 32, 37, 38, + 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, + 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, + 90, 92, 93, 94]) # This set holds block ids that are solid blocks solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, diff --git a/textures.py b/textures.py index 54c713e..c19fc09 100644 --- a/textures.py +++ b/textures.py @@ -257,7 +257,7 @@ def _build_block(top, side, blockID=None): otherside.putalpha(othersidealpha) ## special case for non-block things - if blockID in (37,38,6,39,40,83,30): ## flowers, sapling, mushrooms, reeds, web + if blockID in (31,32,37,38,6,39,40,83,30): ## tall grass, dead shrubs, flowers, sapling, mushrooms, reeds, web # # instead of pasting these blocks at the cube edges, place them in the middle: # and omit the top @@ -410,7 +410,7 @@ def _build_blockimages(): # 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 34, -1, 52, 48, 49,160,144, -1,176, 74, -1, -1, -1, -1, 11, -1, # 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 - -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4, + 55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 9, 4, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 36, 37, -1, -1, 65, -1, -1, -1, 50, 24, -1, -1, 86, -1, -1, -1, # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 @@ -427,7 +427,7 @@ def _build_blockimages(): # 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 34, -1, 52, 48, 49,160,144, -1,192, 74, -1, -1,- 1, -1, 11, -1, # 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 - -1, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 35, + 55, -1, -1, -1, -1, 13, 12, 29, 28, 23, 22, -1, -1, 7, 8, 35, # 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 36, 37, -1, -1, 65, -1, -1,101, 50, 24, -1, -1, 86, -1, -1, -1, # 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 @@ -496,8 +496,8 @@ def generate_opaque_mask(img): return alpha def generate_texture_tuple(img, blockid): - """ This takes a image and returns the needed tuple for the blockmap - list and specialblockmap dictionary.""" + """ This takes an image and returns the needed tuple for the + blockmap list and specialblockmap dictionary.""" return (img.convert("RGB"), img.split()[3], generate_opaque_mask(img)) def generate_special_texture(blockID, data): @@ -638,7 +638,20 @@ def generate_special_texture(blockID, data): return generate_texture_tuple(img, blockID) - + if blockID == 31: # tall grass + if data == 0: # dead shrub + texture = terrain_images[55] + elif data == 1: # tall grass + texture = terrain_images[39].copy() + texture = tintTexture(texture, (115, 175, 71)) + elif data == 2: # fern + texture = terrain_images[56].copy() + texture = tintTexture(texture, (115, 175, 71)) + + img = _build_block(texture, texture, blockID) + return generate_texture_tuple(img,31) + + if blockID == 35: # wool if data == 0: # white top = side = terrain_images[64] @@ -1567,9 +1580,9 @@ def getBiomeData(worlddir, chunkX, chunkY): # (when adding new blocks here and in generate_special_textures, # please, if possible, keep the ascending order of blockid value) -special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 35, 43, 44, 50, - 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, 67, - 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) +special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 31, 35, 43, 44, + 50, 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, + 67, 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1621,6 +1634,7 @@ special_map[2] = range(11) + [0x10,] # grass, grass has not ancildata but is # 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() terrain_images = None From fcd29234fffd339fb38afc2db5c6ab95b4de4322 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 17:03:18 +0200 Subject: [PATCH 08/12] Add trapdoors. --- chunk.py | 2 +- textures.py | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/chunk.py b/chunk.py index 7eb61ab..f8aa1f6 100644 --- a/chunk.py +++ b/chunk.py @@ -117,7 +117,7 @@ def get_tileentity_data(level): transparent_blocks = set([ 0, 6, 8, 9, 18, 20, 26, 27, 28, 30, 31, 32, 37, 38, 39, 40, 44, 50, 51, 52, 53, 55, 59, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 74, 75, 76, 77, 78, 79, 81, 83, 85, - 90, 92, 93, 94]) + 90, 92, 93, 94, 96]) # This set holds block ids that are solid blocks solid_blocks = set([1, 2, 3, 4, 5, 7, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, diff --git a/textures.py b/textures.py index c19fc09..17bce0e 100644 --- a/textures.py +++ b/textures.py @@ -1506,6 +1506,24 @@ def generate_special_texture(blockID, data): composite.alpha_over(img, torch, moving_torch, torch) return generate_texture_tuple(img, blockID) + + + if blockID == 96: # trapdoor + texture = terrain_images[84] + if data & 0x4 == 0x4: # opened trapdoor + if data & 0x3 == 0: # west + img = _build_full_block(None, None, None, None, texture) + if data & 0x3 == 1: # east + img = _build_full_block(None, texture, None, None, None) + if data & 0x3 == 2: # south + img = _build_full_block(None, None, texture, None, None) + if data & 0x3 == 3: # north + img = _build_full_block(None, None, None, texture, None) + + elif data & 0x4 == 0: # closed trapdoor + img = _build_full_block((texture, 9), None, None, texture, texture) + + return generate_texture_tuple(img, blockID) return None @@ -1582,7 +1600,7 @@ def getBiomeData(worlddir, chunkX, chunkY): special_blocks = set([ 2, 6, 9, 17, 18, 26, 23, 27, 28, 31, 35, 43, 44, 50, 51, 53, 54, 55, 58, 59, 61, 62, 63, 64, 65, 66, - 67, 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94]) + 67, 68, 71, 75, 76, 85, 86, 90, 91, 92, 93, 94, 96]) # this is a map of special blockIDs to a list of all # possible values for ancillary data that it might have. @@ -1624,6 +1642,7 @@ special_map[91] = range(5) # jack-o-lantern, orientation special_map[92] = range(6) # cake! special_map[93] = range(16) # OFF redstone repeater, orientation and delay (delay not implemented) special_map[94] = range(16) # ON redstone repeater, orientation and delay (delay not implemented) +special_map[96] = range(8) # trapdoor, open, closed, orientation # grass and leaves are graysacle in terrain.png # we treat them as special so we can manually tint them From d95ae73286e12b5b3ee7a034ccf5fcc20f933805 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Tue, 31 May 2011 18:21:47 +0200 Subject: [PATCH 09/12] Tall grass is now biome tinted. --- src/iterate.c | 5 ++--- src/overviewer.h | 1 + src/rendermode-normal.c | 26 ++++++++++++++++++++++++-- src/rendermodes.h | 2 +- textures.py | 6 +++++- 5 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/iterate.c b/src/iterate.c index e829373..d86ecbf 100644 --- a/src/iterate.c +++ b/src/iterate.c @@ -293,7 +293,6 @@ PyObject* chunk_render(PyObject *self, PyObject *args) { RenderState state; - PyObject *blockdata_expanded; int xoff, yoff; PyObject *imgsize, *imgsize0_py, *imgsize1_py; @@ -311,7 +310,7 @@ chunk_render(PyObject *self, PyObject *args) { PyObject *t = NULL; - if (!PyArg_ParseTuple(args, "OOiiO", &state.self, &state.img, &xoff, &yoff, &blockdata_expanded)) + if (!PyArg_ParseTuple(args, "OOiiO", &state.self, &state.img, &xoff, &yoff, &state.blockdata_expanded)) return NULL; /* fill in important modules */ @@ -402,7 +401,7 @@ chunk_render(PyObject *self, PyObject *args) { } else { PyObject *tmp; - unsigned char ancilData = getArrayByte3D(blockdata_expanded, state.x, state.y, state.z); + unsigned char ancilData = getArrayByte3D(state.blockdata_expanded, state.x, state.y, state.z); if ((state.block == 85) || (state.block == 9) || (state.block == 55) || (state.block == 54) || (state.block == 2) || (state.block == 90)) { ancilData = generate_pseudo_data(&state, ancilData); } diff --git a/src/overviewer.h b/src/overviewer.h index 5ee89dc..184cd4e 100644 --- a/src/overviewer.h +++ b/src/overviewer.h @@ -70,6 +70,7 @@ typedef struct { /* the block position and type, and the block array */ int x, y, z; unsigned char block; + PyObject *blockdata_expanded; PyObject *blocks; PyObject *up_left_blocks; PyObject *up_right_blocks; diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index 0e06e0e..e4247fa 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -56,6 +56,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = NULL; self->grass_texture = NULL; + self->tall_grass_texture = NULL; self->facemask_top = NULL; } else { @@ -64,6 +65,7 @@ rendermode_normal_start(void *data, RenderState *state) { 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"); facemasks_py = PyObject_GetAttrString(state->chunk, "facemasks"); /* borrowed reference, needs to be incref'd if we keep it */ @@ -78,6 +80,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = NULL; self->grass_texture = NULL; + self->tall_grass_texture = NULL; self->facemask_top = NULL; } @@ -98,6 +101,7 @@ rendermode_normal_finish(void *data, RenderState *state) { Py_XDECREF(self->grasscolor); Py_XDECREF(self->leaf_texture); Py_XDECREF(self->grass_texture); + Py_XDECREF(self->tall_grass_texture); Py_XDECREF(self->facemask_top); } @@ -120,8 +124,17 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * RenderModeNormal *self = (RenderModeNormal *)data; /* first, check to see if we should use biome-compatible src, mask */ - if (self->biome_data && state->block == 18) { - src = mask = self->leaf_texture; + if (self->biome_data) { + if (state->block == 18) { + src = mask = self->leaf_texture; + } else if (state->block == 31) { + unsigned char data = getArrayByte3D(state->blockdata_expanded, state->x, state->y, state->z); + if (data == 1) { + src = mask = self->tall_grass_texture; + } else if (data == 2) { + src = mask = self->tall_fern_texture; + } + } } /* draw the block! */ @@ -150,6 +163,15 @@ rendermode_normal_draw(void *data, RenderState *state, PyObject *src, PyObject * color = PySequence_GetItem(self->foliagecolor, index); facemask = mask; break; + case 31: + /* 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); + facemask = mask; + break; + } + break; default: break; }; diff --git a/src/rendermodes.h b/src/rendermodes.h index d6de559..80126a4 100644 --- a/src/rendermodes.h +++ b/src/rendermodes.h @@ -79,7 +79,7 @@ typedef struct { /* grasscolor and foliagecolor lookup tables */ PyObject *grasscolor, *foliagecolor; /* biome-compatible grass/leaf textures */ - PyObject *grass_texture, *leaf_texture; + PyObject *grass_texture, *leaf_texture, *tall_grass_texture, *tall_fern_texture; /* top facemask for grass biome tinting */ PyObject *facemask_top; } RenderModeNormal; diff --git a/textures.py b/textures.py index 17bce0e..02c26c3 100644 --- a/textures.py +++ b/textures.py @@ -1659,6 +1659,8 @@ special_map[31] = range(3) # tall grass, dead shrub, fern and tall grass itself terrain_images = None blockmap = None biome_grass_texture = None +biome_tall_grass_texture = None +biome_tall_fern_texture = None biome_leaf_texture = None specialblockmap = None @@ -1676,9 +1678,11 @@ def generate(path=None): load_water() # generate biome (still grayscale) leaf, grass textures - global biome_grass_texture, biome_leaf_texture + global biome_grass_texture, biome_leaf_texture, biome_tall_grass_texture 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) # generate the special blocks global specialblockmap, special_blocks From 9d4b48b5ae8a388bc833cfc249d5c09841dbddd6 Mon Sep 17 00:00:00 2001 From: Alejandro Aguilera Date: Wed, 1 Jun 2011 00:19:23 +0200 Subject: [PATCH 10/12] Add the agrif's fix for stairs. With 1.6 this is no more a quick fix (I think they are now as slabs are). --- src/rendermode-lighting.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendermode-lighting.c b/src/rendermode-lighting.c index e342c7d..c38fd1e 100644 --- a/src/rendermode-lighting.c +++ b/src/rendermode-lighting.c @@ -91,7 +91,7 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state, /* only do special half-step handling if no authoratative pointer was passed in, which is a sign that we're recursing */ - if (block == 44 && authoratative == NULL) { + if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) { float average_gather = 0.0f; unsigned int average_count = 0; int auth; From 8565919c898a6981e603a60936fceae69eaa9058 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Tue, 31 May 2011 20:05:45 -0400 Subject: [PATCH 11/12] fixed uninitialized texture pointer, and bumped extension version --- src/overviewer.h | 2 +- src/rendermode-normal.c | 3 +++ textures.py | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/overviewer.h b/src/overviewer.h index 184cd4e..49e70fa 100644 --- a/src/overviewer.h +++ b/src/overviewer.h @@ -26,7 +26,7 @@ // increment this value if you've made a change to the c extesion // and want to force users to rebuild -#define OVERVIEWER_EXTENSION_VERSION 6 +#define OVERVIEWER_EXTENSION_VERSION 7 /* Python PIL, and numpy headers */ #include diff --git a/src/rendermode-normal.c b/src/rendermode-normal.c index e4247fa..d975ed9 100644 --- a/src/rendermode-normal.c +++ b/src/rendermode-normal.c @@ -66,6 +66,7 @@ rendermode_normal_start(void *data, RenderState *state) { 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 */ @@ -81,6 +82,7 @@ rendermode_normal_start(void *data, RenderState *state) { self->leaf_texture = NULL; self->grass_texture = NULL; self->tall_grass_texture = NULL; + self->tall_fern_texture = NULL; self->facemask_top = NULL; } @@ -102,6 +104,7 @@ rendermode_normal_finish(void *data, RenderState *state) { Py_XDECREF(self->leaf_texture); Py_XDECREF(self->grass_texture); Py_XDECREF(self->tall_grass_texture); + Py_XDECREF(self->tall_fern_texture); Py_XDECREF(self->facemask_top); } diff --git a/textures.py b/textures.py index 02c26c3..101b933 100644 --- a/textures.py +++ b/textures.py @@ -1678,7 +1678,7 @@ def generate(path=None): load_water() # generate biome (still grayscale) leaf, grass textures - global biome_grass_texture, biome_leaf_texture, biome_tall_grass_texture + global biome_grass_texture, biome_leaf_texture, biome_tall_grass_texture, biome_tall_fern_texture 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) From 733e816dbc0fd6454c2f1bc13c70abd790933e4b Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Tue, 31 May 2011 19:48:07 -0400 Subject: [PATCH 12/12] fixed biome loading order --- world.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/world.py b/world.py index 348aff3..f02098c 100644 --- a/world.py +++ b/world.py @@ -100,9 +100,6 @@ class World(object): logging.error("Sorry, This version of Minecraft-Overviewer only works with the new McRegion chunk format") sys.exit(1) - if self.useBiomeData: - textures.prepareBiomeData(worlddir) - # stores Points Of Interest to be mapped with markers # a list of dictionaries, see below for an example self.POI = []