csdl-2raycasting

Multi-textured floor rendering in 2D raycaster


In this wonderful lodev's raycasting tutorial (https://lodev.org/cgtutor/raycasting2.html), we have a part about floor and ceiling. I bet my problem is simple, but I can't help myself.

Using the horizontal method of rendering I want to render different textures for each tile on the map. In lodev's example we get currentFloorX and currentFloorY, but only using vertical rendering:

//draw the floor from drawEnd to the bottom of the screen
for(int y = drawEnd + 1; y < h; y++)
{
  currentDist = h / (2.0 * y - h); //you could make a small lookup table for this instead

  double weight = (currentDist - distPlayer) / (distWall - distPlayer);

  double currentFloorX = weight * floorXWall + (1.0 - weight) * posX;
  double currentFloorY = weight * floorYWall + (1.0 - weight) * posY;

  int floorTexX, floorTexY;
  floorTexX = int(currentFloorX * texWidth) % texWidth;
  floorTexY = int(currentFloorY * texHeight) % texHeight;
  ...

However, in the example for horizontal rendering we only get to calculate tx and ty for pixel positions on the texture:

for(int x = 0; x < screenWidth; ++x)
{
  // the cell coord is simply got from the integer parts of floorX and floorY
  int cellX = (int)(floorX);
  int cellY = (int)(floorY);

  // get the texture coordinate from the fractional part
  int tx = (int)(texWidth * (floorX - cellX)) & (texWidth - 1);
  int ty = (int)(texHeight * (floorY - cellY)) & (texHeight - 1);

  floorX += floorStepX;
  floorY += floorStepY;
  ...

I am not so good at trigonometry and only trying to understand these calculations. I've already tried various attempts with extracting integer and fractional parts of tx and ty mixed with map width and height. It resulted with total nonsense of currentFloorX and currentFloorY values and crashed, but sometimes produced really weird mosaic:

int currentFloorX = (int)((map->width & tx) * (floorX - cellX)) & (TEXTURE_SIZE -1);
int currentFloorY = (int)((map->height & ty) * (floorY - cellY)) & (TEXTURE_SIZE - 1);

Resulted in mess like this 3 mixed textures


Solution

  • Well, I guess this post motivated me to spend some more time on this.

    So, for anyone interested in the future, to obtain currentFloorX and currentFloorY:

    int currentFloorX = cellX % mapWidth;
    int currentFloorY = cellY % mapHeight;
    

    and then, having separate floor like floorMap (same size as worldMap) you simply do:

    int floorTexture = floorMap[currentFloorX][currentFloorY];