Page 1 of 1

Shared Materials for World, GUI and Models

Posted: 2012-03-07, 14:36
by Haimi
Hi @ll,

I was trying to create an iconset for shared usage as World Material and GUI icons.

So the Start of my Icons.cmat file is

Code: Select all

Textures/Icons/Stones
{
    diffusemap Textures/Icons/0001.png
    blendFunc src_alpha one_minus_src_alpha
    red   ambientLightRed
    green ambientLightGreen
    blue  ambientLightBlue
    ambientMask d 
}
and it is included by my GUI material file Inventory.cmat like this:

Code: Select all

// include Icons
dofile("Icons.cmat")
but when I start the Game and raise the Inventory GUI, I get following console Output:

Code: Select all

Warning: Could not load the bitmap at "Games/myGame/GUIs//Textures/Icons/0001.png".
but if I try to correct the Path to the Textures by adding "../" to the diffusemap file I stell get the error:

Code: Select all

Warning: Could not load the bitmap at "Games/myGame/GUIs//../Textures/Icons/0001.png".
Can I manage to set paths in cmat files so that I can write shared cmat files?

Re: Shared Materials for World, GUI and Models

Posted: 2012-03-07, 22:59
by Carsten
Haimi wrote:

Code: Select all

Warning: Could not load the bitmap at "Games/myGame/GUIs//../Textures/Icons/0001.png".
Can I manage to set paths in cmat files so that I can write shared cmat files?
Maybe the double slash is the culprit...?

Can you please try if this patch?

Code: Select all

Index: Libs/MaterialSystem/MaterialManagerImpl.cpp
===================================================================
--- Libs/MaterialSystem/MaterialManagerImpl.cpp (revision 491)
+++ Libs/MaterialSystem/MaterialManagerImpl.cpp (working copy)
@@ -230,7 +230,7 @@
                 std::string Include=TextParser.GetNextToken();
                 TextParser.AssertAndSkipToken(")");

-                NewMaterials.PushBack(RegisterMaterialScript(BaseDir+Include, BaseDir+cf::String::GetPath(Include)+"/"));
+                NewMaterials.PushBack(RegisterMaterialScript(BaseDir+Include, BaseDir+cf::String::GetPath(Include)));
             }
             else
             {
and/or try

Code: Select all

dofile("./Icons.cmat")
Does this help?

Re: Shared Materials for World, GUI and Models

Posted: 2012-03-08, 11:19
by Haimi
I applied both patches ant - nope - the doucleslash was not the Problem:

Code: Select all

Warning: Could not load the bitmap at "Games/myGame/GUIs/../Textures/Icons/0001.png".

Re: Shared Materials for World, GUI and Models

Posted: 2012-03-09, 11:41
by Carsten
Hmmm. Whatever I try, it works for me. That is, I cannot reproduce this problem here, even if I introduce bitmap names like "../xy" artificially.

Are you sure there is no other problem with the filename? (e.g. capitalization? spelling?) What OS do you use? Can you open the same file with e.g. Gimp?

Re: Shared Materials for World, GUI and Models

Posted: 2012-03-11, 19:26
by Haimi
I tested everything I could, but within inclusion, the paths are still used from the root cmat files path. I tried to introduce a simple change to let the materialManager be able to use paths from the mod's basepath if starting with "#/". Here is a patch for this, if you want I create a ticket with in in the trac:

Code: Select all

Index: Libs/String.hpp
===================================================================
--- Libs/String.hpp	(revision 483)
+++ Libs/String.hpp	(working copy)
@@ -23,6 +23,7 @@
 #define CAFU_STRING_HPP_INCLUDED
 
 #include <string>
+#include <iostream>
 
 
 namespace cf
@@ -67,6 +68,21 @@
             return s;
         }
 
