Editable Terrain Manager [v2.2 released]

A place to show off your latest screenshots and for people to comment on them. Only start a new thread here if you have some nice images to show off!
Post Reply
User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Post by jacmoe » Tue Jun 05, 2007 7:49 am

Code: Select all

		Ogre::Vector3 offset = mTerrainInfo->getOffset(); 
		Ogre::Vector3 scale = mTerrainInfo->getScaling(); 

		size_t tWidth = mTerrainInfo->getWidth();
		size_t tHeight = mTerrainInfo->getHeight();

		//Create indices 
		size_t index_size = (tWidth - 1) * (tHeight - 1) * 6; 
		size_t* indices = new unsigned int[index_size*3]; 
		for( size_t x = 0; x < tWidth - 1; x++) 
		{ 
			for( size_t y=0; y < mTerrainInfo->getHeight() - 1; y++) 
			{ 
				indices[(x+y*(tWidth-1))*6] = (x+1)+(y+1) * tWidth; 
				indices[(x+y*(tWidth-1))*6+1] = (x+1)+y * tWidth; 
				indices[(x+y*(tWidth-1))*6+2] = x+y * tWidth; 

				indices[(x+y*(tWidth-1))*6+3] = (x+1)+(y+1) * tWidth; 
				indices[(x+y*(tWidth-1))*6+4] = x+y * tWidth; 
				indices[(x+y*(tWidth-1))*6+5] = x+(y+1) * tWidth; 
			} 
		} 

		// Create vertices 
		size_t vertex_size = tWidth * tHeight; 
		float* vertices = new float[vertex_size*3]; 
		size_t index = 0; 
		for(size_t z = 0; z < tHeight; z++) 
		{ 
			for(size_t x = 0; x < tWidth; x++) 
			{ 
				Real height = offset.y + mTerrainInfo->at(x, z)*scale.y; 
				vertices[index + 0] = offset.x + x * scale.x; 
				vertices[index + 1] = offset.y + mTerrainInfo->at(x,z)*scale.y; 
				vertices[index + 2] = offset.z + z*scale.z; 
				index += 3; 
			} 
		} 
This code works! :)


Image
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 11:18 am

:D

If you still have any problems, I suggest you split up the terrain data into tiles (just like ETM does internally). I, myself, am not an expert for index and vertex buffers, but from what I remember from a few threads here their size is limited. So having the full terrain in a single piece may or may not get you into trouble (it probably will performance-wise, anyway).
0 x

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Post by jacmoe » Tue Jun 05, 2007 1:37 pm

For the TSM I create a collision mesh per tile, and I think it wouldn't be too problematic to do the same for ETM.
Yeah, it's a big performance hit - notice the framerate when running it through the visual debugger. :)
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

taktik
Gnoblar
Posts: 4
Joined: Tue Jun 05, 2007 2:00 pm

Help with the basics

Post by taktik » Tue Jun 05, 2007 2:19 pm

Hello, I'm really new to all of this, so I come to you with (what at first seemed) a simple question:

I made my terrain using the EarthSculptor application and want to load it with ETSM, here are the files I got:

0 ... 5.png - My textures
map.map - EarthSculptor project (an ascii file)
map.png - The heightmap
map_c0.png - I suppose this is the coverage map as you call it (I don't know what it's used for)
map_d0.png - This should be the detail (channel) map
map_l0.png - The lightmap (I think)

I know how to load the heightmap, but I have no idea how to load and apply the channel map and the textures, and also the lightmap. The material scrips and all other files from the demo don't make too much sense to me, so could you please explain their role and file names (where and when they're used in the code). It would be best if you provided some code, because I'm sure I'll get lost in the complicated explanations...

Here's what I have atm:

Code: Select all

