Merge from trunk, revisions up to 3726. Another major update to latest 1.8 changes.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/branches/ogl-es@3727 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2011-05-18 22:21:50 +00:00
parent 86a1f3f480
commit e379658827
238 changed files with 10084 additions and 3457 deletions

View File

@ -1,5 +1,23 @@
Changes in 1.8 (??.??.2011) Changes in 1.8 (??.??.2011)
- Added IGUIListBox::getItemAt
- Added IGUITable::getColumnWidth
- Added the ability to open an archive from an IReadFile*, added a FileToHeader tool with instructions of how to make a portable app that consists of a single executable file.
- Added ISceneManager::createSceneNodeAnimator to create animators by name
- The Makefile now creates a symlink from the soname to the binary name during install. Binary compatibility is only confirmed between minor releases, so the only useful symlink is from libIrrlicht.so.1.8 to libIrrlicht.so.1.8.0; others should rightly fail.
- Added SMF mesh loader, loads meshes from 3D World Studio. Originally written by Joseph Ellis
- The loader selection process now consistently checks loader lists in reverse order, so new loaders added to Irrlicht override the internal ones. This applies when adding external mesh, image, scene and archive loaders, image writers, plus node, animator and GUI element factories.
- Added getters to retrieve mesh, scene and archive loaders.
- Added ISceneLoader interface and .irr loader. Users can now add their own scene loaders to the scene manager and use them by calling loadScene.
- Renamed IGUIElement::bringToBack to sendToBack, like in Windows - Renamed IGUIElement::bringToBack to sendToBack, like in Windows
- Send EGET_ELEMENT_CLOSED event when context menues should be closed (thx @ Mloren for reporting). - Send EGET_ELEMENT_CLOSED event when context menues should be closed (thx @ Mloren for reporting).
@ -245,6 +263,12 @@ The following names can be queried for the given types:
----------------------------- -----------------------------
Changes in 1.7.3 (??.??.2011) Changes in 1.7.3 (??.??.2011)
- CGUIScrollBar passes unused mousemove-events now to parent element. Fixes focus-bug in ComboBox reported by REDDemon here: http://irrlicht.sourceforge.net/phpBB2/viewtopic.php?t=43474&highlight=
- Fix clipping in CGUITabControl
- Fix clipping in CGUITable, reported by ceyron
- Skip bone weights and additional information in ms3d file if no joint was defined before. - Skip bone weights and additional information in ms3d file if no joint was defined before.
- Fix mem leak in CImage, found by mloren. - Fix mem leak in CImage, found by mloren.
@ -876,6 +900,7 @@ Changes in 1.6 (23.09.2009)
wrong size of Matrices copy. wrong size of Matrices copy.
renamed E_TRANSFORMATION_STATE_2 to E_TRANSFORMATION_STATE_FRUSTUM renamed E_TRANSFORMATION_STATE_2 to E_TRANSFORMATION_STATE_FRUSTUM
therefore also changed SViewFrustum::setTransformState to not tap therefore also changed SViewFrustum::setTransformState to not tap
in the pitfall again of wrong memory... in the pitfall again of wrong memory...
- moved - moved
@ -1819,6 +1844,7 @@ Changes in version 1.4.1 (04 Jun 2008)
- Avoid a crash when passing setSkin the current skin - Avoid a crash when passing setSkin the current skin
- Fixed current frame calculation for non-looped animations. Bug reported by greenya. - Fixed current frame calculation for non-looped animations. Bug reported by greenya.
- Fixed bug in CBillboardSceneNode::setColor, reported by rogerborg - Fixed bug in CBillboardSceneNode::setColor, reported by rogerborg
@ -2508,6 +2534,7 @@ Font improvements:
of Animation name... of Animation name...
- changed spelling "frustrum" to "frustum" - changed spelling "frustrum" to "frustum"
-> changed also SViewFrustrum.h to SViewFrustum.h -> changed also SViewFrustrum.h to SViewFrustum.h
- changed Parameter AutomaticCulling from bool to enum E_CULLING_TYPE - changed Parameter AutomaticCulling from bool to enum E_CULLING_TYPE
@ -4127,6 +4154,7 @@ Changes in version 0.4.2: (13 Dec 2003)
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------
Changes in version 0.4.1: (18 Sep 2003) Changes in version 0.4.1: (18 Sep 2003)
- Input events are now processed faster than repaint and window events. This - Input events are now processed faster than repaint and window events. This
means that input commands now effect things directly, in earlier versions means that input commands now effect things directly, in earlier versions
there could be a delay when there were low frames per second. Some people there could be a delay when there were low frames per second. Some people

View File

