Page 7 of 21

Posted: Tue Jun 05, 2007 7:49 am
by jacmoe

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


Posted: Tue Jun 05, 2007 11:18 am
by CABAListic

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

Posted: Tue Jun 05, 2007 1:37 pm
by jacmoe
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. :)

Help with the basics

Posted: Tue Jun 05, 2007 2:19 pm
by taktik
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 - 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)); 

	// create the splatting manager
	mSplatMgr = new ET::SplattingManager("map_d0", "RTS", 512, 512);
	// specify number of splatting textures we need to handle

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

Thanks in advance!

Posted: Tue Jun 05, 2007 3:55 pm
by CABAListic
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 :)

Posted: Tue Jun 05, 2007 4:43 pm
by CABAListic
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:

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

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

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

Posted: Tue Jun 05, 2007 6:01 pm
by KungFooMasta
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

Posted: Tue Jun 05, 2007 6:12 pm
by CABAListic
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.

Posted: Tue Jun 05, 2007 6:21 pm
by KungFooMasta
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

Posted: Tue Jun 05, 2007 6:24 pm
by CABAListic
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).

Posted: Tue Jun 05, 2007 6:58 pm
by jacmoe
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.

Posted: Tue Jun 05, 2007 7:03 pm
by taktik

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.

Posted: Tue Jun 05, 2007 7:12 pm
by CABAListic
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).

Posted: Tue Jun 05, 2007 7:34 pm
by taktik
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 :(

Posted: Tue Jun 05, 2007 7:39 pm
by CABAListic
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.

Posted: Tue Jun 05, 2007 7:52 pm
by taktik
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...

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.

Posted: Tue Jun 05, 2007 8:04 pm
by CABAListic
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.

Posted: Wed Jun 06, 2007 3:11 am
by KungFooMasta
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.

Posted: Wed Jun 06, 2007 7:33 am
by CABAListic
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;

Posted: Wed Jun 06, 2007 9:42 am
by Fred
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.

Posted: Wed Jun 06, 2007 1:24 pm
by CABAListic
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.

Posted: Wed Jun 06, 2007 9:45 pm
by Squirell
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.

Posted: Wed Jun 06, 2007 9:58 pm
by CABAListic
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...

Posted: Thu Jun 07, 2007 12:38 am
by Squirell
Very cool, thank you

Posted: Thu Jun 07, 2007 2:24 am
by KungFooMasta
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; }

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.