void GameApp::createTerrain()
{
	ResourceGroupManager::getSingleton().addResourceLocation("../../media/rts", "FileSystem", "RTS", true);
	
	// Create terrain manager
	mTerrainMgr = new ET::TerrainManager(mSceneMgr);
    mTerrainMgr->setLODErrorMargin(2, mCamera->getViewport()->getActualHeight()); //why do we need this?
    //mTerrainMgr->setUseLODMorphing(true, 0.2, "morphFactor");

	// Load heightmap
	Image image;
	image.load("map.png", "RTS");

	ET::TerrainInfo info;
	ET::loadHeightmapFromImage(info, image);
    info.setExtents(AxisAlignedBox(0, 0, 0, 1500, 300, 1500)); 

    mTerrainMgr->createTerrain(info);
    
	// create the splatting manager
	mSplatMgr = new ET::SplattingManager("map_d0", "RTS", 512, 512);
    
	// specify number of splatting textures we need to handle
    mSplatMgr->setNumTextures(6);

	image.load("map_c0.png", "RTS");
	mSplatMgr->loadMapFromImage(0, image);
}
This actually doesn't display anything :(

Thanks in advance!
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 3:55 pm

You need to create a fitting material for the terrain, then pass the material to the TerrainManager. However, I'm not exactly sure what the different textures that EarthSculptor creates actually represent. I'll try to figure that out the next time I'm on Windows and can examine EarthSculptor :)
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 4:43 pm

Ok, just checked on EarthSculptor. map_d0.png is indeed a coverage map, but with 4 channels. So you need different shaders and a slightly different material. I've uploaded an example ensemble you can get here: http://downloads.oddbeat.de/earthsculptor.zip

Basically, you need to do something like this:

Code: Select all

// Load heightmap
   Image image;
   image.load("map.png", "RTS");

   ET::TerrainInfo info;
   ET::loadHeightmapFromImage(info, image);
    info.setExtents(AxisAlignedBox(0, 0, 0, 1500, 300, 1500));

    mTerrainMgr->createTerrain(info);
   
   // create the splatting manager
   mSplatMgr = new ET::SplattingManager("ETSplatting", "RTS", 512, 512, 4);
   
   // specify number of splatting textures we need to handle
    mSplatMgr->setNumTextures(4);

   image.load("map_d0.png", "RTS");
   mSplatMgr->loadMapFromImage(0, image); 


      // create a manual lightmap texture
      TexturePtr lightmapTex = TextureManager::getSingleton().createManual(
        "ETLightmap", "ET", TEX_TYPE_2D, 256, 256, 1, PF_BYTE_RGB);
      Image lightmap;
      ET::createTerrainLightmap(terrainInfo, lightmap, 256, 256, Vector3(1, -1, 1), ColourValue::White,
        ColourValue(0.3, 0.3, 0.3));
      lightmapTex->getBuffer(0, 0)->blitFromMemory(lightmap.getPixelBox(0, 0));

      // load the terrain material and assign it
      MaterialPtr material (MaterialManager::getSingleton().getByName("ETTerrainMaterial"));
      mTerrainMgr->setMaterial(material);
You will have to play a bit with the exact settings. Do check out the material script and adjust the names of your splatting textures.
The example code above creates a manual terrain lightmap. It's also possible to use the one provided by EarthSculptor, just remove the lightmap code from above and in the material script at the bottom, change the texture name to map_l0.png.
0 x

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
Contact:

Post by KungFooMasta » Tue Jun 05, 2007 6:01 pm

Sweet, Jacmoe got it working! Thanks for your help CABAlistic! I hope the FPS isn't so bad when the visual debugger is turned off, and program is in release mode.. otherwise I might have to try a tile approach like TSM (although I don't know how..)

The working code looks really similar to what I have.. maybe it's the Ogre::ManualObject class giving me trouble. I'm happy ETM collision is possible, anyway! :D
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 6:12 pm

Actually, I'm rather certain that you will have to split up the terrain (unless it's very small). After all, with one huge bunk of terrain data, Opcode can't pull away parts via bounding box checks (which are rather cheap) but probably needs to test the whole terrain for collision at polygon level. Probably not good for your performance ;)

But then again, splitting the terrain up should not be so hard. Just choose a tile size (like 33). Then create a single index buffer for all tiles and multiple vertex buffers for 33x33 vertices and create several collision shapes from them. The vertices need to overlap by one, i. e. the first terrain tile will go from [0,0] to [32,32], the next from [32,32] to [64,64] etc., otherwise you'd get gaps in the terrain.
0 x

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
Contact:

Post by KungFooMasta » Tue Jun 05, 2007 6:21 pm

Awesome, it seems like the code for TSM will be extremely similar to what we will do for ETM.

