Beispiel #1
0
/* was space_set_commmandline_options in 2.4x */
static void game_set_commmandline_options(GameData *gm)
{
	SYS_SystemHandle syshandle;
	int test;

	if ((syshandle = SYS_GetSystem())) {
		/* User defined settings */
		test = (U.gameflags & USER_DISABLE_MIPMAP);
		GPU_set_mipmap(!test);
		SYS_WriteCommandLineInt(syshandle, "nomipmap", test);

		/* File specific settings: */
		/* Only test the first one. These two are switched
		 * simultaneously. */
		test = (gm->flag & GAME_SHOW_FRAMERATE);
		SYS_WriteCommandLineInt(syshandle, "show_framerate", test);
		SYS_WriteCommandLineInt(syshandle, "show_profile", test);

		test = (gm->flag & GAME_SHOW_DEBUG_PROPS);
		SYS_WriteCommandLineInt(syshandle, "show_properties", test);

		test = (gm->flag & GAME_SHOW_PHYSICS);
		SYS_WriteCommandLineInt(syshandle, "show_physics", test);

		test = (gm->flag & GAME_ENABLE_ALL_FRAMES);
		SYS_WriteCommandLineInt(syshandle, "fixedtime", test);

		test = (gm->flag & GAME_ENABLE_ANIMATION_RECORD);
		SYS_WriteCommandLineInt(syshandle, "animation_record", test);

		test = (gm->flag & GAME_IGNORE_DEPRECATION_WARNINGS);
		SYS_WriteCommandLineInt(syshandle, "ignore_deprecation_warnings", test);

		test = (gm->matmode == GAME_MAT_MULTITEX);
		SYS_WriteCommandLineInt(syshandle, "blender_material", test);
		test = (gm->matmode == GAME_MAT_GLSL);
		SYS_WriteCommandLineInt(syshandle, "blender_glsl_material", test);
		test = (gm->flag & GAME_DISPLAY_LISTS);
		SYS_WriteCommandLineInt(syshandle, "displaylists", test);


	}
}
Beispiel #2
0
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing)
{
	/* context values */
	struct wmWindow *win= CTX_wm_window(C);
	struct Scene *startscene= CTX_data_scene(C);
	struct Main* maggie1= CTX_data_main(C);


	RAS_Rect area_rect;
	area_rect.SetLeft(cam_frame->xmin);
	area_rect.SetBottom(cam_frame->ymin);
	area_rect.SetRight(cam_frame->xmax);
	area_rect.SetTop(cam_frame->ymax);

	int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
	Main* blenderdata = maggie1;

	char* startscenename = startscene->id.name+2;
	char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE];
	STR_String exitstring = "";
	BlendFileData *bfd= NULL;

	BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
	BLI_strncpy(oldsce, G.main->name, sizeof(oldsce));
#ifdef WITH_PYTHON
	resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path
	setGamePythonPath(G.main->name);

	// Acquire Python's GIL (global interpreter lock)
	// so we can safely run Python code and API calls
	PyGILState_STATE gilstate = PyGILState_Ensure();
	
	PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
#endif
	
	bgl::InitExtensions(true);

	// VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable
	int disableVBO = (U.gameflags & USER_DISABLE_VBO);
	U.gameflags |= USER_DISABLE_VBO;

	// Globals to be carried on over blender files
	GlobalSettings gs;
	gs.matmode= startscene->gm.matmode;
	gs.glslflag= startscene->gm.flag;

	do
	{
		View3D *v3d= CTX_wm_view3d(C);
		RegionView3D *rv3d= CTX_wm_region_view3d(C);

		// get some preferences
		SYS_SystemHandle syshandle = SYS_GetSystem();
		bool properties	= (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
		bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
		bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
		bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
		bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0);
		bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
#ifdef WITH_PYTHON
		bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
#endif
		bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
		bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE;
		bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES;

		if(animation_record) usefixed= true; /* override since you's always want fixed time for sim recording */

		// create the canvas, rasterizer and rendertools
		RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect, ar);
		
		// default mouse state set on render panel
		if (mouse_state)
			canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
		else
			canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
		RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
		RAS_IRasterizer* rasterizer = NULL;
		
		if(displaylists) {
			if (GLEW_VERSION_1_1 && !novertexarrays)
				rasterizer = new RAS_ListRasterizer(canvas, true, true);
			else
				rasterizer = new RAS_ListRasterizer(canvas);
		}
		else if (GLEW_VERSION_1_1 && !novertexarrays)
			rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
		else
			rasterizer = new RAS_OpenGLRasterizer(canvas);
		
		// create the inputdevices
		KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
		KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
		
		// create a networkdevice
		NG_NetworkDeviceInterface* networkdevice = new
			NG_LoopBackNetworkDeviceInterface();

		//
		// create a ketsji/blendersystem (only needed for timing and stuff)
		KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
		
		// create the ketsjiengine
		KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);
		
		// set the devices
		ketsjiengine->SetKeyboardDevice(keyboarddevice);
		ketsjiengine->SetMouseDevice(mousedevice);
		ketsjiengine->SetNetworkDevice(networkdevice);
		ketsjiengine->SetCanvas(canvas);
		ketsjiengine->SetRenderTools(rendertools);
		ketsjiengine->SetRasterizer(rasterizer);
		ketsjiengine->SetUseFixedTime(usefixed);
		ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
		ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS);
		KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey));

		//set the global settings (carried over if restart/load new files)
		ketsjiengine->SetGlobalSettings(&gs);

#ifdef WITH_PYTHON
		CValue::SetDeprecationWarnings(nodepwarnings);
#endif

		//lock frame and camera enabled - storing global values
		int tmp_lay= startscene->lay;
		Object *tmp_camera = startscene->camera;

		if (v3d->scenelock==0){
			startscene->lay= v3d->lay;
			startscene->camera= v3d->camera;
		}

		// some blender stuff
		float camzoom;
		int draw_letterbox = 0;
		
		if(rv3d->persp==RV3D_CAMOB) {
			if(startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */
				camzoom = 1.0f;
				draw_letterbox = 1;
			}
			else {
				camzoom = 1.0 / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
			}
		}
		else {
			camzoom = 2.0;
		}


		ketsjiengine->SetDrawType(v3d->drawtype);
		ketsjiengine->SetCameraZoom(camzoom);
		
		// if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
		if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME)
		{
			exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
			if (bfd) BLO_blendfiledata_free(bfd);
			
			char basedpath[FILE_MAX];
			// base the actuator filename with respect
			// to the original file working directory

			if (exitstring != "")
				strcpy(basedpath, exitstring.Ptr());

			// load relative to the last loaded file, this used to be relative
			// to the first file but that makes no sense, relative paths in
			// blend files should be relative to that file, not some other file
			// that happened to be loaded first
			BLI_path_abs(basedpath, pathname);
			bfd = load_game_data(basedpath);
			
			// if it wasn't loaded, try it forced relative
			if (!bfd)
			{
				// just add "//" in front of it
				char temppath[242];
				strcpy(temppath, "//");
				strcat(temppath, basedpath);
				
				BLI_path_abs(temppath, pathname);
				bfd = load_game_data(temppath);
			}
			
			// if we got a loaded blendfile, proceed
			if (bfd)
			{
				blenderdata = bfd->main;
				startscenename = bfd->curscene->id.name + 2;

				if(blenderdata) {
					BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name));
					BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
#ifdef WITH_PYTHON
					setGamePythonPath(G.main->name);
#endif
				}
			}
			// else forget it, we can't find it
			else
			{
				exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
			}
		}

		Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2);

		if (scene)
		{
			int startFrame = scene->r.cfra;
			ketsjiengine->SetAnimRecordMode(animation_record, startFrame);
			
			// Quad buffered needs a special window.
			if(scene->gm.stereoflag == STEREO_ENABLED){
				if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
					rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode);

				rasterizer->SetEyeSeparation(scene->gm.eyeseparation);
			}

			rasterizer->SetBackColor(scene->gm.framing.col[0], scene->gm.framing.col[1], scene->gm.framing.col[2], 0.0f);
		}
		
		if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
		{
			if (rv3d->persp != RV3D_CAMOB)
			{
				ketsjiengine->EnableCameraOverride(startscenename);
				ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO));
				ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat));
				ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat));
				if(rv3d->persp == RV3D_ORTHO)
				{
					ketsjiengine->SetCameraOverrideClipping(-v3d->far, v3d->far);
				}
				else
				{
					ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
				}
				ketsjiengine->SetCameraOverrideLens(v3d->lens);
			}
			
			// create a scene converter, create and convert the startingscene
			KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
			ketsjiengine->SetSceneConverter(sceneconverter);
			sceneconverter->addInitFromFrame=false;
			if (always_use_expand_framing)
				sceneconverter->SetAlwaysUseExpandFraming(true);

			bool usemat = false, useglslmat = false;

			if(GLEW_ARB_multitexture && GLEW_VERSION_1_1)
				usemat = true;

			if(GPU_glsl_support())
				useglslmat = true;
			else if(gs.matmode == GAME_MAT_GLSL)
				usemat = false;

			if(usemat && (gs.matmode != GAME_MAT_TEXFACE))
				sceneconverter->SetMaterials(true);
			if(useglslmat && (gs.matmode == GAME_MAT_GLSL))
				sceneconverter->SetGLSLMaterials(true);
					
			KX_Scene* startscene = new KX_Scene(keyboarddevice,
				mousedevice,
				networkdevice,
				startscenename,
				scene,
				canvas);

#ifdef WITH_PYTHON
			// some python things
			PyObject *gameLogic, *gameLogic_keys;
			setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL);
#endif // WITH_PYTHON

			//initialize Dome Settings
			if(scene->gm.stereoflag == STEREO_DOME)
				ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext);

			// initialize 3D Audio Settings
			AUD_I3DDevice* dev = AUD_get3DDevice();
			if(dev)
			{
				dev->setSpeedOfSound(scene->audio.speed_of_sound);
				dev->setDopplerFactor(scene->audio.doppler_factor);
				dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model));
			}

			// from see blender.c:
			// FIXME: this version patching should really be part of the file-reading code,
			// but we still get too many unrelated data-corruption crashes otherwise...
			if (blenderdata->versionfile < 250)
				do_versions_ipos_to_animato(blenderdata);

			if (sceneconverter)
			{
				// convert and add scene
				sceneconverter->ConvertScene(
					startscene,
					rendertools,
					canvas);
				ketsjiengine->AddScene(startscene);
				
				// init the rasterizer
				rasterizer->Init();
				
				// start the engine
				ketsjiengine->StartEngine(true);
				

				// Set the animation playback rate for ipo's and actions
				// the framerate below should patch with FPS macro defined in blendef.h
				// Could be in StartEngine set the framerate, we need the scene to do this
				ketsjiengine->SetAnimFrameRate(FPS);
				
				// the mainloop
				printf("\nBlender Game Engine Started\n");
				while (!exitrequested)
				{
					// first check if we want to exit
					exitrequested = ketsjiengine->GetExitCode();
					
					// kick the engine
					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,
								ar->winrct.xmax - ar->winrct.xmin, ar->winrct.ymax - ar->winrct.ymin);
							glClear(GL_COLOR_BUFFER_BIT);
						}

						// render the frame
						ketsjiengine->Render();
					}
					
					wm_window_process_events_nosleep();
					
					// test for the ESC key
					//XXX while (qtest())
					while(wmEvent *event= (wmEvent *)win->queue.first)
					{
						short val = 0;
						//unsigned short event = 0; //XXX extern_qread(&val);
						
						if (keyboarddevice->ConvertBlenderEvent(event->type,event->val))
							exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
						
							/* Coordinate conversion... where
							* should this really be?
						*/
						if (event->type==MOUSEMOVE) {
							/* Note, not nice! XXX 2.5 event hack */
							val = event->x - ar->winrct.xmin;
							mousedevice->ConvertBlenderEvent(MOUSEX, val);
							
							val = ar->winy - (event->y - ar->winrct.ymin) - 1;
							mousedevice->ConvertBlenderEvent(MOUSEY, val);
						}
						else {
							mousedevice->ConvertBlenderEvent(event->type,event->val);
						}
						
						BLI_remlink(&win->queue, event);
						wm_event_free(event);
					}
					
					if(win != CTX_wm_window(C)) {
						exitrequested= KX_EXIT_REQUEST_OUTSIDE; /* window closed while bge runs */
					}
				}
				printf("Blender Game Engine Finished\n");
				exitstring = ketsjiengine->GetExitString();
				gs = *(ketsjiengine->GetGlobalSettings());


				// when exiting the mainloop
#ifdef WITH_PYTHON
				// Clears the dictionary by hand:
				// This prevents, extra references to global variables
				// inside the GameLogic dictionary when the python interpreter is finalized.
				// which allows the scene to safely delete them :)
				// see: (space.c)->start_game
				
				//PyDict_Clear(PyModule_GetDict(gameLogic));
				
				// Keep original items, means python plugins will autocomplete members
				PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic));
				const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new);
				Py_ssize_t listIndex;
				for (listIndex=0; listIndex < numitems; listIndex++)  {
					PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex);
					if (!PySequence_Contains(gameLogic_keys, item)) {
						PyDict_DelItem(	PyModule_GetDict(gameLogic), item);
					}
				}
				Py_DECREF(gameLogic_keys_new);
				gameLogic_keys_new = NULL;
#endif
				ketsjiengine->StopEngine();
#ifdef WITH_PYTHON
				exitGamePythonScripting();
#endif
				networkdevice->Disconnect();
			}
			if (sceneconverter)
			{
				delete sceneconverter;
				sceneconverter = NULL;
			}

#ifdef WITH_PYTHON
			Py_DECREF(gameLogic_keys);
			gameLogic_keys = NULL;
#endif
		}
		//lock frame and camera enabled - restoring global values
		if (v3d->scenelock==0){
			startscene->lay= tmp_lay;
			startscene->camera= tmp_camera;
		}

		if(exitrequested != KX_EXIT_REQUEST_OUTSIDE)
		{
			// set the cursor back to normal
			canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
		}
		
		// clean up some stuff
		if (ketsjiengine)
		{
			delete ketsjiengine;
			ketsjiengine = NULL;
		}
		if (kxsystem)
		{
			delete kxsystem;
			kxsystem = NULL;
		}
		if (networkdevice)
		{
			delete networkdevice;
			networkdevice = NULL;
		}
		if (keyboarddevice)
		{
			delete keyboarddevice;
			keyboarddevice = NULL;
		}
		if (mousedevice)
		{
			delete mousedevice;
			mousedevice = NULL;
		}
		if (rasterizer)
		{
			delete rasterizer;
			rasterizer = NULL;
		}
		if (rendertools)
		{
			delete rendertools;
			rendertools = NULL;
		}
		if (canvas)
		{
			delete canvas;
			canvas = NULL;
		}

		// stop all remaining playing sounds
		AUD_getDevice()->stopAll();
	
	} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
	
	if (!disableVBO)
		U.gameflags &= ~USER_DISABLE_VBO;

	if (bfd) BLO_blendfiledata_free(bfd);

	BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name));

