Blitting multiple Bitmaps with transparent parts?

Posted By: Espér

Blitting multiple Bitmaps with transparent parts? - 07/03/11 15:01

hi there..

i´m trying to create a heightmap generator.. for this, i create a black bitmap, and tried to blit (for testing) white circles on it..
But all i get is:

http://www.imagesload.net/img/shot_099.jpg

The Code:
Click to reveal..
Code:
#include <acknex.h>
#include <default.c>


BMAP* map;
BMAP* plain_tile_a = "plain.tga";

var plaincount = 0;

PANEL* viewer =
{
	layer = 1;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

PANEL* infos =
{
	pos_x = 1024;
	pos_y = 50;
	layer = 99999;
	digits(0, 0, "Bitmapcount = %.0f", *, 1, plaincount);
	flags = SHOW | TRANSLUCENT;
}



void main()
{
	video_mode = 9;
	level_load(NULL);
	wait(3);
	
	map = bmap_createblack(2048, 2048, 32);
	bmap_fill(map, vector(1,1,1), 100);
	viewer.bmap = map;
	viewer.scale_x = 0.35;
	viewer.scale_y = 0.35;
	
	plaincount = 0;
	
	while(plaincount < 500)
	{
		bmap_blit(map, plain_tile_a, vector(random(2048), random(2048), 0), vector(random(512), random(512), 0));
		plaincount += 1;
		wait(1);
	}
}



The problem: The Bitmaps are not blit one above the other.. they just overwrite each other..

I´ve no clue how to change that ._.
Posted By: HeelX

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 18:01

Stupid question: does your bitmap contain an alpha channel?
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 18:03

yes...

When i use a TGA without Alpha.. or as 24Bit.. it just blits white plains...
when i use a png instead of TGA.. same problem as before.. no overlaying..
Posted By: hopfel

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 19:51

I don't know if it could work with bmap_blit, but you could write a function which writes pixel for pixel,
then you could check for every pixel also, if there's a pixel under it which shouldn't be replaced.

Well, would be a much bigger code, but it works! ^-^
Posted By: Pappenheimer

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 19:56

Maybe, this helps. Its about pixel_to_bmap:
http://www.opserver.de/ubb7/ubbthreads.p...true#Post348321
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 20:03

it´s not that it shouldn´t be replaced.. it should blend over it.
Posted By: WretchedSid

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 20:31

You have to do the blending yourself by multiplying the alpha with the rgb values and then adding the result to the previous pixel.
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 20:42

means something like:

1. reading pixel X/Y
2. reading minibitmap pixel A/B
3. calculating:
Code:
pixel_X/Y.red + pixel_A/B.red
pixel_X/Y.green + pixel_A/B.green
pixel_X/Y.blue + pixel_A/B.blue


4. next pixel

?

if yes... WHY?!
I´ve 123 Heightmap parts (mountains, cliffs..etc).. so i need to lock 124 bitmaps (the parts + the ground), just to read a random part out..?

._.
Posted By: Shadow969

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 21:39

before adding pixel_A/B color you have to multiply it with A/B alpha value as Sid has already said. besides you don't have to lock all of your heightmap parts at once - just lock em one by one.
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 21:43

ok.. the function at the moment:

Code:
var littleformat;
		var bigformat;
		var pixel;
		var pixel2;
		COLOR* temp;
		COLOR* temp2;
		var position[2];
		position[0] = random(2048);
		position[1] = random(2048);
		
		bigformat = bmap_lock(map, 0);
		while(plainmax != 0 && plaincount < plainmax)
		{
			
			var breite = bmap_width(plain_tile);
			var hoehe = bmap_height(plain_tile);
			
			littleformat = bmap_lock(plain_tile, 0);
			var a = 0;
			var b = 0;
			for(a = 0; a<breite; a++)
			{
				for(b = 0; b<breite; b++)
				{
					if(position[0]+a < breite && position[0]+a > 0 && position[1]+b < hoehe && position[1]+b > 0)
					{
						pixel = pixel_for_bmap(plain_tile, a, b);
						pixel_to_vec(temp,100,8888,pixel);
						
						pixel2 = pixel_for_bmap(map, position[0]+a, position[1]+b);
						pixel_to_vec(temp2,100,8888,pixel2);
						
						vec_add(temp2, temp);
						
						pixel = pixel_for_vec(temp2,100,8888);
						
						
						pixel_to_bmap(map,position[0]+a,position[1]+b,pixel);
					}
				}
				wait(1);
			}
			
			
			
			bmap_unlock(plain_tile);
			plaincount += 1;
			wait(1);
		}
		bmap_unlock(map);
	}


