Had to make some modifications to get it working, but finally it is done!

Video working on 100 terrains:
http://www.youtube.com/watch?v=CnODODp4feg

around one second for all of the following:
-generating random height data (diamond-square algorithym) for 100 terrains.
-splicing 100 terrains
-ent_updtatehull x100
-ent_fixnormals x100
-4 corner normal fix for shadows 4x100 = 400 function calls
-4 edge normal fix for shadows 4x100 function calls

around 32 seconds just for this:
painting 100 512x512 textures...

Painting was incredibly slow, I heavily modified my painting function to optimize as much as I could. I don't think I can make it faster than it is now though (32 secs for 100 512x512 textures). Any suggestions are welcome to help me speed things up.
Click to reveal..
HEIGHT FUNCTION:
Code:
var get_height(var Px, var Py, int SW, ENTITY* Terrain)
{
	//P = point that we want the height of (x,y,0)
	//SW = vertex number of terrain ent closest towards the lower left corner of the square
	//Terrain we are calculating for
	
	
	VECTOR P;
	//TRANSFORM SKIN PIXEL COORDS TO LOCAL ENT COORD SYSTEM
	vec_set(P,vector(Px,Py,0));
	P.x-= 256;
	P.y = 256-P.y;
	
	
	CONTACT* c1;
	VECTOR Triangle[3];
	VECTOR temp_vec;
	ANGLE temp_ang;
	VECTOR Director[2];
	
	VECTOR formula;
	var ind_term;
	
	//retrieve first point of containing triangle (base corner)
	c1= ent_getvertex(Terrain,NULL,SW);
	Triangle[0].x=c1.v.x;
	Triangle[0].y=c1.v.z;
	Triangle[0].z=c1.v.y;
	
	//retrieve second point of containing triangle (diagonal to base)
	c1= ent_getvertex(Terrain,NULL,SW-32);
	Triangle[1].x=c1.v.x;
	Triangle[1].y=c1.v.z;
	Triangle[1].z=c1.v.y;
	
	//determine third point of containing triangle (varying point)
	vec_set (temp_vec, P);
	vec_sub (temp_vec,Triangle[0].x);
	vec_to_angle (temp_ang.pan,temp_vec);
	
	//retrieve third point of containing triangle (varying point)
	if(temp_ang.pan>45)
	{
		c1= ent_getvertex(Terrain,NULL,SW-33);
	}
	else
	{
		c1= ent_getvertex(Terrain,NULL,SW+1);
	}
	Triangle[2].x=c1.v.x;
	Triangle[2].y=c1.v.z;
	Triangle[2].z=c1.v.y;
	
	//calculate the triangle's plane normal for the formula coeficients
	vec_set(Director[0],Triangle[1]);
	vec_sub(Director[0],Triangle[0]);
	vec_set(Director[1],Triangle[2]);
	vec_sub(Director[1],Triangle[0]);
	vec_cross(formula,Director[0],Director[1]);
	//set the independant term of the formula
	ind_term=(-1*formula.x*Triangle[0].x)+(-1*formula.y*Triangle[0].y)+(-1*formula.z*Triangle[0].z);
	//calculate our point's height plugging our values into the formula
	P.z=(-1*((formula.x*P.x)+(formula.y*P.y)+ind_term))/formula.z;
	return(P.z);
}



