copySubImage problem

Quick question - the above function (of PNMImage) doesn’t appear to be working. I’m copying out a chunk of my source image using this code:

   tiles = PNMImage() 
   textureFile = Filename(sourceImgPath)
   tile = PNMImage(tileSize[0], tileSize[1]) 
   tile.copySubImage(tiles, 0, 0, location[0], location[1]) 

Where location is the top-left location in the source image.

tile comes out with (apparently) nothing written to it. Any hints? Thanks.

Looks all right to me. You should probably check the return value of read() to ensure that it successfully read your source image.


Thanks David. read()'s returning true, so looks like the image is coming in properly.

The source image in this instance is a JPG - could that be the issue?

Nope, the file format isn’t related at this point, since by the time it’s read it’s been converted internally into a standard 2-d array of pixels.

I still don’t see anything wrong, so I have to ask the obvious questions: Are you sure that your location values are sensible and represent a valid part of the source image? Are you sure that tileSize is reasonable and big enough to hold the result? Are you sure that the image it’s reading isn’t empty? Are you sure that the resulting image really is empty?


Ahh… heh. Sorry.

I took the resulting tile and dumped it to a file - sure enough, it’s there. Since I was copying from a grayscale image I assumed it would stay grayscale, so the check I put in place to see if the new image was valid was… invalid.

Anyway, now I’m converting the image to grayscale and it’s fine - coming out fairly dark but I assume I can just use lightenImage for that.

Thanks, David.

Ah, OK. If you want it to be a grayscale image after the copy, then create a grayscale image to copy it into:

tile = PNMImage(tileSize[0], tileSize[1], 1)

The third parameter specifies the number of channels. You could also specify 2 for grayscale-alpha, since you are going to add an alpha channel anyway.


Very nice - that’s perfect. Thanks very much!

Right, now’s the bit where I ask a stupid question. Sorry. I’ve been messing with this too long!

I’ve created the sub images - they come out great! However, I try to feed these PNGImages into GeoMipTerrain and get… nothing. PGMM is a bit black-magicky and so I’ve fiddled with various settings that have helped on previous heightmaps and got nothing - I get what amounts to a flat surface. The pixels are clearly there when I save the images to a file - I’m just missing something vital.

I’m sure the parent file is a valid heightmap, etc. I’m using the code outlined above, altered to parse a large image into multiple smaller ones (which seems to be working from my output images).

Any ideas? Thanks.

GeoMipTerrain generates Z position of the vertices in the 0-1 range, which can sometimes look like it’s almost flat. You will need to call setSz(255) on the terrain root (or a different high scale) to make it less flat.


Yep, I’m doing that. I learned my lesson a couple dozen heightmaps ago. :slight_smile: Anyhow, the fact that ALL of my sections come out looking exactly alike when fed in led me to believe it might be an issue with the PNMs.

As I mentioned before I’ve written my various (I’ll call them “tiles”) tiles out to disk. The images on disk look good. I’ve just now tried loading those tile images directly as PGMMs - same thing. They all look exactly the same - flat but slightly bumpy, all in the same pattern. Almost as though they were an uninitialized variable.

Could I be missing something in the translation from heightmap to PNM to PNM sub-image? Is there something special I need to do alpha-wise?

Hard to imagine what could go wrong there.

Looking at the PGMM code, it appears that it handles a color heightfield in a special case: it takes the RGB channels separately as the high, medium, and low-order bytes of the height value, respectively. This means that if you inadvertently build a color image with all of the data in the blue channel (the image will look blue when you view it), which is easy to do accidentally in the PNMImage interface, then you will have loaded on the low-order byte data, and you will see only a little wiggling in the heightfield.


Hmm. Thanks. (I should really start digging into the source as well, I suppose - then I can stop asking so many questions!)

Yes, that’s what was happening before - but the parameter added to the PNMImage constructor created a grayscale image to copy the source image into… so it’s no longer coming out blue. It is noticeably dimmer than the parent. Certainly it appears that “a little wiggling” is precisely what I’m seeing, although it’s odd that all of the tiles appear the same (that might just be an artifact of the multitexturing process, though, making “very slightly bumpy” look “almost exactly the same”).

I tried using lightenSubImage but saw no difference. Could only the low-order byte data be getting copied into the new grayscale image? Both the source and the destination respond positively to a isGrayscale call.

Are you sure it’s not a scaling issue? What happens if you set the Z scale high enough to resolve the wiggling into some real mountains? How much scaling is required before that happens? Does it resemble the terrain you expect it to?


I started off with a z-scale of 90 and increased it to 255 when pro-rsoft suggested. Everything still looks the same. I do get gigantic z-directed seams (big gaps between tiles) when I do that - but I’m not seeing the terrain I expect to see. The tiles all look the same and are relatively flat… they’re just lifted up in the air.

All right guys, thanks for your help. I worked it out. I was scaling and auto-flattening the terrain - and my shaders were being applied per-tile, which was making each of them look very similar. The floating Z thing is my issue. Now I just have to figure out how to make multiple GeoMipTerrains play nicely, preferably as one unit.

There’s a blueprint pending about that, but I’m afraid I won’t have time anywhere in the near future to implement it. … /gmmpaging

I did add a somewhat inefficient way to reduce those seams, though, by adding the setBorderStitching method recently.

I get an “Internetseite konnte nicht gefunden werden!” error when I try to look at the blueprint. You’re right, though, it would be useful.

I guess I’ll need to write something along these lines myself. I’ve been impressed with single-GMM performance but I’d like to have the freedom to have more if possible.

As for setBorderStitching, I suppose I haven’t hit upon the magic parameters to make it work properly for me - I still see seams all over. I’ll have a glance at the source.

Were you thinking of adding the paging system to the PGMM class itself (as in, one PGMM can “own” several heightmaps and page them)? I guess that might be kind of stretching the interface, though.

Oops. I’m contacting ThomasEgi to fix the link.
EDIT: Seems like he fixed it again :slight_smile:

Maybe your heightmaps don’t line up perfectly? There needs to be one pixel overlap.

I was planning to add a PagedGeoMipTerrain class that manages multiple GeoMipZone’s, that each represent a sub-terrain. The specification in the linked URL above should explain the design a bit.

Ahh, thanks! I’ll take a look.

As for the one-pixel overlap… is that in the docs somewhere? From what I’d read on the forums they just needed to match up. Obviously you’re correct… but these little usage details could do with being center stage in the reference docs at least.

The pixels on the heightmap match the vertices on the lowest level of the GeoMipTerrain. So the left border of heightmap 2 must match the right border of heightmap 1 for border stitching to actually make sense.