//--------------------------------------------------------------------------- #include #include #include #pragma hdrstop #include "fTerrainC.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "GLS.LensFlare" #pragma link "GLS.VectorGeometry" #pragma link "Sounds.BASS" #pragma link "GLS.Sound" #pragma link "GLS.SceneViewer" #pragma link "GLS.SkyDome" #pragma link "GLS.BitmapFont" #pragma link "GLS.HUDObjects" #pragma link "GLS.Texture" #pragma link "GLS.Cadencer" #pragma link "GLS.HeightData" #pragma link "GLS.Objects" #pragma link "GLS.TerrainRenderer" #pragma link "GLS.Scene" #pragma link "GLS.Keyboard" #pragma link "GLS.BaseClasses" #pragma link "GLS.Coordinates" #pragma link "GLS.Material" #pragma link "GLS.FileMP3" #pragma resource "*.dfm" TForm1 *Form1; float random(void) { return (float)(rand() & 0x1FFF) / (float)0x1FFF; } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent * Owner):TForm(Owner) { SetGLSceneMediaDir(); // 8 MB height data cache // Note this is the data size in terms of elevation samples, it does not // take into account all the data required/allocated by the renderer GLBitmapHDS1->MaxPoolSize = 8 * 1024 * 1024; // specify height map data GLBitmapHDS1->Picture->LoadFromFile("terrain.bmp"); // load the texture maps GLMaterialLibrary1->Materials->Items[0]->Material->Texture->Image-> LoadFromFile("snow512.jpg"); GLMaterialLibrary1->Materials->Items[1]->Material->Texture->Image-> LoadFromFile("detailmap.jpg"); SPMoon->Material->Texture->Image->LoadFromFile("moon.bmp"); SPSun->Material->Texture->Image->LoadFromFile("flare1.bmp"); // apply texture map scale (our heightmap size is 256) TerrainRenderer1->TilesPerTexture = 256.0 / TerrainRenderer1->TileSize; // load Bitmap Font BitmapFont1->Glyphs->LoadFromFile("darkgold_font.bmp"); // load and setup sound samples GLSoundLibrary->Samples->Add()->LoadFromFile("ChillyWind.mp3"); GLSoundLibrary->Samples->Add()->LoadFromFile("howl.mp3"); // Could've been done at design time, but then it hurts the eyes ;) GLSceneViewer1->Buffer->BackgroundColor = clWhite; // Move camera starting point to an interesting hand-picked location DummyCube1->Position->X = 570; DummyCube1->Position->Z = -385; DummyCube1->Turn(90); // Initial camera height offset (controled with pageUp/pageDown) FCamHeight = 10; randomize(); } //--------------------------------------------------------------------------- void __fastcall TForm1::GLCadencer1Progress(TObject * Sender, const double deltaTime, const double newTime) { float speed; // handle keypresses if(IsKeyDown(VK_SHIFT)) speed = 5 * deltaTime; else speed = deltaTime; TGLCoordinates *c = GLCamera1->Position; if(IsKeyDown(VK_UP)) DummyCube1->Translate(c->Z * speed, 0, -c->X * speed); if(IsKeyDown(VK_DOWN)) DummyCube1->Translate(-c->Z * speed, 0, c->X * speed); if(IsKeyDown(VK_LEFT)) DummyCube1->Translate(-c->X * speed, 0, -c->Z * speed); if(IsKeyDown(VK_RIGHT)) DummyCube1->Translate(c->X * speed, 0, c->Z * speed); if(IsKeyDown(VK_PRIOR)) FCamHeight = FCamHeight + 10 * speed; if(IsKeyDown(VK_NEXT)) FCamHeight = FCamHeight - 10 * speed; if(IsKeyDown(VK_ESCAPE)) Close(); // don't drop through terrain! DummyCube1->Position->Y = TerrainRenderer1->InterpolatedHeight(DummyCube1->Position->AsVector) + FCamHeight; } //--------------------------------------------------------------------------- void __fastcall TForm1::GLSceneViewer1MouseDown(TObject * Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { my = Y; mx = X; } //--------------------------------------------------------------------------- void __fastcall TForm1::GLSceneViewer1MouseMove(TObject * Sender, TShiftState Shift, int X, int Y) { if(Shift.Contains(ssLeft)) { GLCamera1->MoveAroundTarget((my - Y) * 0.5, (mx - X) * 0.5); mx = X; my = Y; } } //--------------------------------------------------------------------------- void __fastcall TForm1::Timer1Timer(TObject * Sender) { String s; // s.printf("%.1f FPS - %d", GLSceneViewer1->FramesPerSecond(), // TerrainRenderer1->LastTriangleCount()); HUDText1->Text = s; GLSceneViewer1->ResetPerformanceMonitor(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormKeyPress(TObject * Sender, char &Key) { TGLMaterial *fp; TGLFogEnvironment *fe; TGIFColor Color; switch (Key) { case 'w': case 'W': fp = GLMaterialLibrary1->Materials->Items[0]->Material; if(fp->PolygonMode == pmLines) fp->PolygonMode = pmFill; else fp->PolygonMode = pmLines; break; case '+': if(GLCamera1->DepthOfView < 2000) { GLCamera1->DepthOfView = GLCamera1->DepthOfView * 1.2; fe = GLSceneViewer1->Buffer->FogEnvironment; fe->FogEnd = fe->FogEnd * 1.2; fe->FogStart = fe->FogStart * 1.2; } break; case '-': if(GLCamera1->DepthOfView > 300) { GLCamera1->DepthOfView = GLCamera1->DepthOfView / 1.2; fe = GLSceneViewer1->Buffer->FogEnvironment; fe->FogEnd = fe->FogEnd / 1.2; fe->FogStart = fe->FogStart / 1.2; } break; case '*': if(TerrainRenderer1->CLODPrecision > 20) TerrainRenderer1->CLODPrecision = RoundInt(TerrainRenderer1->CLODPrecision * 0.8); break; case '/': if(TerrainRenderer1->CLODPrecision < 1000) TerrainRenderer1->CLODPrecision = RoundInt(TerrainRenderer1->CLODPrecision * 1.2); break; case '8': if(TerrainRenderer1->QualityDistance > 40) TerrainRenderer1->QualityDistance = RoundInt(TerrainRenderer1->QualityDistance * 0.8); break; case '9': if(TerrainRenderer1->QualityDistance < 1000) TerrainRenderer1->QualityDistance = RoundInt(TerrainRenderer1->QualityDistance * 1.2); break; case 'n': case 'N': if(SkyDome1->Stars->Count == 0) { // turn on 'night' mode Color.Red = 0; Color.Green = 0; Color.Blue = 8; SkyDome1->Bands->Items[0]->StopColor->AsWinColor = TGIFColorMap::RGB2Color(Color); Color.Red = 0; Color.Green = 0; Color.Blue = 0; SkyDome1->Bands->Items[0]->StartColor->AsWinColor = TGIFColorMap::RGB2Color(Color); Color.Red = 0; Color.Green = 0; Color.Blue = 16; SkyDome1->Bands->Items[1]->StopColor->AsWinColor = TGIFColorMap::RGB2Color(Color); Color.Red = 0; Color.Green = 0; Color.Blue = 8; SkyDome1->Bands->Items[1]->StartColor->AsWinColor = TGIFColorMap::RGB2Color(Color); SkyDome1->Stars->AddRandomStars(700, clWhite, True); // many white stars Color.Red = 255; Color.Green = 100; Color.Blue = 100; SkyDome1->Stars->AddRandomStars(100, TGIFColorMap::RGB2Color(Color), True); // some redish ones Color.Red = 100; Color.Green = 100; Color.Blue = 255; SkyDome1->Stars->AddRandomStars(100, TGIFColorMap::RGB2Color(Color), True); // some blueish ones Color.Red = 255; Color.Green = 255; Color.Blue = 100; SkyDome1->Stars->AddRandomStars(100, TGIFColorMap::RGB2Color(Color), True); // some yellowish ones GLSceneViewer1->Buffer->BackgroundColor = clBlack; fe = GLSceneViewer1->Buffer->FogEnvironment; fe->FogColor->AsWinColor = clBlack; fe->FogStart = -fe->FogStart; // Fog is used to make things darker SPMoon->Visible = True; SPSun->Visible = False; GLLensFlare->Visible = False; } break; case 'd': case 'D': if(SkyDome1->Stars->Count > 0) { // turn on 'day' mode SkyDome1->Bands->Items[1]->StopColor->Color = clrNavy; SkyDome1->Bands->Items[1]->StartColor->Color = clrBlue; SkyDome1->Bands->Items[0]->StopColor->Color = clrBlue; SkyDome1->Bands->Items[0]->StartColor->Color = clrWhite; SkyDome1->Stars->Clear(); GLSceneViewer1->Buffer->BackgroundColor = clWhite; fe = GLSceneViewer1->Buffer->FogEnvironment; fe->FogColor->AsWinColor = clWhite; fe->FogStart = -fe->FogStart; GLSceneViewer1->Buffer->FogEnvironment->FogStart = 0; SPMoon->Visible = False; SPSun->Visible = True; } break; case 't': if(SkyDome1->Options.Contains(sdoTwinkle)) SkyDome1->Options = SkyDome1->Options << sdoTwinkle; else SkyDome1->Options = SkyDome1->Options >> sdoTwinkle; break; case 'l': GLLensFlare->Visible = (!GLLensFlare->Visible) && SPSun->Visible; } Key = '\0'; } //--------------------------------------------------------------------------- void __fastcall TForm1::TISoundTimer(TObject * Sender) { TGLVector wolfPos; float c, s; TGLBSoundEmitter *be; if(!GLSMBASS1->Active) return; if(SkyDome1->Stars->Count == 0) { // wind blows around camera be = GetOrCreateSoundEmitter(GLCamera1); be->Source->SoundLibrary = GLSoundLibrary; be->Source->SoundName = GLSoundLibrary->Samples->Items[0]->Name; be->Source->Volume = random() * 0.5 + 0.5; be->Playing = True; } else { // wolf howl at some distance, at ground level wolfPos = GLCamera1->AbsolutePosition; SinCosine(random() * Gls::Vectorgeometry::c2PI, 100 + random(1000), s, c); wolfPos.X = wolfPos.X + c; wolfPos.Z = wolfPos.Z + s; wolfPos.Y = TerrainRenderer1->InterpolatedHeight(wolfPos); DCSound->Position->AsVector = wolfPos; be = GetOrCreateSoundEmitter(DCSound); be->Source->SoundLibrary = GLSoundLibrary; be->Source->SoundName = GLSoundLibrary->Samples->Items[1]->Name; be->Source->MinDistance = 100; be->Source->MaxDistance = 4000; be->Playing = True; } TISound->Enabled = False; TISound->Interval = 10000 + random(10000); TISound->Enabled = True; } //---------------------------------------------------------------------------