@ -40,7 +40,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -101,7 +101,7 @@ int main()
we are able to read from the files in that archive as if they are we are able to read from the files in that archive as if they are
directly stored on the disk. directly stored on the disk.
*/ */
device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3"); device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
/* /*
Now we can load the mesh by calling Now we can load the mesh by calling

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Linux;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -7,7 +7,7 @@
<Option compiler="gcc" /> <Option compiler="gcc" />
<Build> <Build>
<Target title="Windows"> <Target title="Windows">
<Option output="..\..\bin\Win32-gcc\Movement" prefix_auto="0" extension_auto="1" /> <Option output="../../bin/Win32-gcc/Movement" prefix_auto="0" extension_auto="1" />
<Option type="1" /> <Option type="1" />
<Option compiler="gcc" /> <Option compiler="gcc" />
<Option projectResourceIncludeDirsRelation="1" /> <Option projectResourceIncludeDirsRelation="1" />
@ -17,33 +17,34 @@
<Add option="-D_IRR_STATIC_LIB_" /> <Add option="-D_IRR_STATIC_LIB_" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add directory="..\..\lib\Win32-gcc" /> <Add directory="../../lib/Win32-gcc" />
</Linker> </Linker>
</Target> </Target>
<Target title="Linux"> <Target title="Linux">
<Option platforms="Unix;" /> <Option platforms="Unix;" />
<Option output="..\..\bin\Linux\Movement" prefix_auto="0" extension_auto="0" /> <Option output="../../bin/Linux/Movement" prefix_auto="0" extension_auto="0" />
<Option type="1" /> <Option type="1" />
<Option compiler="gcc" /> <Option compiler="gcc" />
<Compiler> <Compiler>
<Add option="-W" />
<Add option="-g" /> <Add option="-g" />
<Add option="-W" />
<Add option="-D_IRR_STATIC_LIB_" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Xxf86vm" /> <Add library="Xxf86vm" />
<Add library="Xcursor" /> <Add library="Xcursor" />
<Add library="GL" /> <Add library="GL" />
<Add directory="..\..\lib\Linux" /> <Add directory="../../lib/Linux" />
</Linker> </Linker>
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />
<Add option="-g" /> <Add option="-g" />
<Add directory="..\..\include" /> <Add directory="../../include" />
</Compiler> </Compiler>
<Linker> <Linker>
<Add library="Irrlicht" /> <Add library="Irrlicht" />

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -53,7 +53,7 @@ int main()
video::IVideoDriver* driver = device->getVideoDriver(); video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager(); scene::ISceneManager* smgr = device->getSceneManager();
device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3"); device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp"); scene::IAnimatedMesh* q3levelmesh = smgr->getMesh("20kdm2.bsp");
scene::IMeshSceneNode* q3node = 0; scene::IMeshSceneNode* q3node = 0;

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -38,7 +38,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -312,6 +312,7 @@ void createToolBox()
env->addStaticText(L":", core::rect<s32>(10,240,150,265), true, false, t1); env->addStaticText(L":", core::rect<s32>(10,240,150,265), true, false, t1);
env->addStaticText(L"Framerate:", env->addStaticText(L"Framerate:",
core::rect<s32>(12,240,75,265), false, false, t1); core::rect<s32>(12,240,75,265), false, false, t1);
// current frame info
env->addStaticText(L"", core::rect<s32>(75,240,200,265), false, false, t1, env->addStaticText(L"", core::rect<s32>(75,240,200,265), false, false, t1,
GUI_ID_ANIMATION_INFO); GUI_ID_ANIMATION_INFO);
scrollbar = env->addScrollBar(true, scrollbar = env->addScrollBar(true,
@ -703,7 +704,7 @@ int main(int argc, char* argv[])
video::SColorf(1.0f,1.0f,1.0f),2000); video::SColorf(1.0f,1.0f,1.0f),2000);
smgr->setAmbientLight(video::SColorf(0.3f,0.3f,0.3f)); smgr->setAmbientLight(video::SColorf(0.3f,0.3f,0.3f));
// add our media directory as "search path" // add our media directory as "search path"
Device->getFileSystem()->addFolderFileArchive("../../media/"); Device->getFileSystem()->addFileArchive("../../media/");
/* /*
The next step is to read the configuration file. It is stored in the xml The next step is to read the configuration file. It is stored in the xml

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-g" /> <Add option="-g" />

View File

@ -328,7 +328,7 @@ int main()
// scale the mesh by factor 50 // scale the mesh by factor 50
core::matrix4 m; core::matrix4 m;
m.setScale ( core::vector3df(50,50,50) ); m.setScale ( core::vector3df(50,50,50) );
manipulator->transformMesh( tangentSphereMesh, m ); manipulator->transform( tangentSphereMesh, m );
earth = smgr->addMeshSceneNode(tangentSphereMesh); earth = smgr->addMeshSceneNode(tangentSphereMesh);
@ -427,7 +427,7 @@ int main()
core::aabbox3d<f32>(-3,0,-3,3,1,3), core::aabbox3d<f32>(-3,0,-3,3,1,3),
core::vector3df(0.0f,0.03f,0.0f), core::vector3df(0.0f,0.03f,0.0f),
80,100, 80,100,
video::SColor(0,255,255,255), video::SColor(0,255,255,255), video::SColor(10,255,255,255), video::SColor(10,255,255,255),
400,1100); 400,1100);
em->setMinStartSize(core::dimension2d<f32>(30.0f, 40.0f)); em->setMinStartSize(core::dimension2d<f32>(30.0f, 40.0f));
em->setMaxStartSize(core::dimension2d<f32>(30.0f, 40.0f)); em->setMaxStartSize(core::dimension2d<f32>(30.0f, 40.0f));
@ -444,7 +444,7 @@ int main()
ps->setMaterialFlag(video::EMF_LIGHTING, false); ps->setMaterialFlag(video::EMF_LIGHTING, false);
ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); ps->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
ps->setMaterialTexture(0, driver->getTexture("../../media/fireball.bmp")); ps->setMaterialTexture(0, driver->getTexture("../../media/fireball.bmp"));
ps->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA); ps->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR);
MyEventReceiver receiver(room, earth, env, driver); MyEventReceiver receiver(room, earth, env, driver);
device->setEventReceiver(&receiver); device->setEventReceiver(&receiver);

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -29,10 +29,10 @@ class MyEventReceiver : public IEventReceiver
public: public:
MyEventReceiver(scene::ISceneNode* terrain, scene::ISceneNode* skybox, scene::ISceneNode* skydome) : MyEventReceiver(scene::ISceneNode* terrain, scene::ISceneNode* skybox, scene::ISceneNode* skydome) :
Terrain(terrain), Skybox(skybox), Skydome(skydome), showBox(true) Terrain(terrain), Skybox(skybox), Skydome(skydome), showBox(true), showDebug(false)
{ {
Skybox->setVisible(true); Skybox->setVisible(showBox);
Skydome->setVisible(false); Skydome->setVisible(!showBox);
} }
bool OnEvent(const SEvent& event) bool OnEvent(const SEvent& event)
@ -62,6 +62,10 @@ public:
Skybox->setVisible(showBox); Skybox->setVisible(showBox);
Skydome->setVisible(!showBox); Skydome->setVisible(!showBox);
return true; return true;
case irr::KEY_KEY_X: // toggle debug information
showDebug=!showDebug;
Terrain->setDebugDataVisible(showDebug?scene::EDS_BBOX_ALL:scene::EDS_OFF);
return true;
default: default:
break; break;
} }
@ -75,6 +79,7 @@ private:
scene::ISceneNode* Skybox; scene::ISceneNode* Skybox;
scene::ISceneNode* Skydome; scene::ISceneNode* Skydome;
bool showBox; bool showBox;
bool showDebug;
}; };
@ -177,7 +182,6 @@ int main()
terrain->setMaterialType(video::EMT_DETAIL_MAP); terrain->setMaterialType(video::EMT_DETAIL_MAP);
terrain->scaleTexture(1.0f, 20.0f); terrain->scaleTexture(1.0f, 20.0f);
//terrain->setDebugDataVisible ( true );
/* /*
To be able to do collision with the terrain, we create a triangle selector. To be able to do collision with the terrain, we create a triangle selector.

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -40,7 +40,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -38,7 +38,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -31,7 +31,7 @@ to ask the user for a driver type using the console.
#endif #endif
#ifdef IRRLICHT_QUAKE3_ARENA #ifdef IRRLICHT_QUAKE3_ARENA
#define QUAKE3_STORAGE_FORMAT addZipFileArchive #define QUAKE3_STORAGE_FORMAT addFileArchive
#define QUAKE3_STORAGE_1 "../../media/map-20kdm2.pk3" #define QUAKE3_STORAGE_1 "../../media/map-20kdm2.pk3"
#define QUAKE3_MAP_NAME "maps/20kdm2.bsp" #define QUAKE3_MAP_NAME "maps/20kdm2.bsp"
#endif #endif
@ -145,7 +145,7 @@ int IRRCALLCONV main(int argc, char* argv[])
gui::IGUIEnvironment* gui = device->getGUIEnvironment(); gui::IGUIEnvironment* gui = device->getGUIEnvironment();
//! add our private media directory to the file system //! add our private media directory to the file system
device->getFileSystem()->addFolderFileArchive("../../media/"); device->getFileSystem()->addFileArchive("../../media/");
/* /*
To display the Quake 3 map, we first need to load it. Quake 3 maps To display the Quake 3 map, we first need to load it. Quake 3 maps

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -109,7 +109,7 @@ int main()
} }
//Load map //Load map
device->getFileSystem()->addZipFileArchive("../../media/map-20kdm2.pk3"); device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");
IAnimatedMesh *map = smgr->getMesh("20kdm2.bsp"); IAnimatedMesh *map = smgr->getMesh("20kdm2.bsp");
if (map) if (map)
{ {

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -40,7 +40,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -63,19 +63,17 @@ class CMyLightManager : public scene::ILightManager, public IEventReceiver
// These data represent the state information that this light manager // These data represent the state information that this light manager
// is interested in. // is interested in.
scene::ISceneManager * SceneManager; scene::ISceneManager * SceneManager;
core::array<scene::ILightSceneNode*> * SceneLightList; core::array<scene::ISceneNode*> * SceneLightList;
scene::E_SCENE_NODE_RENDER_PASS CurrentRenderPass; scene::E_SCENE_NODE_RENDER_PASS CurrentRenderPass;
scene::ISceneNode * CurrentSceneNode; scene::ISceneNode * CurrentSceneNode;
public: public:
CMyLightManager(scene::ISceneManager* sceneManager) CMyLightManager(scene::ISceneManager* sceneManager)
: Mode(NO_MANAGEMENT), RequestedMode(NO_MANAGEMENT), : Mode(NO_MANAGEMENT), RequestedMode(NO_MANAGEMENT),
SceneManager(sceneManager), SceneLightList(0), SceneManager(sceneManager), SceneLightList(0),
CurrentRenderPass(scene::ESNRP_NONE), CurrentSceneNode(0) CurrentRenderPass(scene::ESNRP_NONE), CurrentSceneNode(0)
{ } { }
virtual ~CMyLightManager(void) { }
// The input receiver interface, which just switches light management strategy // The input receiver interface, which just switches light management strategy
bool OnEvent(const SEvent & event) bool OnEvent(const SEvent & event)
{ {
@ -111,7 +109,7 @@ public:
// This is called before the first scene node is rendered. // This is called before the first scene node is rendered.
virtual void OnPreRender(core::array<scene::ILightSceneNode*> & lightList) virtual void OnPreRender(core::array<scene::ISceneNode*> & lightList)
{ {
// Update the mode; changing it here ensures that it's consistent throughout a render // Update the mode; changing it here ensures that it's consistent throughout a render
Mode = RequestedMode; Mode = RequestedMode;
@ -127,7 +125,7 @@ public:
// lights on to ensure that they are in a consistent state. You wouldn't normally have // lights on to ensure that they are in a consistent state. You wouldn't normally have
// to do this when using a light manager, since you'd continue to do light management // to do this when using a light manager, since you'd continue to do light management
// yourself. // yourself.
for(u32 i = 0; i < SceneLightList->size(); i++) for (u32 i = 0; i < SceneLightList->size(); i++)
(*SceneLightList)[i]->setVisible(true); (*SceneLightList)[i]->setVisible(true);
} }
@ -140,9 +138,9 @@ public:
virtual void OnRenderPassPostRender(scene::E_SCENE_NODE_RENDER_PASS renderPass) virtual void OnRenderPassPostRender(scene::E_SCENE_NODE_RENDER_PASS renderPass)
{ {
// I only want solid nodes to be lit, so after the solid pass, turn all lights off. // I only want solid nodes to be lit, so after the solid pass, turn all lights off.
if(scene::ESNRP_SOLID == renderPass) if (scene::ESNRP_SOLID == renderPass)
{ {
for(u32 i = 0; i < SceneLightList->size(); ++i) for (u32 i = 0; i < SceneLightList->size(); ++i)
(*SceneLightList)[i]->setVisible(false); (*SceneLightList)[i]->setVisible(false);
} }
} }
@ -178,8 +176,8 @@ public:
u32 i; u32 i;
for(i = 0; i < SceneLightList->size(); ++i) for(i = 0; i < SceneLightList->size(); ++i)
{ {
scene::ILightSceneNode* lightNode = (*SceneLightList)[i]; scene::ISceneNode* lightNode = (*SceneLightList)[i];
f64 distance = lightNode->getAbsolutePosition().getDistanceFromSQ(nodePosition); const f64 distance = lightNode->getAbsolutePosition().getDistanceFromSQ(nodePosition);
sortingArray.push_back(LightDistanceElement(lightNode, distance)); sortingArray.push_back(LightDistanceElement(lightNode, distance));
} }
@ -189,7 +187,6 @@ public:
// Turn on the three nearest lights, and turn the others off. // Turn on the three nearest lights, and turn the others off.
for(i = 0; i < sortingArray.size(); ++i) for(i = 0; i < sortingArray.size(); ++i)
sortingArray[i].node->setVisible(i < 3); sortingArray[i].node->setVisible(i < 3);
} }
else if(LIGHTS_IN_ZONE == Mode) else if(LIGHTS_IN_ZONE == Mode)
{ {
@ -200,7 +197,9 @@ public:
// knowledge of how this particular scene graph is organised. // knowledge of how this particular scene graph is organised.
for (u32 i = 0; i < SceneLightList->size(); ++i) for (u32 i = 0; i < SceneLightList->size(); ++i)
{ {
scene::ILightSceneNode* lightNode = (*SceneLightList)[i]; if ((*SceneLightList)[i]->getType() != scene::ESNT_LIGHT)
continue;
scene::ILightSceneNode* lightNode = static_cast<scene::ILightSceneNode*>((*SceneLightList)[i]);
video::SLight & lightData = lightNode->getLightData(); video::SLight & lightData = lightNode->getLightData();
if (video::ELT_DIRECTIONAL != lightData.Type) if (video::ELT_DIRECTIONAL != lightData.Type)
@ -224,10 +223,10 @@ private:
// Find the empty scene node that is the parent of the specified node // Find the empty scene node that is the parent of the specified node
scene::ISceneNode * findZone(scene::ISceneNode * node) scene::ISceneNode * findZone(scene::ISceneNode * node)
{ {
if(!node) if (!node)
return 0; return 0;
if(node->getType() == scene::ESNT_EMPTY) if (node->getType() == scene::ESNT_EMPTY)
return node; return node;
return findZone(node->getParent()); return findZone(node->getParent());
@ -239,11 +238,10 @@ private:
{ {
core::list<scene::ISceneNode*> const & children = node->getChildren(); core::list<scene::ISceneNode*> const & children = node->getChildren();
for (core::list<scene::ISceneNode*>::ConstIterator child = children.begin(); for (core::list<scene::ISceneNode*>::ConstIterator child = children.begin();
child != children.end(); child != children.end(); ++child)
++child)
{ {
if((*child)->getType() == scene::ESNT_LIGHT) if ((*child)->getType() == scene::ESNT_LIGHT)
static_cast<scene::ILightSceneNode*>(*child)->setVisible(true); (*child)->setVisible(true);
else // Assume that lights don't have any children that are also lights else // Assume that lights don't have any children that are also lights
turnOnZoneLights(*child); turnOnZoneLights(*child);
} }
@ -256,10 +254,10 @@ private:
public: public:
LightDistanceElement() {}; LightDistanceElement() {};
LightDistanceElement(scene::ILightSceneNode* n, f64 d) LightDistanceElement(scene::ISceneNode* n, f64 d)
: node(n), distance(d) { } : node(n), distance(d) { }
scene::ILightSceneNode* node; scene::ISceneNode* node;
f64 distance; f64 distance;
// Lower distance elements are sorted to the start of the array // Lower distance elements are sorted to the start of the array

View File

@ -40,7 +40,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -1888,7 +1888,7 @@ void CQuake3EventHandler::createParticleImpacts( u32 now )
pas->setMaterialFlag(video::EMF_LIGHTING, false); pas->setMaterialFlag(video::EMF_LIGHTING, false);
pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); pas->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
pas->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA ); pas->setMaterialType(video::EMT_TRANSPARENT_ADD_COLOR );
pas->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture( smoke[g].texture )); pas->setMaterialTexture(0, Game->Device->getVideoDriver()->getTexture( smoke[g].texture ));
} }

View File

@ -39,7 +39,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9,00" Version="7.10"
Name="22.MaterialViewer" Name="22.MaterialViewer"
ProjectGUID="{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}" ProjectGUID="{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}"
TargetFrameworkVersion="131072" TargetFrameworkVersion="131072"

View File

@ -3,7 +3,7 @@
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9.00"
Name="22.MaterialViewer_vc9" Name="22.MaterialViewer_vc9"
ProjectGUID="{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}" ProjectGUID="{F4C8112D-57A8-4D01-BB62-BAC6A09A6902}"
RootNamespace="MaterialViewer_vc9" RootNamespace="MaterialViewer_vc9"
TargetFrameworkVersion="131072" TargetFrameworkVersion="131072"
> >

View File

@ -227,41 +227,37 @@ protected:
{ {
video::SColor col; video::SColor col;
u32 alpha=col.getAlpha(); if (EditAlpha)
if ( EditAlpha )
{ {
alpha = (u32)core::strtol10( core::stringc( EditAlpha->getText() ).c_str(), 0); u32 alpha = core::strtoul10(core::stringc(EditAlpha->getText()).c_str());
if ( alpha > 255 ) if (alpha > 255)
alpha = 255; alpha = 255;
col.setAlpha(alpha);
} }
col.setAlpha(alpha);
u32 red=col.getRed(); if (EditRed)
if ( EditRed )
{ {
red = (u32)core::strtol10( core::stringc( EditRed->getText() ).c_str(), 0); u32 red = core::strtoul10(core::stringc(EditRed->getText()).c_str());
if ( red > 255 ) if (red > 255)
red = 255; red = 255;
col.setRed(red);
} }
col.setRed(red);
u32 green=col.getGreen(); if (EditGreen)
if ( EditGreen )
{ {
green = (u32)core::strtol10( core::stringc( EditGreen->getText() ).c_str(), 0); u32 green = core::strtoul10(core::stringc(EditGreen->getText()).c_str());
if ( green > 255 ) if (green > 255)
green = 255; green = 255;
col.setGreen(green);
} }
col.setGreen(green);
u32 blue=col.getBlue(); if (EditBlue)
if ( EditBlue )
{ {
blue = (u32)core::strtol10( core::stringc( EditBlue->getText() ).c_str(), 0); u32 blue = core::strtoul10(core::stringc(EditBlue->getText()).c_str());
if ( blue > 255 ) if (blue > 255)
blue = 255; blue = 255;
col.setBlue(blue);
} }
col.setBlue(blue);
return col; return col;
} }

View File

@ -40,7 +40,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -40,7 +40,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-W" /> <Add option="-W" />

View File

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>25.XmlHandling</ProjectName>
<ProjectGuid>{8FDA260E-EF27-4F8C-8720-7AF707DD0D9E}</ProjectGuid>
<RootNamespace>25.XmlHandling</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\bin\Win32-VisualStudio\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\bin\Win32-VisualStudio\</OutDir>
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>false</ExceptionHandling>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>
</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -24,7 +24,7 @@ using namespace gui;
* and manages the options. * and manages the options.
* *
* *
* The class makes use of irrMap which is a an associative arrays using a red-black tree * The class makes use of irrMap which is a an associative arrays using a red-black tree
* it allows easy mapping of a key to a value, along the way there is some information on how to use it * it allows easy mapping of a key to a value, along the way there is some information on how to use it
* *
*/ */
@ -39,26 +39,24 @@ public:
SettingManager(const stringw& settings_file): SettingsFile(settings_file), NullDevice(0) SettingManager(const stringw& settings_file): SettingsFile(settings_file), NullDevice(0)
{ {
// Irrlicht null device, we want to load settings before we actually created our device, therefore, nulldevice // Irrlicht null device, we want to load settings before we actually created our device, therefore, nulldevice
NullDevice = irr::createDevice(irr::video::EDT_NULL); NullDevice = irr::createDevice(irr::video::EDT_NULL);
//DriverOptions is an irrlicht map, //DriverOptions is an irrlicht map,
//we can insert values in the map in two ways by calling insert(key,value) or by using the [key] operator //we can insert values in the map in two ways by calling insert(key,value) or by using the [key] operator
//the [] operator overrides values if they already exist //the [] operator overrides values if they already exist
DriverOptions.insert(L"Software", EDT_SOFTWARE ); DriverOptions.insert(L"Software", EDT_SOFTWARE);
DriverOptions.insert(L"OpenGL", EDT_OPENGL ); DriverOptions.insert(L"OpenGL", EDT_OPENGL);
DriverOptions.insert(L"Direct3D9", EDT_DIRECT3D9 ); DriverOptions.insert(L"Direct3D9", EDT_DIRECT3D9);
//some resolution options //some resolution options
ResolutionOptions.insert(L"640x480", dimension2du(640,480) ); ResolutionOptions.insert(L"640x480", dimension2du(640,480));
ResolutionOptions.insert(L"800x600", dimension2du(800,600) ); ResolutionOptions.insert(L"800x600", dimension2du(800,600));
ResolutionOptions.insert(L"1024x768", dimension2du(1024,768) ); ResolutionOptions.insert(L"1024x768", dimension2du(1024,768));
//our preferred defaults //our preferred defaults
SettingMap.insert(L"driver", L"Direct3D9"); //0 is software SettingMap.insert(L"driver", L"Direct3D9");
SettingMap.insert(L"resolution", L"640x480"); //0 is 640x480 SettingMap.insert(L"resolution", L"640x480");
SettingMap.insert(L"fullscreen", L"0"); //0 is false SettingMap.insert(L"fullscreen", L"0"); //0 is false
} }
/** /**
@ -67,7 +65,7 @@ public:
*/ */
~SettingManager() ~SettingManager()
{ {
if(NullDevice) if (NullDevice)
{ {
NullDevice->closeDevice(); NullDevice->closeDevice();
NullDevice->drop(); NullDevice->drop();
@ -91,28 +89,28 @@ public:
bool load() bool load()
{ {
//if not able to create device dont attempt to load //if not able to create device dont attempt to load
if(!NullDevice) if (!NullDevice)
return false; return false;
irr::io::IXMLReader* xml = NullDevice->getFileSystem()->createXMLReader(SettingsFile); //create xml reader irr::io::IXMLReader* xml = NullDevice->getFileSystem()->createXMLReader(SettingsFile); //create xml reader
if ( !xml ) if (!xml)
return false; return false;
const stringw settingTag(L"setting"); //we'll be looking for this tag in the xml const stringw settingTag(L"setting"); //we'll be looking for this tag in the xml
stringw currentSection; //keep track of our currentsection stringw currentSection; //keep track of our currentsection
const stringw videoTag(L"video"); //constant for videotag const stringw videoTag(L"video"); //constant for videotag
//while there is more to read //while there is more to read
while(xml->read()) while (xml->read())
{ {
//check the node type //check the node type
switch(xml->getNodeType()) switch (xml->getNodeType())
{ {
//we found a new element //we found a new element
case irr::io::EXN_ELEMENT: case irr::io::EXN_ELEMENT:
{ {
//we currently are in the empty or mygame section and find the video tag so we set our current section to video //we currently are in the empty or mygame section and find the video tag so we set our current section to video
if(currentSection.empty() && videoTag.equals_ignore_case(xml->getNodeName())) if (currentSection.empty() && videoTag.equals_ignore_case(xml->getNodeName()))
{ {
currentSection = videoTag; currentSection = videoTag;
} }
@ -120,21 +118,20 @@ public:
else if (currentSection.equals_ignore_case(videoTag) && settingTag.equals_ignore_case(xml->getNodeName() )) else if (currentSection.equals_ignore_case(videoTag) && settingTag.equals_ignore_case(xml->getNodeName() ))
{ {
//read in the key //read in the key
stringw key = xml->getAttributeValueSafe(L"name"); stringw key = xml->getAttributeValueSafe(L"name");
//if there actually is a key to set //if there actually is a key to set
if( !key.empty()) if (!key.empty())
{ {
//set the setting in the map to the value, //set the setting in the map to the value,
//the [] operator overrides values if they already exist or inserts a new key value //the [] operator overrides values if they already exist or inserts a new key value
//pair into the settings map if it was not defined yet //pair into the settings map if it was not defined yet
SettingMap[ key ] = xml->getAttributeValueSafe(L"value"); SettingMap[key] = xml->getAttributeValueSafe(L"value");
} }
} }
//.. //..
// You can add your own sections and tags to read in here // You can add your own sections and tags to read in here
//.. //..
} }
break; break;
@ -160,12 +157,12 @@ public:
{ {
//if not able to create device don't attempt to save //if not able to create device don't attempt to save
if(!NullDevice) if (!NullDevice)
return false; return false;
//create xml writer //create xml writer
irr::io::IXMLWriter* xwriter = NullDevice->getFileSystem()->createXMLWriter( SettingsFile ); irr::io::IXMLWriter* xwriter = NullDevice->getFileSystem()->createXMLWriter( SettingsFile );
if(!xwriter) if (!xwriter)
return false; return false;
//write out the obligatory xml header. Each xml-file needs to have exactly one of those. //write out the obligatory xml header. Each xml-file needs to have exactly one of those.
@ -227,8 +224,8 @@ public:
/** /**
* Get setting as string * Get setting as string
* @param key name of setting * @param key Name of setting
* @return empty string if the settings is not found, else value of the setting * @return Empty string if the settings is not found, else value of the setting
*/ */
stringw getSetting(const stringw& key) const stringw getSetting(const stringw& key) const
{ {
@ -240,18 +237,17 @@ public:
return n->getValue(); return n->getValue();
else else
return L""; return L"";
} }
/** /**
* Get setting as bool * Get setting as bool
* @param key name of setting * @param key Name of setting
* @return false if the key cannot be found, else true if the setting == 1 * @return False if the key cannot be found, else true if the setting == 1
*/ */
bool getSettingAsBoolean(const stringw& key ) const bool getSettingAsBoolean(const stringw& key ) const
{ {
stringw s = getSetting(key); stringw s = getSetting(key);
if(s.empty()) if (s.empty())
return false; return false;
return s.equals_ignore_case(L"1"); return s.equals_ignore_case(L"1");
} }
@ -259,33 +255,29 @@ public:
/** /**
* Get setting as integer NOTE: function is not used in example but provided for completeness * Get setting as integer NOTE: function is not used in example but provided for completeness
* @param key name of setting * @param key name of setting
* @return 0 if the key cannot be found, else the setting converted to an integer * @return 0 if the key cannot be found, else the setting converted to an integer
*/ */
s32 getSettingAsInteger(const stringw& key ) const s32 getSettingAsInteger(const stringw& key) const
{ {
//we implicitly cast to string instead of stringw because strtol10 does not accept wide strings //we implicitly cast to string instead of stringw because strtol10 does not accept wide strings
stringc s = getSetting(key); const stringc s = getSetting(key);
if(s.empty()) if (s.empty())
return 0; return 0;
return strtol10(s.c_str()); return strtol10(s.c_str());
} }
public: public:
map<stringw, s32> DriverOptions; //available options for driver config map<stringw, s32> DriverOptions; //available options for driver config
map<stringw, dimension2du> ResolutionOptions; //available options for resolution config map<stringw, dimension2du> ResolutionOptions; //available options for resolution config
private: private:
SettingManager(const SettingManager& other); // defined but not implemented
SettingManager(const SettingManager& other); // defined but not implemented
SettingManager& operator=(const SettingManager& other); // defined but not implemented SettingManager& operator=(const SettingManager& other); // defined but not implemented
map<stringw, stringw> SettingMap; //current config map<stringw, stringw> SettingMap; //current config
stringw SettingsFile; // location of the xml, usually the
irr::IrrlichtDevice* NullDevice;
stringw SettingsFile; // location of the xml, usually the
irr::IrrlichtDevice* NullDevice;
}; };
/** /**
@ -295,35 +287,35 @@ struct SAppContext
{ {
SAppContext() SAppContext()
: Device(0),Gui(0), Driver(0), Settings(0), ShouldQuit(false), : Device(0),Gui(0), Driver(0), Settings(0), ShouldQuit(false),
ButtonSave(0), ButtonExit(0), ListboxDriver(0), ButtonSave(0), ButtonExit(0), ListboxDriver(0),
ListboxResolution(0), CheckboxFullscreen(0) ListboxResolution(0), CheckboxFullscreen(0)
{ {
} }
~SAppContext() ~SAppContext()
{ {
if(Settings) if (Settings)
delete Settings; delete Settings;
if(Device) if (Device)
{ {
Device->closeDevice(); Device->closeDevice();
Device->drop(); Device->drop();
} }
} }
IrrlichtDevice * Device; IrrlichtDevice* Device;
IGUIEnvironment* Gui; IGUIEnvironment* Gui;
IVideoDriver* Driver; IVideoDriver* Driver;
SettingManager* Settings; SettingManager* Settings;
bool ShouldQuit; bool ShouldQuit;
//settings dialog //settings dialog
IGUIButton* ButtonSave; IGUIButton* ButtonSave;
IGUIButton* ButtonExit; IGUIButton* ButtonExit;
IGUIListBox* ListboxDriver; IGUIListBox* ListboxDriver;
IGUIListBox* ListboxResolution; IGUIListBox* ListboxResolution;
IGUICheckBox* CheckboxFullscreen; IGUICheckBox* CheckboxFullscreen;
}; };
/* /*
@ -347,23 +339,23 @@ public:
if ( event.GUIEvent.Caller == App.ButtonSave ) if ( event.GUIEvent.Caller == App.ButtonSave )
{ {
//if there is a selection write it //if there is a selection write it
if( App.ListboxDriver->getSelected() != -1) if ( App.ListboxDriver->getSelected() != -1)
App.Settings->setSetting(L"driver", App.ListboxDriver->getListItem(App.ListboxDriver->getSelected())); App.Settings->setSetting(L"driver", App.ListboxDriver->getListItem(App.ListboxDriver->getSelected()));
//if there is a selection write it //if there is a selection write it
if( App.ListboxResolution->getSelected() != -1) if ( App.ListboxResolution->getSelected() != -1)
App.Settings->setSetting(L"resolution", App.ListboxResolution->getListItem(App.ListboxResolution->getSelected())); App.Settings->setSetting(L"resolution", App.ListboxResolution->getListItem(App.ListboxResolution->getSelected()));
App.Settings->setSetting(L"fullscreen", App.CheckboxFullscreen->isChecked()); App.Settings->setSetting(L"fullscreen", App.CheckboxFullscreen->isChecked());
if(App.Settings->save()) if (App.Settings->save())
{ {
App.Gui->addMessageBox(L"settings save",L"settings saved, please restart for settings to change effect","",true); App.Gui->addMessageBox(L"settings save",L"settings saved, please restart for settings to change effect","",true);
} }
} }
// cancel/exit button clicked, tell the application to exit // cancel/exit button clicked, tell the application to exit
else if( event.GUIEvent.Caller == App.ButtonExit) else if ( event.GUIEvent.Caller == App.ButtonExit)
{ {
App.ShouldQuit = true; App.ShouldQuit = true;
} }
@ -412,7 +404,7 @@ void createSettingsDialog(SAppContext& app)
// add listbox for resolution choice // add listbox for resolution choice
app.Gui->addStaticText (L"Resolution", rect< s32 >(10,130, 200, 140), false, true, windowSettings); app.Gui->addStaticText (L"Resolution", rect< s32 >(10,130, 200, 140), false, true, windowSettings);
app.ListboxResolution = app.Gui->addListBox(rect<s32>(10,140,220,200), windowSettings, 1,true); app.ListboxResolution = app.Gui->addListBox(rect<s32>(10,140,220,200), windowSettings, 1,true);
//add all available options tothe resolution listbox //add all available options tothe resolution listbox
map<stringw, dimension2du>::Iterator ri = app.Settings->ResolutionOptions.getIterator(); map<stringw, dimension2du>::Iterator ri = app.Settings->ResolutionOptions.getIterator();
@ -423,16 +415,20 @@ void createSettingsDialog(SAppContext& app)
app.ListboxResolution->setSelected(app.Settings->getSetting("resolution").c_str()); app.ListboxResolution->setSelected(app.Settings->getSetting("resolution").c_str());
//add checkbox to toggle fullscreen, initially set to loaded setting //add checkbox to toggle fullscreen, initially set to loaded setting
app.CheckboxFullscreen = app.Gui->addCheckBox(app.Settings->getSettingAsBoolean("fullscreen"), app.CheckboxFullscreen = app.Gui->addCheckBox(
rect<s32>(10,220,220,240), app.Settings->getSettingAsBoolean("fullscreen"),
windowSettings, -1, rect<s32>(10,220,220,240), windowSettings, -1,
L"Fullscreen"); L"Fullscreen");
//last but not least add save button //last but not least add save button
app.ButtonSave = app.Gui->addButton(rect<s32>(80,250,150,270), windowSettings, 2, L"Save video settings"); app.ButtonSave = app.Gui->addButton(
rect<s32>(80,250,150,270), windowSettings, 2,
L"Save video settings");
//exit/cancel button //exit/cancel button
app.ButtonExit = app.Gui->addButton(rect<s32>(160,250,240,270), windowSettings, 2, L"Cancel and exit"); app.ButtonExit = app.Gui->addButton(
rect<s32>(160,250,240,270), windowSettings, 2,
L"Cancel and exit");
} }
int main() int main()
@ -446,12 +442,12 @@ int main()
param.WindowSize.set(640,480); param.WindowSize.set(640,480);
/** /**
* Try to load config. * Try to load config.
* I leave it as an exercise of the reader to store the configuration in the local application data folder, * I leave it as an exercise of the reader to store the configuration in the local application data folder,
* the only logical place to store config data for games. For all other operating systems I redirect to your manuals * the only logical place to store config data for games. For all other operating systems I redirect to your manuals
*/ */
app.Settings = new SettingManager("../../media/settings.xml"); app.Settings = new SettingManager("../../media/settings.xml");
if( !app.Settings->load() ) if ( !app.Settings->load() )
{ {
// ... // ...
// Here add your own exception handling, for now we continue because there are defaults set in SettingManager constructor // Here add your own exception handling, for now we continue because there are defaults set in SettingManager constructor
@ -467,9 +463,9 @@ int main()
//see DriverOptions in the settingmanager class for details //see DriverOptions in the settingmanager class for details
map<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting("driver") ); map<stringw, s32>::Node* driver = app.Settings->DriverOptions.find( app.Settings->getSetting("driver") );
if(driver) if (driver)
{ {
if( irr::IrrlichtDevice::isDriverSupported( static_cast<E_DRIVER_TYPE>( driver->getValue() ))) if ( irr::IrrlichtDevice::isDriverSupported( static_cast<E_DRIVER_TYPE>( driver->getValue() )))
{ {
// selected driver is supported, so we use it. // selected driver is supported, so we use it.
param.DriverType = static_cast<E_DRIVER_TYPE>( driver->getValue()); param.DriverType = static_cast<E_DRIVER_TYPE>( driver->getValue());
@ -478,7 +474,7 @@ int main()
//map resolution setting to dimension in a similar way as demonstrated above //map resolution setting to dimension in a similar way as demonstrated above
map<stringw, dimension2du>::Node* res = app.Settings->ResolutionOptions.find( app.Settings->getSetting("resolution") ); map<stringw, dimension2du>::Node* res = app.Settings->ResolutionOptions.find( app.Settings->getSetting("resolution") );
if(res) if (res)
{ {
param.WindowSize = res->getValue(); param.WindowSize = res->getValue();
} }
@ -506,9 +502,9 @@ int main()
app.Device->setEventReceiver(&receiver); app.Device->setEventReceiver(&receiver);
//enter main loop //enter main loop
while(!app.ShouldQuit && app.Device->run()) while (!app.ShouldQuit && app.Device->run())
{ {
if(app.Device->isWindowActive()) if (app.Device->isWindowActive())
{ {
app.Driver->beginScene(true, true, SColor(0,200,200,200)); app.Driver->beginScene(true, true, SColor(0,200,200,200));
app.Gui->drawAll(); app.Gui->drawAll();
@ -521,3 +517,4 @@ int main()
return 0; return 0;
} }

View File

@ -0,0 +1,39 @@
# Makefile for Irrlicht Examples
# It's usually sufficient to change just the target name and source file list
# and be sure that CXX is set to a valid compiler
Target = 26.OcclusionQuery
Sources = main.cpp
# general compiler settings
CPPFLAGS = -I../../include -I/usr/X11R6/include
CXXFLAGS = -O3 -ffast-math
#CXXFLAGS = -g -Wall
#default target is Linux
all: all_linux
ifeq ($(HOSTTYPE), x86_64)
LIBSELECT=64
endif
# target specific settings
all_linux: LDFLAGS = -L/usr/X11R6/lib$(LIBSELECT) -L../../lib/Linux -lIrrlicht -lGL -lXxf86vm -lXext -lX11 -lXcursor
all_linux clean_linux: SYSTEM=Linux
all_win32: LDFLAGS = -L../../lib/Win32-gcc -lIrrlicht -lopengl32 -lm
all_win32: CPPFLAGS += -D__GNUWIN32__ -D_WIN32 -DWIN32 -D_WINDOWS -D_MBCS -D_USRDLL
all_win32 clean_win32: SYSTEM=Win32-gcc
all_win32 clean_win32: SUF=.exe
# name of the binary - only valid for targets which set SYSTEM
DESTPATH = ../../bin/$(SYSTEM)/$(Target)$(SUF)
all_linux all_win32:
$(warning Building...)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(Sources) -o $(DESTPATH) $(LDFLAGS)
clean: clean_linux clean_win32
$(warning Cleaning...)
clean_linux clean_win32:
@$(RM) $(DESTPATH)
.PHONY: all all_win32 clean clean_linux clean_win32

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Irrlicht Example 26 OcclusionQuery" />
<Option pch_mode="0" />
<Option compiler="gcc" />
<Build>
<Target title="Windows">
<Option output="../../bin/Win32-gcc/OcclusionQuery" prefix_auto="0" extension_auto="1" />
<Option type="1" />
<Option compiler="gcc" />
<Option projectResourceIncludeDirsRelation="1" />
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add option="-D_IRR_STATIC_LIB_" />
</Compiler>
<Linker>
<Add directory="../../lib/Win32-gcc" />
</Linker>
</Target>
<Target title="Linux">
<Option platforms="Unix;" />
<Option output="../../bin/Linux/OcclusionQuery" prefix_auto="0" extension_auto="0" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
<Add option="-W" />
<Add option="-D_IRR_STATIC_LIB_" />
</Compiler>
<Linker>
<Add library="Xxf86vm" />
<Add library="Xcursor" />
<Add library="GL" />
<Add directory="../../lib/Linux" />
</Linker>
</Target>
</Build>
<VirtualTargets>
<Add alias="All" targets="Windows;Linux" />
</VirtualTargets>
<Compiler>
<Add option="-W" />
<Add option="-g" />
<Add directory="../../include" />
</Compiler>
<Linker>
<Add library="Irrlicht" />
</Linker>
<Unit filename="main.cpp" />
<Extensions>
<code_completion />
<debugger />
<envvars />
</Extensions>
</Project>
</CodeBlocks_project_file>

View File

@ -0,0 +1,59 @@
[Project]
FileName=example.dev
Name=Irrlicht Example 26 OcclusionQuery
UnitCount=1
Type=1
Ver=1
ObjFiles=
Includes=..\..\include
Libs=
PrivateResource=
ResourceIncludes=
MakeIncludes=
Compiler=
CppCompiler=
Linker=../../lib/Win32-gcc/libIrrlicht.a_@@_
IsCpp=1
Icon=
ExeOutput=../../bin/Win32-gcc
ObjectOutput=obj
OverrideOutput=1
OverrideOutputName=26.OcclusionQuery.exe
HostApplication=
Folders=
CommandLine=
IncludeVersionInfo=0
SupportXPThemes=0
CompilerSet=0
CompilerSettings=0000000000000000000000
UseCustomMakefile=0
CustomMakefile=
[Unit1]
FileName=main.cpp
CompileCpp=1
Folder=Projekt1
Compile=1
Link=1
Priority=1000
OverrideBuildCmd=0
BuildCmd=
[VersionInfo]
Major=0
Minor=1
Release=1
Build=1
LanguageID=1033
CharsetID=1252
CompanyName=
FileVersion=
FileDescription=Irrlicht Engine example compiled using DevCpp and gcc
InternalName=
LegalCopyright=
LegalTrademarks=
OriginalFilename=
ProductName=
ProductVersion=
AutoIncBuildNr=0

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="26.OcclusionQuery"
ProjectGUID="{735B050B-1AC5-4602-B0BE-D2D2B5893E94}"
SccProjectName=""
SccLocalPath="">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug\OcclusionQuery.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe"
LinkIncremental="0"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\..\lib\Win32-visualstudio"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug\OcclusionQuery.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug\OcclusionQuery.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="3079"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release\OcclusionQuery.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe"
LinkIncremental="0"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\..\lib\Win32-visualstudio"
ProgramDatabaseFile=".\Release\OcclusionQuery.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release\OcclusionQuery.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="3079"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="main.cpp">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectName>26.OcclusionQuery</ProjectName>
<ProjectGuid>{5CE0E2E7-879D-4152-B61D-24E7D0707B45}</ProjectGuid>
<RootNamespace>OcclusionQuery</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC71.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">..\..\bin\Win32-VisualStudio\</OutDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">..\..\bin\Win32-VisualStudio\</OutDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<TypeLibraryName>.\Debug\OcclusionQuery.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c07</Culture>
</ResourceCompile>
<Link>
<OutputFile>..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<TypeLibraryName>.\Release\OcclusionQuery.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>MaxSpeed</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>..\..\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0c07</Culture>
</ResourceCompile>
<Link>
<OutputFile>..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<SubSystem>Console</SubSystem>
<DataExecutionPrevention>
</DataExecutionPrevention>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">EnableFastChecks</BasicRuntimeChecks>
<Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MaxSpeed</Optimization>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,231 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="26.OcclusionQuery_vc8"
ProjectGUID="{7BDBB7E8-E0C9-4A0D-83C1-D389D6140FEF}"
RootNamespace="OcclusionQuery_vc8"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug\OcclusionQuery.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug\OcclusionQuery.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="3079"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe"
LinkIncremental="0"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib\Win32-visualstudio"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\OcclusionQuery.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release\OcclusionQuery.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release\OcclusionQuery.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="3079"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe"
LinkIncremental="0"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib\Win32-visualstudio"
ProgramDatabaseFile=".\Release\OcclusionQuery.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="main.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,230 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="26.OcclusionQuery_vc9"
ProjectGUID="{7BDBB7E8-E0C9-4A0D-83C1-D389D6140FEF}"
RootNamespace="OcclusionQuery_vc9"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug\OcclusionQuery.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug\OcclusionQuery.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="3079"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe"
LinkIncremental="0"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib\Win32-visualstudio"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug\OcclusionQuery.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release\OcclusionQuery.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\include"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release\OcclusionQuery.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="3079"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
OutputFile="..\..\bin\Win32-VisualStudio\26.OcclusionQuery.exe"
LinkIncremental="0"
SuppressStartupBanner="true"
AdditionalLibraryDirectories="..\..\lib\Win32-visualstudio"
ProgramDatabaseFile=".\Release\OcclusionQuery.pdb"
SubSystem="1"
RandomizedBaseAddress="1"
DataExecutionPrevention="0"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<File
RelativePath="main.cpp"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BasicRuntimeChecks="3"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,213 @@
/** Example 026 OcclusionQuery
This Tutorial shows how to speed up rendering by use of the
OcclusionQuery feature. The usual rendering tries to avoid rendering of
scene nodes by culling those nodes which are outside the visible area, the
view frustum. However, this technique does not cope with occluded objects
which are still in the line of sight, but occluded by some larger object
between the object and the eye (camera). Occlusion queries check exactly that.
The queries basically measure the number of pixels that a previous render
left on the screen.
Since those pixels cannot be recognized at the end of a rendering anymore,
the pixel count is measured directly when rendering. Thus, one needs to render
the occluder (the object in front) first. This object needs to write to the
z-buffer in order to become a real occluder. Then the node is rendered and in
case a z-pass happens, i.e. the pixel is written to the framebuffer, the pixel
is counted in the query.
The result of a query is the number of pixels which got through. One can, based
on this number, judge if the scene node is visible enough to be rendered, or if
the node should be removed in the next round. Also note that the number of
pixels is a safe over approximation in general. The pixels might be overdrawn
later on, and the GPU tries to avoid inaccuracies which could lead to false
negatives in the queries.
As you might have recognized already, we had to render the node to get the
numbers. So where's the benefit, you might say. There are several ways where
occlusion queries can help. It is often a good idea to just render the bbox
of the node instead of the actual mesh. This is really fast and is a safe over
approximation. If you need a more exact render with the actual geometry, it's
a good idea to render with just basic solid material. Avoid complex shaders
and state changes through textures. There's no need while just doing the
occlusion query. At least if the render is not used for the actual scene. This
is the third way to optimize occlusion queries. Just check the queries every
5th or 10th frane, or even less frequent. This depends on the movement speed
of the objects and camera.
*/
#ifdef _MSC_VER
// We'll also define this to stop MSVC complaining about sprintf().
#define _CRT_SECURE_NO_WARNINGS
#pragma comment(lib, "Irrlicht.lib")
#endif
#include <irrlicht.h>
#include "driverChoice.h"
using namespace irr;
/*
We need keyboard input events to switch some parameters
*/
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
/*
We create an irr::IrrlichtDevice and the scene nodes. One occluder, one
occluded. The latter is a complex sphere, which has many triangles.
*/
int main()
{
// ask user for driver
video::E_DRIVER_TYPE driverType=driverChoiceConsole();
if (driverType==video::EDT_COUNT)
return 1;
// create device
MyEventReceiver receiver;
IrrlichtDevice* device = createDevice(driverType,
core::dimension2d<u32>(640, 480), 16, false, false, false, &receiver);
if (device == 0)
return 1; // could not create selected driver.
video::IVideoDriver* driver = device->getVideoDriver();
scene::ISceneManager* smgr = device->getSceneManager();
smgr->getGUIEnvironment()->addStaticText(L"Press Space to hide occluder.", core::recti(10,10, 200,50));
/*
Create the node to be occluded. We create a sphere node with high poly count.
*/
scene::ISceneNode * node = smgr->addSphereSceneNode(10, 64);
if (node)
{
node->setPosition(core::vector3df(0,0,60));
node->setMaterialTexture(0, driver->getTexture("../../media/wall.bmp"));
node->setMaterialFlag(video::EMF_LIGHTING, false);
}
/*
Now we create another node, the occluder. It's a simple plane.
*/
scene::ISceneNode* plane = smgr->addMeshSceneNode(smgr->addHillPlaneMesh(
"plane", core::dimension2df(10,10), core::dimension2du(2,2)), 0, -1,
core::vector3df(0,0,20), core::vector3df(270,0,0));
if (plane)
{
plane->setMaterialTexture(0, driver->getTexture("../../media/t351sml.jpg"));
plane->setMaterialFlag(video::EMF_LIGHTING, false);
plane->setMaterialFlag(video::EMF_BACK_FACE_CULLING, true);
}
/*
Here we create the occlusion query. Because we don't have a plain mesh scene node
(ESNT_MESH or ESNT_ANIMATED_MESH), we pass the base geometry as well. Instead,
we could also pass a simpler mesh or the bounding box. But we will use a time
based method, where the occlusion query renders to the frame buffer and in case
of success (occlusion), the mesh is not drawn for several frames.
*/
driver->addOcclusionQuery(node, ((scene::IMeshSceneNode*)node)->getMesh());
/*
We have done everything, just a camera and draw it. We also write the
current frames per second and the name of the driver to the caption of the
window to examine the render speedup.
We also store the time for measuring the time since the last occlusion query ran
and store whether the node should be visible in the next frames.
*/
smgr->addCameraSceneNode();
int lastFPS = -1;
u32 timeNow = device->getTimer()->getTime();
bool nodeVisible=true;
while(device->run())
{
plane->setVisible(!receiver.IsKeyDown(irr::KEY_SPACE));
driver->beginScene(true, true, video::SColor(255,113,113,133));
/*
First, we draw the scene, possibly without the occluded element. This is necessary
because we need the occluder to be drawn first. You can also use several scene
managers to collect a number of possible occluders in a separately rendered
scene.
*/
node->setVisible(nodeVisible);
smgr->drawAll();
smgr->getGUIEnvironment()->drawAll();
/*
Once in a while, here every 100 ms, we check the visibility. We run the queries,
update the pixel value, and query the result. Since we already rendered the node
we render the query invisible. The update is made blocking, as we need the result
immediately. If you don't need the result immediately, e.g. because oyu have other
things to render, you can call the update non-blocking. This gives the GPU more
time to pass back the results without flushing the render pipeline.
If the update was called non-blocking, the result from getOcclusionQueryResult is
either the previous value, or 0xffffffff if no value has been generated at all, yet.
The result is taken immediately as visibility flag for the node.
*/
if (device->getTimer()->getTime()-timeNow>100)
{
driver->runAllOcclusionQueries(false);
driver->updateAllOcclusionQueries();
nodeVisible=driver->getOcclusionQueryResult(node)>0;
timeNow=device->getTimer()->getTime();
}
driver->endScene();
int fps = driver->getFPS();
if (lastFPS != fps)
{
core::stringw tmp(L"OcclusionQuery Example [");
tmp += driver->getName();
tmp += L"] fps: ";
tmp += fps;
device->setWindowCaption(tmp.c_str());
lastFPS = fps;
}
}
/*
In the end, delete the Irrlicht device.
*/
device->drop();
return 0;
}
/*
That's it. Compile and play around with the program.
**/

View File

@ -2,7 +2,7 @@
<CodeBlocks_workspace_file> <CodeBlocks_workspace_file>
<Workspace title="Build all examples"> <Workspace title="Build all examples">
<Project filename="01.HelloWorld/HelloWorld.cbp" /> <Project filename="01.HelloWorld/HelloWorld.cbp" />
<Project filename="02.Quake3Map/Quake3Map.cbp" /> <Project filename="02.Quake3Map/Quake3Map.cbp" active="1" />
<Project filename="03.CustomSceneNode/CustomSceneNode.cbp" /> <Project filename="03.CustomSceneNode/CustomSceneNode.cbp" />
<Project filename="04.Movement/Movement.cbp" /> <Project filename="04.Movement/Movement.cbp" />
<Project filename="05.UserInterface/UserInterface.cbp" /> <Project filename="05.UserInterface/UserInterface.cbp" />
@ -22,9 +22,14 @@
<Project filename="20.ManagedLights/ManagedLights.cbp" /> <Project filename="20.ManagedLights/ManagedLights.cbp" />
<Project filename="21.Quake3Explorer/Quake3Explorer.cbp" /> <Project filename="21.Quake3Explorer/Quake3Explorer.cbp" />
<Project filename="22.MaterialViewer/MaterialViewer.cbp" /> <Project filename="22.MaterialViewer/MaterialViewer.cbp" />
<Project filename="23.SMeshHandling/SMeshHandling.cbp" />
<Project filename="24.CursorControl/CursorControl.cbp" />
<Project filename="25.XmlHandling/XmlHandling.cbp" />
<Project filename="26.OcclusionQuery/OcclusionQuery.cbp" />
<Project filename="Demo/demo.cbp" /> <Project filename="Demo/demo.cbp" />
<Project filename="../tools/GUIEditor/GUIEditor_gcc.cbp" active="1" /> <Project filename="../tools/GUIEditor/GUIEditor_gcc.cbp" />
<Project filename="../tools/MeshConverter/MeshConverter.cbp" /> <Project filename="../tools/MeshConverter/MeshConverter.cbp" />
<Project filename="../source/Irrlicht/Irrlicht-gcc.cbp" /> <Project filename="../source/Irrlicht/Irrlicht-gcc.cbp" />
<Project filename="../tools/FileToHeader/FileToHeader.cbp" />
</Workspace> </Workspace>
</CodeBlocks_workspace_file> </CodeBlocks_workspace_file>

View File

@ -111,10 +111,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "23.SMeshHandling", "23.SMes
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "22.MaterialViewer", "22.MaterialViewer\MaterialViewer.vcproj", "{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GUI Editor", "..\tools\GUIEditor\GUI Editor_v7.vcproj", "{853A396E-C031-4C26-A716-5B4E176BE11D}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GUI Editor", "..\tools\GUIEditor\GUI Editor_v7.vcproj", "{853A396E-C031-4C26-A716-5B4E176BE11D}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
@ -123,6 +119,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Font Tool", "..\tools\IrrFo
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "22.MaterialViewer", "22.MaterialViewer\MaterialViewer.vcproj", "{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfiguration) = preSolution GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug Debug = Debug
@ -219,18 +219,18 @@ Global
{6AEC2AA2-C9FF-4B7D-B07A-94A9D34B41D7}.Debug.Build.0 = Debug|Win32 {6AEC2AA2-C9FF-4B7D-B07A-94A9D34B41D7}.Debug.Build.0 = Debug|Win32
{6AEC2AA2-C9FF-4B7D-B07A-94A9D34B41D7}.Release.ActiveCfg = Release|Win32 {6AEC2AA2-C9FF-4B7D-B07A-94A9D34B41D7}.Release.ActiveCfg = Release|Win32
{6AEC2AA2-C9FF-4B7D-B07A-94A9D34B41D7}.Release.Build.0 = Release|Win32 {6AEC2AA2-C9FF-4B7D-B07A-94A9D34B41D7}.Release.Build.0 = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.ActiveCfg = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.Build.0 = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.ActiveCfg = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.Build.0 = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.ActiveCfg = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.Build.0 = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.ActiveCfg = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.Build.0 = Release|Win32
{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Debug.ActiveCfg = Debug|Win32 {4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Debug.ActiveCfg = Debug|Win32
{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Debug.Build.0 = Debug|Win32 {4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Debug.Build.0 = Debug|Win32
{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Release.ActiveCfg = Release|Win32 {4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Release.ActiveCfg = Release|Win32
{4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Release.Build.0 = Release|Win32 {4E6C2F8D-BA92-4C5B-96FD-72D4FE8BD7FA}.Release.Build.0 = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.ActiveCfg = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.Build.0 = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.ActiveCfg = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.Build.0 = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.ActiveCfg = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Debug.Build.0 = Debug|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.ActiveCfg = Release|Win32
{853A396E-C031-4C26-A716-5B4E176BE11D}.Release.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection EndGlobalSection

View File

@ -134,6 +134,16 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FontTool", "..\tools\IrrFon
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeshConverter", "..\tools\MeshConverter\MeshConverter_vc10.vcxproj", "{E72B637E-4AA6-46F3-885F-AC67B4B470ED}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MeshConverter", "..\tools\MeshConverter\MeshConverter_vc10.vcxproj", "{E72B637E-4AA6-46F3-885F-AC67B4B470ED}"
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "26.OcclusionQuery", "26.OcclusionQuery\OcclusionQuery_vc10.vcxproj", "{5CE0E2E7-879D-4152-B61D-24E7D0707B45}"
ProjectSection(ProjectDependencies) = postProject
{E08E042A-6C45-411B-92BE-3CC31331019F} = {E08E042A-6C45-411B-92BE-3CC31331019F}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "25.XmlHandling", "25.XmlHandling\XmlHandling_vc10.vcxproj", "{8FDA260E-EF27-4F8C-8720-7AF707DD0D9E}"
ProjectSection(ProjectDependencies) = postProject
{E08E042A-6C45-411B-92BE-3CC31331019F} = {E08E042A-6C45-411B-92BE-3CC31331019F}
EndProjectSection
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
@ -256,6 +266,14 @@ Global
{E72B637E-4AA6-46F3-885F-AC67B4B470ED}.Debug|Win32.Build.0 = Debug|Win32 {E72B637E-4AA6-46F3-885F-AC67B4B470ED}.Debug|Win32.Build.0 = Debug|Win32
{E72B637E-4AA6-46F3-885F-AC67B4B470ED}.Release|Win32.ActiveCfg = Release|Win32 {E72B637E-4AA6-46F3-885F-AC67B4B470ED}.Release|Win32.ActiveCfg = Release|Win32
{E72B637E-4AA6-46F3-885F-AC67B4B470ED}.Release|Win32.Build.0 = Release|Win32 {E72B637E-4AA6-46F3-885F-AC67B4B470ED}.Release|Win32.Build.0 = Release|Win32
{5CE0E2E7-879D-4152-B61D-24E7D0707B45}.Debug|Win32.ActiveCfg = Debug|Win32
{5CE0E2E7-879D-4152-B61D-24E7D0707B45}.Debug|Win32.Build.0 = Debug|Win32
{5CE0E2E7-879D-4152-B61D-24E7D0707B45}.Release|Win32.ActiveCfg = Release|Win32
{5CE0E2E7-879D-4152-B61D-24E7D0707B45}.Release|Win32.Build.0 = Release|Win32
{8FDA260E-EF27-4F8C-8720-7AF707DD0D9E}.Debug|Win32.ActiveCfg = Debug|Win32
{8FDA260E-EF27-4F8C-8720-7AF707DD0D9E}.Debug|Win32.Build.0 = Debug|Win32
{8FDA260E-EF27-4F8C-8720-7AF707DD0D9E}.Release|Win32.ActiveCfg = Release|Win32
{8FDA260E-EF27-4F8C-8720-7AF707DD0D9E}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE

View File

@ -525,7 +525,7 @@ void CDemo::loadSceneData()
scene::IParticleEmitter* em = campFire->createBoxEmitter( scene::IParticleEmitter* em = campFire->createBoxEmitter(
core::aabbox3d<f32>(-7,0,-7,7,1,7), core::aabbox3d<f32>(-7,0,-7,7,1,7),
core::vector3df(0.0f,0.06f,0.0f), core::vector3df(0.0f,0.06f,0.0f),
80,100, video::SColor(0,255,255,255),video::SColor(0,255,255,255), 800,2000); 80,100, video::SColor(1,255,255,255),video::SColor(1,255,255,255), 800,2000);
em->setMinStartSize(core::dimension2d<f32>(20.0f, 10.0f)); em->setMinStartSize(core::dimension2d<f32>(20.0f, 10.0f));
em->setMaxStartSize(core::dimension2d<f32>(20.0f, 10.0f)); em->setMaxStartSize(core::dimension2d<f32>(20.0f, 10.0f));
@ -539,7 +539,8 @@ void CDemo::loadSceneData()
campFire->setMaterialFlag(video::EMF_LIGHTING, false); campFire->setMaterialFlag(video::EMF_LIGHTING, false);
campFire->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false); campFire->setMaterialFlag(video::EMF_ZWRITE_ENABLE, false);
campFire->setMaterialTexture(0, driver->getTexture("../../media/fireball.bmp")); campFire->setMaterialTexture(0, driver->getTexture("../../media/fireball.bmp"));
campFire->setMaterialType(video::EMT_TRANSPARENT_VERTEX_ALPHA); campFire->setMaterialType(video::EMT_ONETEXTURE_BLEND);
campFire->getMaterial(0).MaterialTypeParam=video::pack_texureBlendFunc(video::EBF_ONE, video::EBF_ONE_MINUS_SRC_ALPHA, video::EMFN_MODULATE_1X, video::EAS_VERTEX_COLOR);
// load music // load music

View File

@ -25,9 +25,9 @@ bool CMainMenu::run(bool& outFullscreen, bool& outMusic, bool& outShadows,
core::dimension2d<u32>(512, 384), 16, false, false, false, this); core::dimension2d<u32>(512, 384), 16, false, false, false, this);
if (MenuDevice->getFileSystem()->existFile("irrlicht.dat")) if (MenuDevice->getFileSystem()->existFile("irrlicht.dat"))
MenuDevice->getFileSystem()->addZipFileArchive("irrlicht.dat"); MenuDevice->getFileSystem()->addFileArchive("irrlicht.dat");
else else
MenuDevice->getFileSystem()->addZipFileArchive("../../media/irrlicht.dat"); MenuDevice->getFileSystem()->addFileArchive("../../media/irrlicht.dat");
video::IVideoDriver* driver = MenuDevice->getVideoDriver(); video::IVideoDriver* driver = MenuDevice->getVideoDriver();
scene::ISceneManager* smgr = MenuDevice->getSceneManager(); scene::ISceneManager* smgr = MenuDevice->getSceneManager();

View File

@ -109,7 +109,6 @@
<Culture>0x0c07</Culture> <Culture>0x0c07</Culture>
</ResourceCompile> </ResourceCompile>
<Link> <Link>
<OutputFile>..\..\bin\Win32-VisualStudio\Demo.exe</OutputFile>
<AdditionalLibraryDirectories>..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>..\..\lib\Win32-visualstudio;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>

View File

@ -41,7 +41,7 @@
</Target> </Target>
</Build> </Build>
<VirtualTargets> <VirtualTargets>
<Add alias="All" targets="Windows;" /> <Add alias="All" targets="Windows;Linux;" />
</VirtualTargets> </VirtualTargets>
<Compiler> <Compiler>
<Add option="-Wall" /> <Add option="-Wall" />

View File

@ -109,6 +109,12 @@ namespace video
//! Supports occlusion queries //! Supports occlusion queries
EVDF_OCCLUSION_QUERY, EVDF_OCCLUSION_QUERY,
//! Supports polygon offset/depth bias for avoiding z-fighting
EVDF_POLYGON_OFFSET,
//! Support for different blend functions. Without, only ADD is available
EVDF_BLEND_OPERATIONS,
//! Only used for counting the elements of this enum //! Only used for counting the elements of this enum
EVDF_COUNT EVDF_COUNT
}; };

View File

@ -78,7 +78,13 @@ namespace video
EMF_COLOR_MATERIAL = 0x10000, EMF_COLOR_MATERIAL = 0x10000,
//! Flag for enabling/disabling mipmap usage //! Flag for enabling/disabling mipmap usage
EMF_USE_MIP_MAPS = 0x20000 EMF_USE_MIP_MAPS = 0x20000,
//! Flag for blend operation
EMF_BLEND_OPERATION = 0x40000,
//! Flag for polygon offset
EMF_POLYGON_OFFSET = 0x80000
}; };
} // end namespace video } // end namespace video

View File

@ -54,97 +54,6 @@ namespace scene
EAMT_SKINNED EAMT_SKINNED
}; };
//! Possible types of Animation Type
enum E_ANIMATION_TYPE
{
//! No Animation
EAMT_STILL,
//! From Start to End, then Stop ( Limited Line )
EAMT_WAYPOINT,
//! Linear Cycling Animation ( Sawtooth )
EAMT_LOOPING,
//! Linear bobbing ( Triangle )
EAMT_PINGPONG
};
//! Names for Animation Type
const c8* const MeshAnimationTypeNames[] =
{
"still",
"waypoint",
"looping",
"pingpong",
0
};
//! Data for holding named Animation Info
struct KeyFrameInterpolation
{
core::stringc Name; // Name of the current Animation/Bone
E_ANIMATION_TYPE AnimationType; // Type of Animation ( looping, usw..)
f32 CurrentFrame; // Current Frame
s32 NextFrame; // Frame which will be used next. For blending
s32 StartFrame; // Absolute Frame where the current animation start
s32 Frames; // Relative Frames how much Frames this animation have
s32 LoopingFrames; // How much of Frames sould be looped
s32 EndFrame; // Absolute Frame where the current animation ends End = start + frames - 1
f32 FramesPerSecond; // Speed in Frames/Seconds the animation is played
f32 RelativeSpeed; // Factor Original fps is modified
u32 BeginTime; // Animation started at this thime
u32 EndTime; // Animation end at this time
u32 LastTime; // Last Keyframe was done at this time
KeyFrameInterpolation ( const c8 * name = "", s32 start = 0, s32 frames = 0, s32 loopingframes = 0,
f32 fps = 0.f, f32 relativefps = 1.f )
: Name ( name ), AnimationType ( loopingframes ? EAMT_LOOPING : EAMT_WAYPOINT),
CurrentFrame ( (f32) start ), NextFrame ( start ), StartFrame ( start ),
Frames ( frames ), LoopingFrames ( loopingframes ), EndFrame ( start + frames - 1 ),
FramesPerSecond ( fps ), RelativeSpeed ( relativefps ),
BeginTime ( 0 ), EndTime ( 0 ), LastTime ( 0 )
{
}
// linear search
bool operator == ( const KeyFrameInterpolation & other ) const
{
return Name.equals_ignore_case ( other.Name );
}
};
//! a List holding named Animations
typedef core::array < KeyFrameInterpolation > IAnimationList;
//! a List holding named Skins
typedef core::array < core::stringc > ISkinList;
// Current Model per Body
struct SubModel
{
core::stringc name;
u32 startBuffer;
u32 endBuffer;
u32 state;
};
struct BodyPart
{
core::stringc name;
u32 defaultModel;
core::array < SubModel > model;
};
//! a List holding named Models and SubModels
typedef core::array < BodyPart > IBodyList;
//! Interface for an animated mesh. //! Interface for an animated mesh.
/** There are already simple implementations of this interface available so /** There are already simple implementations of this interface available so
you don't have to implement this interface on your own if you need to: you don't have to implement this interface on your own if you need to:

View File

@ -213,20 +213,20 @@ namespace scene
//! holds a associative list of named quaternions //! holds a associative list of named quaternions
struct SMD3QuaternionTagList struct SMD3QuaternionTagList
{ {
SMD3QuaternionTagList () SMD3QuaternionTagList()
{ {
Container.setAllocStrategy ( core::ALLOC_STRATEGY_SAFE ); Container.setAllocStrategy(core::ALLOC_STRATEGY_SAFE);
} }
// construct copy constructor // construct copy constructor
SMD3QuaternionTagList( const SMD3QuaternionTagList & copyMe ) SMD3QuaternionTagList(const SMD3QuaternionTagList& copyMe)
{ {
*this = copyMe; *this = copyMe;
} }
virtual ~SMD3QuaternionTagList () {} virtual ~SMD3QuaternionTagList() {}
SMD3QuaternionTag* get ( const core::stringc& name ) SMD3QuaternionTag* get(const core::stringc& name)
{ {
SMD3QuaternionTag search ( name ); SMD3QuaternionTag search ( name );
s32 index = Container.linear_search ( search ); s32 index = Container.linear_search ( search );
@ -240,14 +240,14 @@ namespace scene
return Container.size(); return Container.size();
} }
void set_used ( u32 new_size) void set_used(u32 new_size)
{ {
s32 diff = (s32) new_size - (s32) Container.allocated_size (); s32 diff = (s32) new_size - (s32) Container.allocated_size();
if ( diff > 0 ) if ( diff > 0 )
{ {
SMD3QuaternionTag e ( "" ); SMD3QuaternionTag e("");
for ( s32 i = 0; i < diff; ++i ) for ( s32 i = 0; i < diff; ++i )
Container.push_back ( e ); Container.push_back(e);
} }
} }
@ -261,9 +261,9 @@ namespace scene
return Container[index]; return Container[index];
} }
void push_back ( const SMD3QuaternionTag& other ) void push_back(const SMD3QuaternionTag& other)
{ {
Container.push_back ( other ); Container.push_back(other);
} }
SMD3QuaternionTagList& operator = (const SMD3QuaternionTagList & copyMe) SMD3QuaternionTagList& operator = (const SMD3QuaternionTagList & copyMe)
@ -292,7 +292,7 @@ namespace scene
} }
core::stringc Name; core::stringc Name;
core::array < SMD3MeshBuffer * > Buffer; core::array<SMD3MeshBuffer*> Buffer;
SMD3QuaternionTagList TagList; SMD3QuaternionTagList TagList;
SMD3Header MD3Header; SMD3Header MD3Header;
}; };
@ -304,13 +304,13 @@ namespace scene
public: public:
//! tune how many frames you want to render inbetween. //! tune how many frames you want to render inbetween.
virtual void setInterpolationShift ( u32 shift, u32 loopMode ) = 0; virtual void setInterpolationShift(u32 shift, u32 loopMode) =0;
//! get the tag list of the mesh. //! get the tag list of the mesh.
virtual SMD3QuaternionTagList *getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) = 0; virtual SMD3QuaternionTagList* getTagList(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) =0;
//! get the original md3 mesh. //! get the original md3 mesh.
virtual SMD3Mesh * getOriginalMesh () = 0; virtual SMD3Mesh* getOriginalMesh() =0;
}; };
} // end namespace scene } // end namespace scene

View File

@ -130,12 +130,6 @@ namespace scene
/** \return Amount of joints in the mesh. */ /** \return Amount of joints in the mesh. */
virtual u32 getJointCount() const = 0; virtual u32 getJointCount() const = 0;
//! Deprecated command, please use getJointNode
virtual ISceneNode* getMS3DJointNode(const c8* jointName) = 0;
//! Deprecated command, please use getJointNode
virtual ISceneNode* getXJointNode(const c8* jointName) = 0;
//! Starts a default MD2 animation. //! Starts a default MD2 animation.
/** With this method it is easily possible to start a Run, /** With this method it is easily possible to start a Run,
Attack, Die or whatever animation, if the mesh contained in Attack, Die or whatever animation, if the mesh contained in
@ -161,7 +155,7 @@ namespace scene
animation with this name could be found. */ animation with this name could be found. */
virtual bool setMD2Animation(const c8* animationName) = 0; virtual bool setMD2Animation(const c8* animationName) = 0;
//! Returns the current displayed frame number. //! Returns the currently displayed frame number.
virtual f32 getFrameNr() const = 0; virtual f32 getFrameNr() const = 0;
//! Returns the current start frame number. //! Returns the current start frame number.
virtual s32 getStartFrame() const = 0; virtual s32 getStartFrame() const = 0;
@ -179,7 +173,7 @@ namespace scene
virtual void setAnimationEndCallback(IAnimationEndCallBack* callback=0) = 0; virtual void setAnimationEndCallback(IAnimationEndCallBack* callback=0) = 0;
//! Sets if the scene node should not copy the materials of the mesh but use them in a read only style. //! Sets if the scene node should not copy the materials of the mesh but use them in a read only style.
/* In this way it is possible to change the materials a mesh /** In this way it is possible to change the materials a mesh
causing all mesh scene nodes referencing this mesh to change causing all mesh scene nodes referencing this mesh to change
too. */ too. */
virtual void setReadOnlyMaterials(bool readonly) = 0; virtual void setReadOnlyMaterials(bool readonly) = 0;

View File

@ -24,6 +24,7 @@
#include "irrArray.h" #include "irrArray.h"
#include "IXMLReader.h" #include "IXMLReader.h"
#include "EAttributes.h" #include "EAttributes.h"
#include "path.h"
namespace irr namespace irr
{ {
@ -636,10 +637,10 @@ public:
*/ */
//! Adds an attribute as texture reference //! Adds an attribute as texture reference
virtual void addTexture(const c8* attributeName, video::ITexture* texture) = 0; virtual void addTexture(const c8* attributeName, video::ITexture* texture, const io::path& filename = "") = 0;
//! Sets an attribute as texture reference //! Sets an attribute as texture reference
virtual void setAttribute(const c8* attributeName, video::ITexture* texture ) = 0; virtual void setAttribute(const c8* attributeName, video::ITexture* texture, const io::path& filename = "") = 0;
//! Gets an attribute as texture reference //! Gets an attribute as texture reference
//! \param attributeName: Name of the attribute to get. //! \param attributeName: Name of the attribute to get.
@ -650,7 +651,7 @@ public:
virtual video::ITexture* getAttributeAsTexture(s32 index) = 0; virtual video::ITexture* getAttributeAsTexture(s32 index) = 0;
//! Sets an attribute as texture reference //! Sets an attribute as texture reference
virtual void setAttribute(s32 index, video::ITexture* texture) = 0; virtual void setAttribute(s32 index, video::ITexture* texture, const io::path& filename = "") = 0;
/* /*

View File

@ -60,8 +60,8 @@ namespace scene
ISceneNode(parent, mgr, id),positionHint(-1),scaleHint(-1),rotationHint(-1) { } ISceneNode(parent, mgr, id),positionHint(-1),scaleHint(-1),rotationHint(-1) { }
//! Get the name of the bone //! Get the name of the bone
/** \deprecated Use getName instead. */ /** \deprecated Use getName instead. This method may be removed by Irrlicht 1.9 */
virtual const c8* getBoneName() const { return getName(); } _IRR_DEPRECATED_ virtual const c8* getBoneName() const { return getName(); }
//! Get the index of the bone //! Get the index of the bone
virtual u32 getBoneIndex() const = 0; virtual u32 getBoneIndex() const = 0;

View File

@ -245,11 +245,12 @@ namespace irr
//! A tree view node was expanded. See IGUITreeView::getLastEventNode(). //! A tree view node was expanded. See IGUITreeView::getLastEventNode().
EGET_TREEVIEW_NODE_EXPAND, EGET_TREEVIEW_NODE_EXPAND,
//! deprecated - use EGET_TREEVIEW_NODE_COLLAPSE instead
EGET_TREEVIEW_NODE_COLLAPS,
//! A tree view node was collapsed. See IGUITreeView::getLastEventNode(). //! A tree view node was collapsed. See IGUITreeView::getLastEventNode().
EGET_TREEVIEW_NODE_COLLAPSE = EGET_TREEVIEW_NODE_COLLAPS, EGET_TREEVIEW_NODE_COLLAPSE,
//! deprecated - use EGET_TREEVIEW_NODE_COLLAPSE instead. This
//! may be removed by Irrlicht 1.9
EGET_TREEVIEW_NODE_COLLAPS = EGET_TREEVIEW_NODE_COLLAPSE,
//! No real event. Just for convenience to get number of events //! No real event. Just for convenience to get number of events
EGET_COUNT EGET_COUNT

View File

@ -117,10 +117,31 @@ public:
E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN, E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN,
const core::stringc& password="") =0; const core::stringc& password="") =0;
//! Adds an external archive loader to the engine. //! Adds an archive to the file system.
/** Use this function to add support for new archive types to the /** After calling this, the Irrlicht Engine will also search and open
engine, for example proprietary or encrypted file storage. */ files directly from this archive. This is useful for hiding data from
virtual void addArchiveLoader(IArchiveLoader* loader) =0; the end user, speeding up file access and making it possible to access
for example Quake3 .pk3 files, which are just renamed .zip files. By
default Irrlicht supports ZIP, PAK, TAR, PNK, and directories as
archives. You can provide your own archive types by implementing
IArchiveLoader and passing an instance to addArchiveLoader.
Irrlicht supports AES-encrypted zip files, and the advanced compression
techniques lzma and bzip2.
\param file: Archive to add to the file system.
\param ignoreCase: If set to true, files in the archive can be accessed without
writing all letters in the right case.
\param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path.
\param archiveType: If no specific E_FILE_ARCHIVE_TYPE is selected then
the type of archive will depend on the extension of the file name. If
you use a different extension then you can use this parameter to force
a specific type of archive.
\param password An optional password, which is used in case of encrypted archives.
\return True if the archive was added successfully, false if not. */
virtual bool addFileArchive(IReadFile* file, bool ignoreCase=true,
bool ignorePaths=true,
E_FILE_ARCHIVE_TYPE archiveType=EFAT_UNKNOWN,
const core::stringc& password="") =0;
//! Get the number of archives currently attached to the file system //! Get the number of archives currently attached to the file system
virtual u32 getFileArchiveCount() const =0; virtual u32 getFileArchiveCount() const =0;
@ -149,9 +170,23 @@ public:
//! Get the archive at a given index. //! Get the archive at a given index.
virtual IFileArchive* getFileArchive(u32 index) =0; virtual IFileArchive* getFileArchive(u32 index) =0;
//! Adds an external archive loader to the engine.
/** Use this function to add support for new archive types to the
engine, for example proprietary or encrypted file storage. */
virtual void addArchiveLoader(IArchiveLoader* loader) =0;
//! Gets the number of archive loaders currently added
virtual u32 getArchiveLoaderCount() const = 0;
//! Retrieve the given archive loader
/** \param index The index of the loader to retrieve. This parameter is an 0-based
array index.
\return A pointer to the specified loader, 0 if the index is incorrect. */
virtual IArchiveLoader* getArchiveLoader(u32 index) const = 0;
//! Adds a zip archive to the file system. //! Adds a zip archive to the file system.
/** \deprecated This function is provided for compatibility /** \deprecated This function is provided for compatibility
with older versions of Irrlicht and may be removed in future versions, with older versions of Irrlicht and may be removed in Irrlicht 1.9,
you should use addFileArchive instead. you should use addFileArchive instead.
After calling this, the Irrlicht Engine will search and open files directly from this archive too. After calling this, the Irrlicht Engine will search and open files directly from this archive too.
This is useful for hiding data from the end user, speeding up file access and making it possible to This is useful for hiding data from the end user, speeding up file access and making it possible to
@ -162,14 +197,14 @@ public:
\param ignorePaths: If set to true, files in the added archive can be accessed \param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path. without its complete path.
\return True if the archive was added successfully, false if not. */ \return True if the archive was added successfully, false if not. */
virtual bool addZipFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true) _IRR_DEPRECATED_ virtual bool addZipFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true)
{ {
return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_ZIP); return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_ZIP);
} }
//! Adds an unzipped archive (or basedirectory with subdirectories..) to the file system. //! Adds an unzipped archive (or basedirectory with subdirectories..) to the file system.
/** \deprecated This function is provided for compatibility /** \deprecated This function is provided for compatibility
with older versions of Irrlicht and may be removed in future versions, with older versions of Irrlicht and may be removed in Irrlicht 1.9,
you should use addFileArchive instead. you should use addFileArchive instead.
Useful for handling data which will be in a zip file Useful for handling data which will be in a zip file
\param filename: Filename of the unzipped zip archive base directory to add to the file system. \param filename: Filename of the unzipped zip archive base directory to add to the file system.
@ -178,14 +213,14 @@ public:
\param ignorePaths: If set to true, files in the added archive can be accessed \param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path. without its complete path.
\return True if the archive was added successful, false if not. */ \return True if the archive was added successful, false if not. */
virtual bool addFolderFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true) _IRR_DEPRECATED_ virtual bool addFolderFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true)
{ {
return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_FOLDER); return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_FOLDER);
} }
//! Adds a pak archive to the file system. //! Adds a pak archive to the file system.
/** \deprecated This function is provided for compatibility /** \deprecated This function is provided for compatibility
with older versions of Irrlicht and may be removed in future versions, with older versions of Irrlicht and may be removed in Irrlicht 1.9,
you should use addFileArchive instead. you should use addFileArchive instead.
After calling this, the Irrlicht Engine will search and open files directly from this archive too. After calling this, the Irrlicht Engine will search and open files directly from this archive too.
This is useful for hiding data from the end user, speeding up file access and making it possible to This is useful for hiding data from the end user, speeding up file access and making it possible to
@ -196,7 +231,7 @@ public:
\param ignorePaths: If set to true, files in the added archive can be accessed \param ignorePaths: If set to true, files in the added archive can be accessed
without its complete path.(should not use with Quake2 paks without its complete path.(should not use with Quake2 paks
\return True if the archive was added successful, false if not. */ \return True if the archive was added successful, false if not. */
virtual bool addPakFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true) _IRR_DEPRECATED_ virtual bool addPakFileArchive(const c8* filename, bool ignoreCase=true, bool ignorePaths=true)
{ {
return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_PAK); return addFileArchive(filename, ignoreCase, ignorePaths, EFAT_PAK);
} }

View File

@ -56,6 +56,10 @@ namespace gui
//! Removes an item from the list //! Removes an item from the list
virtual void removeItem(u32 index) = 0; virtual void removeItem(u32 index) = 0;
//! get the the id of the item at the given absolute coordinates
/** \return The id of the listitem or -1 when no item is at those coordinates*/
virtual s32 getItemAt(s32 xpos, s32 ypos) const = 0;
//! Returns the icon of an item //! Returns the icon of an item
virtual s32 getIcon(u32 index) const = 0; virtual s32 getIcon(u32 index) const = 0;

View File

@ -31,8 +31,10 @@ namespace gui
{ {
//! Default windows look and feel //! Default windows look and feel
EGST_WINDOWS_CLASSIC=0, EGST_WINDOWS_CLASSIC=0,
//! Like EGST_WINDOWS_CLASSIC, but with metallic shaded windows and buttons //! Like EGST_WINDOWS_CLASSIC, but with metallic shaded windows and buttons
EGST_WINDOWS_METALLIC, EGST_WINDOWS_METALLIC,
//! Burning's skin //! Burning's skin
EGST_BURNING_SKIN, EGST_BURNING_SKIN,
@ -155,9 +157,9 @@ namespace gui
EGDS_WINDOW_BUTTON_WIDTH, EGDS_WINDOW_BUTTON_WIDTH,
//! width of a checkbox check //! width of a checkbox check
EGDS_CHECK_BOX_WIDTH, EGDS_CHECK_BOX_WIDTH,
//! deprecated //! \deprecated This may be removed by Irrlicht 1.9
EGDS_MESSAGE_BOX_WIDTH, EGDS_MESSAGE_BOX_WIDTH,
//! deprecated //! \deprecated This may be removed by Irrlicht 1.9
EGDS_MESSAGE_BOX_HEIGHT, EGDS_MESSAGE_BOX_HEIGHT,
//! width of a default button //! width of a default button
EGDS_BUTTON_WIDTH, EGDS_BUTTON_WIDTH,
@ -177,8 +179,6 @@ namespace gui
EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH, EGDS_MESSAGE_BOX_MIN_TEXT_WIDTH,
//! maximal space to reserve for messagebox text-width //! maximal space to reserve for messagebox text-width
EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH, EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH,
//! deprecated - this was a typo. Should be removed for 1.8
EGDS_MESSAGE_BOX_MAX_TEST_WIDTH = EGDS_MESSAGE_BOX_MAX_TEXT_WIDTH,
//! minimal space to reserve for messagebox text-height //! minimal space to reserve for messagebox text-height
EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT, EGDS_MESSAGE_BOX_MIN_TEXT_HEIGHT,
//! maximal space to reserve for messagebox text-height //! maximal space to reserve for messagebox text-height
@ -294,6 +294,7 @@ namespace gui
EGDI_MORE_DOWN, EGDI_MORE_DOWN,
//! plus icon for trees //! plus icon for trees
EGDI_EXPAND, EGDI_EXPAND,
//! minus icon for trees //! minus icon for trees
EGDI_COLLAPSE, EGDI_COLLAPSE,
//! file icon for file selection //! file icon for file selection

View File

@ -97,6 +97,17 @@ namespace gui
//! Checks if the text in this label should be clipped if it goes outside bounds //! Checks if the text in this label should be clipped if it goes outside bounds
virtual bool isTextRestrainedInside() const = 0; virtual bool isTextRestrainedInside() const = 0;
//! Set whether the string should be interpreted as right-to-left (RTL) text
/** \note This component does not implement the Unicode bidi standard, the
text of the component should be already RTL if you call this. The
main difference when RTL is enabled is that the linebreaks for multiline
elements are performed starting from the end.
*/
virtual void setRightToLeft(bool rtl) = 0;
//! Checks whether the text in this element should be interpreted as right-to-left
virtual bool isRightToLeft() const = 0;
}; };

View File

@ -113,6 +113,9 @@ namespace gui
//! Set the width of a column //! Set the width of a column
virtual void setColumnWidth(u32 columnIndex, u32 width) = 0; virtual void setColumnWidth(u32 columnIndex, u32 width) = 0;
//! Get the width of a column
virtual u32 getColumnWidth(u32 columnIndex) const = 0;
//! columns can be resized by drag 'n drop //! columns can be resized by drag 'n drop
virtual void setResizableColumns(bool resizable) = 0; virtual void setResizableColumns(bool resizable) = 0;

View File

@ -70,7 +70,8 @@ namespace gui
virtual void clearChildren() = 0; virtual void clearChildren() = 0;
//! removes all children (recursive) from this node //! removes all children (recursive) from this node
/** \deprecated Deprecated in 1.8, use clearChildren() instead. */ /** \deprecated Deprecated in 1.8, use clearChildren() instead.
This method may be removed by Irrlicht 1.9 */
_IRR_DEPRECATED_ void clearChilds() _IRR_DEPRECATED_ void clearChilds()
{ {
return clearChildren(); return clearChildren();
@ -80,7 +81,8 @@ namespace gui
virtual bool hasChildren() const = 0; virtual bool hasChildren() const = 0;
//! returns true if this node has child nodes //! returns true if this node has child nodes
/** \deprecated Deprecated in 1.8, use hasChildren() instead. */ /** \deprecated Deprecated in 1.8, use hasChildren() instead.
This method may be removed by Irrlicht 1.9 */
_IRR_DEPRECATED_ bool hasChilds() const _IRR_DEPRECATED_ bool hasChilds() const
{ {
return hasChildren(); return hasChildren();

View File

@ -34,7 +34,7 @@ namespace scene
the light manager may modify. This reference will remain valid the light manager may modify. This reference will remain valid
until OnPostRender(). until OnPostRender().
*/ */
virtual void OnPreRender(core::array<ILightSceneNode*> & lightList) = 0; virtual void OnPreRender(core::array<ISceneNode*> & lightList) = 0;
//! Called after the last scene node is rendered. //! Called after the last scene node is rendered.
/** After this call returns, the lightList passed to OnPreRender() becomes invalid. */ /** After this call returns, the lightList passed to OnPreRender() becomes invalid. */

View File

@ -79,35 +79,40 @@ namespace scene
virtual IAnimatedMesh* getMeshByIndex(u32 index) = 0; virtual IAnimatedMesh* getMeshByIndex(u32 index) = 0;
//! Returns a mesh based on its name (often a filename). //! Returns a mesh based on its name (often a filename).
/** \deprecated Use getMeshByName() instead. */ /** \deprecated Use getMeshByName() instead. This method may be removed by
Irrlicht 1.9 */
_IRR_DEPRECATED_ IAnimatedMesh* getMeshByFilename(const io::path& filename) _IRR_DEPRECATED_ IAnimatedMesh* getMeshByFilename(const io::path& filename)
{ {
return getMeshByName(filename); return getMeshByName(filename);
} }
//! Get the name of a loaded mesh, based on its index. (Name is often identical to the filename). //! Get the name of a loaded mesh, based on its index. (Name is often identical to the filename).
/** \deprecated Use getMeshName() instead. */ /** \deprecated Use getMeshName() instead. This method may be removed by
Irrlicht 1.9 */
_IRR_DEPRECATED_ const io::path& getMeshFilename(u32 index) const _IRR_DEPRECATED_ const io::path& getMeshFilename(u32 index) const
{ {
return getMeshName(index).getInternalName(); return getMeshName(index).getInternalName();
} }
//! Get the name of a loaded mesh, if there is any. (Name is often identical to the filename). //! Get the name of a loaded mesh, if there is any. (Name is often identical to the filename).
/** \deprecated Use getMeshName() instead. */ /** \deprecated Use getMeshName() instead. This method may be removed by
Irrlicht 1.9 */
_IRR_DEPRECATED_ const io::path& getMeshFilename(const IMesh* const mesh) const _IRR_DEPRECATED_ const io::path& getMeshFilename(const IMesh* const mesh) const
{ {
return getMeshName(mesh).getInternalName(); return getMeshName(mesh).getInternalName();
} }
//! Renames a loaded mesh. //! Renames a loaded mesh.
/** \deprecated Use renameMesh() instead. */ /** \deprecated Use renameMesh() instead. This method may be removed by
Irrlicht 1.9 */
_IRR_DEPRECATED_ bool setMeshFilename(u32 index, const io::path& filename) _IRR_DEPRECATED_ bool setMeshFilename(u32 index, const io::path& filename)
{ {
return renameMesh(index, filename); return renameMesh(index, filename);
} }
//! Renames a loaded mesh. //! Renames a loaded mesh.
/** \deprecated Use renameMesh() instead. */ /** \deprecated Use renameMesh() instead. This method may be removed by
Irrlicht 1.9 */
_IRR_DEPRECATED_ bool setMeshFilename(const IMesh* const mesh, const io::path& filename) _IRR_DEPRECATED_ bool setMeshFilename(const IMesh* const mesh, const io::path& filename)
{ {
return renameMesh(mesh, filename); return renameMesh(mesh, filename);

View File

@ -91,10 +91,10 @@ namespace scene
} }
//! Scales the actual mesh, not a scene node. //! Scales the actual mesh, not a scene node.
/** \deprecated Use scale() instead /** \deprecated Use scale() instead. This method may be removed by Irrlicht 1.9
\param mesh Mesh on which the operation is performed. \param mesh Mesh on which the operation is performed.
\param factor Scale factor for each axis. */ \param factor Scale factor for each axis. */
void scaleMesh(IMesh* mesh, const core::vector3df& factor) const {return scale(mesh,factor);} _IRR_DEPRECATED_ void scaleMesh(IMesh* mesh, const core::vector3df& factor) const {return scale(mesh,factor);}
//! Scale the texture coords of a mesh. //! Scale the texture coords of a mesh.
/** \param mesh Mesh on which the operation is performed. /** \param mesh Mesh on which the operation is performed.
@ -131,10 +131,10 @@ namespace scene
} }
//! Applies a transformation to a mesh //! Applies a transformation to a mesh
/** \deprecated Use transform() instead /** \deprecated Use transform() instead. This method may be removed by Irrlicht 1.9
\param mesh Mesh on which the operation is performed. \param mesh Mesh on which the operation is performed.
\param m transformation matrix. */ \param m transformation matrix. */
virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);} _IRR_DEPRECATED_ virtual void transformMesh(IMesh* mesh, const core::matrix4& m) const {return transform(mesh,m);}
//! Clones a static IMesh into a modifiable SMesh. //! Clones a static IMesh into a modifiable SMesh.
/** All meshbuffers in the returned SMesh /** All meshbuffers in the returned SMesh

View File

@ -454,7 +454,7 @@ public:
//! Creates a fade out particle affector. //! Creates a fade out particle affector.
/** This affector modifies the color of every particle and and reaches /** This affector modifies the color of every particle and and reaches
the final color when the particle dies. This affector looks really the final color when the particle dies. This affector looks really
good, if the EMT_TRANSPARENT_VERTEX_ALPHA material is used and the good, if the EMT_TRANSPARENT_ADD_COLOR material is used and the
targetColor is video::SColor(0,0,0,0): Particles are fading out into targetColor is video::SColor(0,0,0,0): Particles are fading out into
void with this setting. void with this setting.
\param targetColor: Color whereto the color of the particle is changed. \param targetColor: Color whereto the color of the particle is changed.

View File

@ -771,14 +771,19 @@ namespace quake3
io::IFileSystem *fileSystem, io::IFileSystem *fileSystem,
video::IVideoDriver* driver) video::IVideoDriver* driver)
{ {
static const char * extension[2] = static const char* extension[] =
{ {
".jpg", ".jpg",
".tga" ".jpeg",
".png",
".dds",
".tga",
".bmp",
".pcx"
}; };
tStringList stringList; tStringList stringList;
getAsStringList ( stringList, -1, name, startPos ); getAsStringList(stringList, -1, name, startPos);
textures.clear(); textures.clear();
@ -786,7 +791,7 @@ namespace quake3
for ( u32 i = 0; i!= stringList.size (); ++i ) for ( u32 i = 0; i!= stringList.size (); ++i )
{ {
video::ITexture* texture = 0; video::ITexture* texture = 0;
for ( u32 g = 0; g != 2 ; ++g ) for (u32 g = 0; g != 7 ; ++g)
{ {
core::cutFilenameExtension ( loadFile, stringList[i] ); core::cutFilenameExtension ( loadFile, stringList[i] );

58
include/ISceneLoader.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef __I_SCENE_LOADER_H_INCLUDED__
#define __I_SCENE_LOADER_H_INCLUDED__
#include "IReferenceCounted.h"
#include "path.h"
namespace irr
{
namespace io
{
class IReadFile;
} // end namespace io
namespace scene
{
class ISceneNode;
class ISceneUserDataSerializer;
//! Class which can load a scene into the scene manager.
/** If you want Irrlicht to be able to load currently unsupported
scene file formats (e.g. .vrml), then implement this and add your
new Sceneloader to the engine with ISceneManager::addExternalSceneLoader(). */
class ISceneLoader : public virtual IReferenceCounted
{
public:
//! Returns true if the class might be able to load this file.
/** This decision should be based on the file extension (e.g. ".vrml")
only.
\param fileName Name of the file to test.
\return True if the extension is a recognised type. */
virtual bool isALoadableFileExtension(const io::path& filename) const = 0;
//! Returns true if the class might be able to load this file.
/** This decision will be based on a quick look at the contents of the file.
\param file The file to test.
\return True if the extension is a recognised type. */
virtual bool isALoadableFileFormat(io::IReadFile* file) const = 0;
//! Loads the scene into the scene manager.
/** \param file File which contains the scene.
\param userDataSerializer: If you want to load user data which may be attached
to some some scene nodes in the file, implement the ISceneUserDataSerializer
interface and provide it as parameter here. Otherwise, simply specify 0 as this
parameter.
\param rootNode The node to load the scene into, if none is provided then the
scene will be loaded into the root node.
\return Returns true on success, false on failure. Returns 0 if loading failed. */
virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0,
ISceneNode* rootNode=0) = 0;
};
} // end namespace scene
} // end namespace irr
#endif

View File

@ -49,8 +49,6 @@ namespace video
namespace scene namespace scene
{ {
class IMeshWriter;
//! Enumeration for render passes. //! Enumeration for render passes.
/** A parameter passed to the registerNodeForRendering() method of the ISceneManager, /** A parameter passed to the registerNodeForRendering() method of the ISceneManager,
specifying when the node wants to be drawn in relation to the other nodes. */ specifying when the node wants to be drawn in relation to the other nodes. */
@ -96,33 +94,35 @@ namespace scene
ESNRP_SHADOW =64 ESNRP_SHADOW =64
}; };
class IAnimatedMesh;
class IAnimatedMeshSceneNode;
class IBillboardSceneNode;
class IBillboardTextSceneNode;
class ICameraSceneNode;
class IDummyTransformationSceneNode;
class ILightManager;
class ILightSceneNode;
class IMesh; class IMesh;
class IMeshBuffer; class IMeshBuffer;
class IAnimatedMesh;
class IMeshCache; class IMeshCache;
class IMeshLoader;
class IMeshManipulator;
class IMeshSceneNode;
class IMeshWriter;
class IMetaTriangleSelector;
class IParticleSystemSceneNode;
class ISceneCollisionManager;
class ISceneLoader;
class ISceneNode; class ISceneNode;
class ICameraSceneNode;
class IAnimatedMeshSceneNode;
class ISceneNodeAnimator; class ISceneNodeAnimator;
class ISceneNodeAnimatorCollisionResponse; class ISceneNodeAnimatorCollisionResponse;
class ILightSceneNode;
class IBillboardSceneNode;
class ITerrainSceneNode;
class IMeshSceneNode;
class IMeshLoader;
class ISceneCollisionManager;
class IParticleSystemSceneNode;
class IDummyTransformationSceneNode;
class ITriangleSelector;
class IMetaTriangleSelector;
class IMeshManipulator;
class ITextSceneNode;
class IBillboardTextSceneNode;
class IVolumeLightSceneNode;
class ISceneNodeFactory;
class ISceneNodeAnimatorFactory; class ISceneNodeAnimatorFactory;
class ISceneNodeFactory;
class ISceneUserDataSerializer; class ISceneUserDataSerializer;
class ILightManager; class ITerrainSceneNode;
class ITextSceneNode;
class ITriangleSelector;
class IVolumeLightSceneNode;
namespace quake3 namespace quake3
{ {
@ -144,16 +144,13 @@ namespace scene
character on a moving platform on a moving ship. character on a moving platform on a moving ship.
The SceneManager is also able to load 3d mesh files of different The SceneManager is also able to load 3d mesh files of different
formats. Take a look at getMesh() to find out what formats are formats. Take a look at getMesh() to find out what formats are
supported. And if these formats are not enough use supported. If these formats are not enough, use
addExternalMeshLoader() to add new formats to the engine. addExternalMeshLoader() to add new formats to the engine.
*/ */
class ISceneManager : public virtual IReferenceCounted class ISceneManager : public virtual IReferenceCounted
{ {
public: public:
//! Destructor
virtual ~ISceneManager() {}
//! Get pointer to an animateable mesh. Loads the file if not loaded already. //! Get pointer to an animateable mesh. Loads the file if not loaded already.
/** /**
* If you want to remove a loaded mesh from the cache again, use removeMesh(). * If you want to remove a loaded mesh from the cache again, use removeMesh().
@ -167,12 +164,22 @@ namespace scene
* <TD>3D Studio (.3ds)</TD> * <TD>3D Studio (.3ds)</TD>
* <TD>Loader for 3D-Studio files which lots of 3D packages * <TD>Loader for 3D-Studio files which lots of 3D packages
* are able to export. Only static meshes are currently * are able to export. Only static meshes are currently
* supported by this importer. </TD> * supported by this importer.</TD>
* </TR>
* <TR>
* <TD>3D World Studio (.smf)</TD>
* <TD>Loader for Leadwerks SMF mesh files, a simple mesh format
* containing static geometry for games. The proprietary .STF texture format
* is not supported yet. This loader was originally written by Joseph Ellis. </TD>
* </TR> * </TR>
* <TR> * <TR>
* <TD>Bliz Basic B3D (.b3d)</TD> * <TD>Bliz Basic B3D (.b3d)</TD>
* <TD>Loader for blitz basic files, developed by Mark * <TD>Loader for blitz basic files, developed by Mark
* Sibly, also supports animations.</TD> * Sibly. This is the ideal animated mesh format for game
* characters as it is both rigidly defined and widely
* supported by modeling and animation software.
* As this format supports skeletal animations, an
* ISkinnedMesh will be returned by this importer.</TD>
* </TR> * </TR>
* <TR> * <TR>
* <TD>Cartography shop 4 (.csm)</TD> * <TD>Cartography shop 4 (.csm)</TD>
@ -203,7 +210,7 @@ namespace scene
* behaves like the other loaders and does not create * behaves like the other loaders and does not create
* instances, but it can be switched into this mode by * instances, but it can be switched into this mode by
* using * using
* SceneManager->getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, true); * SceneManager-&gt;getParameters()-&gt;setAttribute(COLLADA_CREATE_SCENE_INSTANCES, true);
* Created scene nodes will be named as the names of the * Created scene nodes will be named as the names of the
* nodes in the COLLADA file. The returned mesh is just * nodes in the COLLADA file. The returned mesh is just
* a dummy object in this mode. Meshes included in the * a dummy object in this mode. Meshes included in the
@ -211,6 +218,8 @@ namespace scene
* following naming scheme: * following naming scheme:
* "path/to/file/file.dea#meshname". The loading of such * "path/to/file/file.dea#meshname". The loading of such
* meshes is logged. Currently, this loader is able to * meshes is logged. Currently, this loader is able to
* create meshes (made of only polygons), lights, and * create meshes (made of only polygons), lights, and
* cameras. Materials and animations are currently not * cameras. Materials and animations are currently not
* supported but this will change with future releases. * supported but this will change with future releases.
@ -244,8 +253,28 @@ namespace scene
* and there are several tools for them available, e.g. * and there are several tools for them available, e.g.
* the Maya exporter included in the DX SDK. * the Maya exporter included in the DX SDK.
* .x files can include skeletal animations and Irrlicht * .x files can include skeletal animations and Irrlicht
* is able to play and display them. Currently, Irrlicht * is able to play and display them, users can manipulate
* only supports uncompressed .x files.</TD> * the joints via the ISkinnedMesh interface. Currently,
* Irrlicht only supports uncompressed .x files.</TD>
* </TR>
* <TR>
* <TD>Half-Life model (.mdl)</TD>
* <TD>This loader opens Half-life 1 models, it was contributed
* by Fabio Concas and adapted by Thomas Alten.</TD>
* </TR>
* <TR>
* <TD>Irrlicht Mesh (.irrMesh)</TD>
* <TD>This is a static mesh format written in XML, native
* to Irrlicht and written by the irr mesh writer.
* This format is exported by the CopperCube engine's
* lightmapper.</TD>
* </TR>
* <TR>
* <TD>LightWave (.lwo)</TD>
* <TD>Native to NewTek's LightWave 3D, the LWO format is well
* known and supported by many exporters. This loader will
* import LWO2 models including lightmaps, bumpmaps and
* reflection textures.</TD>
* </TR> * </TR>
* <TR> * <TR>
* <TD>Maya (.obj)</TD> * <TD>Maya (.obj)</TD>
@ -258,8 +287,8 @@ namespace scene
* <TD>Milkshape (.ms3d)</TD> * <TD>Milkshape (.ms3d)</TD>
* <TD>.MS3D files contain models and sometimes skeletal * <TD>.MS3D files contain models and sometimes skeletal
* animations from the Milkshape 3D modeling and animation * animations from the Milkshape 3D modeling and animation
* software. This importer for Irrlicht can display and/or * software. Like the other skeletal mesh loaders, oints
* animate these files. </TD> * are exposed via the ISkinnedMesh animated mesh type.</TD>
* </TR> * </TR>
* <TR> * <TR>
* <TD>My3D (.my3d)</TD> * <TD>My3D (.my3d)</TD>
@ -331,6 +360,29 @@ namespace scene
* animation. Irrlicht can read, display and animate * animation. Irrlicht can read, display and animate
* them directly with this importer. </TD> * them directly with this importer. </TD>
* </TR> * </TR>
* <TR>
* <TD>Quake 3 models (.md3)</TD>
* <TD>Quake 3 models are characters with morph target
* animation, they contain mount points for weapons and body
* parts and are typically made of several sections which are
* manually joined together.</TD>
* </TR>
* <TR>
* <TD>Stanford Triangle (.ply)</TD>
* <TD>Invented by Stanford University and known as the native
* format of the infamous "Stanford Bunny" model, this is a
* popular static mesh format used by 3D scanning hardware
* and software. This loader supports extremely large models
* in both ASCII and binary format, but only has rudimentary
* material support in the form of vertex colors and texture
* coordinates.</TD>
* </TR>
* <TR>
* <TD>Stereolithography (.stl)</TD>
* <TD>The STL format is used for rapid prototyping and
* computer-aided manufacturing, thus has no support for
* materials.</TD>
* </TR>
* </TABLE> * </TABLE>
* *
* To load and display a mesh quickly, just do this: * To load and display a mesh quickly, just do this:
@ -510,7 +562,7 @@ namespace scene
s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false) = 0; s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false) = 0;
//! Adds a scene node for rendering using a octree to the scene graph. //! Adds a scene node for rendering using a octree to the scene graph.
/** \deprecated Use addOctreeSceneNode instead. */ /** \deprecated Use addOctreeSceneNode instead. This method may be removed by Irrlicht 1.9. */
_IRR_DEPRECATED_ IMeshSceneNode* addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0, _IRR_DEPRECATED_ IMeshSceneNode* addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* parent=0,
s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false) s32 id=-1, s32 minimalPolysPerNode=512, bool alsoAddIfMeshPointerZero=false)
{ {
@ -534,7 +586,7 @@ namespace scene
s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0; s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) = 0;
//! Adds a scene node for rendering using a octree to the scene graph. //! Adds a scene node for rendering using a octree to the scene graph.
/** \deprecated Use addOctreeSceneNode instead. */ /** \deprecated Use addOctreeSceneNode instead. This method may be removed by Irrlicht 1.9. */
_IRR_DEPRECATED_ IMeshSceneNode* addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent=0, _IRR_DEPRECATED_ IMeshSceneNode* addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent=0,
s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false) s32 id=-1, s32 minimalPolysPerNode=256, bool alsoAddIfMeshPointerZero=false)
{ {
@ -1278,7 +1330,7 @@ namespace scene
ISceneNode* node, s32 minimalPolysPerNode=32) = 0; ISceneNode* node, s32 minimalPolysPerNode=32) = 0;
//! //! Creates a Triangle Selector, optimized by an octree. //! //! Creates a Triangle Selector, optimized by an octree.
/** \deprecated Use createOctreeTriangleSelector instead. */ /** \deprecated Use createOctreeTriangleSelector instead. This method may be removed by Irrlicht 1.9. */
_IRR_DEPRECATED_ ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh, _IRR_DEPRECATED_ ITriangleSelector* createOctTreeTriangleSelector(IMesh* mesh,
ISceneNode* node, s32 minimalPolysPerNode=32) ISceneNode* node, s32 minimalPolysPerNode=32)
{ {
@ -1309,10 +1361,37 @@ namespace scene
file formats it currently is not able to load (e.g. .cob), just implement file formats it currently is not able to load (e.g. .cob), just implement
the IMeshLoader interface in your loading class and add it with this method. the IMeshLoader interface in your loading class and add it with this method.
Using this method it is also possible to override built-in mesh loaders with Using this method it is also possible to override built-in mesh loaders with
newer or updated versions without the need of recompiling the engine. newer or updated versions without the need to recompile the engine.
\param externalLoader: Implementation of a new mesh loader. */ \param externalLoader: Implementation of a new mesh loader. */
virtual void addExternalMeshLoader(IMeshLoader* externalLoader) = 0; virtual void addExternalMeshLoader(IMeshLoader* externalLoader) = 0;
//! Returns the number of mesh loaders supported by Irrlicht at this time
virtual u32 getMeshLoaderCount() const = 0;
//! Retrieve the given mesh loader
/** \param index The index of the loader to retrieve. This parameter is an 0-based
array index.
\return A pointer to the specified loader, 0 if the index is incorrect. */
virtual IMeshLoader* getMeshLoader(u32 index) const = 0;
//! Adds an external scene loader for extending the engine with new file formats.
/** If you want the engine to be extended with
file formats it currently is not able to load (e.g. .vrml), just implement
the ISceneLoader interface in your loading class and add it with this method.
Using this method it is also possible to override the built-in scene loaders
with newer or updated versions without the need to recompile the engine.
\param externalLoader: Implementation of a new mesh loader. */
virtual void addExternalSceneLoader(ISceneLoader* externalLoader) = 0;
//! Returns the number of scene loaders supported by Irrlicht at this time
virtual u32 getSceneLoaderCount() const = 0;
//! Retrieve the given scene loader
/** \param index The index of the loader to retrieve. This parameter is an 0-based
array index.
\return A pointer to the specified loader, 0 if the index is incorrect. */
virtual ISceneLoader* getSceneLoader(u32 index) const = 0;
//! Get pointer to the scene collision manager. //! Get pointer to the scene collision manager.
/** \return Pointer to the collision manager /** \return Pointer to the collision manager
This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
@ -1407,6 +1486,13 @@ namespace scene
This pointer should not be dropped. See IReferenceCounted::drop() for more information. */ This pointer should not be dropped. See IReferenceCounted::drop() for more information. */
virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent=0) = 0; virtual ISceneNode* addSceneNode(const char* sceneNodeTypeName, ISceneNode* parent=0) = 0;
//! creates a scene node animator based on its type name
/** \param typeName: Type of the scene node animator to add.
\param target: Target scene node of the new animator.
\return Returns pointer to the new scene node animator or null if not successful. You need to
drop this pointer after calling this, see IReferenceCounted::drop() for details. */
virtual ISceneNodeAnimator* createSceneNodeAnimator(const char* typeName, ISceneNode* target=0) = 0;
//! Creates a new scene manager. //! Creates a new scene manager.
/** This can be used to easily draw and/or store two /** This can be used to easily draw and/or store two
independent scenes at the same time. The mesh cache will be independent scenes at the same time. The mesh cache will be
@ -1459,7 +1545,8 @@ namespace scene
virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0) = 0; virtual bool saveScene(io::IWriteFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0) = 0;
//! Loads a scene. Note that the current scene is not cleared before. //! Loads a scene. Note that the current scene is not cleared before.
/** The scene is usually load from an .irr file, an xml based format. .irr files can /** The scene is usually loaded from an .irr file, an xml based format, but other scene formats
can be added to the engine via ISceneManager::addExternalSceneLoader. .irr files can
Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or
saved directly by the engine using ISceneManager::saveScene(). saved directly by the engine using ISceneManager::saveScene().
\param filename: Name of the file. \param filename: Name of the file.
@ -1468,13 +1555,14 @@ namespace scene
implement the ISceneUserDataSerializer interface and provide it implement the ISceneUserDataSerializer interface and provide it
as parameter here. Otherwise, simply specify 0 as this as parameter here. Otherwise, simply specify 0 as this
parameter. parameter.
\param node Node which is taken as the root node of the scene. Pass 0 to add the scene \param rootNode Node which is taken as the root node of the scene. Pass 0 to add the scene
directly to the scene manager (which is also the default). directly to the scene manager (which is also the default).
\return True if successful. */ \return True if successful. */
virtual bool loadScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0) = 0; virtual bool loadScene(const io::path& filename, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* rootNode=0) = 0;
//! Loads a scene. Note that the current scene is not cleared before. //! Loads a scene. Note that the current scene is not cleared before.
/** The scene is usually load from an .irr file, an xml based format. .irr files can /** The scene is usually loaded from an .irr file, an xml based format, but other scene formats
can be added to the engine via ISceneManager::addExternalSceneLoader. .irr files can
Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or Be edited with the Irrlicht Engine Editor, irrEdit (http://irredit.irrlicht3d.org) or
saved directly by the engine using ISceneManager::saveScene(). saved directly by the engine using ISceneManager::saveScene().
\param file: File where the scene is going to be saved into. \param file: File where the scene is going to be saved into.
@ -1483,10 +1571,10 @@ namespace scene
implement the ISceneUserDataSerializer interface and provide it implement the ISceneUserDataSerializer interface and provide it
as parameter here. Otherwise, simply specify 0 as this as parameter here. Otherwise, simply specify 0 as this
parameter. parameter.
\param node Node which is taken as the root node of the scene. Pass 0 to add the scene \param rootNode Node which is taken as the root node of the scene. Pass 0 to add the scene
directly to the scene manager (which is also the default). directly to the scene manager (which is also the default).
\return True if successful. */ \return True if successful. */
virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* node=0) = 0; virtual bool loadScene(io::IReadFile* file, ISceneUserDataSerializer* userDataSerializer=0, ISceneNode* rootNode=0) = 0;
//! Get a mesh writer implementation if available //! Get a mesh writer implementation if available
/** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop() /** Note: You need to drop() the pointer after use again, see IReferenceCounted::drop()

View File

@ -539,7 +539,7 @@ namespace scene
/** A bitwise OR of the types from @ref irr::scene::E_DEBUG_SCENE_TYPE. /** A bitwise OR of the types from @ref irr::scene::E_DEBUG_SCENE_TYPE.
Please note that not all scene nodes support all debug data types. Please note that not all scene nodes support all debug data types.
\param state The debug data visibility state to be used. */ \param state The debug data visibility state to be used. */
virtual void setDebugDataVisible(s32 state) virtual void setDebugDataVisible(u32 state)
{ {
DebugDataVisible = state; DebugDataVisible = state;
} }
@ -547,7 +547,7 @@ namespace scene
//! Returns if debug data like bounding boxes are drawn. //! Returns if debug data like bounding boxes are drawn.
/** \return A bitwise OR of the debug data values from /** \return A bitwise OR of the debug data values from
@ref irr::scene::E_DEBUG_SCENE_TYPE that are currently visible. */ @ref irr::scene::E_DEBUG_SCENE_TYPE that are currently visible. */
s32 isDebugDataVisible() const u32 isDebugDataVisible() const
{ {
return DebugDataVisible; return DebugDataVisible;
} }
@ -831,7 +831,7 @@ namespace scene
u32 AutomaticCullingState; u32 AutomaticCullingState;
//! Flag if debug data should be drawn, such as Bounding Boxes. //! Flag if debug data should be drawn, such as Bounding Boxes.
s32 DebugDataVisible; u32 DebugDataVisible;
//! Is the node visible? //! Is the node visible?
bool IsVisible; bool IsVisible;

View File

@ -28,8 +28,6 @@ namespace scene
{ {
public: public:
virtual ~ISceneNodeAnimatorFactory() {}
//! creates a scene node animator based on its type id //! creates a scene node animator based on its type id
/** \param type: Type of the scene node animator to add. /** \param type: Type of the scene node animator to add.
\param target: Target scene node of the new animator. \param target: Target scene node of the new animator.

View File

@ -29,10 +29,7 @@ class ITriangleSelector : public virtual IReferenceCounted
{ {
public: public:
//! Destructor //! Get amount of all available triangles in this selector
virtual ~ITriangleSelector() {}
//! Returns amount of all available triangles in this selector
virtual s32 getTriangleCount() const = 0; virtual s32 getTriangleCount() const = 0;
//! Gets the triangles for one associated node. //! Gets the triangles for one associated node.
@ -41,19 +38,19 @@ public:
selector. If there is more than one scene node associated (e.g. for selector. If there is more than one scene node associated (e.g. for
an IMetaTriangleSelector) this this function may be called multiple an IMetaTriangleSelector) this this function may be called multiple
times to retrieve all triangles. times to retrieve all triangles.
\param triangles: Array where the resulting triangles will be \param triangles Array where the resulting triangles will be
written to. written to.
\param arraySize: Size of the target array. \param arraySize Size of the target array.
\param outTriangleCount: Amount of triangles which have been written \param outTriangleCount: Amount of triangles which have been written
into the array. into the array.
\param transform: Pointer to matrix for transforming the triangles \param transform Pointer to matrix for transforming the triangles
before they are returned. Useful for example to scale all triangles before they are returned. Useful for example to scale all triangles
down into an ellipsoid space. If this pointer is null, no down into an ellipsoid space. If this pointer is null, no
transformation will be done. */ transformation will be done. */
virtual void getTriangles(core::triangle3df* triangles, s32 arraySize, virtual void getTriangles(core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::matrix4* transform=0) const = 0; s32& outTriangleCount, const core::matrix4* transform=0) const = 0;
//! Gets the triangles for one associated node which lie or may lie within a specific bounding box. //! Gets the triangles for one associated node which may lie within a specific bounding box.
/** /**
This returns all triangles for one scene node associated with this This returns all triangles for one scene node associated with this
selector. If there is more than one scene node associated (e.g. for selector. If there is more than one scene node associated (e.g. for
@ -62,14 +59,14 @@ public:
This method will return at least the triangles that intersect the box, This method will return at least the triangles that intersect the box,
but may return other triangles as well. but may return other triangles as well.
\param triangles: Array where the resulting triangles will be written \param triangles Array where the resulting triangles will be written
to. to.
\param arraySize: Size of the target array. \param arraySize Size of the target array.
\param outTriangleCount: Amount of triangles which have been written \param outTriangleCount Amount of triangles which have been written
into the array. into the array.
\param box: Only triangles which are in this axis aligned bounding box \param box Only triangles which are in this axis aligned bounding box
will be written into the array. will be written into the array.
\param transform: Pointer to matrix for transforming the triangles \param transform Pointer to matrix for transforming the triangles
before they are returned. Useful for example to scale all triangles before they are returned. Useful for example to scale all triangles
down into an ellipsoid space. If this pointer is null, no down into an ellipsoid space. If this pointer is null, no
transformation will be done. */ transformation will be done. */
@ -86,14 +83,14 @@ public:
Please note that unoptimized triangle selectors also may return Please note that unoptimized triangle selectors also may return
triangles which are not in contact at all with the 3d line. triangles which are not in contact at all with the 3d line.
\param triangles: Array where the resulting triangles will be written \param triangles Array where the resulting triangles will be written
to. to.
\param arraySize: Size of the target array. \param arraySize Size of the target array.
\param outTriangleCount: Amount of triangles which have been written \param outTriangleCount Amount of triangles which have been written
into the array. into the array.
\param line: Only triangles which may be in contact with this 3d line \param line Only triangles which may be in contact with this 3d line
will be written into the array. will be written into the array.
\param transform: Pointer to matrix for transforming the triangles \param transform Pointer to matrix for transforming the triangles
before they are returned. Useful for example to scale all triangles before they are returned. Useful for example to scale all triangles
down into an ellipsoid space. If this pointer is null, no down into an ellipsoid space. If this pointer is null, no
transformation will be done. */ transformation will be done. */
@ -101,9 +98,9 @@ public:
s32& outTriangleCount, const core::line3d<f32>& line, s32& outTriangleCount, const core::line3d<f32>& line,
const core::matrix4* transform=0) const = 0; const core::matrix4* transform=0) const = 0;
//! Return the scene node associated with a given triangle. //! Get scene node associated with a given triangle.
/** /**
This allows you to find which scene node (potentially of several) is This allows to find which scene node (potentially of several) is
associated with a specific triangle. associated with a specific triangle.
\param triangleIndex: the index of the triangle for which you want to find \param triangleIndex: the index of the triangle for which you want to find
@ -112,11 +109,23 @@ public:
*/ */
virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const = 0; virtual ISceneNode* getSceneNodeForTriangle(u32 triangleIndex) const = 0;
//! Get number of TriangleSelectors that are part of this one
/** Only useful for MetaTriangleSelector, others return 1
*/
virtual u32 getSelectorCount() const = 0;
//! Get TriangleSelector based on index based on getSelectorCount
/** Only useful for MetaTriangleSelector, others return 'this' or 0
*/
virtual ITriangleSelector* getSelector(u32 index) = 0;
//! Get TriangleSelector based on index based on getSelectorCount
/** Only useful for MetaTriangleSelector, others return 'this' or 0
*/
virtual const ITriangleSelector* getSelector(u32 index) const = 0;
}; };
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr
#endif #endif

View File

@ -25,6 +25,7 @@ namespace irr
namespace io namespace io
{ {
class IAttributes; class IAttributes;
struct SAttributeReadWriteOptions;
class IReadFile; class IReadFile;
class IWriteFile; class IWriteFile;
} // end namespace io } // end namespace io
@ -84,11 +85,11 @@ namespace video
ETS_COUNT ETS_COUNT
}; };
//! enumeration for signalling ressources which were lost after the last render cycle //! enumeration for signaling resources which were lost after the last render cycle
/** These values can be signalled by the driver, telling the app that some ressources /** These values can be signaled by the driver, telling the app that some resources
were lost and need to be recreated. Irrlicht will sometimes recreate the actual objects, were lost and need to be recreated. Irrlicht will sometimes recreate the actual objects,
but the content needs to be recreated by the application. */ but the content needs to be recreated by the application. */
enum E_LOST_RESSOURCE enum E_LOST_RESOURCE
{ {
//! The whole device/driver is lost //! The whole device/driver is lost
ELR_DEVICE = 1, ELR_DEVICE = 1,
@ -208,20 +209,20 @@ namespace video
E_COLOR_PLANE colorMask=ECP_ALL, E_COLOR_PLANE colorMask=ECP_ALL,
E_BLEND_FACTOR blendFuncSrc=EBF_ONE, E_BLEND_FACTOR blendFuncSrc=EBF_ONE,
E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA, E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA,
bool blendEnable=false) : E_BLEND_OPERATION blendOp=EBO_NONE) :
RenderTexture(texture), RenderTexture(texture),
TargetType(ERT_RENDER_TEXTURE), ColorMask(colorMask), TargetType(ERT_RENDER_TEXTURE), ColorMask(colorMask),
BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst), BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst),
BlendEnable(blendEnable) {} BlendOp(blendOp) {}
IRenderTarget(E_RENDER_TARGET target, IRenderTarget(E_RENDER_TARGET target,
E_COLOR_PLANE colorMask=ECP_ALL, E_COLOR_PLANE colorMask=ECP_ALL,
E_BLEND_FACTOR blendFuncSrc=EBF_ONE, E_BLEND_FACTOR blendFuncSrc=EBF_ONE,
E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA, E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA,
bool blendEnable=false) : E_BLEND_OPERATION blendOp=EBO_NONE) :
RenderTexture(0), RenderTexture(0),
TargetType(target), ColorMask(colorMask), TargetType(target), ColorMask(colorMask),
BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst), BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst),
BlendEnable(blendEnable) {} BlendOp(blendOp) {}
bool operator!=(const IRenderTarget& other) const bool operator!=(const IRenderTarget& other) const
{ {
return ((RenderTexture != other.RenderTexture) || return ((RenderTexture != other.RenderTexture) ||
@ -229,14 +230,14 @@ namespace video
(ColorMask != other.ColorMask) || (ColorMask != other.ColorMask) ||
(BlendFuncSrc != other.BlendFuncSrc) || (BlendFuncSrc != other.BlendFuncSrc) ||
(BlendFuncDst != other.BlendFuncDst) || (BlendFuncDst != other.BlendFuncDst) ||
(BlendEnable != other.BlendEnable)); (BlendOp != other.BlendOp));
} }
ITexture* RenderTexture; ITexture* RenderTexture;
E_RENDER_TARGET TargetType:8; E_RENDER_TARGET TargetType:8;
E_COLOR_PLANE ColorMask:8; E_COLOR_PLANE ColorMask:8;
E_BLEND_FACTOR BlendFuncSrc:4; E_BLEND_FACTOR BlendFuncSrc:4;
E_BLEND_FACTOR BlendFuncDst:4; E_BLEND_FACTOR BlendFuncDst:4;
bool BlendEnable; E_BLEND_OPERATION BlendOp:4;
}; };
//! Interface to driver which is able to perform 2d and 3d graphics functions. //! Interface to driver which is able to perform 2d and 3d graphics functions.
@ -336,7 +337,7 @@ namespace video
//! Retrieve the given image loader //! Retrieve the given image loader
/** \param n The index of the loader to retrieve. This parameter is an 0-based /** \param n The index of the loader to retrieve. This parameter is an 0-based
array index. array index.
\return A pointer to the specified loader, 0 if the index is uncorrect. */ \return A pointer to the specified loader, 0 if the index is incorrect. */
virtual IImageLoader* getImageLoader(u32 n) = 0; virtual IImageLoader* getImageLoader(u32 n) = 0;
//! Retrieve the number of image writers //! Retrieve the number of image writers
@ -346,7 +347,7 @@ namespace video
//! Retrieve the given image writer //! Retrieve the given image writer
/** \param n The index of the writer to retrieve. This parameter is an 0-based /** \param n The index of the writer to retrieve. This parameter is an 0-based
array index. array index.
\return A pointer to the specified writer, 0 if the index is uncorrect. */ \return A pointer to the specified writer, 0 if the index is incorrect. */
virtual IImageWriter* getImageWriter(u32 n) = 0; virtual IImageWriter* getImageWriter(u32 n) = 0;
//! Sets a material. //! Sets a material.
@ -462,7 +463,7 @@ namespace video
//! Create occlusion query. //! Create occlusion query.
/** Use node for identification and mesh for occlusion test. */ /** Use node for identification and mesh for occlusion test. */
virtual void createOcclusionQuery(scene::ISceneNode* node, virtual void addOcclusionQuery(scene::ISceneNode* node,
const scene::IMesh* mesh=0) =0; const scene::IMesh* mesh=0) =0;
//! Remove occlusion query. //! Remove occlusion query.
@ -512,7 +513,8 @@ namespace video
\param zeroTexels \deprecated If set to true, then any texels that match \param zeroTexels \deprecated If set to true, then any texels that match
the color key will have their color, as well as their alpha, set to zero the color key will have their color, as well as their alpha, set to zero
(i.e. black). This behaviour matches the legacy (buggy) behaviour prior (i.e. black). This behaviour matches the legacy (buggy) behaviour prior
to release 1.5 and is provided for backwards compatibility only.*/ to release 1.5 and is provided for backwards compatibility only.
This parameter may be removed by Irrlicht 1.9. */
virtual void makeColorKeyTexture(video::ITexture* texture, virtual void makeColorKeyTexture(video::ITexture* texture,
video::SColor color, video::SColor color,
bool zeroTexels = false) const =0; bool zeroTexels = false) const =0;
@ -528,7 +530,8 @@ namespace video
\param zeroTexels \deprecated If set to true, then any texels that match \param zeroTexels \deprecated If set to true, then any texels that match
the color key will have their color, as well as their alpha, set to zero the color key will have their color, as well as their alpha, set to zero
(i.e. black). This behaviour matches the legacy (buggy) behaviour prior (i.e. black). This behaviour matches the legacy (buggy) behaviour prior
to release 1.5 and is provided for backwards compatibility only.*/ to release 1.5 and is provided for backwards compatibility only.
This parameter may be removed by Irrlicht 1.9. */
virtual void makeColorKeyTexture(video::ITexture* texture, virtual void makeColorKeyTexture(video::ITexture* texture,
core::position2d<s32> colorKeyPixelPos, core::position2d<s32> colorKeyPixelPos,
bool zeroTexels = false) const =0; bool zeroTexels = false) const =0;
@ -1211,23 +1214,23 @@ namespace video
virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) =0; virtual IImage* createImage(ECOLOR_FORMAT format, const core::dimension2d<u32>& size) =0;
//! Creates a software image by converting it to given format from another image. //! Creates a software image by converting it to given format from another image.
/** \deprecated Create an empty image and use copyTo() /** \deprecated Create an empty image and use copyTo(). This method may be removed by Irrlicht 1.9.
\param format Desired color format of the image. \param format Desired color format of the image.
\param imageToCopy Image to copy to the new image. \param imageToCopy Image to copy to the new image.
\return The created image. \return The created image.
If you no longer need the image, you should call IImage::drop(). If you no longer need the image, you should call IImage::drop().
See IReferenceCounted::drop() for more information. */ See IReferenceCounted::drop() for more information. */
virtual IImage* createImage(ECOLOR_FORMAT format, IImage *imageToCopy) =0; _IRR_DEPRECATED_ virtual IImage* createImage(ECOLOR_FORMAT format, IImage *imageToCopy) =0;
//! Creates a software image from a part of another image. //! Creates a software image from a part of another image.
/** \deprecated Create an empty image and use copyTo() /** \deprecated Create an empty image and use copyTo(). This method may be removed by Irrlicht 1.9.
\param imageToCopy Image to copy to the new image in part. \param imageToCopy Image to copy to the new image in part.
\param pos Position of rectangle to copy. \param pos Position of rectangle to copy.
\param size Extents of rectangle to copy. \param size Extents of rectangle to copy.
\return The created image. \return The created image.
If you no longer need the image, you should call IImage::drop(). If you no longer need the image, you should call IImage::drop().
See IReferenceCounted::drop() for more information. */ See IReferenceCounted::drop() for more information. */
virtual IImage* createImage(IImage* imageToCopy, _IRR_DEPRECATED_ virtual IImage* createImage(IImage* imageToCopy,
const core::position2d<s32>& pos, const core::position2d<s32>& pos,
const core::dimension2d<u32>& size) =0; const core::dimension2d<u32>& size) =0;
@ -1308,9 +1311,12 @@ namespace video
renderer names from getMaterialRendererName() to write out the renderer names from getMaterialRendererName() to write out the
material type name, so they should be set before. material type name, so they should be set before.
\param material The material to serialize. \param material The material to serialize.
\param options Additional options which might influence the
serialization.
\return The io::IAttributes container holding the material \return The io::IAttributes container holding the material
properties. */ properties. */
virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material) =0; virtual io::IAttributes* createAttributesFromMaterial(const video::SMaterial& material,
io::SAttributeReadWriteOptions* options=0) =0;
//! Fills an SMaterial structure from attributes. //! Fills an SMaterial structure from attributes.
/** Please note that for setting material types of the /** Please note that for setting material types of the

View File

@ -11,7 +11,7 @@
#define IRRLICHT_VERSION_REVISION 0 #define IRRLICHT_VERSION_REVISION 0
// This flag will be defined only in SVN, the official release code will have // This flag will be defined only in SVN, the official release code will have
// it undefined // it undefined
#define IRRLICHT_VERSION_SVN -beta #define IRRLICHT_VERSION_SVN -alpha
#define IRRLICHT_SDK_VERSION "1.8.0-alpha" #define IRRLICHT_SDK_VERSION "1.8.0-alpha"
#include <stdio.h> // TODO: Although included elsewhere this is required at least for mingw #include <stdio.h> // TODO: Although included elsewhere this is required at least for mingw
@ -122,6 +122,14 @@
#undef _IRR_COMPILE_WITH_JOYSTICK_EVENTS_ #undef _IRR_COMPILE_WITH_JOYSTICK_EVENTS_
#endif #endif
//! Define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_ if you want to use DirectInput for joystick handling.
/** This only applies to Windows devices, currently only supported under Win32 device.
If not defined, Windows Multimedia library is used, which offers also broad support for joystick devices. */
#define _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#ifdef NO_IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#undef _IRR_COMPILE_WITH_DIRECTINPUT_JOYSTICK_
#endif
//! Maximum number of texture an SMaterial can have, up to 8 are supported by Irrlicht. //! Maximum number of texture an SMaterial can have, up to 8 are supported by Irrlicht.
#define _IRR_MATERIAL_MAX_TEXTURES_ 4 #define _IRR_MATERIAL_MAX_TEXTURES_ 4
@ -363,6 +371,13 @@ tool <http://developer.nvidia.com/object/nvperfhud_home.html>. */
//! Uncomment the following line if you want to ignore the deprecated warnings //! Uncomment the following line if you want to ignore the deprecated warnings
//#define IGNORE_DEPRECATED_WARNING //#define IGNORE_DEPRECATED_WARNING
//! Define _IRR_COMPILE_WITH_IRR_SCENE_LOADER_ if you want to be able to load
/** .irr scenes using ISceneManager::loadScene */
#define _IRR_COMPILE_WITH_IRR_SCENE_LOADER_
#ifdef NO_IRR_COMPILE_WITH_IRR_SCENE_LOADER_
#undef _IRR_COMPILE_WITH_IRR_SCENE_LOADER_
#endif
//! Define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ if you want to use bone based //! Define _IRR_COMPILE_WITH_SKINNED_MESH_SUPPORT_ if you want to use bone based
/** animated meshes. If you compile without this, you will be unable to load /** animated meshes. If you compile without this, you will be unable to load
B3D, MS3D or X meshes */ B3D, MS3D or X meshes */
@ -474,6 +489,11 @@ B3D, MS3D or X meshes */
#ifdef NO_IRR_COMPILE_WITH_PLY_LOADER_ #ifdef NO_IRR_COMPILE_WITH_PLY_LOADER_
#undef _IRR_COMPILE_WITH_PLY_LOADER_ #undef _IRR_COMPILE_WITH_PLY_LOADER_
#endif #endif
//! Define _IRR_COMPILE_WITH_SMF_LOADER_ if you want to load 3D World Studio mesh files
#define _IRR_COMPILE_WITH_SMF_LOADER_
#ifdef NO_IRR_COMPILE_WITH_SMF_LOADER_
#undef _IRR_COMPILE_WITH_SMF_LOADER_
#endif
//! Define _IRR_COMPILE_WITH_IRR_WRITER_ if you want to write static .irrMesh files //! Define _IRR_COMPILE_WITH_IRR_WRITER_ if you want to write static .irrMesh files
#define _IRR_COMPILE_WITH_IRR_WRITER_ #define _IRR_COMPILE_WITH_IRR_WRITER_

