Using .raw for terrain


11-02-2008 07:54:59

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

Previous usage:

Ogre::Image i;

Raw function:

/** 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?


11-02-2008 11:00:48

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.


11-02-2008 18:19:06

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 =
mSource, ResourceGroupManager::getSingleton().getWorldResourceGroupName());

Shouldn't the loadHeightmapFromRawData take a DataStreamPtr?


11-02-2008 21:39:11

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 :)


12-02-2008 06:30:21

Works without any problems. ETM ftw. :D


23-02-2008 15:03:58

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);
ET::loadHeightmapFromImage(mTerrainInfoCopy, image);
else if (ResourceGroupManager::getSingleton().resourceExists("General", mBaseName + "_hgt.raw"))
Ogre::String RawPath = mFilePath + mBaseName + "_hgt.raw";
std::ifstream RawFile(RawPath.c_str());
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.


23-02-2008 15:30:01

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 :-/


23-02-2008 16:04:37

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.


23-02-2008 16:15:38

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.


23-02-2008 16:22:26

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


23-02-2008 17:32:43

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.


13-08-2008 12:06:34


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 !