在这个精彩的 lodev 光线投射教程 (https://lodev.org/cgtutor/raycasting2.html) 中,我们有一个关于地板和天花板的部分。 我敢打赌我的问题很简单,但我无法帮助自己。
使用水平渲染方法,我想为地图上的每个图块渲染不同的纹理。在 lodev 的示例中,我们得到
currentFloorX
和 currentFloorY
,但仅使用垂直渲染:
//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;
...
但是,在水平渲染的示例中,我们只能计算纹理上像素位置的
tx
和 ty
:
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;
...
我不太擅长三角学,只是想理解这些计算。我已经尝试过提取
tx
和 ty
的整数和小数部分与地图宽度和高度混合的各种尝试。它导致 currentFloorX
和 currentFloorY
值完全无意义并崩溃,但有时会产生非常奇怪的马赛克:
int currentFloorX = (int)((map->width & tx) * (floorX - cellX)) & (TEXTURE_SIZE -1);
int currentFloorY = (int)((map->height & ty) * (floorY - cellY)) & (TEXTURE_SIZE - 1);
嗯,我想这篇文章激励我花更多时间在这上面。
因此,对于任何对未来感兴趣的人,要获得
currentFloorX
和 currentFloorY
:
int currentFloorX = cellX % mapWidth;
int currentFloorY = cellY % mapHeight;
然后,拥有像
floorMap
这样的单独地板(与worldMap
大小相同),你只需这样做:
int floorTexture = floorMap[currentFloorX][currentFloorY];