1 #pragma once
2 
3 #include "filter_compute.hpp"
4 
5 namespace gli{
6 namespace detail
7 {
8 	template <typename texture_type, typename sampler_value_type, typename fetch_func, typename write_func, typename normalized_type, typename texel_type>
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)9 	inline void generate_mipmaps_1d
10 	(
11 		texture_type & Texture, fetch_func Fetch, write_func Write,
12 		typename texture_type::size_type BaseLayer, typename texture_type::size_type MaxLayer,
13 		typename texture_type::size_type BaseFace, typename texture_type::size_type MaxFace,
14 		typename texture_type::size_type BaseLevel, typename texture_type::size_type MaxLevel,
15 		filter Min
16 	)
17 	{
18 		typedef typename detail::interpolate<sampler_value_type>::type interpolate_type;
19 		typedef typename texture_type::extent_type extent_type;
20 		typedef typename texture_type::size_type size_type;
21 		typedef typename extent_type::value_type component_type;
22 		typedef typename detail::filterBase<detail::DIMENSION_1D, texture_type, interpolate_type, normalized_type, fetch_func, texel_type>::filterFunc filter_func;
23 
24 		filter_func const Filter = detail::get_filter<filter_func, detail::DIMENSION_1D, texture_type, interpolate_type, normalized_type, fetch_func, texel_type, sampler_value_type>(FILTER_NEAREST, Min, false);
25 		GLI_ASSERT(Filter);
26 
27 		for(size_type Layer = BaseLayer; Layer <= MaxLayer; ++Layer)
28 		for(size_type Face = BaseFace; Face <= MaxFace; ++Face)
29 		for(size_type Level = BaseLevel; Level < MaxLevel; ++Level)
30 		{
31 			extent_type const& ExtentDst = Texture.extent(Level + 1);
32 			normalized_type const& Scale = normalized_type(1) / normalized_type(max(ExtentDst - extent_type(1), extent_type(1)));
33 
34 			for(component_type i = 0; i < ExtentDst.x; ++i)
35 			{
36 				normalized_type const& SamplePosition(normalized_type(static_cast<typename normalized_type::value_type>(i)) * Scale);
37 				texel_type const& Texel = Filter(Texture, Fetch, SamplePosition, Layer, Face, static_cast<sampler_value_type>(Level), texel_type(0));
38 				Write(Texture, extent_type(i), Layer, Face, Level + 1, Texel);
39 			}
40 		}
41 	}
42 
43 	template <typename texture_type, typename sampler_value_type, typename fetch_func, typename write_func, typename normalized_type, typename texel_type>
generate_mipmaps_2d(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)44 	inline void generate_mipmaps_2d
45 	(
46 		texture_type & Texture, fetch_func Fetch, write_func Write,
47 		typename texture_type::size_type BaseLayer, typename texture_type::size_type MaxLayer,
48 		typename texture_type::size_type BaseFace, typename texture_type::size_type MaxFace,
49 		typename texture_type::size_type BaseLevel, typename texture_type::size_type MaxLevel,
50 		filter Min
51 	)
52 	{
53 		typedef typename detail::interpolate<sampler_value_type>::type interpolate_type;
54 		typedef typename texture_type::extent_type extent_type;
55 		typedef typename texture_type::size_type size_type;
56 		typedef typename extent_type::value_type component_type;
57 		typedef typename detail::filterBase<detail::DIMENSION_2D, texture_type, interpolate_type, normalized_type, fetch_func, texel_type>::filterFunc filter_func;
58 
59 		filter_func const Filter = detail::get_filter<filter_func, detail::DIMENSION_2D, texture_type, interpolate_type, normalized_type, fetch_func, texel_type, sampler_value_type>(FILTER_NEAREST, Min, false);
60 		GLI_ASSERT(Filter);
61 
62 		for(size_type Layer = BaseLayer; Layer <= MaxLayer; ++Layer)
63 		for(size_type Face = BaseFace; Face <= MaxFace; ++Face)
64 		for(size_type Level = BaseLevel; Level < MaxLevel; ++Level)
65 		{
66 			extent_type const& ExtentDst = Texture.extent(Level + 1);
67 			normalized_type const& Scale = normalized_type(1) / normalized_type(max(ExtentDst - extent_type(1), extent_type(1)));
68 
69 			for(component_type j = 0; j < ExtentDst.y; ++j)
70 			for(component_type i = 0; i < ExtentDst.x; ++i)
71 			{
72 				normalized_type const& SamplePosition(normalized_type(i, j) * Scale);
73 				texel_type const& Texel = Filter(Texture, Fetch, SamplePosition, Layer, Face, static_cast<sampler_value_type>(Level), texel_type(0));
74 				Write(Texture, extent_type(i, j), Layer, Face, Level + 1, Texel);
75 			}
76 		}
77 	}
78 
79 	template <typename texture_type, typename sampler_value_type, typename fetch_func, typename write_func, typename normalized_type, typename texel_type>
generate_mipmaps_3d(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)80 	inline void generate_mipmaps_3d
81 	(
82 		texture_type & Texture, fetch_func Fetch, write_func Write,
83 		typename texture_type::size_type BaseLayer, typename texture_type::size_type MaxLayer,
84 		typename texture_type::size_type BaseFace, typename texture_type::size_type MaxFace,
85 		typename texture_type::size_type BaseLevel, typename texture_type::size_type MaxLevel,
86 		filter Min
87 	)
88 	{
89 		typedef typename detail::interpolate<sampler_value_type>::type interpolate_type;
90 		typedef typename texture_type::extent_type extent_type;
91 		typedef typename texture_type::size_type size_type;
92 		typedef typename extent_type::value_type component_type;
93 		typedef typename detail::filterBase<detail::DIMENSION_3D, texture_type, interpolate_type, normalized_type, fetch_func, texel_type>::filterFunc filter_func;
94 
95 		filter_func const Filter = detail::get_filter<filter_func, detail::DIMENSION_3D, texture_type, interpolate_type, normalized_type, fetch_func, texel_type, sampler_value_type>(FILTER_NEAREST, Min, false);
96 		GLI_ASSERT(Filter);
97 
98 		for(size_type Layer = BaseLayer; Layer <= MaxLayer; ++Layer)
99 		for(size_type Face = BaseFace; Face <= MaxFace; ++Face)
100 		for(size_type Level = BaseLevel; Level < MaxLevel; ++Level)
101 		{
102 			extent_type const& ExtentDst = Texture.extent(Level + 1);
103 			normalized_type const& Scale = normalized_type(1) / normalized_type(max(ExtentDst - extent_type(1), extent_type(1)));
104 
105 			for(component_type k = 0; k < ExtentDst.z; ++k)
106 			for(component_type j = 0; j < ExtentDst.y; ++j)
107 			for(component_type i = 0; i < ExtentDst.x; ++i)
108 			{
109 				normalized_type const& SamplePosition(normalized_type(i, j, k) * Scale);
110 				texel_type const& Texel = Filter(Texture, Fetch, SamplePosition, Layer, Face, static_cast<sampler_value_type>(Level), texel_type(0));
111 				Write(Texture, extent_type(i, j, k), Layer, Face, Level + 1, Texel);
112 			}
113 		}
114 	}
115 }//namespace detail
116 }//namespace gli
117