forked from bartvdbraak/blender
77c4eef90b
(with make, need to confirm with scons) after cleaning the changes are in fact minimal, but the situation is still quite a bit hackish. Game engine coders, there is also quite a number of warnings that need to be fixed. current situation is that everything seems to work, but GLSL shaders spew a lot of errors on console and blender may crash on exit when a GLSL shader was used. ARB stuff works fine.
431 lines
11 KiB
C++
431 lines
11 KiB
C++
/**
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
* Blender's Ketsji startpoint
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <signal.h>
|
|
|
|
#ifdef WIN32
|
|
// don't show stl-warnings
|
|
#pragma warning (disable:4786)
|
|
#endif
|
|
|
|
#ifdef __APPLE__
|
|
#define GL_GLEXT_LEGACY 1
|
|
#endif
|
|
|
|
#include "KX_BlenderGL.h"
|
|
#include "KX_BlenderCanvas.h"
|
|
#include "KX_BlenderKeyboardDevice.h"
|
|
#include "KX_BlenderMouseDevice.h"
|
|
#include "KX_BlenderRenderTools.h"
|
|
#include "KX_BlenderSystem.h"
|
|
#include "BL_Material.h"
|
|
|
|
#include "KX_KetsjiEngine.h"
|
|
#include "KX_BlenderSceneConverter.h"
|
|
#include "KX_PythonInit.h"
|
|
#include "KX_PyConstraintBinding.h"
|
|
|
|
#include "RAS_OpenGLRasterizer.h"
|
|
#include "RAS_VAOpenGLRasterizer.h"
|
|
#include "RAS_GLExtensionManager.h"
|
|
|
|
#include "NG_LoopBackNetworkDeviceInterface.h"
|
|
#include "SND_DeviceManager.h"
|
|
|
|
#include "SYS_System.h"
|
|
|
|
/***/
|
|
|
|
#include "DNA_view3d_types.h"
|
|
#include "DNA_screen_types.h"
|
|
#include "BKE_global.h"
|
|
#include "BIF_screen.h"
|
|
#include "BIF_scrarea.h"
|
|
|
|
#include "BKE_main.h"
|
|
#include "BLI_blenlib.h"
|
|
#include "BLO_readfile.h"
|
|
#include "DNA_scene_types.h"
|
|
/***/
|
|
|
|
static BlendFileData *load_game_data(char *filename) {
|
|
BlendReadError error;
|
|
BlendFileData *bfd= BLO_read_from_file(filename, &error);
|
|
|
|
if (!bfd) {
|
|
printf("Loading %s failed: %s\n", filename, BLO_bre_as_string(error));
|
|
}
|
|
|
|
return bfd;
|
|
}
|
|
|
|
extern "C" void StartKetsjiShell(struct ScrArea *area,
|
|
char* scenename,
|
|
struct Main* maggie,
|
|
struct SpaceIpo *sipo,
|
|
int always_use_expand_framing)
|
|
{
|
|
int exitrequested = KX_EXIT_REQUEST_NO_REQUEST;
|
|
|
|
Main* blenderdata = maggie;
|
|
|
|
char* startscenename = scenename;
|
|
char pathname[160];
|
|
strcpy (pathname, maggie->name);
|
|
STR_String exitstring = "";
|
|
BlendFileData *bfd= NULL;
|
|
|
|
bgl::InitExtensions(1);
|
|
|
|
do
|
|
{
|
|
View3D *v3d= (View3D*) area->spacedata.first;
|
|
|
|
// 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 usemat = false;
|
|
|
|
#ifdef GL_ARB_multitexture
|
|
if(bgl::RAS_EXT_support._ARB_multitexture && bgl::QueryVersion(1, 1)) {
|
|
usemat = (SYS_GetCommandLineInt(syshandle, "blender_material", 0) != 0);
|
|
int unitmax=0;
|
|
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, (GLint*)&unitmax);
|
|
bgl::max_texture_units = MAXTEX>unitmax?unitmax:MAXTEX;
|
|
//std::cout << "using(" << bgl::max_texture_units << ") of(" << unitmax << ") texture units." << std::endl;
|
|
} else {
|
|
bgl::max_texture_units = 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
// create the canvas, rasterizer and rendertools
|
|
RAS_ICanvas* canvas = new KX_BlenderCanvas(area);
|
|
canvas->SetMouseState(RAS_ICanvas::MOUSE_INVISIBLE);
|
|
RAS_IRenderTools* rendertools = new KX_BlenderRenderTools();
|
|
RAS_IRasterizer* rasterizer = NULL;
|
|
|
|
// let's see if we want to use vertexarrays or not
|
|
int usevta = SYS_GetCommandLineInt(syshandle,"vertexarrays",1);
|
|
bool useVertexArrays = (usevta > 0);
|
|
|
|
if (useVertexArrays && bgl::QueryVersion(1, 1))
|
|
rasterizer = new RAS_VAOpenGLRasterizer(canvas);
|
|
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();
|
|
|
|
// get an audiodevice
|
|
SND_DeviceManager::Subscribe();
|
|
SND_IAudioDevice* audiodevice = SND_DeviceManager::Instance();
|
|
audiodevice->UseCD();
|
|
|
|
// 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->SetAudioDevice(audiodevice);
|
|
ketsjiengine->SetUseFixedTime(usefixed);
|
|
ketsjiengine->SetTimingDisplay(frameRate, profile, properties);
|
|
|
|
|
|
|
|
// some blender stuff
|
|
MT_CmMatrix4x4 projmat;
|
|
MT_CmMatrix4x4 viewmat;
|
|
int i;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
float *viewmat_linear= (float*) v3d->viewmat;
|
|
viewmat.setElem(i, viewmat_linear[i]);
|
|
}
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
float *projmat_linear = (float*) area->winmat;
|
|
projmat.setElem(i, projmat_linear[i]);
|
|
}
|
|
|
|
float camzoom = (1.41421 + (v3d->camzoom / 50.0));
|
|
camzoom *= camzoom;
|
|
camzoom = 4.0 / camzoom;
|
|
|
|
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[160];
|
|
// base the actuator filename with respect
|
|
// to the original file working directory
|
|
if (exitstring != "")
|
|
strcpy(basedpath, exitstring.Ptr());
|
|
|
|
BLI_convertstringcode(basedpath, pathname, 0);
|
|
bfd = load_game_data(basedpath);
|
|
|
|
// if it wasn't loaded, try it forced relative
|
|
if (!bfd)
|
|
{
|
|
// just add "//" in front of it
|
|
char temppath[162];
|
|
strcpy(temppath, "//");
|
|
strcat(temppath, basedpath);
|
|
|
|
BLI_convertstringcode(temppath, pathname, 0);
|
|
bfd = load_game_data(temppath);
|
|
}
|
|
|
|
// if we got a loaded blendfile, proceed
|
|
if (bfd)
|
|
{
|
|
blenderdata = bfd->main;
|
|
startscenename = bfd->curscene->id.name + 2;
|
|
}
|
|
// else forget it, we can't find it
|
|
else
|
|
{
|
|
exitrequested = KX_EXIT_REQUEST_QUIT_GAME;
|
|
}
|
|
}
|
|
|
|
Scene *blscene = NULL;
|
|
if (!bfd)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
} else {
|
|
blscene = bfd->curscene;
|
|
}
|
|
|
|
if (blscene)
|
|
{
|
|
int startFrame = blscene->r.cfra;
|
|
ketsjiengine->SetGame2IpoMode(game2ipo,startFrame);
|
|
}
|
|
|
|
|
|
// Quad buffered needs a special window.
|
|
if (blscene->r.stereomode != RAS_IRasterizer::RAS_STEREO_QUADBUFFERED)
|
|
rasterizer->SetStereoMode((RAS_IRasterizer::StereoMode) blscene->r.stereomode);
|
|
|
|
if (exitrequested != KX_EXIT_REQUEST_QUIT_GAME)
|
|
{
|
|
if (v3d->persp != 2)
|
|
{
|
|
ketsjiengine->EnableCameraOverride(startscenename);
|
|
ketsjiengine->SetCameraOverrideUseOrtho((v3d->persp == 0));
|
|
ketsjiengine->SetCameraOverrideProjectionMatrix(projmat);
|
|
ketsjiengine->SetCameraOverrideViewMatrix(viewmat);
|
|
}
|
|
|
|
// create a scene converter, create and convert the startingscene
|
|
KX_ISceneConverter* sceneconverter = new KX_BlenderSceneConverter(maggie,sipo, ketsjiengine);
|
|
ketsjiengine->SetSceneConverter(sceneconverter);
|
|
|
|
if (always_use_expand_framing)
|
|
sceneconverter->SetAlwaysUseExpandFraming(true);
|
|
|
|
if(usemat)
|
|
sceneconverter->SetMaterials(true);
|
|
|
|
KX_Scene* startscene = new KX_Scene(keyboarddevice,
|
|
mousedevice,
|
|
networkdevice,
|
|
audiodevice,
|
|
startscenename);
|
|
|
|
// some python things
|
|
PyObject* dictionaryobject = initGamePythonScripting("Ketsji", psl_Lowest);
|
|
ketsjiengine->SetPythonDictionary(dictionaryobject);
|
|
initRasterizer(rasterizer, canvas);
|
|
initGameLogic(startscene);
|
|
initGameKeys();
|
|
initPythonConstraintBinding();
|
|
|
|
|
|
if (sceneconverter)
|
|
{
|
|
// convert and add scene
|
|
sceneconverter->ConvertScene(
|
|
startscenename,
|
|
startscene,
|
|
dictionaryobject,
|
|
keyboarddevice,
|
|
rendertools,
|
|
canvas);
|
|
ketsjiengine->AddScene(startscene);
|
|
|
|
// init the rasterizer
|
|
rasterizer->Init();
|
|
|
|
// start the engine
|
|
ketsjiengine->StartEngine();
|
|
|
|
// the mainloop
|
|
while (!exitrequested)
|
|
{
|
|
// first check if we want to exit
|
|
exitrequested = ketsjiengine->GetExitCode();
|
|
|
|
// kick the engine
|
|
ketsjiengine->NextFrame();
|
|
|
|
// render the frame
|
|
ketsjiengine->Render();
|
|
|
|
// test for the ESC key
|
|
while (qtest())
|
|
{
|
|
short val;
|
|
unsigned short event = extern_qread(&val);
|
|
|
|
if (keyboarddevice->ConvertBlenderEvent(event,val))
|
|
exitrequested = KX_EXIT_REQUEST_BLENDER_ESC;
|
|
|
|
/* Coordinate conversion... where
|
|
* should this really be?
|
|
*/
|
|
if (event==MOUSEX) {
|
|
val = val - scrarea_get_win_x(area);
|
|
} else if (event==MOUSEY) {
|
|
val = scrarea_get_win_height(area) - (val - scrarea_get_win_y(area)) - 1;
|
|
}
|
|
|
|
mousedevice->ConvertBlenderEvent(event,val);
|
|
}
|
|
}
|
|
exitstring = ketsjiengine->GetExitString();
|
|
|
|
// when exiting the mainloop
|
|
exitGamePythonScripting();
|
|
ketsjiengine->StopEngine();
|
|
networkdevice->Disconnect();
|
|
}
|
|
|
|
if (sceneconverter)
|
|
{
|
|
delete sceneconverter;
|
|
sceneconverter = NULL;
|
|
}
|
|
}
|
|
// set the cursor back to normal
|
|
canvas->SetMouseState(RAS_ICanvas::MOUSE_NORMAL);
|
|
|
|
// clean up some stuff
|
|
audiodevice->StopCD();
|
|
|
|
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;
|
|
}
|
|
SND_DeviceManager::Unsubscribe();
|
|
|
|
} while (exitrequested == KX_EXIT_REQUEST_RESTART_GAME || exitrequested == KX_EXIT_REQUEST_START_OTHER_GAME);
|
|
|
|
if (bfd) BLO_blendfiledata_free(bfd);
|
|
}
|