From 4eaf103213f7fcc78f99bcf2394f592eb48528b5 Mon Sep 17 00:00:00 2001 From: Aaron Griffith Date: Fri, 6 Jan 2012 20:23:15 -0500 Subject: [PATCH] fixes to get lighting mode working again --- overviewer_core/rendermodes.py | 74 +++++++++++++++++++++++ overviewer_core/src/iterate.c | 30 +++++---- overviewer_core/src/overviewer.h | 5 +- overviewer_core/src/rendermode-lighting.c | 22 +++---- overviewer_core/src/rendermodes.c | 4 +- overviewer_core/textures.py | 12 ++-- setup.py | 2 +- 7 files changed, 118 insertions(+), 31 deletions(-) create mode 100644 overviewer_core/rendermodes.py diff --git a/overviewer_core/rendermodes.py b/overviewer_core/rendermodes.py new file mode 100644 index 0000000..e3386a3 --- /dev/null +++ b/overviewer_core/rendermodes.py @@ -0,0 +1,74 @@ +# This file is part of the Minecraft Overviewer. +# +# Minecraft Overviewer is free software: you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation, either version 3 of the License, or (at +# your option) any later version. +# +# Minecraft Overviewer is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with the Overviewer. If not, see . + +from PIL import Image +import textures + +# Render 3 blending masks for lighting +# first is top (+Z), second is left (-X), third is right (+Y) +def generate_facemasks(): + white = Image.new("L", (24,24), 255) + + top = Image.new("L", (24,24), 0) + left = Image.new("L", (24,24), 0) + whole = Image.new("L", (24,24), 0) + + toppart = textures.Textures.transform_image_top(white) + leftpart = textures.Textures.transform_image_side(white) + + # using the real PIL paste here (not alpha_over) because there is + # no alpha channel (and it's mode "L") + top.paste(toppart, (0,0)) + left.paste(leftpart, (0,6)) + right = left.transpose(Image.FLIP_LEFT_RIGHT) + + # Manually touch up 6 pixels that leave a gap, like in + # textures._build_block() + for x,y in [(13,23), (17,21), (21,19)]: + right.putpixel((x,y), 255) + for x,y in [(3,4), (7,2), (11,0)]: + top.putpixel((x,y), 255) + + # special fix for chunk boundary stipple + for x,y in [(13,11), (17,9), (21,7)]: + right.putpixel((x,y), 0) + + return (top, left, right) +facemasks = generate_facemasks() +black_color = Image.new("RGB", (24,24), (0,0,0)) +white_color = Image.new("RGB", (24,24), (255,255,255)) + +# Render 128 different color images for color coded depth blending in cave mode +def generate_depthcolors(): + depth_colors = [] + r = 255 + g = 0 + b = 0 + for z in range(128): + depth_colors.append(r) + depth_colors.append(g) + depth_colors.append(b) + + if z < 32: + g += 7 + elif z < 64: + r -= 7 + elif z < 96: + b += 7 + else: + g -= 7 + + return depth_colors +depth_colors = generate_depthcolors() diff --git a/overviewer_core/src/iterate.c b/overviewer_core/src/iterate.c index da30595..22cfabd 100644 --- a/overviewer_core/src/iterate.c +++ b/overviewer_core/src/iterate.c @@ -18,6 +18,7 @@ #include "overviewer.h" static PyObject *textures = NULL; +static PyObject *support = NULL; unsigned int max_blockid = 0; unsigned int max_data = 0; @@ -46,6 +47,11 @@ PyObject *init_chunk_render(void) { return NULL; } + support = PyImport_ImportModule("overviewer_core.rendermodes"); + if (!support) { + return NULL; + } + tmp = PyObject_GetAttrString(textures, "max_blockid"); if (!tmp) return NULL; @@ -96,7 +102,9 @@ PyObject *init_chunk_render(void) { Py_RETURN_NONE; } -PyObject *get_chunk_data(PyObject *region_set, int x, int z, ChunkNeighborName neighbor, ChunkDataType type) { +PyObject *get_chunk_data(RenderState *state, ChunkNeighborName neighbor, ChunkDataType type) { + int x = state->chunkx; + int z = state->chunkz; PyObject *chunk = NULL; PyObject *data = NULL; @@ -117,7 +125,7 @@ PyObject *get_chunk_data(PyObject *region_set, int x, int z, ChunkNeighborName n break; } - chunk = PyObject_CallMethod(region_set, "get_chunk", "ii", x, z); + chunk = PyObject_CallMethod(state->regionset, "get_chunk", "ii", x, z); if (chunk == NULL || chunk == Py_None) return chunk; @@ -401,10 +409,8 @@ chunk_render(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "OiiOiisO", &state.regionset, &state.chunkx, &state.chunkz, &state.img, &xoff, &yoff, &rendermode_name, &state.textures)) return NULL; - /* conveniences */ - regionset = state.regionset; - chunkx = state.chunkx; - chunkz = state.chunkz; + /* rendermode support */ + state.support = support; /* set up the render mode */ state.rendermode = rendermode = render_mode_create(rendermode_name, &state); @@ -435,25 +441,25 @@ chunk_render(PyObject *self, PyObject *args) { Py_DECREF(imgsize1_py); /* get the block data directly from numpy: */ - blocks_py = get_chunk_data(regionset, chunkx, chunkz, CURRENT, BLOCKS); + blocks_py = get_chunk_data(&state, CURRENT, BLOCKS); state.blocks = blocks_py; if (blocks_py == Py_None) { PyErr_SetString(PyExc_RuntimeError, "chunk does not exist!"); return NULL; } - state.blockdatas = get_chunk_data(regionset, chunkx, chunkz, CURRENT, BLOCKDATA); + state.blockdatas = get_chunk_data(&state, CURRENT, BLOCKDATA); - left_blocks_py = get_chunk_data(regionset, chunkx, chunkz, DOWN_LEFT, BLOCKS); + left_blocks_py = get_chunk_data(&state, DOWN_LEFT, BLOCKS); state.left_blocks = left_blocks_py; - right_blocks_py = get_chunk_data(regionset, chunkx, chunkz, DOWN_RIGHT, BLOCKS); + right_blocks_py = get_chunk_data(&state, DOWN_RIGHT, BLOCKS); state.right_blocks = right_blocks_py; - up_left_blocks_py = get_chunk_data(regionset, chunkx, chunkz, UP_LEFT, BLOCKS); + up_left_blocks_py = get_chunk_data(&state, UP_LEFT, BLOCKS); state.up_left_blocks = up_left_blocks_py; - up_right_blocks_py = get_chunk_data(regionset, chunkx, chunkz, UP_RIGHT, BLOCKS); + up_right_blocks_py = get_chunk_data(&state, UP_RIGHT, BLOCKS); state.up_right_blocks = up_right_blocks_py; /* set up the random number generator again for each chunk diff --git a/overviewer_core/src/overviewer.h b/overviewer_core/src/overviewer.h index f6025f6..1155724 100644 --- a/overviewer_core/src/overviewer.h +++ b/overviewer_core/src/overviewer.h @@ -79,6 +79,9 @@ typedef struct { /* the Texture object */ PyObject *textures; + /* the rendermode support module (rendermodes.py) */ + PyObject *support; + /* the block position and type, and the block array */ int x, y, z; unsigned char block; @@ -137,7 +140,7 @@ typedef enum UP_RIGHT, /* +1, 0 */ UP_LEFT, /* 0, -1 */ } ChunkNeighborName; -PyObject *get_chunk_data(PyObject *region_set, int x, int z, ChunkNeighborName neighbor, ChunkDataType type); +PyObject *get_chunk_data(RenderState *state, ChunkNeighborName neighbor, ChunkDataType type); /* pull in the rendermode info */ #include "rendermodes.h" diff --git a/overviewer_core/src/rendermode-lighting.c b/overviewer_core/src/rendermode-lighting.c index 6a984da..a6eca00 100644 --- a/overviewer_core/src/rendermode-lighting.c +++ b/overviewer_core/src/rendermode-lighting.c @@ -360,22 +360,22 @@ rendermode_lighting_start(void *data, RenderState *state, PyObject *options) { if (!render_mode_parse_option(options, "color_light", "i", &(self->color_light))) return 1; - self->facemasks_py = PyObject_GetAttrString(state->chunk, "facemasks"); + self->facemasks_py = PyObject_GetAttrString(state->support, "facemasks"); // borrowed references, don't need to be decref'd self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0); self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1); self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2); - self->skylight = PyObject_GetAttrString(state->self, "skylight"); - self->blocklight = PyObject_GetAttrString(state->self, "blocklight"); - self->left_skylight = PyObject_GetAttrString(state->self, "left_skylight"); - self->left_blocklight = PyObject_GetAttrString(state->self, "left_blocklight"); - self->right_skylight = PyObject_GetAttrString(state->self, "right_skylight"); - self->right_blocklight = PyObject_GetAttrString(state->self, "right_blocklight"); - self->up_left_skylight = PyObject_GetAttrString(state->self, "up_left_skylight"); - self->up_left_blocklight = PyObject_GetAttrString(state->self, "up_left_blocklight"); - self->up_right_skylight = PyObject_GetAttrString(state->self, "up_right_skylight"); - self->up_right_blocklight = PyObject_GetAttrString(state->self, "up_right_blocklight"); + self->skylight = get_chunk_data(state, CURRENT, SKYLIGHT); + self->blocklight = get_chunk_data(state, CURRENT, BLOCKLIGHT); + self->left_skylight = get_chunk_data(state, DOWN_LEFT, SKYLIGHT); + self->left_blocklight = get_chunk_data(state, DOWN_LEFT, BLOCKLIGHT); + self->right_skylight = get_chunk_data(state, DOWN_RIGHT, SKYLIGHT); + self->right_blocklight = get_chunk_data(state, DOWN_RIGHT, BLOCKLIGHT); + self->up_left_skylight = get_chunk_data(state, UP_LEFT, SKYLIGHT); + self->up_left_blocklight = get_chunk_data(state, UP_LEFT, BLOCKLIGHT); + self->up_right_skylight = get_chunk_data(state, UP_RIGHT, SKYLIGHT); + self->up_right_blocklight = get_chunk_data(state, UP_RIGHT, BLOCKLIGHT); if (self->night) { self->calculate_light_color = calculate_light_color_night; diff --git a/overviewer_core/src/rendermodes.c b/overviewer_core/src/rendermodes.c index 06359c0..b22a6bf 100644 --- a/overviewer_core/src/rendermodes.c +++ b/overviewer_core/src/rendermodes.c @@ -24,8 +24,8 @@ that are only useful as a base for other modes. */ static RenderModeInterface *render_modes[] = { &rendermode_normal, - /*&rendermode_lighting, - &rendermode_smooth_lighting, + &rendermode_lighting, + /*&rendermode_smooth_lighting, &rendermode_spawn, &rendermode_cave, &rendermode_mineral,*/ diff --git a/overviewer_core/textures.py b/overviewer_core/textures.py index 6de8101..b031516 100644 --- a/overviewer_core/textures.py +++ b/overviewer_core/textures.py @@ -255,7 +255,8 @@ class Textures(object): ## Image Transformation Functions ## - def transform_image_top(self, img): + @staticmethod + def transform_image_top(img): """Takes a PIL image and rotates it left 45 degrees and shrinks the y axis by a factor of 2. Returns the resulting image, which will be 24x12 pixels @@ -283,7 +284,8 @@ class Textures(object): newimg = img.transform((24,12), Image.AFFINE, transform) return newimg - def transform_image_side(self, img): + @staticmethod + def transform_image_side(img): """Takes an image and shears it for the left side of the cube (reflect for the right side)""" @@ -299,7 +301,8 @@ class Textures(object): newimg = img.transform((12,18), Image.AFFINE, transform) return newimg - def transform_image_slope(self, img): + @staticmethod + def transform_image_slope(img): """Takes an image and shears it in the shape of a slope going up in the -y direction (reflect for +x direction). Used for minetracks""" @@ -316,7 +319,8 @@ class Textures(object): return newimg - def transform_image_angle(self, img, angle): + @staticmethod + def transform_image_angle(img, angle): """Takes an image an shears it in arbitrary angle with the axis of rotation being vertical. diff --git a/setup.py b/setup.py index 139f641..d9ed66e 100755 --- a/setup.py +++ b/setup.py @@ -150,7 +150,7 @@ except Exception: # used to figure out what files to compile #render_modes = ['normal', 'overlay', 'lighting', 'smooth-lighting', 'spawn', 'cave', 'mineral'] -render_modes = ['normal'] +render_modes = ['normal', 'lighting'] c_overviewer_files = ['main.c', 'composite.c', 'iterate.c', 'endian.c', 'rendermodes.c'] c_overviewer_files += map(lambda mode: 'rendermode-%s.c' % (mode,), render_modes)