TERRAIN PAINTING FUNCTION:
Code:
void Terrain_Paint(int x, int y)
{
	//wait(1);
	
	ENTITY* Terr = Terrain[x][y];
	int i; //vertex info for terrain
	
	BMAP* Source_BM;
	//BMAP* NewSkin = bmap_createblack(512,512,24);
	BMAP* NewSkin = bmap_create("Terrain_Sand.tga");
	BMAP* OldSkin;
	//bmap_for_entity (Terr,Terr.frame);
	VECTOR Pixel_pos; //pixel coordinates for skin bmap
	
	var height;
	var slope;
	
	var pixel_source; var pixel_dest;
	//var t_format1; var t_format2;
	COLOR* t_color; var t_alpha; 
	
	t_format1=bmap_lock(NewSkin,0);
	
	//	t_format2=bmap_lock(Sand_BM,0);
	//	t_format2=bmap_lock(Grass_BM,0);
	//	t_format2=bmap_lock(Rock_BM,0);
	//	t_format2=bmap_lock(Snow_BM,0);

	for(Pixel_pos.y=0;Pixel_pos.y<512;Pixel_pos.y++)
	{
		for(Pixel_pos.x=0;Pixel_pos.x<512;Pixel_pos.x++)
		{
			//              (0to31)+1          (((0to31)+1)*33)+1
			
			i = (integer((Pixel_pos.x)/16)+1) + (((integer((Pixel_pos.y)/16)+1)*33));
			height = get_height(Pixel_pos.x,Pixel_pos.y,i,Terr);
			//slope = get_slope(Pixel_pos.x,Pixel_pos.y,i,Terr);
			
			if(height>16)
			{
				if(height<=16)//sand
				{
					Source_BM=Sand_BM;
				}
				else if(height<75)//grass
				{
					Source_BM=Grass_BM;
				}
				else if(height<150)//stone
				{
					Source_BM=Rock_BM;
				}
				else//snow
				{
					Source_BM=Snow_BM;
				}
			pixel_source = pixel_for_bmap(Source_BM,Pixel_pos.x,Pixel_pos.y);
			t_color = pixel_to_vec(NULL, t_alpha ,t_format2,pixel_source);
			
			//paint pixel on selected terrain's texture
			pixel_dest=pixel_for_vec(t_color,t_alpha,t_format1);
			pixel_to_bmap(NewSkin,Pixel_pos.x,Pixel_pos.y,pixel_dest);
		}
		
		//bmap_unlock(Source_BM);
	}
	
}

//	bmap_unlock(Sand_BM);
//	bmap_unlock(Grass_BM);
//	bmap_unlock(Rock_BM);
//	bmap_unlock(Snow_BM);

bmap_unlock(NewSkin);
OldSkin=ent_getskin(Terr,1);
ptr_remove(OldSkin);
ent_setskin(Terr,NewSkin,1);
}



Call Example:
Code:
var t_format1; var t_format2;


t_format2=bmap_lock(Sand_BM,0);
t_format2=bmap_lock(Grass_BM,0);
t_format2=bmap_lock(Rock_BM,0);
t_format2=bmap_lock(Snow_BM,0);
for(x=0;x<TERRAIN_COUNT;x++)
{
	for(y=0;y<TERRAIN_COUNT;y++)
	{			
		Terrain_Paint(x,y);
		wait(1);
	}
}
wait_for(Terrain_Paint);
bmap_unlock(Sand_BM);
bmap_unlock(Grass_BM);
bmap_unlock(Rock_BM);
bmap_unlock(Snow_BM);



Turns out bmap_lock & bmap_unlock calls were making my paint function extremely slow. I don't have an exact number, but believe me, EXTREMELY slow.
I used to lock a bmap when i draw a pixel, then unlock (per pixel) since i might not need that same texture for the next pixel, so I would only lock each texture while I'm using it. With that version I never saw the completion of a terrain (waited several minutes) before closing realizing something was terribly wrong or terribly slow...
After that I moved the bmap_lock in my painter function before the loops and just locked all of them before hand, and moved the bmap_unlock after the loops, so they were locked and unlocked only once per terrain function. (lock*4 + unlock*4)*100 terrains = 1600 lock/unlock calls. This time I did manage to see the terrains painted after several minutes, but these times were still unacceptable.
So I decided to move the lock/unlock calls out of my painter function. they are called once before painting ALL terrains consecutively, and called the unlocks after ALL terrains have painted.

There have been more tweaks for speed, but lock/unlock seem to be what had the most impact on speed.

hope this experience is a usefull warning for anyone using these functions when they attempt to paint several large textures. An example of the calls and the paint function are in the spoiler above.

Also the height detection function was not working correctly, an updated version is also in the spoiler.

I had also programmed separate cliff textures to be drawn on steep angles, but they didn't blend well with the rest no matter what textures I used. The overall look was terrible so I removed that code.

@EvilSOB: even though you don't like calculating height between vertex, i hope this will help you out when you get to painting. The problem with random terains is that you can't have a pre-made texture looking good on it due to its randomness. And infinite worlds benefit greatly from randomized terrains. In my first attempt at painting I coloured each polygon entirely based on the average height of it's vertexs, and believe me it looks horrible. At least if you decide to take this route you have a head start wink


I have another question regarding this memory problem we are working around... Does this also include textures? I mean, if I remove textures with ptr_remove(BMAP) and create new ones with bmpa_create will that also leave behind unused texture memory and end up growing till the system is saturated like with models?



"The more you know, the more you realize how little you know..."

I <3 HORUS
http://www.opserver.de/ubb7/ubbthreads.php?ubb=showflat&Number=401929&page=1