* Compute the aligned memory required for the texture. * Add texels to the texture if either dimension is not a factor of 4 (required for BC7 compressed formats). */
| 78 | * Add texels to the texture if either dimension is not a factor of 4 (required for BC7 compressed formats). |
| 79 | */ |
| 80 | bool FormatTexture(TextureData& texture, DirectX::XMFLOAT2& uvAdjustment) |
| 81 | { |
| 82 | // BC7 compressed textures require 4x4 texel blocks |
| 83 | // Add texels to the texture if its original dimensions aren't factors of 4 |
| 84 | if (texture.width % 4 != 0 || texture.height % 4 != 0) |
| 85 | { |
| 86 | // Get original row stride |
| 87 | UINT originalWidth = texture.width; |
| 88 | UINT rowSize = (texture.width * texture.stride); |
| 89 | UINT numRows = texture.height; |
| 90 | |
| 91 | // Align the new texture to 4x4 |
| 92 | texture.width = ALIGN(4, texture.width); |
| 93 | texture.height = ALIGN(4, texture.height); |
| 94 | |
| 95 | UINT alignedRowSize = (texture.width * texture.stride); |
| 96 | UINT size = alignedRowSize * texture.height; |
| 97 | |
| 98 | // Figure out uv adjustment needed due to padding (we want UVs to point to the area where original unpadded texture is) |
| 99 | uvAdjustment.x = float(originalWidth) / float(texture.width); |
| 100 | uvAdjustment.y = float(numRows) / float(texture.height); |
| 101 | |
| 102 | // Copy the original texture into the new one |
| 103 | size_t offset = 0; |
| 104 | size_t alignedOffset = 0; |
| 105 | UINT8* texels = new UINT8[size]; |
| 106 | |
| 107 | for (UINT row = 0; row < numRows; row++) |
| 108 | { |
| 109 | memcpy(&texels[alignedOffset], &texture.texels[offset], rowSize); |
| 110 | |
| 111 | // Fill empty space in the aligned row with border pixel value |
| 112 | for (UINT i = 0; i < texture.width - originalWidth; i++) { |
| 113 | memcpy(&texels[alignedOffset + rowSize + (i * UINT(texture.stride))], &texels[alignedOffset + rowSize - texture.stride], texture.stride); |
| 114 | } |
| 115 | |
| 116 | alignedOffset += alignedRowSize; |
| 117 | offset += rowSize; |
| 118 | } |
| 119 | |
| 120 | // Copy last row values into new rows |
| 121 | UINT lastRowOffset = alignedOffset - alignedRowSize; |
| 122 | for (UINT row = 0; row < texture.height - numRows; row++) |
| 123 | { |
| 124 | memcpy(&texels[alignedOffset], &texels[lastRowOffset], alignedRowSize); |
| 125 | |
| 126 | alignedOffset += alignedRowSize; |
| 127 | offset += rowSize; |
| 128 | } |
| 129 | |
| 130 | // Release the memory of the original texture |
| 131 | UnloadTextureData(texture); |
| 132 | texture.texels = texels; |
| 133 | } |
| 134 | |
| 135 | // Compute the texture's aligned memory size |
| 136 | texture.rowPitch = (texture.width * texture.stride); |
| 137 | texture.texelBytes = (texture.rowPitch * UINT64(texture.height)); |
no test coverage detected