#ifdef WITH_PYTHON
	Py_DECREF(pyGlobalDict);

	// Release Python's GIL
	PyGILState_Release(gilstate);
#endif

}
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing)
{
	/* context values */
	struct wmWindowManager *wm= CTX_wm_manager(C);
	struct wmWindow *win= CTX_wm_window(C);
	struct Scene *startscene= CTX_data_scene(C);
	struct Main* maggie1= CTX_data_main(C);


	RAS_Rect area_rect;
	area_rect.SetLeft(cam_frame->xmin);
	area_rect.SetBottom(cam_frame->ymin);
	area_rect.SetRight(cam_frame->xmax);
	area_rect.SetTop(cam_frame->ymax);

	int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
	Main* blenderdata = maggie1;

	char* startscenename = startscene->id.name+2;
	char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE];
	STR_String exitstring = "";
	BlendFileData *bfd= NULL;

	BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
	BLI_strncpy(oldsce, G.main->name, sizeof(oldsce));
#ifdef WITH_PYTHON
	resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path
	setGamePythonPath(G.main->name);

	// Acquire Python's GIL (global interpreter lock)
	// so we can safely run Python code and API calls
	PyGILState_STATE gilstate = PyGILState_Ensure();
	
	PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
#endif
	
	bgl::InitExtensions(true);

	// VBO code for derived mesh is not compatible with BGE (couldn't find why), so disable
	int disableVBO = (U.gameflags & USER_DISABLE_VBO);
	U.gameflags |= USER_DISABLE_VBO;

	// Globals to be carried on over blender files
	GlobalSettings gs;
	gs.matmode= startscene->gm.matmode;
	gs.glslflag= startscene->gm.flag;

	do
	{
		View3D *v3d= CTX_wm_view3d(C);
		RegionView3D *rv3d= CTX_wm_region_view3d(C);

		// get some preferences
		SYS_SystemHandle syshandle = SYS_GetSystem();
		bool properties	= (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
		bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
		bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
		bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
		bool animation_record = (SYS_GetCommandLineInt(syshandle, "animation_record", 0) != 0);
		bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0) && GPU_display_list_support();
#ifdef WITH_PYTHON
		bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
#endif
		// bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
		bool mouse_state = (startscene->gm.flag & GAME_SHOW_MOUSE) != 0;
		bool restrictAnimFPS = (startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES) != 0;

		short drawtype = v3d->drawtype;
		
		/* we do not support material mode in game engine, force change to texture mode */
		if (drawtype == OB_MATERIAL) drawtype = OB_TEXTURE;
		if (animation_record) usefixed= false; /* override since you don't want to run full-speed for sim recording */

		// create the canvas and rasterizer
		RAS_ICanvas* canvas = new KX_BlenderCanvas(wm, win, area_rect, ar);
		
		// default mouse state set on render panel
		if (mouse_state)
			canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
		else
			canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);

		// Setup vsync
		int previous_vsync = 0;
		canvas->GetSwapInterval(previous_vsync);
		if (startscene->gm.vsync == VSYNC_ADAPTIVE)
			canvas->SetSwapInterval(-1);
		else
			canvas->SetSwapInterval((startscene->gm.vsync == VSYNC_ON) ? 1 : 0);

		RAS_IRasterizer* rasterizer = NULL;
		//Don't use displaylists with VBOs
		//If auto starts using VBOs, make sure to check for that here
		if (displaylists && startscene->gm.raster_storage != RAS_STORE_VBO)
			rasterizer = new RAS_ListRasterizer(canvas, true, startscene->gm.raster_storage);
		else
			rasterizer = new RAS_OpenGLRasterizer(canvas, startscene->gm.raster_storage);

		RAS_IRasterizer::MipmapOption mipmapval = rasterizer->GetMipmapping();

		
		// create the inputdevices
		KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
		KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
		
		// create a networkdevice
		NG_NetworkDeviceInterface* networkdevice = new
			NG_LoopBackNetworkDeviceInterface();

		//
		// create a ketsji/blendersystem (only needed for timing and stuff)
		KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
		
		// create the ketsjiengine
		KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);
		
		// set the devices
		ketsjiengine->SetKeyboardDevice(keyboarddevice);
		ketsjiengine->SetMouseDevice(mousedevice);
		ketsjiengine->SetNetworkDevice(networkdevice);
		ketsjiengine->SetCanvas(canvas);
		ketsjiengine->SetRasterizer(rasterizer);
		ketsjiengine->SetUseFixedTime(usefixed);
		ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
		ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS);
		KX_KetsjiEngine::SetExitKey(ConvertKeyCode(startscene->gm.exitkey));

		//set the global settings (carried over if restart/load new files)
		ketsjiengine->SetGlobalSettings(&gs);

#ifdef WITH_PYTHON
		CValue::SetDeprecationWarnings(nodepwarnings);
#endif

		//lock frame and camera enabled - storing global values
		int tmp_lay= startscene->lay;
		Object *tmp_camera = startscene->camera;

		if (v3d->scenelock==0) {
			startscene->lay= v3d->lay;
			startscene->camera= v3d->camera;
		}

		// some blender stuff
		float camzoom;
		int draw_letterbox = 0;
		
		if (rv3d->persp==RV3D_CAMOB) {
			if (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */
				camzoom = 1.0f;
				draw_letterbox = 1;
			}
			else {
				camzoom = 1.0f / BKE_screen_view3d_zoom_to_fac(rv3d->camzoom);
			}
		}
		else {
			camzoom = 2.0;
		}

		rasterizer->SetDrawingMode(drawtype);
		ketsjiengine->SetCameraZoom(camzoom);
		
		// if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
		if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME)
		{
			exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
			if (bfd) BLO_blendfiledata_free(bfd);
			
			char basedpath[FILE_MAX];
			// base the actuator filename with respect
			// to the original file working directory

			if (exitstring != "")
				BLI_strncpy(basedpath, exitstring.ReadPtr(), sizeof(basedpath));

			// load relative to the last loaded file, this used to be relative
			// to the first file but that makes no sense, relative paths in
			// blend files should be relative to that file, not some other file
			// that happened to be loaded first
			BLI_path_abs(basedpath, pathname);
			bfd = load_game_data(basedpath);
			
			// if it wasn't loaded, try it forced relative
			if (!bfd)
			{
				// just add "//" in front of it
				char temppath[FILE_MAX] = "//";
				BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2);
				
				BLI_path_abs(temppath, pathname);
				bfd = load_game_data(temppath);
			}
			
			// if we got a loaded blendfile, proceed
			if (bfd)
			{
				blenderdata = bfd->main;
				startscenename = bfd->curscene->id.name + 2;

				if (blenderdata) {
					BLI_strncpy(G.main->name, blenderdata->name, sizeof(G.main->name));
					BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
#ifdef WITH_PYTHON
					setGamePythonPath(G.main->name);
#endif
				}
			}
			// else forget it, we can't find it
			else
			{
				exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
			}
		}

		Scene *scene= bfd ? bfd->curscene : (Scene *)BLI_findstring(&blenderdata->scene, startscenename, offsetof(ID, name) + 2);

		if (scene)
		{
			int startFrame = scene->r.cfra;
			ketsjiengine->SetAnimRecordMode(animation_record, startFrame);
			
			// Quad buffered needs a special window.
			if (scene->gm.stereoflag == STEREO_ENABLED) {
				if (scene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
					rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) scene->gm.stereomode);

				rasterizer->SetEyeSeparation(scene->gm.eyeseparation);
			}

			rasterizer->SetBackColor(scene->gm.framing.col);
		}
		
		if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
		{
			if (rv3d->persp != RV3D_CAMOB)
			{
				ketsjiengine->EnableCameraOverride(startscenename);
				ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO));
				ketsjiengine->SetCameraOverrideProjectionMatrix(MT_CmMatrix4x4(rv3d->winmat));
				ketsjiengine->SetCameraOverrideViewMatrix(MT_CmMatrix4x4(rv3d->viewmat));
				ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
				ketsjiengine->SetCameraOverrideLens(v3d->lens);
			}
			
			// create a scene converter, create and convert the startingscene
			KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
			ketsjiengine->SetSceneConverter(sceneconverter);
			if (always_use_expand_framing)
				sceneconverter->SetAlwaysUseExpandFraming(true);

			bool usemat = false, useglslmat = false;

			if (GLEW_ARB_multitexture && GLEW_VERSION_1_1)
				usemat = true;

			if (GPU_glsl_support())
				useglslmat = true;
			else if (gs.matmode == GAME_MAT_GLSL)
				usemat = false;

			if (usemat)
				sceneconverter->SetMaterials(true);
			if (useglslmat && (gs.matmode == GAME_MAT_GLSL))
				sceneconverter->SetGLSLMaterials(true);
			if (scene->gm.flag & GAME_NO_MATERIAL_CACHING)
				sceneconverter->SetCacheMaterials(false);
					
			KX_Scene* startscene = new KX_Scene(keyboarddevice,
				mousedevice,
				networkdevice,
				startscenename,
				scene,
				canvas);

#ifdef WITH_PYTHON
			// some python things
			PyObject *gameLogic, *gameLogic_keys;
			setupGamePython(ketsjiengine, startscene, blenderdata, pyGlobalDict, &gameLogic, &gameLogic_keys, 0, NULL);
#endif // WITH_PYTHON

			//initialize Dome Settings
			if (scene->gm.stereoflag == STEREO_DOME)
				ketsjiengine->InitDome(scene->gm.dome.res, scene->gm.dome.mode, scene->gm.dome.angle, scene->gm.dome.resbuf, scene->gm.dome.tilt, scene->gm.dome.warptext);

			// initialize 3D Audio Settings
			AUD_I3DDevice* dev = AUD_get3DDevice();
			if (dev)
			{
				dev->setSpeedOfSound(scene->audio.speed_of_sound);
				dev->setDopplerFactor(scene->audio.doppler_factor);
				dev->setDistanceModel(AUD_DistanceModel(scene->audio.distance_model));
			}

			// from see blender.c:
			// FIXME: this version patching should really be part of the file-reading code,
			// but we still get too many unrelated data-corruption crashes otherwise...
			if (blenderdata->versionfile < 250)
				do_versions_ipos_to_animato(blenderdata);

			if (sceneconverter)
			{
				// convert and add scene
				sceneconverter->ConvertScene(
					startscene,
				    rasterizer,
					canvas);
				ketsjiengine->AddScene(startscene);
				
				// init the rasterizer
				rasterizer->Init();
				
				// start the engine
				ketsjiengine->StartEngine(true);
				

				// Set the animation playback rate for ipo's and actions
				// the framerate below should patch with FPS macro defined in blendef.h
				// Could be in StartEngine set the framerate, we need the scene to do this
				ketsjiengine->SetAnimFrameRate(FPS);
				
#ifdef WITH_PYTHON
				char *python_main = NULL;
				pynextframestate.state = NULL;
				pynextframestate.func = NULL;
				python_main = KX_GetPythonMain(scene);

				// the mainloop
				printf("\nBlender Game Engine Started\n");
				if (python_main) {
					char *python_code = KX_GetPythonCode(blenderdata, python_main);
					if (python_code) {
						ketsjinextframestate.ketsjiengine = ketsjiengine;
						ketsjinextframestate.C = C;
						ketsjinextframestate.win = win;
						ketsjinextframestate.scene = scene;
						ketsjinextframestate.ar = ar;
						ketsjinextframestate.keyboarddevice = keyboarddevice;
						ketsjinextframestate.mousedevice = mousedevice;
						ketsjinextframestate.draw_letterbox = draw_letterbox;
			
						pynextframestate.state = &ketsjinextframestate;
						pynextframestate.func = &BL_KetsjiPyNextFrame;
						printf("Yielding control to Python script '%s'...\n", python_main);
						PyRun_SimpleString(python_code);
						printf("Exit Python script '%s'\n", python_main);
						MEM_freeN(python_code);
					}
				}
				else
#endif  /* WITH_PYTHON */
				{
					while (!exitrequested)
					{
						exitrequested = BL_KetsjiNextFrame(ketsjiengine, C, win, scene, ar, keyboarddevice, mousedevice, draw_letterbox);
					}
				}
				printf("Blender Game Engine Finished\n");
				exitstring = ketsjiengine->GetExitString();
#ifdef WITH_PYTHON
				if (python_main) MEM_freeN(python_main);
#endif  /* WITH_PYTHON */

				gs = *(ketsjiengine->GetGlobalSettings());

				// when exiting the mainloop
#ifdef WITH_PYTHON
				// Clears the dictionary by hand:
				// This prevents, extra references to global variables
				// inside the GameLogic dictionary when the python interpreter is finalized.
				// which allows the scene to safely delete them :)
				// see: (space.c)->start_game
				
				//PyDict_Clear(PyModule_GetDict(gameLogic));
				
				// Keep original items, means python plugins will autocomplete members
				PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic));
				const Py_ssize_t numitems= PyList_GET_SIZE(gameLogic_keys_new);
				Py_ssize_t listIndex;
				for (listIndex=0; listIndex < numitems; listIndex++) {
					PyObject *item = PyList_GET_ITEM(gameLogic_keys_new, listIndex);
					if (!PySequence_Contains(gameLogic_keys, item)) {
						PyDict_DelItem(	PyModule_GetDict(gameLogic), item);
					}
				}
				Py_DECREF(gameLogic_keys_new);
				gameLogic_keys_new = NULL;
#endif
				ketsjiengine->StopEngine();
#ifdef WITH_PYTHON
				exitGamePythonScripting();
#endif
				networkdevice->Disconnect();
			}
			if (sceneconverter)
			{
				delete sceneconverter;
				sceneconverter = NULL;
			}

#ifdef WITH_PYTHON
			Py_DECREF(gameLogic_keys);
			gameLogic_keys = NULL;
#endif
		}
		//lock frame and camera enabled - restoring global values
		if (v3d->scenelock==0) {
			startscene->lay= tmp_lay;
			startscene->camera= tmp_camera;
		}

		if (exitrequested != KX_EXIT_REQUEST_OUTSIDE)
		{
			// set the cursor back to normal
			canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);

			// set mipmap setting back to its original value
			rasterizer->SetMipmapping(mipmapval);
		}
		
		// clean up some stuff
		if (ketsjiengine)
		{
			delete ketsjiengine;
			ketsjiengine = NULL;
		}
		if (kxsystem)
		{
			delete kxsystem;
			kxsystem = NULL;
		}
		if (networkdevice)
		{
			delete networkdevice;
			networkdevice = NULL;
		}
		if (keyboarddevice)
		{
			delete keyboarddevice;
			keyboarddevice = NULL;
		}
		if (mousedevice)
		{
			delete mousedevice;
			mousedevice = NULL;
		}
		if (rasterizer)
		{
			delete rasterizer;
			rasterizer = NULL;
		}
		if (canvas)
		{
			canvas->SetSwapInterval(previous_vsync); // Set the swap interval back
			delete canvas;
			canvas = NULL;
		}

		// stop all remaining playing sounds
		AUD_getDevice()->stopAll();
	
	} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
	
	if (!disableVBO)
		U.gameflags &= ~USER_DISABLE_VBO;

	if (bfd) BLO_blendfiledata_free(bfd);

	BLI_strncpy(G.main->name, oldsce, sizeof(G.main->name));

