0

moved to a layer-based rendermode system, moved normal mode to base primitive

options are now handled partially in the python side, in rendermodes.py
This commit is contained in:
Aaron Griffith
2012-01-07 22:50:01 -05:00
parent 6f66a31738
commit e3610f8ac5
8 changed files with 204 additions and 158 deletions

View File

@@ -19,97 +19,166 @@
#include <string.h>
#include <stdarg.h>
/* list of all render modes, ending in NULL
all of these will be available to the user, so DON'T include modes
that are only useful as a base for other modes. */
static RenderModeInterface *render_modes[] = {
&rendermode_normal,
&rendermode_lighting,
&rendermode_smooth_lighting,
&rendermode_cave,
extern RenderPrimitiveInterface primitive_base;
/* list of all render primitives, ending in NULL
all of these will be available to the user, so DON'T include primitives
that are only useful as a base for other primitives. */
static RenderPrimitiveInterface *render_primitives[] = {
&primitive_base,
//&rendermode_lighting,
//&rendermode_smooth_lighting,
//&rendermode_cave,
&rendermode_spawn,
&rendermode_mineral,
//&rendermode_spawn,
//&rendermode_mineral,
NULL
};
/* rendermode encapsulation */
RenderMode *render_mode_create(const char *mode, RenderState *state) {
PyObject *options;
RenderMode *ret = NULL;
RenderModeInterface *iface = NULL;
/* helper to create a single primitive */
RenderPrimitive *render_primitive_create(PyObject *prim, RenderState *state) {
RenderPrimitive *ret = NULL;
RenderPrimitiveInterface *iface = NULL;
unsigned int i;
PyObject *pyname;
const char* name;
pyname = PyObject_GetAttrString(prim, "name");
if (!pyname)
return NULL;
name = PyString_AsString(pyname);
for (i = 0; render_modes[i] != NULL; i++) {
if (strcmp(render_modes[i]->name, mode) == 0) {
iface = render_modes[i];
for (i = 0; render_primitives[i] != NULL; i++) {
if (strcmp(render_primitives[i]->name, name) == 0) {
iface = render_primitives[i];
break;
}
}
Py_DECREF(pyname);
if (iface == NULL)
return NULL;
options = PyDict_New();
ret = calloc(1, sizeof(RenderMode));
ret = calloc(1, sizeof(RenderPrimitive));
if (ret == NULL) {
Py_DECREF(options);
return PyErr_Format(PyExc_RuntimeError, "Failed to alloc a rendermode");
return (RenderPrimitive *)PyErr_Format(PyExc_RuntimeError, "Failed to alloc a render primitive");
}
ret->mode = calloc(1, iface->data_size);
if (ret->mode == NULL) {
Py_DECREF(options);
ret->primitive = calloc(1, iface->data_size);
if (ret->primitive == NULL) {
free(ret);
return PyErr_Format(PyExc_RuntimeError, "Failed to alloc rendermode data");
return (RenderPrimitive *)PyErr_Format(PyExc_RuntimeError, "Failed to alloc render primitive data");
}
ret->iface = iface;
ret->state = state;
if (iface->start(ret->mode, state, options)) {
Py_DECREF(options);
free(ret->mode);
if (iface->start(ret->primitive, state, prim)) {
free(ret->primitive);
free(ret);
return NULL;
}
Py_DECREF(options);
return ret;
}
RenderMode *render_mode_create(PyObject *mode, RenderState *state) {
RenderMode *ret = NULL;
PyObject *mode_fast = NULL;
unsigned int i;
mode_fast = PySequence_Fast(mode, "Mode is not a sequence type");
if (!mode_fast)
return NULL;
ret = calloc(1, sizeof(RenderMode));
ret->state = state;
ret->num_primitives = PySequence_Length(mode);
ret->primitives = calloc(ret->num_primitives, sizeof(RenderPrimitive*));
for (i = 0; i < ret->num_primitives; i++) {
PyObject *pyprim = PySequence_Fast_GET_ITEM(mode_fast, i);
RenderPrimitive *prim = render_primitive_create(pyprim, state);
if (!prim) {
render_mode_destroy(ret);
Py_DECREF(mode_fast);
return NULL;
}
ret->primitives[i] = prim;
}
return ret;
}
void render_mode_destroy(RenderMode *self) {
self->iface->finish(self->mode, self->state);
free(self->mode);
unsigned int i;
for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i];
/* we may be destroying a half-constructed mode, so we need this
check */
if (prim) {
prim->iface->finish(prim->primitive, self->state);
free(prim->primitive);
free(prim);
}
}
free(self->primitives);
free(self);
}
int render_mode_occluded(RenderMode *self, int x, int y, int z) {
return self->iface->occluded(self->mode, self->state, x, y, z);
unsigned int i;
int occluded = 0;
for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i];
occluded |= prim->iface->occluded(prim->primitive, self->state, x, y, z);
if (occluded)
return occluded;
}
return occluded;
}
int render_mode_hidden(RenderMode *self, int x, int y, int z) {
return self->iface->hidden(self->mode, self->state, x, y, z);
unsigned int i;
int hidden = 0;
for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i];
hidden |= prim->iface->hidden(prim->primitive, self->state, x, y, z);
if (hidden)
return hidden;
}
return hidden;
}
void render_mode_draw(RenderMode *self, PyObject *img, PyObject *mask, PyObject *mask_light) {
self->iface->draw(self->mode, self->state, img, mask, mask_light);
unsigned int i;
for (i = 0; i < self->num_primitives; i++) {
RenderPrimitive *prim = self->primitives[i];
prim->iface->draw(prim->primitive, self->state, img, mask, mask_light);
}
}
/* options parse helper */
int render_mode_parse_option(PyObject *dict, const char *name, const char *format, ...) {
int render_mode_parse_option(PyObject *support, const char *name, const char *format, ...) {
va_list ap;
PyObject *item;
PyObject *item, *dict;
int ret;
if (dict == NULL || name == NULL)
if (support == NULL || name == NULL)
return 1;
dict = PyObject_GetAttrString(support, "option_values");
if (!dict)
return 1;
item = PyDict_GetItemString(dict, name);
if (item == NULL)
if (item == NULL) {
Py_DECREF(dict);
return 1;
};
/* make sure the item we're parsing is a tuple
for VaParse to work correctly */
@@ -124,6 +193,7 @@ int render_mode_parse_option(PyObject *dict, const char *name, const char *forma
va_end(ap);
Py_DECREF(item);
Py_DECREF(dict);
if (!ret) {
PyObject *errtype, *errvalue, *errtraceback;