Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2009-11-22 17:42:22 +0300
committerCampbell Barton <ideasman42@gmail.com>2009-11-22 17:42:22 +0300
commitc36f78dd41b8d2c714b2a94c43eabe928afea26a (patch)
tree48856d51a20eb4024f142e1fb68a9d345a291aeb /source/gameengine/Ketsji/KX_Scene.cpp
parentf4a0c9239ff21a75a336ed3f496dd88d3997d28e (diff)
[#19258] [patch] Adding drawing capabilities to BGE Python
patch from Mitchell Stokes (moguri) simple use case scene.post_draw = [pyOpenGLFunc] this only needs to be set once, then the funcion runs each redraw. note, this patch also changes how python scripts run (not modules): Dont clear the namespace after running a script, since functions still use the namespace, BGE API is now better when dealing with stale data. made some changes to this patch. - assigning a list didnt decrement the existing list. - initialize as NULL rather then a blank list - dont use string comparisons for the callbacks, pass the python list to use instead. - dont check the list items are callable. python will display an error if they are not. - use python list macros that dont do any type checking sine blender does this when assigning the list ---- from tracker, edited since an updated patch changes some things. Here is a patch to be able to draw to the screen with BGE Python. This will be very handy for GUI stuff. This patch works by having the user register a callback in the scene. Two options are available KX_Scene.pre_draw and KX_Scene.post_draw. The difference between these is when Python draws to the screen (before or after the BGE). Each can take a list of functions. Here is an example that draws a blue semi-transparent
Diffstat (limited to 'source/gameengine/Ketsji/KX_Scene.cpp')
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp84
1 files changed, 84 insertions, 0 deletions
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 655c8eedaae..c018dcd387f 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -211,6 +211,8 @@ KX_Scene::KX_Scene(class SCA_IInputDevice* keyboarddevice,
#ifndef DISABLE_PYTHON
m_attr_dict = PyDict_New(); /* new ref */
+ m_draw_call_pre = NULL;
+ m_draw_call_post = NULL;
#endif
}
@@ -264,6 +266,9 @@ KX_Scene::~KX_Scene()
#ifndef DISABLE_PYTHON
PyDict_Clear(m_attr_dict);
Py_DECREF(m_attr_dict);
+
+ Py_XDECREF(m_draw_call_pre);
+ Py_XDECREF(m_draw_call_post);
#endif
}
@@ -401,6 +406,28 @@ bool KX_Scene::IsClearingZBuffer()
return m_isclearingZbuffer;
}
+void KX_Scene::RunDrawingCallbacks(PyObject* cb_list)
+{
+ int len;
+
+ if (cb_list && (len=PyList_GET_SIZE(cb_list)))
+ {
+ PyObject* func;
+ PyObject* ret;
+
+ // Iterate the list and run the callbacks
+ for (int pos=0; pos < len; pos++)
+ {
+ func= PyList_GET_ITEM(cb_list, pos);
+ ret= PyObject_CallObject(func, NULL);
+ if (ret==NULL) {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+ }
+ }
+}
+
void KX_Scene::EnableZBufferClearing(bool isclearingZbuffer)
{
m_isclearingZbuffer = isclearingZbuffer;
@@ -1997,6 +2024,61 @@ int KX_Scene::pyattr_set_active_camera(void *self_v, const KX_PYATTRIBUTE_DEF *a
return PY_SET_ATTR_SUCCESS;
}
+PyObject* KX_Scene::pyattr_get_drawing_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self = static_cast<KX_Scene*>(self_v);
+
+ if(self->m_draw_call_pre==NULL)
+ self->m_draw_call_pre= PyList_New(0);
+ else
+ Py_INCREF(self->m_draw_call_pre);
+ return self->m_draw_call_pre;
+}
+
+PyObject* KX_Scene::pyattr_get_drawing_callback_post(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
+{
+ KX_Scene* self = static_cast<KX_Scene*>(self_v);
+
+ if(self->m_draw_call_post==NULL)
+ self->m_draw_call_post= PyList_New(0);
+ else
+ Py_INCREF(self->m_draw_call_post);
+ return self->m_draw_call_post;
+}
+
+int KX_Scene::pyattr_set_drawing_callback_pre(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Scene* self = static_cast<KX_Scene*>(self_v);
+
+ if (!PyList_CheckExact(value))
+ {
+ PyErr_SetString(PyExc_ValueError, "Expected a list");
+ return PY_SET_ATTR_FAIL;
+ }
+ Py_XDECREF(self->m_draw_call_pre);
+
+ Py_INCREF(value);
+ self->m_draw_call_pre = value;
+
+ return PY_SET_ATTR_SUCCESS;
+}
+
+int KX_Scene::pyattr_set_drawing_callback_post(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
+{
+ KX_Scene* self = static_cast<KX_Scene*>(self_v);
+
+ if (!PyList_CheckExact(value))
+ {
+ PyErr_SetString(PyExc_ValueError, "Expected a list");
+ return PY_SET_ATTR_FAIL;
+ }
+ Py_XDECREF(self->m_draw_call_post);
+
+ Py_INCREF(value);
+ self->m_draw_call_post = value;
+
+ return PY_SET_ATTR_SUCCESS;
+}
PyAttributeDef KX_Scene::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("name", KX_Scene, pyattr_get_name),
@@ -2005,6 +2087,8 @@ PyAttributeDef KX_Scene::Attributes[] = {
KX_PYATTRIBUTE_RO_FUNCTION("cameras", KX_Scene, pyattr_get_cameras),
KX_PYATTRIBUTE_RO_FUNCTION("lights", KX_Scene, pyattr_get_lights),
KX_PYATTRIBUTE_RW_FUNCTION("active_camera", KX_Scene, pyattr_get_active_camera, pyattr_set_active_camera),
+ KX_PYATTRIBUTE_RW_FUNCTION("pre_draw", KX_Scene, pyattr_get_drawing_callback_pre, pyattr_set_drawing_callback_pre),
+ KX_PYATTRIBUTE_RW_FUNCTION("post_draw", KX_Scene, pyattr_get_drawing_callback_post, pyattr_set_drawing_callback_post),
KX_PYATTRIBUTE_BOOL_RO("suspended", KX_Scene, m_suspend),
KX_PYATTRIBUTE_BOOL_RO("activity_culling", KX_Scene, m_activity_culling),
KX_PYATTRIBUTE_FLOAT_RW("activity_culling_radius", 0.5f, FLT_MAX, KX_Scene, m_activity_box_radius),