outdoor beautifullyizing

ok…i want to know everything about things i could use to make my outdoor-game look cool (at the moment, i got a plasma-morphing sun, day/night shift, dynamic height textures, nice trees…)

i can’t use a lightmap because the moon / sun circles around my world, so the lighting is dynamic

weak points :
my main texture is very blurry, so i’m using a detail texture to fix this. but the same detail texture EVERYWHERE doesn’t look really good…any idea how i can blend detail textures from one to another ? i don’t want a sharp edge between 2 detail textures to be visible and ugly…

i want to add some details like a path or something, or blood after some monsters have been killed ^^, but the main texture is not high-resd enough. how can i fix this ? putting a lot of high-res textures across the whole landscape needs about 32-64 mb of ram…too much…

What I’ve seen in some games having detailful terrain, with patches, grass etc, all together is just a collection of textures e.g.:
-grass texture
-patch texture
-grass/patch texture combinations for all cases like grass being only on the edge etc…

Doing this in NxN grid constraints a bit possible layouts of e.g.patches on he grass.

But you may try terrain without strict texture to grid wrapping, so your patches will be allowed to have arbitrary directions.

Have you seen the grass discussion here?
http://www.opengl.org/discussion_boards/ubb/Forum2/HTML/011397.html
There are a couple of demos there with very unclear explanations. But I think it might add to your outdoor beauty if you are running for perfection.

A good terrain texturing article can be found at
http://www.delphi3d.net/articles/viewarticle.php?article=terraintex.htm

Once you’ve read that, you should know how to make those paths with their own detail texture. Altough I use a general purpose detail texture and a low-res colormap on my terrain, it looks quite good too.

Blood splats and such are best made with decals.

-Ilkka

thx for the links…
especially the second one…
i don’t understand the code (maybe i should read it again) but is it right that u basically draw all 3 or 4 detail textures and just change the opacity by enabling glblend, and let ogl interpolate between the different points of the quads/triangles ?

if yes, i have to tell ogl for every point what colors it should use…is it possible to do this by a vertex array ? (i’m asking because display lists don’t save multitexture commands)

Don’t save multitexture commands
Worked for me until now
Although I experienced some problems with intel built in graphic boards.
But not with TNT2 or GF2GTS

[This message has been edited by M/\dm/
(edited 01-16-2003).]

glmultitextcoordarb1 or what the name is never was saved in my displaylists… maybe it’s because i’m using gl4java…

Yes, you can use vertex arrays for that. You could also put the weights in some low-res textures, I think that’s what the article is about. A simple multipass version would go like this:

-render terrain with color=weightTex[1]*detailTex[1]
-set depth test to GL_EQUAL and blending to GL_ONE, GL_ONE
-render other layers with color = weightTex[n]*detailTex[n]

Of course you should, for each pass other than the first, only render those triangles that have at least some of the detail texture in question on them. The technique works best, if the weights for every texel add up to 1.

-Ilkka

10 minutes ago, i had the idea to combine the low-res texture with an alpha channel, draw the first detail texture, and use a third texture unit to draw a second detail texture, which i set to gl_dst_alpha,gl_one

will this work ?
would increase the peformance i think because i would not have to use any additional commands…

Yes, the idea is correct, but I think you’re confusing something… At least me.

You can get two detail textures with 3 texture units, but you can’t use blending for that since it all happens in one pass. You have to do it in texture enviroments, GL_TEX_ENV_COMBINE should be enough. If I recall correctly the article describes this. Please note, however, that many cards, including GF1 and GF2 (I may be wrong about the 2), only have two texture units.

-Ilkka

if i use GL_TEX_ENV_COMBINE, the detail textures are drawn everywhere… i want one to blend into another, dependend on their height

this seems to do everything
can anyone explain how the code does what it does ?
i know what vertex arrays are and how to use them - my problem are the gltexenvi-commands…

procedure TTTForm.ConfigureSinglePass;
begin

// Configure OpenGL for the single-pass rendering.

glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].R);

glClientActiveTextureARB(GL_TEXTURE3_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U2);

glClientActiveTextureARB(GL_TEXTURE2_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);

glClientActiveTextureARB(GL_TEXTURE1_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);

glClientActiveTextureARB(GL_TEXTURE0_ARB);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].U1);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, SizeOf(TTerrainVertex), @va[0].X);