+        /// Assumes that the given string \c s is a filename of pattern "path/filename.ext" and returns the path portion.
+        inline std::string GetRootPath(std::string s)
+        {
+			if (s.empty()) return s;
+
+			size_t PosSep = 0;
+			for (size_t i = 0; i < 2; i++) {
+				PosSep= s.find_first_of("/\\", PosSep + 1);
+			}
+
+			if (PosSep!=std::string::npos) s.erase(PosSep);
+
+            return s;
+        }
+
         /// Replaces in \c s all occurrences of \c search by \c replace, and returns the new string.
         inline std::string Replace(std::string s, const std::string& search, const std::string& replace)
         {
Index: Libs/MaterialSystem/MapComposition.cpp
===================================================================
--- Libs/MaterialSystem/MapComposition.cpp	(revision 483)
+++ Libs/MaterialSystem/MapComposition.cpp	(working copy)
@@ -22,6 +22,7 @@
 #include "MapComposition.hpp"
 #include "Bitmap/Bitmap.hpp"
 #include "ConsoleCommands/Console.hpp"
+#include "String.hpp"
 
 #include <math.h>
 
@@ -356,13 +357,18 @@
 
         case Map:
         {
+        	char* FilePath = new char();
             try
             {
-                return new BitmapT((*BaseDir+FileName).c_str());
+            	FilePath = (char*)(*BaseDir+FileName).c_str();
+            	if (FileName.substr(0,2).compare("#/") == 0) {
+                    FilePath = (char*)(cf::String::GetRootPath(*BaseDir)+"/"+FileName.substr(2, FileName.size()-1)).c_str();
+            	}
+                return new BitmapT(FilePath);
             }
             catch (const BitmapT::LoadErrorT&)
             {
-                Console->Warning(std::string("Could not load the bitmap at \"")+(*BaseDir)+FileName+"\".\n");
+                Console->Warning(std::string("Could not load the bitmap at \"")+(FilePath)+"\".\n");
                 return new BitmapT(BitmapT::GetBuiltInFileNotFoundBitmap());
             }
         }
Index: Libs/MaterialSystem/MaterialManagerImpl.cpp
===================================================================
--- Libs/MaterialSystem/MaterialManagerImpl.cpp	(revision 483)
+++ Libs/MaterialSystem/MaterialManagerImpl.cpp	(working copy)
@@ -230,7 +230,7 @@
                 std::string Include=TextParser.GetNextToken();
                 TextParser.AssertAndSkipToken(")");
 
-                NewMaterials.PushBack(RegisterMaterialScript(BaseDir+Include, BaseDir+cf::String::GetPath(Include)+"/"));
+                NewMaterials.PushBack(RegisterMaterialScript(BaseDir+Include, BaseDir+cf::String::GetPath(Include)));
             }
             else
             {

Re: Shared Materials for World, GUI and Models

Posted: 2012-03-11, 21:03
by Carsten
Haimi wrote:I tested everything I could, but within inclusion, the paths are still used from the root cmat files path.
Can you reproduce this with one of the vanilla Cafu releases?

Code: Select all

Index: Libs/String.hpp
===================================================================
--- Libs/String.hpp	(revision 483)
+++ Libs/String.hpp	(working copy)
 
+        /// Assumes that the given string \c s is a filename of pattern "path/filename.ext" and returns the path portion.
+        inline std::string GetRootPath(std::string s)
+        {
+			if (s.empty()) return s;
+
+			size_t PosSep = 0;
+			for (size_t i = 0; i < 2; i++) {
+				PosSep= s.find_first_of("/\\", PosSep + 1);
+			}
+
+			if (PosSep!=std::string::npos) s.erase(PosSep);
+
+            return s;
+        }
+
If s does not contain any / or \ at all, the second iteration of the loop will refer to std::string::npos + 1 (and most likely crash...)

Btw., it would be more helpful if you attached patches as files, with .patch or .diff suffix, so that a double-click will open them e.g. in TortoiseSVN right away. Inline in [ code ] elements, they're very hard to use. :up:

Re: Shared Materials for World, GUI and Models

Posted: 2012-03-11, 21:11
by Haimi
Okay, here the corrected patch as attachment :)

I could only test it from svn - I am running LinuxMint