0

overlays converted into render primitives

This commit is contained in:
Aaron Griffith
2012-02-26 11:39:07 -05:00
parent 19f6f136e4
commit 2b7af1886a
7 changed files with 139 additions and 150 deletions

View File

@@ -146,6 +146,42 @@ class Lighting(RenderPrimitive):
class SmoothLighting(Lighting): class SmoothLighting(Lighting):
name = "smooth-lighting" name = "smooth-lighting"
class Overlay(RenderPrimitive):
name = "overlay"
@property
def whitecolor(self):
whitecolor = getattr(self, "_whitecolor", None)
if whitecolor:
return whitecolor
white = Image.new("RGBA", (24,24), (255, 255, 255, 255))
self._whitecolor = white
return white
@property
def facemask_top(self):
facemask_top = getattr(self, "_facemask_top", None)
if facemask_top:
return facemask_top
white = Image.new("L", (24,24), 255)
top = Image.new("L", (24,24), 0)
toppart = textures.Textures.transform_image_top(white)
top.paste(toppart, (0,0))
for x,y in [(3,4), (7,2), (11,0)]:
top.putpixel((x,y), 255)
self._facemask_top = top
return top
class SpawnOverlay(Overlay):
name = "overlay-spawn"
class MineralOverlay(Overlay):
name = "overlay-mineral"
options = {
'minerals' : ('a list of (blockid, (r, g, b)) tuples for coloring minerals', None),
}
# Built-in rendermodes for your convenience! # Built-in rendermodes for your convenience!
normal = [Base(), EdgeLines()] normal = [Base(), EdgeLines()]
lighting = [Base(), EdgeLines(), Lighting()] lighting = [Base(), EdgeLines(), Lighting()]

View File

@@ -26,7 +26,7 @@
// increment this value if you've made a change to the c extesion // increment this value if you've made a change to the c extesion
// and want to force users to rebuild // and want to force users to rebuild
#define OVERVIEWER_EXTENSION_VERSION 20 #define OVERVIEWER_EXTENSION_VERSION 21
/* Python PIL, and numpy headers */ /* Python PIL, and numpy headers */
#include <Python.h> #include <Python.h>

View File

