Ejemplo n.º 1
0
void ED_preview_free_dbase(void)
{
	if (G_pr_main)
		BKE_main_free(G_pr_main);

	if (G_pr_main_cycles)
		BKE_main_free(G_pr_main_cycles);
}
Ejemplo n.º 2
0
void ED_preview_free_dbase(void)
{
  if (G_pr_main) {
    BKE_main_free(G_pr_main);
  }

  if (G_pr_main_grease_pencil) {
    BKE_main_free(G_pr_main_grease_pencil);
  }
}
Ejemplo n.º 3
0
int BKE_read_file(bContext *C, const char *filepath, ReportList *reports)
{
	BlendFileData *bfd;
	int retval = BKE_READ_FILE_OK;

	if (strstr(filepath, BLENDER_STARTUP_FILE) == NULL) /* don't print user-pref loading */
		printf("read blend: %s\n", filepath);

	bfd = BLO_read_from_file(filepath, reports);
	if (bfd) {
		if (bfd->user) retval = BKE_READ_FILE_OK_USERPREFS;
		
		if (0 == handle_subversion_warning(bfd->main, reports)) {
			BKE_main_free(bfd->main);
			MEM_freeN(bfd);
			bfd = NULL;
			retval = BKE_READ_FILE_FAIL;
		}
		else
			setup_app_data(C, bfd, filepath);  // frees BFD
	}
	else
		BKE_reports_prependf(reports, "Loading '%s' failed: ", filepath);
		
	return (bfd ? retval : BKE_READ_FILE_FAIL);
}
Ejemplo n.º 4
0
int BKE_blendfile_read(
        bContext *C, const char *filepath,
        const struct BlendFileReadParams *params,
        ReportList *reports)
{
	BlendFileData *bfd;
	int retval = BKE_BLENDFILE_READ_OK;

	/* don't print user-pref loading */
	if (strstr(filepath, BLENDER_STARTUP_FILE) == NULL) {
		printf("Read blend: %s\n", filepath);
	}

	bfd = BLO_read_from_file(filepath, params->skip_flags, reports);
	if (bfd) {
		if (bfd->user) {
			retval = BKE_BLENDFILE_READ_OK_USERPREFS;
		}

		if (0 == handle_subversion_warning(bfd->main, reports)) {
			BKE_main_free(bfd->main);
			MEM_freeN(bfd);
			bfd = NULL;
			retval = BKE_BLENDFILE_READ_FAIL;
		}
		else {
			setup_app_data(C, bfd, filepath, params->is_startup, reports);
		}
	}
	else
		BKE_reports_prependf(reports, "Loading '%s' failed: ", filepath);

	return (bfd ? retval : BKE_BLENDFILE_READ_FAIL);
}
Ejemplo n.º 5
0
/* only to be called on exit blender */
void BKE_blender_free(void)
{
  /* samples are in a global list..., also sets G_MAIN->sound->sample NULL */

  /* Needs to run before main free as wm is still referenced for icons preview jobs. */
  BKE_studiolight_free();

  BKE_main_free(G_MAIN);
  G_MAIN = NULL;

  if (G.log.file != NULL) {
    fclose(G.log.file);
  }

  BKE_spacetypes_free(); /* after free main, it uses space callbacks */

  IMB_exit();
  BKE_cachefiles_exit();
  BKE_images_exit();
  DEG_free_node_types();

  BKE_brush_system_exit();
  RE_texture_rng_exit();

  BLI_callback_global_finalize();

  IMB_moviecache_destruct();

  free_nodesystem();
}
Ejemplo n.º 6
0
static void clear_global(void) 
{
//	extern short winqueue_break;	/* screen.c */

	BKE_main_free(G.main);          /* free all lib data */
	
//	free_vertexpaint();

	G.main = NULL;
}
Ejemplo n.º 7
0
/* only read the userdef from a .blend */
UserDef *BKE_blendfile_userdef_read(const char *filepath, ReportList *reports)
{
	BlendFileData *bfd;
	UserDef *userdef = NULL;

	bfd = BLO_read_from_file(filepath, BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF, reports);
	if (bfd) {
		if (bfd->user) {
			userdef = bfd->user;
		}
		BKE_main_free(bfd->main);
		MEM_freeN(bfd);
	}

	return userdef;
}
Ejemplo n.º 8
0
/* only read the userdef from a .blend */
int BKE_read_file_userdef(const char *filepath, ReportList *reports)
{
	BlendFileData *bfd;
	int retval = 0;
	
	bfd = BLO_read_from_file(filepath, reports);
	if (bfd->user) {
		retval = BKE_READ_FILE_OK_USERPREFS;
		
		/* only here free userdef themes... */
		BKE_userdef_free();
		
		U = *bfd->user;
		MEM_freeN(bfd->user);
	}
	BKE_main_free(bfd->main);
	MEM_freeN(bfd);
	
	return retval;
}
Ejemplo n.º 9
0
UserDef *BKE_blendfile_userdef_read_from_memory(
        const void *filebuf, int filelength,
        ReportList *reports)
{
	BlendFileData *bfd;
	UserDef *userdef = NULL;

	bfd = BLO_read_from_memory(filebuf, filelength, reports, BLO_READ_SKIP_ALL & ~BLO_READ_SKIP_USERDEF);
	if (bfd) {
		if (bfd->user) {
			userdef = bfd->user;
		}
		BKE_main_free(bfd->main);
		MEM_freeN(bfd);
	}
	else {
		BKE_reports_prepend(reports, "Loading failed: ");
	}

	return userdef;
}
Ejemplo n.º 10
0
/* only to be called on exit blender */
void free_blender(void)
{
	/* samples are in a global list..., also sets G.main->sound->sample NULL */
	BKE_main_free(G.main);
	G.main = NULL;

	BKE_spacetypes_free();      /* after free main, it uses space callbacks */
	
	IMB_exit();
	BKE_images_exit();
	DAG_exit();

	BKE_brush_system_exit();

	BLI_callback_global_finalize();

	BKE_sequencer_cache_destruct();
	IMB_moviecache_destruct();
	
	free_nodesystem();
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
void BKE_blender_globals_clear(void)
{
  BKE_main_free(G_MAIN); /* free all lib data */

  G_MAIN = NULL;
}
Ejemplo n.º 13
0
static void render_endjob(void *rjv)
{
	RenderJob *rj = rjv;

	/* this render may be used again by the sequencer without the active 'Render' where the callbacks
	 * would be re-assigned. assign dummy callbacks to avoid referencing freed renderjobs bug [#24508] */
	RE_InitRenderCB(rj->re);

	if (rj->main != G.main)
		BKE_main_free(rj->main);

	/* else the frame will not update for the original value */
	if (rj->anim && !(rj->scene->r.scemode & R_NO_FRAME_UPDATE)) {
		/* possible this fails of loading new file while rendering */
		if (G.main->wm.first) {
			ED_update_for_newframe(G.main, rj->scene, 1);
		}
	}
	
	/* XXX above function sets all tags in nodes */
	ntreeCompositClearTags(rj->scene->nodetree);
	
	/* potentially set by caller */
	rj->scene->r.scemode &= ~R_NO_FRAME_UPDATE;
	
	if (rj->srl) {
		nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
		WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
	}

	if (rj->sa) {
		render_image_restore_layer(rj);
	}

	/* XXX render stability hack */
	G.is_rendering = false;
	WM_main_add_notifier(NC_SCENE | ND_RENDER_RESULT, NULL);

	/* Partial render result will always update display buffer
	 * for first render layer only. This is nice because you'll
	 * see render progress during rendering, but it ends up in
	 * wrong display buffer shown after rendering.
	 *
	 * The code below will mark display buffer as invalid after
	 * rendering in case multiple layers were rendered, which
	 * ensures display buffer matches render layer after
	 * rendering.
	 *
	 * Perhaps proper way would be to toggle active render
	 * layer in image editor and job, so we always display
	 * layer being currently rendered. But this is not so much
	 * trivial at this moment, especially because of external
	 * engine API, so lets use simple and robust way for now
	 *                                          - sergey -
	 */
	if (rj->scene->r.layers.first != rj->scene->r.layers.last ||
	    rj->image_outdated)
	{
		void *lock;
		Image *ima = rj->image;
		ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);

		if (ibuf)
			ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;

		BKE_image_release_ibuf(ima, ibuf, lock);
	}

	/* Finally unlock the user interface (if it was locked). */
	if (rj->interface_locked) {
		Scene *scene;

		/* Interface was locked, so window manager couldn't have been changed
		 * and using one from Global will unlock exactly the same manager as
		 * was locked before running the job.
		 */
		WM_set_locked_interface(G.main->wm.first, false);

		/* We've freed all the derived caches before rendering, which is
		 * effectively the same as if we re-loaded the file.
		 *
		 * So let's not try being smart here and just reset all updated
		 * scene layers and use generic DAG_on_visible_update.
		 */
		for (scene = G.main->scene.first; scene; scene = scene->id.next) {
			scene->lay_updated = 0;
		}

		DAG_on_visible_update(G.main, false);
	}
}
Ejemplo n.º 14
0
/* Note m_map_*** are all ok and don't need to be freed
 * most are temp and NewRemoveObject frees m_map_gameobject_to_blender */
bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie)
{
	int maggie_index = -1;
	int i = 0;

	if (maggie == NULL)
		return false;

	// If the given library is currently in loading, we do nothing.
	if (m_status_map.count(maggie->name)) {
		BLI_mutex_lock(&m_threadinfo->m_mutex);
		const bool finished = m_status_map[maggie->name]->IsFinished();
		BLI_mutex_unlock(&m_threadinfo->m_mutex);

		if (!finished) {
			printf("Library (%s) is currently being loaded asynchronously, and cannot be freed until this process is done\n", maggie->name);
			return false;
		}
	}

	/* tag all false except the one we remove */
	for (vector<Main *>::iterator it = m_DynamicMaggie.begin(); !(it == m_DynamicMaggie.end()); it++) {
		Main *main = *it;
		if (main != maggie) {
			BKE_main_id_tag_all(main, LIB_TAG_DOIT, false);
		}
		else {
			maggie_index = i;
		}
		i++;
	}

	/* should never happen but just to be safe */
	if (maggie_index == -1)
		return false;

	m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index);
	BKE_main_id_tag_all(maggie, LIB_TAG_DOIT, true);

	/* free all tagged objects */
	KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes();
	int numScenes = scenes->size();

	for (int scene_idx = 0; scene_idx < numScenes; scene_idx++) {
		KX_Scene *scene = scenes->at(scene_idx);
		if (IS_TAGGED(scene->GetBlenderScene())) {
			m_ketsjiEngine->RemoveScene(scene->GetName());
			m_mat_cache.erase(scene);
			m_polymat_cache.erase(scene);
			scene_idx--;
			numScenes--;
		}
		else {
			/* in case the mesh might be refered to later */
			{
				CTR_Map<STR_HashedString, void *> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap();
				
				for (int i = 0; i < mapStringToMeshes.size(); i++) {
					RAS_MeshObject *meshobj = (RAS_MeshObject *) *mapStringToMeshes.at(i);
					if (meshobj && IS_TAGGED(meshobj->GetMesh())) {
						STR_HashedString mn = meshobj->GetName();
						mapStringToMeshes.remove(mn);
						m_map_mesh_to_gamemesh.remove(CHashedPtr(meshobj->GetMesh()));
						i--;
					}
				}
			}

			/* Now unregister actions */
			{
				CTR_Map<STR_HashedString, void *> &mapStringToActions = scene->GetLogicManager()->GetActionMap();

				for (int i = 0; i < mapStringToActions.size(); i++) {
					ID *action = (ID*) *mapStringToActions.at(i);

					if (IS_TAGGED(action)) {
						STR_HashedString an = action->name + 2;
						mapStringToActions.remove(an);
						m_map_blender_to_gameAdtList.remove(CHashedPtr(action));
						i--;
					}
				}
			}
			
			//scene->FreeTagged(); /* removed tagged objects and meshes*/
			CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL};

			for (int ob_ls_idx = 0; obj_lists[ob_ls_idx]; ob_ls_idx++) {
				CListValue *obs = obj_lists[ob_ls_idx];
				RAS_MeshObject *mesh;

				for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++) {
					KX_GameObject *gameobj = (KX_GameObject*)obs->GetValue(ob_idx);
					if (IS_TAGGED(gameobj->GetBlenderObject())) {
						int size_before = obs->GetCount();

						/* Eventually calls RemoveNodeDestructObject
						 * frees m_map_gameobject_to_blender from UnregisterGameObject */
						scene->RemoveObject(gameobj);

						if (size_before != obs->GetCount())
							ob_idx--;
						else {
							printf("ERROR COULD NOT REMOVE \"%s\"\n", gameobj->GetName().ReadPtr());
						}
					}
					else {
						gameobj->RemoveTaggedActions();
						/* free the mesh, we could be referecing a linked one! */
						int mesh_index = gameobj->GetMeshCount();
						while (mesh_index--) {
							mesh = gameobj->GetMesh(mesh_index);
							if (IS_TAGGED(mesh->GetMesh())) {
								gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */
								break;
							}
							else {
								/* also free the mesh if it's using a tagged material */
								int mat_index = mesh->NumMaterials();
								while (mat_index--) {
									if (IS_TAGGED(mesh->GetMeshMaterial(mat_index)->m_bucket->GetPolyMaterial()->GetBlenderMaterial())) {
										gameobj->RemoveMeshes(); /* XXX - slack, same as above */
										break;
									}
								}
							}
						}

						/* make sure action actuators are not referencing tagged actions */
						for (unsigned int act_idx = 0; act_idx < gameobj->GetActuators().size(); act_idx++) {
							if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION)) {
								BL_ActionActuator *act = (BL_ActionActuator *)gameobj->GetActuators()[act_idx];
								if (IS_TAGGED(act->GetAction()))
									act->SetAction(NULL);
							}
						}
					}
				}
			}
		}
	}

	int size;

	// delete the entities of this scene
	/* TODO - */
