Biome tinting uses now uses the Biome Extractor data files.
See: http://www.minecraftforum.net/viewtopic.php?f=25&t=80902&view=unread
This commit is contained in:
30
chunk.py
30
chunk.py
@@ -14,10 +14,12 @@
|
||||
# with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
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
|
||||
|
||||
56
textures.py
56
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)
|
||||
|
||||
Reference in New Issue
Block a user