View File

@ -583,9 +583,10 @@ namespace video
}; };
//! Class representing a color in HSV format //! Class representing a color in HSL format
/** The color values for hue, saturation, value /** The color values for hue, saturation, luminance
are stored in a 32 bit floating point variable. are stored in 32bit floating point variables. Hue is in range [0,360],
Luminance and Saturation are in percent [0,100]
*/ */
class SColorHSL class SColorHSL
{ {
@ -593,24 +594,23 @@ namespace video
SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f ) SColorHSL ( f32 h = 0.f, f32 s = 0.f, f32 l = 0.f )
: Hue ( h ), Saturation ( s ), Luminance ( l ) {} : Hue ( h ), Saturation ( s ), Luminance ( l ) {}
void fromRGB(const SColor &color); void fromRGB(const SColorf &color);
void toRGB(SColor &color) const; void toRGB(SColorf &color) const;
f32 Hue; f32 Hue;
f32 Saturation; f32 Saturation;
f32 Luminance; f32 Luminance;
private: private:
inline u32 toRGB1(f32 rm1, f32 rm2, f32 rh) const; inline f32 toRGB1(f32 rm1, f32 rm2, f32 rh) const;
}; };
inline void SColorHSL::fromRGB(const SColor &color) inline void SColorHSL::fromRGB(const SColorf &color)
{ {
const u32 maxValInt = core::max_(color.getRed(), color.getGreen(), color.getBlue()); const f32 maxVal = core::max_(color.getRed(), color.getGreen(), color.getBlue());
const f32 maxVal = (f32)maxValInt;
const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue()); const f32 minVal = (f32)core::min_(color.getRed(), color.getGreen(), color.getBlue());
Luminance = (maxVal/minVal)*0.5f; Luminance = (maxVal+minVal)*50;
if (core::equals(maxVal, minVal)) if (core::equals(maxVal, minVal))
{ {
Hue=0.f; Hue=0.f;
@ -619,7 +619,7 @@ namespace video
} }
const f32 delta = maxVal-minVal; const f32 delta = maxVal-minVal;
if ( Luminance <= 0.5f ) if ( Luminance <= 50 )
{ {
Saturation = (delta)/(maxVal+minVal); Saturation = (delta)/(maxVal+minVal);
} }
@ -627,71 +627,70 @@ namespace video
{ {
Saturation = (delta)/(2-maxVal-minVal); Saturation = (delta)/(2-maxVal-minVal);
} }
Saturation *= 100;
if (maxValInt == color.getRed()) if (core::equals(maxVal, color.getRed()))
Hue = (color.getGreen()-color.getBlue())/delta; Hue = (color.getGreen()-color.getBlue())/delta;
else if (maxValInt == color.getGreen()) else if (core::equals(maxVal, color.getGreen()))
Hue = 2+(color.getBlue()-color.getRed())/delta; Hue = 2+((color.getBlue()-color.getRed())/delta);
else // blue is max else // blue is max
Hue = 4+(color.getRed()-color.getGreen())/delta; Hue = 4+((color.getRed()-color.getGreen())/delta);
Hue *= (60.0f * core::DEGTORAD); Hue *= 60.0f;
while ( Hue < 0.f ) while ( Hue < 0.f )
Hue += 2.f * core::PI; Hue += 360;
} }
inline void SColorHSL::toRGB(SColor &color) const inline void SColorHSL::toRGB(SColorf &color) const
{ {
const f32 l = Luminance/100;
if (core::iszero(Saturation)) // grey if (core::iszero(Saturation)) // grey
{ {
u8 c = (u8) ( Luminance * 255.0 ); color.set(l, l, l);
color.setRed(c);
color.setGreen(c);
color.setBlue(c);
return; return;
} }
f32 rm2; f32 rm2;
if ( Luminance <= 0.5f ) if ( Luminance <= 50 )
{ {
rm2 = Luminance + Luminance * Saturation; rm2 = l + l * (Saturation/100);
} }
else else
{ {
rm2 = Luminance + Saturation - Luminance * Saturation; rm2 = l + (1 - l) * (Saturation/100);
} }
const f32 rm1 = 2.0f * Luminance - rm2; const f32 rm1 = 2.0f * l - rm2;
color.setRed ( toRGB1(rm1, rm2, Hue + (120.0f * core::DEGTORAD )) ); const f32 h = Hue / 360.0f;
color.setGreen ( toRGB1(rm1, rm2, Hue) ); color.set( toRGB1(rm1, rm2, h + 1.f/3.f),
color.setBlue ( toRGB1(rm1, rm2, Hue - (120.0f * core::DEGTORAD) ) ); toRGB1(rm1, rm2, h),
toRGB1(rm1, rm2, h - 1.f/3.f)
);
} }
inline u32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const // algorithm from Foley/Van-Dam
inline f32 SColorHSL::toRGB1(f32 rm1, f32 rm2, f32 rh) const
{ {
while ( rh > 2.f * core::PI ) if (rh<0)
rh -= 2.f * core::PI; rh += 1;
if (rh>1)
rh -= 1;
while ( rh < 0.f ) if (rh < 1.f/6.f)
rh += 2.f * core::PI; rm1 = rm1 + (rm2 - rm1) * rh*6.f;
else if (rh < 0.5f)
if (rh < 60.0f * core::DEGTORAD )
rm1 = rm1 + (rm2 - rm1) * rh / (60.0f * core::DEGTORAD);
else if (rh < 180.0f * core::DEGTORAD )
rm1 = rm2; rm1 = rm2;
else if (rh < 240.0f * core::DEGTORAD ) else if (rh < 2.f/3.f)
rm1 = rm1 + (rm2 - rm1) * ( ( 240.0f * core::DEGTORAD ) - rh) / rm1 = rm1 + (rm2 - rm1) * ((2.f/3.f)-rh)*6.f;
(60.0f * core::DEGTORAD);
return (u32) core::round32(rm1 * 255.f); return rm1;
} }
} // end namespace video } // end namespace video
} // end namespace irr } // end namespace irr
#endif #endif