@@ -15,7 +15,14 @@
* 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 "overlay.h"
typedef struct {
/* inherits from overlay */
RenderPrimitiveOverlay parent;
void *minerals;
} RenderPrimitiveMineral;
struct MineralColor { struct MineralColor {
unsigned char blockid; unsigned char blockid;
@@ -45,7 +52,7 @@ static void get_color(void *data, RenderState *state,
int x = state->x, y = state->y, z_max = state->z + 1, z; int x = state->x, y = state->y, z_max = state->z + 1, z;
int max_i = -1; int max_i = -1;
RenderModeMineral* self = (RenderModeMineral *)data; RenderPrimitiveMineral* self = (RenderPrimitiveMineral *)data;
struct MineralColor *minerals = (struct MineralColor *)(self->minerals); struct MineralColor *minerals = (struct MineralColor *)(self->minerals);
*a = 0; *a = 0;
@@ -70,20 +77,21 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
rendermode_mineral_start(void *data, RenderState *state, PyObject *options) { overlay_mineral_start(void *data, RenderState *state, PyObject *support) {
PyObject *opt; PyObject *opt;
RenderModeMineral* self; RenderPrimitiveMineral* self;
/* first, chain up */ /* first, chain up */
int ret = rendermode_overlay.start(data, state, options); int ret = primitive_overlay.start(data, state, support);
if (ret != 0) if (ret != 0)
return ret; return ret;
/* now do custom initializations */ /* now do custom initializations */
self = (RenderModeMineral *)data; self = (RenderPrimitiveMineral *)data;
opt = PyDict_GetItemString(options, "minerals"); if (!render_mode_parse_option(support, "minerals", "O", &(opt)))
if (opt) { return 1;
if (opt && opt != Py_None) {
struct MineralColor *minerals = NULL; struct MineralColor *minerals = NULL;
Py_ssize_t minerals_size = 0, i; Py_ssize_t minerals_size = 0, i;
/* create custom minerals */ /* create custom minerals */
@@ -110,6 +118,7 @@ rendermode_mineral_start(void *data, RenderState *state, PyObject *options) {
} else { } else {
self->minerals = default_minerals; self->minerals = default_minerals;
} }
Py_XDECREF(opt);
/* setup custom color */ /* setup custom color */
self->parent.get_color = get_color; self->parent.get_color = get_color;
@@ -118,50 +127,24 @@ rendermode_mineral_start(void *data, RenderState *state, PyObject *options) {
} }
static void static void
rendermode_mineral_finish(void *data, RenderState *state) { overlay_mineral_finish(void *data, RenderState *state) {
/* first free all *our* stuff */ /* first free all *our* stuff */
RenderModeMineral* self = (RenderModeMineral *)data; RenderPrimitiveMineral* self = (RenderPrimitiveMineral *)data;
if (self->minerals && self->minerals != default_minerals) { if (self->minerals && self->minerals != default_minerals) {
free(self->minerals); free(self->minerals);
} }
/* now, chain up */ /* now, chain up */
rendermode_overlay.finish(data, state); primitive_overlay.finish(data, state);
} }
static int RenderPrimitiveInterface primitive_overlay_mineral = {
rendermode_mineral_occluded(void *data, RenderState *state, int x, int y, int z) { "overlay-mineral",
/* no special occlusion here */ sizeof(RenderPrimitiveMineral),
return rendermode_overlay.occluded(data, state, x, y, z); overlay_mineral_start,
} overlay_mineral_finish,
overlay_occluded,
static int NULL,
rendermode_mineral_hidden(void *data, RenderState *state, int x, int y, int z) { overlay_draw,
/* no special hiding here */
return rendermode_overlay.hidden(data, state, x, y, z);
}
static void
rendermode_mineral_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
/* draw normally */
rendermode_overlay.draw(data, state, src, mask, mask_light);
}
const RenderModeOption rendermode_mineral_options[] = {
{"minerals", "a list of (blockid, (r, g, b)) tuples for coloring minerals"},
{NULL, NULL}
};
RenderModeInterface rendermode_mineral = {
"mineral", "Mineral",
"draws a colored overlay showing where ores are located",
rendermode_mineral_options,
&rendermode_overlay,
sizeof(RenderModeMineral),
rendermode_mineral_start,
rendermode_mineral_finish,
rendermode_mineral_occluded,
rendermode_mineral_hidden,
rendermode_mineral_draw,
}; };

View File

@@ -15,13 +15,20 @@
* 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 "overlay.h"
#include <math.h> #include <math.h>
typedef struct {
/* inherits from overlay */
RenderPrimitiveOverlay parent;
PyObject *skylight, *blocklight;
} RenderPrimitiveSpawn;
static void get_color(void *data, RenderState *state, static void get_color(void *data, RenderState *state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) {
RenderModeSpawn* self = (RenderModeSpawn *)data; RenderPrimitiveSpawn* self = (RenderPrimitiveSpawn *)data;
int x = state->x, y = state->y, z = state->z; int x = state->x, y = state->y, z = state->z;
int z_light = z + 1; int z_light = z + 1;
unsigned char blocklight, skylight; unsigned char blocklight, skylight;
@@ -59,16 +66,16 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
rendermode_spawn_start(void *data, RenderState *state, PyObject *options) { overlay_spawn_start(void *data, RenderState *state, PyObject *support) {
RenderModeSpawn* self; RenderPrimitiveSpawn* self;
/* first, chain up */ /* first, chain up */
int ret = rendermode_overlay.start(data, state, options); int ret = primitive_overlay.start(data, state, support);
if (ret != 0) if (ret != 0)
return ret; return ret;
/* now do custom initializations */ /* now do custom initializations */
self = (RenderModeSpawn *)data; self = (RenderPrimitiveSpawn *)data;
self->blocklight = get_chunk_data(state, CURRENT, BLOCKLIGHT, 1); self->blocklight = get_chunk_data(state, CURRENT, BLOCKLIGHT, 1);
self->skylight = get_chunk_data(state, CURRENT, SKYLIGHT, 1); self->skylight = get_chunk_data(state, CURRENT, SKYLIGHT, 1);
@@ -79,44 +86,23 @@ rendermode_spawn_start(void *data, RenderState *state, PyObject *options) {
} }
static void static void
rendermode_spawn_finish(void *data, RenderState *state) { overlay_spawn_finish(void *data, RenderState *state) {
/* first free all *our* stuff */ /* first free all *our* stuff */
RenderModeSpawn* self = (RenderModeSpawn *)data; RenderPrimitiveSpawn* self = (RenderPrimitiveSpawn *)data;
Py_DECREF(self->blocklight); Py_DECREF(self->blocklight);
Py_DECREF(self->skylight); Py_DECREF(self->skylight);
/* now, chain up */ /* now, chain up */
rendermode_overlay.finish(data, state); primitive_overlay.finish(data, state);
} }
static int RenderPrimitiveInterface primitive_overlay_spawn = {
rendermode_spawn_occluded(void *data, RenderState *state, int x, int y, int z) { "overlay-spawn",
/* no special occlusion here */ sizeof(RenderPrimitiveSpawn),
return rendermode_overlay.occluded(data, state, x, y, z); overlay_spawn_start,
} overlay_spawn_finish,
overlay_occluded,
static int
rendermode_spawn_hidden(void *data, RenderState *state, int x, int y, int z) {
/* no special hiding here */
return rendermode_overlay.hidden(data, state, x, y, z);
}
static void
rendermode_spawn_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
/* draw normally */
rendermode_overlay.draw(data, state, src, mask, mask_light);
}
RenderModeInterface rendermode_spawn = {
"spawn", "Spawn",
"draws a red overlay where monsters can spawn at night",
NULL, NULL,
&rendermode_overlay, overlay_draw,
sizeof(RenderModeSpawn),
rendermode_spawn_start,
rendermode_spawn_finish,
rendermode_spawn_occluded,
rendermode_spawn_hidden,
rendermode_spawn_draw,
}; };

View File

@@ -15,7 +15,7 @@
* 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 "overlay.h"
static void get_color(void *data, RenderState *state, static void get_color(void *data, RenderState *state,
unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) { unsigned char *r, unsigned char *g, unsigned char *b, unsigned char *a) {
@@ -26,32 +26,27 @@ static void get_color(void *data, RenderState *state,
} }
static int static int
rendermode_overlay_start(void *data, RenderState *state, PyObject *options) { overlay_start(void *data, RenderState *state, PyObject *support) {
PyObject *facemasks_py; PyObject *facemasks_py;
RenderModeOverlay *self = (RenderModeOverlay *)data; RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data;
facemasks_py = PyObject_GetAttrString(state->support, "facemasks"); self->facemask_top = PyObject_GetAttrString(support, "facemask_top");
/* borrowed reference, needs to be incref'd if we keep it */ self->white_color = PyObject_GetAttrString(support, "whitecolor");
self->facemask_top = PyTuple_GetItem(facemasks_py, 0);
Py_INCREF(self->facemask_top);
Py_DECREF(facemasks_py);
self->white_color = PyObject_GetAttrString(state->support, "white_color");
self->get_color = get_color; self->get_color = get_color;
return 0; return 0;
} }
static void static void
rendermode_overlay_finish(void *data, RenderState *state) { overlay_finish(void *data, RenderState *state) {
RenderModeOverlay *self = (RenderModeOverlay *)data; RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data;
Py_DECREF(self->facemask_top); Py_DECREF(self->facemask_top);
Py_DECREF(self->white_color); Py_DECREF(self->white_color);
} }
static int int
rendermode_overlay_occluded(void *data, RenderState *state, int x, int y, int z) { overlay_occluded(void *data, RenderState *state, int x, int y, int z) {
if ( (x != 0) && (y != 15) && (z != 127) && if ( (x != 0) && (y != 15) && (z != 127) &&
!render_mode_hidden(state->rendermode, x-1, y, z) && !render_mode_hidden(state->rendermode, x-1, y, z) &&
!render_mode_hidden(state->rendermode, x, y, z+1) && !render_mode_hidden(state->rendermode, x, y, z+1) &&
@@ -65,15 +60,9 @@ rendermode_overlay_occluded(void *data, RenderState *state, int x, int y, int z)
return 0; return 0;
} }
static int void
rendermode_overlay_hidden(void *data, RenderState *state, int x, int y, int z) { overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
/* overlays hide nothing by default */ RenderPrimitiveOverlay *self = (RenderPrimitiveOverlay *)data;
return 0;
}
static void
rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light) {
RenderModeOverlay *self = (RenderModeOverlay *)data;
unsigned char r, g, b, a; unsigned char r, g, b, a;
// exactly analogous to edge-line code for these special blocks // exactly analogous to edge-line code for these special blocks
@@ -118,15 +107,12 @@ rendermode_overlay_draw(void *data, RenderState *state, PyObject *src, PyObject
} }
} }
RenderModeInterface rendermode_overlay = { RenderPrimitiveInterface primitive_overlay = {
"overlay", "Overlay", "overlay",
"base rendermode for informational overlays", sizeof(RenderPrimitiveOverlay),
overlay_start,
overlay_finish,
overlay_occluded,
NULL, NULL,
NULL, overlay_draw,
sizeof(RenderModeOverlay),
rendermode_overlay_start,
rendermode_overlay_finish,
rendermode_overlay_occluded,
rendermode_overlay_hidden,
rendermode_overlay_draw,
}; };

View File

@@ -0,0 +1,32 @@
/*
* 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 {
/* top facemask and white color image, for drawing overlays */
PyObject *facemask_top, *white_color;
/* can be overridden in derived classes to control
overlay alpha and color
last four vars are r, g, b, a out */
void (*get_color)(void *, RenderState *,
unsigned char *, unsigned char *, unsigned char *, unsigned char *);
} RenderPrimitiveOverlay;
extern RenderPrimitiveInterface primitive_overlay;
void overlay_draw(void *data, RenderState *state, PyObject *src, PyObject *mask, PyObject *mask_light);
int overlay_occluded(void *data, RenderState *state, int x, int y, int z);

View File

@@ -102,38 +102,4 @@ void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject
works like PyArg_ParseTuple on a support object */ works like PyArg_ParseTuple on a support object */
int render_mode_parse_option(PyObject *support, const char *name, const char *format, ...); int render_mode_parse_option(PyObject *support, const char *name, const char *format, ...);
/* XXX individual rendermode interface declarations follow */
#ifdef OLD_MODES
/* OVERLAY */
typedef struct {
/* top facemask and white color image, for drawing overlays */
PyObject *facemask_top, *white_color;
/* can be overridden in derived classes to control
overlay alpha and color
last four vars are r, g, b, a out */
void (*get_color)(void *, RenderState *,
unsigned char *, unsigned char *, unsigned char *, unsigned char *);
} RenderModeOverlay;
extern RenderModeInterface rendermode_overlay;
/* SPAWN */
typedef struct {
/* inherits from overlay */
RenderModeOverlay parent;
PyObject *skylight, *blocklight;
} RenderModeSpawn;
extern RenderModeInterface rendermode_spawn;
/* MINERAL */
typedef struct {
/* inherits from overlay */
RenderModeOverlay parent;
void *minerals;
} RenderModeMineral;
extern RenderModeInterface rendermode_mineral;
#endif /* OLD_MODES */
#endif /* __RENDERMODES_H_INCLUDED__ */ #endif /* __RENDERMODES_H_INCLUDED__ */