指向纹理数据的指针-垂直翻转数据



我使用一个库来加载纹理,它返回一个指向数据、图像宽度和高度的指针。我想垂直翻转纹理数据,所以我创建了以下功能:

void FlipYTexture(const unsigned int width, const unsigned int height, uint8_t* data)
{
const unsigned int rowsSwapCount = height / 2;
const unsigned int maxRowIndex = height - 1;
for (int i = 0; i < rowsSwapCount; ++i)
{
for (int j = 0; j < width; ++j)
{
const unsigned int currentDataIndex = width * i + j;
const unsigned int swapDataIndex = width * (maxRowIndex - i) + j;
uint8_t temp = data[currentDataIndex];
data[currentDataIndex] = data[swapDataIndex];
data[swapDataIndex] = temp;
}
} 
}

有什么方法可以优化该功能和/或更简单地实现它吗?

如果您可以将数据参数从指针更改为数组引用,那么这将是一个更简单的选项,尽管我不知道如果不使用典型的输入数据进行测试,它会更快。

#include <algorithm>
template<typename T, size_t N> 
void FlipYTexture(const unsigned int width, const unsigned int height, T(&data)[N]) {
std::reverse(std::begin(data), std::end(data));
}

如果必须将数据参数作为指针,那么您至少可以使用std::swap:

#include <utility>
void FlipYTexture(const unsigned int width, const unsigned int height, uint8_t* data) {
const unsigned int rowsSwapCount = height / 2;
const unsigned int maxRowIndex = height - 1;
for (unsigned int i = 0; i < rowsSwapCount; ++i) {
for (unsigned int j = 0; j < width; ++j) {
const unsigned int currentDataIndex = width * i + j;
const unsigned int swapDataIndex = width * (maxRowIndex - i) + j;
std::swap(data[currentDataIndex], data[swapDataIndex]);
}
}
}

将内部循环分解为标准算法,并使用简化的指针算法:

#include <cstdint>
#include <algorithm>
void FlipYTexture(unsigned width, unsigned height, uint8_t* data)
{
auto row_offset = [&](unsigned row)
{
return row * height;
};
// pointer arithmetic once up front
auto first_row = data + row_offset(0);
auto last_row = data + row_offset(height / 2);
auto other_row = data + row_offset(height);
// swap each row
for ( ; first_row != last_row ; first_row += width )
{
other_row -= width;
std::swap_ranges(first_row, first_row + width, other_row);
}
}

最新更新