0

re-fixed cave mode lighting problems (no longer slows down lighting mode itself!)

This commit is contained in:
Aaron Griffith
2011-09-08 07:07:43 -04:00
parent bc138ac859
commit bbb2a3943e
3 changed files with 88 additions and 49 deletions

View File

@@ -79,6 +79,59 @@ touches_light(unsigned int x, unsigned int y, unsigned int z,
return 0; return 0;
} }
static inline int
rendermode_cave_adjacent_occluded(void *data, RenderState *state, int x, int y, int z) {
/* check for occlusion of edge blocks, using adjacent block data */
if (z != 127) {
if ( (x == 0) && (y != 15) ) {
if (state->left_blocks != Py_None) {
if (!is_transparent(getArrayByte3D(state->left_blocks, 15, y, z)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y+1, z))) {
return 1;
}
} else {
return 1;
}
}
if ( (x != 0) && (y == 15) ) {
if (state->right_blocks != Py_None) {
if (!is_transparent(getArrayByte3D(state->blocks, x-1, y, z)) &&
!is_transparent(getArrayByte3D(state->right_blocks, x, 0, z)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1))) {
return 1;
}
} else {
return 1;
}
}
if ( (x == 0) && (y == 15) ) {
if ((state->left_blocks != Py_None) &&
(state->right_blocks != Py_None)) {
if (!is_transparent(getArrayByte3D(state->left_blocks, 15, y, z)) &&
!is_transparent(getArrayByte3D(state->right_blocks, x, 0, z)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1))) {
return 1;
}
} else {
return 1;
}
}
if ( (x != 0) && (y != 15) &&
!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+1, z))) {
return 1;
}
}
return 0;
}
static int static int
rendermode_cave_occluded(void *data, RenderState *state, int x, int y, int z) { rendermode_cave_occluded(void *data, RenderState *state, int x, int y, int z) {
/* first, check to see if it's "normally" occluded */ /* first, check to see if it's "normally" occluded */
@@ -87,52 +140,7 @@ rendermode_cave_occluded(void *data, RenderState *state, int x, int y, int z) {
/* check for normal occlusion */ /* check for normal occlusion */
/* use ajacent chunks, if not you get blocks spreaded in chunk edges */ /* use ajacent chunks, if not you get blocks spreaded in chunk edges */
if ( (x == 0) && (y != 15) ) { return rendermode_cave_adjacent_occluded(data, state, x, y, z);
if (state->left_blocks != Py_None) {
if (!is_transparent(getArrayByte3D(state->left_blocks, 15, y, z)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y+1, z))) {
return 1;
}
} else {
return 1;
}
}
if ( (x != 0) && (y == 15) ) {
if (state->right_blocks != Py_None) {
if (!is_transparent(getArrayByte3D(state->blocks, x-1, y, z)) &&
!is_transparent(getArrayByte3D(state->right_blocks, x, 0, z)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1))) {
return 1;
}
} else {
return 1;
}
}
if ( (x == 0) && (y == 15) ) {
if ((state->left_blocks != Py_None) &&
(state->right_blocks != Py_None)) {
if (!is_transparent(getArrayByte3D(state->left_blocks, 15, y, z)) &&
!is_transparent(getArrayByte3D(state->right_blocks, x, 0, z)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y, z+1))) {
return 1;
}
} else {
return 1;
}
}
if ( (x != 0) && (y != 15) &&
!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+1, z))) {
return 1;
}
/* guess we're not occluded */
return 0;
} }
static int static int
@@ -179,6 +187,23 @@ rendermode_cave_hidden(void *data, RenderState *state, int x, int y, int z) {
} }
} }
/* unfortunate side-effect of lit cave mode: we need to count occluded
* blocks as hidden for the lighting to look right, since technically our
* hiding depends on occlusion as well
*
* We leave out this check otherwise because it's fairly expensive.
*/
if (self->lighting) {
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)) &&
!is_transparent(getArrayByte3D(state->blocks, x, y+1, z))) {
return 1;
}
return rendermode_cave_adjacent_occluded(data, state, x, y, z);
}
return 0; return 0;
} }
@@ -205,6 +230,12 @@ rendermode_cave_start(void *data, RenderState *state, PyObject *options) {
if (!render_mode_parse_option(options, "lighting", "i", &(self->lighting))) if (!render_mode_parse_option(options, "lighting", "i", &(self->lighting)))
return 1; return 1;
if (self->lighting)
{
/* we can't skip lighting the sides in cave mode, it looks too weird */
self->parent.skip_sides = 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");

View File

@@ -221,7 +221,7 @@ do_shading_with_mask(RenderModeLighting *self, RenderState *state,
/* this face isn't visible, so don't draw anything */ /* this face isn't visible, so don't draw anything */
return; return;
} }
} else if ((x == -1) && (state->left_blocks != Py_None)) { } else if (self->skip_sides && (x == -1) && (state->left_blocks != Py_None)) {
unsigned char block = getArrayByte3D(state->left_blocks, 15, state->y, state->z); unsigned char block = getArrayByte3D(state->left_blocks, 15, state->y, state->z);
if (!is_transparent(block)) { if (!is_transparent(block)) {
/* the same thing but for adjacent chunks, this solves an /* the same thing but for adjacent chunks, this solves an
@@ -230,7 +230,7 @@ do_shading_with_mask(RenderModeLighting *self, RenderState *state,
tessellate-able */ tessellate-able */
return; return;
} }
} else if ((y == 16) && (state->right_blocks != Py_None)) { } else if (self->skip_sides && (y == 16) && (state->right_blocks != Py_None)) {
unsigned char block = getArrayByte3D(state->right_blocks, state->x, 0, state->z); unsigned char block = getArrayByte3D(state->right_blocks, state->x, 0, state->z);
if (!is_transparent(block)) { if (!is_transparent(block)) {
/* the same thing but for adjacent chunks, this solves an /* the same thing but for adjacent chunks, this solves an
@@ -257,6 +257,9 @@ rendermode_lighting_start(void *data, RenderState *state, PyObject *options) {
self = (RenderModeLighting *)data; self = (RenderModeLighting *)data;
/* skip sides by default */
self->skip_sides = 1;
self->shade_strength = 1.0; self->shade_strength = 1.0;
if (!render_mode_parse_option(options, "shade_strength", "f", &(self->shade_strength))) if (!render_mode_parse_option(options, "shade_strength", "f", &(self->shade_strength)))
return 1; return 1;

View File

@@ -170,6 +170,11 @@ typedef struct {
arguments are skylight, blocklight */ arguments are skylight, blocklight */
float (*calculate_darkness)(unsigned char, unsigned char); float (*calculate_darkness)(unsigned char, unsigned char);
/* can be set to 0 in derived modes to indicate that lighting the chunk
* sides is actually important. Right now, this is used in cave mode
*/
int skip_sides;
float shade_strength; float shade_strength;
} RenderModeLighting; } RenderModeLighting;
extern RenderModeInterface rendermode_lighting; extern RenderModeInterface rendermode_lighting;