Fix and improve multi-texture reloading

master
stujones11 2018-09-05 18:40:51 +01:00
parent 77c31ce84a
commit d5073f3dbf
7 changed files with 137 additions and 47 deletions

View File

@ -315,31 +315,44 @@ TexturesDialog::TexturesDialog(IGUIEnvironment *env, IGUIElement *parent,
conf(conf),
smgr(smgr)
{
IGUITabControl *tabs = env->addTabControl(rect<s32>(2,2,398,250), this,
IGUITabControl *tabs = env->addTabControl(rect<s32>(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<s32>(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<s32>(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<s32>(15,top,25,top+20),
env->addStaticText(num.c_str(), rect<s32>(15,top,25,top+20),
false, false, tab_model, -1);
edit = env->addEditBox(fn.c_str(), rect<s32>(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<s32>(15,top,25,top+20),
env->addStaticText(num.c_str(), rect<s32>(15,top,25,top+20),
false, false, tab_wield, -1);
edit = env->addEditBox(fn.c_str(), rect<s32>(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<s32>(315,255,395,285), this,
button = env->addButton(rect<s32>(315,285,395,315), this,
E_DIALOG_ID_TEXTURES_OK, L"OK");
button = env->addButton(rect<s32>(230,255,310,285), this,
button = env->addButton(rect<s32>(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);
}
}

View File

@ -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
};

View File

@ -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<s32>(0,20,400,310), conf, smgr);
E_DIALOG_ID_TEXTURES, rect<s32>(0,20,400,340), conf, smgr);
dialog->drop();
}

View File

@ -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"},

View File

@ -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");
}

View File

@ -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;

View File

@ -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;