}
}
void drawView ()
{
Angle phi;
13. Элементы виртуальной реальност
Fixed distance; tota!Frames++;
for (int col = 0; col < 320; col++ ) {
phi = angle + rayAngle [col];
Fixed d1 = checkVWalls ( phi); Fixed d2 = checkHWalls ( phi );
distance = d1;
if (d2 < distance ) distance = d2;
// adjustment for fish-eye
distance = (distance » 8) * (cosine ( phi - angle ) » 8);
drawSpan (distance, WALL_COLOR, col);
}
}
void setVideoMode (int mode ) {
asm {
mov ax, mode int 10h
}
}
void initTables () {
initFixMath ();
for (int i = 0; i < SCREENJ/VIDTH; i++ )
rayAngle [i] = rad2Angle ( atan (-swing + 2 * i * swing / (SCREEN_WIDTH-1)));
}
main () {
int done = 0;
Fixed ct = float2Fixed ( 0.3 ); Angle da = 5 * (ANGLE_90 / 90);
angle = 0;
locX = float2Fixed (1.5 ); locY =float2Fixed(1.5); swing = tan ( VIEW_WIDTH / 2 ); locX =375476; locY = 358224; angle = 60084U;
initTables (); setVideoMode (0x13 );
int start = clock ();
while ('.done )
{
Компьютерная графика. Полигональные модели
drawView ();
' if ( bioskey ( 1 )) {
Fixed vx = cosine ( angle ); Fixed vy = sine ( angle ); Fixed x, y;
switch ( bioskey ( 0 )) {
case LEFT: angle -= da; break;
case RIGHT:
angle += da;
break; case UP:
x = locX + (ct » 8) * (vx » 8);
у = locY + (ct » 8) * (vy » 8);
if ( worldMap [fixed2lnt (y)][fixed2lnt (x)] == " ) {
locX = x; locY = y;
}
break;
case DOWN:
x = locX - (ct » 8) * (vx » 8); у = locY - (ct » 8) * (vy » 8);
if ( worldMap [fixed2lnt (y)][fixed2lnt (x)] == '') {
locX = x; locY = y;
}
break;
case ESC: done = 1;
}
}
}
float totalTime = ( clock () - start) / CLKJTCK; setVideoMode (0x03 );
printf ("\nFrames rendered : %ld", totalFrames );
printf ("\nTotal time ( sec ): %7.2f\ totalTime );
printf ("\nFPS : %7.2f\ totalFrames / totalTime );
}
Обратите внимание на вычисление первой точки пересечения луча с вертика ной и горизонтальной стенами - там используются несколько иные формулы для ления чисел с фиксированной точкой 16.16, чем в приложении. Несложно, одна