#ifdef WITH_PYTHON
	Py_DECREF(pyGlobalDict);

	// Release Python's GIL
	PyGILState_Release(gilstate);
#endif

}
Beispiel #4
0
int main(int argc, const char **argv)
#endif
{
	bContext *C = CTX_create();
	SYS_SystemHandle syshandle;

#ifndef WITH_PYTHON_MODULE
	bArgs *ba;
#endif

#ifdef WIN32
	wchar_t **argv_16 = CommandLineToArgvW(GetCommandLineW(), &argc);
	int argci = 0;
	char **argv = MEM_mallocN(argc * sizeof(char *), "argv array");
	for (argci = 0; argci < argc; argci++) {
		argv[argci] = alloc_utf_8_from_16(argv_16[argci], 0);
	}
	LocalFree(argv_16);
#endif

#ifdef WITH_PYTHON_MODULE
#ifdef __APPLE__
	environ = *_NSGetEnviron();
#endif

#undef main
	evil_C = C;
#endif



#ifdef WITH_BINRELOC
	br_init(NULL);
#endif

#ifdef WITH_LIBMV
	libmv_initLogging(argv[0]);
#endif

	setCallbacks();
#if defined(__APPLE__) && !defined(WITH_PYTHON_MODULE)
	/* patch to ignore argument finder gives us (pid?) */
	if (argc == 2 && strncmp(argv[1], "-psn_", 5) == 0) {
		extern int GHOST_HACK_getFirstFile(char buf[]);
		static char firstfilebuf[512];

		argc = 1;

		if (GHOST_HACK_getFirstFile(firstfilebuf)) {
			argc = 2;
			argv[1] = firstfilebuf;
		}
	}

#endif

#ifdef __FreeBSD__
	fpsetmask(0);
#endif

	/* initialize path to executable */
	BLI_init_program_path(argv[0]);

	BLI_threadapi_init();

	initglobals();  /* blender.c */

	IMB_init();
	BKE_images_init();

	BKE_brush_system_init();

	BLI_callback_global_init();

#ifdef WITH_GAMEENGINE
	syshandle = SYS_GetSystem();
#else
	syshandle = 0;
#endif

	/* first test for background */
#ifndef WITH_PYTHON_MODULE
	ba = BLI_argsInit(argc, (const char **)argv); /* skip binary path */
	setupArguments(C, ba, &syshandle);

	BLI_argsParse(ba, 1, NULL, NULL);

	if (use_crash_handler) {
		/* after parsing args */
		signal(SIGSEGV, blender_crash_handler);
	}
#else
	G.factory_startup = true;  /* using preferences or user startup makes no sense for py-as-module */
	(void)syshandle;
#endif

#ifdef WITH_FFMPEG
	IMB_ffmpeg_init();
#endif

	/* after level 1 args, this is so playanim skips RNA init */
	RNA_init();

	RE_engines_init();
	init_nodesystem();
	/* end second init */


#if defined(WITH_PYTHON_MODULE) || defined(WITH_HEADLESS)
	G.background = true; /* python module mode ALWAYS runs in background mode (for now) */
#else
	/* for all platforms, even windos has it! */
	if (G.background) {
		signal(SIGINT, blender_esc);  /* ctrl c out bg render */
	}
#endif

	/* background render uses this font too */
	BKE_vfont_builtin_register(datatoc_bfont_pfb, datatoc_bfont_pfb_size);

	/* Initialize ffmpeg if built in, also needed for bg mode if videos are
	 * rendered via ffmpeg */
	sound_init_once();
	
	init_def_material();

	if (G.background == 0) {
#ifndef WITH_PYTHON_MODULE
		BLI_argsParse(ba, 2, NULL, NULL);
		BLI_argsParse(ba, 3, NULL, NULL);
#endif
		WM_init(C, argc, (const char **)argv);

		/* this is properly initialized with user defs, but this is default */
		/* call after loading the startup.blend so we can read U.tempdir */
		BLI_init_temporary_dir(U.tempdir);

#ifdef WITH_SDL
		BLI_setenv("SDL_VIDEODRIVER", "dummy");
#endif
	}
	else {
#ifndef WITH_PYTHON_MODULE
		BLI_argsParse(ba, 3, NULL, NULL);
#endif

		WM_init(C, argc, (const char **)argv);

		/* don't use user preferences temp dir */
		BLI_init_temporary_dir(NULL);
	}
#ifdef WITH_PYTHON
	/**
	 * NOTE: the U.pythondir string is NULL until WM_init() is executed,
	 * so we provide the BPY_ function below to append the user defined
	 * python-dir to Python's sys.path at this point.  Simply putting
	 * WM_init() before #BPY_python_start() crashes Blender at startup.
	 */

	/* TODO - U.pythondir */
#else
	printf("\n* WARNING * - Blender compiled without Python!\nthis is not intended for typical usage\n\n");
#endif
	
	CTX_py_init_set(C, 1);
	WM_keymap_init(C);

#ifdef WITH_FREESTYLE
	/* initialize Freestyle */
	FRS_initialize();
	FRS_set_context(C);
#endif

	/* OK we are ready for it */
#ifndef WITH_PYTHON_MODULE
	BLI_argsParse(ba, 4, load_file, C);
	
	if (G.background == 0) {
		if (!G.file_loaded)
			if (U.uiflag2 & USER_KEEP_SESSION)
				WM_recover_last_session(C, NULL);
	}

#endif

#ifndef WITH_PYTHON_MODULE
	BLI_argsFree(ba);
#endif

#ifdef WIN32
	while (argci) {
		free(argv[--argci]);
	}
	MEM_freeN(argv);
	argv = NULL;
#endif

#ifdef WITH_PYTHON_MODULE
	return 0; /* keep blender in background mode running */
#endif

	if (G.background) {
		/* actually incorrect, but works for now (ton) */
		WM_exit(C);
	}
	else {
		if (G.fileflags & G_FILE_AUTOPLAY) {
			if (G.f & G_SCRIPT_AUTOEXEC) {
				if (WM_init_game(C)) {
					return 0;
				}
			}
			else {
				if (!(G.f & G_SCRIPT_AUTOEXEC_FAIL_QUIET)) {
					G.f |= G_SCRIPT_AUTOEXEC_FAIL;
					BLI_snprintf(G.autoexec_fail, sizeof(G.autoexec_fail), "Game AutoStart");
				}
			}
		}

		if (!G.file_loaded) {
			WM_init_splash(C);
		}
	}

	WM_main(C);

	return 0;
} /* end of int main(argc, argv)	*/
Beispiel #5
0
/**
 * \note doesn't run exit() call #WM_exit() for that.
 */
void WM_exit_ext(bContext *C, const bool do_python)
{
	wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL;

	/* first wrap up running stuff, we assume only the active WM is running */
	/* modal handlers are on window level freed, others too? */
	/* note; same code copied in wm_files.c */
	if (C && wm) {
		wmWindow *win;

		if (!G.background) {
			struct MemFile *undo_memfile = wm->undo_stack ? ED_undosys_stack_memfile_get_active(wm->undo_stack) : NULL;
			if ((U.uiflag2 & USER_KEEP_SESSION) || (undo_memfile != NULL)) {
				/* save the undo state as quit.blend */
				char filename[FILE_MAX];
				bool has_edited;
				int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_HISTORY);

				BLI_make_file_string("/", filename, BKE_tempdir_base(), BLENDER_QUIT_FILE);

				has_edited = ED_editors_flush_edits(C, false);

				if ((has_edited && BLO_write_file(CTX_data_main(C), filename, fileflags, NULL, NULL)) ||
				    (undo_memfile && BLO_memfile_write_file(undo_memfile, filename)))
				{
					printf("Saved session recovery to '%s'\n", filename);
				}
			}
		}

		WM_jobs_kill_all(wm);

		for (win = wm->windows.first; win; win = win->next) {

			CTX_wm_window_set(C, win);  /* needed by operator close callbacks */
			WM_event_remove_handlers(C, &win->handlers);
			WM_event_remove_handlers(C, &win->modalhandlers);
			ED_screen_exit(C, win, win->screen);
		}
	}

	BKE_addon_pref_type_free();
	wm_operatortype_free();
	wm_dropbox_free();
	WM_menutype_free();
	WM_uilisttype_free();

	/* all non-screen and non-space stuff editors did, like editmode */
	if (C)
		ED_editors_exit(C);

	ED_undosys_type_free();

//	XXX
//	BIF_GlobalReebFree();
//	BIF_freeRetarget();
	BIF_freeTemplates(C);

	free_openrecent();

	BKE_mball_cubeTable_free();

	/* render code might still access databases */
	RE_FreeAllRender();
	RE_engines_exit();

	ED_preview_free_dbase();  /* frees a Main dbase, before BKE_blender_free! */

	if (C && wm)
		wm_free_reports(C);  /* before BKE_blender_free! - since the ListBases get freed there */

	BKE_sequencer_free_clipboard(); /* sequencer.c */
	BKE_tracking_clipboard_free();
	BKE_mask_clipboard_free();
	BKE_vfont_clipboard_free();

#ifdef WITH_COMPOSITOR
	COM_deinitialize();
#endif

	BKE_blender_free();  /* blender.c, does entire library and spacetypes */
//	free_matcopybuf();
	ANIM_fcurves_copybuf_free();
	ANIM_drivers_copybuf_free();
	ANIM_driver_vars_copybuf_free();
	ANIM_fmodifiers_copybuf_free();
	ED_gpencil_anim_copybuf_free();
	ED_gpencil_strokes_copybuf_free();
	BKE_node_clipboard_clear();

	BLF_exit();

#ifdef WITH_INTERNATIONAL
	BLF_free_unifont();
	BLF_free_unifont_mono();
	BLT_lang_free();
#endif

	ANIM_keyingset_infos_exit();

//	free_txt_data();


#ifdef WITH_PYTHON
	/* option not to close python so we can use 'atexit' */
	if (do_python && ((C == NULL) || CTX_py_init_get(C))) {
		/* XXX - old note */
		/* before BKE_blender_free so py's gc happens while library still exists */
		/* needed at least for a rare sigsegv that can happen in pydrivers */

		/* Update for blender 2.5, move after BKE_blender_free because blender now holds references to PyObject's
		 * so decref'ing them after python ends causes bad problems every time
		 * the pyDriver bug can be fixed if it happens again we can deal with it then */
		BPY_python_end();
	}
#else
	(void)do_python;
#endif

	if (!G.background) {
#ifdef WITH_OPENSUBDIV
		BKE_subsurf_osd_cleanup();
#endif

		GPU_global_buffer_pool_free();
		GPU_free_unused_buffers(G_MAIN);

		GPU_exit();
	}

	ED_file_exit(); /* for fsmenu */

	UI_exit();
	BKE_blender_userdef_data_free(&U, false);

	RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */

	wm_ghost_exit();

	CTX_free(C);
#ifdef WITH_GAMEENGINE
	SYS_DeleteSystem(SYS_GetSystem());
#endif

	GHOST_DisposeSystemPaths();

	DNA_sdna_current_free();

	BLI_threadapi_exit();

	/* No need to call this early, rather do it late so that other pieces of Blender using sound may exit cleanly,
	 * see also T50676. */
	BKE_sound_exit();

	CLG_exit();

	BKE_blender_atexit();

	if (MEM_get_memory_blocks_in_use() != 0) {
		size_t mem_in_use = MEM_get_memory_in_use() + MEM_get_memory_in_use();
		printf("Error: Not freed memory blocks: %u, total unfreed memory %f MB\n",
		       MEM_get_memory_blocks_in_use(),
		       (double)mem_in_use / 1024 / 1024);
		MEM_printmemlist();
	}
	wm_autosave_delete();

	BKE_tempdir_session_purge();
}
Beispiel #6
0
int main(int argc, char** argv)
{
    int i;
    int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
    bool error = false;
    SYS_SystemHandle syshandle = SYS_GetSystem();
    bool fullScreen = false;
    bool fullScreenParFound = false;
    bool windowParFound = false;
#ifdef WIN32
    bool closeConsole = true;
#endif
    RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
    bool stereoWindow = false;
    bool stereoParFound = false;
    int stereoFlag = STEREO_NOSTEREO;
    int domeFov = -1;
    int domeTilt = -200;
    int domeMode = 0;
    char* domeWarp = NULL;
    Text *domeText  = NULL;
    int windowLeft = 100;
    int windowTop = 100;
    int windowWidth = 640;
    int windowHeight = 480;
    GHOST_TUns32 fullScreenWidth = 0;
    GHOST_TUns32 fullScreenHeight= 0;
    int fullScreenBpp = 32;
    int fullScreenFrequency = 60;
    GHOST_TEmbedderWindowID parentWindow = 0;
    bool isBlenderPlayer = false; //true when lauching from blender or command line. false for bundled player
    int validArguments=0;
    bool samplesParFound = false;
    GHOST_TUns16 aasamples = 0;

#ifdef __linux__
#ifdef __alpha__
    signal (SIGFPE, SIG_IGN);
#endif /* __alpha__ */
#endif /* __linux__ */

#ifdef WITH_SDL_DYNLOAD
    sdlewInit();
#endif

    BKE_appdir_program_path_init(argv[0]);
    BKE_tempdir_init(NULL);

    // We don't use threads directly in the BGE, but we need to call this so things like
    // freeing up GPU_Textures works correctly.
    BLI_threadapi_init();

    RNA_init();

    init_nodesystem();

    initglobals();

    U.gameflags |= USER_DISABLE_VBO;
    // We load our own G.main, so free the one that initglobals() gives us
    BKE_main_free(G.main);
    G.main = NULL;

    MEM_CacheLimiter_set_disabled(true);
    IMB_init();
    BKE_images_init();
    BKE_modifier_init();
    DAG_init();

#ifdef WITH_FFMPEG
    IMB_ffmpeg_init();
#endif

    // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
    BLF_init(11, U.dpi);
    BLF_lang_init();
    BLF_lang_set("");

    BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);
    if (blf_mono_font == -1)
        blf_mono_font = BLF_load_mem_unique("monospace", (unsigned char*)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);

    // Parse command line options
#if defined(DEBUG)
    printf("argv[0] = '%s'\n", argv[0]);
#endif

#ifdef WIN32
    if (scr_saver_init(argc, argv))
    {
        switch (scr_saver_mode)
        {
        case SCREEN_SAVER_MODE_CONFIGURATION:
            MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
            break;
        case SCREEN_SAVER_MODE_PASSWORD:
        /* This is W95 only, which we currently do not support.
         * Fall-back to normal screen saver behavior in that case... */
        case SCREEN_SAVER_MODE_SAVER:
            fullScreen = true;
            fullScreenParFound = true;
            break;

        case SCREEN_SAVER_MODE_PREVIEW:
            /* This will actually be handled somewhere below... */
            break;
        }
    }
