diff --git a/src/dialog.cpp b/src/dialog.cpp index 92e243e..bc19557 100644 --- a/src/dialog.cpp +++ b/src/dialog.cpp @@ -315,31 +315,44 @@ TexturesDialog::TexturesDialog(IGUIEnvironment *env, IGUIElement *parent, conf(conf), smgr(smgr) { - IGUITabControl *tabs = env->addTabControl(rect(2,2,398,250), this, + IGUITabControl *tabs = env->addTabControl(rect(2,2,398,280), this, true, true); IGUITab *tab_model = tabs->addTab(L"Model"); IGUITab *tab_wield = tabs->addTab(L"Wield"); - IGUIStaticText *text; IGUIEditBox *edit; IGUIButton *button; + IGUICheckBox *check; stringw fn; std::string key; + bool model_texture_single = conf->getBool("model_texture_single"); + bool wield_texture_single = conf->getBool("wield_texture_single"); + check = env->addCheckBox(false, rect(15,20,380,40), tab_model, + E_DIALOG_ID_TEXTURES_1_MODEL, L"Use single texture for all layers"); + check->setChecked(model_texture_single); + check = env->addCheckBox(false, rect(15,20,380,40), tab_wield, + E_DIALOG_ID_TEXTURES_1_WIELD, L"Use single texture for all layers"); + check->setChecked(wield_texture_single); + ITexture *image = getTexture("browse.png"); ISceneNode *model = smgr->getSceneNodeFromId(E_SCENE_ID_MODEL); ISceneNode *wield = smgr->getSceneNodeFromId(E_SCENE_ID_WIELD); - u32 mc_model = (model) ? model->getMaterialCount() : 0; - u32 mc_wield = (wield) ? wield->getMaterialCount() : 0; + u32 mc_model = 0; + if (model) + mc_model = (model_texture_single) ? 1 : model->getMaterialCount(); + u32 mc_wield = 0; + if (wield) + mc_wield = (wield_texture_single) ? 1 : wield->getMaterialCount(); for (u32 i = 0; i < 6; ++i) { - s32 top = i * 30 + 20; + s32 top = i * 30 + 50; stringw num = stringw(i + 1); key = "model_texture_" + std::to_string(i + 1); fn = conf->getCStr(key); - text = env->addStaticText(num.c_str(), rect(15,top,25,top+20), + env->addStaticText(num.c_str(), rect(15,top,25,top+20), false, false, tab_model, -1); edit = env->addEditBox(fn.c_str(), rect(35,top,350,top+20), true, tab_model, E_TEXTURE_ID_MODEL + i); @@ -359,7 +372,7 @@ TexturesDialog::TexturesDialog(IGUIEnvironment *env, IGUIElement *parent, key = "wield_texture_" + std::to_string(i + 1); fn = conf->getCStr(key); - text = env->addStaticText(num.c_str(), rect(15,top,25,top+20), + env->addStaticText(num.c_str(), rect(15,top,25,top+20), false, false, tab_wield, -1); edit = env->addEditBox(fn.c_str(), rect(35,top,350,top+20), true, tab_wield, E_TEXTURE_ID_WIELD + i); @@ -376,9 +389,9 @@ TexturesDialog::TexturesDialog(IGUIEnvironment *env, IGUIElement *parent, } button->setEnabled(i < mc_wield); } - button = env->addButton(rect(315,255,395,285), this, + button = env->addButton(rect(315,285,395,315), this, E_DIALOG_ID_TEXTURES_OK, L"OK"); - button = env->addButton(rect(230,255,310,285), this, + button = env->addButton(rect(230,285,310,315), this, E_DIALOG_ID_TEXTURES_CANCEL, L"Cancel"); } @@ -408,44 +421,67 @@ bool TexturesDialog::OnEvent(const SEvent &event) } } } + else if (event.GUIEvent.EventType == EGET_CHECKBOX_CHANGED) + { + IGUICheckBox *check = (IGUICheckBox*)getElementFromId(id, true); + std::string is_checked = (check->isChecked()) ? "true" : "false"; + + ISceneNode *node = 0; + s32 edit_box_id; + if (id == E_DIALOG_ID_TEXTURES_1_MODEL) + { + node = smgr->getSceneNodeFromId(E_SCENE_ID_MODEL); + edit_box_id = E_TEXTURE_ID_MODEL; + conf->set("model_texture_single", is_checked); + } + else if (id == E_DIALOG_ID_TEXTURES_1_WIELD) + { + node = smgr->getSceneNodeFromId(E_SCENE_ID_WIELD); + edit_box_id = E_TEXTURE_ID_WIELD; + conf->set("wield_texture_single", is_checked); + } + if (node) + { + for (u32 i = 1; i < 6; ++i) + { + if (i < node->getMaterialCount()) + { + IGUIEditBox *edit = (IGUIEditBox*) + getElementFromId(edit_box_id + i, true); + edit->setEnabled(is_checked == "false"); + } + } + } + } else if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED) { if (id == E_DIALOG_ID_TEXTURES_OK) { - ISceneNode *model = smgr->getSceneNodeFromId(E_SCENE_ID_MODEL); - ISceneNode *wield = smgr->getSceneNodeFromId(E_SCENE_ID_WIELD); IGUIEditBox *edit; - + ITexture *texture = 0; + stringc fn; for (u32 i = 0; i < 6; ++i) { std::string idx = std::to_string(i + 1); edit = (IGUIEditBox*) getElementFromId(E_TEXTURE_ID_MODEL + i, true); - if (edit && model && i < model->getMaterialCount()) + + fn = stringc(edit->getText()).c_str(); + texture = getTexture(fn); + if (texture) { - stringc fn = stringc(edit->getText()).c_str(); - ITexture *texture = getTexture(fn); - if (texture) - { - std::string key = "model_texture_" + idx; - conf->set(key, fn.c_str()); - SMaterial &material = model->getMaterial(i); - material.TextureLayer[0].Texture = texture; - } + std::string key = "model_texture_" + idx; + conf->set(key, fn.c_str()); } edit = (IGUIEditBox*) getElementFromId(E_TEXTURE_ID_WIELD + i, true); - if (edit && wield && i < wield->getMaterialCount()) + + fn = stringc(edit->getText()).c_str(); + texture = getTexture(fn); + if (texture) { - stringc fn = stringc(edit->getText()).c_str(); - ITexture *texture = getTexture(fn); - if (texture) - { - std::string key = "wield_texture_" + idx; - conf->set(key, fn.c_str()); - SMaterial &material = wield->getMaterial(i); - material.TextureLayer[0].Texture = texture; - } + std::string key = "wield_texture_" + idx; + conf->set(key, fn.c_str()); } } } @@ -487,4 +523,4 @@ bool TexturesDialog::OnEvent(const SEvent &event) } } return IGUIElement::OnEvent(event); -} \ No newline at end of file +} diff --git a/src/dialog.h b/src/dialog.h index 4c65824..b3fba61 100644 --- a/src/dialog.h +++ b/src/dialog.h @@ -29,6 +29,8 @@ enum E_DIALOG_ID_SETTINGS_OK, E_DIALOG_ID_SETTINGS_CANCEL, E_DIALOG_ID_TEXTURES, + E_DIALOG_ID_TEXTURES_1_MODEL, + E_DIALOG_ID_TEXTURES_1_WIELD, E_DIALOG_ID_TEXTURES_OK, E_DIALOG_ID_TEXTURES_CANCEL }; diff --git a/src/gui.cpp b/src/gui.cpp index 684469f..e481c13 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -527,11 +527,11 @@ void GUI::showTexturesDialog() { IGUIEnvironment *env = device->getGUIEnvironment(); ISceneManager *smgr = device->getSceneManager(); - IGUIWindow *window = env->addWindow(getWindowRect(400, 310), + IGUIWindow *window = env->addWindow(getWindowRect(400, 340), true, L"Textures"); TexturesDialog *dialog = new TexturesDialog(env, window, - E_DIALOG_ID_TEXTURES, rect(0,20,400,310), conf, smgr); + E_DIALOG_ID_TEXTURES, rect(0,20,400,340), conf, smgr); dialog->drop(); } diff --git a/src/main.cpp b/src/main.cpp index 871c663..f58ec55 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -20,6 +20,7 @@ int main() {"model_texture_4", "blank.png"}, {"model_texture_5", "blank.png"}, {"model_texture_6", "blank.png"}, + {"model_texture_single", "false"}, {"wield_mesh", "pickaxe.obj"}, {"wield_position", "0,5,0"}, {"wield_rotation", "0,0,0"}, @@ -33,6 +34,7 @@ int main() {"wield_texture_4", "blank.png"}, {"wield_texture_5", "blank.png"}, {"wield_texture_6", "blank.png"}, + {"wield_texture_single", "false"}, {"anim_start", "168"}, {"anim_end", "187"}, {"anim_speed", "15"}, diff --git a/src/scene.cpp b/src/scene.cpp index 5adba6e..bbad013 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -124,21 +124,45 @@ bool Scene::loadWieldMesh(const io::path &filename) return true; } +void Scene::clearTextures(ISceneNode *node, const std::string &prefix) +{ + for (u32 i = 0; i < node->getMaterialCount(); ++i) + { + SMaterial &material = node->getMaterial(i); + material.TextureLayer[0].Texture = 0; + } +} + void Scene::loadTextures(ISceneNode *node, const std::string &prefix) { IVideoDriver *driver = SceneManager->getVideoDriver(); - for (u32 i = 0; i < node->getMaterialCount(); ++i) + u32 material_count = node->getMaterialCount(); + u32 texture_count = (material_count < 6) ? material_count : 5; + if (conf->getBool(prefix + "_texture_single")) { - std::string key = prefix + "_texture_" + std::to_string(i + 1); - io::path fn = conf->getCStr(key); + io::path fn = conf->getCStr(prefix + "_texture_1"); ITexture *texture = driver->getTexture(fn); - if (texture) - driver->removeTexture(texture); - texture = driver->getTexture(fn); if (texture) { - SMaterial &material = node->getMaterial(i); - material.TextureLayer[0].Texture = texture; + for (u32 i = 0; i < material_count; ++i) + { + SMaterial &material = node->getMaterial(i); + material.TextureLayer[0].Texture = texture; + } + } + } + else + { + for (u32 i = 0; i < texture_count; ++i) + { + std::string key = prefix + "_texture_" + std::to_string(i + 1); + io::path fn = conf->getCStr(key); + ITexture *texture = driver->getTexture(fn); + if (texture) + { + SMaterial &material = node->getMaterial(i); + material.TextureLayer[0].Texture = texture; + } } } } @@ -240,10 +264,34 @@ void Scene::rotate(s32 axis, const f32 &step) void Scene::refresh() { + IVideoDriver *driver = SceneManager->getVideoDriver(); + + // Important, clear all texture refs before removing. ISceneNode *model = getNode(E_SCENE_ID_MODEL); + ISceneNode *wield = getNode(E_SCENE_ID_WIELD); + if (model) + clearTextures(model, "model"); + if (wield) + clearTextures(wield, "wield"); + + // Remove all textures before reloading. + std::string prefix[] = {"model", "wield"}; + for (u32 p = 0; p < 2; ++p) + { + for (u32 i = 0; i < 6; ++i) + { + std::string key = prefix[p] + "_texture_" + std::to_string(i + 1); + if (conf->hasKey(key)) + { + io::path fn = conf->getCStr(key); + ITexture *texture = driver->getTexture(fn); + if (texture) + driver->removeTexture(texture); + } + } + } if (model) loadTextures(model, "model"); - ISceneNode *wield = getNode(E_SCENE_ID_WIELD); if (wield) loadTextures(wield, "wield"); } diff --git a/src/scene.h b/src/scene.h index 57a8805..01454da 100644 --- a/src/scene.h +++ b/src/scene.h @@ -52,6 +52,7 @@ public: private: void loadTextures(ISceneNode *node, const std::string &prefix); + void clearTextures(ISceneNode *node, const std::string &prefix); Config *conf; bool show_grid; diff --git a/src/viewer.cpp b/src/viewer.cpp index cf0eac0..40a8196 100644 --- a/src/viewer.cpp +++ b/src/viewer.cpp @@ -393,19 +393,20 @@ bool Viewer::OnEvent(const SEvent &event) break; case E_DIALOG_ID_SETTINGS_OK: event.GUIEvent.Caller->getParent()->getParent()->remove(); - gui->setFocused(false); setBackgroundColor(conf->getHex("bg_color")); scene->setGridColor(conf->getHex("grid_color")); scene->setAttachment(); scene->setDebugInfo(conf->getBool("debug_info")); + gui->setFocused(false); break; case E_DIALOG_ID_SETTINGS_CANCEL: + case E_DIALOG_ID_TEXTURES_CANCEL: + case E_DIALOG_ID_ABOUT_OK: event.GUIEvent.Caller->getParent()->getParent()->remove(); gui->setFocused(false); break; - case E_DIALOG_ID_ABOUT_OK: case E_DIALOG_ID_TEXTURES_OK: - case E_DIALOG_ID_TEXTURES_CANCEL: + scene->refresh(); event.GUIEvent.Caller->getParent()->getParent()->remove(); gui->setFocused(false); break;