View File

@ -22,19 +22,34 @@ namespace video
//! Flag for EMT_ONETEXTURE_BLEND, ( BlendFactor ) BlendFunc = source * sourceFactor + dest * destFactor //! Flag for EMT_ONETEXTURE_BLEND, ( BlendFactor ) BlendFunc = source * sourceFactor + dest * destFactor
enum E_BLEND_FACTOR enum E_BLEND_FACTOR
{ {
EBF_ZERO = 0, //!< src & dest (0, 0, 0, 0) EBF_ZERO = 0, //!< src & dest (0, 0, 0, 0)
EBF_ONE, //!< src & dest (1, 1, 1, 1) EBF_ONE, //!< src & dest (1, 1, 1, 1)
EBF_DST_COLOR, //!< src (destR, destG, destB, destA) EBF_DST_COLOR, //!< src (destR, destG, destB, destA)
EBF_ONE_MINUS_DST_COLOR, //!< src (1-destR, 1-destG, 1-destB, 1-destA) EBF_ONE_MINUS_DST_COLOR, //!< src (1-destR, 1-destG, 1-destB, 1-destA)
EBF_SRC_COLOR, //!< dest (srcR, srcG, srcB, srcA) EBF_SRC_COLOR, //!< dest (srcR, srcG, srcB, srcA)
EBF_ONE_MINUS_SRC_COLOR, //!< dest (1-srcR, 1-srcG, 1-srcB, 1-srcA) EBF_ONE_MINUS_SRC_COLOR, //!< dest (1-srcR, 1-srcG, 1-srcB, 1-srcA)
EBF_SRC_ALPHA, //!< src & dest (srcA, srcA, srcA, srcA) EBF_SRC_ALPHA, //!< src & dest (srcA, srcA, srcA, srcA)
EBF_ONE_MINUS_SRC_ALPHA, //!< src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA) EBF_ONE_MINUS_SRC_ALPHA, //!< src & dest (1-srcA, 1-srcA, 1-srcA, 1-srcA)
EBF_DST_ALPHA, //!< src & dest (destA, destA, destA, destA) EBF_DST_ALPHA, //!< src & dest (destA, destA, destA, destA)
EBF_ONE_MINUS_DST_ALPHA, //!< src & dest (1-destA, 1-destA, 1-destA, 1-destA) EBF_ONE_MINUS_DST_ALPHA, //!< src & dest (1-destA, 1-destA, 1-destA, 1-destA)
EBF_SRC_ALPHA_SATURATE //!< src (min(srcA, 1-destA), idem, ...) EBF_SRC_ALPHA_SATURATE //!< src (min(srcA, 1-destA), idem, ...)
}; };
//! Values defining the blend operation used when blend is enabled
enum E_BLEND_OPERATION
{
EBO_NONE = 0, //!< No blending happens
EBO_ADD, //!< Default blending adds the color values
EBO_SUBTRACT, //!< This mode subtracts the color values
EBO_REVSUBTRACT,//!< This modes subtracts destination from source
EBO_MIN, //!< Choose minimum value of each color channel
EBO_MAX, //!< Choose maximum value of each color channel
EBO_MIN_FACTOR, //!< Choose minimum value of each color channel after applying blend factors, not widely supported
EBO_MAX_FACTOR, //!< Choose maximum value of each color channel after applying blend factors, not widely supported
EBO_MIN_ALPHA, //!< Choose minimum value of each color channel based on alpha value, not widely supported
EBO_MAX_ALPHA //!< Choose maximum value of each color channel based on alpha value, not widely supported
};
//! MaterialTypeParam: e.g. DirectX: D3DTOP_MODULATE, D3DTOP_MODULATE2X, D3DTOP_MODULATE4X //! MaterialTypeParam: e.g. DirectX: D3DTOP_MODULATE, D3DTOP_MODULATE2X, D3DTOP_MODULATE4X
enum E_MODULATE_FUNC enum E_MODULATE_FUNC
{ {
@ -182,6 +197,19 @@ namespace video
ECM_DIFFUSE_AND_AMBIENT ECM_DIFFUSE_AND_AMBIENT
}; };
//! Flags for the definition of the polygon offset feature
/** These flags define whether the offset should be into the screen, or towards the eye. */
enum E_POLYGON_OFFSET
{
//! Push pixel towards the far plane, away from the eye
/** This is typically used for rendering inner areas. */
EPO_BACK=0,
//! Pull pixels towards the camera.
/** This is typically used for polygons which should appear on top
of other elements, such as decals. */
EPO_FRONT=1
};
//! Maximum number of texture an SMaterial can have. //! Maximum number of texture an SMaterial can have.
const u32 MATERIAL_MAX_TEXTURES = _IRR_MATERIAL_MAX_TEXTURES_; const u32 MATERIAL_MAX_TEXTURES = _IRR_MATERIAL_MAX_TEXTURES_;
@ -195,9 +223,11 @@ namespace video
EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255), EmissiveColor(0,0,0,0), SpecularColor(255,255,255,255),
Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f), Shininess(0.0f), MaterialTypeParam(0.0f), MaterialTypeParam2(0.0f), Thickness(1.0f),
ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL), ZBuffer(ECFN_LESSEQUAL), AntiAliasing(EAAM_SIMPLE), ColorMask(ECP_ALL),
ColorMaterial(ECM_DIFFUSE), ColorMaterial(ECM_DIFFUSE), BlendOperation(EBO_NONE),
Wireframe(false), PointCloud(false), GouraudShading(true), Lighting(true), ZWriteEnable(true), PolygonOffsetFactor(0), PolygonOffsetDirection(EPO_FRONT),
BackfaceCulling(true), FrontfaceCulling(false), FogEnable(false), NormalizeNormals(false), UseMipMaps(true) Wireframe(false), PointCloud(false), GouraudShading(true),
Lighting(true), ZWriteEnable(true), BackfaceCulling(true), FrontfaceCulling(false),
FogEnable(false), NormalizeNormals(false), UseMipMaps(true)
{ } { }
//! Copy constructor //! Copy constructor
@ -246,6 +276,9 @@ namespace video
AntiAliasing = other.AntiAliasing; AntiAliasing = other.AntiAliasing;
ColorMask = other.ColorMask; ColorMask = other.ColorMask;
ColorMaterial = other.ColorMaterial; ColorMaterial = other.ColorMaterial;
BlendOperation = other.BlendOperation;
PolygonOffsetFactor = other.PolygonOffsetFactor;
PolygonOffsetDirection = other.PolygonOffsetDirection;
UseMipMaps = other.UseMipMaps; UseMipMaps = other.UseMipMaps;
return *this; return *this;
@ -344,6 +377,20 @@ namespace video
a very similar rendering as with lighting turned off, just with light shading. */ a very similar rendering as with lighting turned off, just with light shading. */
u8 ColorMaterial:3; u8 ColorMaterial:3;
//! Store the blend operation of choice
/** Values to be chosen from E_BLEND_OPERATION. The actual way to use this value
is not yet determined, so ignore it for now. */
E_BLEND_OPERATION BlendOperation:4;
//! Factor specifying how far the polygon offset should be made
/** Specifying 0 disables the polygon offset. The direction is specified spearately.
The factor can be from 0 to 7.*/
u8 PolygonOffsetFactor:3;
//! Flag defining the direction the polygon offset is applied to.
/** Can be to front or to back, specififed by values from E_POLYGON_OFFSET. */
E_POLYGON_OFFSET PolygonOffsetDirection:1;
//! Draw as wireframe or filled triangles? Default: false //! Draw as wireframe or filled triangles? Default: false
/** The user can access a material flag using /** The user can access a material flag using
\code material.Wireframe=true \endcode \code material.Wireframe=true \endcode
@ -489,16 +536,19 @@ namespace video
} }
break; break;
case EMF_ANTI_ALIASING: case EMF_ANTI_ALIASING:
AntiAliasing = value?EAAM_SIMPLE:EAAM_OFF; AntiAliasing = value?EAAM_SIMPLE:EAAM_OFF; break;
break;
case EMF_COLOR_MASK: case EMF_COLOR_MASK:
ColorMask = value?ECP_ALL:ECP_NONE; ColorMask = value?ECP_ALL:ECP_NONE; break;
break;
case EMF_COLOR_MATERIAL: case EMF_COLOR_MATERIAL:
ColorMaterial = value?ECM_DIFFUSE:ECM_NONE; ColorMaterial = value?ECM_DIFFUSE:ECM_NONE; break;
break;
case EMF_USE_MIP_MAPS: case EMF_USE_MIP_MAPS:
UseMipMaps = value; UseMipMaps = value; break;
case EMF_BLEND_OPERATION:
BlendOperation = value?EBO_ADD:EBO_NONE; break;
case EMF_POLYGON_OFFSET:
PolygonOffsetFactor = value?1:0;
PolygonOffsetDirection = EPO_BACK;
break;
default: default:
break; break;
} }
@ -554,6 +604,10 @@ namespace video
return (ColorMaterial != ECM_NONE); return (ColorMaterial != ECM_NONE);
case EMF_USE_MIP_MAPS: case EMF_USE_MIP_MAPS:
return UseMipMaps; return UseMipMaps;
case EMF_BLEND_OPERATION:
return BlendOperation != EBO_NONE;
case EMF_POLYGON_OFFSET:
return PolygonOffsetFactor != 0;
} }
return false; return false;
@ -587,6 +641,9 @@ namespace video
AntiAliasing != b.AntiAliasing || AntiAliasing != b.AntiAliasing ||
ColorMask != b.ColorMask || ColorMask != b.ColorMask ||
ColorMaterial != b.ColorMaterial || ColorMaterial != b.ColorMaterial ||
BlendOperation != b.BlendOperation ||
PolygonOffsetFactor != b.PolygonOffsetFactor ||
PolygonOffsetDirection != b.PolygonOffsetDirection ||
UseMipMaps != b.UseMipMaps; UseMipMaps != b.UseMipMaps;
for (u32 i=0; (i<MATERIAL_MAX_TEXTURES) && !different; ++i) for (u32 i=0; (i<MATERIAL_MAX_TEXTURES) && !different; ++i)
{ {

View File

@ -2,8 +2,8 @@
// This file is part of the "Irrlicht Engine" and the "irrXML" project. // This file is part of the "Irrlicht Engine" and the "irrXML" project.
// For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h // For conditions of distribution and use, see copyright notice in irrlicht.h and irrXML.h
#ifndef __FAST_A_TO_F_H_INCLUDED__ #ifndef __FAST_ATOF_H_INCLUDED__
#define __FAST_A_TO_F_H_INCLUDED__ #define __FAST_ATOF_H_INCLUDED__
#include "irrMath.h" #include "irrMath.h"
@ -33,66 +33,233 @@ const float fast_atof_table[17] = {
0.0000000000000001f 0.0000000000000001f
}; };
//! Convert a simple string of base 10 digits into a signed 32 bit integer. //! Convert a simple string of base 10 digits into an unsigned 32 bit integer.
//! \param[in] in: The string of digits to convert. Only a leading - or + followed /** \param[in] in: The string of digits to convert. No leading chars are
//! by digits 0 to 9 will be considered. Parsing stops at the allowed, only digits 0 to 9. Parsing stops at the first non-digit.
//! first non-digit. \param[out] out: (optional) If provided, it will be set to point at the
//! \param[out] out: (optional) If provided, it will be set to point at the first first character not used in the calculation.
//! character not used in the calculation. \return The unsigned integer value of the digits. If the string specifies
//! \return The signed integer value of the digits. If the string specifies too many too many digits to encode in an u32 then INT_MAX will be returned.
//! digits to encode in an s32 then +INT_MAX or -INT_MAX will be returned. */
inline s32 strtol10(const char* in, const char** out=0) inline u32 strtoul10(const char* in, const char** out=0)
{ {
if(!in) if (!in)
return 0;
bool negative = false;
if('-' == *in)
{ {
negative = true; if (out)
++in; *out = in;
return 0;
} }
else if('+' == *in)
++in;
bool overflow=false;
u32 unsignedValue = 0; u32 unsignedValue = 0;
while ( ( *in >= '0') && ( *in <= '9' )) while ( ( *in >= '0') && ( *in <= '9' ))
{ {
unsignedValue = ( unsignedValue * 10 ) + ( *in - '0' ); const u32 tmp = ( unsignedValue * 10 ) + ( *in - '0' );
++in; if (tmp<unsignedValue)
if(unsignedValue > (u32)INT_MAX)
{ {
unsignedValue = (u32)INT_MAX; unsignedValue=(u32)0xffffffff;
break; overflow=true;
} }
if (!overflow)
unsignedValue = tmp;
++in;
} }
if (out) if (out)
*out = in; *out = in;
if(negative) return unsignedValue;
return -((s32)unsignedValue); }
//! Convert a simple string of base 10 digits into a signed 32 bit integer.
/** \param[in] in: The string of digits to convert. Only a leading - or +
followed by digits 0 to 9 will be considered. Parsing stops at the first
non-digit.
\param[out] out: (optional) If provided, it will be set to point at the
first character not used in the calculation.
\return The signed integer value of the digits. If the string specifies
too many digits to encode in an s32 then +INT_MAX or -INT_MAX will be
returned.
*/
inline s32 strtol10(const char* in, const char** out=0)
{
if (!in)
{
if (out)
*out = in;
return 0;
}
const bool negative = ('-' == *in);
if (negative || ('+' == *in))
++in;
const u32 unsignedValue = strtoul10(in,out);
if (unsignedValue > (u32)INT_MAX)
{
if (negative)
return (s32)INT_MIN;
else
return (s32)INT_MAX;
}
else else
return (s32)unsignedValue; {
if (negative)
return -((s32)unsignedValue);
else
return (s32)unsignedValue;
}
}
//! Convert a hex-encoded character to an unsigned integer.
/** \param[in] in The digit to convert. Only digits 0 to 9 and chars A-F,a-f
will be considered.
\return The unsigned integer value of the digit. 0xffffffff if the input is
not hex
*/
inline u32 ctoul16(char in)
{
if (in >= '0' && in <= '9')
return in - '0';
else if (in >= 'a' && in <= 'f')
return 10u + in - 'a';
else if (in >= 'A' && in <= 'F')
return 10u + in - 'A';
else
return 0xffffffff;
}
//! Convert a simple string of base 16 digits into an unsigned 32 bit integer.
/** \param[in] in: The string of digits to convert. No leading chars are
allowed, only digits 0 to 9 and chars A-F,a-f are allowed. Parsing stops
at the first illegal char.
\param[out] out: (optional) If provided, it will be set to point at the
first character not used in the calculation.
\return The unsigned integer value of the digits. If the string specifies
too many digits to encode in an u32 then INT_MAX will be returned.
*/
inline u32 strtoul16(const char* in, const char** out=0)
{
if (!in)
{
if (out)
*out = in;
return 0;
}
bool overflow=false;
u32 unsignedValue = 0;
while (true)
{
u32 tmp = 0;
if ((*in >= '0') && (*in <= '9'))
tmp = (unsignedValue << 4u) + (*in - '0');
else if ((*in >= 'A') && (*in <= 'F'))
tmp = (unsignedValue << 4u) + (*in - 'A') + 10;
else if ((*in >= 'a') && (*in <= 'f'))
tmp = (unsignedValue << 4u) + (*in - 'a') + 10;
else
break;
if (tmp<unsignedValue)
{
unsignedValue=(u32)INT_MAX;
overflow=true;
}
if (!overflow)
unsignedValue = tmp;
++in;
}
if (out)
*out = in;
return unsignedValue;
}
//! Convert a simple string of base 8 digits into an unsigned 32 bit integer.
/** \param[in] in The string of digits to convert. No leading chars are
allowed, only digits 0 to 7 are allowed. Parsing stops at the first illegal
char.
\param[out] out (optional) If provided, it will be set to point at the
first character not used in the calculation.
\return The unsigned integer value of the digits. If the string specifies
too many digits to encode in an u32 then INT_MAX will be returned.
*/
inline u32 strtoul8(const char* in, const char** out=0)
{
if (!in)
{
if (out)
*out = in;
return 0;
}
bool overflow=false;
u32 unsignedValue = 0;
while (true)
{
u32 tmp = 0;
if ((*in >= '0') && (*in <= '7'))
tmp = (unsignedValue << 3u) + (*in - '0');
else
break;
if (tmp<unsignedValue)
{
unsignedValue=(u32)INT_MAX;
overflow=true;
}
if (!overflow)
unsignedValue = tmp;
++in;
}
if (out)
*out = in;
return unsignedValue;
}
//! Convert a C-style prefixed string (hex, oct, integer) into an unsigned 32 bit integer.
/** \param[in] in The string of digits to convert. If string starts with 0x the
hex parser is used, if only leading 0 is used, oct parser is used. In all
other cases, the usual unsigned parser is used.
\param[out] out (optional) If provided, it will be set to point at the
first character not used in the calculation.
\return The unsigned integer value of the digits. If the string specifies
too many digits to encode in an u32 then INT_MAX will be returned.
*/
inline u32 strtoul_prefix(const char* in, const char** out=0)
{
if (!in)
{
if (out)
*out = in;
return 0;
}
if ('0'==in[0])
return ('x'==in[1] ? strtoul16(in+2,out) : strtoul8(in+1,out));
return strtoul10(in,out);
} }
//! Converts a sequence of digits into a whole positive floating point value. //! Converts a sequence of digits into a whole positive floating point value.
//! Only digits 0 to 9 are parsed. Parsing stops at any other character, /** Only digits 0 to 9 are parsed. Parsing stops at any other character,
//! including sign characters or a decimal point. including sign characters or a decimal point.
//! \param in: the sequence of digits to convert. \param in: the sequence of digits to convert.
//! \param out: (optional) will be set to point at the first non-converted character. \param out: (optional) will be set to point at the first non-converted
//! \return The whole positive floating point representation of the digit sequence. character.
inline f32 strtof10(const char* in, const char * * out = 0) \return The whole positive floating point representation of the digit
sequence.
*/
inline f32 strtof10(const char* in, const char** out = 0)
{ {
if(out) if (!in)
*out = in; {
if (out)
if(!in) *out = in;
return 0.f; return 0.f;
}
static const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10; const u32 MAX_SAFE_U32_VALUE = UINT_MAX / 10 - 10;
f32 floatValue = 0.f;
u32 intValue = 0; u32 intValue = 0;
// Use integer arithmetic for as long as possible, for speed // Use integer arithmetic for as long as possible, for speed
@ -101,66 +268,59 @@ inline f32 strtof10(const char* in, const char * * out = 0)
{ {
// If it looks like we're going to overflow, bail out // If it looks like we're going to overflow, bail out
// now and start using floating point. // now and start using floating point.
if(intValue >= MAX_SAFE_U32_VALUE) if (intValue >= MAX_SAFE_U32_VALUE)
break; break;
intValue = ( intValue * 10) + ( *in - '0' ); intValue = (intValue * 10) + (*in - '0');
++in; ++in;
} }
floatValue = (f32)intValue; f32 floatValue = (f32)intValue;
// If there are any digits left to parse, then we need to use // If there are any digits left to parse, then we need to use
// floating point arithmetic from here. // floating point arithmetic from here.
while ( ( *in >= '0') && ( *in <= '9' ) ) while ( ( *in >= '0') && ( *in <= '9' ) )
{ {
floatValue = ( floatValue * 10.f ) + (f32)( *in - '0' ); floatValue = (floatValue * 10.f) + (f32)(*in - '0');
++in; ++in;
if(floatValue > FLT_MAX) // Just give up. if (floatValue > FLT_MAX) // Just give up.
break; break;
} }
if(out) if (out)
*out = in; *out = in;
return floatValue; return floatValue;
} }
//! Provides a fast function for converting a string into a float. //! Provides a fast function for converting a string into a float.
//! This is not guaranteed to be as accurate as atof(), but is /** This is not guaranteed to be as accurate as atof(), but is
//! approximately 6 to 8 times as fast. approximately 6 to 8 times as fast.
//! \param[in] in: The string to convert. \param[in] in The string to convert.
//! \param[out] out: The resultant float will be written here. \param[out] result The resultant float will be written here.
//! \return A pointer to the first character in the string that wasn't \return Pointer to the first character in the string that wasn't used
//! use to create the float value. to create the float value.
inline const char* fast_atof_move( const char * in, f32 & out) */
inline const char* fast_atof_move(const char* in, f32& result)
{ {
// Please run this regression test when making any modifications to this function: // Please run this regression test when making any modifications to this function:
// https://sourceforge.net/tracker/download.php?group_id=74339&atid=540676&file_id=298968&aid=1865300 // https://sourceforge.net/tracker/download.php?group_id=74339&atid=540676&file_id=298968&aid=1865300
out = 0.f; result = 0.f;
if(!in) if (!in)
return 0; return 0;
bool negative = false; const bool negative = ('-' == *in);
if(*in == '-') if (negative || ('+'==*in))
{
negative = true;
++in;
}
f32 value = strtof10 ( in, &in );
if (*in == '.')
{
++in; ++in;
const char * afterDecimal = in; f32 value = strtof10(in, &in);
f32 decimal = strtof10 ( in, &afterDecimal );
decimal *= fast_atof_table[afterDecimal - in];
value += decimal;
if ('.' == *in)
{
const char* afterDecimal = ++in;
const f32 decimal = strtof10(in, &afterDecimal);
value += decimal * fast_atof_table[afterDecimal - in];
in = afterDecimal; in = afterDecimal;
} }
@ -169,24 +329,27 @@ inline const char* fast_atof_move( const char * in, f32 & out)
++in; ++in;
// Assume that the exponent is a whole number. // Assume that the exponent is a whole number.
// strtol10() will deal with both + and - signs, // strtol10() will deal with both + and - signs,
// but cast to (f32) to prevent overflow at FLT_MAX // but calculate as f32 to prevent overflow at FLT_MAX
value *= (f32)pow(10.0f, (f32)strtol10(in, &in)); value *= powf(10.f, (f32)strtol10(in, &in));
} }
if(negative) result = negative?-value:value;
out = -value;
else
out = value;
return in; return in;
} }
//! Convert a string to a floating point number //! Convert a string to a floating point number
//! \param floatAsString: The string to convert. /** \param floatAsString The string to convert.
inline float fast_atof(const char* floatAsString) \param out Optional pointer to the first character in the string that
wasn't used to create the float value.
\result Float value parsed from the input string
*/
inline float fast_atof(const char* floatAsString, const char** out=0)
{ {
float ret; float ret;
fast_atof_move(floatAsString, ret); if (out)
*out=fast_atof_move(floatAsString, ret);
else
fast_atof_move(floatAsString, ret);
return ret; return ret;
} }

