writing heightfield to tga

Started by
5 comments, last by GameDev.net 19 years, 5 months ago
hello, i want to write out a 2dimensional array to a tga to be used as a heightmap. here is what i got so far:

void SaveHeightMap(char *filename, int width, int height, float hf[1024][1024]) {
	unsigned char *pixels;
	FILE *fp;

	if((fp=fopen(filename, "wb"))==NULL) return;

	unsigned char TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};
	unsigned char header[6] = {width%256,width/256,height%256,height/256,32,0};
	
	pixels = new unsigned char[width*height*4];
	for (int i=0;i<width;i++) {
		for (int j=0;j<height;j++) {
			// here is where i am stuck. ???
		}
	}

	fwrite(TGAheader, sizeof(unsigned char), 12, fp);
	fwrite(header, sizeof(unsigned char), 6, fp);
	fwrite(pixels, sizeof(unsigned char), width*height*4, fp);
	fclose(fp);

}

but i dont know how to write the heightvalues in the heightfield. thanks in advance for any help!
Advertisement
you need to find the highest and lowest points in your array of floats (heightfield) then range compress them down to 0-255 and save them as unsigned char's (pixels) its not hard, for each point:
pixels[currentPixel] = (unsigned char)(((hf[currentPixel]-minHeight) / (maxHeight - minHeight)) * 255.0f)


[Edited by - silvermace on November 16, 2004 2:20:28 AM]
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
I haven't done much with terrains, but AFAIK most heightmap images are just grayscale where the intensity of the pixel color corresponds to the height.

I don't know if there's a 'standard' method, but in your case for each pixel r = g = b = (height / heightrange) * 255.0f, and a = whatever, probably 255.

(Note that I assumed minheight = 0. If that's not the case you'd have to tweak the code a little.)

Basically, you normalize the height into the range [0, 1], then multiply that by 255 to scale it into a byte. Then you do the reverse when you read it in.

Does that help?
yes, but there must be some error in the TGA writing, because whatever i try, i always get an image that is lightgreen with a black bar at the bottom.

here is what i have now:

void SaveHeightMap(char *filename, int width, int height, float hf[1024][1024]) {	unsigned char *pixels;	FILE *fp;	int p=0;	if((fp=fopen(filename, "wb"))==NULL) return;	unsigned char TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0};	unsigned char header[6] = {width%256,width/256,height%256,height/256,32,0};		pixels = new unsigned char[width*height*4];	for (int i=0;i<width;i++) {		for (int j=0;j<height;j++) {			pixels=(unsigned char) (hf[j]);			p++;		}	}	fwrite(TGAheader, sizeof(unsigned char), 12, fp);	fwrite(header, sizeof(unsigned char), 6, fp);	fwrite(pixels, sizeof(unsigned char), width*height*4, fp);	fclose(fp);}


(the hf values are between 0 and 255 already.)

thanks!

edit: ok i figured out, that i have to write each value four times, cause TGA is in BGRA format, right?
"edit: ok i figured out, that i have to write each value four times, cause TGA is in BGRA format, right?"

Right :) And actually, the A value probably doesn't matter (although it depends on how the data is going to be read in).
ok, so far i manage to get out the right size of tga, but it looks like a binary image:

im doing it like this:

pixels[p++]=(unsigned char) (hf[j]);
pixels[p++]=(unsigned char) (hf[j]);
pixels[p++]=(unsigned char) (hf[j]);
pixels[p++]=(unsigned char) 0;



ok, i got it.
im now writing it with:

putc((int)(hf[j),fp);


[Edited by - ehmdjii on November 15, 2004 5:06:51 AM]
silvermace: you forgot to subtract the minHeight from the height value.

pixels[currentPixel] = (unsigned char)(((hf[currentPixel] - minHeight) / (maxHeight - minHeight)) * 255.0f)

This topic is closed to new replies.

Advertisement