Part 4: Texture mapping - krisp3t/KrisRaycaster GitHub Wiki

Texture atlas

I've created a texture atlas - all my textures are composed in one 512x512 texture atlas. I've used open-source Faithful resource pack for Minecraft which has a similar format, composing of 32x32 textures.

Faithful

Importing into TouchGFX

TouchGFX makes importing images very straightforward. You simply select the desired format and memory section in which to place the image. image

You can then get pixel data simply by:

touchgfx::Bitmap mapSource(BITMAP_WALL_ID);
const uint16_t* texData = (const uint16_t*)mapSource.getData();

Use

Getting the texture by its index can be done by figuring out x and y value from texture size and atlas stride:

touchgfx::Rect Raycaster::getMapRect(uint8_t cellType)
{
    int16_t rectX = ((cellType - 1) % TEXTURE_STRIDE) * TEXTURE_SIDE;
    int16_t rectY = ((cellType - 1) / TEXTURE_STRIDE) * TEXTURE_SIDE;
    return touchgfx::Rect{
		rectX,
		rectY,
		TEXTURE_SIDE,
		TEXTURE_SIDE};
}

Scaling

We cannot assume source (texture) and destination (part of framebuffer where we want to display texture) will be of same width and size. We need to apply scaling:

void copySrcDestRect(
                     const uint16_t *src, 
                     uint16_t *dest, 
                     Vec2 srcSize, 
                     Vec2 destSize, 
                     touchgfx::Rect srcRect, 
                     touchgfx::Rect destRect
)
{
    float scaleX = static_cast<float>(srcRect.width) / destRect.width;
    float scaleY = static_cast<float>(srcRect.height) / destRect.height;
    for (uint16_t destY = destRect.y; destY < destRect.y + destRect.height; destY++)
    {
        for (uint16_t destX = destRect.x; destX < destRect.x + destRect.width; destX++)
        {
            uint16_t srcX = static_cast<uint16_t>((destX - destRect.x) * scaleX) + srcRect.x;
            uint16_t srcY = static_cast<uint16_t>((destY - destRect.y) * scaleY) + srcRect.y;
            dest[destY * destSize.x + destX] = src[srcY * srcSize.x + srcX];
        }
    }
}

Displaying minimap

We can now initialize and display minimap by iterating through our map array. We can get the texture of individual cell from texture atlas, which is then written in appropriate row and column in the map section of framebuffer.

Minimap

⚠️ **GitHub.com Fallback** ⚠️