diff --git a/examples/22.MaterialViewer/main.cpp b/examples/22.MaterialViewer/main.cpp index 12c7a05f..ebee794b 100755 --- a/examples/22.MaterialViewer/main.cpp +++ b/examples/22.MaterialViewer/main.cpp @@ -9,8 +9,7 @@ You can move the camera while left-mouse button is clicked. */ // TODO: Should be possible to set all material values by the GUI. -// For now just change the defaultMaterial in CApp::init for the rest. -// TODO: Allow users to switch between a sphere and a box mesh. +// For now just change the defaultMaterial in CApp::setActiveMeshNodeType for the rest. #include #include "driverChoice.h" @@ -414,14 +413,13 @@ void CTextureControl::updateTextures(video::IVideoDriver * driver) /* Control which allows setting some of the material values for a meshscenenode */ -void CMaterialControl::init(scene::IMeshSceneNode* node, IrrlichtDevice * device, const core::position2d & pos, const wchar_t * description) +void CMaterialControl::init(IrrlichtDevice * device, const core::position2d & pos, const wchar_t * description) { - if ( Initialized || !node || !device) // initializing twice or with invalid data not allowed + if ( Initialized || !device) // initializing twice or with invalid data not allowed return; Driver = device->getVideoDriver (); gui::IGUIEnvironment* guiEnv = device->getGUIEnvironment(); - const video::SMaterial & material = node->getMaterial(0); s32 top = pos.Y; @@ -437,14 +435,13 @@ void CMaterialControl::init(scene::IMeshSceneNode* node, IrrlichtDevice * device { ComboMaterial->addItem( core::stringw(video::sBuiltInMaterialTypeNames[i]).c_str() ); } - ComboMaterial->setSelected( (s32)material.MaterialType ); + ComboMaterial->setSelected(0); // Control to enable/disabling material lighting core::rect rectBtn(core::position2d(pos.X, top), core::dimension2d(100, 15)); top += 15; ButtonLighting = guiEnv->addButton (rectBtn, 0, -1, L"Lighting"); ButtonLighting->setIsPushButton(true); - ButtonLighting->setPressed(material.Lighting); core::rect rectInfo( rectBtn.LowerRightCorner.X, rectBtn.UpperLeftCorner.Y, rectBtn.LowerRightCorner.X+50, rectBtn.UpperLeftCorner.Y+15 ); InfoLighting = guiEnv->addStaticText(L"", rectInfo, true, false ); InfoLighting->setTextAlignment(gui::EGUIA_CENTER, gui::EGUIA_CENTER ); @@ -452,7 +449,6 @@ void CMaterialControl::init(scene::IMeshSceneNode* node, IrrlichtDevice * device // Controls for colors TypicalColorsControl = new CTypicalColorsControl(guiEnv, core::position2d(pos.X, top), true, guiEnv->getRootGUIElement()); top += 300; - TypicalColorsControl->setColorsToMaterialColors(material); // Controls for selecting the material textures guiEnv->addStaticText(L"Textures", core::rect(pos.X, top, pos.X+150, top+15), true, false, 0, -1, true); @@ -469,6 +465,18 @@ void CMaterialControl::init(scene::IMeshSceneNode* node, IrrlichtDevice * device Initialized = true; } +void CMaterialControl::setMaterial(const irr::video::SMaterial & material) +{ + if (ComboMaterial) + ComboMaterial->setSelected( (s32)material.MaterialType ); + if (ButtonLighting) + ButtonLighting->setPressed(material.Lighting); + if (TypicalColorsControl) + TypicalColorsControl->setColorsToMaterialColors(material); + for (irr::u32 i=0; isetDirty(); +} + void CMaterialControl::update(scene::IMeshSceneNode* sceneNode, scene::IMeshSceneNode* sceneNode2T, scene::IMeshSceneNode* sceneNodeTangents) { if ( !Initialized ) @@ -616,6 +624,26 @@ bool CApp::OnEvent(const SEvent &event) } break; + case gui::EGET_COMBO_BOX_CHANGED: + if (event.GUIEvent.Caller == ComboMeshType ) + { + irr::scene::IMeshSceneNode* currentNode = getVisibleMeshNode(); + if (currentNode) + { + // ensure next mesh will get same color and material settings + if ( ControlVertexColors ) + { + video::S3DVertex * vertices = (video::S3DVertex *)currentNode->getMesh()->getMeshBuffer(0)->getVertices(); + ControlVertexColors->setColor(vertices[0].Color); + } + if ( MeshMaterialControl ) + MeshMaterialControl->setMaterial(currentNode->getMaterial(0)); + } + setActiveMeshNodeType((ENodeType)ComboMeshType->getSelected()); + return true; + } + break; + default: break; } @@ -697,44 +725,14 @@ bool CApp::init(int argc, char *argv[]) core::vector3df(0, 10, 0), -1); - // default material - video::SMaterial defaultMaterial; - defaultMaterial.Shininess = 20.f; - - // add the nodes which are used to show the materials -#if 1 - SceneNode = smgr->addCubeSceneNode (30.0f, 0, -1, - core::vector3df(0, 0, 0), - core::vector3df(0.f, 45.f, 0.f), - core::vector3df(1.0f, 1.0f, 1.0f), - scene::ECMT_1BUF_24VTX_NP); - // avoid wrong colored lines at cube-borders (uv's go from 0-1 currently, which does not work well with interpolation) - for ( int i=0; i < irr::video::MATERIAL_MAX_TEXTURES_USED; ++i) - { - defaultMaterial.TextureLayer[i].TextureWrapU = irr::video::ETC_CLAMP_TO_EDGE; - defaultMaterial.TextureLayer[i].TextureWrapV = irr::video::ETC_CLAMP_TO_EDGE; - } -#else - SceneNode = smgr->addSphereSceneNode(30.f); -#endif - SceneNode->getMaterial(0) = defaultMaterial; - // SceneNode->setDebugDataVisible(scene::EDS_NORMALS); // showing normals can sometimes be useful to understand what's going on + setActiveMeshNodeType(ENT_CUBE); const s32 controlsTop = 20; MeshMaterialControl = new CMaterialControl(); - MeshMaterialControl->init( SceneNode, Device, core::position2d(10,controlsTop), L"Material" ); + MeshMaterialControl->init( Device, core::position2d(10,controlsTop), L"Material"); + MeshMaterialControl->setMaterial(SceneNode->getMaterial(0)); MeshMaterialControl->selectTextures(core::stringw("CARO_A8R8G8B8")); // set a useful default texture - // create nodes with other vertex types - scene::IMesh * mesh2T = MeshManipulator->createMeshWith2TCoords(SceneNode->getMesh()); - SceneNode2T = smgr->addMeshSceneNode(mesh2T, 0, -1, SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() ); - mesh2T->drop(); - - scene::IMesh * meshTangents = MeshManipulator->createMeshWithTangents(SceneNode->getMesh(), false, false, false); - SceneNodeTangents = smgr->addMeshSceneNode(meshTangents, 0, -1 - , SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() ); - meshTangents->drop(); - // add one light const f32 lightRadius = 80.f; @@ -758,14 +756,13 @@ bool CApp::init(int argc, char *argv[]) backgroundCube->getMaterial(0).EmissiveColor.set(255,50,50,50); // we keep some self lighting to keep texts visible - // Add a the mesh vertex color control + // Add a the mesh UI controls guiEnv->addStaticText(L"Mesh", core::rect(440, controlsTop, 520, controlsTop+15), true, false, 0, -1, true); - ControlVertexColors = new CColorControl( guiEnv, core::position2d(440, controlsTop+15), L"Vertex colors", guiEnv->getRootGUIElement()); - video::S3DVertex * vertices = (video::S3DVertex *)SceneNode->getMesh()->getMeshBuffer(0)->getVertices(); - if ( vertices ) - { - ControlVertexColors->setColor(vertices[0].Color); - } + ComboMeshType = guiEnv->addComboBox(core::rect(440, controlsTop+16, 520, controlsTop+30), 0, -1); + ComboMeshType->addItem(L"cube"); + ComboMeshType->addItem(L"sphere"); + ControlVertexColors = new CColorControl( guiEnv, core::position2d(440, controlsTop+30), L"Vertex colors", guiEnv->getRootGUIElement()); + ControlVertexColors->setColor(irr::video::SColor(255,255,255,255)); // Add a control for ambient light GlobalAmbient = new CColorControl( guiEnv, core::position2d(550, 300), L"Global ambient", guiEnv->getRootGUIElement()); @@ -1028,6 +1025,68 @@ void CApp::UpdateRotationAxis(irr::scene::ISceneNode* node, irr::core::vector3df } } +void CApp::setActiveMeshNodeType(ENodeType nodeType) +{ + scene::ISceneManager* smgr = Device->getSceneManager(); + + if ( SceneNode ) + smgr->addToDeletionQueue(SceneNode); + SceneNode = nullptr; + if ( SceneNode2T ) + smgr->addToDeletionQueue(SceneNode2T); + SceneNode2T = nullptr; + if ( SceneNodeTangents ) + smgr->addToDeletionQueue(SceneNodeTangents); + SceneNodeTangents = nullptr; + + // default material + video::SMaterial defaultMaterial; + defaultMaterial.Shininess = 20.f; + + // add the nodes which are used to show the materials + if ( nodeType == ENT_CUBE) + { + SceneNode = smgr->addCubeSceneNode (30.0f, 0, -1, + core::vector3df(0, 0, 0), + core::vector3df(0.f, 45.f, 0.f), + core::vector3df(1.0f, 1.0f, 1.0f), + scene::ECMT_1BUF_24VTX_NP); + // avoid wrong colored lines at cube-borders (uv's go from 0-1 currently, which does not work well with interpolation) + for ( u32 i=0; i < irr::video::MATERIAL_MAX_TEXTURES_USED; ++i) + { + defaultMaterial.TextureLayer[i].TextureWrapU = irr::video::ETC_CLAMP_TO_EDGE; + defaultMaterial.TextureLayer[i].TextureWrapV = irr::video::ETC_CLAMP_TO_EDGE; + } + } + else + { + SceneNode = smgr->addSphereSceneNode(30.f); + } + SceneNode->getMaterial(0) = defaultMaterial; + // SceneNode->setDebugDataVisible(scene::EDS_NORMALS); // showing normals can sometimes be useful to understand what's going on + + // create nodes with other vertex types + scene::IMesh * mesh2T = MeshManipulator->createMeshWith2TCoords(SceneNode->getMesh()); + SceneNode2T = smgr->addMeshSceneNode(mesh2T, 0, -1, SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() ); + mesh2T->drop(); + + scene::IMesh * meshTangents = MeshManipulator->createMeshWithTangents(SceneNode->getMesh(), false, false, false); + SceneNodeTangents = smgr->addMeshSceneNode(meshTangents, 0, -1 + , SceneNode->getPosition(), SceneNode->getRotation(), SceneNode->getScale() ); + meshTangents->drop(); +} + +irr::scene::IMeshSceneNode* CApp::getVisibleMeshNode() const +{ + if ( SceneNode && SceneNode->isVisible() ) + return SceneNode; + if ( SceneNode2T && SceneNode2T->isVisible() ) + return SceneNode2T; + if ( SceneNodeTangents && SceneNodeTangents->isVisible() ) + return SceneNodeTangents; + return nullptr; +} + /* Short main as most is done in classes. */ diff --git a/examples/22.MaterialViewer/main.h b/examples/22.MaterialViewer/main.h index d9f83254..dc121cd8 100644 --- a/examples/22.MaterialViewer/main.h +++ b/examples/22.MaterialViewer/main.h @@ -110,6 +110,12 @@ public: // Change active selectionbased on the texture name void selectTextureByName(const irr::core::stringw& name); + // Set dirty flag (node will update texture) + void setDirty() + { + DirtyFlag = true; + } + // Reset the dirty flag void resetDirty() { @@ -154,7 +160,9 @@ public: TypicalColorsControl->drop(); } - void init(irr::scene::IMeshSceneNode* node, irr::IrrlichtDevice * device, const irr::core::position2d & pos, const wchar_t * description); + void init(irr::IrrlichtDevice * device, const irr::core::position2d & pos, const wchar_t * description); + + void setMaterial(const irr::video::SMaterial & material); void update(irr::scene::IMeshSceneNode* sceneNode, irr::scene::IMeshSceneNode* sceneNode2T, irr::scene::IMeshSceneNode* sceneNodeTangents); @@ -239,6 +247,7 @@ public: , LightRotationAxis(irr::core::vector3df(1,0,0)) , MeshMaterialControl(0) , LightControl(0) + , ComboMeshType(0) , ControlVertexColors(0) , GlobalAmbient(0) , MousePressed(false) @@ -290,6 +299,14 @@ protected: void ZoomOut(irr::scene::ISceneNode* node, irr::f32 units); void UpdateRotationAxis(irr::scene::ISceneNode* node, irr::core::vector3df& axis); + enum ENodeType + { + ENT_CUBE, + ENT_SPHERE + }; + void setActiveMeshNodeType(ENodeType nodeType); + + irr::scene::IMeshSceneNode* getVisibleMeshNode() const; private: SConfig Config; @@ -306,6 +323,7 @@ private: irr::core::vector3df LightRotationAxis; CMaterialControl* MeshMaterialControl; CLightNodeControl* LightControl; + irr::gui::IGUIComboBox* ComboMeshType; CColorControl* ControlVertexColors; CColorControl* GlobalAmbient; bool KeysPressed[irr::KEY_KEY_CODES_COUNT];