// Texture 3: previous * L
glActiveTextureARB(GL_TEXTURE3_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, L);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

// Texture 2: lerp(C0.alpha, previous, T3)
glActiveTextureARB(GL_TEXTURE2_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, T3);

glMatrixMode(GL_TEXTURE);
glScalef(0.2, 0.2, 0);
glMatrixMode(GL_MODELVIEW);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);

// Texture 1: lerp(C0.rgb, T1, T2)
glActiveTextureARB(GL_TEXTURE1_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, T1);

glMatrixMode(GL_TEXTURE);
glScalef(0.2, 0.2, 0);
glMatrixMode(GL_MODELVIEW);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR);

// Texture 0: T1
glActiveTextureARB(GL_TEXTURE0_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, T2);

glMatrixMode(GL_TEXTURE);
glScalef(0.2, 0.2, 0);
glMatrixMode(GL_MODELVIEW);

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

end;

plz help …
my engine would be godlike if i would understand this…

You can read about GL_TEX_ENV_COMBINE from opengl specs. In general, the idea is following:

You have some number of texture units, each of which can have a texture bound. In addition with GL_TEX_ENV_COMBINE you can define each unit’s outcome as a funcion based on the unit’s texture, outcome of the previous unit, primary color and a constant. The outcome of the last unit is the one that goes to screen, possibly through blending.

The available functions are replace, add, add signed, modulate and lerp (linear interpolation). Different functions can be assigned to color and alpha channels.

In your code units 0-2 have different detail textures in them and unit 3 is propably a lightmap. Primary colors (as in glColorPointer) contain the interpolation factors, one in color channel, one in alpha.

Unit 0 just outputs it’s texture color. Unit 1 interpolates it with it’s own texture using primary color as interpolation factor. Unit 2 takes this result and interpolates it with the third texture, this time using primary alpha as the interpolation factor. Finally the result is modulated with the lightmap in unit 3.

I hope that was clear enough, I don’t exactly marvel at explaining things.

-Ilkka

glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
-> i’m using simple detailtexturing so no problem to understand this one

glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB);
-> i think this one tells opengl how to combine the new texture with the other one.

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB);
-> i guess this means : do something with the previous texture unit, and something with the color of the texture binded to unit 0.

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_PRIMARY_COLOR_ARB);
-> ???

glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA);
-> ???

ok got it !
found a site that explains multitexturing perfectly

but how to use GL_ARB_texture_env_crossbar
just replace GL_texture_env ?

No, you replace the source (for example GL_PREVIOUS_ARB) with GL_TEXTURE<n>_ARB where <n> is the number of the texture unit. But nvidia doesn’t support crossbar on any cards I think, so make sure you have a fallback if you ever want to release whatever you’re doing.

-Ilkka

nvidia has its own extension doing the same i think…

after some hard work, i got 2 detail-textures combined. but i absolutely don’t understand the calculation of the coverage factors…

can anyone help me?

thats the code :

a1 and a2 are the coverage factors…
but how are they calculated ? there are no comments in the code grr

procedure Color(x, y: Integer);
var
h, s: Single;
w1, w2, w3, l: Single;
a1, a2: Single;
cl: TColor;
begin

// Encode the blending weights for this heightmap pixel in an RGBA color.

if coverage = nil then
begin
  h := map[x,y]/255;
  s := CalcSlope(x, y);

  cl := LUT.Canvas.Pixels[Trunc(h*LUT.Width), LUT.Height - 1 - Trunc(s*LUT.Height)];
  w1 := (cl mod $100) / 255;
  w2 := ((cl div $100) mod $100) / 255;
  w3 := (cl div $10000) / 255;

  l := sqrt(w1*w1 + w2*w2 + w3*w3);
  w1 := w1/l;
  w2 := w2/l;
  w3 := w3/l;

  bmp.Canvas.Pixels[x,y] := RGB(Trunc(w1*255), Trunc(w2*255), Trunc(w3*255));
end
else begin
  cl := coverage.Canvas.Pixels[x,y];
  w1 := (cl mod $100) / 255;

// w2 := ((cl div $100) mod $100) / 255;
w3 := (cl div $10000) / 255;
end;

a1 := w1/(1-w3);
a2 := 1 - w3;

va[y*mW + x].R := a1;
va[y*mW + x].G := a1;
va[y*mW + x].B := a1;
va[y*mW + x].A := a2;

end;