Tunnel: C++Builder Version
/****************************************************************************\
* *
* Tunnel.cpp *
* TunnelU.cpp *
* *
* This program draws a Gouraud-shaded tunnel and allows the viewer to move *
* through the tunnel using keyboard controls. *
* *
\****************************************************************************/
#include
#pragma hdrstop
#include "TunnelU.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::OnIdle(TObject *Sender, bool &Done)
{
CheckForMovement();
Done = False;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormActivate(TObject *Sender)
{
fg_realize(hPal);
Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
int vbDepth;
hDC = GetDC(Form1->Handle);
fg_setdc(hDC);
hPal = fg_defpal();
fg_realize(hPal);
fg_vbinit();
vbDepth = fg_colors();
if (vbDepth < 16) vbDepth = 16;
fg_vbdepth(vbDepth);
hVB = fg_vballoc(vbWidth,vbHeight);
fg_vbopen(hVB);
fg_vbcolors();
hZB = fg_zballoc(vbWidth,vbHeight);
fg_zbopen(hZB);
fg_setcolor(-1);
fg_fillpage();
fg_3Dviewport(0,vbWidth-1,0,vbHeight-1,1.0);
fg_3Drenderstate(FG_ZBUFFER | FG_ZCLIP);
fg_3Dlookat(0.0,10.0,50.0,0.0,10.0,100.0);
Application->OnActivate = OnActivate;
Application->OnIdle = OnIdle;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
fg_vbscale(0,vbWidth-1,0,vbHeight-1,0,cxClient-1,0,cyClient-1);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
cxClient = ClientWidth;
cyClient = ClientHeight;
Invalidate();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
fg_vbclose();
fg_zbfree(hZB);
fg_vbfree(hVB);
fg_vbfin();
DeleteObject(hPal);
ReleaseDC(Form1->Handle,hDC);
}
/****************************************************************************\
* *
* CheckForMovement() *
* *
* The CheckForMovement() function checks for key presses that control the *
* user's movement, and if required redraws the tunnel viewed from the new *
* camera position. It is called from the WinMain() message loop when there *
* are no messages waiting. *
* *
\****************************************************************************/
void __fastcall TForm1::CheckForMovement()
{
static bool Redraw = True;
// up arrow moves viewer forward
if (fg_kbtest(72))
{
fg_3Dmoveforward(2.0);
Redraw = TRUE;
}
// down arrow moves viewer backward
else if (fg_kbtest(80))
{
fg_3Dmoveforward(-2.0);
Redraw = TRUE;
}
// right arrow turns viewer to the right
else if (fg_kbtest(77))
{
fg_3Drotateright(6*10);
Redraw = TRUE;
}
// left arrow turns viewer to the left
else if (fg_kbtest(75))
{
fg_3Drotateright(-6*10);
Redraw = TRUE;
}
// if the viewer's position or rotation changed, redraw the tunnel
if (Redraw)
{
// prepare the z-buffer for the next frame
fg_zbframe();
// erase the previous frame from the virtual buffer
fg_setcolor(-1);
fg_fillpage();
// draw the tunnel
DrawTunnel();
// display what we just drew
fg_vbscale(0,vbWidth-1,0,vbHeight-1,0,cxClient-1,0,cyClient-1);
Redraw = False;
}
}
/****************************************************************************\
* *
* DrawTunnel() *
* *
* Draws each of the tunnel's four sides in 3D world space. *
* *
\****************************************************************************/
void __fastcall TForm1::DrawTunnel()
{
register int i;
for (i = 0; i < 4; i++)
{
fg_3Dshade((double *)Faces[i],(char *)FacesRGB[i],4);
}
}
|