PDA

View Full Version : Terrain Engine using multitexturing



glBomb
12-08-2006, 01:28 AM
I am trying to make a terrain engine like age of empires. Its 2D isometric.I plan to produce the terrain like this.
1.Render a base texture like grass
2.Render another texture on top like sand but control its alpha using an alpha texture(or map i think its called).

that makes it 2 passes for each tile.

Can somebody show me the code on how to do it using ARB extensions.i.e. the sequence of glTexEnvi() calls etc & the parameters reqd. etc.

I was initially planning to combine both the textures in just 1 pass with their alphas already set.say all pixels of both textures have their alpha set to 128..then i do this:-

//for 1st texture
glActiveTexture(..)
glBindTexture(..)

//for 2nd texture
glActiveTexture(..)
glBindTexture(..)


glBegin(GL_QUADS)
.
.
glMultiTexCoords2f(...) //for grass texture
glMultiTexCoords2f(...) //for sand texture
glVertex2i(...) //i repeat this 4 times for 4 vertices
..
glEnd()


But that does not give me much variation.Is their a better way to do this.I want to use max 2 texture units as this is just a 2d game.

thinks
12-08-2006, 01:45 AM
I'm sorry but why does the fact that the game is 2D make you want to use only 2 texture units? That does n't make any sense to me.

If you're worried about the glTexEnv() calls maybe you could write a fragment shader instead. I always thought that was easier since you can see what's going on all the way!

arekkusu
12-08-2006, 08:56 AM
Read Multi-texturing on Terrains (http://www.cs.auckland.ac.nz/~jvan006/multitex/multitex.html) .

glBomb
12-09-2006, 12:41 AM
well actually i did this

// TEXTURE-UNIT #0:Grass
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, textures[0]);

// TEXTURE-UNIT #1:Farm
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, textures[1]);

glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT, GL_MODULATE );

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_P REVIOUS_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_ SRC_ALPHA);

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_TEX TURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SR C_COLOR);



glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glBegin(GL_QUADS);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0,0.0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0,0.0);
glVertex2i(0,0);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.378,0.0);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.378,0.0);
glVertex2i(TILE_WIDTH,0.0);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.378,0.765);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.378,0.765);
glVertex2i(TILE_WIDTH,TILE_HEIGHT);

glMultiTexCoord2fARB(GL_TEXTURE0_ARB,0.0,0.765);
glMultiTexCoord2fARB(GL_TEXTURE1_ARB,0.0,0.765);
glVertex2i(0.0,TILE_HEIGHT);


glEnd();


but i only get the 1st texture(grass) on the screen....yet i have seen other programs use multitexturing perfectly on my card.Here i am multiplying the colors of both textures.But no matter wat i use i seems to get only the 1st texture.....am i missing something?

soconne
12-09-2006, 01:19 PM
What I would do is render your terrain in 2 passes. In the first pass render the terrain with your base texture.

In the second pass, set the first texture unit to your alpha map specifying where the dirt should show through and then bind the dirt texture to the second texture unit.

Then for this second pass call:
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Then right after you render the terrain this second time call:
glDisable(GL_BLEND);


So all in all:

// render grass
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, grassID);

RenderTerrain();

// render dirt
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, alphaMapID);

glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, dirtID);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT, GL_MODULATE );

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_P REVIOUS);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_ SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_EXT,GL_P REVIOUS);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_EXT,GL_ SRC_ALPHA);

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_TEX TURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SR C_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_TEX TURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SR C_COLOR);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

RenderTerrain();

glDisable(GL_BLEND);

// disable 2nd texture unit
glActiveTextureARB(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);


That's it.

glBomb
12-11-2006, 03:01 AM
Thanks a lot soccone.But for the dirt+alpha map part...if i am to multiply the alpha of the alpha map with the source color of the terrain then shoudnt the code be like:-

// render dirt
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, alphaMapID);

glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, dirtID);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_CO MBINE_EXT);
glTexEnvi(GL_TEXTURE_ENV,GL_COMBINE_RGB_EXT, GL_MODULATE );

glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_P REVIOUS);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_ SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_TEX TURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SR C_COLOR);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

RenderTerrain();

glDisable(GL_BLEND);

That should take GL_SRC_ALPHA from tex unit 1 & GL_SRC_COLOR from tex unit 2 & do
dest color = GL_SRC_ALPHA*GL_SRC_COLOR

but the way you are doing it it seems you have multiplied the alpha channel of tex unit 1 with itself in :-
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_ALPHA_EXT,GL_P REVIOUS);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_ALPHA_EXT,GL_ SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_ALPHA_EXT,GL_P REVIOUS);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_ALPHA_EXT,GL_ SRC_ALPHA);


Then the rgb of tex unit 2 with itself in:-
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE0_RGB_EXT,GL_TEX TURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND0_RGB_EXT,GL_SR C_COLOR);
glTexEnvi(GL_TEXTURE_ENV,GL_SOURCE1_RGB_EXT,GL_TEX TURE);
glTexEnvi(GL_TEXTURE_ENV,GL_OPERAND1_RGB_EXT,GL_SR C_COLOR);

....i dont get why this has to be done

Also 1 more question.The following segment is to blend in the alpha modulated dirt texture with the already existing grass texture in frame buffer right?

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

RenderTerrain();

glDisable(GL_BLEND);


And of course i would like to store the alpha map as 8 bit textures....can i mix that with my 24 bit dirt texture?(i dont need alpha channel in dirt texture ...so 24 bit)

glBomb
12-13-2006, 01:31 AM
Hey come on people ....this should be a simple problem...help me resolve this.Can someone check out the above code.I am most confused about what format to generate the alpha map in.. 32bit or 8bit ?