#endif
    // XXX add the ability to change this values to the command line parsing.
    U.mixbufsize = 2048;
    U.audiodevice = 2;
    U.audiorate = 44100;
    U.audioformat = 0x24;
    U.audiochannels = 2;

    // XXX this one too
    U.anisotropic_filter = 2;
    // enable fast mipmap generation
    U.use_gpu_mipmap = 1;

    sound_init_once();

    set_free_windowmanager_cb(wm_free);

    /* if running blenderplayer the last argument can't be parsed since it has to be the filename. else it is bundled */
    isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
    if (isBlenderPlayer)
        validArguments = argc - 1;
    else
        validArguments = argc;


    /* Parsing command line arguments (can be set from WM_OT_blenderplayer_start) */
#if defined(DEBUG)
    printf("Parsing command line arguments...\n");
    printf("Num of arguments is: %i\n", validArguments-1); //-1 because i starts at 1
#endif

    for (i = 1; (i < validArguments) && !error
#ifdef WIN32
            && scr_saver_mode == SCREEN_SAVER_MODE_NONE
#endif
            ;)

    {
#if defined(DEBUG)
        printf("argv[%d] = '%s'\n", i, argv[i]);
#endif
        if (argv[i][0] == '-')
        {
            /* ignore all args after " - ", allow python to have own args */
            if (argv[i][1]=='\0') {
                argc_py_clamped= i;
                break;
            }

            switch (argv[i][1])
            {
            case 'g': //game engine options (show_framerate, fixedtime, etc)
            {
                i++;
                if (i <= validArguments)
                {
                    char* paramname = argv[i];
                    // Check for single value versus assignment
                    if (i+1 <= validArguments && (*(argv[i+1]) == '='))
                    {
                        i++;
                        if (i + 1 <= validArguments)
                        {
                            i++;
                            // Assignment
                            SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
                            SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
                            SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
#if defined(DEBUG)
                            printf("%s = '%s'\n", paramname, argv[i]);
#endif
                            i++;
                        }
                        else
                        {
                            error = true;
                            printf("error: argument assignment %s without value.\n", paramname);
                        }
                    }
                    else
                    {
//						SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
                    }
                }
                break;
            }
            case 'd': //debug on
            {
                i++;
                G.debug |= G_DEBUG;
                MEM_set_memory_debug();
#ifdef DEBUG
                BLI_mempool_set_memory_debug();
#endif
                break;
            }
            case 'f': //fullscreen mode
            {
                i++;
                fullScreen = true;
                fullScreenParFound = true;
                if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    fullScreenWidth = atoi(argv[i++]);
                    fullScreenHeight = atoi(argv[i++]);
                    if ((i + 1) <= validArguments && argv[i][0] != '-')
                    {
                        fullScreenBpp = atoi(argv[i++]);
                        if ((i + 1) <= validArguments && argv[i][0] != '-')
                            fullScreenFrequency = atoi(argv[i++]);
                    }
                }
                else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    error = true;
                    printf("error: to define fullscreen width or height, both options must be used.\n");
                }
                break;
            }
            case 'w': //display in a window
            {
                i++;
                fullScreen = false;
                windowParFound = true;

                // Parse window position and size options
                if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    windowWidth = atoi(argv[i++]);
                    windowHeight = atoi(argv[i++]);

                    if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                    {
                        windowLeft = atoi(argv[i++]);
                        windowTop = atoi(argv[i++]);
                    }
                    else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                    {
                        error = true;
                        printf("error: to define the window left or right coordinates, both options must be used.\n");
                    }
                }
                else if ((i + 1) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    error = true;
                    printf("error: to define the window's width or height, both options must be used.\n");
                }
                break;
            }
            case 'h': //display help
            {
                usage(argv[0], isBlenderPlayer);
                return 0;
                break;
            }
            case 'i': //parent window ID
            {
                i++;
                if ( (i + 1) <= validArguments )
                    parentWindow = atoi(argv[i++]);
                else {
                    error = true;
                    printf("error: too few options for parent window argument.\n");
                }
#if defined(DEBUG)
                printf("XWindows ID = %d\n", parentWindow);
#endif // defined(DEBUG)
                break;
            }
            case 'm': //maximum anti-aliasing (eg. 2,4,8,16)
            {
                i++;
                samplesParFound = true;
                if ((i+1) <= validArguments )
                    aasamples = atoi(argv[i++]);
                else
                {
                    error = true;
                    printf("error: No argument supplied for -m");
                }
                break;
            }
            case 'c': //keep console (windows only)
            {
                i++;
#ifdef WIN32
                closeConsole = false;
#endif
                break;
            }
            case 's': //stereo mode
            {
                i++;
                if ((i + 1) <= validArguments)
                {
                    stereoParFound = true;
                    stereoFlag = STEREO_ENABLED;

                    if (!strcmp(argv[i], "nostereo"))  // may not be redundant if the file has different setting
                    {
                        stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
                        stereoFlag = STEREO_NOSTEREO;
                    }

                    // only the hardware pageflip method needs a stereo window
                    else if (!strcmp(argv[i], "hwpageflip")) {
                        stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
                        stereoWindow = true;
                    }
                    else if (!strcmp(argv[i], "syncdoubling"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;

                    else if (!strcmp(argv[i], "3dtvtopbottom"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_3DTVTOPBOTTOM;

                    else if (!strcmp(argv[i], "anaglyph"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;

                    else if (!strcmp(argv[i], "sidebyside"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;

                    else if (!strcmp(argv[i], "interlace"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_INTERLACED;

                    else if (!strcmp(argv[i], "vinterlace"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;

#if 0
//					// future stuff
//					else if (!strcmp(argv[i], "stencil")
//						stereomode = RAS_STEREO_STENCIL;
#endif
                    else
                    {
                        error = true;
                        printf("error: stereomode '%s' unrecognized.\n", argv[i]);
                    }

                    i++;
                }
                else
                {
                    error = true;
                    printf("error: too few options for stereo argument.\n");
                }
                break;
            }
            case 'D': //dome mode
            {
                stereoFlag = STEREO_DOME;
                stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
                i++;
                if ((i + 1) <= validArguments)
                {
                    if (!strcmp(argv[i], "angle")) {
                        i++;
                        domeFov = atoi(argv[i++]);
                    }
                    if (!strcmp(argv[i], "tilt")) {
                        i++;
                        domeTilt = atoi(argv[i++]);
                    }
                    if (!strcmp(argv[i], "warpdata")) {
                        i++;
                        domeWarp = argv[i++];
                    }
                    if (!strcmp(argv[i], "mode")) {
                        i++;
                        if (!strcmp(argv[i], "fisheye"))
                            domeMode = DOME_FISHEYE;

                        else if (!strcmp(argv[i], "truncatedfront"))
                            domeMode = DOME_TRUNCATED_FRONT;

                        else if (!strcmp(argv[i], "truncatedrear"))
                            domeMode = DOME_TRUNCATED_REAR;

                        else if (!strcmp(argv[i], "cubemap"))
                            domeMode = DOME_ENVMAP;

                        else if (!strcmp(argv[i], "sphericalpanoramic"))
                            domeMode = DOME_PANORAM_SPH;

                        else
                            printf("error: %s is not a valid dome mode.\n", argv[i]);
                    }
                    i++;
                }
                break;
            }
            default:  //not recognized
            {
                printf("Unknown argument: %s\n", argv[i++]);
                break;
            }
            }
        }
        else
        {
            i++;
        }
    }

    if ((windowWidth < kMinWindowWidth) || (windowHeight < kMinWindowHeight))
    {
        error = true;
        printf("error: window size too small.\n");
    }

    if (error )
    {
        usage(argv[0], isBlenderPlayer);
        return 0;
    }

#ifdef WIN32
    if (scr_saver_mode != SCREEN_SAVER_MODE_CONFIGURATION)
#endif
    {
        // Create the system
        if (GHOST_ISystem::createSystem() == GHOST_kSuccess) {
            GHOST_ISystem* system = GHOST_ISystem::getSystem();
            assertd(system);

            if (!fullScreenWidth || !fullScreenHeight)
                system->getMainDisplayDimensions(fullScreenWidth, fullScreenHeight);
            // process first batch of events. If the user
            // drops a file on top off the blenderplayer icon, we
            // receive an event with the filename

            system->processEvents(0);

            // this bracket is needed for app (see below) to get out
            // of scope before GHOST_ISystem::disposeSystem() is called.
            {
                int exitcode = KX_EXIT_REQUEST_NO_REQUEST;
                STR_String exitstring = "";
                GPG_Application app(system);
                bool firstTimeRunning = true;
                char filename[FILE_MAX];
                char pathname[FILE_MAX];
                char *titlename;

                get_filename(argc_py_clamped, argv, filename);
                if (filename[0])
                    BLI_path_cwd(filename);


                // fill the GlobalSettings with the first scene files
                // those may change during the game and persist after using Game Actuator
                GlobalSettings gs;

                do {
                    // Read the Blender file
                    BlendFileData *bfd;

                    // if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
                    if (exitcode == KX_EXIT_REQUEST_START_OTHER_GAME)
                    {
                        char basedpath[FILE_MAX];

                        // base the actuator filename relative to the last file
                        BLI_strncpy(basedpath, exitstring.Ptr(), sizeof(basedpath));
                        BLI_path_abs(basedpath, pathname);

                        bfd = load_game_data(basedpath);

                        if (!bfd) {
                            // just add "//" in front of it
                            char temppath[FILE_MAX] = "//";
                            BLI_strncpy(temppath + 2, basedpath, FILE_MAX - 2);

                            BLI_path_abs(temppath, pathname);
                            bfd = load_game_data(temppath);
                        }
                    }
                    else {
                        bfd = load_game_data(BKE_appdir_program_path(), filename[0]? filename: NULL);
                    }

#if defined(DEBUG)
                    printf("Game data loaded from %s\n", filename);
#endif

                    if (!bfd) {
                        usage(argv[0], isBlenderPlayer);
                        error = true;
                        exitcode = KX_EXIT_REQUEST_QUIT_GAME;
                    }
                    else {
                        /* Setting options according to the blend file if not overriden in the command line */
#ifdef WIN32
#if !defined(DEBUG)
                        if (closeConsole) {
                            system->toggleConsole(0); // Close a console window
                        }
#endif // !defined(DEBUG)
#endif // WIN32
                        Main *maggie = bfd->main;
                        Scene *scene = bfd->curscene;
                        G.main = maggie;

                        if (firstTimeRunning) {
                            G.fileflags  = bfd->fileflags;

                            gs.matmode= scene->gm.matmode;
                            gs.glslflag= scene->gm.flag;
                        }

                        //Seg Fault; icon.c gIcons == 0
                        BKE_icons_init(1);

                        titlename = maggie->name;

                        // Check whether the game should be displayed full-screen
                        if ((!fullScreenParFound) && (!windowParFound)) {
                            // Only use file settings when command line did not override
                            if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) {
                                //printf("fullscreen option found in Blender file\n");
                                fullScreen = true;
                                fullScreenWidth= scene->gm.xplay;
                                fullScreenHeight= scene->gm.yplay;
                                fullScreenFrequency= scene->gm.freqplay;
                                fullScreenBpp = scene->gm.depth;
                            }
                            else
                            {
                                fullScreen = false;
                                windowWidth = scene->gm.xplay;
                                windowHeight = scene->gm.yplay;
                            }
                        }


                        // Check whether the game should be displayed in stereo (dome included)
                        if (!stereoParFound) {
                            // Only use file settings when command line did not override
                            if (scene->gm.stereoflag == STEREO_ENABLED) {
                                stereomode = (RAS_IRasterizer::StereoMode) scene->gm.stereomode;
                                if (stereomode == RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
                                    stereoWindow = true;
                            }
                        }
                        else {
                            scene->gm.stereoflag = STEREO_ENABLED;
                        }

                        if (!samplesParFound)
                            aasamples = scene->gm.aasamples;

                        // Dome specific settings
                        if (stereoFlag == STEREO_DOME) {
                            stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
                            scene->gm.stereoflag = STEREO_DOME;
                            if (domeFov > 89)
                                scene->gm.dome.angle = domeFov;
                            if (domeTilt > -180)
                                scene->gm.dome.tilt = domeTilt;
                            if (domeMode > 0)
                                scene->gm.dome.mode = domeMode;
                            if (domeWarp) {
                                //XXX to do: convert relative to absolute path
                                domeText= BKE_text_load(G.main, domeWarp, "");
                                if (!domeText)
                                    printf("error: invalid warpdata text file - %s\n", domeWarp);
                                else
                                    scene->gm.dome.warptext = domeText;
                            }
                        }

                        //					GPG_Application app (system, maggie, startscenename);
                        app.SetGameEngineData(maggie, scene, &gs, argc, argv); /* this argc cant be argc_py_clamped, since python uses it */
                        BLI_strncpy(pathname, maggie->name, sizeof(pathname));
                        if (G.main != maggie) {
                            BLI_strncpy(G.main->name, maggie->name, sizeof(G.main->name));
                        }
#ifdef WITH_PYTHON
                        setGamePythonPath(G.main->name);
#endif
                        if (firstTimeRunning) {
                            firstTimeRunning = false;

                            if (fullScreen) {
#ifdef WIN32
                                if (scr_saver_mode == SCREEN_SAVER_MODE_SAVER)
                                {
                                    app.startScreenSaverFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
                                                                   stereoWindow, stereomode, aasamples);
                                }
                                else
#endif
                                {
                                    app.startFullScreen(fullScreenWidth, fullScreenHeight, fullScreenBpp, fullScreenFrequency,
                                                        stereoWindow, stereomode, aasamples, (scene->gm.playerflag & GAME_PLAYER_DESKTOP_RESOLUTION));
                                }
                            }
                            else
                            {
#ifdef __APPLE__
                                // on Mac's we'll show the executable name instead of the 'game.blend' name
                                char tempname[1024], *appstring;
                                ::strcpy(tempname, titlename);

                                appstring = strstr(tempname, ".app/");
                                if (appstring) {
                                    appstring[2] = 0;
                                    titlename = &tempname[0];
                                }
#endif
                                // Strip the path so that we have the name of the game file
                                STR_String path = titlename;
#ifndef WIN32
                                vector<STR_String> parts = path.Explode('/');
#else  // WIN32
                                vector<STR_String> parts = path.Explode('\\');
#endif // WIN32                        
                                STR_String title;
                                if (parts.size()) {
                                    title = parts[parts.size()-1];
                                    parts = title.Explode('.');
                                    if (parts.size() > 1)
                                    {
                                        title = parts[0];
                                    }
                                }
                                else {
                                    title = "blenderplayer";
                                }
#ifdef WIN32
                                if (scr_saver_mode == SCREEN_SAVER_MODE_PREVIEW)
                                {
                                    app.startScreenSaverPreview(scr_saver_hwnd, stereoWindow, stereomode, aasamples);
                                }
                                else
#endif
                                {
                                    if (parentWindow != 0)
                                        app.startEmbeddedWindow(title, parentWindow, stereoWindow, stereomode, aasamples);
                                    else
                                        app.startWindow(title, windowLeft, windowTop, windowWidth, windowHeight,
                                                        stereoWindow, stereomode, aasamples);

                                    if (SYS_GetCommandLineInt(syshandle, "nomipmap", 0)) {
                                        GPU_set_mipmap(0);
                                    }

                                    GPU_set_anisotropic(U.anisotropic_filter);
                                    GPU_set_gpu_mipmapping(U.use_gpu_mipmap);
                                }
                            }
                        }
                        else {
                            app.StartGameEngine(stereomode);
                            exitcode = KX_EXIT_REQUEST_NO_REQUEST;
                        }

                        // Add the application as event consumer
                        system->addEventConsumer(&app);

                        // Enter main loop
                        bool run = true;
                        char *python_main = NULL;
                        pynextframestate.state = NULL;
                        pynextframestate.func = NULL;
#ifdef WITH_PYTHON
                        python_main = KX_GetPythonMain(scene);
#endif // WITH_PYTHON
                        if (python_main) {
                            char *python_code = KX_GetPythonCode(maggie, python_main);
                            if (python_code) {
#ifdef WITH_PYTHON
                                gpg_nextframestate.system = system;
                                gpg_nextframestate.app = &app;
                                gpg_nextframestate.gs = &gs;
                                pynextframestate.state = &gpg_nextframestate;
                                pynextframestate.func = &GPG_PyNextFrame;

                                printf("Yielding control to Python script '%s'...\n", python_main);
                                PyRun_SimpleString(python_code);
                                printf("Exit Python script '%s'\n", python_main);
#endif // WITH_PYTHON
                                MEM_freeN(python_code);
                            }
                            else {
                                fprintf(stderr, "ERROR: cannot yield control to Python: no Python text data block named '%s'\n", python_main);
                            }
                        }
                        else {
                            while (run) {
                                run = GPG_NextFrame(system, &app, exitcode, exitstring, &gs);
                            }
                        }
                        app.StopGameEngine();

                        /* 'app' is freed automatic when out of scope.
                         * removal is needed else the system will free an already freed value */
                        system->removeEventConsumer(&app);

                        BLO_blendfiledata_free(bfd);
                        /* G.main == bfd->main, it gets referenced in free_nodesystem so we can't have a dangling pointer */
                        G.main = NULL;
                        if (python_main) MEM_freeN(python_main);
                    }
                } while (exitcode == KX_EXIT_REQUEST_RESTART_GAME || exitcode == KX_EXIT_REQUEST_START_OTHER_GAME);
            }

            // Seg Fault; icon.c gIcons == 0
            BKE_icons_free();

            // Dispose the system
            GHOST_ISystem::disposeSystem();
        }
        else {
            error = true;
            printf("error: couldn't create a system.\n");
        }
    }

    /* refer to WM_exit_ext() and free_blender(),
     * these are not called in the player but we need to match some of there behavior here,
     * if the order of function calls or blenders state isn't matching that of blender proper,
     * we may get troubles later on */

    free_nodesystem();

    // Cleanup
    RNA_exit();
    BLF_exit();

#ifdef WITH_INTERNATIONAL
    BLF_free_unifont();
    BLF_free_unifont_mono();
    BLF_lang_free();
#endif

    IMB_exit();
    BKE_images_exit();
    DAG_exit();
    IMB_moviecache_destruct();

    SYS_DeleteSystem(syshandle);

    int totblock= MEM_get_memory_blocks_in_use();
    if (totblock!=0) {
        printf("Error Totblock: %d\n",totblock);
        MEM_set_error_callback(mem_error_cb);
        MEM_printmemlist();
    }

    BKE_tempdir_session_purge();

    return error ? -1 : 0;
}
Beispiel #7
0
void KX_BlenderSceneConverter::ConvertScene(class KX_Scene* destinationscene,
											class RAS_IRenderTools* rendertools,
											class RAS_ICanvas* canvas)
{
	//find out which physics engine
	Scene *blenderscene = destinationscene->GetBlenderScene();

	e_PhysicsEngine physics_engine = UseBullet;
	bool useDbvtCulling = false;
	// hook for registration function during conversion.
	m_currentScene = destinationscene;
	destinationscene->SetSceneConverter(this);
	SG_SetActiveStage(SG_STAGE_CONVERTER);

	if (blenderscene)
	{
	
		switch (blenderscene->gm.physicsEngine)
		{
		case WOPHY_BULLET:
			{
				physics_engine = UseBullet;
				useDbvtCulling = (blenderscene->gm.mode & WO_DBVT_CULLING) != 0;
				break;
			}
			default:
			case WOPHY_NONE:
			{
				physics_engine = UseNone;
				break;
			}
		}
	}

	switch (physics_engine)
	{
#ifdef USE_BULLET
		case UseBullet:
			{
				CcdPhysicsEnvironment* ccdPhysEnv = new CcdPhysicsEnvironment(useDbvtCulling);
				ccdPhysEnv->setDebugDrawer(new BlenderDebugDraw());
				ccdPhysEnv->setDeactivationLinearTreshold(0.8f); // default, can be overridden by Python
				ccdPhysEnv->setDeactivationAngularTreshold(1.0f); // default, can be overridden by Python

				SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
				int visualizePhysics = SYS_GetCommandLineInt(syshandle,"show_physics",0);
				if (visualizePhysics)
					ccdPhysEnv->setDebugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb|btIDebugDraw::DBG_DrawContactPoints|btIDebugDraw::DBG_DrawText|btIDebugDraw::DBG_DrawConstraintLimits|btIDebugDraw::DBG_DrawConstraints);
		
				//todo: get a button in blender ?
				//disable / enable debug drawing (contact points, aabb's etc)	
				//ccdPhysEnv->setDebugMode(1);
				destinationscene->SetPhysicsEnvironment(ccdPhysEnv);
				break;
			}
#endif
		default:
		case UseNone:
			physics_engine = UseNone;
			destinationscene ->SetPhysicsEnvironment(new DummyPhysicsEnvironment());
			break;
	}

	BL_ConvertBlenderObjects(m_maggie,
		destinationscene,
		m_ketsjiEngine,
		physics_engine,
		rendertools,
		canvas,
		this,
		m_alwaysUseExpandFraming
		);

	//These lookup are not needed during game
	m_map_blender_to_gameactuator.clear();
	m_map_blender_to_gamecontroller.clear();
	m_map_blender_to_gameobject.clear();

	//Clearing this lookup table has the effect of disabling the cache of meshes
	//between scenes, even if they are shared in the blend file.
	//This cache mecanism is buggy so I leave it disable and the memory leak
	//that would result from this is fixed in RemoveScene()
	m_map_mesh_to_gamemesh.clear();

#ifndef USE_BULLET
	/* quiet compiler warning */
	(void)useDbvtCulling;
#endif

}
bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
{
	if (!m_engineInitialized)
	{
		GPU_extensions_init();
		bgl::InitExtensions(true);

		// get and set the preferences
		SYS_SystemHandle syshandle = SYS_GetSystem();
		if (!syshandle)
			return false;
		
		// SYS_WriteCommandLineInt(syshandle, "fixedtime", 0);
		// SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);
		GameData *gm= &m_startScene->gm;
		bool properties	= (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
		bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);

		bool showPhysics = (gm->flag & GAME_SHOW_PHYSICS);
		SYS_WriteCommandLineInt(syshandle, "show_physics", showPhysics);

		bool fixed_framerate= (SYS_GetCommandLineInt(syshandle, "fixedtime", (gm->flag & GAME_ENABLE_ALL_FRAMES)) != 0);
		bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
		bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", gm->flag & GAME_DISPLAY_LISTS) != 0) && GPU_display_list_support();
		bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 1) != 0);
		bool restrictAnimFPS = gm->flag & GAME_RESTRICT_ANIM_UPDATES;

		if (GLEW_ARB_multitexture && GLEW_VERSION_1_1)
			m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 1) != 0);

		if (GPU_glsl_support())
			m_blenderglslmat = (SYS_GetCommandLineInt(syshandle, "blender_glsl_material", 1) != 0);
		else if (m_globalSettings->matmode == GAME_MAT_GLSL)
			m_blendermat = false;

		// create the canvas, rasterizer and rendertools
		m_canvas = new GPG_Canvas(window);
		if (!m_canvas)
			return false;

		if (gm->vsync == VSYNC_ADAPTIVE)
			m_canvas->SetSwapInterval(-1);
		else
			m_canvas->SetSwapInterval((gm->vsync == VSYNC_ON) ? 1 : 0);

		m_canvas->Init();
		if (gm->flag & GAME_SHOW_MOUSE)
			m_canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
		
		//Don't use displaylists with VBOs
		//If auto starts using VBOs, make sure to check for that here
		if (useLists && gm->raster_storage != RAS_STORE_VBO)
			m_rasterizer = new RAS_ListRasterizer(m_canvas, false, gm->raster_storage);
		else
			m_rasterizer = new RAS_OpenGLRasterizer(m_canvas, gm->raster_storage);

		/* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
		m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
		m_rasterizer->SetEyeSeparation(m_startScene->gm.eyeseparation);
		
		if (!m_rasterizer)
			goto initFailed;
						
		// create the inputdevices
		m_keyboard = new GPG_KeyboardDevice();
		if (!m_keyboard)
			goto initFailed;
			
		m_mouse = new GPC_MouseDevice();
		if (!m_mouse)
			goto initFailed;
			
		// create a networkdevice
		m_networkdevice = new NG_LoopBackNetworkDeviceInterface();
		if (!m_networkdevice)
			goto initFailed;
			
		sound_init(m_maggie);

		// create a ketsjisystem (only needed for timing and stuff)
		m_kxsystem = new GPG_System (m_system);
		if (!m_kxsystem)
			goto initFailed;
		
		// create the ketsjiengine
		m_ketsjiengine = new KX_KetsjiEngine(m_kxsystem);
		
		// set the devices
		m_ketsjiengine->SetKeyboardDevice(m_keyboard);
		m_ketsjiengine->SetMouseDevice(m_mouse);
		m_ketsjiengine->SetNetworkDevice(m_networkdevice);
		m_ketsjiengine->SetCanvas(m_canvas);
		m_ketsjiengine->SetRasterizer(m_rasterizer);

		KX_KetsjiEngine::SetExitKey(ConvertKeyCode(gm->exitkey));
#ifdef WITH_PYTHON
		CValue::SetDeprecationWarnings(nodepwarnings);
#else
		(void)nodepwarnings;
#endif

		m_ketsjiengine->SetUseFixedTime(fixed_framerate);
		m_ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
		m_ketsjiengine->SetRestrictAnimationFPS(restrictAnimFPS);

		//set the global settings (carried over if restart/load new files)
		m_ketsjiengine->SetGlobalSettings(m_globalSettings);

		m_engineInitialized = true;
	}

	return m_engineInitialized;
initFailed:
	sound_exit();
	delete m_kxsystem;
	delete m_networkdevice;
	delete m_mouse;
	delete m_keyboard;
	delete m_rasterizer;
	delete m_canvas;
	m_canvas = NULL;
	m_rasterizer = NULL;
	m_keyboard = NULL;
	m_mouse = NULL;
	m_networkdevice = NULL;
	m_kxsystem = NULL;
	return false;
}
Beispiel #9
0
int main(int argc, char** argv)
{
    int i;
    int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
    bool error = false;
    SYS_SystemHandle syshandle = SYS_GetSystem();
    bool fullScreen = false;
    bool fullScreenParFound = false;
    bool windowParFound = false;
#ifdef WIN32
    bool closeConsole = true;
#endif
    RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
    bool stereoWindow = false;
    bool stereoParFound = false;
    int stereoFlag = STEREO_NOSTEREO;
    int domeFov = -1;
    int domeTilt = -200;
    int domeMode = 0;
    char* domeWarp = NULL;
    Text *domeText  = NULL;
    int windowLeft = 100;
    int windowTop = 100;
    int windowWidth = 640;
    int windowHeight = 480;
    GHOST_TUns32 fullScreenWidth = 0;
    GHOST_TUns32 fullScreenHeight= 0;
    int fullScreenBpp = 32;
    int fullScreenFrequency = 60;
    GHOST_TEmbedderWindowID parentWindow = 0;
    bool isBlenderPlayer = false;
    int validArguments=0;
    GHOST_TUns16 aasamples = 0;

#ifdef __linux__
#ifdef __alpha__
    signal (SIGFPE, SIG_IGN);
#endif /* __alpha__ */
#endif /* __linux__ */
    BLI_where_am_i(bprogname, sizeof(bprogname), argv[0]);
#ifdef __APPLE__
    // Can't use Carbon right now because of double defined type ID (In Carbon.h and DNA_ID.h, sigh)
    /*
    IBNibRef 		nibRef;
    WindowRef 		window;
    OSStatus		err;

      // Create a Nib reference passing the name of the nib file (without the .nib extension)
      // CreateNibReference only searches into the application bundle.
      err = ::CreateNibReference(CFSTR("main"), &nibRef);
      if (err) return -1;

    	// Once the nib reference is created, set the menu bar. "MainMenu" is the name of the menu bar
    	// object. This name is set in InterfaceBuilder when the nib is created.
    	err = ::SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
    	if (err) return -1;

    	  // We don't need the nib reference anymore.
    	  ::DisposeNibReference(nibRef);
    */
#endif // __APPLE__

    // We don't use threads directly in the BGE, but we need to call this so things like
    // freeing up GPU_Textures works correctly.
    BLI_threadapi_init();

    RNA_init();

    init_nodesystem();

    initglobals();

    // We load our own G.main, so free the one that initglobals() gives us
    free_main(G.main);
    G.main = NULL;

    IMB_init();

    // Setup builtin font for BLF (mostly copied from creator.c, wm_init_exit.c and interface_style.c)
    BLF_init(11, U.dpi);
    BLF_lang_init();
    BLF_load_mem("default", (unsigned char*)datatoc_bfont_ttf, datatoc_bfont_ttf_size);

    // Parse command line options
#if defined(DEBUG)
    printf("argv[0] = '%s'\n", argv[0]);
#endif

#ifdef WIN32
    if (scr_saver_init(argc, argv))
    {
        switch (scr_saver_mode)
        {
        case SCREEN_SAVER_MODE_CONFIGURATION:
            MessageBox(scr_saver_hwnd, "This screen saver has no options that you can set", "Screen Saver", MB_OK);
            break;
        case SCREEN_SAVER_MODE_PASSWORD:
        /* This is W95 only, which we currently do not support.
           Fall-back to normal screen saver behaviour in that case... */
        case SCREEN_SAVER_MODE_SAVER:
            fullScreen = true;
            fullScreenParFound = true;
            break;

        case SCREEN_SAVER_MODE_PREVIEW:
            /* This will actually be handled somewhere below... */
            break;
        }
    }
#endif
    // XXX add the ability to change this values to the command line parsing.
    U.mixbufsize = 2048;
    U.audiodevice = 2;
    U.audiorate = 44100;
    U.audioformat = 0x24;
    U.audiochannels = 2;

    // XXX this one too
    U.anisotropic_filter = 2;

    sound_init_once();

    /* if running blenderplayer the last argument can't be parsed since it has to be the filename. */
    isBlenderPlayer = !BLO_is_a_runtime(argv[0]);
    if (isBlenderPlayer)
        validArguments = argc - 1;
    else
        validArguments = argc;

    for (i = 1; (i < validArguments) && !error
#ifdef WIN32
            && scr_saver_mode == SCREEN_SAVER_MODE_NONE
#endif
            ;)

    {
#if defined(DEBUG)
        printf("argv[%d] = '%s'   , %i\n", i, argv[i],argc);
#endif
        if (argv[i][0] == '-')
        {
            /* ignore all args after " - ", allow python to have own args */
            if (argv[i][1]=='\0') {
                argc_py_clamped= i;
                break;
            }

            switch (argv[i][1])
            {
            case 'g':
                // Parse game options
            {
                i++;
                if (i <= validArguments)
                {
                    char* paramname = argv[i];
                    // Check for single value versus assignment
                    if (i+1 <= validArguments && (*(argv[i+1]) == '='))
                    {
                        i++;
                        if (i + 1 <= validArguments)
                        {
                            i++;
                            // Assignment
                            SYS_WriteCommandLineInt(syshandle, paramname, atoi(argv[i]));
                            SYS_WriteCommandLineFloat(syshandle, paramname, atof(argv[i]));
                            SYS_WriteCommandLineString(syshandle, paramname, argv[i]);
#if defined(DEBUG)
                            printf("%s = '%s'\n", paramname, argv[i]);
#endif
                            i++;
                        }
                        else
                        {
                            error = true;
                            printf("error: argument assignment %s without value.\n", paramname);
                        }
                    }
                    else
                    {
//							SYS_WriteCommandLineInt(syshandle, argv[i++], 1);
                    }
                }
            }
            break;

            case 'd':
                i++;
                G.f |= G_DEBUG;     /* std output printf's */
                MEM_set_memory_debug();
                break;

            case 'f':
                i++;
                fullScreen = true;
                fullScreenParFound = true;
                if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    fullScreenWidth = atoi(argv[i++]);
                    fullScreenHeight = atoi(argv[i++]);
                    if ((i + 1) <= validArguments && argv[i][0] != '-')
                    {
                        fullScreenBpp = atoi(argv[i++]);
                        if ((i + 1) <= validArguments && argv[i][0] != '-')
                            fullScreenFrequency = atoi(argv[i++]);
                    }
                }
                break;
            case 'w':
                // Parse window position and size options
                i++;
                fullScreen = false;
                windowParFound = true;

                if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                {
                    windowWidth = atoi(argv[i++]);
                    windowHeight = atoi(argv[i++]);
                    if ((i + 2) <= validArguments && argv[i][0] != '-' && argv[i+1][0] != '-')
                    {
                        windowLeft = atoi(argv[i++]);
                        windowTop = atoi(argv[i++]);
                    }
                }
                break;

            case 'h':
                usage(argv[0], isBlenderPlayer);
                return 0;
                break;
            case 'i':
                i++;
                if ( (i + 1) <= validArguments )
                    parentWindow = atoi(argv[i++]);
                else {
                    error = true;
                    printf("error: too few options for parent window argument.\n");
                }
#if defined(DEBUG)
                printf("XWindows ID = %d\n", parentWindow);
#endif // defined(DEBUG)
                break;
            case 'm':
                i++;
                if ((i+1) <= validArguments )
                    aasamples = atoi(argv[i++]);
                break;
            case 'c':
                i++;
#ifdef WIN32
                closeConsole = false;
#endif
                break;
            case 's':  // stereo
                i++;
                if ((i + 1) <= validArguments)
                {
                    stereomode = (RAS_IRasterizer::StereoMode) atoi(argv[i]);
                    if (stereomode < RAS_IRasterizer::RAS_STEREO_NOSTEREO || stereomode >= RAS_IRasterizer::RAS_STEREO_MAXSTEREO)
                        stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;

                    if(!strcmp(argv[i], "nostereo"))  // ok, redundant but clear
                        stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;

                    // only the hardware pageflip method needs a stereo window
                    else if(!strcmp(argv[i], "hwpageflip")) {
                        stereomode = RAS_IRasterizer::RAS_STEREO_QUADBUFFERED;
                        stereoWindow = true;
                    }
                    else if(!strcmp(argv[i], "syncdoubling"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_ABOVEBELOW;

                    else if(!strcmp(argv[i], "anaglyph"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_ANAGLYPH;

                    else if(!strcmp(argv[i], "sidebyside"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_SIDEBYSIDE;

                    else if(!strcmp(argv[i], "vinterlace"))
                        stereomode = RAS_IRasterizer::RAS_STEREO_VINTERLACE;

#if 0
                    // future stuff
                    else if(!strcmp(argv[i], "stencil")
                            stereomode = RAS_STEREO_STENCIL;
#endif

                            i++;
                            stereoParFound = true;
                            stereoFlag = STEREO_ENABLED;
                }
            else
            {
                error = true;
                printf("error: too few options for stereo argument.\n");
                }
                break;
            case 'D':
                stereoFlag = STEREO_DOME;
                stereomode = RAS_IRasterizer::RAS_STEREO_DOME;
                i++;
                if ((i + 1) <= validArguments)
                {
                    if(!strcmp(argv[i], "angle")) {
                        i++;
                        domeFov = atoi(argv[i++]);
                    }
                    if(!strcmp(argv[i], "tilt")) {
                        i++;
                        domeTilt = atoi(argv[i++]);
                    }
                    if(!strcmp(argv[i], "warpdata")) {
                        i++;
                        domeWarp = argv[i++];
                    }
                    if(!strcmp(argv[i], "mode")) {
                        i++;
                        if(!strcmp(argv[i], "fisheye"))
                            domeMode = DOME_FISHEYE;

                        else if(!strcmp(argv[i], "truncatedfront"))
                            domeMode = DOME_TRUNCATED_FRONT;

                        else if(!strcmp(argv[i], "truncatedrear"))
                            domeMode = DOME_TRUNCATED_REAR;

                        else if(!strcmp(argv[i], "cubemap"))
                            domeMode = DOME_ENVMAP;

                        else if(!strcmp(argv[i], "sphericalpanoramic"))
                            domeMode = DOME_PANORAM_SPH;

                        else
                            printf("error: %s is not a valid dome mode.\n", argv[i]);
                    }
                    i++;
                }
                break;
            default:
                printf("Unknown argument: %s\n", argv[i++]);
                break;
            }
        }
Beispiel #10
0
extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *cam_frame, int always_use_expand_framing)
{
	/* context values */
	struct wmWindow *win= CTX_wm_window(C);
	struct Scene *scene= CTX_data_scene(C);
	struct Main* maggie1= CTX_data_main(C);


	RAS_Rect area_rect;
	area_rect.SetLeft(cam_frame->xmin);
	area_rect.SetBottom(cam_frame->ymin);
	area_rect.SetRight(cam_frame->xmax);
	area_rect.SetTop(cam_frame->ymax);

	int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
	Main* blenderdata = maggie1;

	char* startscenename = scene->id.name+2;
	char pathname[FILE_MAXDIR+FILE_MAXFILE], oldsce[FILE_MAXDIR+FILE_MAXFILE];
	STR_String exitstring = "";
	BlendFileData *bfd= NULL;

	BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
	BLI_strncpy(oldsce, G.sce, sizeof(oldsce));
#ifndef DISABLE_PYTHON
	resetGamePythonPath(); // need this so running a second time wont use an old blendfiles path
	setGamePythonPath(G.sce);

	// Acquire Python's GIL (global interpreter lock)
	// so we can safely run Python code and API calls
	PyGILState_STATE gilstate = PyGILState_Ensure();
	
	PyObject *pyGlobalDict = PyDict_New(); /* python utility storage, spans blend file loading */
#endif
	
	bgl::InitExtensions(true);

	do
	{
		View3D *v3d= CTX_wm_view3d(C);
		RegionView3D *rv3d= CTX_wm_region_view3d(C);

		// get some preferences
		SYS_SystemHandle syshandle = SYS_GetSystem();
		bool properties	= (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
		bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
		bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
		bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
		bool game2ipo = (SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0);
		bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
		bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 0) != 0);
		bool novertexarrays = (SYS_GetCommandLineInt(syshandle, "novertexarrays", 0) != 0);
		// create the canvas, rasterizer and rendertools
		RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect);
		canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
		RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
		RAS_IRasterizer* rasterizer = NULL;
		
		if(displaylists) {
			if (GLEW_VERSION_1_1 && !novertexarrays)
				rasterizer = new RAS_ListRasterizer(canvas, true, true);
			else
				rasterizer = new RAS_ListRasterizer(canvas);
		}
		else if (GLEW_VERSION_1_1 && !novertexarrays)
			rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
		else
			rasterizer = new RAS_OpenGLRasterizer(canvas);
		
		// create the inputdevices
		KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
		KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();
		
		// create a networkdevice
		NG_NetworkDeviceInterface* networkdevice = new
			NG_LoopBackNetworkDeviceInterface();

		//
		// create a ketsji/blendersystem (only needed for timing and stuff)
		KX_BlenderSystem* kxsystem = new KX_BlenderSystem();
		
		// create the ketsjiengine
		KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);
		
		// set the devices
		ketsjiengine->SetKeyboardDevice(keyboarddevice);
		ketsjiengine->SetMouseDevice(mousedevice);
		ketsjiengine->SetNetworkDevice(networkdevice);
		ketsjiengine->SetCanvas(canvas);
		ketsjiengine->SetRenderTools(rendertools);
		ketsjiengine->SetRasterizer(rasterizer);
		ketsjiengine->SetNetworkDevice(networkdevice);
		ketsjiengine->SetUseFixedTime(usefixed);
		ketsjiengine->SetTimingDisplay(frameRate, profile, properties);

#ifndef DISABLE_PYTHON
		CValue::SetDeprecationWarnings(nodepwarnings);
#endif

		//lock frame and camera enabled - storing global values
		int tmp_lay= scene->lay;
		Object *tmp_camera = scene->camera;

		if (v3d->scenelock==0){
			scene->lay= v3d->lay;
			scene->camera= v3d->camera;
		}

		// some blender stuff
		MT_CmMatrix4x4 projmat;
		MT_CmMatrix4x4 viewmat;
		float camzoom;
		int i;

		for (i = 0; i < 16; i++)
		{
			float *viewmat_linear= (float*) rv3d->viewmat;
			viewmat.setElem(i, viewmat_linear[i]);
		}
		for (i = 0; i < 16; i++)
		{
			float *projmat_linear= (float*) rv3d->winmat;
			projmat.setElem(i, projmat_linear[i]);
		}
		
		if(rv3d->persp==RV3D_CAMOB) {
			if(scene->gm.framing.type == SCE_GAMEFRAMING_BARS) { /* Letterbox */
				camzoom = 1.0f;
			}
			else {
				camzoom = (1.41421 + (rv3d->camzoom / 50.0));
				camzoom *= camzoom;
				camzoom = 4.0 / camzoom;
			}
		}
		else {
			camzoom = 2.0;
		}

		

		ketsjiengine->SetDrawType(v3d->drawtype);
		ketsjiengine->SetCameraZoom(camzoom);
		
		// if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
		if (exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME || exitrequested == KX_EXIT_REQUEST_RESTART_GAME)
		{
			exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
			if (bfd) BLO_blendfiledata_free(bfd);
			
			char basedpath[240];
			// base the actuator filename with respect
			// to the original file working directory

			if (exitstring != "")
				strcpy(basedpath, exitstring.Ptr());

			// load relative to the last loaded file, this used to be relative
			// to the first file but that makes no sense, relative paths in
			// blend files should be relative to that file, not some other file
			// that happened to be loaded first
			BLI_convertstringcode(basedpath, pathname);
			bfd = load_game_data(basedpath);
			
			// if it wasn't loaded, try it forced relative
			if (!bfd)
			{
				// just add "//" in front of it
				char temppath[242];
				strcpy(temppath, "//");
				strcat(temppath, basedpath);
				
				BLI_convertstringcode(temppath, pathname);
				bfd = load_game_data(temppath);
			}
			
			// if we got a loaded blendfile, proceed
			if (bfd)
			{
				blenderdata = bfd->main;
				startscenename = bfd->curscene->id.name + 2;

				if(blenderdata) {
					BLI_strncpy(G.sce, blenderdata->name, sizeof(G.sce));
					BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));
#ifndef DISABLE_PYTHON
					setGamePythonPath(G.sce);
#endif
				}
			}
			// else forget it, we can't find it
			else
			{
				exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
			}
		}
		
		Scene *blscene = NULL;
		if (!bfd)
		{
			blscene = (Scene*) blenderdata->scene.first;
			for (Scene *sce= (Scene*) blenderdata->scene.first; sce; sce= (Scene*) sce->id.next)
			{
				if (startscenename == (sce->id.name+2))
				{
					blscene = sce;
					break;
				}
			}
		} else {
			blscene = bfd->curscene;
		}

		if (blscene)
		{
			int startFrame = blscene->r.cfra;
			ketsjiengine->SetGame2IpoMode(game2ipo,startFrame);
			
			// Quad buffered needs a special window.
			if(blscene->gm.stereoflag == STEREO_ENABLED){
				if (blscene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
					rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->gm.stereomode);
			}

			rasterizer->SetBackColor(blscene->gm.framing.col[0], blscene->gm.framing.col[1], blscene->gm.framing.col[2], 0.0f);
		}
		
		if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
		{
			if (rv3d->persp != RV3D_CAMOB)
			{
				ketsjiengine->EnableCameraOverride(startscenename);
				ketsjiengine->SetCameraOverrideUseOrtho((rv3d->persp == RV3D_ORTHO));
				ketsjiengine->SetCameraOverrideProjectionMatrix(projmat);
				ketsjiengine->SetCameraOverrideViewMatrix(viewmat);
				ketsjiengine->SetCameraOverrideClipping(v3d->near, v3d->far);
				ketsjiengine->SetCameraOverrideLens(v3d->lens);
			}
			
			// create a scene converter, create and convert the startingscene
			KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(blenderdata, ketsjiengine);
			ketsjiengine->SetSceneConverter(sceneconverter);
			sceneconverter->addInitFromFrame=false;
			if (always_use_expand_framing)
				sceneconverter->SetAlwaysUseExpandFraming(true);

			bool usemat = false, useglslmat = false;

			if(GLEW_ARB_multitexture && GLEW_VERSION_1_1)
				usemat = true;

			if(GPU_glsl_support())
				useglslmat = true;
			else if(blscene->gm.matmode == GAME_MAT_GLSL)
				usemat = false;

            if(usemat && (blscene->gm.matmode != GAME_MAT_TEXFACE))
				sceneconverter->SetMaterials(true);
			if(useglslmat && (blscene->gm.matmode == GAME_MAT_GLSL))
				sceneconverter->SetGLSLMaterials(true);
					
			KX_Scene* startscene = new KX_Scene(keyboarddevice,
				mousedevice,
				networkdevice,
				startscenename,
				blscene);

#ifndef DISABLE_PYTHON
			// some python things
			PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest, blenderdata);
			ketsjiengine->SetPyNamespace(dictionaryobject);
			initRasterizer(rasterizer, canvas);
			PyObject *gameLogic = initGameLogic(ketsjiengine, startscene);
			PyDict_SetItemString(PyModule_GetDict(gameLogic), "globalDict", pyGlobalDict); // Same as importing the module.
			PyObject *gameLogic_keys = PyDict_Keys(PyModule_GetDict(gameLogic));
			PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module.
			
			initGameKeys();
			initPythonConstraintBinding();
			initMathutils();
			initGeometry();
			initBGL();
#ifdef WITH_FFMPEG
			initVideoTexture();
#endif
#endif // DISABLE_PYTHON

			//initialize Dome Settings
			if(blscene->gm.stereoflag == STEREO_DOME)
				ketsjiengine->InitDome(blscene->gm.dome.res, blscene->gm.dome.mode, blscene->gm.dome.angle, blscene->gm.dome.resbuf, blscene->gm.dome.tilt, blscene->gm.dome.warptext);

			// initialize 3D Audio Settings
			AUD_set3DSetting(AUD_3DS_SPEED_OF_SOUND, blscene->audio.speed_of_sound);
			AUD_set3DSetting(AUD_3DS_DOPPLER_FACTOR, blscene->audio.doppler_factor);
			AUD_set3DSetting(AUD_3DS_DISTANCE_MODEL, blscene->audio.distance_model);

			if (sceneconverter)
			{
				// convert and add scene
				sceneconverter->ConvertScene(
					startscene,
					rendertools,
					canvas);
				ketsjiengine->AddScene(startscene);
				
				// init the rasterizer
				rasterizer->Init();
				
				// start the engine
				ketsjiengine->StartEngine(true);
				

				// Set the animation playback rate for ipo's and actions
				// the framerate below should patch with FPS macro defined in blendef.h
				// Could be in StartEngine set the framerate, we need the scene to do this
				ketsjiengine->SetAnimFrameRate( (((double) blscene->r.frs_sec) / blscene->r.frs_sec_base) );
				
				// the mainloop
				printf("\nBlender Game Engine Started\n\n");
				while (!exitrequested)
				{
					// first check if we want to exit
					exitrequested = ketsjiengine->GetExitCode();
					
					// kick the engine
					bool render = ketsjiengine->NextFrame(); // XXX 2.5 Bug, This is never true! FIXME-  Campbell
					
					if (render)
					{
						// render the frame
						ketsjiengine->Render();
					}
					
					wm_window_process_events_nosleep(C);
					
					// test for the ESC key
					//XXX while (qtest())
					while(wmEvent *event= (wmEvent *)win->queue.first)
					{
						short val = 0;
						//unsigned short event = 0; //XXX extern_qread(&val);
						
						if (keyboarddevice->ConvertBlenderEvent(event->type,event->val))
							exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
						
							/* Coordinate conversion... where
							* should this really be?
						*/
						if (event->type==MOUSEMOVE) {
							/* Note nice! XXX 2.5 event hack */
							val = event->x - ar->winrct.xmin;
							mousedevice->ConvertBlenderEvent(MOUSEX, val);
							
							val = ar->winy - (event->y - ar->winrct.ymin) - 1;
							mousedevice->ConvertBlenderEvent(MOUSEY, val);
						}
						else {
							mousedevice->ConvertBlenderEvent(event->type,event->val);
						}
						
						BLI_remlink(&win->queue, event);
						wm_event_free(event);
					}
					
				}
				printf("\nBlender Game Engine Finished\n\n");
				exitstring = ketsjiengine->GetExitString();


				// when exiting the mainloop
#ifndef DISABLE_PYTHON
				// Clears the dictionary by hand:
				// This prevents, extra references to global variables
				// inside the GameLogic dictionary when the python interpreter is finalized.
				// which allows the scene to safely delete them :)
				// see: (space.c)->start_game
				
				//PyDict_Clear(PyModule_GetDict(gameLogic));
				
				// Keep original items, means python plugins will autocomplete members
				int listIndex;
				PyObject *gameLogic_keys_new = PyDict_Keys(PyModule_GetDict(gameLogic));
				for (listIndex=0; listIndex < PyList_Size(gameLogic_keys_new); listIndex++)  {
					PyObject* item = PyList_GET_ITEM(gameLogic_keys_new, listIndex);
					if (!PySequence_Contains(gameLogic_keys, item)) {
						PyDict_DelItem(	PyModule_GetDict(gameLogic), item);
					}
				}
				Py_DECREF(gameLogic_keys_new);
				gameLogic_keys_new = NULL;
#endif
				ketsjiengine->StopEngine();
#ifndef DISABLE_PYTHON
				exitGamePythonScripting();
#endif
				networkdevice->Disconnect();
			}
			if (sceneconverter)
			{
				delete sceneconverter;
				sceneconverter = NULL;
			}

#ifndef DISABLE_PYTHON
			Py_DECREF(gameLogic_keys);
			gameLogic_keys = NULL;
#endif
		}
		//lock frame and camera enabled - restoring global values
		if (v3d->scenelock==0){
			scene->lay= tmp_lay;
			scene->camera= tmp_camera;
		}

		// set the cursor back to normal
		canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
		
		// clean up some stuff
		if (ketsjiengine)
		{
			delete ketsjiengine;
			ketsjiengine = NULL;
		}
		if (kxsystem)
		{
			delete kxsystem;
			kxsystem = NULL;
		}
		if (networkdevice)
		{
			delete networkdevice;
			networkdevice = NULL;
		}
		if (keyboarddevice)
		{
			delete keyboarddevice;
			keyboarddevice = NULL;
		}
		if (mousedevice)
		{
			delete mousedevice;
			mousedevice = NULL;
		}
		if (rasterizer)
		{
			delete rasterizer;
			rasterizer = NULL;
		}
		if (rendertools)
		{
			delete rendertools;
			rendertools = NULL;
		}
		if (canvas)
		{
			delete canvas;
			canvas = NULL;
                }
	
	} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
	
	if (bfd) BLO_blendfiledata_free(bfd);

	BLI_strncpy(G.sce, oldsce, sizeof(G.sce));

#ifndef DISABLE_PYTHON
	Py_DECREF(pyGlobalDict);

	// Release Python's GIL
	PyGILState_Release(gilstate);
#endif

}
Beispiel #11
0
extern "C" void StartKetsjiShellSimulation(struct wmWindow *win,
								 struct ARegion *ar,
								 char* scenename,
								 struct Main* maggie,
								 int always_use_expand_framing)
{
    int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;

	Main* blenderdata = maggie;

	RAS_Rect area_rect;
	area_rect.SetLeft(ar->winrct.xmin);
	area_rect.SetBottom(ar->winrct.ymin);
	area_rect.SetRight(ar->winrct.xmax);
	area_rect.SetTop(ar->winrct.ymax);

	char* startscenename = scenename;
	char pathname[FILE_MAXDIR+FILE_MAXFILE];
	STR_String exitstring = "";

	BLI_strncpy(pathname, blenderdata->name, sizeof(pathname));

#ifndef DISABLE_PYTHON
	// Acquire Python's GIL (global interpreter lock)
	// so we can safely run Python code and API calls
	PyGILState_STATE gilstate = PyGILState_Ensure();
#endif

	bgl::InitExtensions(true);

	do
	{

		// get some preferences
		SYS_SystemHandle syshandle = SYS_GetSystem();
		/*
		bool properties	= (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
		bool usefixed = (SYS_GetCommandLineInt(syshandle, "fixedtime", 0) != 0);
		bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
		bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
		*/
		bool game2ipo = true;//(SYS_GetCommandLineInt(syshandle, "game2ipo", 0) != 0);
		bool displaylists = (SYS_GetCommandLineInt(syshandle, "displaylists", 0) != 0);
		bool usemat = false;

		// create the canvas, rasterizer and rendertools
		RAS_ICanvas* canvas = new KX_BlenderCanvas(win, area_rect);
		//canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
		RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
		RAS_IRasterizer* rasterizer = NULL;

		if(displaylists) {
			if (GLEW_VERSION_1_1)
				rasterizer = new RAS_ListRasterizer(canvas, true, true);
			else
				rasterizer = new RAS_ListRasterizer(canvas);
		}
		else if (GLEW_VERSION_1_1)
			rasterizer = new RAS_VAOpenGLRasterizer(canvas, false);
		else
			rasterizer = new RAS_OpenGLRasterizer(canvas);

		// create the inputdevices
		KX_BlenderKeyboardDevice* keyboarddevice = new KX_BlenderKeyboardDevice();
		KX_BlenderMouseDevice* mousedevice = new KX_BlenderMouseDevice();

		// create a networkdevice
		NG_NetworkDeviceInterface* networkdevice = new
			NG_LoopBackNetworkDeviceInterface();

		// create a ketsji/blendersystem (only needed for timing and stuff)
		KX_BlenderSystem* kxsystem = new KX_BlenderSystem();

		// create the ketsjiengine
		KX_KetsjiEngine* ketsjiengine = new KX_KetsjiEngine(kxsystem);

		Scene *blscene = NULL;

		blscene = (Scene*) maggie->scene.first;
		for (Scene *sce= (Scene*) maggie->scene.first; sce; sce= (Scene*) sce->id.next)
		{
			if (startscenename == (sce->id.name+2))
			{
				blscene = sce;
				break;
			}
		}

        int cframe = 1, startFrame;
		if (blscene)
		{
			cframe=blscene->r.cfra;
			startFrame = blscene->r.sfra;
			blscene->r.cfra=startFrame;
			// update_for_newframe(); // XXX scene_update_for_newframe wont cut it!
			ketsjiengine->SetGame2IpoMode(game2ipo,startFrame);
		}

		// Quad buffered needs a special window.
		if(blscene->gm.stereoflag == STEREO_ENABLED){
			if (blscene->gm.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
				rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->gm.stereomode);
		}
		rasterizer->SetBackColor(blscene->gm.framing.col[0], blscene->gm.framing.col[1], blscene->gm.framing.col[2], 0.0f);

		if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
		{
			// create a scene converter, create and convert the startingscene
			KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(maggie, ketsjiengine);
			ketsjiengine->SetSceneConverter(sceneconverter);
			sceneconverter->addInitFromFrame=true;
			
			if (always_use_expand_framing)
				sceneconverter->SetAlwaysUseExpandFraming(true);

			if(usemat)
				sceneconverter->SetMaterials(true);

			KX_Scene* startscene = new KX_Scene(keyboarddevice,
				mousedevice,
				networkdevice,
				startscenename,
				blscene);

#ifndef DISABLE_PYTHON
			// some python things
			PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest, blenderdata);
			ketsjiengine->SetPyNamespace(dictionaryobject);
			initRasterizer(rasterizer, canvas);
			PyObject *gameLogic = initGameLogic(ketsjiengine, startscene);
			PyDict_SetItemString(dictionaryobject, "GameLogic", gameLogic); // Same as importing the module
			initGameKeys();
			initPythonConstraintBinding();
			initMathutils();
			initGeometry();
			initBGL();
#ifdef WITH_FFMPEG
			initVideoTexture();
#endif
#endif // DISABLE_PYTHON

			if (sceneconverter)
			{
				// convert and add scene
				sceneconverter->ConvertScene(
					startscene,
					rendertools,
					canvas);
				ketsjiengine->AddScene(startscene);

				// start the engine
				ketsjiengine->StartEngine(false);
				
				ketsjiengine->SetUseFixedTime(true);
				
				ketsjiengine->SetTicRate(
					(double) blscene->r.frs_sec /
					(double) blscene->r.frs_sec_base);

				// the mainloop
				while ((blscene->r.cfra<=blscene->r.efra)&&(!exitrequested))
				{
                    printf("frame %i\n",blscene->r.cfra);
                    // first check if we want to exit
					exitrequested = ketsjiengine->GetExitCode();
	
					// kick the engine
					ketsjiengine->NextFrame();
				    blscene->r.cfra=blscene->r.cfra+1;
				    // update_for_newframe(); // XXX scene_update_for_newframe wont cut it
					
				}
				exitstring = ketsjiengine->GetExitString();
			}
			if (sceneconverter)
			{
				delete sceneconverter;
				sceneconverter = NULL;
			}
		}
		blscene->r.cfra=cframe;
		// set the cursor back to normal
		canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);

		// clean up some stuff
		if (ketsjiengine)
		{
			delete ketsjiengine;
			ketsjiengine = NULL;
		}
		if (kxsystem)
		{
			delete kxsystem;
			kxsystem = NULL;
		}
		if (networkdevice)
		{
			delete networkdevice;
			networkdevice = NULL;
		}
		if (keyboarddevice)
		{
			delete keyboarddevice;
			keyboarddevice = NULL;
		}
		if (mousedevice)
		{
			delete mousedevice;
			mousedevice = NULL;
		}
		if (rasterizer)
		{
			delete rasterizer;
			rasterizer = NULL;
		}
		if (rendertools)
		{
			delete rendertools;
			rendertools = NULL;
                }

	} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);

#ifndef DISABLE_PYTHON
	// Release Python's GIL
	PyGILState_Release(gilstate);
#endif
}
Beispiel #12
0
/* called in creator.c even... tsk, split this! */
void WM_exit(bContext *C)
{
	wmWindow *win;

	sound_exit();

	/* first wrap up running stuff, we assume only the active WM is running */
	/* modal handlers are on window level freed, others too? */
	/* note; same code copied in wm_files.c */
	if(C && CTX_wm_manager(C)) {
		
		WM_jobs_stop_all(CTX_wm_manager(C));
		
		for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) {
			
			CTX_wm_window_set(C, win);	/* needed by operator close callbacks */
			WM_event_remove_handlers(C, &win->handlers);
			WM_event_remove_handlers(C, &win->modalhandlers);
			ED_screen_exit(C, win, win->screen);
		}
	}
	wm_operatortype_free();
	WM_menutype_free();
	
	/* all non-screen and non-space stuff editors did, like editmode */
	if(C)
		ED_editors_exit(C);

//	XXX	
//	BIF_GlobalReebFree();
//	BIF_freeRetarget();
	BIF_freeTemplates(C);
	
	free_ttfont(); /* bke_font.h */
	
	free_openrecent();
	
	BKE_freecubetable();
	
	fastshade_free_render();	/* shaded view */
	ED_preview_free_dbase();	/* frees a Main dbase, before free_blender! */

	if(C && CTX_wm_manager(C))
		wm_free_reports(C);			/* before free_blender! - since the ListBases get freed there */
		
	free_blender();				/* blender.c, does entire library and spacetypes */
//	free_matcopybuf();
	free_anim_copybuf();
	free_anim_drivers_copybuf();
	free_posebuf();
//	free_vertexpaint();
//	free_imagepaint();
	
//	fsmenu_free();

	BLF_exit();

	RE_FreeAllRender();
	RE_engines_exit();
	
//	free_txt_data();
	

#ifndef DISABLE_PYTHON
	/* XXX - old note */
	/* before free_blender so py's gc happens while library still exists */
	/* needed at least for a rare sigsegv that can happen in pydrivers */

	/* Update for blender 2.5, move after free_blender because blender now holds references to PyObject's
	 * so decref'ing them after python ends causes bad problems every time
	 * the pyDriver bug can be fixed if it happens again we can deal with it then */
	BPY_end_python();
#endif

	libtiff_exit();
	
#ifdef WITH_QUICKTIME
	quicktime_exit();
#endif
	
	if (!G.background) {
// XXX		UI_filelist_free_icons();
	}
	
	GPU_buffer_pool_free(0);
	GPU_extensions_exit();
	
//	if (copybuf) MEM_freeN(copybuf);
//	if (copybufinfo) MEM_freeN(copybufinfo);
	
	BKE_undo_save_quit();	// saves quit.blend if global undo is on
	BKE_reset_undo(); 
	
	ED_file_exit(); /* for fsmenu */

	UI_exit();
	BKE_userdef_free();

	RNA_exit(); /* should be after BPY_end_python so struct python slots are cleared */
	
	wm_ghost_exit();

	CTX_free(C);
	
	SYS_DeleteSystem(SYS_GetSystem());

	if(MEM_get_memory_blocks_in_use()!=0) {
		printf("Error Totblock: %d\n", MEM_get_memory_blocks_in_use());
		MEM_printmemlist();
	}
	wm_autosave_delete();
	
	printf("\nBlender quit\n");
	
#ifdef WIN32   
	/* ask user to press enter when in debug mode */
	if(G.f & G_DEBUG) {
		printf("press enter key to exit...\n\n");
		getchar();
	}
#endif 
	
	exit(G.afbreek==1);
}
Beispiel #13
0
/* note, doesnt run exit() call WM_exit() for that */
void WM_exit_ext(bContext *C, const short do_python)
{
	wmWindowManager *wm = C ? CTX_wm_manager(C) : NULL;

	sound_exit();

	/* first wrap up running stuff, we assume only the active WM is running */
	/* modal handlers are on window level freed, others too? */
	/* note; same code copied in wm_files.c */
	if (C && wm) {
		wmWindow *win;

		if (!G.background) {
			if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) {
				/* save the undo state as quit.blend */
				char filename[FILE_MAX];
				
				BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE);

				if (BKE_undo_save_file(filename))
					printf("Saved session recovery to '%s'\n", filename);
			}
		}
		
		WM_jobs_kill_all(wm);

		for (win = wm->windows.first; win; win = win->next) {
			
			CTX_wm_window_set(C, win);  /* needed by operator close callbacks */
			WM_event_remove_handlers(C, &win->handlers);
			WM_event_remove_handlers(C, &win->modalhandlers);
			ED_screen_exit(C, win, win->screen);
		}
	}

	BKE_addon_pref_type_free();
	wm_operatortype_free();
	wm_dropbox_free();
	WM_menutype_free();
	WM_uilisttype_free();
	
	/* all non-screen and non-space stuff editors did, like editmode */
	if (C)
		ED_editors_exit(C);