It makes.. nothing.. means: i can´t see anything ._.


Multiplying what alpha???
(plan = the heightmap part, map = the ground)
Posted By: Shadow969

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 21:49

if you'll make a small testlevel and upload it somewhere - i'll take a look
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 21:53

Here you go:
http://nakoon-game.de/Nakoon_Game/Artworks/Archives/HEIGHTMAP%20GENERATOR.rar


Edit:
Updated the file.. now it contains the random-image code.
Posted By: Shadow969

Re: Blitting multiple Bitmaps with transparent parts? - 07/03/11 23:07



i've stripped the code to the bare minimum, to show the basic principle. it's heavily commented and not optimised to make it easier to understand. here it is

Code:
#include <acknex.h>
#include <default.c>

//bitmap to be generated
BMAP* map;

//tile bmaps
BMAP* tile1 = "plain001.tga";
BMAP* tile2 = "plain002.tga";

//display for our bitmap
PANEL* viewer =
{
	pos_x = 5;
	pos_y = 5;
	layer = 10;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

//small utility function to ensure vector components are smaller than a certain value
void vec_trunc(var *vec, var limit)
{
	vec[0] = minv(vec[0], limit);
	vec[1] = minv(vec[1], limit);
	vec[2] = minv(vec[2], limit);
}

//adds feature bitmap to the map at the (X,Y) position. you have to manually lock and unlock bitmaps
void add_bmap(var X, var Y, BMAP *map, var map_format, BMAP *feature, var feature_format)
{
	var temp_map_pixel[3];
	var temp_feature_pixel[3];
	var temp_map_alpha;
	var temp_feature_alpha;

	var i, j;
	for(i = 0; i < bmap_width(feature); i++)
	{
		for(j = 0; j < bmap_height(feature); j++)
		{
			//ensure we stay within main bitmap bounds to prevent engine crashing
			if(X+i >= bmap_width(map) || Y+j >= bmap_height(map)) continue;
			
			//read map pixel
			pixel_to_vec(temp_map_pixel, temp_map_alpha, map_format, pixel_for_bmap(map, X+i, Y+j));
			//read feature pixel
			pixel_to_vec(temp_feature_pixel, temp_feature_alpha, feature_format, pixel_for_bmap(feature, i, j));
			
			//color mixing in 3 steps
			//1.multiply feature pixel's color with normalized alpha
			vec_scale(temp_feature_pixel, temp_feature_alpha/100);
			//2.add resulting color to the map pixel's color
			vec_add(temp_map_pixel, temp_feature_pixel); 
			//3.check that resulting vector components stay within 0-255 range
			vec_trunc(temp_map_pixel, 255);
			
			//write the resulting color to the map
			pixel_to_bmap(map, X+i, Y+j, pixel_for_vec(temp_map_pixel, temp_map_alpha, map_format));
		}
	}
}

void main()
{
	level_load(NULL);
	wait(3);
	
	//create a blank map
	map = bmap_createblack(512, 512, 32);
	bmap_fill(map, vector(1,1,1), 100);
	viewer.bmap = map;
	
	var i;//our index var

	//lock main bitmap
	var map_format = bmap_lock(map, 0);

	//lock first feature bitmap - called only once instead of locking\unlocking bitmap every time
	var feature_format = bmap_lock(tile1, 0);
	
	//add 20 features at random positions
	for(i = 0; i < 20; i++)
	{
		add_bmap(random(bmap_width(map)), random(bmap_height(map)), map, map_format, tile1, feature_format);
	}
	
	//we're done with first feature - can unlock it's bitmap
	bmap_unlock(tile1);
	
	//do the same routine for the second feature type
	var feature_format = bmap_lock(tile2, 0);
	
	for(i = 0; i < 20; i++)
	{
		add_bmap(random(bmap_width(map)), random(bmap_height(map)), map, map_format, tile2, feature_format);
	}
	
	bmap_unlock(tile2);
	
	//unlock main bitmap
	bmap_unlock(map);
}



btw your images seem to have a blank alpha channel, so i've made my own dummies. i can upload them somewhere if you want
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/04/11 05:50

no need for your images...
i've problems to understand the code now .__.
perhaps i'm a bit tired..
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/04/11 10:04

okay.. tried to implement that to my code..
Click to reveal..
Code:
#include <acknex.h>
#include <d3d9.h>
#include <default.c>


BMAP* map;
BMAP* plain_tile = "plain001.tga";

var plaincount = 0;
var plainmax = 500;
var active   = 0;
int pixelcount = 0;
var position[3];
var groundsize = 2048;

STRING* wort = "BILDMENGE ANGEBEN\noder ESC um den Generator\nzu beenden:";
STRING* input = "   ";
STRING* bitmapname = "Plain";
STRING* bitmapnumb = "1";

FONT* arial = "Arial#15";

PANEL* viewer =
{
	pos_x = 5;
	pos_y = 5;
	layer = 10;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

PANEL* infos =
{
	pos_x = 730;
	pos_y = 50;
	layer = 99990;
	alpha = 100;
	digits(5, 5,  "INFOS:", arial, 1, 0);
	digits(5, 15, "^^^^^^", arial, 1, 0);
	digits(5, 25, "<> Bitmapcount = %.0f", arial, 1, plaincount);
	digits(132, 25, "/", arial, 1, 0);
	digits(140, 25, 4, arial, 1, plainmax);
	digits(5, 115, "PLAIN NAME:", arial, 1, 0);
	digits(5, 127, bitmapname, arial, 1,0);
	digits(5, 145, "PIXELS SET:", arial, 1, 0);
	digits(5, 157, 10, arial, 1,pixelcount);
	flags = SHOW | TRANSLUCENT;
}
PANEL* frames =
{
	pos_x = 0;
	pos_y = 0;
	layer = 1;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

TEXT* txt_input =
{
	pos_x = 735;
	pos_y = 95;
	layer = 99999;
	alpha = 100;
	font = arial;
	string(wort, input);
	flags = SHOW | TRANSLUCENT;
}


void vec_trunc(var *vec, var limit)
{
	vec[0] = minv(vec[0], limit);
	vec[1] = minv(vec[1], limit);
	vec[2] = minv(vec[2], limit);
}


void main()
{
	video_mode = 8;
	d3d_antialias = 9;
	wait(1);
	video_window(NULL, NULL, (2+16), "Heightmap Generator");
	vec_set(sky_color, vector(1,1,1));
	vec_set(screen_color, vector(1,1,1));
	level_load(NULL);
	wait(3);
	
	map = bmap_createblack(groundsize, groundsize, 32);
	bmap_fill(map, vector(50,50,50), 100);
	viewer.bmap = map;
	frames.bmap = bmap_createblack(726, 726, 24);
	bmap_fill(frames.bmap, vector(255,255,255), 100);
	if(groundsize >= 2048)
	{
		viewer.scale_x = 0.35;
		viewer.scale_y = 0.35;
	}
	
	plaincount = 0;
	
	var randompic = 1;
	var little_format;
	var big_format;
	var alphablend;
	var alphablend2;
	var temp[3];
	var temp2[3];
	var a = 0;
	var b = 0;
	
	while(1)
	{
		str_cpy(wort, "BILDMENGE ANGEBEN\noder ESC um den generator\nzu beenden:");
		str_cpy(input, "   ");
		inkey(input);
		while(inkey_active != 0)
		{wait(1);}
		
		if(str_cmpi(input, "esc"))
		{break;}
		
		str_cpy(wort, "GEWÄHLTE BILDMENGE:");
		plainmax = str_to_num(input);
		map = bmap_createblack(groundsize, groundsize, 32);
		bmap_fill(map, vector(50,50,50), 100);
		viewer.bmap = map;
		pixelcount = 0;
		plaincount = 0;
		
		
		big_format = bmap_lock(map, 0);
		while(plainmax != 0 && plaincount < plainmax)
		{
			str_cpy(bitmapname, "Plain");
			str_cpy(bitmapnumb, "111");
			randompic = integer(random(3)+1);
			if(randompic < 10){str_cat(bitmapname, "00");}
			else if(randompic < 100){str_cat(bitmapname, "0");}
			str_for_num(bitmapnumb, randompic);
			str_cat(bitmapname, bitmapnumb);
			str_cat(bitmapname, ".tga");
			plain_tile = bmap_create(bitmapname);
			
			position[0] = random(bmap_width(map));
			position[1] = random(bmap_width(map));
			position[2] = 0;
			wait(1);
			little_format = bmap_lock(plain_tile, 0);
			for(a = 0; a<bmap_width(plain_tile); a++)
			{
				for(b = 0; b<bmap_height(plain_tile); b++)
				{
					if(position[0]+a >= bmap_width(map) || position[1]+b >= bmap_height(map)) continue;
					
					//read map pixel
					pixel_to_vec(temp, alphablend, big_format, pixel_for_bmap(map, position[0]+a, position[1]+b));
					//read feature pixel
					pixel_to_vec(temp2, alphablend2, little_format, pixel_for_bmap(plain_tile, a, b));
					
					//color mixing in 3 steps
					//1.multiply feature pixel's color with normalized alpha
					vec_scale(temp2, alphablend2/100);
					//2.add resulting color to the map pixel's color
					vec_add(temp, temp2); 
					//3.check that resulting vector components stay within 0-255 range
					vec_trunc(temp, 255);
					
					//write the resulting color to the map
					pixel_to_bmap(map, position[0]+a, position[1]+b, pixel_for_vec(temp, alphablend, big_format));
					pixelcount += 1;
				}
			}
			bmap_unlock(plain_tile);
			plaincount += 1;
		}
		wait(1);
		bmap_unlock(map);
	}
	sys_exit("");
}



But all it does is:
- create 1 mini circle
- run the complete loop but draw nothing more.

so.. it just creates 1 little circle ._.
doesn´t matter how many times the while loop runs through..
Posted By: Shadow969

Re: Blitting multiple Bitmaps with transparent parts? - 07/04/11 20:38

you had some logic errors in your code, for example you've recreated map every heightmap recalculation and filled it at wrong time. besides, you load the feature bitmap for every feature, instead of loading all features of type 'a' first, and the features of other types later. i've fixed the errors to make your code work, but you should redesign the structure of your program

Code:
#include <acknex.h>
#include <d3d9.h>
#include <default.c>


BMAP* map;
BMAP* plain_tile = "plain001.tga";

var plaincount = 0;
var plainmax = 500;
var active   = 0;
int pixelcount = 0;
var position[3];
var groundsize = 2048;

STRING* wort = "BILDMENGE ANGEBEN\noder ESC um den Generator\nzu beenden:";
STRING* input = "   ";
STRING* bitmapname = "Plain";
STRING* bitmapnumb = "1";

FONT* arial = "Arial#15";

PANEL* viewer =
{
	pos_x = 5;
	pos_y = 5;
	layer = 10;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

PANEL* infos =
{
	pos_x = 730;
	pos_y = 50;
	layer = 99990;
	alpha = 100;
	digits(5, 5,  "INFOS:", arial, 1, 0);
	digits(5, 15, "^^^^^^", arial, 1, 0);
	digits(5, 25, "<> Bitmapcount = %.0f", arial, 1, plaincount);
	digits(132, 25, "/", arial, 1, 0);
	digits(140, 25, 4, arial, 1, plainmax);
	digits(5, 115, "PLAIN NAME:", arial, 1, 0);
	digits(5, 127, bitmapname, arial, 1,0);
	digits(5, 145, "PIXELS SET:", arial, 1, 0);
	digits(5, 157, 10, arial, 1,pixelcount);
	flags = SHOW | TRANSLUCENT;
}
PANEL* frames =
{
	pos_x = 0;
	pos_y = 0;
	layer = 1;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

TEXT* txt_input =
{
	pos_x = 735;
	pos_y = 95;
	layer = 99999;
	alpha = 100;
	font = arial;
	string(wort, input);
	flags = SHOW | TRANSLUCENT;
}


void vec_trunc(var *vec, var limit)
{
	vec[0] = minv(vec[0], limit);
	vec[1] = minv(vec[1], limit);
	vec[2] = minv(vec[2], limit);
}


void main()
{
	video_mode = 8;
	d3d_antialias = 9;
	wait(1);
	video_window(NULL, NULL, (2+16), "Heightmap Generator");
	vec_set(sky_color, vector(1,1,1));
	vec_set(screen_color, vector(1,1,1));
	level_load(NULL);
	wait(3);
	
	map = bmap_createblack(groundsize, groundsize, 32);
	bmap_fill(map, vector(50,50,50), 100);
	viewer.bmap = map;
	frames.bmap = bmap_createblack(726, 726, 24);
	bmap_fill(frames.bmap, vector(255,255,255), 100);
	if(groundsize >= 2048)
	{
		viewer.scale_x = 0.35;
		viewer.scale_y = 0.35;
	}
	
	plaincount = 0;
	
	var randompic = 1;
	var little_format;
	var big_format;
	var alphablend;
	var alphablend2;
	var temp[3];
	var temp2[3];
	var a = 0;
	var b = 0;
	
	map = bmap_createblack(groundsize, groundsize, 32);
	bmap_fill(map, vector(50,50,50), 100);
	viewer.bmap = map;
	
	while(1)
	{
		str_cpy(wort, "BILDMENGE ANGEBEN\noder ESC um den generator\nzu beenden:");
		str_cpy(input, "   ");
		inkey(input);
		while(inkey_active != 0)
		{wait(1);}
		
		if(str_cmpi(input, "esc"))
		{break;}
		
		str_cpy(wort, "GEWÄHLTE BILDMENGE:");
		plainmax = str_to_num(input);
		
		pixelcount = 0;
		plaincount = 0;
		
		bmap_fill(map, vector(50,50,50), 100);

		big_format = bmap_lock(map, 0);
		
		while(plainmax != 0 && plaincount < plainmax)
		{
			if(random(10) > 5) plain_tile = bmap_create("plain001.tga");//i've changed this part too
			else plain_tile = bmap_create("plain002.tga");
			
			position[0] = random(bmap_width(map));
			position[1] = random(bmap_width(map));
			position[2] = 0;

			little_format = bmap_lock(plain_tile, 0);
			for(a = 0; a<bmap_width(plain_tile); a++)
			{
				for(b = 0; b<bmap_height(plain_tile); b++)
				{
					if(position[0]+a >= bmap_width(map) || position[1]+b >= bmap_height(map)) continue;
					
					//read map pixel
					pixel_to_vec(temp, alphablend, big_format, pixel_for_bmap(map, position[0]+a, position[1]+b));
					//read feature pixel
					pixel_to_vec(temp2, alphablend2, little_format, pixel_for_bmap(plain_tile, a, b));
					
					//color mixing in 3 steps
					//1.multiply feature pixel's color with normalized alpha
					vec_scale(temp2, alphablend2/100);
					//2.add resulting color to the map pixel's color
					vec_add(temp, temp2); 
					//3.check that resulting vector components stay within 0-255 range
					vec_trunc(temp, 255);
					
					//write the resulting color to the map
					pixel_to_bmap(map, position[0]+a, position[1]+b, pixel_for_vec(temp, alphablend, big_format));
					pixelcount += 1;
				}
			}
			bmap_unlock(plain_tile);
			plaincount += 1;
		}
		wait(1);
		bmap_unlock(map);
	}
	sys_exit("");
}


Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 07/04/11 20:47

That´s cause i will use now 144 different feature bitmaps.. means.. i need them absolutely randomized.. so i need them to be changed for every drawing...

means: i need that codepart:
Code:
str_cpy(bitmapname, "Plain");
			str_cpy(bitmapnumb, "111");
			randompic = integer(random(3)+1);
			if(randompic < 10){str_cat(bitmapname, "00");}
			else if(randompic < 100){str_cat(bitmapname, "0");}
			str_for_num(bitmapnumb, randompic);
			str_cat(bitmapname, bitmapnumb);
			str_cat(bitmapname, ".tga");
			plain_tile = bmap_create(bitmapname);



But it works now.. thanks ^^
Posted By: WretchedSid

Re: Blitting multiple Bitmaps with transparent parts? - 07/04/11 21:56

You can't achive real randomness in software. But if you need a good pseudo algorithm, check out mersenne twister.
Posted By: Shadow969

Re: Blitting multiple Bitmaps with transparent parts? - 07/04/11 22:54

i don't think his software needs to comply to diehard standarts wink
Posted By: WretchedSid

Re: Blitting multiple Bitmaps with transparent parts? - 07/05/11 09:17

You are probably right, but if he wants good randomness, well he now knows what to implement tongue
Posted By: Joozey

Re: Blitting multiple Bitmaps with transparent parts? - 07/06/11 20:27

If you need real randomness on quantum level, you don't need advanced software or hardware, just read out the mic for a snap second, and convert the result into a number tongue.
Or the webcam.
Or the position and time the user clicked with the mouse.
Or total play time, or total time the user pressed left arrow.

Just be creative to get some real randomness laugh.
Posted By: WretchedSid

Re: Blitting multiple Bitmaps with transparent parts? - 07/06/11 20:54

On UNIX systems its fairy common to use noise generated by hardware drivers as entropy source.
Posted By: Espér

Re: Blitting multiple Bitmaps with transparent parts? - 10/17/11 17:15

hi there again.. sry to push that up.. but i´ve a problem.. again.. sry


Problem: Adding BLACK Fields isn´t possible, it seems like just everything grey-white is recognized


What i´ve tried:
Creating a 128 pixel circle. Complete black with a fadeout into transparent. Added Alpha Channel and saved as 32Bit TGA including Alpha.
Running the code with that circle.. just creates a grey outlines (border of alpha channel to black).. nothing more..

When i tried to use a 150,150,150 (RGB) Background, the background isn´t made darker at the circle position.. but became brighter at the alpha border...

the actual code:
Click to reveal..

Code:
#include <acknex.h>
#include <d3d9.h>
#include <default.c>


BMAP* map;
BMAP* plain_tile = "plain001.tga";

var plaincount = 0;
var plainfilecount = 7;
var plainmax = 500;
var active   = 0;
int pixelcount = 0;
var position[3];
var groundsize = 2048;

STRING* wort = "BILDMENGE ANGEBEN\noder ESC um den Generator\nzu beenden:";
STRING* input = "   ";
STRING* bitmapname = "Plain";
STRING* bitmapnumb = "1";

FONT* arial = "Arial#15";

PANEL* viewer =
{
	pos_x = 5;
	pos_y = 5;
	layer = 10;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

PANEL* infos =
{
	pos_x = 730;
	pos_y = 50;
	layer = 99990;
	alpha = 100;
	digits(5, 5,  "INFOS:", arial, 1, 0);
	digits(5, 15, "^^^^^^", arial, 1, 0);
	digits(5, 25, "<> Bitmapcount = %.0f", arial, 1, plaincount);
	digits(132, 25, "/", arial, 1, 0);
	digits(140, 25, 4, arial, 1, plainmax);
	digits(5, 115, "PLAIN NAME:", arial, 1, 0);
	digits(5, 127, bitmapname, arial, 1,0);
	digits(5, 145, "PIXELS SET:", arial, 1, 0);
	digits(5, 157, 10, arial, 1,pixelcount);
	flags = SHOW | TRANSLUCENT;
}
PANEL* frames =
{
	pos_x = 0;
	pos_y = 0;
	layer = 1;
	alpha = 100;
	flags = SHOW | TRANSLUCENT;
}

TEXT* txt_input =
{
	pos_x = 735;
	pos_y = 95;
	layer = 99999;
	alpha = 100;
	font = arial;
	string(wort, input);
	flags = SHOW | TRANSLUCENT;
}


void vec_trunc(var *vec, var limit)
{
	vec[0] = minv(vec[0], limit);
	vec[1] = minv(vec[1], limit);
	vec[2] = minv(vec[2], limit);
}


function terrain_to_height(ENTITY* ent,BMAP* he_bmap,var altitude)
{
	VECTOR temp_vektor, pixel_size;
	COLOR pixel1_color;
	var format, pixel1,pixel_posx,pixel_posy,vertex_num,pic_size;
	pic_size=bmap_width(he_bmap);
	pixel_posy=0;
	while(pixel_posy<pic_size)
	{
		pixel_posx=0;
		while(pixel_posx<pic_size)
		{
			
			//convert pixel_pos to vector
			pixel_size.x=(ent.max_x-ent.min_x)/pic_size;
			pixel_size.y=(ent.max_y-ent.min_y)/pic_size;
			temp_vektor.x=((ent.x-ent.min_x)-(pixel_size.x*pixel_posx))-pixel_size.x/2;
			temp_vektor.y=((ent.y-ent.min_y)-(pixel_size.y*pixel_posy))-pixel_size.y/2;
			format = bmap_lock (he_bmap,0);
			pixel1 = pixel_for_bmap(he_bmap, pic_size-pixel_posx, pixel_posy);
			pixel_to_vec (pixel1_color, NULL, format, pixel1); 
			vertex_num = ent_nextvertex(ent,temp_vektor.x);
			CONTACT* kontak = ent_getvertex(ent,NULL,vertex_num); 
			if(kontak.z!=ent.z)//if position of vertex changed, set 0
			{
				kontak.z=ent.z;
				kontak.v=NULL;
			}
			if(kontak.z==ent.z)//if position of vertex not already changed
			{
				if (pixel1_color.blue>0) 
				{
					kontak.z+=0.1+(pixel1_color.blue*altitude);
					draw_point3d(vector(temp_vektor.x,temp_vektor.y,kontak.z),vector(0,255,0),100,50);
					kontak.v=NULL;
				}
				
			}
			ent_setvertex(ent,kontak,vertex_num);    
			bmap_unlock (he_bmap);
			pixel_posx+=1;
		}
		pixel_posy+=1;
		wait(1);
	}
	c_updatehull(ent,1);

}


void main()
{
	video_mode = 8;
	d3d_antialias = 9;
	wait(1);
	video_window(NULL, NULL, (2+16), "Heightmap Generator");
	vec_set(sky_color, vector(1,1,1));
	vec_set(screen_color, vector(1,1,1));
	level_load(NULL);
	wait(3);
	
	map = bmap_createblack(groundsize, groundsize, 32);
	bmap_fill(map, vector(50,50,50), 100);
	viewer.bmap = map;
	frames.bmap = bmap_createblack(726, 726, 24);
	bmap_fill(frames.bmap, vector(255,255,255), 100);
	if(groundsize >= 2048)
	{
		viewer.scale_x = 0.35;
		viewer.scale_y = 0.35;
	}
	
	plaincount = 0;
	
	var randompic = 1;
	var little_format;
	var big_format;
	var alphablend;
	var alphablend2;
	var temp[3];
	var temp2[3];
	var a = 0;
	var b = 0;
	
	map = bmap_createblack(groundsize, groundsize, 24);
	bmap_fill(map, vector(50,50,50), 100);
	viewer.bmap = map;
	
	while(1)
	{
		str_cpy(wort, "BILDMENGE ANGEBEN\noder ESC um den generator\nzu beenden:");
		str_cpy(input, "   ");
		inkey(input);
		while(inkey_active != 0)
		{wait(1);}
		
		if(str_cmpi(input, "esc"))
		{break;}
		
		str_cpy(wort, "GEWÄHLTE BILDMENGE:");
		plainmax = str_to_num(input);
		
		pixelcount = 0;
		plaincount = 0;
		
		bmap_fill(map, vector(0,0,0), 100);

		big_format = bmap_lock(map, 0);
		if(plainmax > 200)
		{
			plainmax = 200;
		}
		
		while(plainmax != 0 && plaincount < plainmax)
		{
			str_cpy(bitmapname, "Plain");
			str_cpy(bitmapnumb, "111");
			randompic = integer(random(plainfilecount)+1);
			if(randompic < 10){str_cat(bitmapname, "00");}
			else if(randompic < 100){str_cat(bitmapname, "0");}
			str_for_num(bitmapnumb, randompic);
			str_cat(bitmapname, bitmapnumb);
			str_cat(bitmapname, ".tga");
			plain_tile = bmap_create(bitmapname);
			
			position[0] = random(bmap_width(map));
			position[1] = random(bmap_width(map));
			position[2] = 0;

			little_format = bmap_lock(plain_tile, 0);
			for(a = 0; a<bmap_width(plain_tile); a++)
			{
				for(b = 0; b<bmap_height(plain_tile); b++)
				{
					if(position[0]+a >= bmap_width(map) || position[1]+b >= bmap_height(map)) continue;
					
					//read map pixel
					pixel_to_vec(temp, alphablend, big_format, pixel_for_bmap(map, position[0]+a, position[1]+b));
					//read feature pixel
					pixel_to_vec(temp2, alphablend2, little_format, pixel_for_bmap(plain_tile, a, b));
					
					//color mixing in 3 steps
					//1.multiply feature pixel's color with normalized alpha
					vec_scale(temp2, alphablend2/100);
					//2.add resulting color to the map pixel's color
					vec_add(temp, temp2); 
					//3.check that resulting vector components stay within 0-255 range
					vec_trunc(temp, 255);
					
					//write the resulting color to the map
					pixel_to_bmap(map, position[0]+a, position[1]+b, pixel_for_vec(temp, alphablend, big_format));
					pixelcount += 1;
				}
			}
			bmap_unlock(plain_tile);
			plaincount += 1;
		}
		wait(1);
		bmap_unlock(map);
		break;
	}
	
	
	bmap_save(map, "Terrain.tga");
	reset(viewer, SHOW);
	reset(infos, SHOW);
	reset(frames, SHOW);
	reset(txt_input, SHOW);
	ENTITY* terr = ent_createterrain(map, nullvector, 512, 512, 8);
	terrain_to_height(terr, map, 0.5);
	
	//	sys_exit("");
}



© 2024 lite-C Forums