I see that TerrainInfo and TerrainManager don't tell us number of tiles or tilesize, what would be the correct way to derive these values?

Once again, thanks. Your willingness to help and provide information is another great feature of ETM! :D
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 6:24 pm

Choose whatever you like and gets the terrain covered completely. The tiling of your collision data does not need to match the one the ETM uses for display. In fact, in theory you don't even need to use a single size for the whole terrain (though tiles of various size probably don't make that much sense, heh).
0 x

User avatar
jacmoe
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 20570
Joined: Thu Jan 22, 2004 10:13 am
Location: Denmark
Contact:

Post by jacmoe » Tue Jun 05, 2007 6:58 pm

I see that you provide project files for use with the Ogre SDK - I need a set for source/CVS Ogre.
Consider providing two sets. I usually postfix their names with 'VC8_SDK' and 'VC8' (or 'VC8_SRC'). :)
You probably don't use VC8, so I can send the project files to you, if you want.
0 x
/* Less noise. More signal. */
Ogitor Scenebuilder - powered by Ogre, presented by Qt, fueled by Passion.
OgreAddons - the Ogre code suppository.

taktik
Gnoblar
Posts: 4
Joined: Tue Jun 05, 2007 2:00 pm

Post by taktik » Tue Jun 05, 2007 7:03 pm

@CABAListic:

Thanks for the fast reply, I really appreciate it, as well as ET :D (just need to learn to use it ;) )

I did as you suggested and it seems that it worked (cause the framerate dropped from ~125 to ~21 and the terrain isn't light gray any more), but now it's so dark that it's almost completely invisible (I can see some of it while moving the camera but it's almost black).

I tried both leaving and removing the lightmap code (and specifying my own in the material), but it didn't help. I have this in my createScene function

Code: Select all

createTerrain(); // the code here is almost identical to the one in your reply

mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

Light* l = mSceneMgr->createLight("MainLight");
l->setPosition(20, 80, 50); //camera is at (200, 200, 200), looking at(200, 0, 100) with FixedYawAxis(true, Vector3(0, 0, -1))
and it worked fine up until now.

Maybe there's a problem with the shader... (the ET demo works fine btw)

I hope these questions don't sound stupid, this is all new to me.
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 7:12 pm

Hm, I tested it locally with a sample from EarthSculptor, and it seemed fine. It's a bit darker than in EarthSculptor, but EarthSculptor was terribly overlighted anyway, imho :)

Anyway, the framerate drop seems a bit extreme. Is this debug or release build? Did you check the Ogre.log? Maybe it's missing a texture or something (which would also explain the fps drop).
0 x

taktik
Gnoblar
Posts: 4
Joined: Tue Jun 05, 2007 2:00 pm

Post by taktik » Tue Jun 05, 2007 7:34 pm

It's a debug build, within VS 2005. What's strange is that now fps is around 93 :?

Anyway, here's the log - everything seems ok to me.

I can upload my data/screenshots/test app source so you can see it for yourself, I have no idea what to do :(
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 7:39 pm

20:20:16: Error in material RTSTerrainMaterial at line 12 of RTSTerrain.material: Invalid vertex_program_ref entry - vertex program VSLodMorph2 has not been defined.
20:20:16: Error in material RTSTerrainMaterial at line 16 of RTSTerrain.material: Invalid fragment_program_ref entry - fragment program PSSplat2 has not been defined.
20:20:16: Error in material RTSTerrainMaterial at line 52 of RTSTerrain.material: Invalid vertex_program_ref entry - vertex program VSLodMorph2 has not been defined.
That's the problem. The names of the shader programs in the material are not correct. Curious though since it was working here. But anyway, please check how the shaders are named in the ETShader.program file and change it in the material script accordingly - I think, the correct names are ET/Programs/PSSplat2 or something similar.
0 x

taktik
Gnoblar
Posts: 4
Joined: Tue Jun 05, 2007 2:00 pm

Post by taktik » Tue Jun 05, 2007 7:52 pm

Oops :oops: Sorry, I was looking at the wrong log, but uploaded the right one and by the time I realized it... maybe you're too fast ;)

Thanks for helping, I'll correct the errors and try again :D

BTW I deleted the "ET/Programs/" from the cg files because I thought that was a path on your machine and I have all of these in the same folder. But, as I said, I'm very new to all this...

<edit>
It works :) and it's beautiful :D