//	XXX	
//	BIF_GlobalReebFree();
//	BIF_freeRetarget();
	BIF_freeTemplates(C);

	free_openrecent();
	
	BKE_mball_cubeTable_free();
	
	/* render code might still access databases */
	RE_FreeAllRender();
	RE_engines_exit();
	
	ED_preview_free_dbase();  /* frees a Main dbase, before free_blender! */

	if (C && wm)
		wm_free_reports(C);  /* before free_blender! - since the ListBases get freed there */

	BKE_sequencer_free_clipboard(); /* sequencer.c */
	BKE_tracking_clipboard_free();
		
#ifdef WITH_COMPOSITOR
	COM_deinitialize();
#endif
	
	free_blender();  /* blender.c, does entire library and spacetypes */
//	free_matcopybuf();
	free_anim_copybuf();
	free_anim_drivers_copybuf();
	free_fmodifiers_copybuf();
	ED_clipboard_posebuf_free();
	BKE_node_clipboard_clear();

	BLF_exit();

#ifdef WITH_INTERNATIONAL
	BLF_free_unifont();
	BLF_free_unifont_mono();
	BLF_lang_free();
#endif
	
	ANIM_keyingset_infos_exit();
	
//	free_txt_data();
	

#ifdef WITH_PYTHON
	/* option not to close python so we can use 'atexit' */
	if (do_python) {
		/* XXX - old note */
		/* before free_blender so py's gc happens while library still exists */
		/* needed at least for a rare sigsegv that can happen in pydrivers */

		/* Update for blender 2.5, move after free_blender because blender now holds references to PyObject's
		 * so decref'ing them after python ends causes bad problems every time
		 * the pyDriver bug can be fixed if it happens again we can deal with it then */
		BPY_python_end();
	}
