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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user