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)]:
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))

View File

@@ -317,7 +317,7 @@ chunk_render(PyObject *self, PyObject *args) {
/* set up the render mode */
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);
if (rendermode == NULL) {
return Py_BuildValue("i", "-1");
@@ -386,7 +386,7 @@ chunk_render(PyObject *self, PyObject *args) {
blockid = PyInt_FromLong(state.block);
// check for occlusion
if (render_mode_occluded(rendermode)) {
if (render_mode_occluded(rendermode, state.x, state.y, state.z)) {
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,
PyObject *mask, int dx, int dy, int xsize, int ysize);
/* forward declaration of RenderMode object */
typedef struct _RenderMode RenderMode;
/* in iterate.c */
typedef struct {
/* the ChunkRenderer object */
@@ -61,6 +64,9 @@ typedef struct {
PyObject *textures;
PyObject *chunk;
/* the current render mode in use */
RenderMode *rendermode;
/* the rest only make sense for occluded() and draw() !! */
/* the tile image and destination */

View File

@@ -80,13 +80,13 @@ touches_light(unsigned int x, unsigned int y, unsigned int z,
}
static int
rendermode_cave_occluded(void *data, RenderState *state) {
int x = state->x, y = state->y, z = state->z, dz = 0;
rendermode_cave_occluded(void *data, RenderState *state, int x, int y, int z) {
RenderModeCave* self;
int dz = 0;
self = (RenderModeCave *)data;
/* 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;
/* check if the block is touching skylight */
@@ -182,7 +182,7 @@ rendermode_cave_start(void *data, RenderState *state, PyObject *options) {
self = (RenderModeCave *)data;
/* first, chain up */
ret = rendermode_normal.start(data, state, options);
ret = rendermode_lighting.start(data, state, options);
if (ret != 0)
return ret;
@@ -200,6 +200,13 @@ rendermode_cave_start(void *data, RenderState *state, PyObject *options) {
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! */
self->skylight = PyObject_GetAttrString(state->self, "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);
rendermode_normal.finish(data, state);
rendermode_lighting.finish(data, state);
}
static void
@@ -255,7 +262,11 @@ rendermode_cave_draw(void *data, RenderState *state, PyObject *src, PyObject *ma
r = 0, g = 0, b = 0;
/* 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) {
/* 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[] = {
{"depth_tinting", "tint caves based on how deep they are (default: True)"},
{"only_lit", "only render lit caves (default: False)"},
{"lighting", "render caves with lighting enabled (default: False)"},
{NULL, NULL}
};
RenderModeInterface rendermode_cave = {
"cave", "render only caves in normal mode",
"cave", "render only caves",
rendermode_cave_options,
&rendermode_normal,
&rendermode_lighting,
sizeof(RenderModeCave),
rendermode_cave_start,
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);
/* 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
passed in, which is a sign that we're recursing */
if ((block == 44 || block == 53 || block == 67) && authoratative == NULL) {
@@ -154,11 +148,14 @@ static inline void
do_shading_with_mask(RenderModeLighting *self, RenderState *state,
int x, int y, int z, PyObject *mask) {
float black_coeff;
PyObject *blocks;
/* 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) {
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 */
return;
}
@@ -230,9 +227,9 @@ rendermode_lighting_finish(void *data, RenderState *state) {
}
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 */
return rendermode_normal.occluded(data, state);
return rendermode_normal.occluded(data, state, x, y, z);
}
static void

View File

@@ -48,9 +48,9 @@ rendermode_night_finish(void *data, RenderState *state) {
}
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 */
return rendermode_lighting.occluded(data, state);
return rendermode_lighting.occluded(data, state, x, y, z);
}
static void

View File

@@ -144,9 +144,8 @@ rendermode_normal_finish(void *data, RenderState *state) {
}
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;
int x = state->x, y = state->y, z = state->z;
if (z > self->max_depth || z < self->min_depth) {
return 1;

View File

@@ -57,9 +57,7 @@ rendermode_overlay_finish(void *data, RenderState *state) {
}
static int
rendermode_overlay_occluded(void *data, RenderState *state) {
int x = state->x, y = state->y, z = state->z;
rendermode_overlay_occluded(void *data, RenderState *state, int x, int y, int z) {
if ( (x != 0) && (y != 15) && (z != 127) &&
!is_transparent(getArrayByte3D(state->blocks, x-1, y, z)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1)) &&

View File

@@ -96,9 +96,9 @@ rendermode_spawn_finish(void *data, RenderState *state) {
}
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 */
return rendermode_overlay.occluded(data, state);
return rendermode_overlay.occluded(data, state, x, y, z);
}
static void

View File

@@ -164,8 +164,8 @@ void render_mode_destroy(RenderMode *self) {
free(self);
}
int render_mode_occluded(RenderMode *self) {
return self->iface->occluded(self->mode, self->state);
int render_mode_occluded(RenderMode *self, int x, int y, int z) {
return self->iface->occluded(self->mode, self->state, x, y, z);
}
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light) {

View File

@@ -36,6 +36,7 @@
#define __RENDERMODES_H_INCLUDED__
#include <Python.h>
#include "overviewer.h"
typedef struct {
const char *name;
@@ -62,22 +63,22 @@ struct _RenderModeInterface {
int (*start)(void *, RenderState *, PyObject *);
void (*finish)(void *, RenderState *);
/* 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 */
void (*draw)(void *, RenderState *, PyObject *, PyObject *, PyObject *);
};
/* wrapper for passing around rendermodes */
typedef struct {
struct _RenderMode {
void *mode;
RenderModeInterface *iface;
RenderState *state;
} RenderMode;
};
/* functions for creating / using rendermodes */
RenderMode *render_mode_create(const char *mode, RenderState *state);
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);
/* python metadata bindings */
@@ -167,7 +168,7 @@ extern RenderModeInterface rendermode_spawn;
/* CAVE */
typedef struct {
/* render blocks with lighting mode */
RenderModeNormal parent;
RenderModeLighting parent;
/* data used to know where the surface is */
PyObject *skylight;
@@ -188,6 +189,7 @@ typedef struct {
int depth_tinting;
int only_lit;
int lighting;
} RenderModeCave;
extern RenderModeInterface rendermode_cave;