I wasnt aware there was any portal system in the db engine EXCEPT when dealing with BSP, they are obviously bsp portals and bsp isnt very good
If you fill a terrain with lots of objects it will surely grind, you will have to look after this type of thing yourself. You can indeed set the max draw range of the camera using
dbSetCameraRange ( float fNear, float fFar )
Near being the minium distance to draw and far being the furthest. 1 is the default minium, I recommend keeping that as 1. 3000 you can set to whatever you like, as far as im aware it works in db units - play for a good result.
However, unless you create your levels with your max draw distance in mind (lots of corners, turns, etc) then you will see a nasty "edge" of the world thing going on. One way to combat this is to enable fogging (dbFogOn()), setting the fogging distance to say 5 units smaller than the camera range (dbFogDistance(fDistance)) and colouring the fog the same colour as the backdrop (dbFogColor(iCol)). This creates a nice smoothing between the fog and the backdrop and is much easier on the eyes than just a sudden edge of the world. I find it doesnt work too well if the fog isnt the same colour as the backdrop though, you can colour the backdrop with dbColorBackdrop() - note I can never remember wether dgsdk uses the word Color or Colour so if one command doesnt work try the other version of the word
Again, however, if you are intending to put in lots of things like grass etc then chances are you want a different draw distance on the grass/trees than you do the actual world - thats how it works in most games I see.
What you want to do there is create some sort of handler (function or class) to look after vegitation. When you add a peice of grass to the world have it add the object id of that grass to an array which holds all the info about it. Then write a function called something like CalculateVegitation() or something which takes the player position and calculates which vegitiation should be shown or hidden.
you will want to run through all the grass etc using a for loop and do a few checks. On the simplest of levels the first thing you want to do is check if its even on screen - you can use dbObjectInScreen(object_id) to see if it is. If it isnt then its behind you or something and you can happily call dbHideObject() on it to get some of your FPS back. The 2nd check I would do is a distance check. You want to decide the maxium distance you will draw vegitation in, turn it into a constant like MAX_GRASS_DRAW or something. Then use a distance check like this:
float Get3dDistance(float x1, float y1, float z1, float x2, float y2, float z2) {
return (float) fsqrt(((x2 - x1)*(x2 - x1)) + ((y2 - y1)*(y2 - y1)) + ((z2 - z1)*(z2 - z1)));
}
double fsqrt(double r) {
double x,y;
double tempf;
unsigned long *tfptr = ((unsigned long *)&tempf)+1;
tempf = r;
*tfptr=(0xbfcd4600-*tfptr)>>1;
x=tempf;
y=r*0.5;
x*=1.5-x*x*y;
x*=1.5-x*x*y;
x*=1.5-x*x*y;
x*=1.5-x*x*y;
return x*r;
}
to check if the distance between the vegitations position and the player's is within the limit - if so then show the object, if not then hide it. This will get you alot of speed.
Note - i included my fsqrt function for the distance check which performs a much faster square root operation making the distance check less intensive - however it may still be faster to use vecter maths - I never have and havnt researched it but its something im going to have to do in the future
Par from that it all depends on your game what other types of optimisations you want to make. Maybe you could make a MAX_VEG constant so you only draw a maxium amount of vegitation regardless of how close to you it all is, I dunno.
Hope all that helps