mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
pgraph: custom binding for set_shader_input()
Should be faster and more reliable at PTA handling We no longer need the interrogate perf hack for the first-arg InternalName Fixes: #161
This commit is contained in:
parent
8ed85c80c8
commit
0e2b14cf4c
@ -4389,57 +4389,6 @@ write_function_forset(ostream &out,
|
||||
std::sort(remaps.begin(), remaps.end(), RemapCompareLess);
|
||||
std::vector<FunctionRemap *>::const_iterator sii;
|
||||
|
||||
// Check if all of them have an InternalName pointer as first parameter.
|
||||
// This is a dirty hack, of course, to work around an awkward overload
|
||||
// resolution problem in NodePath::set_shader_input() (while perhaps also
|
||||
// improving its performance). If I had more time I'd create a better
|
||||
// solution.
|
||||
bool first_internalname = false;
|
||||
string first_pexpr2(first_pexpr);
|
||||
if (first_pexpr.empty() && args_type != AT_no_args) {
|
||||
first_internalname = true;
|
||||
|
||||
for (sii = remaps.begin(); sii != remaps.end(); ++sii) {
|
||||
remap = (*sii);
|
||||
if (remap->_parameters.size() > (size_t)remap->_has_this) {
|
||||
ParameterRemap *param = remap->_parameters[(size_t)remap->_has_this]._remap;
|
||||
string param_name = param->get_orig_type()->get_local_name(&parser);
|
||||
|
||||
if (param_name != "CPT_InternalName" &&
|
||||
param_name != "InternalName const *" &&
|
||||
param_name != "InternalName *") {
|
||||
// Aw.
|
||||
first_internalname = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
first_internalname = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (first_internalname) {
|
||||
// Yeah, all remaps have a first InternalName parameter, so process
|
||||
// that and remove it from the args tuple.
|
||||
if (args_type == AT_single_arg) {
|
||||
// Bit of a weird case, but whatever.
|
||||
indent(out, indent_level) << "PyObject *name_obj = arg;\n";
|
||||
args_type = AT_no_args;
|
||||
} else if (min_num_args == 2 && max_num_args == 2) {
|
||||
indent(out, indent_level) << "PyObject *name_obj = PyTuple_GET_ITEM(args, 0);\n";
|
||||
indent(out, indent_level) << "PyObject *arg = PyTuple_GET_ITEM(args, 1);\n";
|
||||
args_type = AT_single_arg;
|
||||
} else {
|
||||
indent(out, indent_level) << "PyObject *name_obj = PyTuple_GET_ITEM(args, 0);\n";
|
||||
indent(out, indent_level) << "args = PyTuple_GetSlice(args, 1, PyTuple_GET_SIZE(args));\n";
|
||||
return_flags |= RF_decref_args;
|
||||
}
|
||||
indent(out, indent_level) << "PT(InternalName) name;\n";
|
||||
indent(out, indent_level) << "if (Dtool_Coerce_InternalName(name_obj, name)) {\n";
|
||||
indent_level += 2;
|
||||
first_pexpr2 = "name";
|
||||
}
|
||||
}
|
||||
|
||||
int num_coercion_possible = 0;
|
||||
sii = remaps.begin();
|
||||
while (sii != remaps.end()) {
|
||||
@ -4474,7 +4423,7 @@ write_function_forset(ostream &out,
|
||||
write_function_instance(out, remap, min_num_args, max_num_args,
|
||||
expected_params, indent_level + 2,
|
||||
false, false, args_type, return_flags,
|
||||
check_exceptions, first_pexpr2);
|
||||
check_exceptions, first_pexpr);
|
||||
|
||||
indent(out, indent_level) << "}\n\n";
|
||||
}
|
||||
@ -4507,28 +4456,11 @@ write_function_forset(ostream &out,
|
||||
write_function_instance(out, remap, min_num_args, max_num_args,
|
||||
ignore_expected_params, indent_level + 2,
|
||||
true, false, args_type, return_flags,
|
||||
check_exceptions, first_pexpr2);
|
||||
check_exceptions, first_pexpr);
|
||||
|
||||
indent(out, indent_level) << "}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (first_internalname) {
|
||||
indent_level -= 2;
|
||||
if (report_errors) {
|
||||
indent(out, indent_level) << "} else {\n";
|
||||
|
||||
string class_name = remap->_cpptype->get_simple_name();
|
||||
ostringstream msg;
|
||||
msg << classNameFromCppName(class_name, false) << "."
|
||||
<< methodNameFromCppName(remap, class_name, false)
|
||||
<< "() first argument must be str or InternalName";
|
||||
|
||||
error_raise_return(out, indent_level + 2, return_flags,
|
||||
"TypeError", msg.str());
|
||||
}
|
||||
indent(out, indent_level) << "}\n";
|
||||
}
|
||||
} else {
|
||||
// There is only one possible overload with this number of parameters.
|
||||
// Just call it.
|
||||
|
@ -630,9 +630,12 @@ PUBLISHED:
|
||||
void clear_shader();
|
||||
|
||||
void set_shader_input(ShaderInput input);
|
||||
INLINE void set_shader_input(CPT_InternalName id, Texture *tex, int priority=0);
|
||||
|
||||
INLINE void set_shader_input(CPT_InternalName id, Texture *tex, const SamplerState &sampler, int priority=0);
|
||||
INLINE void set_shader_input(CPT_InternalName id, Texture *tex, bool read, bool write, int z=-1, int n=0, int priority=0);
|
||||
|
||||
public:
|
||||
INLINE void set_shader_input(CPT_InternalName id, Texture *tex, int priority=0);
|
||||
INLINE void set_shader_input(CPT_InternalName id, ShaderBuffer *buf, int priority=0);
|
||||
INLINE void set_shader_input(CPT_InternalName id, const NodePath &np, int priority=0);
|
||||
INLINE void set_shader_input(CPT_InternalName id, const PTA_float &v, int priority=0);
|
||||
@ -659,6 +662,8 @@ PUBLISHED:
|
||||
INLINE void set_shader_input(CPT_InternalName id, PN_stdfloat n1, PN_stdfloat n2=0,
|
||||
PN_stdfloat n3=0, PN_stdfloat n4=0, int priority=0);
|
||||
|
||||
PUBLISHED:
|
||||
EXTENSION(void set_shader_input(CPT_InternalName, PyObject *, int priority=0));
|
||||
EXTENSION(void set_shader_inputs(PyObject *args, PyObject *kwargs));
|
||||
|
||||
void clear_shader_input(CPT_InternalName id);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "nodePath_ext.h"
|
||||
#include "typedWritable_ext.h"
|
||||
#include "shaderInput_ext.h"
|
||||
#include "shaderAttrib.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
@ -25,35 +26,7 @@ extern struct Dtool_PyTypedObject Dtool_LPoint3d;
|
||||
#else
|
||||
extern struct Dtool_PyTypedObject Dtool_LPoint3f;
|
||||
#endif
|
||||
extern struct Dtool_PyTypedObject Dtool_Texture;
|
||||
extern struct Dtool_PyTypedObject Dtool_NodePath;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_float;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_double;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_int;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4i;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3i;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2i;
|
||||
extern struct Dtool_PyTypedObject Dtool_ShaderBuffer;
|
||||
extern struct Dtool_PyTypedObject Dtool_ParamValueBase;
|
||||
#endif // CPPPARSER
|
||||
|
||||
/**
|
||||
@ -241,6 +214,28 @@ py_decode_NodePath_from_bam_stream_persist(PyObject *unpickler, const string &da
|
||||
return NodePath::decode_from_bam_stream(data, reader);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a single shader input.
|
||||
*/
|
||||
void Extension<NodePath>::
|
||||
set_shader_input(CPT_InternalName name, PyObject *value, int priority) {
|
||||
PT(PandaNode) node = _this->node();
|
||||
CPT(RenderAttrib) prev_attrib = node->get_attrib(ShaderAttrib::get_class_slot());
|
||||
PT(ShaderAttrib) attrib;
|
||||
if (prev_attrib == nullptr) {
|
||||
attrib = new ShaderAttrib();
|
||||
} else {
|
||||
attrib = new ShaderAttrib(*(const ShaderAttrib *)prev_attrib.p());
|
||||
}
|
||||
|
||||
ShaderInput &input = attrib->_inputs[name];
|
||||
invoke_extension(&input).__init__(move(name), value);
|
||||
|
||||
if (!_PyErr_OCCURRED()) {
|
||||
node->set_attrib(ShaderAttrib::return_new(attrib));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets multiple shader inputs at the same time. This can be significantly
|
||||
* more efficient if many inputs need to be set at the same time.
|
||||
@ -278,153 +273,13 @@ set_shader_inputs(PyObject *args, PyObject *kwargs) {
|
||||
}
|
||||
|
||||
CPT_InternalName name(string(buffer, length));
|
||||
ShaderInput input(nullptr, 0);
|
||||
|
||||
if (PyTuple_CheckExact(value)) {
|
||||
// A tuple is interpreted as a vector.
|
||||
Py_ssize_t size = PyTuple_GET_SIZE(value);
|
||||
if (size > 4) {
|
||||
Dtool_Raise_TypeError("NodePath.set_shader_inputs tuple input should not have more than 4 scalars");
|
||||
return;
|
||||
}
|
||||
// If any of them is a float, we are storing it as a float vector.
|
||||
bool is_float = false;
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
if (PyFloat_CheckExact(PyTuple_GET_ITEM(value, i))) {
|
||||
is_float = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_float) {
|
||||
LVecBase4 vec(0);
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
vec[i] = (PN_stdfloat)PyFloat_AsDouble(PyTuple_GET_ITEM(value, i));
|
||||
}
|
||||
input = ShaderInput(move(name), vec);
|
||||
} else {
|
||||
LVecBase4i vec(0);
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
vec[i] = (int)PyLong_AsLong(PyTuple_GET_ITEM(value, i));
|
||||
}
|
||||
input = ShaderInput(move(name), vec);
|
||||
}
|
||||
|
||||
} else if (DtoolCanThisBeAPandaInstance(value)) {
|
||||
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)value;
|
||||
void *ptr;
|
||||
|
||||
if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_Texture))) {
|
||||
input = ShaderInput(move(name), (Texture *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_NodePath))) {
|
||||
input = ShaderInput(move(name), *(const NodePath *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_float))) {
|
||||
input = ShaderInput(move(name), *(const PTA_float *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_double))) {
|
||||
input = ShaderInput(move(name), *(const PTA_double *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_int))) {
|
||||
input = ShaderInput(move(name), *(const PTA_int *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4f))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase4f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3f))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase3f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2f))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase2f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4f))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LMatrix4f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3f))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LMatrix3f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4d))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase4d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3d))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase3d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2d))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase2d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4d))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LMatrix4d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3d))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LMatrix3d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4i))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase4i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3i))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase3i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2i))) {
|
||||
input = ShaderInput(move(name), *(const PTA_LVecBase2i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4f))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase4f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3f))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase3f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2f))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase2f *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4d))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase4d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3d))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase3d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2d))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase2d *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4i))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase4i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3i))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase3i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2i))) {
|
||||
input = ShaderInput(move(name), *(const LVecBase2i *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ShaderBuffer))) {
|
||||
input = ShaderInput(move(name), (ShaderBuffer *)ptr);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ParamValueBase))) {
|
||||
input = ShaderInput(move(name), (ParamValueBase *)ptr);
|
||||
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown type passed to NodePath.set_shader_inputs");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (PyFloat_Check(value)) {
|
||||
input = ShaderInput(move(name), LVecBase4(PyFloat_AS_DOUBLE(value), 0, 0, 0));
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
} else if (PyInt_Check(value)) {
|
||||
input = ShaderInput(move(name), LVecBase4i((int)PyInt_AS_LONG(value), 0, 0, 0));
|
||||
#endif
|
||||
|
||||
} else if (PyLong_Check(value)) {
|
||||
input = ShaderInput(move(name), LVecBase4i((int)PyLong_AsLong(value), 0, 0, 0));
|
||||
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown type passed to NodePath.set_shader_inputs");
|
||||
return;
|
||||
}
|
||||
|
||||
attrib->_inputs[input.get_name()] = move(input);
|
||||
ShaderInput &input = attrib->_inputs[name];
|
||||
invoke_extension(&input).__init__(move(name), value);
|
||||
}
|
||||
|
||||
if (!_PyErr_OCCURRED()) {
|
||||
node->set_attrib(ShaderAttrib::return_new(attrib));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
// This is defined to implement cycle detection in Python tags.
|
||||
INLINE int __traverse__(visitproc visit, void *arg);
|
||||
|
||||
void set_shader_input(CPT_InternalName id, PyObject *value, int priority=0);
|
||||
void set_shader_inputs(PyObject *args, PyObject *kwargs);
|
||||
|
||||
PyObject *get_tight_bounds(const NodePath &other = NodePath()) const;
|
||||
|
@ -2,4 +2,6 @@
|
||||
#include "nodePathCollection_ext.cxx"
|
||||
#include "pandaNode_ext.cxx"
|
||||
#include "renderState_ext.cxx"
|
||||
#include "shaderAttrib_ext.cxx"
|
||||
#include "shaderInput_ext.cxx"
|
||||
#include "transformState_ext.cxx"
|
||||
|
@ -73,6 +73,7 @@ PUBLISHED:
|
||||
// Shader Inputs
|
||||
CPT(RenderAttrib) set_shader_input(ShaderInput input) const;
|
||||
|
||||
public:
|
||||
INLINE CPT(RenderAttrib) set_shader_input(CPT_InternalName id, Texture *tex, int priority=0) const;
|
||||
INLINE CPT(RenderAttrib) set_shader_input(CPT_InternalName id, const NodePath &np, int priority=0) const;
|
||||
INLINE CPT(RenderAttrib) set_shader_input(CPT_InternalName id, const PTA_float &v, int priority=0) const;
|
||||
@ -90,6 +91,10 @@ PUBLISHED:
|
||||
INLINE CPT(RenderAttrib) set_shader_input(CPT_InternalName id, double n1=0, double n2=0, double n3=0, double n4=1,
|
||||
int priority=0) const;
|
||||
|
||||
PUBLISHED:
|
||||
EXTENSION(CPT(RenderAttrib) set_shader_input(CPT_InternalName, PyObject *, int priority=0) const);
|
||||
EXTENSION(CPT(RenderAttrib) set_shader_inputs(PyObject *args, PyObject *kwargs) const);
|
||||
|
||||
CPT(RenderAttrib) set_instance_count(int instance_count) const;
|
||||
|
||||
CPT(RenderAttrib) set_flag(int flag, bool value) const;
|
||||
@ -150,6 +155,7 @@ private:
|
||||
Inputs _inputs;
|
||||
|
||||
friend class Extension<NodePath>;
|
||||
friend class Extension<ShaderAttrib>;
|
||||
|
||||
PUBLISHED:
|
||||
static int get_class_slot() {
|
||||
|
71
panda/src/pgraph/shaderAttrib_ext.cxx
Normal file
71
panda/src/pgraph/shaderAttrib_ext.cxx
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file shaderAttrib_ext.cxx
|
||||
* @author rdb
|
||||
* @date 2017-10-08
|
||||
*/
|
||||
|
||||
#include "shaderAttrib_ext.h"
|
||||
#include "shaderInput_ext.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
/**
|
||||
* Returns a new ShaderAttrib with the given shader input set.
|
||||
*/
|
||||
CPT(RenderAttrib) Extension<ShaderAttrib>::
|
||||
set_shader_input(CPT_InternalName name, PyObject *value, int priority) const {
|
||||
ShaderAttrib *attrib = new ShaderAttrib(*_this);
|
||||
|
||||
ShaderInput &input = attrib->_inputs[name];
|
||||
invoke_extension(&input).__init__(move(name), value);
|
||||
|
||||
return ShaderAttrib::return_new(attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new ShaderAttrib with the given shader inputs set. This is a
|
||||
* more efficient way to set multiple shader inputs than calling
|
||||
* set_shader_input multiple times.
|
||||
*/
|
||||
CPT(RenderAttrib) Extension<ShaderAttrib>::
|
||||
set_shader_inputs(PyObject *args, PyObject *kwargs) const {
|
||||
if (PyObject_Size(args) > 0) {
|
||||
Dtool_Raise_TypeError("ShaderAttrib.set_shader_inputs takes only keyword arguments");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ShaderAttrib *attrib = new ShaderAttrib(*_this);
|
||||
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
while (PyDict_Next(kwargs, &pos, &key, &value)) {
|
||||
char *buffer;
|
||||
Py_ssize_t length;
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
buffer = (char *)PyUnicode_AsUTF8AndSize(key, &length);
|
||||
if (buffer == nullptr) {
|
||||
#else
|
||||
if (PyString_AsStringAndSize(key, &buffer, &length) == -1) {
|
||||
#endif
|
||||
Dtool_Raise_TypeError("ShaderAttrib.set_shader_inputs accepts only string keywords");
|
||||
delete attrib;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CPT_InternalName name(string(buffer, length));
|
||||
ShaderInput &input = attrib->_inputs[name];
|
||||
invoke_extension(&input).__init__(move(name), value);
|
||||
}
|
||||
|
||||
return ShaderAttrib::return_new(attrib);
|
||||
}
|
||||
|
||||
#endif // HAVE_PYTHON
|
38
panda/src/pgraph/shaderAttrib_ext.h
Normal file
38
panda/src/pgraph/shaderAttrib_ext.h
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file shaderAttrib_ext.h
|
||||
* @author rdb
|
||||
* @date 2017-10-08
|
||||
*/
|
||||
|
||||
#ifndef SHADERATTRIB_EXT_H
|
||||
#define SHADERATTRIB_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "shaderAttrib.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
/**
|
||||
* This class defines the extension methods for ShaderAttrib, which are called
|
||||
* instead of any C++ methods with the same prototype.
|
||||
*/
|
||||
template<>
|
||||
class Extension<ShaderAttrib> : public ExtensionBase<ShaderAttrib> {
|
||||
public:
|
||||
CPT(RenderAttrib) set_shader_input(CPT_InternalName id, PyObject *value, int priority=0) const;
|
||||
CPT(RenderAttrib) set_shader_inputs(PyObject *args, PyObject *kwargs) const;
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // SHADERATTRIB_EXT_H
|
@ -46,7 +46,11 @@ PUBLISHED:
|
||||
};
|
||||
|
||||
static const ShaderInput &get_blank();
|
||||
INLINE ShaderInput(CPT_InternalName name, int priority=0);
|
||||
INLINE explicit ShaderInput(CPT_InternalName name, int priority=0);
|
||||
|
||||
EXTENSION(explicit ShaderInput(CPT_InternalName name, PyObject *value, int priority=0));
|
||||
|
||||
public:
|
||||
INLINE ShaderInput(CPT_InternalName name, Texture *tex, int priority=0);
|
||||
INLINE ShaderInput(CPT_InternalName name, ParamValueBase *param, int priority=0);
|
||||
INLINE ShaderInput(CPT_InternalName name, ShaderBuffer *buf, int priority=0);
|
||||
@ -83,6 +87,8 @@ PUBLISHED:
|
||||
INLINE ShaderInput(CPT_InternalName name, const LVecBase2i &vec, int priority=0);
|
||||
|
||||
ShaderInput(CPT_InternalName name, const NodePath &np, int priority=0);
|
||||
|
||||
PUBLISHED:
|
||||
ShaderInput(CPT_InternalName name, Texture *tex, bool read, bool write, int z=-1, int n=0, int priority=0);
|
||||
ShaderInput(CPT_InternalName name, Texture *tex, const SamplerState &sampler, int priority=0);
|
||||
|
||||
@ -132,6 +138,7 @@ private:
|
||||
int _type;
|
||||
|
||||
friend class ShaderAttrib;
|
||||
friend class Extension<ShaderInput>;
|
||||
};
|
||||
|
||||
#include "shaderInput.I"
|
||||
|
539
panda/src/pgraph/shaderInput_ext.cxx
Normal file
539
panda/src/pgraph/shaderInput_ext.cxx
Normal file
@ -0,0 +1,539 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file shaderInput_ext.cxx
|
||||
* @author rdb
|
||||
* @date 2017-10-06
|
||||
*/
|
||||
|
||||
#include "shaderInput_ext.h"
|
||||
#include "paramNodePath.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#ifndef CPPPARSER
|
||||
extern struct Dtool_PyTypedObject Dtool_Texture;
|
||||
extern struct Dtool_PyTypedObject Dtool_NodePath;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToVoid;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_float;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_double;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_int;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLMatrix4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LMatrix3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_UnalignedLVecBase4i;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase3i;
|
||||
extern struct Dtool_PyTypedObject Dtool_PointerToArray_LVecBase2i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LMatrix4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LMatrix3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LMatrix4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LMatrix3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2f;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2d;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase4i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase3i;
|
||||
extern struct Dtool_PyTypedObject Dtool_LVecBase2i;
|
||||
extern struct Dtool_PyTypedObject Dtool_ShaderBuffer;
|
||||
extern struct Dtool_PyTypedObject Dtool_ParamValueBase;
|
||||
#endif // CPPPARSER
|
||||
|
||||
/**
|
||||
* Sets a shader input from an arbitrary Python object.
|
||||
*/
|
||||
void Extension<ShaderInput>::
|
||||
__init__(CPT_InternalName name, PyObject *value, int priority) {
|
||||
_this->_name = move(name);
|
||||
_this->_priority = priority;
|
||||
|
||||
if (PyTuple_CheckExact(value) && PyTuple_GET_SIZE(value) <= 4) {
|
||||
// A tuple is interpreted as a vector.
|
||||
Py_ssize_t size = PyTuple_GET_SIZE(value);
|
||||
|
||||
// If any of them is a float, we are storing it as a float vector.
|
||||
bool is_float = false;
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
if (PyFloat_CheckExact(PyTuple_GET_ITEM(value, i))) {
|
||||
is_float = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_float) {
|
||||
LVecBase4 vec(0);
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
vec[i] = (PN_stdfloat)PyFloat_AsDouble(PyTuple_GET_ITEM(value, i));
|
||||
}
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector = vec;
|
||||
} else {
|
||||
LVecBase4i vec(0);
|
||||
for (Py_ssize_t i = 0; i < size; ++i) {
|
||||
vec[i] = (int)PyLong_AsLong(PyTuple_GET_ITEM(value, i));
|
||||
}
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector = LCAST(PN_stdfloat, vec);
|
||||
}
|
||||
|
||||
} else if (DtoolCanThisBeAPandaInstance(value)) {
|
||||
Dtool_PyInstDef *inst = (Dtool_PyInstDef *)value;
|
||||
void *ptr;
|
||||
|
||||
if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_Texture))) {
|
||||
_this->_type = ShaderInput::M_texture;
|
||||
_this->_value = (Texture *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_NodePath))) {
|
||||
_this->_type = ShaderInput::M_nodepath;
|
||||
_this->_value = new ParamNodePath(*(const NodePath *)ptr);
|
||||
|
||||
} else if (inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToVoid)) {
|
||||
if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_float))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_float *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_double))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_double *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_int))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_int *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4f))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase4f *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3f))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase3f *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2f))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase2f *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4f))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LMatrix4f *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3f))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LMatrix3f *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4d))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase4d *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3d))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase3d *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2d))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase2d *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLMatrix4d))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LMatrix4d *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LMatrix3d))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LMatrix3d *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_UnalignedLVecBase4i))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase4i *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase3i))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase3i *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_PointerToArray_LVecBase2i))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const PTA_LVecBase2i *)ptr;
|
||||
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown type passed to ShaderInput");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix4f))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const LMatrix4f *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix3f))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const LMatrix3f *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix4d))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const LMatrix4d *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LMatrix3d))) {
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = *(const LMatrix3d *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4f))) {
|
||||
const LVecBase4f &vec = *(const LVecBase4f *)ptr;
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector = LCAST(PN_stdfloat, vec);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3f))) {
|
||||
const LVecBase3f &vec = *(const LVecBase3f *)ptr;
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set(vec[0], vec[1], vec[2], 0);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2f))) {
|
||||
const LVecBase2f &vec = *(const LVecBase2f *)ptr;
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set(vec[0], vec[1], 0, 0);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4d))) {
|
||||
const LVecBase4d &vec = *(const LVecBase4d *)ptr;
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector = LCAST(PN_stdfloat, vec);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3d))) {
|
||||
const LVecBase3d &vec = *(const LVecBase3d *)ptr;
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set(vec[0], vec[1], vec[2], 0);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2d))) {
|
||||
const LVecBase2d &vec = *(const LVecBase2d *)ptr;
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set(vec[0], vec[1], 0, 0);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase4i))) {
|
||||
const LVecBase4i &vec = *(const LVecBase4i *)ptr;
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector = LCAST(PN_stdfloat, vec);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase3i))) {
|
||||
const LVecBase3i &vec = *(const LVecBase3i *)ptr;
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set(vec[0], vec[1], vec[2], 0);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_LVecBase2i))) {
|
||||
const LVecBase2i &vec = *(const LVecBase2i *)ptr;
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set(vec[0], vec[1], 0, 0);
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ShaderBuffer))) {
|
||||
_this->_type = ShaderInput::M_buffer;
|
||||
_this->_value = (ShaderBuffer *)ptr;
|
||||
|
||||
} else if ((ptr = inst->_My_Type->_Dtool_UpcastInterface(value, &Dtool_ParamValueBase))) {
|
||||
_this->_type = ShaderInput::M_param;
|
||||
_this->_value = (ParamValueBase *)ptr;
|
||||
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown type passed to ShaderInput");
|
||||
return;
|
||||
}
|
||||
|
||||
} else if (PyFloat_Check(value)) {
|
||||
LVecBase4 vec(PyFloat_AS_DOUBLE(value), 0, 0, 0);
|
||||
_this->_type = ShaderInput::M_vector;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector = vec;
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
} else if (PyInt_Check(value)) {
|
||||
LVecBase4i vec((int)PyInt_AS_LONG(value), 0, 0, 0);
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set((PN_stdfloat)vec[0], 0, 0, 0);
|
||||
#endif
|
||||
|
||||
} else if (PyLong_Check(value)) {
|
||||
LVecBase4i vec((int)PyLong_AsLong(value), 0, 0, 0);
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
_this->_stored_ptr = vec;
|
||||
_this->_stored_vector.set((PN_stdfloat)vec[0], 0, 0, 0);
|
||||
|
||||
} else if (PySequence_Check(value) && !PyUnicode_CheckExact(value)) {
|
||||
// Iterate over the sequence to make sure all have the same type.
|
||||
PyObject *fast = PySequence_Fast(value, "unknown type passed to ShaderInput");
|
||||
if (fast == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Py_ssize_t num_items = PySequence_Fast_GET_SIZE(value);
|
||||
if (num_items <= 0) {
|
||||
// We can't determine the type of a list of size 0.
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
Py_DECREF(fast);
|
||||
return;
|
||||
}
|
||||
|
||||
bool has_float = false;
|
||||
Py_ssize_t known_itemsize = -1;
|
||||
|
||||
PyObject **items = PySequence_Fast_ITEMS(fast);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
|
||||
if (PySequence_Check(item)) {
|
||||
Py_ssize_t itemsize = PySequence_Size(item);
|
||||
if (known_itemsize >= 0 && itemsize != known_itemsize) {
|
||||
Dtool_Raise_TypeError("inconsistent sequence length among elements of sequence passed to ShaderInput");
|
||||
Py_DECREF(fast);
|
||||
return;
|
||||
}
|
||||
known_itemsize = itemsize;
|
||||
|
||||
// Check their types.
|
||||
for (Py_ssize_t j = 0; j < itemsize; ++j) {
|
||||
PyObject *subitem = PySequence_ITEM(item, j);
|
||||
if (PyFloat_CheckExact(subitem)) {
|
||||
Py_DECREF(subitem);
|
||||
has_float = true;
|
||||
break;
|
||||
} else if (PyLongOrInt_Check(subitem)) {
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown element type in sequence passed as element of sequence passed to ShaderInput");
|
||||
Py_DECREF(subitem);
|
||||
Py_DECREF(fast);
|
||||
break;
|
||||
}
|
||||
Py_DECREF(subitem);
|
||||
}
|
||||
} else if (PyFloat_CheckExact(item)) {
|
||||
has_float = true;
|
||||
} else if (PyLongOrInt_Check(item)) {
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown element type in sequence passed to ShaderInput");
|
||||
Py_DECREF(fast);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Now that we have verified the dimensions and type of the PTA, we can
|
||||
// read in the actual elements.
|
||||
switch (known_itemsize) {
|
||||
case -1:
|
||||
if (has_float) {
|
||||
PTA_float pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
pta.push_back(PyFloat_AsDouble(items[i]));
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
} else {
|
||||
PTA_int pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
pta.push_back((int)PyLongOrInt_AS_LONG(items[i]));
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
if (has_float) {
|
||||
PTA_float pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem = PySequence_ITEM(item, 0);
|
||||
pta.push_back(PyFloat_AsDouble(subitem));
|
||||
Py_DECREF(subitem);
|
||||
} else {
|
||||
pta.push_back(PyFloat_AsDouble(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
} else {
|
||||
PTA_int pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem = PySequence_ITEM(item, 0);
|
||||
pta.push_back((int)PyLongOrInt_AS_LONG(subitem));
|
||||
Py_DECREF(subitem);
|
||||
} else {
|
||||
pta.push_back((int)PyLongOrInt_AS_LONG(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (has_float) {
|
||||
PTA_LVecBase2f pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem0 = PySequence_ITEM(item, 0);
|
||||
PyObject *subitem1 = PySequence_ITEM(item, 1);
|
||||
pta.push_back(LVecBase2f(PyFloat_AsDouble(subitem0),
|
||||
PyFloat_AsDouble(subitem1)));
|
||||
Py_DECREF(subitem0);
|
||||
Py_DECREF(subitem1);
|
||||
} else {
|
||||
pta.push_back(PyFloat_AsDouble(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
} else {
|
||||
PTA_LVecBase2i pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem0 = PySequence_ITEM(item, 0);
|
||||
PyObject *subitem1 = PySequence_ITEM(item, 1);
|
||||
pta.push_back(LVecBase2i((int)PyLongOrInt_AS_LONG(subitem0),
|
||||
(int)PyLongOrInt_AS_LONG(subitem1)));
|
||||
Py_DECREF(subitem0);
|
||||
Py_DECREF(subitem1);
|
||||
} else {
|
||||
pta.push_back((int)PyLongOrInt_AS_LONG(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
if (has_float) {
|
||||
PTA_LVecBase3f pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem0 = PySequence_ITEM(item, 0);
|
||||
PyObject *subitem1 = PySequence_ITEM(item, 1);
|
||||
PyObject *subitem2 = PySequence_ITEM(item, 2);
|
||||
pta.push_back(LVecBase3f(PyFloat_AsDouble(subitem0),
|
||||
PyFloat_AsDouble(subitem1),
|
||||
PyFloat_AsDouble(subitem2)));
|
||||
Py_DECREF(subitem0);
|
||||
Py_DECREF(subitem1);
|
||||
Py_DECREF(subitem2);
|
||||
} else {
|
||||
pta.push_back(PyFloat_AsDouble(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
} else {
|
||||
PTA_LVecBase3i pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem0 = PySequence_ITEM(item, 0);
|
||||
PyObject *subitem1 = PySequence_ITEM(item, 1);
|
||||
PyObject *subitem2 = PySequence_ITEM(item, 2);
|
||||
pta.push_back(LVecBase3i((int)PyLongOrInt_AS_LONG(subitem0),
|
||||
(int)PyLongOrInt_AS_LONG(subitem1),
|
||||
(int)PyLongOrInt_AS_LONG(subitem2)));
|
||||
Py_DECREF(subitem0);
|
||||
Py_DECREF(subitem1);
|
||||
Py_DECREF(subitem2);
|
||||
} else {
|
||||
pta.push_back((int)PyLongOrInt_AS_LONG(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (has_float) {
|
||||
PTA_LVecBase4f pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem0 = PySequence_ITEM(item, 0);
|
||||
PyObject *subitem1 = PySequence_ITEM(item, 1);
|
||||
PyObject *subitem2 = PySequence_ITEM(item, 2);
|
||||
PyObject *subitem3 = PySequence_ITEM(item, 3);
|
||||
pta.push_back(LVecBase4f(PyFloat_AsDouble(subitem0),
|
||||
PyFloat_AsDouble(subitem1),
|
||||
PyFloat_AsDouble(subitem2),
|
||||
PyFloat_AsDouble(subitem3)));
|
||||
Py_DECREF(subitem0);
|
||||
Py_DECREF(subitem1);
|
||||
Py_DECREF(subitem2);
|
||||
Py_DECREF(subitem3);
|
||||
} else {
|
||||
pta.push_back(PyFloat_AsDouble(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
} else {
|
||||
PTA_LVecBase4i pta;
|
||||
pta.reserve(num_items);
|
||||
for (Py_ssize_t i = 0; i < num_items; ++i) {
|
||||
PyObject *item = items[i];
|
||||
if (PySequence_Check(item)) {
|
||||
PyObject *subitem0 = PySequence_ITEM(item, 0);
|
||||
PyObject *subitem1 = PySequence_ITEM(item, 1);
|
||||
PyObject *subitem2 = PySequence_ITEM(item, 2);
|
||||
PyObject *subitem3 = PySequence_ITEM(item, 3);
|
||||
pta.push_back(LVecBase4i((int)PyLongOrInt_AS_LONG(subitem0),
|
||||
(int)PyLongOrInt_AS_LONG(subitem1),
|
||||
(int)PyLongOrInt_AS_LONG(subitem2),
|
||||
(int)PyLongOrInt_AS_LONG(subitem3)));
|
||||
Py_DECREF(subitem0);
|
||||
Py_DECREF(subitem1);
|
||||
Py_DECREF(subitem2);
|
||||
Py_DECREF(subitem3);
|
||||
} else {
|
||||
pta.push_back((int)PyLongOrInt_AS_LONG(item));
|
||||
}
|
||||
}
|
||||
_this->_stored_ptr = pta;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
Dtool_Raise_TypeError("sequence passed to ShaderInput contains an empty sequence");
|
||||
break;
|
||||
|
||||
default:
|
||||
Dtool_Raise_TypeError("sequence passed to ShaderInput contains a sequence of more than 4 elements");
|
||||
break;
|
||||
}
|
||||
|
||||
_this->_type = ShaderInput::M_numeric;
|
||||
|
||||
Py_DECREF(fast);
|
||||
|
||||
} else {
|
||||
Dtool_Raise_TypeError("unknown type passed to ShaderInput");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HAVE_PYTHON
|
37
panda/src/pgraph/shaderInput_ext.h
Normal file
37
panda/src/pgraph/shaderInput_ext.h
Normal file
@ -0,0 +1,37 @@
|
||||
/**
|
||||
* PANDA 3D SOFTWARE
|
||||
* Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
*
|
||||
* All use of this software is subject to the terms of the revised BSD
|
||||
* license. You should have received a copy of this license along
|
||||
* with this source code in a file named "LICENSE."
|
||||
*
|
||||
* @file shaderInput_ext.h
|
||||
* @author rdb
|
||||
* @date 2017-10-06
|
||||
*/
|
||||
|
||||
#ifndef SHADERINPUT_EXT_H
|
||||
#define SHADERINPUT_EXT_H
|
||||
|
||||
#include "dtoolbase.h"
|
||||
|
||||
#ifdef HAVE_PYTHON
|
||||
|
||||
#include "extension.h"
|
||||
#include "shaderInput.h"
|
||||
#include "py_panda.h"
|
||||
|
||||
/**
|
||||
* This class defines the extension methods for NodePath, which are called
|
||||
* instead of any C++ methods with the same prototype.
|
||||
*/
|
||||
template<>
|
||||
class Extension<ShaderInput> : public ExtensionBase<ShaderInput> {
|
||||
public:
|
||||
void __init__(CPT_InternalName name, PyObject *value, int priority=0);
|
||||
};
|
||||
|
||||
#endif // HAVE_PYTHON
|
||||
|
||||
#endif // SHADERINPUT_EXT_H
|
Loading…
x
Reference in New Issue
Block a user