#else
	(void)do_python;
#endif

	GPU_global_buffer_pool_free();
	GPU_free_unused_buffers();
	GPU_extensions_exit();

	BKE_reset_undo(); 
	
	ED_file_exit(); /* for fsmenu */

	UI_exit();
	BKE_userdef_free();

	RNA_exit(); /* should be after BPY_python_end so struct python slots are cleared */
	
	wm_ghost_exit();

	CTX_free(C);
#ifdef WITH_GAMEENGINE
	SYS_DeleteSystem(SYS_GetSystem());
#endif
	
	GHOST_DisposeSystemPaths();

	if (MEM_get_memory_blocks_in_use() != 0) {
		printf("Error: Not freed memory blocks: %d\n", MEM_get_memory_blocks_in_use());
		MEM_printmemlist();
	}
	wm_autosave_delete();
	
	printf("\nBlender quit\n");
	
#ifdef WIN32   
	/* ask user to press a key when in debug mode */
	if (G.debug & G_DEBUG) {
		printf("Press any key to exit . . .\n\n");
		wait_for_console_key();
	}
#endif 
}
	}
}

int main(
	int argc,
#ifdef WIN32
	char **UNUSED(argv_c)
#else
	char **argv
#endif
	)
{
	int i;
	int argc_py_clamped= argc; /* use this so python args can be added after ' - ' */
	bool error = false;
	SYS_SystemHandle syshandle = SYS_GetSystem();
	bool fullScreen = false;
	bool fullScreenParFound = false;
	bool windowParFound = false;
#ifdef WIN32
	bool closeConsole = true;
#endif
	RAS_IRasterizer::StereoMode stereomode = RAS_IRasterizer::RAS_STEREO_NOSTEREO;
	bool stereoWindow = false;
	bool stereoParFound = false;
	int stereoFlag = STEREO_NOSTEREO;
	int domeFov = -1;
	int domeTilt = -200;
	int domeMode = 0;
	char* domeWarp = NULL;
	Text *domeText  = NULL;
void KX_BlenderSceneConverter::ConvertScene(KX_Scene *destinationscene, RAS_IRasterizer *rendertools,
											RAS_ICanvas *canvas, bool libloading)
{
	//find out which physics engine
	Scene *blenderscene = destinationscene->GetBlenderScene();

	PHY_IPhysicsEnvironment *phy_env = NULL;

	e_PhysicsEngine physics_engine = UseBullet;
	// hook for registration function during conversion.
	m_currentScene = destinationscene;
	destinationscene->SetSceneConverter(this);

	// This doesn't really seem to do anything except cause potential issues
	// when doing threaded conversion, so it's disabled for now.
	// SG_SetActiveStage(SG_STAGE_CONVERTER);

	switch (blenderscene->gm.physicsEngine) {
#ifdef WITH_BULLET
	case WOPHY_BULLET:
		{
			SYS_SystemHandle syshandle = SYS_GetSystem(); /*unused*/
			int visualizePhysics = SYS_GetCommandLineInt(syshandle, "show_physics", 0);

			phy_env = CcdPhysicsEnvironment::Create(blenderscene, visualizePhysics);
			physics_engine = UseBullet;
			break;
		}
#endif
	default:
	case WOPHY_NONE:
		{
			// We should probably use some sort of factory here
			phy_env = new DummyPhysicsEnvironment();
			physics_engine = UseNone;
			break;
		}
	}

	destinationscene->SetPhysicsEnvironment(phy_env);

	BL_ConvertBlenderObjects(
		m_maggie,
		destinationscene,
		m_ketsjiEngine,
		physics_engine,
		rendertools,
		canvas,
		this,
		m_alwaysUseExpandFraming,
		libloading);

	//These lookup are not needed during game
	m_map_blender_to_gameactuator.clear();
	m_map_blender_to_gamecontroller.clear();
	m_map_blender_to_gameobject.clear();

	//Clearing this lookup table has the effect of disabling the cache of meshes
	//between scenes, even if they are shared in the blend file.
	//This cache mecanism is buggy so I leave it disable and the memory leak
	//that would result from this is fixed in RemoveScene()
	m_map_mesh_to_gamemesh.clear();
}
Beispiel #16
0
bool GPG_Application::initEngine(GHOST_IWindow* window, const int stereoMode)
{
	if (!m_engineInitialized)
	{
		GPU_extensions_init();
		bgl::InitExtensions(true);

		// get and set the preferences
		SYS_SystemHandle syshandle = SYS_GetSystem();
		if (!syshandle)
			return false;
		
		// SYS_WriteCommandLineInt(syshandle, "fixedtime", 0);
		// SYS_WriteCommandLineInt(syshandle, "vertexarrays",1);		
		GameData *gm= &m_startScene->gm;
		bool properties	= (SYS_GetCommandLineInt(syshandle, "show_properties", 0) != 0);
		bool profile = (SYS_GetCommandLineInt(syshandle, "show_profile", 0) != 0);
		bool fixedFr = (gm->flag & GAME_ENABLE_ALL_FRAMES);

		bool showPhysics = (gm->flag & GAME_SHOW_PHYSICS);
		SYS_WriteCommandLineInt(syshandle, "show_physics", showPhysics);

		bool fixed_framerate= (SYS_GetCommandLineInt(syshandle, "fixed_framerate", fixedFr) != 0);
		bool frameRate = (SYS_GetCommandLineInt(syshandle, "show_framerate", 0) != 0);
		bool useLists = (SYS_GetCommandLineInt(syshandle, "displaylists", gm->flag & GAME_DISPLAY_LISTS) != 0);
		bool nodepwarnings = (SYS_GetCommandLineInt(syshandle, "ignore_deprecation_warnings", 1) != 0);

		if(GLEW_ARB_multitexture && GLEW_VERSION_1_1)
			m_blendermat = (SYS_GetCommandLineInt(syshandle, "blender_material", 1) != 0);

		if(GPU_glsl_support())
			m_blenderglslmat = (SYS_GetCommandLineInt(syshandle, "blender_glsl_material", 1) != 0);
		else if(gm->matmode == GAME_MAT_GLSL)
			m_blendermat = false;

        printf("enjalot: instantiate canvas\n");
		// create the canvas, rasterizer and rendertools
		m_canvas = new GPG_Canvas(window);
		if (!m_canvas)
			return false;
#if 1				
        printf("enjalot: init canvas\n");
		m_canvas->Init();
		if (gm->flag & GAME_SHOW_MOUSE)
			m_canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);				

        printf("enjalot: rendertools\n");
		m_rendertools = new GPC_RenderTools();
		if (!m_rendertools)
			goto initFailed;
#endif	
        printf("enjalot: rasterizer\n");
#if 1
		if(useLists) {
			if(GLEW_VERSION_1_1)
				m_rasterizer = new RAS_ListRasterizer(m_canvas, true);
			else
				m_rasterizer = new RAS_ListRasterizer(m_canvas);
		}
		else if (GLEW_VERSION_1_1)
			m_rasterizer = new RAS_VAOpenGLRasterizer(m_canvas);
		else
			m_rasterizer = new RAS_OpenGLRasterizer(m_canvas);

		/* Stereo parameters - Eye Separation from the UI - stereomode from the command-line/UI */
		m_rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) stereoMode);
		m_rasterizer->SetEyeSeparation(m_startScene->gm.eyeseparation);
		
		if (!m_rasterizer)
			goto initFailed;
