mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-28 15:53:55 -04:00
pgraph: Support any number of attribs in RenderState::make()
in Python
This commit is contained in:
parent
e09f78b987
commit
63017864ab
@ -71,6 +71,9 @@ PUBLISHED:
|
|||||||
bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
bool cull_callback(CullTraverser *trav, const CullTraverserData &data) const;
|
||||||
|
|
||||||
INLINE static CPT(RenderState) make_empty();
|
INLINE static CPT(RenderState) make_empty();
|
||||||
|
EXTENSION(static explicit CPT(RenderState) make(PyObject *args, PyObject *kwargs));
|
||||||
|
|
||||||
|
public:
|
||||||
static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
|
static CPT(RenderState) make(const RenderAttrib *attrib, int override = 0);
|
||||||
static CPT(RenderState) make(const RenderAttrib *attrib1,
|
static CPT(RenderState) make(const RenderAttrib *attrib1,
|
||||||
const RenderAttrib *attrib2, int override = 0);
|
const RenderAttrib *attrib2, int override = 0);
|
||||||
@ -89,6 +92,7 @@ PUBLISHED:
|
|||||||
static CPT(RenderState) make(const RenderAttrib * const *attrib,
|
static CPT(RenderState) make(const RenderAttrib * const *attrib,
|
||||||
int num_attribs, int override = 0);
|
int num_attribs, int override = 0);
|
||||||
|
|
||||||
|
PUBLISHED:
|
||||||
CPT(RenderState) compose(const RenderState *other) const;
|
CPT(RenderState) compose(const RenderState *other) const;
|
||||||
CPT(RenderState) invert_compose(const RenderState *other) const;
|
CPT(RenderState) invert_compose(const RenderState *other) const;
|
||||||
|
|
||||||
|
@ -15,6 +15,64 @@
|
|||||||
|
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a RenderState with a given number of attributes set.
|
||||||
|
*/
|
||||||
|
CPT(RenderState) Extension<RenderState>::
|
||||||
|
make(PyObject *args, PyObject *kwds) {
|
||||||
|
extern struct Dtool_PyTypedObject Dtool_RenderAttrib;
|
||||||
|
|
||||||
|
Py_ssize_t num_attribs = PyTuple_GET_SIZE(args);
|
||||||
|
|
||||||
|
// Check for the override keyword argument.
|
||||||
|
PyObject *py_override = nullptr;
|
||||||
|
if (kwds != nullptr && PyDict_GET_SIZE(kwds) > 0) {
|
||||||
|
if (PyDict_GET_SIZE(kwds) > 1) {
|
||||||
|
Dtool_Raise_TypeError("RenderState.make() received an unexpected keyword argument");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject *key;
|
||||||
|
Py_ssize_t ppos = 0;
|
||||||
|
if (!PyDict_Next(kwds, &ppos, &key, &py_override)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We got the item, we just need to make sure that it had the right key.
|
||||||
|
if (!PyUnicode_CheckExact(key) || !_PyUnicode_EqualToASCIIString(key, "override")) {
|
||||||
|
Dtool_Raise_TypeError("RenderState.make() received an unexpected keyword argument");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!PyLong_Check(py_override)) {
|
||||||
|
Dtool_Raise_TypeError("RenderState.make() override argument should be int");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (num_attribs > 1 && PyLong_Check(PyTuple_GET_ITEM(args, num_attribs - 1))) {
|
||||||
|
// It was specified as last positional argument.
|
||||||
|
py_override = PyTuple_GET_ITEM(args, --num_attribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
int override = 0;
|
||||||
|
if (py_override != nullptr) {
|
||||||
|
override = _PyLong_AsInt(py_override);
|
||||||
|
if (override == -1 && _PyErr_OCCURRED()) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const RenderAttrib **attribs = (const RenderAttrib **)alloca(sizeof(RenderAttrib *) * num_attribs);
|
||||||
|
for (Py_ssize_t i = 0; i < num_attribs; ++i) {
|
||||||
|
PyObject *arg = PyTuple_GET_ITEM(args, i);
|
||||||
|
if (!DtoolInstance_GetPointer(arg, attribs[i], Dtool_RenderAttrib)) {
|
||||||
|
Dtool_Raise_ArgTypeError(arg, i, "RenderState.make", "RenderAttrib");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RenderState::make(attribs, num_attribs, override);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a list of 2-tuples that represents the composition cache. For each
|
* Returns a list of 2-tuples that represents the composition cache. For each
|
||||||
* tuple in the list, the first element is the source render, and the second
|
* tuple in the list, the first element is the source render, and the second
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
template<>
|
template<>
|
||||||
class Extension<RenderState> : public ExtensionBase<RenderState> {
|
class Extension<RenderState> : public ExtensionBase<RenderState> {
|
||||||
public:
|
public:
|
||||||
|
static CPT(RenderState) make(PyObject *args, PyObject *kwds);
|
||||||
|
|
||||||
PyObject *get_composition_cache() const;
|
PyObject *get_composition_cache() const;
|
||||||
PyObject *get_invert_composition_cache() const;
|
PyObject *get_invert_composition_cache() const;
|
||||||
static PyObject *get_states();
|
static PyObject *get_states();
|
||||||
|
21
tests/pgraph/test_renderstate.py
Normal file
21
tests/pgraph/test_renderstate.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from panda3d.core import RenderState, TransparencyAttrib, ColorAttrib
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
def test_renderstate_make():
|
||||||
|
assert RenderState.make() == RenderState.make_empty()
|
||||||
|
assert RenderState.make(override=123) == RenderState.make_empty()
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
RenderState.make(override=0, blargh=123)
|
||||||
|
RenderState.make(blargh=123)
|
||||||
|
|
||||||
|
with pytest.raises(OverflowError):
|
||||||
|
RenderState.make(override=0x80000000)
|
||||||
|
RenderState.make(override=-0x80000000)
|
||||||
|
|
||||||
|
state = RenderState.make(ColorAttrib.make_vertex(), TransparencyAttrib.make_default())
|
||||||
|
assert state.has_attrib(ColorAttrib)
|
||||||
|
assert state.has_attrib(TransparencyAttrib)
|
||||||
|
assert state.attribs[ColorAttrib] == ColorAttrib.make_vertex()
|
||||||
|
assert state.attribs[TransparencyAttrib] == TransparencyAttrib.make_default()
|
Loading…
x
Reference in New Issue
Block a user