Using .raw for terrain
Sorry for the noob question. I'm changing from .png to .raw files, and I don't know how to load the file.
New File: Lost_HF.raw
Previous File: Terrain.png
/** Loads a heightmap from a raw data file and stores it in the given TerrainInfo. */
void _ETManagerExport loadHeightmapFromRawData(TerrainInfo& info, Ogre::DataStream& stream,
size_t width, size_t height);
Assuming I need to convert the .raw file into an Ogre::DataStream object, how do I do this? How do I obtain the width/height, and what is the width/height of?
One way to get the DataStream is to use Ogre's ResourceGroupManager::openResource. The width and height are just that - they determine the size of the heightmap contained in the .raw file. Seeing as .raw is not a real file format, but just dumps of height values, they have no knowledge about their size (image files do), so you have to provide those.
Ok, I'll give it a shot at home. I looked at ETM code just to see how they are doing it, and it looks like openResource does the job:
DataStreamPtr stream =
Shouldn't the loadHeightmapFromRawData take a DataStreamPtr?
Not really; there are other ways to acquire a DataStream (for example, from a memory block) which do not give a DataStreamPtr. It would be very inconvenient for these cases to somehow create one to be able to pass it along. It's easier for a DataStreamPtr to dereference it via * than the other way around
Works without any problems. ETM ftw.
I keep running into a problem trying to load .raw files. The same .raw files load fine with the terrain scene manager included with Ogre.
My code for loading the .raw or .png is:
if (ResourceGroupManager::getSingleton().resourceExists("General", mBaseName + "_hgt.png"))
image.load(mBaseName + "_hgt.png", "General");
if ((image.getWidth() != (CountX + 1)) && (image.getHeight() != (CountZ + 1)))
image.resize(CountX + 1, CountZ + 1);
else if (ResourceGroupManager::getSingleton().resourceExists("General", mBaseName + "_hgt.raw"))
Ogre::String RawPath = mFilePath + mBaseName + "_hgt.raw";
Ogre::FileStreamDataStream RawStream(&RawFile, false);
ET::loadHeightmapFromRawData(mTerrainInfoCopy, RawStream, CountX + 1, CountZ + 1);
Debugging shows no issue. The .png files load fine.
When loading a .raw file it appears to open the file fine. The ET::loadHeightmapFromRawData() function sees the file as the correct size, but flat terrain is loaded, except for a small flat rise along the x=0 coordinates I believe. I've made sure the extents are correct.
Does the standard issue Ogre terrain scene manager assume a different format with raw files? I wouldn't have thought so.
No, should be the same. Your code looks fine to me (except that to get a DataStream, it would be a lot easier to use ResourceGroupManager::openResource). Does increasing the y scale show any more structure? Otherwise I'm currently out of ideas :-/
All I can tell after further debugging is that the data from the file is read just fine into the std::vector<float> up until element 8377 of that vector in loadHeightmapFromRawData(...), which of course is file offset 16754. Then the rest is all 0.
I looked at the file using a hex editor at corresponding offset. The value there is 0x1A1A, not sure why that would matter. However the file is full of data from then on, even though read as all 0s in the code apparently.
In debugging, the file shows up as the right size. I need to understand why reading from the file would not be returning the right values after that particular offset. I may try a different raw file.
I'll try your suggestion as well, but I would sure like to understand this wierdness.
Thanks for the help.
A different raw file, and again, a byte value of 0x1A at the point where all 0s are read from then on. There must be something I don't understand about ifstream. maybe that isn't the right class to use for this kind of data.
Ah yes, the 0x1A was the hint I needed, now I see the error
It is once again that idiotic Windows behaviour to make a difference between "binary" and "ascii" access to a file. In ASCII mode, any appearance of the ascii code for newline \n is replaced with the control sequence \r\n, which of course is a catastrophe for your case.
So, in summary, you need to tell the ifstream to open the file in binary mode - or, way easier, use openResource as this automatically gives you a DataStream in binary mode.
If you still want to use the ifstream, I think this is the right call:
std::ifstream RawFile(RawPath.c_str(), std::ios_base::binary | std::ios_base::in);
Up until now I've been using ifstream for text files, so this has been educational.
I got it working using ResourceGroupManager::openResource, so I'm back on track, and may not need to use ifstream directly. It may be beneficial to not rely on the file path.
A big thanks for the help.
I'm working on some tests with ETL, and I have 3 short questions
1) I would like to know the pros and the cons about using a ".raw" file over a ".png" file ; what is the best format to use ?
2) if I have a 1024x1024 texture for my terrain, do I have to cut this texture into pieces/tiles or something in order to use it for the terrain in ETL ?
3) the size of the texture is something like 1024*1024 or 1025*1025 ?
Thanks for your pieces of advice, and thank you, CABAListic, for ETL !