View File

@ -737,7 +737,7 @@ class map
return Root == 0; return Root == 0;
} }
//! \deprecated Use empty() instead. //! \deprecated Use empty() instead. This method may be removed by Irrlicht 1.9
_IRR_DEPRECATED_ bool isEmpty() const _IRR_DEPRECATED_ bool isEmpty() const
{ {
return empty(); return empty();

View File

@ -129,6 +129,7 @@
#include "path.h" #include "path.h"
#include "irrXML.h" #include "irrXML.h"
#include "ISceneCollisionManager.h" #include "ISceneCollisionManager.h"
#include "ISceneLoader.h"
#include "ISceneManager.h" #include "ISceneManager.h"
#include "ISceneNode.h" #include "ISceneNode.h"
#include "ISceneNodeAnimator.h" #include "ISceneNodeAnimator.h"

View File

@ -120,7 +120,10 @@ class quaternion
//! Inverts this quaternion //! Inverts this quaternion
quaternion& makeInverse(); quaternion& makeInverse();
//! Set this quaternion to the result of the interpolation between two quaternions //! Set this quaternion to the result of the linear interpolation between two quaternions
quaternion& lerp(quaternion q1, quaternion q2, f32 time);
//! Set this quaternion to the result of the spherical interpolation between two quaternions
quaternion& slerp( quaternion q1, quaternion q2, f32 interpolate ); quaternion& slerp( quaternion q1, quaternion q2, f32 interpolate );
//! Create quaternion from rotation angle and rotation axis. //! Create quaternion from rotation angle and rotation axis.
@ -490,43 +493,37 @@ inline quaternion& quaternion::normalize()
} }
// set this quaternion to the result of the linear interpolation between two quaternions
inline quaternion& quaternion::lerp(quaternion q1, quaternion q2, f32 time)
{
const f32 scale = 1.0f - time;
const f32 invscale = time;
return (*this = (q1*scale) + (q2*invscale));
}
// set this quaternion to the result of the interpolation between two quaternions // set this quaternion to the result of the interpolation between two quaternions
inline quaternion& quaternion::slerp(quaternion q1, quaternion q2, f32 time) inline quaternion& quaternion::slerp(quaternion q1, quaternion q2, f32 time)
{ {
f32 angle = q1.dotProduct(q2); f32 angle = q1.dotProduct(q2);
// make sure we use the short rotation
if (angle < 0.0f) if (angle < 0.0f)
{ {
q1 *= -1.0f; q1 *= -1.0f;
angle *= -1.0f; angle *= -1.0f;
} }
f32 scale; if (angle <= 0.95f) // spherical interpolation
f32 invscale;
if ((angle + 1.0f) > 0.05f)
{ {
if ((1.0f - angle) >= 0.05f) // spherical interpolation const f32 theta = acosf(angle);
{ const f32 invsintheta = reciprocal(sinf(theta));
const f32 theta = acosf(angle); const f32 scale = sinf(theta * (1.0f-time)) * invsintheta;
const f32 invsintheta = reciprocal(sinf(theta)); const f32 invscale = sinf(theta * time) * invsintheta;
scale = sinf(theta * (1.0f-time)) * invsintheta; return (*this = (q1*scale) + (q2*invscale));
invscale = sinf(theta * time) * invsintheta;
}
else // linear interploation
{
scale = 1.0f - time;
invscale = time;
}
} }
else else // linear interploation
{ return lerp(q1,q2,time);
q2.set(-q1.Y, q1.X, -q1.W, q1.Z);
scale = sinf(PI * (0.5f - time));
invscale = sinf(PI * time);
}
return (*this = (q1*scale) + (q2*invscale));
} }
@ -578,15 +575,35 @@ inline void quaternion::toEuler(vector3df& euler) const
const f64 sqx = X*X; const f64 sqx = X*X;
const f64 sqy = Y*Y; const f64 sqy = Y*Y;
const f64 sqz = Z*Z; const f64 sqz = Z*Z;
const f64 test = 2.0 * (Y*W - X*Z);
// heading = rotation about z-axis if (core::equals(test, 1.0, 0.000001))
euler.Z = (f32) (atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw))); {
// heading = rotation about z-axis
// bank = rotation about x-axis euler.Z = (f32) (-2.0*atan2(X, W));
euler.X = (f32) (atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw))); // bank = rotation about x-axis
euler.X = 0;
// attitude = rotation about y-axis // attitude = rotation about y-axis
euler.Y = asinf( clamp(-2.0f * (X*Z - Y*W), -1.0f, 1.0f) ); euler.Y = (f32) (core::PI64/2.0);
}
else if (core::equals(test, -1.0, 0.000001))
{
// heading = rotation about z-axis
euler.Z = (f32) (2.0*atan2(X, W));
// bank = rotation about x-axis
euler.X = 0;
// attitude = rotation about y-axis
euler.Y = (f32) (core::PI64/-2.0);
}
else
{
// heading = rotation about z-axis
euler.Z = (f32) atan2(2.0 * (X*Y +Z*W),(sqx - sqy - sqz + sqw));
// bank = rotation about x-axis
euler.X = (f32) atan2(2.0 * (Y*Z +X*W),(-sqx - sqy + sqz + sqw));
// attitude = rotation about y-axis
euler.Y = (f32) asin( clamp(test, -1.0, 1.0) );
}
} }

View File

@ -214,6 +214,8 @@ public:
// don't use getLength here to avoid precision loss with s32 vectors // don't use getLength here to avoid precision loss with s32 vectors
f64 tmp = Y / sqrt((f64)(X*X + Y*Y)); f64 tmp = Y / sqrt((f64)(X*X + Y*Y));
if ( tmp > 1.0 ) // avoid floating-point trouble as sqrt(y*y) is occasionally larger y
tmp = 1.0;
tmp = atan( core::squareroot(1 - tmp*tmp) / tmp) * RADTODEG64; tmp = atan( core::squareroot(1 - tmp*tmp) / tmp) * RADTODEG64;
if (X>0 && Y>0) if (X>0 && Y>0)
@ -244,6 +246,8 @@ public:
tmp = tmp / core::squareroot((f64)((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y))); tmp = tmp / core::squareroot((f64)((X*X + Y*Y) * (b.X*b.X + b.Y*b.Y)));
if (tmp < 0.0) if (tmp < 0.0)
tmp = -tmp; tmp = -tmp;
if ( tmp > 1.0 ) // avoid floating-point trouble
tmp = 1.0;
return atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64; return atan(sqrt(1 - tmp*tmp) / tmp) * RADTODEG64;
} }

View File

@ -14,7 +14,6 @@ The Irrlicht Engine SDK version 1.8
6. Contact 6. Contact
========================================================================== ==========================================================================
1. Directory Structure Overview 1. Directory Structure Overview
========================================================================== ==========================================================================

View File

