3d without rotation or translation:
A single perspective transform is as easy as this:
//sw is screen width, sh is screen height
//zcut is z plane cutoff (don't render anything closer to or behind z) WHY? z=0 is forbidden. z > 1 means point is in front of camera. z=-1 means point is behind camera. zcutoff of .1, .01 etc are reasonable.
int perspective(float x, float y, float z, int* sx, int* sy)
{
if (z < zcutoff)
return 0; //refuse to transform
sx = x* sw / z; //scale X by screen height and distance.
//So, an object sw pixels wide at Z=1 is the width of the screen.
//Z=2, half the widht of the screen. Z=.5, twice the width of the screen. etc
sy = y* sh / z;
return 1;
}
To draw a line in 3d:
void line3d( float x, float y, float z, float x2, float y2, float z2)
{
int sx, sy, sx2, sy2;
//only draws if both points are in front of camera
//later, if you want to get fancy, if one is in front, and the other is behind, you clip at z=zcutoff
if (perspective(x,y,z, &sx, &sy) && perspective(x2,y2,z2,&sx2, &sy2))
draw_line(sx,sy,sx2,sy2);
}
With the above snippets, you should be able to draw a 3d perspective object from the point of view of the origin.
To move the camera around, just subtract the camera position from the coordinates:
int perspective(float x, float y, float z, int* sx, int* sy)
{
x -= camera_x;
y -= camera_y
z -= camera_z;
if (z < zcutoff)
return 0; //refuse to transform
sx = x* sw / z; //scale X by screen height and distance.
//So, an object sw pixels wide at Z=1 is the width of the screen.
//Z=2, half the widht of the screen. Z=.5, twice the width of the screen. etc
sy = y* sh / z;
return 1;
}
With that, you should be able to move around the 3d environment, but view is constrained to always looking down the Z axis. But, its a start.
The last thing you can do, is allow camera rotation along the y axis (like wolf3d). It's been a while but if http://www.siggraph....tran/2drota.htm is correct, then:
int perspective(float x, float y, float z, int* sx, int* sy)
{
float xr, yr, zr;
//translate to camera position
x -= camera_x;
y-= camera_y
z -= camera_z;
//rotate 2D about y axis:
xr = x * cos(camera_angle) - z * sin(camera_angle);
zr = z* cos(camera_angle) + x * sin(camera_angle);
yr = y; // height does not change
if (zr < zcutoff)
return 0; //refuse to transform
sx = xr* sw / zr; //scale X by screen height and distance.
//So, an object sw pixels wide at Z=1 is the width of the screen.
//Z=2, half the widht of the screen. Z=.5, twice the width of the screen. etc
sy = yr* sh / zr;
return 1;
}
That should give you 5 degrees of freedom: You can move up/down, left/right, forward/back and rotate about Y. So, it's 'DOOM' controls. You can add another rotation to look up/down, but at the point you should consider trying to understand matrices.