0

converted smooth-lighting into a primitive

for the first time ever, smooth-lit cave mode is now possible \o/
This commit is contained in:
Aaron Griffith
2012-01-08 22:49:20 -05:00
parent ae88b6e27b
commit 16fec5085e
5 changed files with 82 additions and 83 deletions

View File

@@ -135,3 +135,6 @@ class Lighting(RenderPrimitive):
self._facemasks = (top, left, right) self._facemasks = (top, left, right)
return self._facemasks return self._facemasks
class SmoothLighting(Lighting):
name = "smooth-lighting"

View File

@@ -16,36 +16,9 @@
*/ */
#include "../overviewer.h" #include "../overviewer.h"
#include "lighting.h"
#include <math.h> #include <math.h>
typedef struct {
PyObject *facemasks_py;
PyObject *facemasks[3];
/* extra data, loaded off the chunk class */
PyObject *skylight, *blocklight;
PyObject *left_skylight, *left_blocklight;
PyObject *right_skylight, *right_blocklight;
PyObject *up_left_skylight, *up_left_blocklight;
PyObject *up_right_skylight, *up_right_blocklight;
/* light color image, loaded if color_light is True */
PyObject *lightcolor;
/* can be overridden in derived rendermodes to control lighting
arguments are data, skylight, blocklight, return RGB */
void (*calculate_light_color)(void *, unsigned char, unsigned char, unsigned char *, 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 strength;
int color;
int night;
} RenderPrimitiveLighting;
/* figures out the color from a given skylight and blocklight, /* figures out the color from a given skylight and blocklight,
used in lighting calculations */ used in lighting calculations */
static void static void

View File

@@ -0,0 +1,53 @@
/*
* This file is part of the Minecraft Overviewer.
*
* Minecraft Overviewer is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Minecraft Overviewer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
* Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../overviewer.h"
typedef struct {
PyObject *facemasks_py;
PyObject *facemasks[3];
/* extra data, loaded off the chunk class */
PyObject *skylight, *blocklight;
PyObject *left_skylight, *left_blocklight;
PyObject *right_skylight, *right_blocklight;
PyObject *up_left_skylight, *up_left_blocklight;
PyObject *up_right_skylight, *up_right_blocklight;
/* light color image, loaded if color_light is True */
PyObject *lightcolor;
/* can be overridden in derived rendermodes to control lighting
arguments are data, skylight, blocklight, return RGB */
void (*calculate_light_color)(void *, unsigned char, unsigned char, unsigned char *, 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 strength;
int color;
int night;
} RenderPrimitiveLighting;
/* exposed so that smooth-lighting can use them */
extern RenderPrimitiveInterface primitive_lighting;
int lighting_is_face_occluded(RenderState *state, int skip_sides, int x, int y, int z);
void get_lighting_color(RenderPrimitiveLighting *self, RenderState *state,
int x, int y, int z,
unsigned char *r, unsigned char *g, unsigned char *b);

View File

@@ -15,9 +15,15 @@
* with the Overviewer. If not, see <http://www.gnu.org/licenses/>. * with the Overviewer. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "overviewer.h" #include "../overviewer.h"
#include "lighting.h"
#include <math.h> #include <math.h>
typedef struct {
/* inherits from lighting */
RenderPrimitiveLighting parent;
} RenderPrimitiveSmoothLighting;
/* structure representing one corner of a face (see below) */ /* structure representing one corner of a face (see below) */
struct SmoothLightingCorner { struct SmoothLightingCorner {
/* where this corner shows up on each block texture */ /* where this corner shows up on each block texture */
@@ -123,12 +129,12 @@ enum
}; };
static void static void
do_shading_with_rule(RenderModeSmoothLighting *self, RenderState *state, struct SmoothLightingFace face) { do_shading_with_rule(RenderPrimitiveSmoothLighting *self, RenderState *state, struct SmoothLightingFace face) {
int i; int i;
RenderModeLighting *lighting = (RenderModeLighting *)self; RenderPrimitiveLighting *lighting = (RenderPrimitiveLighting *)self;
int x = state->imgx, y = state->imgy; int x = state->imgx, y = state->imgy;
struct SmoothLightingCorner *pts = face.corners; struct SmoothLightingCorner *pts = face.corners;
float comp_shade_strength = 1.0 - lighting->shade_strength; float comp_shade_strength = 1.0 - lighting->strength;
unsigned char pts_r[4] = {0, 0, 0, 0}; unsigned char pts_r[4] = {0, 0, 0, 0};
unsigned char pts_g[4] = {0, 0, 0, 0}; unsigned char pts_g[4] = {0, 0, 0, 0};
unsigned char pts_b[4] = {0, 0, 0, 0}; unsigned char pts_b[4] = {0, 0, 0, 0};
@@ -137,7 +143,7 @@ do_shading_with_rule(RenderModeSmoothLighting *self, RenderState *state, struct
int cz = state->z + face.dz; int cz = state->z + face.dz;
/* 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 (rendermode_lighting_is_face_occluded(state, 0, cx, cy, cz)) if (lighting_is_face_occluded(state, 0, cx, cy, cz))
return; return;
/* calculate the lighting colors for each point */ /* calculate the lighting colors for each point */
@@ -189,55 +195,38 @@ do_shading_with_rule(RenderModeSmoothLighting *self, RenderState *state, struct
} }
static int static int
rendermode_smooth_lighting_start(void *data, RenderState *state, PyObject *options) { smooth_lighting_start(void *data, RenderState *state, PyObject *support) {
/* first, chain up */ /* first, chain up */
int ret = rendermode_lighting.start(data, state, options); int ret = primitive_lighting.start(data, state, support);
if (ret != 0) if (ret != 0)
return ret; return ret;
return 0; return 0;
} }
static void static void
rendermode_smooth_lighting_finish(void *data, RenderState *state) { smooth_lighting_finish(void *data, RenderState *state) {
/* nothing special to do */ /* nothing special to do */
rendermode_lighting.finish(data, state); primitive_lighting.finish(data, state);
}
static int
rendermode_smooth_lighting_occluded(void *data, RenderState *state, int x, int y, int z) {
/* no special occlusion here */
return rendermode_lighting.occluded(data, state, x, y, z);
}
static int
rendermode_smooth_lighting_hidden(void *data, RenderState *state, int x, int y, int z) {
/* no special hiding here */
return rendermode_lighting.hidden(data, state, x, y, z);
} }
static void static void
rendermode_smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) { smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
int light_top = 1; int light_top = 1;
int light_left = 1; int light_left = 1;
int light_right = 1; int light_right = 1;
RenderModeSmoothLighting *self = (RenderModeSmoothLighting *)data; RenderPrimitiveSmoothLighting *self = (RenderPrimitiveSmoothLighting *)data;
/* special case for leaves, water 8, water 9 /* special case for leaves, water 8, water 9
-- these are also smooth-lit! */ -- these are also smooth-lit! */
if (state->block != 18 && state->block != 8 && state->block != 9 && is_transparent(state->block)) if (state->block != 18 && state->block != 8 && state->block != 9 && is_transparent(state->block))
{ {
/* transparent blocks are rendered as usual, with flat lighting */ /* transparent blocks are rendered as usual, with flat lighting */
rendermode_lighting.draw(data, state, src, mask, mask_light); primitive_lighting.draw(data, state, src, mask, mask_light);
return; return;
} }
/* non-transparent blocks get the special smooth treatment */ /* non-transparent blocks get the special smooth treatment */
/* nothing special to do, but we do want to avoid vanilla
* lighting mode draws */
rendermode_normal.draw(data, state, src, mask, mask_light);
/* special code for water */ /* special code for water */
if (state->block == 9) if (state->block == 9)
{ {
@@ -257,15 +246,11 @@ rendermode_smooth_lighting_draw(void *data, RenderState *state, PyObject *src, P
do_shading_with_rule(self, state, lighting_rules[FACE_RIGHT]); do_shading_with_rule(self, state, lighting_rules[FACE_RIGHT]);
} }
RenderModeInterface rendermode_smooth_lighting = { RenderPrimitiveInterface primitive_smooth_lighting = {
"smooth-lighting", "Smooth Lighting", "smooth-lighting", sizeof(RenderPrimitiveSmoothLighting),
"like \"lighting\", except smooth", smooth_lighting_start,
smooth_lighting_finish,
NULL, NULL,
&rendermode_lighting, NULL,
sizeof(RenderModeSmoothLighting), smooth_lighting_draw,
rendermode_smooth_lighting_start,
rendermode_smooth_lighting_finish,
rendermode_smooth_lighting_occluded,
rendermode_smooth_lighting_hidden,
rendermode_smooth_lighting_draw,
}; };

View File

@@ -117,21 +117,6 @@ typedef struct {
} RenderModeOverlay; } RenderModeOverlay;
extern RenderModeInterface rendermode_overlay; extern RenderModeInterface rendermode_overlay;
/* exposed so it can be used in other per-face occlusion checks */
int rendermode_lighting_is_face_occluded(RenderState *state, int skip_sides, int x, int y, int z);
/* exposed so sub-modes can look at colors directly */
void get_lighting_color(RenderModeLighting *self, RenderState *state,
int x, int y, int z,
unsigned char *r, unsigned char *g, unsigned char *b);
/* SMOOTH LIGHTING */
typedef struct {
/* inherits from lighting */
RenderModeLighting parent;
} RenderModeSmoothLighting;
extern RenderModeInterface rendermode_smooth_lighting;
/* SPAWN */ /* SPAWN */
typedef struct { typedef struct {
/* inherits from overlay */ /* inherits from overlay */