irrlicht/examples/Demo/CMainMenu.cpp
engineer_apple c130d56b76 Changes in 1.6 TA
- fixed createMeshWith2TCoords
		normals were missing during copy. 
	- addded
		//! Creates a copy of the mesh, which will only consist of S3DVertex vertices.
		IMesh* CMeshManipulator::createMeshWith1TCoords(IMesh* mesh) const

	- added io::IFileSystem* CSceneManager::getFileSystem()
		for preparing to remove the (mostly) unnecessary double member variables
		in many loaders

	-	added virtual const c8* ISceneManager::getAnimatorTypeName(ESCENE_NODE_ANIMATOR_TYPE type);
		to the SceneManger Interface. just like getTypeName is public
	
	- added CSceneNodeAnimatorFlyCircle::radiusEllipsoid.
		if radiusEllipsoid == 0 the default circle animation is done
		else radiusEllipsoid forms the b-axe of the ellipsoid.
		
		-> gummiball bouncing
		
	- added ISceneManager::createFlyStraightAnimator variable bool ping-pong
		used in loop mode to device if start from beginning ( default ) or make ping-pong
		
		-> straight bouncing

	- changed IFileSystem::registerFileArchive
		remove the index of the hiarchy and added a new interface method
	
		//! move the hirarchy of the filesystem. moves sourceIndex relative up or down
		virtual bool moveFileArchive( u32 sourceIndex, s32 relative ) = 0;
	
	 	
	- bugfix and changes in
		SViewFrustum::SViewFrustum
		wrong size of Matrices copy. This bug must be ages old... (typo)
		detected during resizing the Matrices. removed obsolute Matrices
		renamed E_TRANSFORMATION_STATE_2 to E_TRANSFORMATION_STATE_FRUSTUM
		
		therefore also changed SViewFrustum::setTransformState to not tap
		in the pitfall again of wrong memory...
		and renamed it to getTransform, like in the driver
		and Matrices private
		
	- OpenGL:
		Specular 
	- moved
		//! EMT_ONETEXTURE_BLEND: has BlendFactor Alphablending
		inline bool textureBlendFunc_hasAlpha ( E_BLEND_FACTOR factor ) const
		from the material renderes ( 3x declared ) to SMaterial.h

	- updated managed light example to use standard driver selection
	- BurningsVideo
		- LightModel reworked.
			Point Light & Direction Light works for Diffuse Color as aspected
			Specular and Fog still have problems ( needs new pixel shader )
			pushed burningsvideo to 0.42 for this major step

		-	removed obsolete matrix transformations
			renamed E_TRANSFORMATION_STATE_2 to E_TRANSFORMATION_STATE_BURNING

			
	- cleaned line3d.h vector3d.h template behavior.
		many mixed f32/f64 implementations are here. i'm not sure if this should be
		the default behavior to use f64 for example for 1.0/x value, because they
		benefit from more precisions, but in my point of view the user is responsible
		of choosing a vector3d<f32> or vector3d<f64>.
	- added core::squareroot to irrmath.h
		-> for having candidates for faster math in the same file
	- added AllowZWriteOnTransparent from SceneManager to burningsvideo	
		Following SceneManger guideline
	-added hasAlpha() to ITexture
		This info can be used for e.q to downgrade a transparent alpha channel blit
		to add if the texture has no alpha channel.
	


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2199 dfc29bdd-3216-0410-991c-e03cc46cb475
2009-02-05 15:33:55 +00:00

377 lines
11 KiB
C++

