[Bf-blender-cvs] [9847537979b] ge_2df_textures: BGE: new bge.logic.Render() to perform render w/o logic step.
Benoit Bolsee
noreply at git.blender.org
Sat Apr 1 01:02:53 CEST 2017
Commit: 9847537979b8a3ccf4ee5c7f6ca5b66ed9d7b80b
Author: Benoit Bolsee
Date: Sat Apr 1 00:57:38 2017 +0200
Branches: ge_2df_textures
https://developer.blender.org/rB9847537979b8a3ccf4ee5c7f6ca5b66ed9d7b80b
BGE: new bge.logic.Render() to perform render w/o logic step.
This function works only if python has control:
1. add scene custom property, call it __main__
2. give it string value as the name of a text block
3. code game loop in python in text block. Example:
import bge
bge.logic.setUseExternalClock(True)
t = 0.0;
scene = bge.logic.getCurrentScene()
cam = scene.cameras["Camera"]
cam.setViewport(120,120,370,370)
while not bge.logic.NextFrame():
cam.useViewport = True
# second render with viewport enable, clock time unchanged
bge.logic.Render()
# advance animation for next frame
t += 0.02
bge.logic.setClockTime(t)
cam.useViewport = False
===================================================================
M source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
M source/gameengine/GamePlayer/ghost/GPG_Application.cpp
M source/gameengine/GamePlayer/ghost/GPG_Application.h
M source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
M source/gameengine/Ketsji/KX_PythonInit.cpp
M source/gameengine/Ketsji/KX_PythonInit.h
===================================================================
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 6c3751ae34d..e6266c00d07 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -122,6 +122,23 @@ static BlendFileData *load_game_data(const char *filename)
return bfd;
}
+static void BL_KetsjiRender(KX_KetsjiEngine *ketsjiengine, ARegion *ar, Scene *scene, int draw_letterbox)
+{
+ if (draw_letterbox) {
+ // Clear screen to border color
+ // We do this here since we set the canvas to be within the frames. This means the engine
+ // itself is unaware of the extra space, so we clear the whole region for it.
+ glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f);
+ glViewport(ar->winrct.xmin, ar->winrct.ymin,
+ BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ // render the frame
+ ketsjiengine->Render();
+
+}
+
static int BL_KetsjiNextFrame(KX_KetsjiEngine *ketsjiengine, bContext *C, wmWindow *win, Scene *scene, ARegion *ar,
KX_BlenderKeyboardDevice* keyboarddevice, KX_BlenderMouseDevice* mousedevice, int draw_letterbox)
{
@@ -134,18 +151,7 @@ static int BL_KetsjiNextFrame(KX_KetsjiEngine *ketsjiengine, bContext *C, wmWind
bool render = ketsjiengine->NextFrame();
if (render) {
- if (draw_letterbox) {
- // Clear screen to border color
- // We do this here since we set the canvas to be within the frames. This means the engine
- // itself is unaware of the extra space, so we clear the whole region for it.
- glClearColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 1.0f);
- glViewport(ar->winrct.xmin, ar->winrct.ymin,
- BLI_rcti_size_x(&ar->winrct), BLI_rcti_size_y(&ar->winrct));
- glClear(GL_COLOR_BUFFER_BIT);
- }
-
- // render the frame
- ketsjiengine->Render();
+ BL_KetsjiRender(ketsjiengine, ar, scene, draw_letterbox);
}
wm_window_process_events_nosleep();
@@ -211,6 +217,13 @@ static int BL_KetsjiPyNextFrame(void *state0)
state->mousedevice,
state->draw_letterbox);
}
+
+static void BL_KetsjiPyRender(void *state0)
+{
+ BL_KetsjiNextFrameState *state = (BL_KetsjiNextFrameState *) state0;
+ BL_KetsjiRender(state->ketsjiengine, state->ar, state->scene, state->draw_letterbox);
+}
+
#endif
@@ -526,6 +539,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
char *python_main = NULL;
pynextframestate.state = NULL;
pynextframestate.func = NULL;
+ pynextframestate.render = NULL;
python_main = KX_GetPythonMain(scene);
// the mainloop
@@ -548,6 +562,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
pynextframestate.state = &ketsjinextframestate;
pynextframestate.func = &BL_KetsjiPyNextFrame;
+ pynextframestate.render = &BL_KetsjiPyRender;
printf("Yielding control to Python script '%s'...\n", python_main);
PyRun_SimpleString(python_code);
printf("Exit Python script '%s'\n", python_main);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index 408006a0dae..7c742b66506 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -848,6 +848,12 @@ void GPG_Application::EngineNextFrame()
m_exitString = m_ketsjiengine->GetExitString();
}
+void GPG_Application::EngineRender()
+{
+ // render the frame
+ m_ketsjiengine->Render();
+}
+
void GPG_Application::exitEngine()
{
// We only want to kill the engine if it has been initialized
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.h b/source/gameengine/GamePlayer/ghost/GPG_Application.h
index e757cc10e32..dfab9166c7a 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.h
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.h
@@ -93,6 +93,7 @@ public:
bool StartGameEngine(int stereoMode);
void StopGameEngine();
void EngineNextFrame();
+ void EngineRender();
protected:
bool handleWheel(GHOST_IEvent* event);
diff --git a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
index e5ee60c89a7..7e4fe300531 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_ghost.cpp
@@ -385,6 +385,11 @@ static bool GPG_NextFrame(GHOST_ISystem* system, GPG_Application *app, int &exit
return run;
}
+static void GPG_Render(GPG_Application *app)
+{
+ app->EngineRender();
+}
+
struct GPG_NextFrameState {
GHOST_ISystem* system;
GPG_Application *app;
@@ -405,6 +410,12 @@ static int GPG_PyNextFrame(void *state0)
}
}
+static void GPG_PyRender(void *state0)
+{
+ GPG_NextFrameState *state = (GPG_NextFrameState *) state0;
+ GPG_Render(state->app);
+}
+
int main(
int argc,
#ifdef WIN32
@@ -1124,6 +1135,7 @@ int main(
char *python_main = NULL;
pynextframestate.state = NULL;
pynextframestate.func = NULL;
+ pynextframestate.render = NULL;
#ifdef WITH_PYTHON
python_main = KX_GetPythonMain(scene);
#endif // WITH_PYTHON
@@ -1141,6 +1153,7 @@ int main(
gpg_nextframestate.gs = &gs;
pynextframestate.state = &gpg_nextframestate;
pynextframestate.func = &GPG_PyNextFrame;
+ pynextframestate.render = &GPG_PyRender;
printf("Yielding control to Python script '%s'...\n", python_main);
PyRun_SimpleString(python_code);
diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp
index a93294e93ee..8b9dd2df9b1 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.cpp
+++ b/source/gameengine/Ketsji/KX_PythonInit.cpp
@@ -905,6 +905,15 @@ static PyObject *gPyNextFrame(PyObject *)
}
}
+static PyObject *gPyRender(PyObject *)
+{
+ if (pynextframestate.render == NULL) Py_RETURN_NONE;
+ if (pynextframestate.state == NULL) Py_RETURN_NONE; //should never happen; raise exception instead?
+
+ pynextframestate.render(pynextframestate.state);
+ Py_RETURN_NONE;
+}
+
static struct PyMethodDef game_methods[] = {
{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (const char *)gPyExpandPath_doc},
@@ -953,6 +962,7 @@ static struct PyMethodDef game_methods[] = {
{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
{"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine statistics"},
{"NextFrame", (PyCFunction)gPyNextFrame, METH_NOARGS, (const char *)"Render next frame (if Python has control)"},
+ {"Render", (PyCFunction)gPyRender, METH_NOARGS, (const char *)"Do only render (skip logic), if Python has control"},
{"getProfileInfo", (PyCFunction)gPyGetProfileInfo, METH_NOARGS, gPyGetProfileInfo_doc},
/* library functions */
{"LibLoad", (PyCFunction)gLibLoad, METH_VARARGS|METH_KEYWORDS, (const char *)""},
diff --git a/source/gameengine/Ketsji/KX_PythonInit.h b/source/gameengine/Ketsji/KX_PythonInit.h
index 6550934a916..3b754ea1e25 100644
--- a/source/gameengine/Ketsji/KX_PythonInit.h
+++ b/source/gameengine/Ketsji/KX_PythonInit.h
@@ -78,12 +78,15 @@ KX_Scene *KX_GetActiveScene();
KX_KetsjiEngine *KX_GetActiveEngine();
typedef int (*PyNextFrameFunc)(void *);
+typedef void (*PyRenderFunc)(void *);
struct PyNextFrameState {
/** can be either a GPG_NextFrameState or a BL_KetsjiNextFrameState */
void *state;
/** can be either GPG_PyNextFrame or BL_KetsjiPyNextFrame */
PyNextFrameFunc func;
+ /** can be either GPG_PyRender or BL_KetsjiPyRender */
+ PyRenderFunc render;
};
extern struct PyNextFrameState pynextframestate;
More information about the Bf-blender-cvs
mailing list