[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