added 'lighting' option to cave mode
This commit is contained in:
4
chunk.py
4
chunk.py
@@ -476,6 +476,10 @@ def generate_facemasks():
|
|||||||
for x,y in [(3,4), (7,2), (11,0)]:
|
for x,y in [(3,4), (7,2), (11,0)]:
|
||||||
top.putpixel((x,y), 255)
|
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)
|
return (top, left, right)
|
||||||
facemasks = generate_facemasks()
|
facemasks = generate_facemasks()
|
||||||
black_color = Image.new("RGB", (24,24), (0,0,0))
|
black_color = Image.new("RGB", (24,24), (0,0,0))
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
|
|
||||||
/* set up the render mode */
|
/* set up the render mode */
|
||||||
rendermode_py = PyObject_GetAttrString(state.self, "rendermode");
|
rendermode_py = PyObject_GetAttrString(state.self, "rendermode");
|
||||||
rendermode = render_mode_create(PyString_AsString(rendermode_py), &state);
|
state.rendermode = rendermode = render_mode_create(PyString_AsString(rendermode_py), &state);
|
||||||
Py_DECREF(rendermode_py);
|
Py_DECREF(rendermode_py);
|
||||||
if (rendermode == NULL) {
|
if (rendermode == NULL) {
|
||||||
return Py_BuildValue("i", "-1");
|
return Py_BuildValue("i", "-1");
|
||||||
@@ -386,7 +386,7 @@ chunk_render(PyObject *self, PyObject *args) {
|
|||||||
blockid = PyInt_FromLong(state.block);
|
blockid = PyInt_FromLong(state.block);
|
||||||
|
|
||||||
// check for occlusion
|
// check for occlusion
|
||||||
if (render_mode_occluded(rendermode)) {
|
if (render_mode_occluded(rendermode, state.x, state.y, state.z)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,9 @@ PyObject *tint_with_mask(PyObject *dest, unsigned char sr, unsigned char sg,
|
|||||||
unsigned char sb, unsigned char sa,
|
unsigned char sb, unsigned char sa,
|
||||||
PyObject *mask, int dx, int dy, int xsize, int ysize);
|
PyObject *mask, int dx, int dy, int xsize, int ysize);
|
||||||
|
|
||||||
|
/* forward declaration of RenderMode object */
|
||||||
|
typedef struct _RenderMode RenderMode;
|
||||||
|
|
||||||
/* in iterate.c */
|
/* in iterate.c */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* the ChunkRenderer object */
|
/* the ChunkRenderer object */
|
||||||
@@ -61,6 +64,9 @@ typedef struct {
|
|||||||
PyObject *textures;
|
PyObject *textures;
|
||||||
PyObject *chunk;
|
PyObject *chunk;
|
||||||
|
|
||||||
|
/* the current render mode in use */
|
||||||
|
RenderMode *rendermode;
|
||||||
|
|
||||||
/* the rest only make sense for occluded() and draw() !! */
|
/* the rest only make sense for occluded() and draw() !! */
|
||||||
|
|
||||||
/* the tile image and destination */
|
/* the tile image and destination */
|
||||||
|
|||||||
@@ -80,13 +80,13 @@ touches_light(unsigned int x, unsigned int y, unsigned int z,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_cave_occluded(void *data, RenderState *state) {
|
rendermode_cave_occluded(void *data, RenderState *state, int x, int y, int z) {
|
||||||
int x = state->x, y = state->y, z = state->z, dz = 0;
|
|
||||||
RenderModeCave* self;
|
RenderModeCave* self;
|
||||||
|
int dz = 0;
|
||||||
self = (RenderModeCave *)data;
|
self = (RenderModeCave *)data;
|
||||||
|
|
||||||
/* first, check to see if it's "normally" occluded */
|
/* first, check to see if it's "normally" occluded */
|
||||||
if (rendermode_normal.occluded(data, state))
|
if (rendermode_lighting.occluded(data, state, x, y, z))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* check if the block is touching skylight */
|
/* check if the block is touching skylight */
|
||||||
@@ -182,7 +182,7 @@ rendermode_cave_start(void *data, RenderState *state, PyObject *options) {
|
|||||||
self = (RenderModeCave *)data;
|
self = (RenderModeCave *)data;
|
||||||
|
|
||||||
/* first, chain up */
|
/* first, chain up */
|
||||||
ret = rendermode_normal.start(data, state, options);
|
ret = rendermode_lighting.start(data, state, options);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -200,6 +200,13 @@ rendermode_cave_start(void *data, RenderState *state, PyObject *options) {
|
|||||||
self->only_lit = 0;
|
self->only_lit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
opt = PyDict_GetItemString(options, "lighting");
|
||||||
|
if (opt) {
|
||||||
|
self->lighting = PyObject_IsTrue(opt);
|
||||||
|
} else {
|
||||||
|
self->lighting = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* if there's skylight we are in the surface! */
|
/* if there's skylight we are in the surface! */
|
||||||
self->skylight = PyObject_GetAttrString(state->self, "skylight");
|
self->skylight = PyObject_GetAttrString(state->self, "skylight");
|
||||||
self->left_skylight = PyObject_GetAttrString(state->self, "left_skylight");
|
self->left_skylight = PyObject_GetAttrString(state->self, "left_skylight");
|
||||||
@@ -242,7 +249,7 @@ rendermode_cave_finish(void *data, RenderState *state) {
|
|||||||
|
|
||||||
Py_DECREF(self->depth_colors);
|
Py_DECREF(self->depth_colors);
|
||||||
|
|
||||||
rendermode_normal.finish(data, state);
|
rendermode_lighting.finish(data, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -255,7 +262,11 @@ rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *ma
|
|||||||
r = 0, g = 0, b = 0;
|
r = 0, g = 0, b = 0;
|
||||||
|
|
||||||
/* draw the normal block */
|
/* draw the normal block */
|
||||||
rendermode_normal.draw(data, state, src, mask, mask_light);
|
if (self->lighting) {
|
||||||
|
rendermode_lighting.draw(data, state, src, mask, mask_light);
|
||||||
|
} else {
|
||||||
|
rendermode_normal.draw(data, state, src, mask, mask_light);
|
||||||
|
}
|
||||||
|
|
||||||
if (self->depth_tinting) {
|
if (self->depth_tinting) {
|
||||||
/* get the colors and tint and tint */
|
/* get the colors and tint and tint */
|
||||||
@@ -271,13 +282,14 @@ rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *ma
|
|||||||
static RenderModeOption rendermode_cave_options[] = {
|
static RenderModeOption rendermode_cave_options[] = {
|
||||||
{"depth_tinting", "tint caves based on how deep they are (default: True)"},
|
{"depth_tinting", "tint caves based on how deep they are (default: True)"},
|
||||||
{"only_lit", "only render lit caves (default: False)"},
|
{"only_lit", "only render lit caves (default: False)"},
|
||||||
|
{"lighting", "render caves with lighting enabled (default: False)"},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
RenderModeInterface rendermode_cave = {
|
RenderModeInterface rendermode_cave = {
|
||||||
"cave", "render only caves in normal mode",
|
"cave", "render only caves",
|
||||||
rendermode_cave_options,
|
rendermode_cave_options,
|
||||||
&rendermode_normal,
|
&rendermode_lighting,
|
||||||
sizeof(RenderModeCave),
|
sizeof(RenderModeCave),
|
||||||
rendermode_cave_start,
|
rendermode_cave_start,
|
||||||
rendermode_cave_finish,
|
rendermode_cave_finish,
|
||||||
|
|||||||
@@ -83,12 +83,6 @@ get_lighting_coefficient(RenderModeLighting *self, RenderState *state,
|
|||||||
|
|
||||||
block = getArrayByte3D(blocks, local_x, local_y, local_z);
|
block = getArrayByte3D(blocks, local_x, local_y, local_z);
|
||||||
|
|
||||||
/* if this block is opaque, use a fully-lit coeff instead
|
|
||||||
to prevent stippled lines along chunk boundaries! */
|
|
||||||
if (!is_transparent(block)) {
|
|
||||||
return self->calculate_darkness(15, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only do special half-step handling if no authoratative pointer was
|
/* only do special half-step handling if no authoratative pointer was
|
||||||
passed in, which is a sign that we're recursing */
|
passed in, which is a sign that we're recursing */
|
||||||
if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) {
|
if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) {
|
||||||
@@ -154,11 +148,14 @@ static inline void
|
|||||||
do_shading_with_mask(RenderModeLighting *self, RenderState *state,
|
do_shading_with_mask(RenderModeLighting *self, RenderState *state,
|
||||||
int x, int y, int z, PyObject *mask) {
|
int x, int y, int z, PyObject *mask) {
|
||||||
float black_coeff;
|
float black_coeff;
|
||||||
|
PyObject *blocks;
|
||||||
|
|
||||||
/* first, check for occlusion if the block is in the local chunk */
|
/* first, check for occlusion if the block is in the local chunk */
|
||||||
if (x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 128) {
|
if (x >= 0 && x < 16 && y >= 0 && y < 16 && z >= 0 && z < 128) {
|
||||||
unsigned char block = getArrayByte3D(state->blocks, x, y, z);
|
unsigned char block = getArrayByte3D(state->blocks, x, y, z);
|
||||||
if (!is_transparent(block)) {
|
int occluded = render_mode_occluded(state->rendermode, x, y, z);
|
||||||
|
|
||||||
|
if (!occluded && !is_transparent(block)) {
|
||||||
/* this face isn't visible, so don't draw anything */
|
/* this face isn't visible, so don't draw anything */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -230,9 +227,9 @@ rendermode_lighting_finish(void *data, RenderState *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_lighting_occluded(void *data, RenderState *state) {
|
rendermode_lighting_occluded(void *data, RenderState *state, int x, int y, int z) {
|
||||||
/* no special occlusion here */
|
/* no special occlusion here */
|
||||||
return rendermode_normal.occluded(data, state);
|
return rendermode_normal.occluded(data, state, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -48,9 +48,9 @@ rendermode_night_finish(void *data, RenderState *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_night_occluded(void *data, RenderState *state) {
|
rendermode_night_occluded(void *data, RenderState *state, int x, int y, int z) {
|
||||||
/* no special occlusion here */
|
/* no special occlusion here */
|
||||||
return rendermode_lighting.occluded(data, state);
|
return rendermode_lighting.occluded(data, state, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -144,9 +144,8 @@ rendermode_normal_finish(void *data, RenderState *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_normal_occluded(void *data, RenderState *state) {
|
rendermode_normal_occluded(void *data, RenderState *state, int x, int y, int z) {
|
||||||
RenderModeNormal *self = (RenderModeNormal *)data;
|
RenderModeNormal *self = (RenderModeNormal *)data;
|
||||||
int x = state->x, y = state->y, z = state->z;
|
|
||||||
|
|
||||||
if (z > self->max_depth || z < self->min_depth) {
|
if (z > self->max_depth || z < self->min_depth) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -57,9 +57,7 @@ rendermode_overlay_finish(void *data, RenderState *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_overlay_occluded(void *data, RenderState *state) {
|
rendermode_overlay_occluded(void *data, RenderState *state, int x, int y, int z) {
|
||||||
int x = state->x, y = state->y, z = state->z;
|
|
||||||
|
|
||||||
if ( (x != 0) && (y != 15) && (z != 127) &&
|
if ( (x != 0) && (y != 15) && (z != 127) &&
|
||||||
!is_transparent(getArrayByte3D(state->blocks, x-1, y, z)) &&
|
!is_transparent(getArrayByte3D(state->blocks, x-1, y, z)) &&
|
||||||
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1)) &&
|
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1)) &&
|
||||||
|
|||||||
@@ -96,9 +96,9 @@ rendermode_spawn_finish(void *data, RenderState *state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
rendermode_spawn_occluded(void *data, RenderState *state) {
|
rendermode_spawn_occluded(void *data, RenderState *state, int x, int y, int z) {
|
||||||
/* no special occlusion here */
|
/* no special occlusion here */
|
||||||
return rendermode_overlay.occluded(data, state);
|
return rendermode_overlay.occluded(data, state, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|||||||
@@ -164,8 +164,8 @@ void render_mode_destroy(RenderMode *self) {
|
|||||||
free(self);
|
free(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
int render_mode_occluded(RenderMode *self) {
|
int render_mode_occluded(RenderMode *self, int x, int y, int z) {
|
||||||
return self->iface->occluded(self->mode, self->state);
|
return self->iface->occluded(self->mode, self->state, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light) {
|
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light) {
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#define __RENDERMODES_H_INCLUDED__
|
#define __RENDERMODES_H_INCLUDED__
|
||||||
|
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
|
#include "overviewer.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -62,22 +63,22 @@ struct _RenderModeInterface {
|
|||||||
int (*start)(void *, RenderState *, PyObject *);
|
int (*start)(void *, RenderState *, PyObject *);
|
||||||
void (*finish)(void *, RenderState *);
|
void (*finish)(void *, RenderState *);
|
||||||
/* returns non-zero to skip rendering this block */
|
/* returns non-zero to skip rendering this block */
|
||||||
int (*occluded)(void *, RenderState *);
|
int (*occluded)(void *, RenderState *, int, int, int);
|
||||||
/* last two arguments are img and mask, from texture lookup */
|
/* last two arguments are img and mask, from texture lookup */
|
||||||
void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *);
|
void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *);
|
||||||
};
|
};
|
||||||
|
|
||||||
/* wrapper for passing around rendermodes */
|
/* wrapper for passing around rendermodes */
|
||||||
typedef struct {
|
struct _RenderMode {
|
||||||
void *mode;
|
void *mode;
|
||||||
RenderModeInterface *iface;
|
RenderModeInterface *iface;
|
||||||
RenderState *state;
|
RenderState *state;
|
||||||
} RenderMode;
|
};
|
||||||
|
|
||||||
/* functions for creating / using rendermodes */
|
/* functions for creating / using rendermodes */
|
||||||
RenderMode *render_mode_create(const char *mode, RenderState *state);
|
RenderMode *render_mode_create(const char *mode, RenderState *state);
|
||||||
void render_mode_destroy(RenderMode *self);
|
void render_mode_destroy(RenderMode *self);
|
||||||
int render_mode_occluded(RenderMode *self);
|
int render_mode_occluded(RenderMode *self, int x, int y, int z);
|
||||||
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light);
|
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light);
|
||||||
|
|
||||||
/* python metadata bindings */
|
/* python metadata bindings */
|
||||||
@@ -167,7 +168,7 @@ extern RenderModeInterface rendermode_spawn;
|
|||||||
/* CAVE */
|
/* CAVE */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* render blocks with lighting mode */
|
/* render blocks with lighting mode */
|
||||||
RenderModeNormal parent;
|
RenderModeLighting parent;
|
||||||
|
|
||||||
/* data used to know where the surface is */
|
/* data used to know where the surface is */
|
||||||
PyObject *skylight;
|
PyObject *skylight;
|
||||||
@@ -188,6 +189,7 @@ typedef struct {
|
|||||||
|
|
||||||
int depth_tinting;
|
int depth_tinting;
|
||||||
int only_lit;
|
int only_lit;
|
||||||
|
int lighting;
|
||||||
} RenderModeCave;
|
} RenderModeCave;
|
||||||
extern RenderModeInterface rendermode_cave;
|
extern RenderModeInterface rendermode_cave;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user