fixes to get lighting mode working again
This commit is contained in:
74
overviewer_core/rendermodes.py
Normal file
74
overviewer_core/rendermodes.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
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()
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "overviewer.h"
|
#include "overviewer.h"
|
||||||
|
|
||||||
static PyObject *textures = NULL;
|
static PyObject *textures = NULL;
|
||||||
|
static PyObject *support = NULL;
|
||||||
|
|
||||||
unsigned int max_blockid = 0;
|
unsigned int max_blockid = 0;
|
||||||
unsigned int max_data = 0;
|
unsigned int max_data = 0;
|
||||||
@@ -46,6 +47,11 @@ PyObject *init_chunk_render(void) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
support = PyImport_ImportModule("overviewer_core.rendermodes");
|
||||||
|
if (!support) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = PyObject_GetAttrString(textures, "max_blockid");
|
tmp = PyObject_GetAttrString(textures, "max_blockid");
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -96,7 +102,9 @@ PyObject *init_chunk_render(void) {
|
|||||||
Py_RETURN_NONE;
|
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 *chunk = NULL;
|
||||||
PyObject *data = NULL;
|
PyObject *data = NULL;
|
||||||
|
|
||||||
@@ -117,7 +125,7 @@ PyObject *get_chunk_data(PyObject *region_set, int x, int z, ChunkNeighborName n
|
|||||||
break;
|
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)
|
if (chunk == NULL || chunk == Py_None)
|
||||||
return chunk;
|
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))
|
if (!PyArg_ParseTuple(args, "OiiOiisO", &state.regionset, &state.chunkx, &state.chunkz, &state.img, &xoff, &yoff, &rendermode_name, &state.textures))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* conveniences */
|
/* rendermode support */
|
||||||
regionset = state.regionset;
|
state.support = support;
|
||||||
chunkx = state.chunkx;
|
|
||||||
chunkz = state.chunkz;
|
|
||||||
|
|
||||||
/* set up the render mode */
|
/* set up the render mode */
|
||||||
state.rendermode = rendermode = render_mode_create(rendermode_name, &state);
|
state.rendermode = rendermode = render_mode_create(rendermode_name, &state);
|
||||||
@@ -435,25 +441,25 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
Py_DECREF(imgsize1_py);
|
Py_DECREF(imgsize1_py);
|
||||||
|
|
||||||
/* get the block data directly from numpy: */
|
/* 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;
|
state.blocks = blocks_py;
|
||||||
if (blocks_py == Py_None) {
|
if (blocks_py == Py_None) {
|
||||||
PyErr_SetString(PyExc_RuntimeError, "chunk does not exist!");
|
PyErr_SetString(PyExc_RuntimeError, "chunk does not exist!");
|
||||||
return NULL;
|
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;
|
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;
|
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;
|
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;
|
state.up_right_blocks = up_right_blocks_py;
|
||||||
|
|
||||||
/* set up the random number generator again for each chunk
|
/* set up the random number generator again for each chunk
|
||||||
|
|||||||
@@ -79,6 +79,9 @@ typedef struct {
|
|||||||
/* the Texture object */
|
/* the Texture object */
|
||||||
PyObject *textures;
|
PyObject *textures;
|
||||||
|
|
||||||
|
/* the rendermode support module (rendermodes.py) */
|
||||||
|
PyObject *support;
|
||||||
|
|
||||||
/* the block position and type, and the block array */
|
/* the block position and type, and the block array */
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
unsigned char block;
|
unsigned char block;
|
||||||
@@ -137,7 +140,7 @@ typedef enum
|
|||||||
UP_RIGHT, /* +1, 0 */
|
UP_RIGHT, /* +1, 0 */
|
||||||
UP_LEFT, /* 0, -1 */
|
UP_LEFT, /* 0, -1 */
|
||||||
} ChunkNeighborName;
|
} 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 */
|
/* pull in the rendermode info */
|
||||||
#include "rendermodes.h"
|
#include "rendermodes.h"
|
||||||
|
|||||||
@@ -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)))
|
if (!render_mode_parse_option(options, "color_light", "i", &(self->color_light)))
|
||||||
return 1;
|
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
|
// borrowed references, don't need to be decref'd
|
||||||
self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0);
|
self->facemasks[0] = PyTuple_GetItem(self->facemasks_py, 0);
|
||||||
self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1);
|
self->facemasks[1] = PyTuple_GetItem(self->facemasks_py, 1);
|
||||||
self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2);
|
self->facemasks[2] = PyTuple_GetItem(self->facemasks_py, 2);
|
||||||
|
|
||||||
self->skylight = PyObject_GetAttrString(state->self, "skylight");
|
self->skylight = get_chunk_data(state, CURRENT, SKYLIGHT);
|
||||||
self->blocklight = PyObject_GetAttrString(state->self, "blocklight");
|
self->blocklight = get_chunk_data(state, CURRENT, BLOCKLIGHT);
|
||||||
self->left_skylight = PyObject_GetAttrString(state->self, "left_skylight");
|
self->left_skylight = get_chunk_data(state, DOWN_LEFT, SKYLIGHT);
|
||||||
self->left_blocklight = PyObject_GetAttrString(state->self, "left_blocklight");
|
self->left_blocklight = get_chunk_data(state, DOWN_LEFT, BLOCKLIGHT);
|
||||||
self->right_skylight = PyObject_GetAttrString(state->self, "right_skylight");
|
self->right_skylight = get_chunk_data(state, DOWN_RIGHT, SKYLIGHT);
|
||||||
self->right_blocklight = PyObject_GetAttrString(state->self, "right_blocklight");
|
self->right_blocklight = get_chunk_data(state, DOWN_RIGHT, BLOCKLIGHT);
|
||||||
self->up_left_skylight = PyObject_GetAttrString(state->self, "up_left_skylight");
|
self->up_left_skylight = get_chunk_data(state, UP_LEFT, SKYLIGHT);
|
||||||
self->up_left_blocklight = PyObject_GetAttrString(state->self, "up_left_blocklight");
|
self->up_left_blocklight = get_chunk_data(state, UP_LEFT, BLOCKLIGHT);
|
||||||
self->up_right_skylight = PyObject_GetAttrString(state->self, "up_right_skylight");
|
self->up_right_skylight = get_chunk_data(state, UP_RIGHT, SKYLIGHT);
|
||||||
self->up_right_blocklight = PyObject_GetAttrString(state->self, "up_right_blocklight");
|
self->up_right_blocklight = get_chunk_data(state, UP_RIGHT, BLOCKLIGHT);
|
||||||
|
|
||||||
if (self->night) {
|
if (self->night) {
|
||||||
self->calculate_light_color = calculate_light_color_night;
|
self->calculate_light_color = calculate_light_color_night;
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
that are only useful as a base for other modes. */
|
that are only useful as a base for other modes. */
|
||||||
static RenderModeInterface *render_modes[] = {
|
static RenderModeInterface *render_modes[] = {
|
||||||
&rendermode_normal,
|
&rendermode_normal,
|
||||||
/*&rendermode_lighting,
|
&rendermode_lighting,
|
||||||
&rendermode_smooth_lighting,
|
/*&rendermode_smooth_lighting,
|
||||||
&rendermode_spawn,
|
&rendermode_spawn,
|
||||||
&rendermode_cave,
|
&rendermode_cave,
|
||||||
&rendermode_mineral,*/
|
&rendermode_mineral,*/
|
||||||
|
|||||||
@@ -255,7 +255,8 @@ class Textures(object):
|
|||||||
## Image Transformation Functions
|
## 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
|
"""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
|
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)
|
newimg = img.transform((24,12), Image.AFFINE, transform)
|
||||||
return newimg
|
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
|
"""Takes an image and shears it for the left side of the cube (reflect for
|
||||||
the right side)"""
|
the right side)"""
|
||||||
|
|
||||||
@@ -299,7 +301,8 @@ class Textures(object):
|
|||||||
newimg = img.transform((12,18), Image.AFFINE, transform)
|
newimg = img.transform((12,18), Image.AFFINE, transform)
|
||||||
return newimg
|
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
|
"""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"""
|
in the -y direction (reflect for +x direction). Used for minetracks"""
|
||||||
|
|
||||||
@@ -316,7 +319,8 @@ class Textures(object):
|
|||||||
return newimg
|
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
|
"""Takes an image an shears it in arbitrary angle with the axis of
|
||||||
rotation being vertical.
|
rotation being vertical.
|
||||||
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -150,7 +150,7 @@ except Exception:
|
|||||||
|
|
||||||
# used to figure out what files to compile
|
# used to figure out what files to compile
|
||||||
#render_modes = ['normal', 'overlay', 'lighting', 'smooth-lighting', 'spawn', 'cave', 'mineral']
|
#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 = ['main.c', 'composite.c', 'iterate.c', 'endian.c', 'rendermodes.c']
|
||||||
c_overviewer_files += map(lambda mode: 'rendermode-%s.c' % (mode,), render_modes)
|
c_overviewer_files += map(lambda mode: 'rendermode-%s.c' % (mode,), render_modes)
|
||||||
|
|||||||
Reference in New Issue
Block a user