Loading Resource files in Desktop/ios application
-
I am writing a model viewer that can load 3D model data and present the model to the user. I am writing it for both Desktop and Ios. And I am running into a snag with how to get at the data files.
My project is broken into 2 parts. The engine and the application. The engine has within it a asset loader. Now, up til now I have been developing this for desktop. I have no problem reaching out to the hard drive and loading the assets. But IOS presents me with a couple of problems: 1) how to get the assets on the device 2) how to get my engine (which is its own library) to see those assets.
My first (and only thought for now) was to put the assets in a .qrc file. Which I have.
But now neither the desktop or the ios device and get at the assets! For the sake of my testcase, I have rerouted the engines loader to load assets with these paths:
@void DataHarbor::setTargetPath(uw::Enum_IOTarget _target, const QString &_path )
{
if( m_useQtResources ) {
storage[_target].basepath = ":/assets/packets";
storage[_target].packets = ":/assets/packets";
storage[_target].texture = ":/assets/textures";
storage[_target].font = ":/assets";
storage[_target].sound = ":/assets";
} else {
storage[_target].basepath = m_userRootPath + "/" + _path ;
storage[_target].packets = m_userRootPath + "/" + _path + PATH_PACKETS;
storage[_target].texture = m_userRootPath + "/" + _path + PATH_TEXTURES;
storage[_target].font = m_userRootPath + "/" + _path + PATH_FONT;
storage[_target].sound = m_userRootPath + "/" + _path + PATH_SOUND;
}
}@When I attempt to load a asset, it concatenates the paths. So my final path to say load a simple cube, is this:
@:/assets/packets/cube.gly@
This is the code I am trying to load the asset with:
@ QString pathstring = packetPath(_packet, _target, false);
QFile file(pathstring);
if(file.exists()) {
QFileInfo finfo(file);
QString fileCreatedAt = finfo.created().toString();
QString fileModified = finfo.lastModified().toString();if( file.open(QFile::ReadOnly | QFile::Text)) {
_status.comment("Loading ascii packet '" + _packet + "'..." );
QTextStream in(&file);
code = in.readAll();
file.close();
setActiveOwner(_packet);
GlyphParser::parse(code);timer.stop(); _status.note("Created: " + fileCreatedAt); _status.note("Last modified: " + fileModified); _status.timeReport("Total time to load file:",timer);
} else
_status.errorc(enFailedToOpenPacket,
"Packet '" + _packet + "'' failed to open. Load failed.");
} else
_status.error(enPacketDoesntExist,
"Packet '" + _packet + "'' doesn't exist. Load failed.");@What I am finding is the line if(file.exists()) is always failing.
Now keep in mind, I am in my library here. I have read this line is important when loading content in a library:
Q_INIT_RESOURCE(assets);
But with or without this line, nothing is loading. What am I doing wrong here?
-
If you are compiling your qrc file correctly, you would reference those assets like
@
qrc:/assets/packets/cube.gly
@"Using the qrc":http://qt-project.org/doc/qt-5/resources.html
-
so qrc: is part of the path? Let me give that a shot!
-
Here is an exact example from that link.
@
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Q_INIT_RESOURCE(graphlib);QFile file("qrc:/graph.png"); ... return app.exec();
}
@So, yes the qrc: is part of the path when using QFile.
-
Ok, I tried the following:
@qrc:/cube.gly
qrc:/packets/cube.gly
qrc:/assets/packets/cube.gly@None of these work. qrc:/assets/packets/cube.gly should have been the correct one. But it fails.
cube.gly is the actual file.
packets is the prefix
assets is the .qrc file.
-
Oh ok, you only need the prefix and not qrc file name. You do need the Q_INIT_RESOURCE if the qrc is in a library.
This should have worked.
@qrc:/packets/cube.gly@
I can't think right now to help point you in the right direction.
-
I'm thinking that this problem is due to the fact that my asset loader is in a library. Does my library .pro file require this?
@RESOURCES +=
assets.qrc@I figured the resources would be available to all the components in my main application
-
Yes, your pro file for your library must have the RESOURCES += so that the qrc file is compiled. All a qrc file is is a xml file. When that file is compiled by the rcc, the output is then used to compile those resources into your binary. To reference those resources, you must use Q_INIT_RESOURCE outside of any namespace.
-
Hi,
Something's not clear here. Are you compiling the resources in your application and then try to access them in your library ?
-
SGaist,
Yes. My library has the file loader in it. When I read from a harddrive, I can specify a path and everything is great.But Qt's resource system seems to choke on the same basic design. It doesn't work like a hard drive at all. And another question I have is this. Does it load everything into memory when the app starts up? Thats ridiculous if does. I will be putting hundreds of megabytes of data in here. The idea is I want to load them into memory as I need it-like I do with a harddrive.
With XCode, I can include assets (ie, image files, data files [such as 3d model assets], etc.) It puts the content in the bundle and I can access it just like I can on my mac--I just need the bundle path. I am having a hard time wrapping my head around how this is done in Qt.
-
If you plan on hundreds of megabytes then you're using the wrong tool. Qt's resources are not meant to bundle that much data. Each resource will be compiled in your application.
However you still can use iOS assets, see "here":http://qt-project.org/doc/qt-5/platform-notes-ios.html
-
Forgot to add to get the path you want you have QStandardPaths
-
After reviewing your information, its clear I'm taking the wrong approach using a resource file. I understand now what the intent of the resource file is. It isn't to load my image/game assets.
On iOS, it looks like I need to look at using QMAKE_BUNDLE_DATA to package up my content. I don't yet know what I am to do on Android. I'm sure I'm going to have a few more questions ;)
-
Indeed, game assets are way to heavy for resources.
AFAIK, you should be able to use QMAKE_BUNDLE_DATA also on android