From dc80c88e94803a98242ece5546103d813a0cff2a Mon Sep 17 00:00:00 2001 From: Andrew Chin Date: Sun, 14 Nov 2010 15:07:26 -0500 Subject: [PATCH] Biome tinting uses now uses the Biome Extractor data files. See: http://www.minecraftforum.net/viewtopic.php?f=25&t=80902&view=unread --- chunk.py | 30 +++++++++++++++++++++++----- textures.py | 56 ++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/chunk.py b/chunk.py index 400d7ca..85b4f08 100644 --- a/chunk.py +++ b/chunk.py @@ -14,10 +14,12 @@ # with the Overviewer. If not, see . import numpy -from PIL import Image, ImageDraw, ImageEnhance +from PIL import Image, ImageDraw, ImageEnhance, ImageOps import os.path import hashlib import logging +import time +import math import nbt import textures @@ -473,6 +475,7 @@ class ChunkRenderer(object): For cave mode, all blocks that have any direct sunlight are not rendered, and blocks are drawn with a color tint depending on their depth.""" + blocks = self.blocks if cave: @@ -494,6 +497,11 @@ class ChunkRenderer(object): tileEntities = get_tileentity_data(self.level) + biomeColorData = textures.prepareBiomeData(self.world.worlddir, + self.chunkX, self.chunkY) + # in the 8x8 block of biome data, what chunk is this?l + startX = (self.chunkX - int(math.floor(self.chunkX/8)*8)) + startY = (self.chunkY - int(math.floor(self.chunkY/8)*8)) # Each block is 24x24 # The next block on the X axis adds 12px to x and subtracts 6px from y in the image @@ -528,8 +536,22 @@ class ChunkRenderer(object): if not t: continue - if blockid in (2,18): # grass or leaves, tint according to biome - t = textures.tintForBiome(t, (16*self.chunkX) + x,y+(16*self.chunkY)) + if blockid == 2: #grass + index = biomeColorData[ ((startY*16)+y) * 128 + (startX*16) + x] + c = textures.grasscolor[index] + + # only tint the top texture + t = textures.prepareGrassTexture(c) + elif blockid == 18: # leaves + index = biomeColorData[ ((startY*16)+y) * 128 + (startX*16) + x] + c = textures.foliagecolor[index] + #i = textures.tintTexture(t,c) + i = ImageOps.colorize(ImageOps.grayscale(t[0]), (0,0,0), c) + i.putalpha(t[1]) + t = (i, t[1]) + + + # Check if this block is occluded if cave and ( @@ -648,8 +670,6 @@ class ChunkRenderer(object): # list above. self.queue.put(['removePOI', (self.chunkX, self.chunkY)]) - - return img # Render 3 blending masks for lighting diff --git a/textures.py b/textures.py index 6f782b7..08408ed 100644 --- a/textures.py +++ b/textures.py @@ -538,30 +538,50 @@ def tintTexture(im, c): i.putalpha(im.split()[3]); # copy the alpha band back in. assuming RGBA return i -## prepare grasscolor.png +grassSide1 = transform_image_side(terrain_images[3]) +grassSide2 = transform_image_side(terrain_images[3]).transpose(Image.FLIP_LEFT_RIGHT) +def prepareGrassTexture(color): + top = transform_image(tintTexture(terrain_images[0],color)) + img = Image.new("RGBA", (24,24), (38,92,255,0)) + + img.paste(grassSide1, (0,6), grassSide1) + img.paste(grassSide2, (12,6), grassSide2) + img.paste(top, (0,0), top) + return (img.convert("RGB"), img.split()[3]) + +# TODO be more intelligent about where to find these files grasscolor = list(Image.open("grasscolor.png").getdata()) +foliagecolor = list(Image.open("foliagecolor.png").getdata()) +currentBiomeFile = None +currentBiomeData = None +def prepareBiomeData(worlddir, chunkX, chunkY): + '''Opens the worlddir and reads in the biome color information + from the .biome files. See also: + http://www.minecraftforum.net/viewtopic.php?f=25&t=80902 + ''' + t = sys.modules[__name__] + if not os.path.exists(os.path.join(worlddir, "EXTRACTEDBIOMES")): + raise Exception("EXTRACTEDBIOMES not found") + biomeFile = "%d.%d.biome" % ( + int(math.floor(chunkX/8)*8), + int(math.floor(chunkY/8)*8) + ) + if biomeFile == t.currentBiomeFile: + return currentBiomeData -def tintForBiome(im, x, y): - result = gmc.submit_job("GetBiome", "%d,%d" % (x,y)) - temp, moisture = map(lambda x: float(x),result.result.split("/")) + t.currentBiomeFile = biomeFile - #print result.result - moisture *= temp - i = int((1.0 - temp) * 255) - j = int((1.0 - moisture) * 255) - #print "tintInfo for %d,%d is %f,%f coord %d, %d" % (x,y, temp, moisture, i, j) - #print "resulting color: %r" % (grasscolor.getpixel((i,j))[:-1],) - #t = tintTexture(im[0], grasscolor.getpixel((i, j))[:-1]) - #im[0] = t - #c = grasscolor.getpixel((j,i))[:-1] - c = grasscolor[(j << 8 | i)] - #print "grass color: %r" % (c,) - i = ImageOps.colorize(ImageOps.grayscale(im[0]), (0,0,0), c) - i.putalpha(im[1]) - return (i, im[1]) + f = open(os.path.join(worlddir, "EXTRACTEDBIOMES", biomeFile)) + rawdata = f.read() + f.close() + data = numpy.frombuffer(rawdata, dtype=numpy.dtype(">u2")) + + t.currentBiomeData = data + return data + # This set holds block ids that require special pre-computing. These are typically # things that require ancillary data to render properly (i.e. ladder plus orientation)