 | The 3D Story Your guide to the third dimension. |
Comments
This second version of our box demo does not contain that very many differences. The actual output isn't affected at all, the differences is hidden behind the code.
This code can handle alot more lines, this is due to the introduction of precalculated tables. Also, the graphics will not flicker on older computers that don't manage to keep the calculations in sync with the screen's updates.
To get more information on how it has been done, read the comments after the code.
BOX2.CPP
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include "gfxman2.h"
#define MAXMARKS 8
#define MAXLINES 12
#define DIST 256
#define MIDDLEX 160
#define MIDDLEY 100
void main(void);
struct point
{
double x,y,z;
};
struct line
{
int m1,m2;
unsigned char colour;
};
double c[3600],s[3600];
point rotpoint(point i,point a);
point projpoint(point i);
void precalc(void);
void main(void)
{
precalc();
point rmark[MAXMARKS];
point mark[]={{25,25,25},{-25,25,25},{-25,-25,25},{25,-25,25},{25,25,-25},{-25,25,-25},{-25,-25,-25},{25,-25,-25}};
line lines[]={{0,1,15},{1,2,15},{2,3,15},{3,0,15},
{4,5,15},{5,6,15},{6,7,15},{7,4,15},
{0,4,15},{1,5,15},{2,6,15},{3,7,15}};
point angle={10,0,20};
if(!SetVGA())
exit(EXIT_FAILURE);
do
{
Cls();
for(int a=0;a
rmark[a]=projpoint(mark[a]=rotpoint(mark[a],angle));
for(a=0;a
Line(rmark[lines[a].m1].x,rmark[lines[a].m1].y,rmark[lines[a].m2].x,rmark[lines[a].m2].y,lines[a].colour);
ScreenCopy();
WaitRetrace();
}
while(!kbhit());
getch();
SetText();
}
point rotpoint(point i,point a)
{
point r;
r.x=c[(int)a.z]*i.x-s[(int)a.z]*i.y;
r.y=s[(int)a.z]*i.x+c[(int)a.z]*i.y;
r.z=i.z;
i.x=c[(int)a.y]*r.x-s[(int)a.y]*r.z;
i.y=r.y;
i.z=s[(int)a.y]*r.x+c[(int)a.y]*r.z;
r.x=i.x;
r.y=s[(int)a.x]*i.z+c[(int)a.x]*i.y;
r.z=c[(int)a.x]*i.z-s[(int)a.x]*i.y;
return r;
}
point projpoint(point i)
{
double t;
point r;
t=DIST+i.z;
r.z=i.z;
if(t)
{
r.x=i.x*DIST/t+MIDDLEX;
r.y=i.y*DIST/t+MIDDLEY;
}
else
{
r.x=i.x+MIDDLEX;
r.y=i.y+MIDDLEY;
}
return r;
}
void precalc(void)
{
for(int a=0;a<3600;a++)
{
s[a]=sin((a/10.0)*(M_PI/180));
c[a]=cos((a/10.0)*(M_PI/180));
}
}
The following comments apply to the code with the title's colour.
Precalculated tables
These lines are used to create the precalculated tables for the functions cos and sin. First the two vectors are defines, then a function prototype appears.
This function is called first in the main function, and it initialises the tables. The only difference when calling the functions are that the rotations will have to be initialized in the number of tenths of degrees that the rotation is going to be (see the intitialisation of angle.)
The actual precalc function simply iterates through the cos and sin tables and save the results in the vectors.
This does not affect the result yet, but soon, when the time left after a redraw is shrinking, this will truly pay off well.
The Virtual Screen
The SetVGA function will now also reserve memory for the virtual screen and can fail, even on systems with a VGA card. Because of this, we'll need to verify that the required memory is available before continuing, or otherwise exit with an error message.
What you'll need to remember is that all the graphics functions used are invisible to the user until the ScreenCopy function is being called. To avoid flicker, the WaitRetrace function will have to be called directly after the ScreenCopy call, this forces the computer to let the new image to be completely redrawn before replaced.
The SetText function now also frees the memory reserved for our virtual screen.
The rotpoint Function
In the references to the c[] and s[] vectors the angle will have to be converted to integer. This is because a double (or float) cannot be used to specify an index in a vector.
Just remove the (int) parts to see the error message.
Compilation
Just follow the instructions in the VGA routines I appendix, but compile the BOX2.CPP with the GFXMAN2.OBJ instead of GFXMAN.OBJ.
If you experience any trouble, don't hessitate to mail me at e8johan@etek.chalmers.se.
[ Previous | Main Page | Next ]
Copyright©1997 Johan E. Thelin