// This is a Demo of the Irrlicht Engine (c) 2005-2009 by N.Gebhardt.
// This file is not documented.
#include "CMainMenu.h"
CMainMenu::CMainMenu()
: startButton(0), MenuDevice(0), selected(2), start(false), fullscreen(true),
music(true), shadows(false), additive(false), transparent(true), vsync(false), aa(false)
{
}
bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
bool& outAdditive, bool& outVSync, bool& outAA,
video::E_DRIVER_TYPE& outDriver)
{
//video::E_DRIVER_TYPE driverType = video::EDT_DIRECT3D9;
//video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
video::E_DRIVER_TYPE driverType = video::EDT_BURNINGSVIDEO;
//video::E_DRIVER_TYPE driverType = video::EDT_SOFTWARE;
MenuDevice = createDevice(driverType,
core::dimension2d<u32>(512, 384), 16, false, false, false, this);
if (MenuDevice->getFileSystem()->existFile("irrlicht.dat"))
MenuDevice->getFileSystem()->addZipFileArchive("irrlicht.dat");
else
MenuDevice->getFileSystem()->addZipFileArchive("../../media/irrlicht.dat");
video::IVideoDriver* driver = MenuDevice->getVideoDriver();
scene::ISceneManager* smgr = MenuDevice->getSceneManager();
gui::IGUIEnvironment* guienv = MenuDevice->getGUIEnvironment();
core::stringw str = "Irrlicht Engine Demo v";
str += MenuDevice->getVersion();
MenuDevice->setWindowCaption(str.c_str());
// set new Skin
gui::IGUISkin* newskin = guienv->createSkin(gui::EGST_BURNING_SKIN);
guienv->setSkin(newskin);
newskin->drop();
// load font
gui::IGUIFont* font = guienv->getFont("../../media/fonthaettenschweiler.bmp");
if (font)
guienv->getSkin()->setFont(font);
// add images
const s32 leftX = 260;
// add tab control
gui::IGUITabControl* tabctrl = guienv->addTabControl(core::rect<int>(leftX,10,512-10,384-10),
0, true, true);
gui::IGUITab* optTab = tabctrl->addTab(L"Demo");
gui::IGUITab* aboutTab = tabctrl->addTab(L"About");
// add list box
gui::IGUIListBox* box = guienv->addListBox(core::rect<int>(10,10,220,120), optTab, 1);
box->addItem(L"OpenGL 1.5");
box->addItem(L"Direct3D 8.1");
box->addItem(L"Direct3D 9.0c");
box->addItem(L"Burning's Video 0.42");
box->addItem(L"Irrlicht Software Renderer 1.0");
box->setSelected(selected);
// add button
startButton = guienv->addButton(core::rect<int>(30,295,200,324), optTab, 2, L"Start Demo");
// add checkbox
const s32 d = 50;
guienv->addCheckBox(fullscreen, core::rect<int>(20,85+d,130,110+d),
optTab, 3, L"Fullscreen");
guienv->addCheckBox(music, core::rect<int>(135,85+d,245,110+d),
optTab, 4, L"Music & Sfx");
guienv->addCheckBox(shadows, core::rect<int>(20,110+d,135,135+d),
optTab, 5, L"Realtime shadows");
guienv->addCheckBox(additive, core::rect<int>(20,135+d,230,160+d),
optTab, 6, L"Old HW compatible blending");
guienv->addCheckBox(vsync, core::rect<int>(20,160+d,230,185+d),
optTab, 7, L"Vertical synchronisation");
guienv->addCheckBox(aa, core::rect<int>(20,185+d,230,210+d),
optTab, 8, L"Antialiasing");
// add about text
wchar_t* text2 = L"This is the tech demo of the Irrlicht engine. To start, "\
L"select a video driver which works best with your hardware and press 'Start Demo'.\n"\
L"What you currently see is displayed using the Burning Software Renderer (Thomas Alten).\n"\
L"The Irrlicht Engine was written by me, Nikolaus Gebhardt. The models, "\
L"maps and textures were placed at my disposal by B.Collins, M.Cook and J.Marton. The music was created by "\
L"M.Rohde and is played back by irrKlang.\n"\
L"For more informations, please visit the homepage of the Irrlicht engine:\nhttp://irrlicht.sourceforge.net";
guienv->addStaticText(text2, core::rect<int>(10, 10, 230, 320),
true, true, aboutTab);
// add md2 model
scene::IAnimatedMesh* mesh = smgr->getMesh("../../media/faerie.md2");
scene::IAnimatedMeshSceneNode* modelNode = smgr->addAnimatedMeshSceneNode(mesh);
if (modelNode)
{
modelNode->setPosition( core::vector3df(0.f, 0.f, -5.f) );
modelNode->setMaterialTexture(0, driver->getTexture("../../media/faerie2.bmp"));
modelNode->setMaterialFlag(video::EMF_LIGHTING, true);
modelNode->getMaterial(0).Shininess = 50.f;
//modelNode->getMaterial(0).NormalizeNormals = true;
modelNode->setMD2Animation(scene::EMAT_STAND);
}
// set ambient light (no sun light in the catacombs)
smgr->setAmbientLight( video::SColorf(0.2f, 0.2f, 0.2f) );
scene::ILightSceneNode *light;
scene::ISceneNodeAnimator* anim;
scene::ISceneNode* bill;
enum eLightParticle
{
LIGHT_NONE,
LIGHT_GLOBAL,
LIGHT_RED,
LIGHT_BLUE
};
core::vector3df lightDir[2] = {
core::vector3df(0.f, 0.1f, 0.4f),
core::vector3df(0.f, 0.1f, -0.4f),
};
struct SLightParticle
{
eLightParticle type;
u32 dir;
};
const SLightParticle lightParticle[] =
{
//LIGHT_GLOBAL,0,
LIGHT_RED,0,
LIGHT_BLUE,0,
LIGHT_RED,1,
LIGHT_BLUE,1,
LIGHT_NONE,0
};
const SLightParticle *l = lightParticle;
while ( l->type != LIGHT_NONE )
{
switch ( l->type )
{
case LIGHT_GLOBAL:
// add illumination from the background
light = smgr->addLightSceneNode(0, core::vector3df(10.f,40.f,-5.f),
video::SColorf(0.2f, 0.2f, 0.2f), 90.f);
break;
case LIGHT_RED:
// add light nearly red
light = smgr->addLightSceneNode(0, core::vector3df(0,1,0),
video::SColorf(0.8f, 0.f, 0.f, 0.0f), 30.0f);
// attach red billboard to the light
bill = smgr->addBillboardSceneNode(light, core::dimension2d<f32>(10, 10));
if ( bill )
{
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0, driver->getTexture("../../media/particlered.bmp"));
}
// add fly circle animator to the light
anim = smgr->createFlyCircleAnimator(core::vector3df(0.f,0.f,-5.f),20.f,
0.002f, lightDir [l->dir] );
light->addAnimator(anim);
anim->drop();
break;
case LIGHT_BLUE:
// add light nearly blue
light = smgr->addLightSceneNode(0, core::vector3df(0,1,0),
video::SColorf(0.f, 0.0f, 0.8f, 0.0f), 30.0f);
// attach blue billboard to the light
bill = smgr->addBillboardSceneNode(light, core::dimension2d<f32>(10, 10));
if (bill)
{
bill->setMaterialFlag(video::EMF_LIGHTING, false);
bill->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
bill->setMaterialTexture(0, driver->getTexture("../../media/portal1.bmp"));
}
// add fly circle animator to the light
anim = smgr->createFlyCircleAnimator(core::vector3df(0.f,0.f,-5.f),20.f,
-0.002f, lightDir [l->dir], 0.5f);
light->addAnimator(anim);
anim->drop();
break;
}
l += 1;
}
// create a fixed camera
scene::ICameraSceneNode* cam = smgr->addCameraSceneNode(0, core::vector3df(45,0,0), core::vector3df(0,0,10));
// irrlicht logo and background
// add irrlicht logo
bool oldMipMapState = driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, false);
guienv->addImage(driver->getTexture("../../media/irrlichtlogo3.png"),
core::position2d<s32>(5,5));
video::ITexture* irrlichtBack = driver->getTexture("../../media/demoback.jpg");
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, oldMipMapState);
// query original skin color
getOriginalSkinColor();
// set transparency
setTransparency();
// draw all
while(MenuDevice->run())
{
if (MenuDevice->isWindowActive())
{
driver->beginScene(false, true, video::SColor(0,0,0,0));
if (irrlichtBack)
driver->draw2DImage(irrlichtBack,
core::position2d<int>(0,0));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
}
MenuDevice->drop();
outFullscreen = fullscreen;
outMusic = music;
outShadows = shadows;
outAdditive = additive;
outVSync = vsync;
outAA = aa;
switch(selected)
{
case 0: outDriver = video::EDT_OPENGL; break;
case 1: outDriver = video::EDT_DIRECT3D8; break;
case 2: outDriver = video::EDT_DIRECT3D9; break;
case 3: outDriver = video::EDT_BURNINGSVIDEO; break;
case 4: outDriver = video::EDT_SOFTWARE; break;
}
return start;
}
bool CMainMenu::OnEvent(const SEvent& event)
{
if (event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.Key == KEY_F9 &&
event.KeyInput.PressedDown == false)
{
video::IImage* image = MenuDevice->getVideoDriver()->createScreenShot();
if (image)
{
MenuDevice->getVideoDriver()->writeImageToFile(image, "screenshot_main.jpg");
image->drop();
}
}
else
if (event.EventType == irr::EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_RMOUSE_LEFT_UP )
{
core::rect<s32> r(event.MouseInput.X, event.MouseInput.Y, 0, 0);
gui::IGUIContextMenu* menu = MenuDevice->getGUIEnvironment()->addContextMenu(r, 0, 45);
menu->addItem(L"transparent menus", 666, transparent == false);
menu->addItem(L"solid menus", 666, transparent == true);
menu->addSeparator();
menu->addItem(L"Cancel");
}
else
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
switch(id)
{
case 45: // context menu
if (event.GUIEvent.EventType == gui::EGET_MENU_ITEM_SELECTED)
{
s32 s = ((gui::IGUIContextMenu*)event.GUIEvent.Caller)->getSelectedItem();
if (s == 0 || s == 1)
{
transparent = !transparent;
setTransparency();
}
}
break;
case 1:
if (event.GUIEvent.EventType == gui::EGET_LISTBOX_CHANGED ||
event.GUIEvent.EventType == gui::EGET_LISTBOX_SELECTED_AGAIN)
{
selected = ((gui::IGUIListBox*)event.GUIEvent.Caller)->getSelected();
//startButton->setEnabled(selected != 4);
startButton->setEnabled(true);
}
break;
case 2:
if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED )
{
MenuDevice->closeDevice();
start = true;
}
case 3:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
fullscreen = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 4:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
music = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 5:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
shadows = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 6:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
additive = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 7:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
vsync = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
case 8:
if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED )
aa = ((gui::IGUICheckBox*)event.GUIEvent.Caller)->isChecked();
break;
}
}
return false;
}
void CMainMenu::getOriginalSkinColor()
{
irr::gui::IGUISkin * skin = MenuDevice->getGUIEnvironment()->getSkin();
for (s32 i=0; i<gui::EGDC_COUNT ; ++i)
{
SkinColor[i] = skin->getColor( (gui::EGUI_DEFAULT_COLOR)i );
}
}
void CMainMenu::setTransparency()
{
irr::gui::IGUISkin * skin = MenuDevice->getGUIEnvironment()->getSkin();
for (u32 i=0; i<gui::EGDC_COUNT ; ++i)
{
video::SColor col = SkinColor[i];
if (false == transparent)
col.setAlpha(255);
skin->setColor((gui::EGUI_DEFAULT_COLOR)i, col);
}
}