Want to do trees

Hello,

I want to place bitmap based billboarding trees in my terrain engine.
I have two major problems:

I can’t make the background of the trees transparent. It seems that OpenGL
has a raster mode system similar to windows ROP-Codes, so it shouldn’t be
that hard to make a black/white background transparent. Can anybody show
me how to do it ?

Billboarding ! I wrote my own billboarding class, but it doesn’t seem to
work very good. It uses some heavy math like asin() in realtime, this
probably isn’t a good way. I guess it would be something with glMultMatrix(),
but my maths skillz aren’t that good :wink:

2b.
When I billboard a tree, would it look better to just rotate it around Y axis,
or should I rotate it around the Y and X axis ?

Thanks for any help.

Tcs

do you have the Redbook? All the procedure to do that is written.

I’ll tell you anyway.

You have to select a transparent color. let’s say bright pink(255,0,255).

So when you draw you tree texture, you make the background bright pink.

When you load your texture in opengl, when you find a bright pink color, you just make the alpha component 0 and the other whatever you like but not 0.

When you render, you enable blending and use the blending function (GL_SRC_ALPHA, ONE_MINUS_SOURCE_ALPHA).

Have you seen the fine developer-demo from NVidia, with the nice procedual tree ?
I think 2D trees are out of runnig out of date,why don´t you like to code a routine like the procedual-tree from NVidia. Meanwhile, the source should be available at
Nvidias-hompage( i have looked last before last three weeks). Ok Ok, iknow, the scene shows a very high-detailed tree, but if you are able to realize this with a smaller account of polys, it should work fast and it will look very good - also you can optimize this algorythm, if you use precalculated-tables for your values.
Let me know, if you have realized it !

Yesm I know to do fractal and procedural generated trees, it isn’t that hard. My landscape is very big, and I’m not hitting the poly limit of my GeForce DDR yet, but hey, it should run ok on Celi@333 with a normal TNT2. So bitmap trees with billboarding would be look ok. I mean even the “T&L demo” 3dmark2000 uses bitmap trees…

I already knew the thing with giving the texture alpha channel. I just thought there is an easy reason, similar to the win32 bitblt function.

and what about bilboarding ?

thanks anyway…

Bilboarding is what I explained with the blend func.

the alpha channel is for opacity of the texture .

When you call glBlend(GL_SOURCE_ALPHA, ONE_MINUS_SOURCE_ALPHA), what happen with the color is that:

the first param is for what you are going to draw,(it’s called the source), the second parameter is for the color already present.

since you wrote gl_source_alpha for the source, then when you are going to draw the texture it will multiply every color component for the source by the alpha value. So it is zero, the component will become zero.

for the destination color: it will multiply by 1- Alpha source, so if the alpha is 0 then the color that will be drawn is the color that was already there because all the component will be multiply by one.

You just have the two modified component and you the color for a point.

[This message has been edited by Gorg (edited 02-12-2000).]

by the geometrical side, billboarding mean to setup a model that is always facing either the viewpoint or the viewplane.

since you’re talking about trees, you probably want viewplane-aligned billmoards (math is simpler/faster) and your model is a simple textured quad.

there are many ways to code vab’s… depends on what infos you can get easier.

you can project your vab 3D location on a 2D plane, then draw the quad in this location.
you’ll have to set the modelview matrix to identity, then to the roll angle your camera has.

another way could be to inverse rotate your textured quad with the camera current heading.

personally i implemented the first way: i find it simpler, it costs only 2 divides (if you’re using plane z=-1) and it avoid me to redefine the projection matrix.

surely you know, but to project a 3-space point to a fixed-Z plane, you do this:

vert.x=VIEW_PLANEpoint.x/point.z;
vert.y=VIEW_PLANE
point.y/point.z;
vert.z=VIEW_PLANE;

where point is your 3-space location and vert is the projected point.
vert has 3 components since it still lays in 3-space.

thanks dmy, your billboarding stuff works.
But back to the transparency texture stuff. Can someone tell me how to load a texture (BMP) as RGBA and do this put “all black pixels to aplha 0” stuff ?

tcs

