Textures
first see Ray Casting with different height size
what you need is to change the scan line rendering of your engine to use textures. The C++ code in above link is just for starters (look for // render scan line
in the code) and will do for the walls but ceiling and floor will have distortions present. To remedy that you need to apply perspective correct texture mapping.
This is how it look like (after I implement it to the former code I linked)
void Doom3D::draw_scanline(int sx,int sy0,int sy1,int sz0,int sz1,int symin,int tx0,int ty0,int tx1,int ty1,DWORD li)
{
//
union { DWORD dd; BYTE db[4]; } cc;
int Txs=txs*tn;
if (sz0==sz1) // affine texture mapping (front side of walls)
{
int sy,tx,ty,ktx,kty,dtx,dty,ctx,cty,dsy;
dsy=sy1-sy0; if (dsy<0) dsy=-dsy;
ktx=0; dtx=tx1-tx0; if (dtx>0) ktx=+1; else { ktx=-1; dtx=-dtx; } tx=tx0; ctx=0;
kty=0; dty=ty1-ty0; if (dty>0) kty=+1; else { kty=-1; dty=-dty; } ty=ty0; cty=0;
if (dsy) for (sy=sy0;sy>=sy1;sy--)
{
if ((sy>=0)&&(sy<sys)&&(sy<=symin))
if ((tx>=0)&&(tx<Txs)&&(ty>=0)&&(ty<tys))
{
cc.dd=ptxr[ty][tx];
cc.db[0]=DWORD((DWORD(cc.db[0])*li)>>8);
cc.db[1]=DWORD((DWORD(cc.db[1])*li)>>8);
cc.db[2]=DWORD((DWORD(cc.db[2])*li)>>8);
pscr[sy][sx]=cc.dd;
}
for (ctx+=dtx;ctx>=dsy;) { ctx-=dsy; tx+=ktx; }
for (cty+=dty;cty>=dsy;) { cty-=dsy; ty+=kty; }
}
}
else{ // perspective correct mapping (floor, top side of walls, ceiling)
int sy,tx,ty,dsy,dtx,dty,_n,n,dn;
int a,b,_z0,_z1;
const int acc=15;
dsy=sy1-sy0; n=abs(dsy); dn=n;
dtx=tx1-tx0; n=abs(dtx); if (dn<n) dn=n;
dty=ty1-ty0; n=abs(dty); if (dn<n) dn=n;
if (sz0==0) return; _z0=(1<<acc)/sz0;
if (sz1==0) return; _z1=(1<<acc)/sz1;
if (dn) for (n=0;n<=dn;n++)
{
sy=sy0+((n*dsy)/dn);
tx=tx0+((n*dtx)/dn);
ty=ty0+((n*dty)/dn);
// perspective correction (https://en.wikipedia.org/wiki/Texture_mapping)
_n=dn-n;
a=(_n*tx0*_z0) + (n*tx1*_z1);
b=(_n *_z0) + (n *_z1); tx=a/b;
a=(_n*ty0*_z0) + (n*ty1*_z1);
b=(_n *_z0) + (n *_z1); ty=a/b;
if ((sy>=0)&&(sy<sys)&&(sy<=symin))
if ((tx>=0)&&(tx<Txs)&&(ty>=0)&&(ty<tys))
{
cc.dd=ptxr[ty][tx];
cc.db[0]=DWORD((DWORD(cc.db[0])*li)>>8);
cc.db[1]=DWORD((DWORD(cc.db[1])*li)>>8);
cc.db[2]=DWORD((DWORD(cc.db[2])*li)>>8);
pscr[sy][sx]=cc.dd;
}
}
}
}
The sx,sy0,sy1
are screen coordinated of the scan line tx0,ty0,tx1,ty1
are the texture coordinates and l0,l1
are distances from camera. li
is just light intensity. The texture coordinates are the fractional part of each grid cell hit coordinates. The texture used is atlas so the x coordinate encodes also which texture is used from it.
On top of this you should also add mip maps (use texture resolution close to projected cell size) that will avoid the shimmering of pixels on distant walls while movement or turn around ...