@ -134,7 +134,6 @@ C3DSMeshFileLoader::C3DSMeshFileLoader(ISceneManager* smgr, io::IFileSystem* fs)
setDebugName("C3DSMeshFileLoader"); setDebugName("C3DSMeshFileLoader");
#endif #endif
TransformationMatrix.makeIdentity();
if (FileSystem) if (FileSystem)
FileSystem->grab(); FileSystem->grab();
} }
@ -237,7 +236,7 @@ bool C3DSMeshFileLoader::readPercentageChunk(io::IReadFile* file,
ChunkData* chunk, f32& percentage) ChunkData* chunk, f32& percentage)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load percentage chunk."); os::Printer::log("Load percentage chunk.", ELL_DEBUG);
#endif #endif
ChunkData data; ChunkData data;
@ -289,7 +288,7 @@ bool C3DSMeshFileLoader::readColorChunk(io::IReadFile* file, ChunkData* chunk,
video::SColor& out) video::SColor& out)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load color chunk."); os::Printer::log("Load color chunk.", ELL_DEBUG);
#endif #endif
ChunkData data; ChunkData data;
readChunkData(file, data); readChunkData(file, data);
@ -340,7 +339,7 @@ bool C3DSMeshFileLoader::readColorChunk(io::IReadFile* file, ChunkData* chunk,
bool C3DSMeshFileLoader::readMaterialChunk(io::IReadFile* file, ChunkData* parent) bool C3DSMeshFileLoader::readMaterialChunk(io::IReadFile* file, ChunkData* parent)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load material chunk."); os::Printer::log("Load material chunk.", ELL_DEBUG);
#endif #endif
u16 matSection=0; u16 matSection=0;
@ -551,7 +550,7 @@ bool C3DSMeshFileLoader::readTrackChunk(io::IReadFile* file, ChunkData& data,
IMeshBuffer* mb, const core::vector3df& pivot) IMeshBuffer* mb, const core::vector3df& pivot)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load track chunk."); os::Printer::log("Load track chunk.", ELL_DEBUG);
#endif #endif
u16 flags; u16 flags;
u32 flags2; u32 flags2;
@ -634,7 +633,7 @@ bool C3DSMeshFileLoader::readTrackChunk(io::IReadFile* file, ChunkData& data,
bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent) bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load frame chunk."); os::Printer::log("Load frame chunk.", ELL_DEBUG);
#endif #endif
ChunkData data; ChunkData data;
@ -645,7 +644,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
else else
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load keyframe header."); os::Printer::log("Load keyframe header.", ELL_DEBUG);
#endif #endif
u16 version; u16 version;
file->read(&version, 2); file->read(&version, 2);
@ -676,7 +675,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_OBJECT_TAG: case C3DS_OBJECT_TAG:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load object tag."); os::Printer::log("Load object tag.", ELL_DEBUG);
#endif #endif
mb=0; mb=0;
pivot.set(0.0f, 0.0f, 0.0f); pivot.set(0.0f, 0.0f, 0.0f);
@ -685,7 +684,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_KF_SEG: case C3DS_KF_SEG:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load keyframe segment."); os::Printer::log("Load keyframe segment.", ELL_DEBUG);
#endif #endif
u32 flags; u32 flags;
file->read(&flags, 4); file->read(&flags, 4);
@ -702,7 +701,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_KF_NODE_HDR: case C3DS_KF_NODE_HDR:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load keyframe node header."); os::Printer::log("Load keyframe node header.", ELL_DEBUG);
#endif #endif
s16 flags; s16 flags;
c8* c = new c8[data.header.length - data.read-6]; c8* c = new c8[data.header.length - data.read-6];
@ -737,7 +736,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_KF_CURTIME: case C3DS_KF_CURTIME:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load keyframe current time."); os::Printer::log("Load keyframe current time.", ELL_DEBUG);
#endif #endif
u32 flags; u32 flags;
file->read(&flags, 4); file->read(&flags, 4);
@ -750,7 +749,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_NODE_ID: case C3DS_NODE_ID:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load node ID."); os::Printer::log("Load node ID.", ELL_DEBUG);
#endif #endif
u16 flags; u16 flags;
file->read(&flags, 2); file->read(&flags, 2);
@ -763,7 +762,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_PIVOTPOINT: case C3DS_PIVOTPOINT:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load pivot point."); os::Printer::log("Load pivot point.", ELL_DEBUG);
#endif #endif
file->read(&pivot.X, sizeof(f32)); file->read(&pivot.X, sizeof(f32));
file->read(&pivot.Y, sizeof(f32)); file->read(&pivot.Y, sizeof(f32));
@ -779,7 +778,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_BOUNDBOX: case C3DS_BOUNDBOX:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load bounding box."); os::Printer::log("Load bounding box.", ELL_DEBUG);
#endif #endif
core::aabbox3df bbox; core::aabbox3df bbox;
// abuse bboxCenter as temporary variable // abuse bboxCenter as temporary variable
@ -808,7 +807,7 @@ bool C3DSMeshFileLoader::readFrameChunk(io::IReadFile* file, ChunkData* parent)
case C3DS_MORPH_SMOOTH: case C3DS_MORPH_SMOOTH:
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load morph smooth."); os::Printer::log("Load morph smooth.", ELL_DEBUG);
#endif #endif
f32 flag; f32 flag;
file->read(&flag, 4); file->read(&flag, 4);
@ -903,7 +902,7 @@ bool C3DSMeshFileLoader::readChunk(io::IReadFile* file, ChunkData* parent)
bool C3DSMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData* parent) bool C3DSMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData* parent)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load object chunk."); os::Printer::log("Load object chunk.", ELL_DEBUG);
#endif #endif
while(parent->read < parent->header.length) while(parent->read < parent->header.length)
{ {
@ -1004,6 +1003,9 @@ bool C3DSMeshFileLoader::readObjectChunk(io::IReadFile* file, ChunkData* parent)
void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& name) void C3DSMeshFileLoader::composeObject(io::IReadFile* file, const core::stringc& name)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Compose object.", ELL_DEBUG);
#endif
if (Mesh->getMeshBufferCount() != Materials.size()) if (Mesh->getMeshBufferCount() != Materials.size())
loadMaterials(file); loadMaterials(file);
@ -1254,7 +1256,7 @@ void C3DSMeshFileLoader::cleanUp()
void C3DSMeshFileLoader::readTextureCoords(io::IReadFile* file, ChunkData& data) void C3DSMeshFileLoader::readTextureCoords(io::IReadFile* file, ChunkData& data)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load texture coords."); os::Printer::log("Load texture coords.", ELL_DEBUG);
#endif #endif
file->read(&CountTCoords, sizeof(CountTCoords)); file->read(&CountTCoords, sizeof(CountTCoords));
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
@ -1282,7 +1284,7 @@ void C3DSMeshFileLoader::readTextureCoords(io::IReadFile* file, ChunkData& data)
void C3DSMeshFileLoader::readMaterialGroup(io::IReadFile* file, ChunkData& data) void C3DSMeshFileLoader::readMaterialGroup(io::IReadFile* file, ChunkData& data)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load material group."); os::Printer::log("Load material group.", ELL_DEBUG);
#endif #endif
SMaterialGroup group; SMaterialGroup group;
@ -1310,7 +1312,7 @@ void C3DSMeshFileLoader::readMaterialGroup(io::IReadFile* file, ChunkData& data)
void C3DSMeshFileLoader::readIndices(io::IReadFile* file, ChunkData& data) void C3DSMeshFileLoader::readIndices(io::IReadFile* file, ChunkData& data)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load indices."); os::Printer::log("Load indices.", ELL_DEBUG);
#endif #endif
file->read(&CountFaces, sizeof(CountFaces)); file->read(&CountFaces, sizeof(CountFaces));
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__
@ -1335,7 +1337,7 @@ void C3DSMeshFileLoader::readIndices(io::IReadFile* file, ChunkData& data)
void C3DSMeshFileLoader::readVertices(io::IReadFile* file, ChunkData& data) void C3DSMeshFileLoader::readVertices(io::IReadFile* file, ChunkData& data)
{ {
#ifdef _IRR_DEBUG_3DS_LOADER_ #ifdef _IRR_DEBUG_3DS_LOADER_
os::Printer::log("Load vertices."); os::Printer::log("Load vertices.", ELL_DEBUG);
#endif #endif
file->read(&CountVertices, sizeof(CountVertices)); file->read(&CountVertices, sizeof(CountVertices));
#ifdef __BIG_ENDIAN__ #ifdef __BIG_ENDIAN__

View File

@ -21,19 +21,19 @@ namespace scene
using namespace video; using namespace video;
void AngleQuaternion( const vec3_hl angles, vec4_hl quaternion ) void AngleQuaternion(const core::vector3df& angles, vec4_hl quaternion)
{ {
f32 angle; f32 angle;
f32 sr, sp, sy, cr, cp, cy; f32 sr, sp, sy, cr, cp, cy;
// FIXME: rescale the inputs to 1/2 angle // FIXME: rescale the inputs to 1/2 angle
angle = angles[2] * 0.5f; angle = angles.Z * 0.5f;
sy = sin(angle); sy = sin(angle);
cy = cos(angle); cy = cos(angle);
angle = angles[1] * 0.5f; angle = angles.Y * 0.5f;
sp = sin(angle); sp = sin(angle);
cp = cos(angle); cp = cos(angle);
angle = angles[0] * 0.5f; angle = angles.X * 0.5f;
sr = sin(angle); sr = sin(angle);
cr = cos(angle); cr = cos(angle);
@ -122,40 +122,17 @@ namespace scene
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3]; out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
} }
#define EQUAL_EPSILON 0.001
s32 VectorCompare (vec3_hl v1, vec3_hl v2)
{
s32 i;
for (i=0 ; i<3 ; i++)
if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON)
return false;
return true;
}
#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2]) #define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
inline void VectorTransform(const vec3_hl in1, const f32 in2[3][4], core::vector3df& out)
inline void VectorTransform (const vec3_hl in1, const f32 in2[3][4], vec3_hl out)
{
out[0] = DotProduct(in1, in2[0]) + in2[0][3];
out[1] = DotProduct(in1, in2[1]) + in2[1][3];
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
}
inline void VectorTransform2 (core::vector3df &out, const vec3_hl in1, const f32 in2[3][4])
{ {
out.X = DotProduct(in1, in2[0]) + in2[0][3]; out.X = DotProduct(in1, in2[0]) + in2[0][3];
out.Z = DotProduct(in1, in2[1]) + in2[1][3]; out.Y = DotProduct(in1, in2[1]) + in2[1][3];
out.Y = DotProduct(in1, in2[2]) + in2[2][3]; out.Z = DotProduct(in1, in2[2]) + in2[2][3];
} }
static f32 BoneTransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix static f32 BoneTransform[MAXSTUDIOBONES][3][4]; // bone transformation matrix
void getBoneVector ( core::vector3df &out, u32 index ) void getBoneVector ( core::vector3df &out, u32 index )
{ {
out.X = BoneTransform[index][0][3]; out.X = BoneTransform[index][0][3];
@ -185,12 +162,12 @@ namespace scene
//! Constructor //! Constructor
CHalflifeMDLMeshFileLoader::CHalflifeMDLMeshFileLoader( scene::ISceneManager* smgr ) CHalflifeMDLMeshFileLoader::CHalflifeMDLMeshFileLoader(
scene::ISceneManager* smgr) : SceneManager(smgr)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CHalflifeMDLMeshFileLoader"); setDebugName("CHalflifeMDLMeshFileLoader");
#endif #endif
SceneManager = smgr;
} }
@ -198,7 +175,7 @@ CHalflifeMDLMeshFileLoader::CHalflifeMDLMeshFileLoader( scene::ISceneManager* sm
//! based on the file extension (e.g. ".bsp") //! based on the file extension (e.g. ".bsp")
bool CHalflifeMDLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const bool CHalflifeMDLMeshFileLoader::isALoadableFileExtension(const io::path& filename) const
{ {
return core::hasFileExtension ( filename, "mdl" ); return core::hasFileExtension(filename, "mdl");
} }
@ -211,55 +188,57 @@ IAnimatedMesh* CHalflifeMDLMeshFileLoader::createMesh(io::IReadFile* file)
CAnimatedMeshHalfLife* msh = new CAnimatedMeshHalfLife(); CAnimatedMeshHalfLife* msh = new CAnimatedMeshHalfLife();
if (msh) if (msh)
{ {
if ( msh->loadModelFile ( file, SceneManager ) ) if (msh->loadModelFile(file, SceneManager))
return msh; return msh;
msh->drop(); msh->drop();
} }
return 0; return 0;
} }
//! Constructor //! Constructor
CAnimatedMeshHalfLife::CAnimatedMeshHalfLife() CAnimatedMeshHalfLife::CAnimatedMeshHalfLife()
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CAnimatedMeshHalfLife"); setDebugName("CAnimatedMeshHalfLife");
#endif #endif
initData();
initData ();
} }
/*! /*!
loads a complete model loads a complete model
*/ */
bool CAnimatedMeshHalfLife::loadModelFile( io::IReadFile* file,ISceneManager * smgr ) bool CAnimatedMeshHalfLife::loadModelFile(io::IReadFile* file,
ISceneManager* smgr)
{ {
if (!file) if (!file)
return false; return false;
bool r = false;
SceneManager = smgr; SceneManager = smgr;
if ( loadModel ( file, file->getFileName() ) ) if ( loadModel(file, file->getFileName()) )
{ {
if ( postLoadModel ( file->getFileName() ) ) if ( postLoadModel ( file->getFileName() ) )
{ {
initModel (); initModel ();
//dumpModelInfo ( 1 ); //dumpModelInfo ( 1 );
r = true; return true;
} }
} }
return r; return false;
} }
//! Destructor //! Destructor
CAnimatedMeshHalfLife::~CAnimatedMeshHalfLife() CAnimatedMeshHalfLife::~CAnimatedMeshHalfLife()
{ {
freeModel (); delete [] (u8*) Header;
if (OwnTexModel)
delete [] (u8*) TextureHeader;
for (u32 i = 0; i < 32; ++i)
delete [] (u8*) AnimationHeader[i];
} }
@ -282,15 +261,13 @@ void CAnimatedMeshHalfLife::setDirty(E_BUFFER_TYPE buffer)
} }
static core::vector3df TransformedVerts[MAXSTUDIOVERTS]; // transformed vertices
//static core::vector3df TransformedNormals[MAXSTUDIOVERTS]; // light surface normals
static vec3_hl TransformedVerts[MAXSTUDIOVERTS]; // transformed vertices
static vec3_hl TransformedNormals[MAXSTUDIOVERTS]; // light surface normals
/*! /*!
*/ */
void CAnimatedMeshHalfLife::initModel () void CAnimatedMeshHalfLife::initModel()
{ {
// init Sequences to Animation // init Sequences to Animation
KeyFrameInterpolation ipol; KeyFrameInterpolation ipol;
@ -337,7 +314,7 @@ void CAnimatedMeshHalfLife::initModel ()
u32 meshBuffer = 0; u32 meshBuffer = 0;
BodyList.clear(); BodyList.clear();
SHalflifeBody *body = (SHalflifeBody *) ((u8*) Header + Header->bodypartindex); SHalflifeBody *body = (SHalflifeBody *) ((u8*) Header + Header->bodypartindex);
for ( i = 0; i < Header->numbodyparts; ++i) for (i=0; i < Header->numbodyparts; ++i)
{ {
BodyPart part; BodyPart part;
part.name = body[i].name; part.name = body[i].name;
@ -360,38 +337,32 @@ void CAnimatedMeshHalfLife::initModel ()
SequenceIndex = 0; SequenceIndex = 0;
CurrentFrame = 0.f; CurrentFrame = 0.f;
SetController (0, 0.f); SetController(0, 0.f);
SetController (1, 0.f); SetController(1, 0.f);
SetController (2, 0.f); SetController(2, 0.f);
SetController (3, 0.f); SetController(3, 0.f);
SetController (MOUTH_CONTROLLER, 0.f); SetController(MOUTH_CONTROLLER, 0.f);
SetSkin (0); SetSkin (0);
// init Meshbuffers // init Meshbuffers
io::path store;
const SHalflifeTexture *tex = (SHalflifeTexture *) ((u8*) TextureHeader + TextureHeader->textureindex); const SHalflifeTexture *tex = (SHalflifeTexture *) ((u8*) TextureHeader + TextureHeader->textureindex);
const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex); const u16 *skinref = (u16 *)((u8*)TextureHeader + TextureHeader->skinindex);
if (SkinGroupSelection != 0 && SkinGroupSelection < TextureHeader->numskinfamilies) if ((SkinGroupSelection != 0) && (SkinGroupSelection < TextureHeader->numskinfamilies))
skinref += (SkinGroupSelection * TextureHeader->numskinref); skinref += (SkinGroupSelection * TextureHeader->numskinref);
io::path fname;
io::path ext;
core::vector2df tex_scale; core::vector2df tex_scale;
core::vector2di tex_trans ( 0, 0 ); core::vector2di tex_trans ( 0, 0 );
#ifdef HL_TEXTURE_ATLAS #ifdef HL_TEXTURE_ATLAS
TextureAtlas.getScale ( tex_scale ); TextureAtlas.getScale(tex_scale);
#endif #endif
for ( u32 bodypart=0 ; bodypart < Header->numbodyparts ; ++bodypart) for (u32 bodypart=0 ; bodypart < Header->numbodyparts ; ++bodypart)
{ {
const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart; const SHalflifeBody *body = (SHalflifeBody *)((u8*) Header + Header->bodypartindex) + bodypart;
for ( u32 modelnr = 0; modelnr < body->nummodels; ++modelnr ) for (u32 modelnr = 0; modelnr < body->nummodels; ++modelnr)
{ {
const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr;
#if 0 #if 0
@ -522,10 +493,12 @@ void CAnimatedMeshHalfLife::initModel ()
} }
#ifdef HL_TEXTURE_ATLAS #ifdef HL_TEXTURE_ATLAS
store = TextureBaseName + "atlas"; io::path store = TextureBaseName + "atlas";
#else #else
io::path fname;
io::path ext;
core::splitFilename ( currentex->name, 0, &fname, &ext ); core::splitFilename ( currentex->name, 0, &fname, &ext );
store = TextureBaseName + fname; io::path store = TextureBaseName + fname;
#endif #endif
m.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture ( store ); m.TextureLayer[0].Texture = SceneManager->getVideoDriver()->getTexture ( store );
m.Lighting = false; m.Lighting = false;
@ -535,7 +508,6 @@ void CAnimatedMeshHalfLife::initModel ()
} // mesh } // mesh
} // model } // model
} // body part } // body part
} }
@ -562,16 +534,16 @@ void CAnimatedMeshHalfLife::buildVertices ()
const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr; const SHalflifeModel *model = (SHalflifeModel *)((u8*) Header + body->modelindex) + modelnr;
const u8 *vertbone = ((u8*)Header + model->vertinfoindex); const u8 *vertbone = ((u8*)Header + model->vertinfoindex);
const u8 *normbone = ((u8*)Header + model->norminfoindex);
const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex); const vec3_hl *studioverts = (vec3_hl *)((u8*)Header + model->vertindex);
const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex);
for ( i = 0; i < model->numverts; i++) for ( i = 0; i < model->numverts; i++)
{ {
VectorTransform ( studioverts[i], BoneTransform[vertbone[i]], TransformedVerts[i] ); VectorTransform ( studioverts[i], BoneTransform[vertbone[i]], TransformedVerts[i] );
} }
/* /*
const u8 *normbone = ((u8*)Header + model->norminfoindex);
const vec3_hl *studionorms = (vec3_hl *)((u8*)Header + model->normindex);
for ( i = 0; i < model->numnorms; i++) for ( i = 0; i < model->numnorms; i++)
{ {
VectorTransform ( studionorms[i], BoneTransform[normbone[i]], TransformedNormals[i] ); VectorTransform ( studionorms[i], BoneTransform[normbone[i]], TransformedNormals[i] );
@ -593,15 +565,11 @@ void CAnimatedMeshHalfLife::buildVertices ()
for ( g = 0; g < c; ++g, v += 1, tricmd += 4 ) for ( g = 0; g < c; ++g, v += 1, tricmd += 4 )
{ {
// fill vertex // fill vertex
const f32 *av = TransformedVerts[tricmd[0]]; const core::vector3df& av = TransformedVerts[tricmd[0]];
v->Pos.X = av[0]; v->Pos = av;
v->Pos.Z = av[1];
v->Pos.Y = av[2];
/* /*
av = TransformedNormals[tricmd[1]]; const core::vector3df& an = TransformedNormals[tricmd[1]];
v->Normal.X = av[0]; v->Normal = an;
v->Normal.Z = av[1];
v->Normal.Y = av[2];
//v->Normal.normalize(); //v->Normal.normalize();
*/ */
} }
@ -612,18 +580,17 @@ void CAnimatedMeshHalfLife::buildVertices ()
} }
/*! /*!
render Bones render Bones
*/ */
void CAnimatedMeshHalfLife::renderModel ( u32 param, IVideoDriver * driver, const core::matrix4 &absoluteTransformation) void CAnimatedMeshHalfLife::renderModel(u32 param, IVideoDriver * driver, const core::matrix4 &absoluteTransformation)
{ {
SHalflifeBone *bone = (SHalflifeBone *) ((u8 *) Header + Header->boneindex); SHalflifeBone *bone = (SHalflifeBone *) ((u8 *) Header + Header->boneindex);
video::SColor blue ( 0xFF000080 ); video::SColor blue(0xFF000080);
video::SColor red ( 0xFF800000 ); video::SColor red(0xFF800000);
video::SColor yellow ( 0xFF808000 ); video::SColor yellow(0xFF808000);
video::SColor cyan ( 0xFF008080 ); video::SColor cyan(0xFF008080);
core::aabbox3df box; core::aabbox3df box;
@ -654,7 +621,7 @@ void CAnimatedMeshHalfLife::renderModel ( u32 param, IVideoDriver * driver, con
} }
// attachements // attachements
SHalfelifeAttachment *attach = (SHalfelifeAttachment *) ((u8*) Header + Header->attachmentindex); SHalflifeAttachment *attach = (SHalflifeAttachment *) ((u8*) Header + Header->attachmentindex);
core::vector3df v[8]; core::vector3df v[8];
for ( i = 0; i < Header->numattachments; i++) for ( i = 0; i < Header->numattachments; i++)
{ {
@ -729,20 +696,19 @@ void CAnimatedMeshHalfLife::renderModel ( u32 param, IVideoDriver * driver, con
} }
} }
//! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. //! Returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail.
IMesh* CAnimatedMeshHalfLife::getMesh(s32 frameInt, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) IMesh* CAnimatedMeshHalfLife::getMesh(s32 frameInt, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
{ {
f32 frame = frameInt + (detailLevel * 0.001f); f32 frame = frameInt + (detailLevel * 0.001f);
u32 frameA = core::floor32 ( frame ); u32 frameA = core::floor32 ( frame );
f32 blend = core::fract ( frame ); // f32 blend = core::fract ( frame );
u32 i;
SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex); SHalflifeSequence *seq = (SHalflifeSequence*) ((u8*) Header + Header->seqindex);
// find SequenceIndex from summed list // find SequenceIndex from summed list
u32 frameCount = 0; u32 frameCount = 0;
for ( i = 0; i < Header->numseq; i++) for (u32 i = 0; i < Header->numseq; ++i)
{ {
u32 val = core::max_ ( 1, seq[i].numframes - 1 ); u32 val = core::max_ ( 1, seq[i].numframes - 1 );
if ( frameCount + val > frameA ) if ( frameCount + val > frameA )
@ -771,6 +737,7 @@ IMesh* CAnimatedMeshHalfLife::getMesh(s32 frameInt, s32 detailLevel, s32 startFr
return &MeshIPol; return &MeshIPol;
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::initData () void CAnimatedMeshHalfLife::initData ()
@ -805,19 +772,6 @@ void CAnimatedMeshHalfLife::initData ()
#endif #endif
} }
/*!
*/
void CAnimatedMeshHalfLife::freeModel ()
{
delete [] (u8*) Header;
if (OwnTexModel )
delete [] (u8*) TextureHeader;
for ( u32 i = 0; i < 32; ++i )
delete [] (u8*) AnimationHeader[i];
}
/*! /*!
*/ */
@ -834,6 +788,7 @@ void STextureAtlas::release ()
Master = 0; Master = 0;
} }
/*! /*!
*/ */
void STextureAtlas::addSource ( const c8 * name, video::IImage * image ) void STextureAtlas::addSource ( const c8 * name, video::IImage * image )
@ -848,6 +803,7 @@ void STextureAtlas::addSource ( const c8 * name, video::IImage * image )
atlas.push_back ( entry ); atlas.push_back ( entry );
} }
/*! /*!
*/ */
void STextureAtlas::getScale(core::vector2df& scale) void STextureAtlas::getScale(core::vector2df& scale)
@ -865,12 +821,11 @@ void STextureAtlas::getScale(core::vector2df& scale)
scale.Y = 1.f; scale.Y = 1.f;
} }
/*! /*!
*/ */
void STextureAtlas::getTranslation ( const c8 * name, core::vector2di &pos ) void STextureAtlas::getTranslation(const c8* name, core::vector2di& pos)
{ {
u32 i = 0;
for ( u32 i = 0; i < atlas.size(); ++i) for ( u32 i = 0; i < atlas.size(); ++i)
{ {
if ( atlas[i].name == name ) if ( atlas[i].name == name )
@ -881,9 +836,10 @@ void STextureAtlas::getTranslation ( const c8 * name, core::vector2di &pos )
} }
} }
/*! /*!
*/ */
void STextureAtlas::create ( u32 border, E_TEXTURE_CLAMP texmode) void STextureAtlas::create(u32 border, E_TEXTURE_CLAMP texmode)
{ {
u32 i = 0; u32 i = 0;
u32 w = 0; u32 w = 0;
@ -955,17 +911,16 @@ void STextureAtlas::create ( u32 border, E_TEXTURE_CLAMP texmode)
// build image // build image
core::dimension2d<u32> dim = core::dimension2d<u32>( wsum, hsum ).getOptimalSize(); core::dimension2d<u32> dim = core::dimension2d<u32>( wsum, hsum ).getOptimalSize();
IImage* master = new CImage( format, dim ); IImage* master = new CImage( format, dim );
master->fill ( 0 ); master->fill(0);
video::SColor col[2]; video::SColor col[2];
static const u8 wrap[][4] = static const u8 wrap[][4] =
{ {
{1, 0 }, // ETC_REPEAT {1, 0}, // ETC_REPEAT
{0, 1 }, // ETC_CLAMP {0, 1}, // ETC_CLAMP
{0, 1 }, // ETC_CLAMP_TO_EDGE {0, 1}, // ETC_CLAMP_TO_EDGE
{0, 1 } // ETC_MIRROR {0, 1} // ETC_MIRROR
}; };
s32 a,b; s32 a,b;
@ -1004,26 +959,28 @@ void STextureAtlas::create ( u32 border, E_TEXTURE_CLAMP texmode)
/*! /*!
*/ */
SHalflifeHeader * CAnimatedMeshHalfLife::loadModel( io::IReadFile* file, const io::path &filename ) SHalflifeHeader* CAnimatedMeshHalfLife::loadModel(io::IReadFile* file, const io::path& filename)
{ {
bool closefile = false; bool closefile = false;
// if secondary files are needed, open here and mark for closing
if ( 0 == file ) if ( 0 == file )
{ {
file = SceneManager->getFileSystem()->createAndOpenFile ( filename ); file = SceneManager->getFileSystem()->createAndOpenFile(filename);
closefile = true; closefile = true;
} }
if ( 0 == file ) if ( 0 == file )
return 0; return 0;
u8 * pin = new u8 [ file->getSize() ]; // read into memory
file->read ( pin, file->getSize() ); u8* pin = new u8[file->getSize()];
file->read(pin, file->getSize());
SHalflifeHeader * header = (SHalflifeHeader*) pin; SHalflifeHeader* header = (SHalflifeHeader*) pin;
const bool idst = 0 == strncmp ( header->id, "IDST", 4); const bool idst = (0 == strncmp(header->id, "IDST", 4));
const bool idsq = 0 == strncmp ( header->id, "IDSQ", 4); const bool idsq = (0 == strncmp(header->id, "IDSQ", 4));
if ( (!idst && !idsq) || (idsq && !Header) ) if ( (!idst && !idsq) || (idsq && !Header) )
{ {
@ -1034,25 +991,22 @@ SHalflifeHeader * CAnimatedMeshHalfLife::loadModel( io::IReadFile* file, const i
file = 0; file = 0;
} }
delete [] pin; delete [] pin;
return false; return 0;
} }
// don't know the real header.. idsg might be different // don't know the real header.. idsg might be different
if (header->textureindex && idst ) if (header->textureindex && idst )
{ {
io::path path;
io::path fname; io::path fname;
io::path ext; io::path ext;
io::path path;
io::path store;
core::splitFilename ( file->getFileName(), &path, &fname, &ext ); core::splitFilename(file->getFileName(), &path, &fname, &ext);
TextureBaseName = path + fname + "_"; TextureBaseName = path + fname + "_";
SHalflifeTexture *tex = (SHalflifeTexture *)(pin + header->textureindex); SHalflifeTexture *tex = (SHalflifeTexture *)(pin + header->textureindex);
u32 i;
u32 *palette = new u32[256]; u32 *palette = new u32[256];
for (i = 0; i < header->numtextures; i++) for (u32 i = 0; i < header->numtextures; ++i)
{ {
const u8 *src = pin + tex[i].index; const u8 *src = pin + tex[i].index;
@ -1066,25 +1020,16 @@ SHalflifeHeader * CAnimatedMeshHalfLife::loadModel( io::IReadFile* file, const i
} }
} }
IImage* image = new CImage( ECF_R8G8B8, core::dimension2d<u32> ( tex[i].width, tex[i].height ) ); IImage* image = new CImage( ECF_R8G8B8, core::dimension2d<u32>(tex[i].width, tex[i].height) );
CColorConverter::convert8BitTo24Bit(src, (u8*)image->lock(), tex[i].width, tex[i].height, (u8*) palette, 0, false); CColorConverter::convert8BitTo24Bit(src, (u8*)image->lock(), tex[i].width, tex[i].height, (u8*) palette, 0, false);
image->unlock(); image->unlock();
#if 0
core::splitFilename ( tex[i].name, 0, &fname, 0 );
io::path store = io::path ( "c:/h2/convert/" ) + fname + ".bmp";
SceneManager->getVideoDriver()->writeImageToFile ( image, store );
#endif
#ifdef HL_TEXTURE_ATLAS #ifdef HL_TEXTURE_ATLAS
TextureAtlas.addSource ( tex[i].name, image ); TextureAtlas.addSource ( tex[i].name, image );
#else #else
core::splitFilename ( tex[i].name, 0, &fname, &ext ); core::splitFilename ( tex[i].name, 0, &fname, &ext );
store = TextureBaseName + fname; SceneManager->getVideoDriver()->addTexture ( TextureBaseName + fname, image );
SceneManager->getVideoDriver()->addTexture ( store, image );
image->drop(); image->drop();
#endif #endif
} }
@ -1092,16 +1037,8 @@ SHalflifeHeader * CAnimatedMeshHalfLife::loadModel( io::IReadFile* file, const i
#ifdef HL_TEXTURE_ATLAS #ifdef HL_TEXTURE_ATLAS
TextureAtlas.create ( 2 * 2 + 1, ETC_CLAMP ); TextureAtlas.create ( 2 * 2 + 1, ETC_CLAMP );
SceneManager->getVideoDriver()->addTexture ( TextureBaseName + "atlas", TextureAtlas.Master );
store = TextureBaseName + "atlas"; TextureAtlas.release();
SceneManager->getVideoDriver()->addTexture ( store, TextureAtlas.Master );
#if 0
core::splitFilename ( store, 0, &fname, 0 );
store = io::path ( "c:/h2/convert/" ) + fname + ".bmp";
SceneManager->getVideoDriver()->writeImageToFile ( TextureAtlas.Master, store );
#endif
TextureAtlas.release ();
#endif #endif
} }
@ -1174,7 +1111,6 @@ f32 CAnimatedMeshHalfLife::SetController( s32 controllerIndex, f32 value )
} }
/*! /*!
*/ */
u32 CAnimatedMeshHalfLife::SetSkin( u32 value ) u32 CAnimatedMeshHalfLife::SetSkin( u32 value )
@ -1185,6 +1121,7 @@ u32 CAnimatedMeshHalfLife::SetSkin( u32 value )
return SkinGroupSelection; return SkinGroupSelection;
} }
/*! /*!
*/ */
bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename ) bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename )
@ -1196,10 +1133,11 @@ bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename )
core::splitFilename ( filename ,&path, &texname, 0 ); core::splitFilename ( filename ,&path, &texname, 0 );
// preload textures // preload textures
// if no textures are stored in main file, use texfile
if (Header->numtextures == 0) if (Header->numtextures == 0)
{ {
submodel = path + texname + "T.mdl"; submodel = path + texname + "T.mdl";
TextureHeader = loadModel( 0, submodel ); TextureHeader = loadModel(0, submodel);
if (!TextureHeader) if (!TextureHeader)
return false; return false;
OwnTexModel = true; OwnTexModel = true;
@ -1210,18 +1148,16 @@ bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename )
OwnTexModel = false; OwnTexModel = false;
} }
u32 i;
// preload animations // preload animations
if (Header->numseqgroups > 1) if (Header->numseqgroups > 1)
{ {
c8 seq[8]; c8 seq[8];
for ( i = 1; i < Header->numseqgroups; i++) for (u32 i = 1; i < Header->numseqgroups; i++)
{ {
snprintf( seq, 8, "%02d.mdl", i ); snprintf( seq, 8, "%02d.mdl", i );
submodel = path + texname + seq; submodel = path + texname + seq;
AnimationHeader[i] = loadModel( 0, submodel ); AnimationHeader[i] = loadModel(0, submodel);
if (!AnimationHeader[i]) if (!AnimationHeader[i])
return false; return false;
} }
@ -1231,7 +1167,6 @@ bool CAnimatedMeshHalfLife::postLoadModel( const io::path &filename )
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::dumpModelInfo ( u32 level ) void CAnimatedMeshHalfLife::dumpModelInfo ( u32 level )
@ -1268,7 +1203,6 @@ void CAnimatedMeshHalfLife::dumpModelInfo ( u32 level )
return; return;
} }
printf("id: %c%c%c%c\n", phdr[0], phdr[1], phdr[2], phdr[3]); printf("id: %c%c%c%c\n", phdr[0], phdr[1], phdr[2], phdr[3]);
printf("version: %d\n", hdr->version); printf("version: %d\n", hdr->version);
printf("name: \"%s\"\n", hdr->name); printf("name: \"%s\"\n", hdr->name);
@ -1351,7 +1285,7 @@ void CAnimatedMeshHalfLife::dumpModelInfo ( u32 level )
printf("\nnumattachments: %d\n", hdr->numattachments); printf("\nnumattachments: %d\n", hdr->numattachments);
for (i = 0; i < hdr->numattachments; i++) for (i = 0; i < hdr->numattachments; i++)
{ {
SHalfelifeAttachment *attach = (SHalfelifeAttachment *) ((u8*) hdr + hdr->attachmentindex); SHalflifeAttachment *attach = (SHalflifeAttachment *) ((u8*) hdr + hdr->attachmentindex);
printf("attachment %d.name: \"%s\"\n", i + 1, attach[i].name); printf("attachment %d.name: \"%s\"\n", i + 1, attach[i].name);
} }
@ -1370,6 +1304,7 @@ void CAnimatedMeshHalfLife::dumpModelInfo ( u32 level )
} }
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::ExtractBbox( s32 sequence, core::aabbox3df &box ) void CAnimatedMeshHalfLife::ExtractBbox( s32 sequence, core::aabbox3df &box )
@ -1386,23 +1321,19 @@ void CAnimatedMeshHalfLife::ExtractBbox( s32 sequence, core::aabbox3df &box )
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::calcBoneAdj() void CAnimatedMeshHalfLife::calcBoneAdj()
{ {
u32 j; SHalflifeBoneController *bonecontroller =
s32 i; (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex);
f32 value;
SHalflifeBoneController *bonecontroller;
bonecontroller = (SHalflifeBoneController *)((u8*) Header + Header->bonecontrollerindex); for (u32 j = 0; j < Header->numbonecontrollers; j++)
for (j = 0; j < Header->numbonecontrollers; j++)
{ {
i = bonecontroller[j].index; s32 i = bonecontroller[j].index;
f32 range = i <= 3 ? 255.f : 64.f; f32 range = i <= 3 ? 255.f : 64.f;
// check for 360% wrapping // check for 360% wrapping
f32 value;
if (bonecontroller[j].type & STUDIO_RLOOP) if (bonecontroller[j].type & STUDIO_RLOOP)
{ {
value = BoneController[i] * (360.f/256.f) + bonecontroller[j].start; value = BoneController[i] * (360.f/256.f) + bonecontroller[j].start;
@ -1431,98 +1362,80 @@ void CAnimatedMeshHalfLife::calcBoneAdj()
} }
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::calcBoneQuaternion( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *q ) const void CAnimatedMeshHalfLife::calcBoneQuaternion(const s32 frame, const SHalflifeBone * const bone,
SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const
{ {
s32 j, k; // three vector components
vec4_hl q1, q2; if (anim->offset[j+3] == 0)
vec3_hl angle1, angle2;
SHalfelifeAnimationFrame *animvalue;
for (j = 0; j < 3; j++)
{ {
if (anim->offset[j+3] == 0) angle2 = angle1 = bone->value[j+3]; // default
{
angle2[j] = angle1[j] = bone->value[j+3]; // default;
}
else
{
animvalue = (SHalfelifeAnimationFrame *)((u8*)anim + anim->offset[j+3]);
k = frame;
while (animvalue->num.total <= k)
{
k -= animvalue->num.total;
animvalue += animvalue->num.valid + 1;
}
// Bah, missing blend!
if (animvalue->num.valid > k)
{
angle1[j] = animvalue[k+1].value;
if (animvalue->num.valid > k + 1)
{
angle2[j] = animvalue[k+2].value;
}
else
{
if (animvalue->num.total > k + 1)
angle2[j] = angle1[j];
else
angle2[j] = animvalue[animvalue->num.valid+2].value;
}
}
else
{
angle1[j] = animvalue[animvalue->num.valid].value;
if (animvalue->num.total > k + 1)
{
angle2[j] = angle1[j];
}
else
{
angle2[j] = animvalue[animvalue->num.valid + 2].value;
}
}
angle1[j] = bone->value[j+3] + angle1[j] * bone->scale[j+3];
angle2[j] = bone->value[j+3] + angle2[j] * bone->scale[j+3];
}
if (bone->bonecontroller[j+3] != -1)
{
angle1[j] += BoneAdj[bone->bonecontroller[j+3]];
angle2[j] += BoneAdj[bone->bonecontroller[j+3]];
}
}
if (!VectorCompare( angle1, angle2 ))
{
AngleQuaternion( angle1, q1 );
AngleQuaternion( angle2, q2 );
QuaternionSlerp( q1, q2, s, q );
} }
else else
{ {
AngleQuaternion( angle1, q ); SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j+3]);
s32 k = frame;
while (animvalue->num.total <= k)
{
k -= animvalue->num.total;
animvalue += animvalue->num.valid + 1;
}
// Bah, missing blend!
if (animvalue->num.valid > k)
{
angle1 = animvalue[k+1].value;
if (animvalue->num.valid > k + 1)
{
angle2 = animvalue[k+2].value;
}
else
{
if (animvalue->num.total > k + 1)
angle2 = angle1;
else
angle2 = animvalue[animvalue->num.valid+2].value;
}
}
else
{
angle1 = animvalue[animvalue->num.valid].value;
if (animvalue->num.total > k + 1)
{
angle2 = angle1;
}
else
{
angle2 = animvalue[animvalue->num.valid + 2].value;
}
}
angle1 = bone->value[j+3] + angle1 * bone->scale[j+3];
angle2 = bone->value[j+3] + angle2 * bone->scale[j+3];
}
if (bone->bonecontroller[j+3] != -1)
{
angle1 += BoneAdj[bone->bonecontroller[j+3]];
angle2 += BoneAdj[bone->bonecontroller[j+3]];
} }
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::calcBonePosition( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *pos ) const void CAnimatedMeshHalfLife::calcBonePosition(const s32 frame, f32 s,
const SHalflifeBone * const bone, SHalflifeAnimOffset *anim, f32 *pos) const
{ {
s32 j, k; for (s32 j = 0; j < 3; ++j)
SHalfelifeAnimationFrame *animvalue;
for (j = 0; j < 3; j++)
{ {
pos[j] = bone->value[j]; // default; pos[j] = bone->value[j]; // default;
if (anim->offset[j] != 0) if (anim->offset[j] != 0)
{ {
animvalue = (SHalfelifeAnimationFrame *)((u8*)anim + anim->offset[j]); SHalflifeAnimationFrame *animvalue = (SHalflifeAnimationFrame *)((u8*)anim + anim->offset[j]);
k = frame; s32 k = frame;
// find span of values that includes the frame we want // find span of values that includes the frame we want
while (animvalue->num.total <= k) while (animvalue->num.total <= k)
{ {
@ -1562,25 +1475,39 @@ void CAnimatedMeshHalfLife::calcBonePosition( s32 frame, f32 s, SHalflifeBone *b
} }
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::calcRotations ( vec3_hl *pos, vec4_hl *q, SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f ) void CAnimatedMeshHalfLife::calcRotations(vec3_hl *pos, vec4_hl *q,
SHalflifeSequence *seq, SHalflifeAnimOffset *anim, f32 f)
{ {
s32 frame; s32 frame = (s32)f;
SHalflifeBone *bone; f32 s = (f - frame);
f32 s;
frame = (s32)f;
s = (f - frame);
// add in programatic controllers // add in programatic controllers
calcBoneAdj( ); calcBoneAdj();
bone = (SHalflifeBone *)((u8 *)Header + Header->boneindex); SHalflifeBone *bone = (SHalflifeBone *)((u8 *)Header + Header->boneindex);
for ( u32 i = 0; i < Header->numbones; i++, bone++, anim++) for ( u32 i = 0; i < Header->numbones; i++, bone++, anim++)
{ {
calcBoneQuaternion( frame, s, bone, anim, q[i] ); core::vector3df angle1, angle2;
calcBonePosition( frame, s, bone, anim, pos[i] ); calcBoneQuaternion(frame, bone, anim, 0, angle1.X, angle2.X);
calcBoneQuaternion(frame, bone, anim, 1, angle1.Y, angle2.Y);
calcBoneQuaternion(frame, bone, anim, 2, angle1.Z, angle2.Z);
if (!angle1.equals(angle2))
{
vec4_hl q1, q2;
AngleQuaternion( angle1, q1 );
AngleQuaternion( angle2, q2 );
QuaternionSlerp( q1, q2, s, q[i] );
}
else
{
AngleQuaternion( angle1, q[i] );
}
calcBonePosition(frame, s, bone, anim, pos[i]);
} }
if (seq->motiontype & STUDIO_X) if (seq->motiontype & STUDIO_X)
@ -1591,12 +1518,12 @@ void CAnimatedMeshHalfLife::calcRotations ( vec3_hl *pos, vec4_hl *q, SHalflifeS
pos[seq->motionbone][2] = 0.f; pos[seq->motionbone][2] = 0.f;
} }
/*! /*!
*/ */
SHalflifeAnimOffset * CAnimatedMeshHalfLife::getAnim( SHalflifeSequence *seq ) SHalflifeAnimOffset * CAnimatedMeshHalfLife::getAnim( SHalflifeSequence *seq )
{ {
SHalflifeSequenceGroup *seqgroup; SHalflifeSequenceGroup *seqgroup = (SHalflifeSequenceGroup *)((u8*)Header + Header->seqgroupindex) + seq->seqgroup;
seqgroup = (SHalflifeSequenceGroup *)((u8*)Header + Header->seqgroupindex) + seq->seqgroup;
if (seq->seqgroup == 0) if (seq->seqgroup == 0)
{ {
@ -1609,18 +1536,18 @@ SHalflifeAnimOffset * CAnimatedMeshHalfLife::getAnim( SHalflifeSequence *seq )
/*! /*!
*/ */
void CAnimatedMeshHalfLife::slerpBones( vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s ) void CAnimatedMeshHalfLife::slerpBones(vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s)
{ {
vec4_hl q3; if (s < 0)
f32 s1; s = 0;
else if (s > 1.f)
s = 1.f;
if (s < 0) s = 0; f32 s1 = 1.f - s;
else if (s > 1.f) s = 1.f;
s1 = 1.f - s;
for ( u32 i = 0; i < Header->numbones; i++) for ( u32 i = 0; i < Header->numbones; i++)
{ {
vec4_hl q3;
QuaternionSlerp( q1[i], q2[i], s, q3 ); QuaternionSlerp( q1[i], q2[i], s, q3 );
q1[i][0] = q3[0]; q1[i][0] = q3[0];
q1[i][1] = q3[1]; q1[i][1] = q3[1];
@ -1632,14 +1559,11 @@ void CAnimatedMeshHalfLife::slerpBones( vec4_hl q1[], vec3_hl pos1[], vec4_hl q2
} }
} }
/*! /*!
*/ */
void CAnimatedMeshHalfLife::setUpBones () void CAnimatedMeshHalfLife::setUpBones()
{ {
SHalflifeBone *bone;
SHalflifeSequence *seq;
SHalflifeAnimOffset *anim;
static vec3_hl pos[MAXSTUDIOBONES]; static vec3_hl pos[MAXSTUDIOBONES];
f32 bonematrix[3][4]; f32 bonematrix[3][4];
static vec4_hl q[MAXSTUDIOBONES]; static vec4_hl q[MAXSTUDIOBONES];
@ -1654,18 +1578,16 @@ void CAnimatedMeshHalfLife::setUpBones ()
if (SequenceIndex >= Header->numseq) if (SequenceIndex >= Header->numseq)
SequenceIndex = 0; SequenceIndex = 0;
seq = (SHalflifeSequence *)((u8*) Header + Header->seqindex) + SequenceIndex; SHalflifeSequence *seq = (SHalflifeSequence *)((u8*) Header + Header->seqindex) + SequenceIndex;
anim = getAnim( seq ); SHalflifeAnimOffset *anim = getAnim(seq);
calcRotations( pos, q, seq, anim, CurrentFrame ); calcRotations(pos, q, seq, anim, CurrentFrame);
if (seq->numblends > 1) if (seq->numblends > 1)
{ {
f32 s;
anim += Header->numbones; anim += Header->numbones;
calcRotations( pos2, q2, seq, anim, CurrentFrame ); calcRotations( pos2, q2, seq, anim, CurrentFrame );
s = Blending[0] / 255.f; f32 s = Blending[0] / 255.f;
slerpBones( q, pos, q2, pos2, s ); slerpBones( q, pos, q2, pos2, s );
@ -1685,7 +1607,7 @@ void CAnimatedMeshHalfLife::setUpBones ()
} }
} }
bone = (SHalflifeBone *)((u8*) Header + Header->boneindex); SHalflifeBone *bone = (SHalflifeBone *)((u8*) Header + Header->boneindex);
for (u32 i = 0; i < Header->numbones; i++) for (u32 i = 0; i < Header->numbones; i++)
{ {
@ -1705,7 +1627,6 @@ void CAnimatedMeshHalfLife::setUpBones ()
} }
//! Returns an axis aligned bounding box //! Returns an axis aligned bounding box
const core::aabbox3d<f32>& CAnimatedMeshHalfLife::getBoundingBox() const const core::aabbox3d<f32>& CAnimatedMeshHalfLife::getBoundingBox() const
{ {
@ -1726,10 +1647,11 @@ u32 CAnimatedMeshHalfLife::getMeshBufferCount() const
return MeshIPol.getMeshBufferCount(); return MeshIPol.getMeshBufferCount();
} }
//! returns pointer to a mesh buffer //! returns pointer to a mesh buffer
IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(u32 nr) const IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(u32 nr) const
{ {
return MeshIPol.getMeshBuffer ( nr ); return MeshIPol.getMeshBuffer(nr);
} }
@ -1737,16 +1659,18 @@ IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(u32 nr) const
/** \param material: material to search for /** \param material: material to search for
\return Returns the pointer to the mesh buffer or \return Returns the pointer to the mesh buffer or
NULL if there is no such mesh buffer. */ NULL if there is no such mesh buffer. */
IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer( const video::SMaterial &material) const IMeshBuffer* CAnimatedMeshHalfLife::getMeshBuffer(const video::SMaterial &material) const
{ {
return MeshIPol.getMeshBuffer ( material ); return MeshIPol.getMeshBuffer(material);
} }
void CAnimatedMeshHalfLife::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) void CAnimatedMeshHalfLife::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
{ {
MeshIPol.setMaterialFlag ( flag, newvalue ); MeshIPol.setMaterialFlag ( flag, newvalue );
} }
//! set user axis aligned bounding box //! set user axis aligned bounding box
void CAnimatedMeshHalfLife::setBoundingBox(const core::aabbox3df& box) void CAnimatedMeshHalfLife::setBoundingBox(const core::aabbox3df& box)
{ {

View File

@ -101,7 +101,7 @@ namespace scene
s32 numtransitions; // animation node to animation node transition graph s32 numtransitions; // animation node to animation node transition graph
s32 transitionindex; s32 transitionindex;
}; } PACK_STRUCT;
// header for demand loaded sequence group data // header for demand loaded sequence group data
typedef struct typedef struct
@ -111,7 +111,7 @@ namespace scene
c8 name[64]; c8 name[64];
s32 length; s32 length;
} studioseqhdr_t; } PACK_STRUCT studioseqhdr_t;
// bones // bones
struct SHalflifeBone struct SHalflifeBone
@ -122,7 +122,7 @@ namespace scene
s32 bonecontroller[6]; // bone controller index, -1 == none s32 bonecontroller[6]; // bone controller index, -1 == none
f32 value[6]; // default DoF values f32 value[6]; // default DoF values
f32 scale[6]; // scale for delta DoF values f32 scale[6]; // scale for delta DoF values
}; } PACK_STRUCT;
// bone controllers // bone controllers
@ -134,7 +134,7 @@ namespace scene
f32 end; f32 end;
s32 rest; // byte index value at rest s32 rest; // byte index value at rest
s32 index; // 0-3 user set controller, 4 mouth s32 index; // 0-3 user set controller, 4 mouth
}; } PACK_STRUCT;
// intersection boxes // intersection boxes
struct SHalflifeBBox struct SHalflifeBBox
@ -143,7 +143,7 @@ namespace scene
s32 group; // intersection group s32 group; // intersection group
vec3_hl bbmin; // bounding box vec3_hl bbmin; // bounding box
vec3_hl bbmax; vec3_hl bbmax;
}; } PACK_STRUCT;
#ifndef ZONE_H #ifndef ZONE_H
typedef void *cache_user_t; typedef void *cache_user_t;
@ -156,7 +156,7 @@ namespace scene
c8 name[64]; // file name c8 name[64]; // file name
cache_user_t cache; // cache index pointer cache_user_t cache; // cache index pointer
s32 data; // hack for group 0 s32 data; // hack for group 0
}; } PACK_STRUCT;
// sequence descriptions // sequence descriptions
struct SHalflifeSequence struct SHalflifeSequence
@ -202,7 +202,7 @@ namespace scene
s32 nodeflags; // transition rules s32 nodeflags; // transition rules
s32 nextseq; // auto advancing sequences s32 nextseq; // auto advancing sequences
}; } PACK_STRUCT;
// events // events
typedef struct typedef struct
@ -211,7 +211,7 @@ namespace scene
s32 event; s32 event;
s32 type; s32 type;
c8 options[64]; c8 options[64];
} mstudioevent_t; } PACK_STRUCT mstudioevent_t;
// pivots // pivots
@ -220,32 +220,32 @@ namespace scene
vec3_hl org; // pivot point vec3_hl org; // pivot point
s32 start; s32 start;
s32 end; s32 end;
} mstudiopivot_t; } PACK_STRUCT mstudiopivot_t;
// attachment // attachment
struct SHalfelifeAttachment struct SHalflifeAttachment
{ {
c8 name[32]; c8 name[32];
s32 type; s32 type;
s32 bone; s32 bone;
vec3_hl org; // attachment point vec3_hl org; // attachment point
vec3_hl vectors[3]; vec3_hl vectors[3];
}; } PACK_STRUCT;
struct SHalflifeAnimOffset struct SHalflifeAnimOffset
{ {
u16 offset[6]; u16 offset[6];
}; } PACK_STRUCT;
// animation frames // animation frames
union SHalfelifeAnimationFrame union SHalflifeAnimationFrame
{ {
struct { struct {
u8 valid; u8 valid;
u8 total; u8 total;
} num; } PACK_STRUCT num;
s16 value; s16 value;
}; } PACK_STRUCT;
// body part index // body part index
@ -255,7 +255,7 @@ namespace scene
u32 nummodels; u32 nummodels;
u32 base; u32 base;
u32 modelindex; // index into models array u32 modelindex; // index into models array
}; } PACK_STRUCT;
// skin info // skin info
@ -266,7 +266,7 @@ namespace scene
s32 width; s32 width;
s32 height; s32 height;
s32 index; s32 index;
}; } PACK_STRUCT;
// skin families // skin families
@ -292,7 +292,7 @@ namespace scene
u32 numgroups; // deformation groups u32 numgroups; // deformation groups
u32 groupindex; u32 groupindex;
}; } PACK_STRUCT;
// meshes // meshes
@ -303,14 +303,14 @@ namespace scene
u32 skinref; u32 skinref;
u32 numnorms; // per mesh normals u32 numnorms; // per mesh normals
u32 normindex; // normal vec3_hl u32 normindex; // normal vec3_hl
} SHalflifeMesh; } PACK_STRUCT SHalflifeMesh;
// lighting options // lighting options
#define STUDIO_NF_FLATSHADE 0x0001 #define STUDIO_NF_FLATSHADE 0x0001
#define STUDIO_NF_CHROME 0x0002 #define STUDIO_NF_CHROME 0x0002
#define STUDIO_NF_FULLBRIGHT 0x0004 #define STUDIO_NF_FULLBRIGHT 0x0004
// motion flags // motion flags
#define STUDIO_X 0x0001 #define STUDIO_X 0x0001
#define STUDIO_Y 0x0002 #define STUDIO_Y 0x0002
#define STUDIO_Z 0x0004 #define STUDIO_Z 0x0004
@ -329,10 +329,10 @@ namespace scene
#define STUDIO_TYPES 0x7FFF #define STUDIO_TYPES 0x7FFF
#define STUDIO_RLOOP 0x8000 // controller that wraps shortest distance #define STUDIO_RLOOP 0x8000 // controller that wraps shortest distance
// sequence flags // sequence flags
#define STUDIO_LOOPING 0x0001 #define STUDIO_LOOPING 0x0001
// bone flags // bone flags
#define STUDIO_HAS_NORMALS 0x0001 #define STUDIO_HAS_NORMALS 0x0001
#define STUDIO_HAS_VERTICES 0x0002 #define STUDIO_HAS_VERTICES 0x0002
#define STUDIO_HAS_BBOX 0x0004 #define STUDIO_HAS_BBOX 0x0004
@ -341,7 +341,7 @@ namespace scene
#define RAD_TO_STUDIO (32768.0/M_PI) #define RAD_TO_STUDIO (32768.0/M_PI)
#define STUDIO_TO_RAD (M_PI/32768.0) #define STUDIO_TO_RAD (M_PI/32768.0)
// Default alignment // Default alignment
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__) #if defined(_MSC_VER) || defined(__BORLANDC__) || defined (__BCPLUSPLUS__)
# pragma pack( pop, packing ) # pragma pack( pop, packing )
#endif #endif
@ -392,12 +392,102 @@ namespace scene
}; };
//! Possible types of Animation Type
enum E_ANIMATION_TYPE
{
//! No Animation
EAMT_STILL,
//! From Start to End, then Stop ( Limited Line )
EAMT_WAYPOINT,
//! Linear Cycling Animation ( Sawtooth )
EAMT_LOOPING,
//! Linear bobbing ( Triangle )
EAMT_PINGPONG
};
//! Names for Animation Type
const c8* const MeshAnimationTypeNames[] =
{
"still",
"waypoint",
"looping",
"pingpong",
0
};
//! Data for holding named Animation Info
struct KeyFrameInterpolation
{
core::stringc Name; // Name of the current Animation/Bone
E_ANIMATION_TYPE AnimationType; // Type of Animation ( looping, usw..)
f32 CurrentFrame; // Current Frame
s32 NextFrame; // Frame which will be used next. For blending
s32 StartFrame; // Absolute Frame where the current animation start
s32 Frames; // Relative Frames how much Frames this animation have
s32 LoopingFrames; // How much of Frames sould be looped
s32 EndFrame; // Absolute Frame where the current animation ends End = start + frames - 1
f32 FramesPerSecond; // Speed in Frames/Seconds the animation is played
f32 RelativeSpeed; // Factor Original fps is modified
u32 BeginTime; // Animation started at this thime
u32 EndTime; // Animation end at this time
u32 LastTime; // Last Keyframe was done at this time
KeyFrameInterpolation ( const c8 * name = "", s32 start = 0, s32 frames = 0, s32 loopingframes = 0,
f32 fps = 0.f, f32 relativefps = 1.f )
: Name ( name ), AnimationType ( loopingframes ? EAMT_LOOPING : EAMT_WAYPOINT),
CurrentFrame ( (f32) start ), NextFrame ( start ), StartFrame ( start ),
Frames ( frames ), LoopingFrames ( loopingframes ), EndFrame ( start + frames - 1 ),
FramesPerSecond ( fps ), RelativeSpeed ( relativefps ),
BeginTime ( 0 ), EndTime ( 0 ), LastTime ( 0 )
{
}
// linear search
bool operator == ( const KeyFrameInterpolation & other ) const
{
return Name.equals_ignore_case ( other.Name );
}
};
//! a List holding named Animations
typedef core::array < KeyFrameInterpolation > IAnimationList;
//! a List holding named Skins
typedef core::array < core::stringc > ISkinList;
// Current Model per Body
struct SubModel
{
core::stringc name;
u32 startBuffer;
u32 endBuffer;
u32 state;
};
struct BodyPart
{
core::stringc name;
u32 defaultModel;
core::array < SubModel > model;
};
//! a List holding named Models and SubModels
typedef core::array < BodyPart > IBodyList;
class CAnimatedMeshHalfLife : public IAnimatedMesh class CAnimatedMeshHalfLife : public IAnimatedMesh
{ {
public: public:
//! constructor //! constructor
CAnimatedMeshHalfLife( ); CAnimatedMeshHalfLife();
//! destructor //! destructor
virtual ~CAnimatedMeshHalfLife(); virtual ~CAnimatedMeshHalfLife();
@ -449,7 +539,6 @@ namespace scene
//! return a Mesh per frame //! return a Mesh per frame
SMesh MeshIPol; SMesh MeshIPol;
ISceneManager *SceneManager; ISceneManager *SceneManager;
SHalflifeHeader *Header; SHalflifeHeader *Header;
@ -458,7 +547,6 @@ namespace scene
SHalflifeHeader *AnimationHeader[32]; // sequences named model01.mdl, model02.mdl SHalflifeHeader *AnimationHeader[32]; // sequences named model01.mdl, model02.mdl
void initData (); void initData ();
void freeModel ();
SHalflifeHeader * loadModel( io::IReadFile* file, const io::path &filename ); SHalflifeHeader * loadModel( io::IReadFile* file, const io::path &filename );
bool postLoadModel( const io::path &filename ); bool postLoadModel( const io::path &filename );
@ -466,13 +554,12 @@ namespace scene
f32 CurrentFrame; // Current Frame f32 CurrentFrame; // Current Frame
#define MOUTH_CONTROLLER 4 #define MOUTH_CONTROLLER 4
u8 BoneController[4 + 1 ]; // bone controllers + mouth position u8 BoneController[4 + 1 ]; // bone controllers + mouth position
u8 Blending[2]; // animation blending u8 Blending[2]; // animation blending
f32 SetController( s32 controllerIndex, f32 value ); f32 SetController( s32 controllerIndex, f32 value );
u32 SkinGroupSelection; // skin group selection
u32 SkinGroupSelection; // skin group selection
u32 SetSkin( u32 value ); u32 SetSkin( u32 value );
void initModel (); void initModel ();
@ -480,7 +567,6 @@ namespace scene
void ExtractBbox( s32 sequence, core::aabbox3df &box ); void ExtractBbox( s32 sequence, core::aabbox3df &box );
void setUpBones (); void setUpBones ();
SHalflifeAnimOffset * getAnim( SHalflifeSequence *seq ); SHalflifeAnimOffset * getAnim( SHalflifeSequence *seq );
void slerpBones( vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s ); void slerpBones( vec4_hl q1[], vec3_hl pos1[], vec4_hl q2[], vec3_hl pos2[], f32 s );
@ -488,8 +574,8 @@ namespace scene
vec4_hl BoneAdj; vec4_hl BoneAdj;
void calcBoneAdj(); void calcBoneAdj();
void calcBoneQuaternion( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *q ) const; void calcBoneQuaternion(const s32 frame, const SHalflifeBone *bone, SHalflifeAnimOffset *anim, const u32 j, f32& angle1, f32& angle2) const;
void calcBonePosition( s32 frame, f32 s, SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *pos ) const; void calcBonePosition(const s32 frame, f32 s, const SHalflifeBone *bone, SHalflifeAnimOffset *anim, f32 *pos ) const;
void buildVertices (); void buildVertices ();
@ -497,7 +583,6 @@ namespace scene
#define HL_TEXTURE_ATLAS #define HL_TEXTURE_ATLAS
#ifdef HL_TEXTURE_ATLAS #ifdef HL_TEXTURE_ATLAS
STextureAtlas TextureAtlas; STextureAtlas TextureAtlas;
video::ITexture *TextureMaster; video::ITexture *TextureMaster;
@ -515,13 +600,14 @@ namespace scene
CHalflifeMDLMeshFileLoader( scene::ISceneManager* smgr ); CHalflifeMDLMeshFileLoader( scene::ISceneManager* smgr );
//! returns true if the file maybe is able to be loaded by this class //! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".bsp") /** based on the file extension (e.g. ".bsp") */
virtual bool isALoadableFileExtension(const io::path& filename) const; virtual bool isALoadableFileExtension(const io::path& filename) const;
//! creates/loads an animated mesh from the file. //! creates/loads an animated mesh from the file.
//! \return Pointer to the created mesh. Returns 0 if loading failed. /** \return Pointer to the created mesh. Returns 0 if loading failed.
//! If you no longer need the mesh, you should call IAnimatedMesh::drop(). If you no longer need the mesh, you should call IAnimatedMesh::drop().
//! See IReferenceCounted::drop() for more information. See IReferenceCounted::drop() for more information.
*/
virtual IAnimatedMesh* createMesh(io::IReadFile* file); virtual IAnimatedMesh* createMesh(io::IReadFile* file);
private: private:

View File

@ -63,7 +63,7 @@ struct SMD3Shader
//! Constructor //! Constructor
CAnimatedMeshMD3::CAnimatedMeshMD3() CAnimatedMeshMD3::CAnimatedMeshMD3()
:Mesh(0), IPolShift(0), LoopMode(0), Scaling(1.f) :Mesh(0), IPolShift(0), LoopMode(0), Scaling(1.f)//, FramesPerSecond(25.f)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CAnimatedMeshMD3"); setDebugName("CAnimatedMeshMD3");
@ -71,7 +71,7 @@ CAnimatedMeshMD3::CAnimatedMeshMD3()
Mesh = new SMD3Mesh(); Mesh = new SMD3Mesh();
setInterpolationShift ( 0, 0 ); setInterpolationShift(0, 0);
} }
@ -119,7 +119,7 @@ SMD3QuaternionTagList *CAnimatedMeshMD3::getTagList(s32 frame, s32 detailLevel,
if ( 0 == Mesh ) if ( 0 == Mesh )
return 0; return 0;
getMesh ( frame, detailLevel, startFrameLoop, endFrameLoop ); getMesh(frame, detailLevel, startFrameLoop, endFrameLoop);
return &TagListIPol; return &TagListIPol;
} }
@ -130,8 +130,6 @@ IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop,
if ( 0 == Mesh ) if ( 0 == Mesh )
return 0; return 0;
u32 i;
//! check if we have the mesh in our private cache //! check if we have the mesh in our private cache
SCacheInfo candidate ( frame, startFrameLoop, endFrameLoop ); SCacheInfo candidate ( frame, startFrameLoop, endFrameLoop );
if ( candidate == Current ) if ( candidate == Current )
@ -173,12 +171,11 @@ IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop,
} }
// build current vertex // build current vertex
for ( i = 0; i!= Mesh->Buffer.size (); ++i ) for (u32 i = 0; i!= Mesh->Buffer.size (); ++i)
{ {
buildVertexArray(frameA, frameB, iPol, buildVertexArray(frameA, frameB, iPol,
Mesh->Buffer[i], Mesh->Buffer[i],
(SMeshBufferLightMap*) MeshIPol.getMeshBuffer(i) (SMeshBufferLightMap*) MeshIPol.getMeshBuffer(i));
);
} }
MeshIPol.recalculateBoundingBox(); MeshIPol.recalculateBoundingBox();
@ -192,7 +189,7 @@ IMesh* CAnimatedMeshMD3::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop,
//! create a Irrlicht MeshBuffer for a MD3 MeshBuffer //! create a Irrlicht MeshBuffer for a MD3 MeshBuffer
IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source, IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source,
io::IFileSystem* fs, video::IVideoDriver * driver) io::IFileSystem* fs, video::IVideoDriver * driver)
{ {
SMeshBufferLightMap * dest = new SMeshBufferLightMap(); SMeshBufferLightMap * dest = new SMeshBufferLightMap();
dest->Vertices.set_used( source->MeshHeader.numVertices ); dest->Vertices.set_used( source->MeshHeader.numVertices );
@ -203,9 +200,9 @@ IMeshBuffer * CAnimatedMeshMD3::createMeshBuffer(const SMD3MeshBuffer* source,
// fill in static face info // fill in static face info
for ( i = 0; i < source->Indices.size(); i += 3 ) for ( i = 0; i < source->Indices.size(); i += 3 )
{ {
dest->Indices[i + 0 ] = (u16) source->Indices[i + 0]; dest->Indices[i + 0] = (u16) source->Indices[i + 0];
dest->Indices[i + 1 ] = (u16) source->Indices[i + 1]; dest->Indices[i + 1] = (u16) source->Indices[i + 1];
dest->Indices[i + 2 ] = (u16) source->Indices[i + 2]; dest->Indices[i + 2] = (u16) source->Indices[i + 2];
} }
// fill in static vertex info // fill in static vertex info
@ -294,7 +291,7 @@ void CAnimatedMeshMD3::buildTagArray ( u32 frameA, u32 frameB, f32 interpolate )
loads a model loads a model
*/ */
bool CAnimatedMeshMD3::loadModelFile( u32 modelIndex, io::IReadFile* file, bool CAnimatedMeshMD3::loadModelFile( u32 modelIndex, io::IReadFile* file,
io::IFileSystem* fs, video::IVideoDriver * driver) io::IFileSystem* fs, video::IVideoDriver * driver)
{ {
if (!file) if (!file)
return false; return false;
@ -448,4 +445,3 @@ E_ANIMATED_MESH_TYPE CAnimatedMeshMD3::getMeshType() const
} // end namespace irr } // end namespace irr
#endif // _IRR_COMPILE_WITH_MD3_LOADER_ #endif // _IRR_COMPILE_WITH_MD3_LOADER_

View File

@ -777,7 +777,15 @@ void CAnimatedMeshSceneNode::serializeAttributes(io::IAttributes* out, io::SAttr
{ {
IAnimatedMeshSceneNode::serializeAttributes(out, options); IAnimatedMeshSceneNode::serializeAttributes(out, options);
out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str()); if (options && (options->Flags&io::EARWF_USE_RELATIVE_PATHS) && options->Filename)
{
const io::path path = SceneManager->getFileSystem()->getRelativeFilename(
SceneManager->getFileSystem()->getAbsolutePath(SceneManager->getMeshCache()->getMeshName(Mesh).getPath()),
options->Filename);
out->addString("Mesh", path.c_str());
}
else
out->addString("Mesh", SceneManager->getMeshCache()->getMeshName(Mesh).getPath().c_str());
out->addBool("Looping", Looping); out->addBool("Looping", Looping);
out->addBool("ReadOnlyMaterials", ReadOnlyMaterials); out->addBool("ReadOnlyMaterials", ReadOnlyMaterials);
out->addFloat("FramesPerSecond", FramesPerSecond); out->addFloat("FramesPerSecond", FramesPerSecond);

View File

@ -88,10 +88,10 @@ namespace scene
//! Gets joint count. //! Gets joint count.
virtual u32 getJointCount() const; virtual u32 getJointCount() const;
//! Redundant command, please use getJointNode. //! Deprecated command, please use getJointNode.
virtual ISceneNode* getMS3DJointNode(const c8* jointName); virtual ISceneNode* getMS3DJointNode(const c8* jointName);
//! Redundant command, please use getJointNode. //! Deprecated command, please use getJointNode.
virtual ISceneNode* getXJointNode(const c8* jointName); virtual ISceneNode* getXJointNode(const c8* jointName);
//! Removes a child from this scene node. //! Removes a child from this scene node.

View File

@ -1797,8 +1797,8 @@ class CTextureAttribute : public IAttribute
{ {
public: public:
CTextureAttribute(const char* name, video::ITexture* value, video::IVideoDriver* driver) CTextureAttribute(const char* name, video::ITexture* value, video::IVideoDriver* driver, const io::path& filename)
: Value(0), Driver(driver) : Value(0), Driver(driver), OverrideName(filename)
{ {
if (Driver) if (Driver)
Driver->grab(); Driver->grab();
@ -1828,13 +1828,15 @@ public:
virtual core::stringw getStringW() virtual core::stringw getStringW()
{ {
return core::stringw(Value ? Value->getName().getPath().c_str() : 0); return core::stringw(OverrideName.size()?OverrideName:
Value ? Value->getName().getPath().c_str() : 0);
} }
virtual core::stringc getString() virtual core::stringc getString()
{ {
// since texture names can be stringw we are careful with the types // since texture names can be stringw we are careful with the types
return core::stringc(Value ? Value->getName().getPath().c_str() : 0); return core::stringc(OverrideName.size()?OverrideName:
Value ? Value->getName().getPath().c_str() : 0);
} }
virtual void setString(const char* text) virtual void setString(const char* text)
@ -1842,7 +1844,10 @@ public:
if (Driver) if (Driver)
{ {
if (text && *text) if (text && *text)
{
setTexture(Driver->getTexture(text)); setTexture(Driver->getTexture(text));
OverrideName=text;
}
else else
setTexture(0); setTexture(0);
} }
@ -1875,6 +1880,7 @@ public:
video::ITexture* Value; video::ITexture* Value;
video::IVideoDriver* Driver; video::IVideoDriver* Driver;
io::path OverrideName;
}; };

View File

@ -509,13 +509,13 @@ void CAttributes::getAttributeEnumerationLiteralsOfEnumeration(const c8* attribu
} }
//! Sets an attribute as texture reference //! Sets an attribute as texture reference
void CAttributes::setAttribute(const c8* attributeName, video::ITexture* value ) void CAttributes::setAttribute(const c8* attributeName, video::ITexture* value, const io::path& filename)
{ {
IAttribute* att = getAttributeP(attributeName); IAttribute* att = getAttributeP(attributeName);
if (att) if (att)
att->setTexture(value); att->setTexture(value, filename);
else else
Attributes.push_back(new CTextureAttribute(attributeName, value, Driver)); Attributes.push_back(new CTextureAttribute(attributeName, value, Driver, filename));
} }
@ -818,9 +818,9 @@ void CAttributes::addBinary(const c8* attributeName, void* data, s32 dataSizeInB
} }
//! Adds an attribute as texture reference //! Adds an attribute as texture reference
void CAttributes::addTexture(const c8* attributeName, video::ITexture* texture) void CAttributes::addTexture(const c8* attributeName, video::ITexture* texture, const io::path& filename)
{ {
Attributes.push_back(new CTextureAttribute(attributeName, texture, Driver)); Attributes.push_back(new CTextureAttribute(attributeName, texture, Driver, filename));
} }
//! Returns if an attribute with a name exists //! Returns if an attribute with a name exists
@ -918,10 +918,10 @@ void CAttributes::setAttribute(s32 index, const char* enumValue, const char* con
//! Sets an attribute as texture reference //! Sets an attribute as texture reference
void CAttributes::setAttribute(s32 index, video::ITexture* texture) void CAttributes::setAttribute(s32 index, video::ITexture* texture, const io::path& filename)
{ {
if ((u32)index < Attributes.size()) if ((u32)index < Attributes.size())
Attributes[index]->setTexture(texture); Attributes[index]->setTexture(texture, filename);
} }

View File

@ -602,10 +602,10 @@ public:
*/ */
//! Adds an attribute as texture reference //! Adds an attribute as texture reference
virtual void addTexture(const c8* attributeName, video::ITexture* texture); virtual void addTexture(const c8* attributeName, video::ITexture* texture, const io::path& filename = "");
//! Sets an attribute as texture reference //! Sets an attribute as texture reference
virtual void setAttribute(const c8* attributeName, video::ITexture* texture ); virtual void setAttribute(const c8* attributeName, video::ITexture* texture, const io::path& filename = "");
//! Gets an attribute as texture reference //! Gets an attribute as texture reference
//! \param attributeName: Name of the attribute to get. //! \param attributeName: Name of the attribute to get.
@ -616,7 +616,7 @@ public:
virtual video::ITexture* getAttributeAsTexture(s32 index); virtual video::ITexture* getAttributeAsTexture(s32 index);
//! Sets an attribute as texture reference //! Sets an attribute as texture reference
virtual void setAttribute(s32 index, video::ITexture* texture); virtual void setAttribute(s32 index, video::ITexture* texture, const io::path& filename = "");

View File

@ -28,8 +28,13 @@ namespace irr
u32 srcPixelMul; u32 srcPixelMul;
u32 dstPixelMul; u32 dstPixelMul;
};
bool stretch;
float x_stretch;
float y_stretch;
SBlitJob() : stretch(false) {}
};
// Bitfields Cohen Sutherland // Bitfields Cohen Sutherland
enum eClipCode enum eClipCode
@ -164,7 +169,7 @@ inline void GetClip(AbsRectangle &clipping, video::IImage * t)
return alpha in [0;256] Granularity from 32-Bit ARGB return alpha in [0;256] Granularity from 32-Bit ARGB
add highbit alpha ( alpha > 127 ? + 1 ) add highbit alpha ( alpha > 127 ? + 1 )
*/ */
static inline u32 extractAlpha ( const u32 c ) static inline u32 extractAlpha(const u32 c)
{ {
return ( c >> 24 ) + ( c >> 31 ); return ( c >> 24 ) + ( c >> 31 );
} }
@ -173,7 +178,7 @@ static inline u32 extractAlpha ( const u32 c )
return alpha in [0;255] Granularity and 32-Bit ARGB return alpha in [0;255] Granularity and 32-Bit ARGB
add highbit alpha ( alpha > 127 ? + 1 ) add highbit alpha ( alpha > 127 ? + 1 )
*/ */
static inline u32 packAlpha ( const u32 c ) static inline u32 packAlpha(const u32 c)
{ {
return (c > 127 ? c - 1 : c) << 24; return (c > 127 ? c - 1 : c) << 24;
} }
@ -183,7 +188,7 @@ static inline u32 packAlpha ( const u32 c )
Scale Color by (1/value) Scale Color by (1/value)
value 0 - 256 ( alpha ) value 0 - 256 ( alpha )
*/ */
inline u32 PixelLerp32 ( const u32 source, const u32 value ) inline u32 PixelLerp32(const u32 source, const u32 value)
{ {
u32 srcRB = source & 0x00FF00FF; u32 srcRB = source & 0x00FF00FF;
u32 srcXG = (source & 0xFF00FF00) >> 8; u32 srcXG = (source & 0xFF00FF00) >> 8;
@ -470,38 +475,87 @@ static void RenderLine16_Blend(video::IImage *t,
*/ */
static void executeBlit_TextureCopy_x_to_x( const SBlitJob * job ) static void executeBlit_TextureCopy_x_to_x( const SBlitJob * job )
{ {
const void *src = (void*) job->src; const u32 w = job->width;
void *dst = (void*) job->dst; const u32 h = job->height;
if (job->stretch)
const u32 widthPitch = job->width * job->dstPixelMul;
for ( s32 dy = 0; dy != job->height; ++dy )
{ {
memcpy( dst, src, widthPitch ); const u32 *src = static_cast<const u32*>(job->src);
u32 *dst = static_cast<u32*>(job->dst);
const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
src = (void*) ( (u8*) (src) + job->srcPitch ); for ( u32 dy = 0; dy < h; ++dy )
dst = (void*) ( (u8*) (dst) + job->dstPitch ); {
const u32 src_y = (u32)(dy*hscale);
src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
for ( u32 dx = 0; dx < w; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
dst[dx] = src[src_x];
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
const u32 widthPitch = job->width * job->dstPixelMul;
const void *src = (void*) job->src;
void *dst = (void*) job->dst;
for ( u32 dy = 0; dy != h; ++dy )
{
memcpy( dst, src, widthPitch );
src = (void*) ( (u8*) (src) + job->srcPitch );
dst = (void*) ( (u8*) (dst) + job->dstPitch );
}
} }
} }
/*! /*!
*/ */
static void executeBlit_TextureCopy_32_to_16( const SBlitJob * job ) static void executeBlit_TextureCopy_32_to_16( const SBlitJob * job )
{ {
const u32 w = job->width;
const u32 h = job->height;
const u32 *src = static_cast<const u32*>(job->src); const u32 *src = static_cast<const u32*>(job->src);
u16 *dst = static_cast<u16*>(job->dst); u16 *dst = static_cast<u16*>(job->dst);
for ( s32 dy = 0; dy != job->height; ++dy ) if (job->stretch)
{ {
for ( s32 dx = 0; dx != job->width; ++dx ) const float wscale = 1.f/job->x_stretch;
{ const float hscale = 1.f/job->y_stretch;
//16 bit Blitter depends on pre-multiplied color
const u32 s = PixelLerp32( src[dx] | 0xFF000000, extractAlpha( src[dx] ) );
dst[dx] = video::A8R8G8B8toA1R5G5B5( s );
}
src = (u32*) ( (u8*) (src) + job->srcPitch ); for ( u32 dy = 0; dy < h; ++dy )
dst = (u16*) ( (u8*) (dst) + job->dstPitch ); {
const u32 src_y = (u32)(dy*hscale);
src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
for ( u32 dx = 0; dx < w; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
//16 bit Blitter depends on pre-multiplied color
const u32 s = PixelLerp32( src[src_x] | 0xFF000000, extractAlpha( src[src_x] ) );
dst[dx] = video::A8R8G8B8toA1R5G5B5( s );
}
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
for ( u32 dy = 0; dy != h; ++dy )
{
for ( u32 dx = 0; dx != w; ++dx )
{
//16 bit Blitter depends on pre-multiplied color
const u32 s = PixelLerp32( src[dx] | 0xFF000000, extractAlpha( src[dx] ) );
dst[dx] = video::A8R8G8B8toA1R5G5B5( s );
}
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
}
} }
} }
@ -509,21 +563,43 @@ static void executeBlit_TextureCopy_32_to_16( const SBlitJob * job )
*/ */
static void executeBlit_TextureCopy_24_to_16( const SBlitJob * job ) static void executeBlit_TextureCopy_24_to_16( const SBlitJob * job )
{ {
const void *src = (void*) job->src; const u32 w = job->width;
u16 *dst = (u16*) job->dst; const u32 h = job->height;
const u8 *src = static_cast<const u8*>(job->src);
u16 *dst = static_cast<u16*>(job->dst);
for ( s32 dy = 0; dy != job->height; ++dy ) if (job->stretch)
{ {
u8 * s = (u8*) src; const float wscale = 3.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
for ( s32 dx = 0; dx != job->width; ++dx ) for ( u32 dy = 0; dy < h; ++dy )
{ {
dst[dx] = video::RGBA16(s[0], s[1], s[2]); const u32 src_y = (u32)(dy*hscale);
s += 3; src = (u8*)(job->src) + job->srcPitch*src_y;
}
src = (void*) ( (u8*) (src) + job->srcPitch ); for ( u32 dx = 0; dx < w; ++dx )
dst = (u16*) ( (u8*) (dst) + job->dstPitch ); {
const u8* src_x = src+(u32)(dx*wscale);
dst[dx] = video::RGBA16(src_x[0], src_x[1], src_x[2]);
}
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
for ( u32 dy = 0; dy != h; ++dy )
{
const u8* s = src;
for ( u32 dx = 0; dx != w; ++dx )
{
dst[dx] = video::RGBA16(s[0], s[1], s[2]);
s += 3;
}
src = src+job->srcPitch;
dst = (u16*) ( (u8*) (dst) + job->dstPitch );
}
} }
} }
@ -532,116 +608,235 @@ static void executeBlit_TextureCopy_24_to_16( const SBlitJob * job )
*/ */
static void executeBlit_TextureCopy_16_to_32( const SBlitJob * job ) static void executeBlit_TextureCopy_16_to_32( const SBlitJob * job )
{ {
const u16 *src = (u16*) job->src; const u32 w = job->width;
u32 *dst = (u32*) job->dst; const u32 h = job->height;
const u16 *src = static_cast<const u16*>(job->src);
u32 *dst = static_cast<u32*>(job->dst);
for ( s32 dy = 0; dy != job->height; ++dy ) if (job->stretch)
{ {
for ( s32 dx = 0; dx != job->width; ++dx ) const float wscale = 1.f/job->x_stretch;
{ const float hscale = 1.f/job->y_stretch;
dst[dx] = video::A1R5G5B5toA8R8G8B8( src[dx] );
}
src = (u16*) ( (u8*) (src) + job->srcPitch ); for ( u32 dy = 0; dy < h; ++dy )
dst = (u32*) ( (u8*) (dst) + job->dstPitch ); {
const u32 src_y = (u32)(dy*hscale);
src = (u16*) ( (u8*) (job->src) + job->srcPitch*src_y );
for ( u32 dx = 0; dx < w; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
dst[dx] = video::A1R5G5B5toA8R8G8B8(src[src_x]);
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
for ( u32 dy = 0; dy != h; ++dy )
{
for ( u32 dx = 0; dx != w; ++dx )
{
dst[dx] = video::A1R5G5B5toA8R8G8B8( src[dx] );
}
src = (u16*) ( (u8*) (src) + job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
} }
} }
static void executeBlit_TextureCopy_16_to_24( const SBlitJob * job ) static void executeBlit_TextureCopy_16_to_24( const SBlitJob * job )
{ {
const u16 *src = (u16*) job->src; const u32 w = job->width;
u8 *dst = (u8*) job->dst; const u32 h = job->height;
const u16 *src = static_cast<const u16*>(job->src);
u8 *dst = static_cast<u8*>(job->dst);
for ( s32 dy = 0; dy != job->height; ++dy ) if (job->stretch)
{ {
for ( s32 dx = 0; dx != job->width; ++dx ) const float wscale = 1.f/job->x_stretch;
{ const float hscale = 1.f/job->y_stretch;
u32 colour = video::A1R5G5B5toA8R8G8B8( src[dx] );
u8 * writeTo = &dst[dx * 3];
*writeTo++ = (colour >> 16)& 0xFF;
*writeTo++ = (colour >> 8) & 0xFF;
*writeTo++ = colour & 0xFF;
}
src = (u16*) ( (u8*) (src) + job->srcPitch ); for ( u32 dy = 0; dy < h; ++dy )
dst += job->dstPitch; {
const u32 src_y = (u32)(dy*hscale);
src = (u16*) ( (u8*) (job->src) + job->srcPitch*src_y );
for ( u32 dx = 0; dx < w; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
u32 color = video::A1R5G5B5toA8R8G8B8(src[src_x]);
u8 * writeTo = &dst[dx * 3];
*writeTo++ = (color >> 16)& 0xFF;
*writeTo++ = (color >> 8) & 0xFF;
*writeTo++ = color & 0xFF;
}
dst += job->dstPitch;
}
}
else
{
for ( u32 dy = 0; dy != h; ++dy )
{
for ( u32 dx = 0; dx != w; ++dx )
{
u32 color = video::A1R5G5B5toA8R8G8B8(src[dx]);
u8 * writeTo = &dst[dx * 3];
*writeTo++ = (color >> 16)& 0xFF;
*writeTo++ = (color >> 8) & 0xFF;
*writeTo++ = color & 0xFF;
}
src = (u16*) ( (u8*) (src) + job->srcPitch );
dst += job->dstPitch;
}
} }
} }
/*! /*!
*/ */
static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job ) static void executeBlit_TextureCopy_24_to_32( const SBlitJob * job )
{ {
void *src = (void*) job->src; const u32 w = job->width;
u32 *dst = (u32*) job->dst; const u32 h = job->height;
const u8 *src = static_cast<const u8*>(job->src);
u32 *dst = static_cast<u32*>(job->dst);
for ( s32 dy = 0; dy != job->height; ++dy ) if (job->stretch)
{ {
u8 * s = (u8*) src; const float wscale = 3.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
for ( s32 dx = 0; dx != job->width; ++dx ) for ( u32 dy = 0; dy < h; ++dy )
{ {
dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2]; const u32 src_y = (u32)(dy*hscale);
s += 3; src = (const u8*)job->src+(job->srcPitch*src_y);
}
src = (void*) ( (u8*) (src) + job->srcPitch ); for ( u32 dx = 0; dx < w; ++dx )
dst = (u32*) ( (u8*) (dst) + job->dstPitch ); {
const u8* s = src+(u32)(dx*wscale);
dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
for ( s32 dy = 0; dy != job->height; ++dy )
{
const u8* s = src;
for ( s32 dx = 0; dx != job->width; ++dx )
{
dst[dx] = 0xFF000000 | s[0] << 16 | s[1] << 8 | s[2];
s += 3;
}
src = src + job->srcPitch;
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
} }
} }
static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job ) static void executeBlit_TextureCopy_32_to_24( const SBlitJob * job )
{ {
const u32 * src = (u32*) job->src; const u32 w = job->width;
u8 * dst = (u8*) job->dst; const u32 h = job->height;
const u32 *src = static_cast<const u32*>(job->src);
u8 *dst = static_cast<u8*>(job->dst);
for ( s32 dy = 0; dy != job->height; ++dy ) if (job->stretch)
{ {
for ( s32 dx = 0; dx != job->width; ++dx ) const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{ {
u8 * writeTo = &dst[dx * 3]; const u32 src_y = (u32)(dy*hscale);
*writeTo++ = (src[dx] >> 16)& 0xFF; src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y);
*writeTo++ = (src[dx] >> 8) & 0xFF;
*writeTo++ = src[dx] & 0xFF; for ( u32 dx = 0; dx < w; ++dx )
{
const u32 src_x = src[(u32)(dx*wscale)];
u8 * writeTo = &dst[dx * 3];
*writeTo++ = (src_x >> 16)& 0xFF;
*writeTo++ = (src_x >> 8) & 0xFF;
*writeTo++ = src_x & 0xFF;
}
dst += job->dstPitch;
} }
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst += job->dstPitch ;
} }
else
{
for ( u32 dy = 0; dy != h; ++dy )
{
for ( u32 dx = 0; dx != w; ++dx )
{
u8 * writeTo = &dst[dx * 3];
*writeTo++ = (src[dx] >> 16)& 0xFF;
*writeTo++ = (src[dx] >> 8) & 0xFF;
*writeTo++ = src[dx] & 0xFF;
}
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst += job->dstPitch;
}
}
} }
/*! /*!
*/ */
static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job ) static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )
{ {
u32 dx; const u32 w = job->width;
s32 dy; const u32 h = job->height;
const u32 rdx = w>>1;
u32 *src = (u32*) job->src; const u32 *src = (u32*) job->src;
u32 *dst = (u32*) job->dst; u32 *dst = (u32*) job->dst;
if (job->stretch)
const u32 rdx = job->width >> 1;
const u32 off = core::if_c_a_else_b( job->width & 1 ,job->width - 1, 0 );
for ( dy = 0; dy != job->height; ++dy )
{ {
for ( dx = 0; dx != rdx; ++dx ) const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
const u32 off = core::if_c_a_else_b(w&1, (u32)((w-1)*wscale), 0);
for ( u32 dy = 0; dy < h; ++dy )
{ {
dst[dx] = PixelBlend16_simd( dst[dx], src[dx] ); const u32 src_y = (u32)(dy*hscale);
} src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
if ( off ) for ( u32 dx = 0; dx < rdx; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
dst[dx] = PixelBlend16_simd( dst[dx], src[src_x] );
}
if ( off )
{
((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
const u32 off = core::if_c_a_else_b(w&1, w-1, 0);
for (u32 dy = 0; dy != h; ++dy )
{ {
((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] ); for (u32 dx = 0; dx != rdx; ++dx )
} {
dst[dx] = PixelBlend16_simd( dst[dx], src[dx] );
}
src = (u32*) ( (u8*) (src) + job->srcPitch ); if ( off )
dst = (u32*) ( (u8*) (dst) + job->dstPitch ); {
((u16*) dst)[off] = PixelBlend16( ((u16*) dst)[off], ((u16*) src)[off] );
}
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
} }
} }
@ -649,17 +844,40 @@ static void executeBlit_TextureBlend_16_to_16( const SBlitJob * job )
*/ */
static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job ) static void executeBlit_TextureBlend_32_to_32( const SBlitJob * job )
{ {
u32 *src = (u32*) job->src; const u32 w = job->width;
const u32 h = job->height;
const u32 *src = (u32*) job->src;
u32 *dst = (u32*) job->dst; u32 *dst = (u32*) job->dst;
for ( s32 dy = 0; dy != job->height; ++dy ) if (job->stretch)
{ {
for ( s32 dx = 0; dx != job->width; ++dx ) const float wscale = 1.f/job->x_stretch;
const float hscale = 1.f/job->y_stretch;
for ( u32 dy = 0; dy < h; ++dy )
{ {
dst[dx] = PixelBlend32( dst[dx], src[dx] ); const u32 src_y = (u32)(dy*hscale);
src = (u32*) ( (u8*) (job->src) + job->srcPitch*src_y );
for ( u32 dx = 0; dx < w; ++dx )
{
const u32 src_x = (u32)(dx*wscale);
dst[dx] = PixelBlend32( dst[dx], src[src_x] );
}
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
}
}
else
{
for ( u32 dy = 0; dy != h; ++dy )
{
for ( u32 dx = 0; dx != w; ++dx )
{
dst[dx] = PixelBlend32( dst[dx], src[dx] );
}
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
} }
src = (u32*) ( (u8*) (src) + job->srcPitch );
dst = (u32*) ( (u8*) (dst) + job->dstPitch );
} }
} }
@ -927,10 +1145,8 @@ static s32 Blit(eBlitter operation,
job.width = job.Dest.x1 - job.Dest.x0; job.width = job.Dest.x1 - job.Dest.x0;
job.height = job.Dest.y1 - job.Dest.y0; job.height = job.Dest.y1 - job.Dest.y0;
job.Source.x0 = sourceClip.x0 + ( job.Dest.x0 - v.x0 ); job.Source.x0 = sourceClip.x0 + ( job.Dest.x0 - v.x0 );
job.Source.x1 = job.Source.x0 + job.width; job.Source.x1 = job.Source.x0 + job.width;
job.Source.y0 = sourceClip.y0 + ( job.Dest.y0 - v.y0 ); job.Source.y0 = sourceClip.y0 + ( job.Dest.y0 - v.y0 );
job.Source.y1 = job.Source.y0 + job.height; job.Source.y1 = job.Source.y0 + job.height;
@ -963,6 +1179,60 @@ static s32 Blit(eBlitter operation,
return 1; return 1;
} }
static s32 StretchBlit(eBlitter operation,
video::IImage* dest, const core::rect<s32> *destRect,
const core::rect<s32> *srcRect, video::IImage* const source,
u32 argb)
{
tExecuteBlit blitter = getBlitter2( operation, dest, source );
if ( 0 == blitter )
{
return 0;
}
SBlitJob job;
// Clipping
setClip ( job.Source, srcRect, source, 1 );
setClip ( job.Dest, destRect, dest, 0 );
job.width = job.Dest.x1-job.Dest.x0;
job.height = job.Dest.y1-job.Dest.y0;
job.argb = argb;
// use original dest size, despite any clipping
job.x_stretch = (float)destRect->getWidth() / (float)(job.Source.x1-job.Source.x0);
job.y_stretch = (float)destRect->getHeight() / (float)(job.Source.y1-job.Source.y0);
job.stretch = (job.x_stretch != 1.f) || (job.y_stretch != 1.f);
if ( source )
{
job.srcPitch = source->getPitch();
job.srcPixelMul = source->getBytesPerPixel();
job.src = (void*) ( (u8*) source->lock() + ( job.Source.y0 * job.srcPitch ) + ( job.Source.x0 * job.srcPixelMul ) );
}
else
{
// use srcPitch for color operation on dest
job.srcPitch = job.width * dest->getBytesPerPixel();
}
job.dstPitch = dest->getPitch();
job.dstPixelMul = dest->getBytesPerPixel();
job.dst = (void*) ( (u8*) dest->lock() + ( job.Dest.y0 * job.dstPitch ) + ( job.Dest.x0 * job.dstPixelMul ) );
blitter( &job );
if ( source )
source->unlock();
if ( dest )
dest->unlock();
return 1;
}
} }
#endif #endif

View File

@ -17,6 +17,7 @@
#include "CD3D8ShaderMaterialRenderer.h" #include "CD3D8ShaderMaterialRenderer.h"
#include "CD3D8NormalMapRenderer.h" #include "CD3D8NormalMapRenderer.h"
#include "CD3D8ParallaxMapRenderer.h" #include "CD3D8ParallaxMapRenderer.h"
#include "SIrrCreationParameters.h"
namespace irr namespace irr
{ {
@ -605,6 +606,8 @@ bool CD3D8Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0; return (Caps.TextureCaps & D3DPTEXTURECAPS_POW2) == 0;
case EVDF_COLOR_MASK: case EVDF_COLOR_MASK:
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0; return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_COLORWRITEENABLE) != 0;
case EVDF_BLEND_OPERATIONS:
return true;
default: default:
return false; return false;
}; };
@ -806,13 +809,21 @@ bool CD3D8Driver::setRenderTarget(video::ITexture* texture,
//! Creates a render target texture. //! Creates a render target texture.
ITexture* CD3D8Driver::addRenderTargetTexture(const core::dimension2d<u32>& size, ITexture* CD3D8Driver::addRenderTargetTexture(
const io::path& name, const core::dimension2d<u32>& size, const io::path& name,
const ECOLOR_FORMAT format) const ECOLOR_FORMAT format)
{ {
ITexture* tex = new CD3D8Texture(this, size, name); CD3D8Texture* tex = new CD3D8Texture(this, size, name);
addTexture(tex); if (tex)
tex->drop(); {
if (!tex->Texture)
{
tex->drop();
return 0;
}
addTexture(tex);
tex->drop();
}
return tex; return tex;
} }
@ -1562,6 +1573,47 @@ void CD3D8Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag);
} }
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
else
{
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
switch (material.BlendOperation)
{
case EBO_MAX:
case EBO_MAX_FACTOR:
case EBO_MAX_ALPHA:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX);
break;
case EBO_MIN:
case EBO_MIN_FACTOR:
case EBO_MIN_ALPHA:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN);
break;
case EBO_SUBTRACT:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
break;
case EBO_REVSUBTRACT:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
break;
default:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
break;
}
}
}
// Polygon offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor))
{
pID3DDevice->SetRenderState(D3DRS_ZBIAS, material.PolygonOffsetFactor);
}
// thickness // thickness
if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness)
{ {
@ -2367,16 +2419,14 @@ namespace video
#ifdef _IRR_COMPILE_WITH_DIRECT3D_8_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_8_
//! creates a video driver //! creates a video driver
IVideoDriver* createDirectX8Driver(const core::dimension2d<u32>& screenSize, IVideoDriver* createDirectX8Driver(const SIrrlichtCreationParameters& params,
HWND window, u32 bits, bool fullscreen, bool stencilbuffer, io::IFileSystem* io, HWND window)
io::IFileSystem* io, bool pureSoftware, bool highPrecisionFPU,
bool vsync, u8 antiAlias, u32 displayAdapter)
{ {
CD3D8Driver* dx8 = new CD3D8Driver(screenSize, window, fullscreen, const bool pureSoftware = false;
stencilbuffer, io, pureSoftware); CD3D8Driver* dx8 = new CD3D8Driver(params.WindowSize, window, params.Fullscreen, params.Stencilbuffer, io, pureSoftware);
if (!dx8->initDriver(screenSize, window, bits, fullscreen, if (!dx8->initDriver(params.WindowSize, window, params.Bits, params.Fullscreen, pureSoftware, params.HighPrecisionFPU,
pureSoftware, highPrecisionFPU, vsync, antiAlias, displayAdapter)) params.Vsync, params.AntiAlias, params.DisplayAdapter))
{ {
dx8->drop(); dx8->drop();
dx8 = 0; dx8 = 0;

View File

@ -251,7 +251,7 @@ void* CD3D8Texture::lock(E_TEXTURE_LOCK_MODE mode, u32 mipmapLevel)
os::Printer::log("Could not lock DIRECT3D8 Texture.", "Data copy failed.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D8 Texture.", "Data copy failed.", ELL_ERROR);
return 0; return 0;
} }
hr = RTTSurface->LockRect(&rect, 0, readOnly?D3DLOCK_READONLY:0); hr = RTTSurface->LockRect(&rect, 0, (mode==ETLM_READ_ONLY)?D3DLOCK_READONLY:0);
if(FAILED(hr)) if(FAILED(hr))
{ {
os::Printer::log("Could not lock DIRECT3D8 Texture.", "LockRect failed.", ELL_ERROR); os::Printer::log("Could not lock DIRECT3D8 Texture.", "LockRect failed.", ELL_ERROR);

View File

@ -16,12 +16,18 @@
#include "CD3D9NormalMapRenderer.h" #include "CD3D9NormalMapRenderer.h"
#include "CD3D9ParallaxMapRenderer.h" #include "CD3D9ParallaxMapRenderer.h"
#include "CD3D9HLSLMaterialRenderer.h" #include "CD3D9HLSLMaterialRenderer.h"
#include "SIrrCreationParameters.h"
namespace irr namespace irr
{ {
namespace video namespace video
{ {
namespace
{
inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
}
//! constructor //! constructor
CD3D9Driver::CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window, CD3D9Driver::CD3D9Driver(const core::dimension2d<u32>& screenSize, HWND window,
bool fullscreen, bool stencilbuffer, bool fullscreen, bool stencilbuffer,
@ -659,6 +665,10 @@ bool CD3D9Driver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0; return (Caps.PrimitiveMiscCaps & D3DPMISCCAPS_MRTPOSTPIXELSHADERBLENDING) != 0;
case EVDF_OCCLUSION_QUERY: case EVDF_OCCLUSION_QUERY:
return OcclusionQuerySupport; return OcclusionQuerySupport;
case EVDF_POLYGON_OFFSET:
return (Caps.RasterCaps & (D3DPRASTERCAPS_DEPTHBIAS|D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS)) != 0;
case EVDF_BLEND_OPERATIONS:
return true;
default: default:
return false; return false;
}; };
@ -1265,12 +1275,12 @@ void CD3D9Driver::drawHardwareBuffer(SHWBufferLink *_HWBuffer)
//! Create occlusion query. //! Create occlusion query.
/** Use node for identification and mesh for occlusion test. */ /** Use node for identification and mesh for occlusion test. */
void CD3D9Driver::createOcclusionQuery(scene::ISceneNode* node, void CD3D9Driver::addOcclusionQuery(scene::ISceneNode* node,
const scene::IMesh* mesh) const scene::IMesh* mesh)
{ {
if (!queryFeature(EVDF_OCCLUSION_QUERY)) if (!queryFeature(EVDF_OCCLUSION_QUERY))
return; return;
CNullDriver::createOcclusionQuery(node, mesh); CNullDriver::addOcclusionQuery(node, mesh);
const s32 index = OcclusionQueries.linear_search(SOccQuery(node)); const s32 index = OcclusionQueries.linear_search(SOccQuery(node));
if ((index != -1) && (OcclusionQueries[index].PID == 0)) if ((index != -1) && (OcclusionQueries[index].PID == 0))
pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[index].PID)); pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[index].PID));
@ -1446,13 +1456,13 @@ void CD3D9Driver::draw2D3DVertexPrimitiveList(const void* vertices,
if (pType==scene::EPT_POINT_SPRITES) if (pType==scene::EPT_POINT_SPRITES)
pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); pID3DDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE); pID3DDevice->SetRenderState(D3DRS_POINTSCALEENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *(DWORD*)(&tmp)); pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(tmp));
tmp=1.0f; tmp=1.0f;
pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, *(DWORD*)(&tmp)); pID3DDevice->SetRenderState(D3DRS_POINTSCALE_A, F2DW(tmp));
pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, *(DWORD*)(&tmp)); pID3DDevice->SetRenderState(D3DRS_POINTSCALE_B, F2DW(tmp));
pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, *(DWORD*)(&tmp)); pID3DDevice->SetRenderState(D3DRS_POINTSIZE_MIN, F2DW(tmp));
tmp=0.0f; tmp=0.0f;
pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, *(DWORD*)(&tmp)); pID3DDevice->SetRenderState(D3DRS_POINTSCALE_C, F2DW(tmp));
if (!vertices) if (!vertices)
{ {
@ -2246,6 +2256,64 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag); pID3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, flag);
} }
if (queryFeature(EVDF_BLEND_OPERATIONS) &&
(resetAllRenderstates|| lastmaterial.BlendOperation != material.BlendOperation))
{
if (EBO_NONE)
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
else
{
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
switch (material.BlendOperation)
{
case EBO_SUBTRACT:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
break;
case EBO_REVSUBTRACT:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_REVSUBTRACT);
break;
case EBO_MIN:
case EBO_MIN_FACTOR:
case EBO_MIN_ALPHA:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MIN);
break;
case EBO_MAX:
case EBO_MAX_FACTOR:
case EBO_MAX_ALPHA:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_MAX);
break;
default:
pID3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
break;
}
}
}
// Polygon offset
if (queryFeature(EVDF_POLYGON_OFFSET) && (resetAllRenderstates ||
lastmaterial.PolygonOffsetDirection != material.PolygonOffsetDirection ||
lastmaterial.PolygonOffsetFactor != material.PolygonOffsetFactor))
{
if (material.PolygonOffsetFactor)
{
if (material.PolygonOffsetDirection==EPO_BACK)
{
pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(1.f));
pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)material.PolygonOffsetFactor));
}
else
{
pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, F2DW(-1.f));
pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, F2DW((FLOAT)-material.PolygonOffsetFactor));
}
}
else
{
pID3DDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0);
pID3DDevice->SetRenderState(D3DRS_DEPTHBIAS, 0);
}
}
// Anti Aliasing // Anti Aliasing
if (resetAllRenderstates || lastmaterial.AntiAliasing != material.AntiAliasing) if (resetAllRenderstates || lastmaterial.AntiAliasing != material.AntiAliasing)
{ {
@ -2282,7 +2350,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
// thickness // thickness
if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness) if (resetAllRenderstates || lastmaterial.Thickness != material.Thickness)
{ {
pID3DDevice->SetRenderState(D3DRS_POINTSIZE, *((DWORD*)&material.Thickness)); pID3DDevice->SetRenderState(D3DRS_POINTSIZE, F2DW(material.Thickness));
} }
// texture address mode // texture address mode
@ -2291,7 +2359,7 @@ void CD3D9Driver::setBasicRenderStates(const SMaterial& material, const SMateria
if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias) if (resetAllRenderstates || lastmaterial.TextureLayer[st].LODBias != material.TextureLayer[st].LODBias)
{ {
const float tmp = material.TextureLayer[st].LODBias * 0.125f; const float tmp = material.TextureLayer[st].LODBias * 0.125f;
pID3DDevice->SetSamplerState(st, D3DSAMP_MIPMAPLODBIAS, *(DWORD*)(&tmp)); pID3DDevice->SetSamplerState(st, D3DSAMP_MIPMAPLODBIAS, F2DW(tmp));
} }
if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU) if (resetAllRenderstates || lastmaterial.TextureLayer[st].TextureWrapU != material.TextureLayer[st].TextureWrapU)
@ -2354,13 +2422,6 @@ void CD3D9Driver::setRenderStatesStencilShadowMode(bool zfail)
setActiveTexture(3,0); setActiveTexture(3,0);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetFVF(D3DFVF_XYZ); pID3DDevice->SetFVF(D3DFVF_XYZ);
LastVertexType = (video::E_VERTEX_TYPE)(-1); LastVertexType = (video::E_VERTEX_TYPE)(-1);
@ -2433,11 +2494,6 @@ void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha)
pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE); pID3DDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1); pID3DDevice->SetRenderState(D3DRS_STENCILREF, 0x1);
pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL); pID3DDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_LESSEQUAL);
@ -2452,23 +2508,19 @@ void CD3D9Driver::setRenderStatesStencilFillMode(bool alpha)
Transformation3DChanged = false; Transformation3DChanged = false;
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
if (alpha) if (alpha)
{ {
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
} }
else else
{ {
pID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
} }
} }
@ -2507,11 +2559,6 @@ void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
// fix everything that is wrongly set by InitMaterial2D default // fix everything that is wrongly set by InitMaterial2D default
pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(3, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetTextureStageState(3, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE ); pID3DDevice->SetRenderState( D3DRS_STENCILENABLE, FALSE );
} }
@ -2582,7 +2629,6 @@ void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
{ {
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
} }
} }
@ -2592,17 +2638,18 @@ void CD3D9Driver::setRenderStates2DMode(bool alpha, bool texture, bool alphaChan
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);
if (alpha) if (alpha)
{ {
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG2);
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE );
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA ); pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
} }
else else
{ {
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
} }
} }
@ -2817,11 +2864,11 @@ void CD3D9Driver::setFog(SColor color, E_FOG_TYPE fogType, f32 start,
if (fogType==EFT_FOG_LINEAR) if (fogType==EFT_FOG_LINEAR)
{ {
pID3DDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD*)(&start)); pID3DDevice->SetRenderState(D3DRS_FOGSTART, F2DW(start));
pID3DDevice->SetRenderState(D3DRS_FOGEND, *(DWORD*)(&end)); pID3DDevice->SetRenderState(D3DRS_FOGEND, F2DW(end));
} }
else else
pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD*)(&density)); pID3DDevice->SetRenderState(D3DRS_FOGDENSITY, F2DW(density));
if(!pixelFog) if(!pixelFog)
pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog); pID3DDevice->SetRenderState(D3DRS_RANGEFOGENABLE, rangeFog);
@ -3109,9 +3156,14 @@ ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d<u32>& size
const io::path& name, const io::path& name,
const ECOLOR_FORMAT format) const ECOLOR_FORMAT format)
{ {
ITexture* tex = new CD3D9Texture(this, size, name, format); CD3D9Texture* tex = new CD3D9Texture(this, size, name, format);
if (tex) if (tex)
{ {
if (!tex->Texture)
{
tex->drop();
return 0;
}
checkDepthBuffer(tex); checkDepthBuffer(tex);
addTexture(tex); addTexture(tex);
tex->drop(); tex->drop();
@ -3447,13 +3499,13 @@ namespace video
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_ #ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
//! creates a video driver //! creates a video driver
IVideoDriver* createDirectX9Driver(const core::dimension2d<u32>& screenSize, IVideoDriver* createDirectX9Driver(const SIrrlichtCreationParameters& params,
HWND window, u32 bits, bool fullscreen, bool stencilbuffer, io::IFileSystem* io, HWND window)
io::IFileSystem* io, bool pureSoftware, bool highPrecisionFPU,
bool vsync, u8 antiAlias, u32 displayAdapter)
{ {
CD3D9Driver* dx9 = new CD3D9Driver(screenSize, window, fullscreen, stencilbuffer, io, pureSoftware); const bool pureSoftware = false;
if (!dx9->initDriver(screenSize, window, bits, fullscreen, pureSoftware, highPrecisionFPU, vsync, antiAlias, displayAdapter)) CD3D9Driver* dx9 = new CD3D9Driver(params.WindowSize, window, params.Fullscreen, params.Stencilbuffer, io, pureSoftware);
if (!dx9->initDriver(params.WindowSize, window, params.Bits, params.Fullscreen, pureSoftware, params.HighPrecisionFPU,
params.Vsync, params.AntiAlias, params.DisplayAdapter))
{ {
dx9->drop(); dx9->drop();
dx9 = 0; dx9 = 0;

View File

@ -121,7 +121,7 @@ namespace video
//! Create occlusion query. //! Create occlusion query.
/** Use node for identification and mesh for occlusion test. */ /** Use node for identification and mesh for occlusion test. */
virtual void createOcclusionQuery(scene::ISceneNode* node, virtual void addOcclusionQuery(scene::ISceneNode* node,
const scene::IMesh* mesh=0); const scene::IMesh* mesh=0);
//! Remove occlusion query. //! Remove occlusion query.

Some files were not shown because too many files have changed in this diff Show More