Tutorial 08-
Weather
This tutorial demonstrates special effects and lighting simulation.
Gradient of the sky
We use genie to render the sky without textures.
hgeSprite *sky;
sky=new hgeSprite(0, 0, 0, SCREEN_WIDTH, SKY_HEIGHT);
It has different colors on the top and bottom vertices for smooth transition.
hgeColor colSkyTop;
hgeColor colSkyBtm;
sky->SetColor(colSkyTop.GetHWColor(), 0);
sky->SetColor(colSkyTop.GetHWColor(), 1);
sky->SetColor(colSkyBtm.GetHWColor(), 2);
sky->SetColor(colSkyBtm.GetHWColor(), 3);
sky->Render(0, 0);
The color of the sky is determined by the time of the day and calculated in the interpolation of some color constants.
hgeColor col1, col2;
col1.SetHWColor(skyTopColors[seq[seq_id]]);
col2.SetHWColor(skyTopColors[seq[seq_id+1]]);
colSkyTop=col2*seq_residue + col1*(1.0f-seq_residue);
col1.SetHWColor(skyBtmColors[seq[seq_id]]);
col2.SetHWColor(skyBtmColors[seq[seq_id+1]]);
colSkyBtm=col2*seq_residue + col1*(1.0f-seq_residue);
Sea and waves
The same coloring technology can be used in the sea. However, this time we use the hgeDistortionMesh class to simulate waves instead of hgeSprite.
hgeDistortionMesh *sea;
sea=new hgeDistortionMesh(SEA_SUBDIVISION, SEA_SUBDIVISION);
sea->SetTextureRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT-SKY_HEIGHT);
To create waves, we set the displacement and color for each surface mesh node (we skip the first and last lines because we don't want them to move ):
for(i=1; i<SEA_SUBDIVISION-1; i++)
{
// these are constants for each vertices line
a=float(i)/(SEA_SUBDIVISION-1);
col1=colSeaTop*(1-a)+colSeaBtm*a;
dwCol1=col1.GetHWColor();
fTime=2.0f*hge->Timer_GetTime();
a*=20;
for(j=0; j<SEA_SUBDIVISION; j++)
{
sea->SetColor(j, i, dwCol1);
dy=a*sinf(seaP[i]+ // precalculated phase shift
(float(j)/(SEA_SUBDIVISION-1)-0.5f)*M_PI*16.0f-fTime);
sea->SetDisplacement(j, i, 0.0f, dy, HGEDISP_NODE);
}
}
Now we set the color for the first and last lines skipped before.
dwCol1=colSeaTop.GetHWColor();
dwCol2=colSeaBtm.GetHWColor();
for(j=0; j<SEA_SUBDIVISION; j++)
{
sea->SetColor(j, 0, dwCol1);
sea->SetColor(j, SEA_SUBDIVISION-1, dwCol2);
}
The sea is ready. Let's start rendering:
sea->Render(0, SKY_HEIGHT);
A ray from the moon to the sun is simulated in the source code. To achieve this, we only need to add a 1 bit white line under the sun and moon.
Sky objects
Stars, moon, and sun are genie composed of colored points.
hgeSprite *sun;
hgeSprite *moon;
hgeSprite *star;
sun=new hgeSprite(texObjects,81,0,114,114);
sun->SetHotSpot(57,57);
moon=new hgeSprite(texObjects,0,0,81,81);
moon->SetHotSpot(40,40);
star=new hgeSprite(texObjects,72,81,9,9);
star->SetHotSpot(5,5);
What's interesting is the halo and reflection on the sea. They are all genie:
hgeSprite *glow;
hgeSprite *seaglow;
glow=new hgeSprite(texObjects,128,128,128,128);
glow->SetHotSpot(64,64);
glow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHABLEND);
seaglow=new hgeSprite(texObjects,128,224,128,32);
seaglow->SetHotSpot(64,0);
seaglow->SetBlendMode(BLEND_COLORADD | BLEND_ALPHAADD);
Note that the halo genie uses different rendering modes to achieve the appropriate color. They share the same texture area.
The ratio and color of the sun and moon areUpdateSimulationInRenderSimulationRendering in:
glow->SetColor(colSunGlow.GetHWColor());
glow->RenderEx(sunX, sunY, 0.0f, sunGlowS);
sun->SetColor(colSun.GetHWColor());
sun->RenderEx(sunX, sunY, 0.0f, sunS);
glow->SetColor(colMoonGlow.GetHWColor());
glow->RenderEx(moonX, moonY, 0.0f, moonGlowS);
moon->SetColor(colMoon.GetHWColor());
moon->RenderEx(moonX, moonY, 0.0f, moonS);
The same reflection on the sea surface:
seaglow->SetColor(colSeaGlow.GetHWColor());
seaglow->RenderEx(seaGlowX, SKY_HEIGHT,
0.0f, seaGlowSX, seaGlowSY);
Note that the sea reflection genie is not a proper proportion.
Run
This example runs at a very high FPS. This may be becauseDirect3DThe bottleneck of the rendering genie is the texture bandwidth. In this example, only a small texture is used to render a small number of genie. Most of the screen areas are filled with a single color.