x to disable interpolation, try Minetest texture naming convention

master
poikilos 2019-04-08 22:52:18 -04:00
parent 8a61dea048
commit 49ac8c9a5b
12 changed files with 225 additions and 76 deletions

View File

@ -1,5 +1,17 @@
# Changelog
## [git] - 2019-04-08
(poikilos)
### Added
* toggle texture interpolation (via checkbox and `x` hotkey)
* INDEX_ variables to store ID of GUI elements
* Text box show name of loaded texture path
### Changed
* check if model is loaded before changing view options (prevents crash)
* unified checkboxes with m_* booleans, by tracking whether box is
checked via INDEX_ variables for each ID of GUI elements.
* look for ../textures/<model basename>.png & .jpg 1st time pressing `t`
## [git] - 2019-03-09
(poikilos)
### Added

View File

@ -265,6 +265,8 @@ void Engine::loadMesh( const wstring &fileName )
}
}
}
m_LoadedMesh->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
// EMT_TRANSPARENT_ALPHA_CHANNEL: constant transparency
}
}
}
@ -279,7 +281,10 @@ void Engine::reloadMesh()
void Engine::reloadTexture()
{
if (this->m_PrevTexturePath.length() > 0) {
loadTexture(this->m_PrevTexturePath);
if (this->m_UserInterface->texturePathEditBox->getText() != L"")
loadTexture(this->m_UserInterface->texturePathEditBox->getText());
else
loadTexture(this->m_PrevTexturePath);
}
}
@ -292,28 +297,53 @@ bool Engine::loadTexture(const wstring &fileName)
ret = true;
}
this->m_PrevTexturePath = fileName;
this->m_UserInterface->texturePathEditBox->setText(this->m_PrevTexturePath.c_str());
return ret;
}
void Engine::setMeshDisplayMode( bool wireframe, bool lighting )
void Engine::setMeshDisplayMode( bool wireframe, bool lighting, bool textureInterpolation)
{
for( int materialIndex = 0; materialIndex < m_LoadedMesh->getMaterialCount(); materialIndex ++ )
{
// Set Wireframe display
m_LoadedMesh->getMaterial( materialIndex ).Wireframe = wireframe;
if (m_LoadedMesh != nullptr) {
for( int materialIndex = 0; materialIndex < m_LoadedMesh->getMaterialCount(); materialIndex ++ )
{
// Set Wireframe display
m_LoadedMesh->getMaterial(materialIndex).Wireframe = wireframe;
// Set Lighting
if( ! lighting )
{
m_LoadedMesh->getMaterial( materialIndex ).Lighting = false;
m_LoadedMesh->getMaterial( materialIndex ).EmissiveColor = SColor( 255, 255, 255, 255 );
}
else
{
m_LoadedMesh->getMaterial( materialIndex ).Lighting = true;
m_LoadedMesh->getMaterial( materialIndex ).EmissiveColor = SColor( 255, 0, 0, 0 );
// Set Lighting
if( ! lighting )
{
m_LoadedMesh->getMaterial(materialIndex).Lighting = false;
m_LoadedMesh->getMaterial(materialIndex).EmissiveColor = SColor( 255, 255, 255, 255 );
}
else
{
m_LoadedMesh->getMaterial(materialIndex).Lighting = true;
m_LoadedMesh->getMaterial(materialIndex).EmissiveColor = SColor( 255, 0, 0, 0 );
}
// m_LoadedMesh->setMaterialType(video::EMT_TRANSPARENT_ALPHA_CHANNEL); //already done on load
// m_LoadedMesh->setMaterialFlag(video::E_ALPHA_SOURCE, true); // requires EMT_ONETEXTURE
if (textureInterpolation) {
m_LoadedMesh->setMaterialFlag(video::EMF_BILINEAR_FILTER, true);
m_LoadedMesh->setMaterialFlag(video::EMF_TRILINEAR_FILTER, true);
}
else {
m_LoadedMesh->setMaterialFlag(video::EMF_BILINEAR_FILTER, false);
m_LoadedMesh->setMaterialFlag(video::EMF_TRILINEAR_FILTER, false);
//m_LoadedMesh->setMaterialFlag(video::E_ALPHA_SOURCE, true);
// below doesn't work for some reason:
// video::SMaterial mat = m_LoadedMesh->getMaterial(materialIndex);
// mat.UseMipMaps = false;
// mat.setFlag(video::EMF_BILINEAR_FILTER, false);
// mat.setFlag(video::EMF_TRILINEAR_FILTER, false);
// below would require patching Irrlicht:
// GLint filteringMipMaps = GL_NEAREST_MIPMAP_NEAREST
// // above is used by glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filteringMipMaps);
}
}
}
else debug() << "WARNING in setMeshDisplayMode: No mesh is loaded " << endl;
}
bool Engine::isAnimating()

View File

@ -80,7 +80,7 @@ public:
void reloadMesh();
void reloadTexture();
bool loadTexture( const std::wstring &fileName );
void setMeshDisplayMode( bool wireframe = false, bool lighting = true );
void setMeshDisplayMode(bool wireframe = false, bool lighting = true, bool textureInterpolation = true);
bool isAnimating();
void playAnimation();
void pauseAnimation();

View File

@ -10,7 +10,8 @@ bird: [github.com/poikilos/mobs_sky](https://github.com/poikilos/mobs_sky)
Website: [poikilos.org](https://poikilos.org)
## Main Features in poikilos fork
* stabilized (makes sure font, model or texture loads before using)
* stabilized (makes sure font, model or texture loads before using;
makes sure model is loaded before setting View options)
* modernized includes (`#include` statements specify "irrlicht"
directory instead of assuming it)
* double-click after you associate this program with the file types
@ -123,10 +124,15 @@ only applies to Visual Studio users.)
* `t` / `e`: cycle through textures in `../textures` using `t` key (`e`
to go back) such as for Minetest mods, where model must be in
`modname/models/` and texture must be in `modname/textures/`.
If `../textures` doesn't exist relative to the model file's directory,
the model file's own directory will be used.
- If `"../textures/" + basename(modelName) + ".png"` or `".jpg"` is
present, pressing `t` for the first time will load it.
- If `../textures` doesn't exist relative to the model file's
directory, the model file's own directory will be used.
* `x`: toggle texture interpolation (shortcut for View, Texture
Interpolation)
* `F5`: Reload last model file
* `r`: Reload last texture file
* `r`: Reload last texture file (may not be working due to caching,
but does try to load different file if texture edit box changed).
* drag with middle button: rotate view
* drag with middle button while holding shift key: pan up and down
* `z` or `y`: change camera "up" axis to Z or Y (Y is default;

View File

@ -29,20 +29,21 @@ namespace fs = std::experimental::filesystem;
void UserInterface::setupUserInterface()
{
// Menu
IGUIContextMenu *menu = m_Gui->addMenu();
menu = m_Gui->addMenu();
menu->addItem( L"File", UIE_FILEMENU, true, true );
menu->addItem( L"View", UIE_VIEWMENU, true, true );
// File Menu
IGUIContextMenu *fileMenu = menu->getSubMenu( 0 );
fileMenu = menu->getSubMenu( 0 );
fileMenu->addItem( L"Load", UIC_FILE_LOAD );
fileMenu->addItem( L"LoadTexture", UIC_FILE_LOAD_TEXTURE );
fileMenu->addItem( L"Quit", UIC_FILE_QUIT );
// View Menu
IGUIContextMenu *viewMenu = menu->getSubMenu( 1 );
viewMenu->addItem( L"Wireframe Mesh", UIC_VIEW_WIREFRAME, true, false, false, true );
viewMenu->addItem( L"Lighting",UIC_VIEW_LIGHTING, true, false, true, true );
viewMenu = menu->getSubMenu( 1 );
INDEX_VIEW_WIREFRAME_MESH = viewMenu->addItem(L"Wireframe Mesh", UIC_VIEW_WIREFRAME, true, false, this->m_WireframeDisplay, true);
INDEX_VIEW_LIGHTING = viewMenu->addItem(L"Lighting", UIC_VIEW_LIGHTING, true, false, this->m_Lighting, true );
INDEX_VIEW_TEXTURE_INTERPOLATION = viewMenu->addItem(L"Texture Interpolation", UIC_VIEW_TEXTURE_INTERPOLATION, true, false, this->m_TextureInterpolation, true);
// Playback Control Window
dimension2d<u32> windowSize = m_Engine->m_Driver->getScreenSize();
@ -87,6 +88,25 @@ void UserInterface::setupUserInterface()
UIE_PLAYBACKSETFRAMEEDITBOX
);
y += size_y + spacing_y;
texturePathStaticText = m_Gui->addStaticText(
L"Texture Path:",
rect<s32>( vector2d<s32>( spacing_x, y ), dimension2d<s32>( size_x, size_y )),
true,
true,
playbackWindow,
UIE_TEXTUREPATHSTATICTEXT,
false
);
y += size_y + spacing_y;
texturePathEditBox = m_Gui->addEditBox(
L"",
rect<s32>( vector2d<s32>( spacing_x, y ), dimension2d<s32>( size_x, size_y )),
true,
playbackWindow,
UIE_TEXTUREPATHEDITBOX
);
// Set Font for UI Elements
m_GuiFontFace = new CGUITTFace();
// irrString defines stringc as string<c8>
@ -155,20 +175,31 @@ void UserInterface::handleMenuItemPressed( IGUIContextMenu *menu )
break;
case UIC_VIEW_WIREFRAME:
m_WireframeDisplay = m_WireframeDisplay ? false : true;
m_Engine->setMeshDisplayMode( m_WireframeDisplay, m_Lighting );
m_WireframeDisplay = viewMenu->isItemChecked(INDEX_VIEW_WIREFRAME_MESH);
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
break;
case UIC_VIEW_LIGHTING:
m_Lighting = m_Lighting ? false : true;
m_Engine->setMeshDisplayMode( m_WireframeDisplay, m_Lighting );
m_Lighting = viewMenu->isItemChecked(INDEX_VIEW_LIGHTING);
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
break;
case UIC_VIEW_TEXTURE_INTERPOLATION:
m_TextureInterpolation = viewMenu->isItemChecked(INDEX_VIEW_TEXTURE_INTERPOLATION);
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
break;
}
}
// PUBLIC
UserInterface::UserInterface( Engine *engine )
{
INDEX_VIEW_TEXTURE_INTERPOLATION = -1;
INDEX_VIEW_WIREFRAME_MESH = -1;
INDEX_VIEW_LIGHTING = -1;
this->playbackStartStopButton = nullptr;
m_Engine = engine;
@ -176,6 +207,7 @@ UserInterface::UserInterface( Engine *engine )
m_WireframeDisplay = false;
m_Lighting = true;
m_TextureInterpolation = true;
setupUserInterface();
}
@ -230,7 +262,40 @@ bool UserInterface::loadNextTexture(int direction)
std::wstring lastPath = L"";
bool found = false;
bool force = false;
wstring tryPath;
if (fs::is_directory(fs::status(path))) {
if (this->m_Engine->m_PrevTexturePath.length() == 0) {
if (this->m_Engine->m_PreviousPath.length() > 0 ) {
//debug() << "tryPath..." << endl;
tryPath = texturesPath + dirSeparator + Utility::withoutExtension(Utility::basename(this->m_Engine->m_PreviousPath)) + L".png";
// debug() << "tryPath 1a " << Utility::toString(tryPath) << "..." << endl;
tryPath = Utility::toWstring(Utility::toString(tryPath));
// debug() << "tryPath 1b " << Utility::toString(tryPath) << "..." << endl;
// tryPath = texturesPath + dirSeparator + Utility::basename(this->m_Engine->m_PreviousPath) + L".png";
if (!Utility::isFile(tryPath)) {
//asdf
tryPath = texturesPath + dirSeparator + Utility::withoutExtension(Utility::basename(this->m_Engine->m_PreviousPath)) + L".jpg";
// debug() << "tryPath 2a " << Utility::toString(tryPath) << "..." << endl;
tryPath = Utility::toWstring(Utility::toString(tryPath));
// tryPath = Utility::toWstring(Utility::toString(L"debug1")); // ../iconv/loop.c:457: internal_utf8_loop_single: Assertion `inptr - (state->__count & 7)' failed.
// debug() << "tryPath 2b " << Utility::toString(tryPath) << "..." << endl;
// tryPath = texturesPath + dirSeparator + Utility::basename(this->m_Engine->m_PreviousPath) + L".jpg";
if (Utility::isFile(tryPath)) {
nextPath = tryPath;
found = true;
force = true;
}
}
else {
nextPath = tryPath;
found = true;
force = true;
}
}
}
//debug() << "tryPath: " << Utility::toString(tryPath) << endl;
//debug() << "nextPath: " << Utility::toString(nextPath) << endl;
for (const auto & itr : fs::directory_iterator(path)) {
std::wstring ext = Utility::extensionOf(itr.path().wstring()); // no dot!
if (!is_directory(itr.status())
@ -240,14 +305,14 @@ bool UserInterface::loadNextTexture(int direction)
if (nextPath.length() == 0) nextPath = itr.path().wstring();
lastPath = itr.path().wstring();
if (found && direction > 0) {
nextPath = itr.path().wstring();
if (!force) nextPath = itr.path().wstring();
break;
}
if (itr.path().wstring()==this->m_Engine->m_PrevTexturePath) found = true;
if (itr.path().wstring() == this->m_Engine->m_PrevTexturePath) found = true;
if (!found) retroPath = itr.path().wstring();
}
}
if (retroPath.length()==0)
if (retroPath.length() == 0)
retroPath = lastPath; // previous is last if at beginning
if (direction < 0)
nextPath = retroPath;
@ -286,6 +351,14 @@ bool UserInterface::OnEvent( const SEvent &event )
else if (event.KeyInput.Key == irr::KEY_KEY_Y) {
m_Engine->setZUp(false);
}
else if (event.KeyInput.Key == irr::KEY_KEY_X) {
// IGUIContextMenu* textureInterpolationElement = dynamic_cast<IGUIContextMenu*>(viewMenu->getElementFromId(UIC_VIEW_TEXTURE_INTERPOLATION));
//m_TextureInterpolation = textureInterpolationElement->isItemChecked(UIC_VIEW_TEXTURE_INTERPOLATION);
m_TextureInterpolation = m_TextureInterpolation ? false : true;
//doesn't work: m_TextureInterpolation = viewMenu->isItemChecked(UIC_VIEW_TEXTURE_INTERPOLATION);
m_Engine->setMeshDisplayMode(m_WireframeDisplay, m_Lighting, m_TextureInterpolation);
viewMenu->setItemChecked(INDEX_VIEW_TEXTURE_INTERPOLATION, m_TextureInterpolation);
}
else if (event.KeyInput.Char == L'+' || event.KeyInput.Char == L'=') {
m_Engine->setAnimationFPS(m_Engine->animationFPS() + 5);
}

View File

@ -18,16 +18,19 @@ enum UserInterfaceElements
UIE_LOADTEXTUREDIALOG = 1006,
UIE_PLAYBACKINCREASEBUTTON = 1007,
UIE_PLAYBACKDECREASEBUTTON = 1008,
UIE_PLAYBACKSETFRAMEEDITBOX = 1009
UIE_PLAYBACKSETFRAMEEDITBOX = 1009,
UIE_TEXTUREPATHSTATICTEXT = 1010,
UIE_TEXTUREPATHEDITBOX = 1011
};
enum UserInterfaceCommands
{
UIC_FILE_LOAD = 1000,
UIC_FILE_QUIT = 1001,
UIC_FILE_LOAD_TEXTURE = 1002,
UIC_VIEW_WIREFRAME = 2000,
UIC_VIEW_LIGHTING = 2001
UIC_FILE_LOAD = 1000,
UIC_FILE_QUIT = 1001,
UIC_FILE_LOAD_TEXTURE = 1002,
UIC_VIEW_WIREFRAME = 2000,
UIC_VIEW_LIGHTING = 2001,
UIC_VIEW_TEXTURE_INTERPOLATION = 2002
};
class UserInterface : public irr::IEventReceiver
@ -45,12 +48,22 @@ private:
bool m_WireframeDisplay;
bool m_Lighting;
bool m_TextureInterpolation;
public:
irr::gui::IGUIContextMenu *menu;
irr::gui::IGUIContextMenu *fileMenu;
irr::gui::IGUIContextMenu *viewMenu;
irr::gui::IGUIButton *playbackStartStopButton;
irr::gui::IGUIButton *playbackIncreaseButton;
irr::gui::IGUIButton *playbackDecreaseButton;
irr::gui::IGUIEditBox *playbackSetFrameEditBox;
irr::gui::IGUIStaticText *texturePathStaticText;
irr::gui::IGUIEditBox *texturePathEditBox;
irr::u32 INDEX_VIEW_TEXTURE_INTERPOLATION;
irr::u32 INDEX_VIEW_WIREFRAME_MESH;
irr::u32 INDEX_VIEW_LIGHTING;
UserInterface( Engine *device );
~UserInterface();

View File

@ -123,7 +123,7 @@ wstring Utility::delimiter(const wstring &path)
std::wstring ret = L"/";
std::wstring::size_type lastSlashPos = path.find_last_of(L"/");
if (lastSlashPos == std::wstring::npos) {
// ret = "/";
// ret = L"/";
}
else {
std::wstring::size_type lastSlashPos = path.find_last_of(L"\\");
@ -145,22 +145,33 @@ bool Utility::isFile(const std::string& name) {
std::string Utility::toString(const std::wstring& ws) {
std::string ret;
// convert to w_string using locale: see Phillipp on <https://stackoverflow.com/questions/4804298/how-to-convert-wstring-into-string>
std::setlocale(LC_ALL, "");
const std::locale locale("");
typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
const converter_type& converter = std::use_facet<converter_type>(locale);
std::vector<char> to(ws.length() * converter.max_length());
std::mbstate_t state;
const wchar_t* from_next;
char* to_next;
const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
if (result == converter_type::ok or result == converter_type::noconv) {
const std::string s(&to[0], to_next);
//std::cout <<"std::string = "<<s<<std::endl;
ret = s;
if (ws.length() > 0) {
// std::string str = "Hello";
ret = std::string(ws.length(), L' '); // Make room for characters
// Copy string to wstring.
std::copy(ws.begin(), ws.end(), ret.begin());
}
return ret;
//below sometimes results in "internal_utf8_loop_single: Assertion `inptr - bytebuf > (state->__count & 7)' failed." on the converter.out call:
// if (ws.length() > 0) {
// // convert to w_string using locale: see Phillipp on <https://stackoverflow.com/questions/4804298/how-to-convert-wstring-into-string>
// std::setlocale(LC_ALL, "");
// const std::locale locale("");
// typedef std::codecvt<wchar_t, char, std::mbstate_t> converter_type;
// const converter_type& converter = std::use_facet<converter_type>(locale);
// std::vector<char> to(ws.length() * converter.max_length());
// std::mbstate_t state;
// const wchar_t* from_next = nullptr;
// char* to_next = nullptr;
// const converter_type::result result = converter.out(state, ws.data(), ws.data() + ws.length(), from_next, &to[0], &to[0] + to.size(), to_next);
// if (result == converter_type::ok or result == converter_type::noconv) {
// const std::string s(&to[0], to_next);
// //std::cout <<"std::string = "<<s<<std::endl;
// ret = s;
// }
// }
// return ret;
}
std::string Utility::toLower(const std::string &s)
@ -187,6 +198,18 @@ wstring Utility::toWstring(int val)
return std::to_wstring(val);
}
wstring Utility::toWstring(const std::string &str)
{
std::wstring ret;
if (str.length() > 0) {
// std::string str = "Hello";
ret = std::wstring(str.length(), L' '); // Make room for characters
// Copy string to wstring.
std::copy(str.begin(), str.end(), ret.begin());
}
return ret;
}
irr::f32 Utility::toF32(wstring val)
{
std::wstringstream ss(val);

View File

@ -23,6 +23,7 @@ public:
static std::wstring toLower(const std::wstring &s);
static std::wstring toWstring(irr::f32 val);
static std::wstring toWstring(int val);
static std::wstring toWstring(const std::string &str);
static irr::f32 toF32(std::wstring val);
// compiler doesn't like template function when class is not a template--instantiate immediately
// see http://processors.wiki.ti.com/index.php/C%2B%2B_Template_Instantiation_Issues

View File

@ -54,7 +54,7 @@ if [ ! -f "$try_dest_bin" ]; then
echo "WARNING: can't write to $prev_dir, so"
fi
if [ "@$PROFILE_ENABLE" = "@true" ]; then
dest_bin_dir="$USER/.local/bin"
dest_bin_dir="$HOME/.local/bin"
echo "installing to '$dest_bin_dir'."
echo "Press Ctrl C to cancel..."
sleep 1

View File

@ -1,20 +0,0 @@
[Desktop Entry]
Comment[en_US]=
Comment=
GenericName[en_US]=Irrlicht Model Viewer
GenericName=Irrlicht Model Viewer
MimeType=
Name[en_US]=b3view
Name=b3view
Path=
StartupNotify=true
Terminal=false
TerminalOptions=
Type=Application
X-DBUS-ServiceName=
X-DBUS-StartupType=
X-KDE-SubstituteUID=false
X-KDE-Username=
Exec=owner/.local/bin/b3view
Icon=owner/.local/share/icons/b3view.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 727 B

View File

@ -1,4 +1,15 @@
#!/bin/sh
echo "Use the install.sh in build instead. Switching to build/install.sh..." && cd build || echo "ERROR: No build directory" && exit 1
customDie() {
echo
echo "ERROR:"
echo "$1"
echo
echo
exit 1
}
echo "Use the install.sh in build instead. Switching to build/install.sh..."
cd build || customDie "ERROR: No build directory"
chmod +x install.sh
./install.sh