0

added 'lighting' option to cave mode

This commit is contained in:
Aaron Griffith
2011-06-12 22:03:42 -04:00
parent 3d6042260c
commit bdee438060
11 changed files with 54 additions and 36 deletions

View File

@@ -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))

View File

@@ -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;
} }

View File

@@ -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 */

View File

@@ -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 */
if (self->lighting) {
rendermode_lighting.draw(data, state, src, mask, mask_light);
} else {
rendermode_normal.draw(data, state, src, mask, mask_light); 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,

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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)) &&

View File

@@ -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

View File

@@ -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) {

View File

@@ -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;