inline void generate_mipmaps_1d ( texture_type & Texture, fetch_func Fetch, write_func Write, typename texture_type::size_type BaseLayer, typename texture_type::size_type MaxLayer, typename texture_type::size_type BaseFace, typename texture_type::size_type MaxFace, typename texture_type::size_type BaseLevel, typename texture_type::size_type MaxLevel, filter Min ) { typedef typename detail::interpolate<sampler_value_type>::type interpolate_type; typedef typename texture_type::texelcoord_type texelcoord_type; typedef typename texture_type::size_type size_type; typedef typename texelcoord_type::value_type component_type; typedef typename detail::filterBase<detail::DIMENSION_1D, texture_type, interpolate_type, samplecoord_type, fetch_func, texel_type>::filterFunc filter_func; filter_func const Filter = detail::get_filter<filter_func, detail::DIMENSION_1D, texture_type, interpolate_type, samplecoord_type, fetch_func, texel_type, sampler_value_type>(FILTER_NEAREST, Min, false); GLI_ASSERT(Filter); for(size_type Layer = BaseLayer; Layer <= MaxLayer; ++Layer) for(size_type Face = BaseFace; Face <= MaxFace; ++Face) for(size_type Level = BaseLevel; Level < MaxLevel; ++Level) { texelcoord_type const& DimDst = Texture.dimensions(Level + 1); samplecoord_type const& Scale = samplecoord_type(1) / samplecoord_type(max(DimDst - texelcoord_type(1), texelcoord_type(1))); for(component_type i = 0; i < DimDst.x; ++i) { samplecoord_type const& SamplePosition(samplecoord_type(static_cast<typename samplecoord_type::value_type>(i)) * Scale); texel_type const& Texel = Filter(Texture, Fetch, SamplePosition, Layer, Face, static_cast<sampler_value_type>(Level), texel_type(0)); Write(Texture, texelcoord_type(i), Layer, Face, Level + 1, Texel); } } }
inline filter_type get_filter(filter Mip, filter Min, bool Border) { static filter_type Table[][FILTER_COUNT][2] = { { { nearest_mipmap_nearest<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, false>::call, nearest_mipmap_nearest<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, true>::call }, { linear_mipmap_nearest<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, false>::call, linear_mipmap_nearest<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, true>::call } }, { { nearest_mipmap_linear<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, false>::call, nearest_mipmap_linear<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, true>::call }, { linear_mipmap_linear<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, false>::call, linear_mipmap_linear<Dimensions, texture_type, interpolate_type, samplecoord_type, fetch_type, texel_type, std::numeric_limits<T>::is_iec559, true>::call } } }; static_assert(sizeof(Table) / sizeof(Table[0]) == FILTER_COUNT, "GLI ERROR: 'Table' doesn't match the number of supported filters"); GLI_ASSERT(Table[Mip - FILTER_FIRST][Min - FILTER_FIRST][Border ? 1 : 0]); return Table[Mip - FILTER_FIRST][Min - FILTER_FIRST][Border ? 1 : 0]; }
int run() { int Error(0); { gli::texture1d Texture(gli::FORMAT_RGBA8_UINT_PACK8, gli::texture1d::extent_type(2), 2); GLI_ASSERT(!Texture.empty()); gli::image Image0 = Texture[0]; gli::image Image1 = Texture[1]; std::size_t Size0 = Image0.size(); std::size_t Size1 = Image1.size(); Error += Size0 == sizeof(glm::u8vec4) * 2 ? 0 : 1; Error += Size1 == sizeof(glm::u8vec4) * 1 ? 0 : 1; *Image0.data<glm::u8vec4>() = glm::u8vec4(255, 127, 0, 255); *Image1.data<glm::u8vec4>() = glm::u8vec4(0, 127, 255, 255); glm::u8vec4 * PointerA = Image0.data<glm::u8vec4>(); glm::u8vec4 * PointerB = Image1.data<glm::u8vec4>(); glm::u8vec4 * Pointer0 = Texture.data<glm::u8vec4>() + 0; glm::u8vec4 * Pointer1 = Texture.data<glm::u8vec4>() + 2; Error += PointerA == Pointer0 ? 0 : 1; Error += PointerB == Pointer1 ? 0 : 1; glm::u8vec4 ColorA = *Image0.data<glm::u8vec4>(); glm::u8vec4 ColorB = *Image1.data<glm::u8vec4>(); glm::u8vec4 Color0 = *Pointer0; glm::u8vec4 Color1 = *Pointer1; Error += ColorA == Color0 ? 0 : 1; Error += ColorB == Color1 ? 0 : 1; Error += glm::all(glm::equal(Color0, glm::u8vec4(255, 127, 0, 255))) ? 0 : 1; Error += glm::all(glm::equal(Color1, glm::u8vec4(0, 127, 255, 255))) ? 0 : 1; } { gli::texture Texture(gli::TARGET_2D, gli::FORMAT_RGBA8_UINT_PACK8, gli::texture::extent_type(1), 1, 1, 1); std::size_t SizeA = Texture.size(); Error += SizeA == sizeof(glm::u8vec4) * 1 ? 0 : 1; *Texture.data<glm::u8vec4>() = glm::u8vec4(255, 127, 0, 255); glm::u8vec4 * Pointer0 = Texture.data<glm::u8vec4>() + 0;; glm::u8vec4 Color0 = *Pointer0; Error += glm::all(glm::equal(Color0, glm::u8vec4(255, 127, 0, 255))) ? 0 : 1; } return Error; }
int test(params const & Params) { int Error(0); gli::texture2D TextureA(gli::load_dds(path(Params.Filename.c_str()))); Error += TextureA.format() == Params.Format ? 0 : 1; GLI_ASSERT(!Error); gli::save_dds(TextureA, Params.Filename.c_str()); gli::texture2D TextureB(gli::load_dds(Params.Filename.c_str())); Error += TextureB.format() == Params.Format ? 0 : 1; GLI_ASSERT(!Error); Error += TextureA == TextureB ? 0 : 1; GLI_ASSERT(!Error); return Error; }
int test_texture3d_access() { int Error(0); { glm::u8vec4 const Orange(255, 127, 0, 255); gli::image Image(gli::FORMAT_RGBA8_UINT_PACK8, gli::image::extent_type(2)); gli::texture3d Texture(gli::FORMAT_RGBA8_UINT_PACK8, gli::texture3d::extent_type(2), gli::texture3d::size_type(1)); Error += Image.size() == Texture.size() ? 0 : 1; } { gli::texture3d Texture( gli::FORMAT_RGBA8_UINT_PACK8, gli::texture3d::extent_type(2), gli::texture3d::size_type(2)); GLI_ASSERT(!Texture.empty()); gli::image Image0 = Texture[0]; gli::image Image1 = Texture[1]; std::size_t Size0 = Image0.size(); std::size_t Size1 = Image1.size(); Error += Size0 == sizeof(glm::u8vec4) * 8 ? 0 : 1; Error += Size1 == sizeof(glm::u8vec4) * 1 ? 0 : 1; *Image0.data<glm::u8vec4>() = glm::u8vec4(255, 127, 0, 255); *Image1.data<glm::u8vec4>() = glm::u8vec4(0, 127, 255, 255); glm::u8vec4 * PointerA = Image0.data<glm::u8vec4>(); glm::u8vec4 * PointerB = Image1.data<glm::u8vec4>(); glm::u8vec4 * Pointer0 = Texture.data<glm::u8vec4>() + 0; glm::u8vec4 * Pointer1 = Texture.data<glm::u8vec4>() + 8; Error += PointerA == Pointer0 ? 0 : 1; Error += PointerB == Pointer1 ? 0 : 1; glm::u8vec4 ColorA = *Image0.data<glm::u8vec4>(); glm::u8vec4 ColorB = *Image1.data<glm::u8vec4>(); glm::u8vec4 Color0 = *Pointer0; glm::u8vec4 Color1 = *Pointer1; Error += ColorA == Color0 ? 0 : 1; Error += ColorB == Color1 ? 0 : 1; Error += glm::all(glm::equal(Color0, glm::u8vec4(255, 127, 0, 255))) ? 0 : 1; Error += glm::all(glm::equal(Color1, glm::u8vec4(0, 127, 255, 255))) ? 0 : 1; } return Error; }
int test(std::vector<char> const & Data, params const & Params) { int Error(0); gli::texture2D TextureA(gli::load_dds(&Data[0], Data.size())); Error += TextureA.format() == Params.Format ? 0 : 1; GLI_ASSERT(!Error); std::vector<char> Memory; gli::save_dds(TextureA, Memory); gli::texture2D TextureB(gli::load_dds(&Memory[0], Memory.size())); Error += TextureB.format() == Params.Format ? 0 : 1; GLI_ASSERT(!Error); Error += TextureA == TextureB ? 0 : 1; GLI_ASSERT(!Error); return Error; }
int test_texture3d_size() { int Error(0); std::vector<test> Tests; Tests.push_back(test(gli::FORMAT_RGBA8_UINT_PACK8, gli::texture3d::extent_type(4), 256)); Tests.push_back(test(gli::FORMAT_R8_UINT_PACK8, gli::texture3d::extent_type(4), 64)); Tests.push_back(test(gli::FORMAT_RGBA_DXT1_UNORM_BLOCK8, gli::texture3d::extent_type(4), 32)); Tests.push_back(test(gli::FORMAT_RGBA_DXT1_UNORM_BLOCK8, gli::texture3d::extent_type(2), 32)); Tests.push_back(test(gli::FORMAT_RGBA_DXT1_UNORM_BLOCK8, gli::texture3d::extent_type(1), 32)); Tests.push_back(test(gli::FORMAT_RGBA_DXT5_UNORM_BLOCK16, gli::texture3d::extent_type(4), 64)); for(std::size_t i = 0; i < Tests.size(); ++i) { gli::texture3d Texture( Tests[i].Format, gli::texture3d::extent_type(4), 1); Error += Texture.size() == Tests[i].Size ? 0 : 1; GLI_ASSERT(!Error); } for(std::size_t i = 0; i < Tests.size(); ++i) { gli::texture3d Texture( Tests[i].Format, gli::texture3d::extent_type(4), 1); gli::image Image = Texture[0]; Error += Image.size() == Tests[i].Size ? 0 : 1; GLI_ASSERT(!Error); } return Error; }
int test() { int Error(0); gli::texture2d TextureA(gli::load(path("kueken7_rgba16_sfloat.ktx"))); GLI_ASSERT(!TextureA.empty()); gli::texture2d Convert = gli::convert(TextureA, gli::FORMAT_RG11B10_UFLOAT_PACK32); gli::save(Convert, "kueken7_rg11b10_ufloat.dds"); gli::save(Convert, "kueken7_rg11b10_ufloat.ktx"); gli::texture2d TextureDDS(gli::load("kueken7_rg11b10_ufloat.dds")); GLI_ASSERT(!TextureDDS.empty()); gli::texture2d TextureKTX(gli::load("kueken7_rg11b10_ufloat.ktx")); GLI_ASSERT(!TextureKTX.empty()); Error += TextureDDS == TextureKTX ? 0 : 1; Error += TextureDDS == Convert ? 0 : 1; GLI_ASSERT(!Error); return Error; }
int main() { int Error(0); Error += swizzle::run(); Error += texture1d::run(); Error += texture1d_array::run(); Error += texture2d::run(); Error += texture2d_array::run(); Error += texture3d::run(); Error += texture_cube::run(); Error += texture_cube_array::run(); GLI_ASSERT(!Error); return Error; }
int run() { int Error(0); std::vector<test> Tests; Tests.push_back(test(gli::FORMAT_RGBA8_UINT_PACK8, gli::texture::extent_type(1), 4)); Tests.push_back(test(gli::FORMAT_R8_UINT_PACK8, gli::texture::extent_type(1), 1)); for(std::size_t i = 0; i < Tests.size(); ++i) { gli::texture Texture( gli::TARGET_2D, Tests[i].Format, gli::texture::extent_type(1), gli::texture::size_type(1), gli::texture::size_type(1), gli::texture::size_type(1)); Error += Texture.size() == Tests[i].Size ? 0 : 1; GLI_ASSERT(!Error); } return Error; }
inline size_t linear_index(tvec3<T, P> const & Coord, tvec3<T, P> const & Dimensions) { GLI_ASSERT(glm::all(glm::lessThan(Coord, Dimensions))); return static_cast<size_t>(Coord.x + Coord.y * Dimensions.x + Coord.z * Dimensions.x * Dimensions.y); }