I forgot to change the fragment program names in the .program file, that's why it didn't work.
</edit>
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Tue Jun 05, 2007 8:04 pm

Very good :D

BTW, I'd recommend you to make yourself comfortable with writing and understanding materials. It's not so difficult, but you'll need it soon enough ;) Also, a (very) basic understanding of shaders is very useful. I myself just learned the basics alongside writing ETM, hehe.
0 x

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
Contact:

Post by KungFooMasta » Wed Jun 06, 2007 3:11 am

I'm currently trying to set the groundwork for an OgreOpcode Terrain collision object for the ETM.

For the most part, we can derive the needed data so that we don't have to include ETM library. Would it be possible to make a function

Code: Select all

std::vector<float> getHeightmapData();
It sort of matches the "setHeightmap" function. This would mainly be a convenience method. (Otherwise we have to force users to store their heightmap source data (which TerrainInfo already does). If the source is an image, we have to re-write exactly what you've already written, to convert the heightmap into a list of floats)

The main reason for this is that we have to implement the equivalent of your TerrainInfo::at(x, z) function.
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Wed Jun 06, 2007 7:33 am

Sure, you can add it to TerrainInfo. Though, the correct function declaration should be like this:

Code: Select all

const std::vector<float>& getHeightmapData() const;
0 x

Fred
Halfling
Posts: 46
Joined: Thu Nov 02, 2006 11:06 pm
Location: Germany

Post by Fred » Wed Jun 06, 2007 9:42 am

The Demo doesn't run on my PC. There is an Error Message like this:
Cannot locate a resource grop is called "ET" for resource "brush.png" in ResourceGroupManager::openResourceAt::..\scr\OgreResourceGroupManager.cpp(line54)

But the code I've seen up to now looks quiete good.
I'll be able to use this lib in my next project.
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Wed Jun 06, 2007 1:24 pm

You need to add the media files provided inside the ZIP file to your resources.cfg. I think an according resources.cfg should be at least in bin/release, unless I forgot it. Otherwise, just add the resource dir to [ET] resource group.
0 x

Squirell
Gnoblar
Posts: 18
Joined: Sat Oct 28, 2006 9:34 pm

Post by Squirell » Wed Jun 06, 2007 9:45 pm

Any progress on figuring out whats wrong with using ETM with OpenGL? When I run things using the OpenGL renderer every other material in my scene gets messed up (and those in the demo do too it looks like). Direct3D9 works fine. I know your aware of the problem so unless you've figured out what causes it I was going to do some digging to see if I could help you out.

Other than that, great work, this is really useful.
0 x

CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
Contact:

Post by CABAListic » Wed Jun 06, 2007 9:58 pm

I had the problem posted in the Help forum, and so far it's probably a bug in the OpenGL renderer (at least I'm not aware of anything that I'd do wrong).

However, you can definitely use ETM with OpenGL, just don't use the 6 splatting texture shader I provided as an example. In fact, in ETShader.program you can remove arbfp1 from the profiles line from PSSplat2, and then the demo material will fall back to a shader 1.1 version which works just fine with OpenGL. Therefore, it's more a bug with shaders and OpenGL...
0 x

Squirell
Gnoblar
Posts: 18
Joined: Sat Oct 28, 2006 9:34 pm

Post by Squirell » Thu Jun 07, 2007 12:38 am

Very cool, thank you
0 x

User avatar
KungFooMasta
OGRE Contributor
OGRE Contributor
Posts: 2087
Joined: Thu Mar 03, 2005 7:11 am
Location: WA, USA
Contact:

Post by KungFooMasta » Thu Jun 07, 2007 2:24 am

I made an incredibly huge modifcation to the ETM Library:

Code: Select all

/** Gets an array of floats representing heightmap for terrain. */
	const std::vector<float>& getHeightmapData() const { return mHeightmap; }
:D

Now OgreOpcode can make ETM terrain into a TerrainShape without linking to the ETM library. (TerrainShape not implemented, but pretty much setup)

Not having luck with getting Tiles working.. still trying things out. Vertices and Indices just aren't my thing.
0 x

Post Reply