#if 0
	vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit;
	size = m_worldinfos.size();
	for (i=0, worldit=m_worldinfos.begin(); i<size; ) {
		if ((*worldit).second) {
			delete (*worldit).second;
			*worldit = m_worldinfos.back();
			m_worldinfos.pop_back();
			size--;
		} else {
			i++;
			worldit++;
		}
	}
#endif


	/* Worlds don't reference original blender data so we need to make a set from them */
	typedef std::set<KX_WorldInfo *> KX_WorldInfoSet;
	KX_WorldInfoSet worldset;
	for (int scene_idx = 0; scene_idx < numScenes; scene_idx++) {
		KX_Scene *scene = scenes->at(scene_idx);
		if (scene->GetWorldInfo())
			worldset.insert(scene->GetWorldInfo());
	}

	vector<pair<KX_Scene *, KX_WorldInfo *> >::iterator worldit;
	size = m_worldinfos.size();
	for (i = 0, worldit = m_worldinfos.begin(); i < size;) {
		if (worldit->second && (worldset.count(worldit->second)) == 0) {
			delete worldit->second;
			*worldit = m_worldinfos.back();
			m_worldinfos.pop_back();
			size--;
		} 
		else {
			i++;
			worldit++;
		}
	}
	worldset.clear();
	/* done freeing the worlds */

	vector<pair<KX_Scene *, RAS_IPolyMaterial *> >::iterator polymit;
	size = m_polymaterials.size();

	for (i = 0, polymit = m_polymaterials.begin(); i < size; ) {
		RAS_IPolyMaterial *mat = polymit->second;
		Material *bmat = NULL;

		KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial *>(mat);
		bmat = bl_mat->GetBlenderMaterial();

		if (IS_TAGGED(bmat)) {
			/* only remove from bucket */
			polymit->first->GetBucketManager()->RemoveMaterial(mat);
		}

		i++;
		polymit++;
	}

	for (i = 0, polymit = m_polymaterials.begin(); i < size; ) {
		RAS_IPolyMaterial *mat = polymit->second;
		Material *bmat = NULL;

		KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat);
		bmat = bl_mat->GetBlenderMaterial();

		if (IS_TAGGED(bmat)) {
			// Remove the poly material coresponding to this Blender Material.
			m_polymat_cache[polymit->first].erase(bmat);
			delete polymit->second;
			*polymit = m_polymaterials.back();
			m_polymaterials.pop_back();
			size--;
		} else {
			i++;
			polymit++;
		}
	}

	vector<pair<KX_Scene *, BL_Material *> >::iterator matit;
	size = m_materials.size();
	for (i = 0, matit = m_materials.begin(); i < size; ) {
		BL_Material *mat = matit->second;
		if (IS_TAGGED(mat->material)) {
			// Remove the bl material coresponding to this Blender Material.
			m_mat_cache[matit->first].erase(mat->material);
			delete matit->second;
			*matit = m_materials.back();
			m_materials.pop_back();
			size--;
		} 
		else {
			i++;
			matit++;
		}
	}

	vector<pair<KX_Scene *, RAS_MeshObject *> >::iterator meshit;
	RAS_BucketManager::BucketList::iterator bit;
	list<RAS_MeshSlot>::iterator msit;
	RAS_BucketManager::BucketList buckets;

	size = m_meshobjects.size();
	for (i = 0, meshit = m_meshobjects.begin(); i < size;) {
		RAS_MeshObject *me = meshit->second;
		if (IS_TAGGED(me->GetMesh())) {
			// Before deleting the mesh object, make sure the rasterizer is
			// no longer referencing it.
			buckets = meshit->first->GetBucketManager()->GetSolidBuckets();
			for (bit = buckets.begin(); bit != buckets.end(); bit++) {
				msit = (*bit)->msBegin();

				while (msit != (*bit)->msEnd()) {
					if (msit->m_mesh == meshit->second)
						(*bit)->RemoveMesh(&(*msit++));
					else
						msit++;
				}
			}

			// And now the alpha buckets
			buckets = meshit->first->GetBucketManager()->GetAlphaBuckets();
			for (bit = buckets.begin(); bit != buckets.end(); bit++) {
				msit = (*bit)->msBegin();

				while (msit != (*bit)->msEnd()) {
					if (msit->m_mesh == meshit->second)
						(*bit)->RemoveMesh(&(*msit++));
					else
						msit++;
				}
			}

			// Now it should be safe to delete
			delete meshit->second;
			*meshit = m_meshobjects.back();
			m_meshobjects.pop_back();
			size--;
		} 
		else {
			i++;
			meshit++;
		}
	}

#ifdef WITH_PYTHON
	/* make sure this maggie is removed from the import list if it's there
	 * (this operation is safe if it isn't in the list) */
	removeImportMain(maggie);
#endif

	delete m_status_map[maggie->name];
	m_status_map.erase(maggie->name);

	BKE_main_free(maggie);

	return true;
}
Ejemplo n.º 15
0
void BKE_blender_globals_clear(void)
{
	BKE_main_free(G.main);          /* free all lib data */

	G.main = NULL;
}