First of all, I want to say sorry because I was way off with the billboarding thing! Somebody once told me that billboarding was just the alpha technique!

as for the bitmap : here’s my code

a basic texture object :

typedef struct
{
GLubyte* colors;
int width;
int height;
GLuint glID; //id number from opengl
} Texture;

the bitmap loading

void loadBitmap(char* filename, Texture* tex, int trans_color[3])
{
FILE* bmpfile;
BITMAPFILEHEADER bmfileheader;
BITMAPINFOHEADER bminfoheader;
RGBTRIPLE rgb;

int i,j,texpos = 0;

bmpfile = fopen(filename, "rb");

if (!bmpfile)
	exit(1);

fread(&bmfileheader, sizeof(BITMAPFILEHEADER), 1, bmpfile);
fread(&bminfoheader, sizeof(BITMAPINFOHEADER), 1, bmpfile);


tex->width = bminfoheader.biWidth;
tex->height = bminfoheader.biHeight;


tex->colors = (GLubyte*)malloc(tex->width * tex->height *4);

// read color
for (i = 0; i < tex->width; i++)
{
	for(j = tex->height - 1; j>=0 ; j--)    //start with the height because the first data you read in the color array of the bitmap
	{										// is coord (1.0).
		fread(&rgb, sizeof(RGBTRIPLE),1,bmpfile);
		tex->colors[texpos] = rgb.rgbtRed ;
		tex->colors[texpos+1] = rgb.rgbtGreen;
		tex->colors[texpos+2] = rgb.rgbtBlue;
		
		//test if color should be transparent
		if ((rgb.rgbtRed == trans_color[0]) && (rgb.rgbtGreen == trans_color[1]) && (rgb.rgbtGreen == trans_color[2]))
			tex->colors[texpos+3] = 0; 
		else
			tex->colores[texpos+3] = 255;

		texpos += 4;
	}
	
}
fclose(bmpfile);

}

You don’t need to have a special writing color like with rop code.

You just use blending with the blending function set to (GL_SOURCE_ALPHA, ONE_MINUS_SOURCE_ALPHA).

[This message has been edited by Gorg (edited 02-12-2000).]

thousand thanks gorg !!!
It works.

But there’s a little problem…
You have left out a little bit of your code. I have never bothered to write a texture loading function, I’m not that experienced at that topic. I have figured out that those parameters must work:

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
gluBuild2DMipmaps(GL_TEXTURE_2D, 4, m_nWidth, m_nHeight, GL_RGBA, GL_UNSIGNED_BYTE, colors);

Is it right ?

I experienced some problems with laoding some of my bitmaps. My terrain bitmaps load ok, but my sky bitmap doesn’t load right with your code. All bitmaps are 24bpp. Are there any limitations to your code ? What kinds of bitmaps should I use ?

Tcs

I figured out why your code doesn’t work. It seems it deosn’t support none square textures ? Can you (or anyone) tell me hoe to fix this ???

Thanks

Just to tell you : the glPixelstorei are ok. But those value are the defaults and it is those you are suppose to use with my loading code. to learn more about the glpixelstori just find an electronic version of the red book.

As for the non rectangular texture: it is not my code fault! Opengl only support texture that are power of 2.

So examples are 64 X 64, 128 X 64, 256 X 64 etc.

so the height must be 2^m and the with 2^n where n and m can and cannot be equal.

if their are not, some weird things will happen.

[This message has been edited by Gorg (edited 02-12-2000).]

No, nonsquare textures are at least supported by GeForce cards. Ive heard that limitations of OpenGL, but with my recent texture code even nonsquare textures work. I played around a bit with your code. It doesn’t fail when the texture is nonsquare, it fails when you can’t divide the width or the height of the texture evenly through 4… this is strange, ic no way to fix this myself…

Tcs

hmm. I don’t have that problem though. I still think it is because you don’t have power of 2 textures (it can be rectangular 128 X 64, 64 X 128), but I’ll look into it and come back to you later.

If you are using

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);

you need to have your texture data aligned to 4 bytes.

I guess this is specific to data read in from BMP files for example. So, you don’t necessarily have to do this. If your texture data is not aligned, just simply leave those four lines of code out.

Cheers,
Hude