smooth-lighting triangles now pull lighting data correctly for each vertex
This commit is contained in:
@@ -18,10 +18,144 @@
|
||||
#include "overviewer.h"
|
||||
#include <math.h>
|
||||
|
||||
/* structure representing one corner of a face (see below) */
|
||||
struct SmoothLightingCorner {
|
||||
/* where this corner shows up on each block texture */
|
||||
int imgx, imgy;
|
||||
|
||||
/* the two block offsets that (together) determine the 4 blocks to use */
|
||||
int dx1, dy1, dz1;
|
||||
int dx2, dy2, dz2;
|
||||
};
|
||||
|
||||
/* structure for rule table handling lighting */
|
||||
struct SmoothLightingFace {
|
||||
/* offset from current coordinate to the block this face points towards
|
||||
used for occlusion calculations, and as a base for later */
|
||||
int dx, dy, dz;
|
||||
|
||||
/* the points that form the corners of this face */
|
||||
struct SmoothLightingCorner corners[4];
|
||||
};
|
||||
|
||||
/* the lighting face rule list! */
|
||||
static struct SmoothLightingFace lighting_rules[] = {
|
||||
/* top */
|
||||
{0, 0, 1, {
|
||||
{0, 6,
|
||||
-1, 0, 0,
|
||||
0, -1, 0},
|
||||
{12, 0,
|
||||
1, 0, 0,
|
||||
0, -1, 0},
|
||||
{24, 6,
|
||||
1, 0, 0,
|
||||
0, 1, 0},
|
||||
{12, 12,
|
||||
-1, 0, 0,
|
||||
0, 1, 0},
|
||||
}},
|
||||
/* left */
|
||||
{-1, 0, 0, {
|
||||
{12, 24,
|
||||
0, 1, 0,
|
||||
0, 0, -1},
|
||||
{0, 18,
|
||||
0, -1, 0,
|
||||
0, 0, -1},
|
||||
{0, 6,
|
||||
0, -1, 0,
|
||||
0, 0, 1},
|
||||
{12, 12,
|
||||
0, 1, 0,
|
||||
0, 0, 1},
|
||||
}},
|
||||
/* right */
|
||||
{0, 1, 0, {
|
||||
{12, 12,
|
||||
-1, 0, 0,
|
||||
0, 0, 1},
|
||||
{12, 24,
|
||||
-1, 0, 0,
|
||||
0, 0, -1},
|
||||
{24, 18,
|
||||
1, 0, 0,
|
||||
0, 0, -1},
|
||||
{24, 6,
|
||||
1, 0, 0,
|
||||
0, 0, 1},
|
||||
}},
|
||||
};
|
||||
|
||||
/* helpers for indexing the rule list */
|
||||
enum
|
||||
{
|
||||
FACE_TOP = 0,
|
||||
FACE_LEFT = 1,
|
||||
FACE_RIGHT = 2,
|
||||
};
|
||||
|
||||
static void
|
||||
do_shading_with_rule(RenderModeSmoothLighting *self, RenderState *state, struct SmoothLightingFace face) {
|
||||
int i;
|
||||
RenderModeLighting *lighting = (RenderModeLighting *)self;
|
||||
int x = state->imgx, y = state->imgy;
|
||||
struct SmoothLightingCorner *pts = face.corners;
|
||||
unsigned char pts_r[4] = {0, 0, 0, 0};
|
||||
unsigned char pts_g[4] = {0, 0, 0, 0};
|
||||
unsigned char pts_b[4] = {0, 0, 0, 0};
|
||||
int cx = state->x + face.dx;
|
||||
int cy = state->y + face.dy;
|
||||
int cz = state->z + face.dz;
|
||||
|
||||
/* first, check for occlusion if the block is in the local chunk */
|
||||
if (rendermode_lighting_is_face_occluded(state, 0, cx, cy, cz))
|
||||
return;
|
||||
|
||||
/* calculate the lighting colors for each point */
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
unsigned int rgather = 0, ggather = 0, bgather = 0;
|
||||
|
||||
get_lighting_color(lighting, state, cx, cy, cz,
|
||||
&r, &g, &b);
|
||||
rgather += r; ggather += g; bgather += b;
|
||||
|
||||
get_lighting_color(lighting, state,
|
||||
cx+pts[i].dx1, cy+pts[i].dy1, cz+pts[i].dz1,
|
||||
&r, &g, &b);
|
||||
rgather += r; ggather += g; bgather += b;
|
||||
|
||||
get_lighting_color(lighting, state,
|
||||
cx+pts[i].dx2, cy+pts[i].dy2, cz+pts[i].dz2,
|
||||
&r, &g, &b);
|
||||
rgather += r; ggather += g; bgather += b;
|
||||
|
||||
/* FIXME special far corner handling */
|
||||
get_lighting_color(lighting, state,
|
||||
cx+pts[i].dx1+pts[i].dx2, cy+pts[i].dy1+pts[i].dy2, cz+pts[i].dz1+pts[i].dz2,
|
||||
&r, &g, &b);
|
||||
rgather += r; ggather += g; bgather += b;
|
||||
|
||||
pts_r[i] = rgather / 4;
|
||||
pts_g[i] = ggather / 4;
|
||||
pts_b[i] = bgather / 4;
|
||||
}
|
||||
|
||||
/* draw the face */
|
||||
draw_triangle(state->img, 1,
|
||||
x+pts[0].imgx, y+pts[0].imgy, pts_r[0], pts_g[0], pts_b[0],
|
||||
x+pts[1].imgx, y+pts[1].imgy, pts_r[1], pts_g[1], pts_b[1],
|
||||
x+pts[2].imgx, y+pts[2].imgy, pts_r[2], pts_g[2], pts_b[2]);
|
||||
draw_triangle(state->img, 0,
|
||||
x+pts[0].imgx, y+pts[0].imgy, pts_r[0], pts_g[0], pts_b[0],
|
||||
x+pts[2].imgx, y+pts[2].imgy, pts_r[2], pts_g[2], pts_b[2],
|
||||
x+pts[3].imgx, y+pts[3].imgy, pts_r[3], pts_g[3], pts_b[3]);
|
||||
}
|
||||
|
||||
static int
|
||||
rendermode_smooth_lighting_start(void *data, RenderState *state, PyObject *options) {
|
||||
RenderModeNight* self;
|
||||
|
||||
/* first, chain up */
|
||||
int ret = rendermode_lighting.start(data, state, options);
|
||||
if (ret != 0)
|
||||
@@ -50,9 +184,10 @@ rendermode_smooth_lighting_hidden(void *data, RenderState *state, int x, int y,
|
||||
|
||||
static void
|
||||
rendermode_smooth_lighting_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
|
||||
int x = state->imgx, y = state->imgy;
|
||||
RenderModeSmoothLighting *self = (RenderModeSmoothLighting *)data;
|
||||
|
||||
if (is_transparent(state->block))
|
||||
/* special case for leaves -- these are also smooth-lit! */
|
||||
if (state->block != 18 && is_transparent(state->block))
|
||||
{
|
||||
/* transparent blocks are rendered as usual, with flat lighting */
|
||||
rendermode_lighting.draw(data, state, src, mask, mask_light);
|
||||
@@ -65,35 +200,9 @@ rendermode_smooth_lighting_draw(void *data, RenderState *state, PyObject *src, P
|
||||
* lighting mode draws */
|
||||
rendermode_normal.draw(data, state, src, mask, mask_light);
|
||||
|
||||
/* draw a triangle on top of each block */
|
||||
draw_triangle(state->img,
|
||||
x+12, y, 255, 0, 0,
|
||||
x+24, y+6, 0, 255, 0,
|
||||
x, y+6, 0, 0, 255);
|
||||
draw_triangle(state->img,
|
||||
x+24, y+6, 255, 0, 0,
|
||||
x, y+6, 0, 255, 0,
|
||||
x+12, y+12, 0, 0, 255);
|
||||
|
||||
/* left side... */
|
||||
draw_triangle(state->img,
|
||||
x, y+6, 255, 0, 0,
|
||||
x+12, y+12, 0, 255, 0,
|
||||
x+12, y+24, 0, 0, 255);
|
||||
draw_triangle(state->img,
|
||||
x+12, y+24, 255, 0, 0,
|
||||
x, y+6, 0, 255, 0,
|
||||
x, y+18, 0, 0, 255);
|
||||
|
||||
/* right side... */
|
||||
draw_triangle(state->img,
|
||||
x+24, y+6, 255, 0, 0,
|
||||
x+12, y+12, 0, 255, 0,
|
||||
x+12, y+24, 0, 0, 255);
|
||||
draw_triangle(state->img,
|
||||
x+12, y+24, 255, 0, 0,
|
||||
x+24, y+6, 0, 255, 0,
|
||||
x+24, y+18, 0, 0, 255);
|
||||
do_shading_with_rule(self, state, lighting_rules[FACE_TOP]);
|
||||
do_shading_with_rule(self, state, lighting_rules[FACE_LEFT]);
|
||||
do_shading_with_rule(self, state, lighting_rules[FACE_RIGHT]);
|
||||
}
|
||||
|
||||
RenderModeInterface rendermode_smooth_lighting = {
|
||||
|
||||
Reference in New Issue
Block a user