#endif					
		// create the inputdevices
		m_keyboard = new GPG_KeyboardDevice();
		if (!m_keyboard)
			goto initFailed;
			
		m_mouse = new GPC_MouseDevice();
		if (!m_mouse)
			goto initFailed;
			
		// create a networkdevice
		m_networkdevice = new NG_LoopBackNetworkDeviceInterface();
		if (!m_networkdevice)
			goto initFailed;
			
		sound_init(m_maggie);

		// create a ketsjisystem (only needed for timing and stuff)
		m_kxsystem = new GPG_System (m_system);
		if (!m_kxsystem)
			goto initFailed;
		
        printf("enjalot: ketsji engine\n");
		// create the ketsjiengine
		m_ketsjiengine = new KX_KetsjiEngine(m_kxsystem);
		
		// set the devices
		m_ketsjiengine->SetKeyboardDevice(m_keyboard);
		m_ketsjiengine->SetMouseDevice(m_mouse);
		m_ketsjiengine->SetNetworkDevice(m_networkdevice);
		m_ketsjiengine->SetCanvas(m_canvas);
		m_ketsjiengine->SetRenderTools(m_rendertools);
		m_ketsjiengine->SetRasterizer(m_rasterizer);

		m_ketsjiengine->SetTimingDisplay(frameRate, false, false);
#ifdef WITH_PYTHON
		CValue::SetDeprecationWarnings(nodepwarnings);
#else
		(void)nodepwarnings;
#endif

		m_ketsjiengine->SetUseFixedTime(fixed_framerate);
		m_ketsjiengine->SetTimingDisplay(frameRate, profile, properties);

		m_engineInitialized = true;
        printf("enjalot: end of init\n");
	}

	return m_engineInitialized;
initFailed:
	sound_exit();
	delete m_kxsystem;
	delete m_networkdevice;
	delete m_mouse;
	delete m_keyboard;
	delete m_rasterizer;
	delete m_rendertools;
	delete m_canvas;
	m_canvas = NULL;
	m_rendertools = NULL;
	m_rasterizer = NULL;
	m_keyboard = NULL;
	m_mouse = NULL;
	m_networkdevice = NULL;
	m_kxsystem = NULL;
	return false;
}