re-fixed cave mode lighting problems (no longer slows down lighting mode itself!)
This commit is contained in:
@@ -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");
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user