1///////////////////////////////////////////////////////////////////////////////////////////////////
2// OpenGL Image Copyright (c) 2008 - 2011 G-Truc Creation (www.g-truc.net)
3///////////////////////////////////////////////////////////////////////////////////////////////////
4// Created : 2010-09-27
5// Updated : 2010-09-27
6// Licence : This source is under MIT License
7// File    : gli/core/texture2D.inl
8///////////////////////////////////////////////////////////////////////////////////////////////////
9
10namespace gli
11{
12	namespace detail
13	{
14		inline texture2D::size_type sizeLinear
15		(
16			texture2D const & Texture
17		)
18		{
19			texture2D::size_type Result = 0;
20			for(texture2D::level_type Level = 0; Level < Texture.levels(); ++Level)
21				Result += sizeLinear(Texture[Level]);
22			return Result;
23		}
24	}//namespace detail
25
26	inline texture2D::texture2D()
27	{}
28
29	inline texture2D::texture2D
30	(
31		level_type const & Levels
32	)
33	{
34		this->Images.resize(Levels);
35	}
36
37	//inline texture2D::texture2D
38	//(
39	//	image const & Mipmap,
40	//	bool GenerateMipmaps // ToDo
41	//)
42	//{
43	//	//std::size_t Levels = !GenerateMipmaps ? 1 : std::size_t(glm::log2(float(glm::max(Mipmap.width(), Mipmap.height()))));
44	//	texture2D::level_type Levels = !GenerateMipmaps ? 1 : std::size_t(glm::log2(float(glm::compMax(Mipmap.dimensions()))));
45	//	this->Mipmaps.resize(Levels);
46	//	this->Mipmaps[0] = Mipmap;
47
48	//	if(GenerateMipmaps)
49	//		this->generateMipmaps(0);
50	//}
51
52	inline texture2D::~texture2D()
53	{}
54
55	inline image2D & texture2D::operator[] (level_type const & Level)
56	{
57		return this->Images[Level];
58	}
59
60	inline image2D const & texture2D::operator[] (level_type const & Level) const
61	{
62		return this->Images[Level];
63	}
64
65	inline bool texture2D::empty() const
66	{
67		return this->Images.size() == 0;
68	}
69
70	inline texture2D::format_type texture2D::format() const
71	{
72		return this->Images.empty() ? FORMAT_NULL : this->Images[0].format();
73	}
74
75	inline texture2D::level_type texture2D::levels() const
76	{
77		return this->Images.size();
78	}
79
80	inline void texture2D::resize
81	(
82		texture2D::level_type const & Levels
83	)
84	{
85		this->Images.resize(Levels);
86	}
87
88	template <typename genType>
89	inline void texture2D::swizzle(gli::comp X, gli::comp Y, gli::comp Z, gli::comp W)
90	{
91		for(texture2D::level_type Level = 0; Level < this->levels(); ++Level)
92		{
93			genType * Data = reinterpret_cast<genType*>(this->Images[Level].data());
94			texture2D::size_type Components = this->Images[Level].components();
95			//gli::detail::getComponents(this->Images[Level].format());
96			texture2D::size_type Size = (glm::compMul(this->Images[Level].dimensions()) * Components) / sizeof(genType);
97
98			for(texture2D::size_type i = 0; i < Size; ++i)
99			{
100				genType Copy = Data[i];
101				if(Components > 0)
102					Data[i][0] = Copy[X];
103				if(Components > 1)
104					Data[i][1] = Copy[Y];
105				if(Components > 2)
106					Data[i][2] = Copy[Z];
107				if(Components > 3)
108					Data[i][3] = Copy[W];
109			}
110		}
111	}
112
113/*
114	template <typename T>
115	inline T texture<T>::texture(float x, float y) const
116	{
117        size_type x_below = size_type(std::floor(x * (_width - 1)));
118		size_type x_above = size_type(std::ceil(x * (_width - 1)));
119        size_type y_below = size_type(std::floor(y * (_height - 1)));
120        size_type y_above = size_type(std::ceil(y * (_height - 1)));
121
122        float x_step = 1.0f / float(_width);
123        float y_step = 1.0f / float(_height);
124
125        float x_below_normalized = float(x_below) / float(_width - 1);
126        float x_above_normalized = float(x_above) / float(_width - 1);
127        float y_below_normalized = float(y_below) / float(_height - 1);
128        float y_above_normalized = float(y_above) / float(_height - 1);
129
130		T value1 = _data[x_below + y_below * _width];
131		T value2 = _data[x_above + y_below * _width];
132		T value3 = _data[x_above + y_above * _width];
133		T value4 = _data[x_below + y_above * _width];
134
135		T valueA = glm::mix(value1, value2, x - x_below_normalized);
136		T valueB = glm::mix(value4, value3, x - x_below_normalized);
137		T valueC = glm::mix(valueA, valueB, y - y_below_normalized);
138		return valueC;
139	}
140*/
141/*
142	template <typename T>
143	inline T texture(const texture2D<T>& Image2D, const glm::vec2& TexCoord)
144	{
145		texture2D<T>::size_type s_below = texture2D<T>::size_type(std::floor(TexCoord.s * (Image2D.width() - 1)));
146		texture2D<T>::size_type s_above = texture2D<T>::size_type(std::ceil(TexCoord.s * (Image2D.width() - 1)));
147        texture2D<T>::size_type t_below = texture2D<T>::size_type(std::floor(TexCoord.t * (Image2D.height() - 1)));
148        texture2D<T>::size_type t_above = texture2D<T>::size_type(std::ceil(TexCoord.t * (Image2D.height() - 1)));
149
150		glm::vec2::value_type s_step = 1.0f / glm::vec2::value_type(Image2D.width());
151        glm::vec2::value_type t_step = 1.0f / glm::vec2::value_type(Image2D.height());
152
153        glm::vec2::value_type s_below_normalized = glm::vec2::value_type(s_below) / glm::vec2::value_type(Image2D.width() - 1);
154        glm::vec2::value_type s_above_normalized = glm::vec2::value_type(s_above) / glm::vec2::value_type(Image2D.width() - 1);
155        glm::vec2::value_type t_below_normalized = glm::vec2::value_type(t_below) / glm::vec2::value_type(Image2D.height() - 1);
156        glm::vec2::value_type t_above_normalized = glm::vec2::value_type(t_above) / glm::vec2::value_type(Image2D.height() - 1);
157
158		T value1 = Image2D[s_below + t_below * Image2D.width()];
159		T value2 = Image2D[s_above + t_below * Image2D.width()];
160		T value3 = Image2D[s_above + t_above * Image2D.width()];
161		T value4 = Image2D[s_below + t_above * Image2D.width()];
162
163		T valueA = glm::mix(value1, value2, TexCoord.s - s_below_normalized);
164		T valueB = glm::mix(value4, value3, TexCoord.s - s_below_normalized);
165		T valueC = glm::mix(valueA, valueB, TexCoord.t - t_below_normalized);
166		return valueC;
167	}
168
169	template <typename T>
170	inline T textureNearest(const texture2D<T>& Image2D, const glm::vec2& TexCoord)
171	{
172		texture2D<T>::size_type s = texture2D<T>::size_type(glm::roundGTX(TexCoord.s * (Image2D.width() - 1)));
173        texture2D<T>::size_type t = texture2D<T>::size_type(std::roundGTX(TexCoord.t * (Image2D.height() - 1)));
174
175		return Image2D[s + t * Image2D.width()];
176	}
177*/
178
179namespace wip
180{
181	////////////////
182	// image
183/*
184	//
185	template
186	<
187		typename coordType
188	>
189	template
190	<
191		typename genType,
192		template <typename> class surface
193	>
194	typename texture2D<genType, surface>::value_type &
195	texture2D<genType, surface>::image_impl<coordType>::operator()
196	(
197		coordType const & Coord
198	)
199	{
200
201	}
202*/
203/*
204	//
205	template
206	<
207		typename coordType
208	>
209	template
210	<
211		typename genType,
212		template <typename> class surface
213	>
214	typename texture2D<genType, surface>::value_type const &
215	texture2D<genType, surface>::image_impl::operator()
216	(
217		coordType const & Coord
218	) const
219	{
220		return value_type(0);
221	}
222*/
223/*
224	//
225	template
226	<
227		typename coordType
228	>
229	template
230	<
231		typename genType,
232		template <typename> class surface
233	>
234	void texture2D<genType, surface>::image_impl::operator()
235	(
236		coordType const & Coord
237	) const
238	{
239
240	}
241*/
242	////
243	//template
244	//<
245	//	typename genType,
246	//	template <typename> class surface
247	//>
248	//template
249	//<
250	//	typename coordType
251	//>
252	//typename texture2D<genType, surface>::value_type const &
253	//texture2D<genType, surface>::image_impl::operator()
254	//(
255	//	coordType const & Coord
256	//) const
257	//{
258	//	return value_type(0);
259	//}
260
261	//////////////////
262	//// texture2D
263
264	////
265	//template
266	//<
267	//	typename genType,
268	//	template <typename> class surface
269	//>
270	//typename texture2D<genType, surface>::level_type texture2D<genType, surface>::levels() const
271	//{
272	//	return this->Mipmaps.size();
273	//}
274
275	////
276	//template
277	//<
278	//	typename genType,
279	//	template <typename> class surface
280	//>
281	//typename texture2D<genType, surface>::image & texture2D<genType, surface>::operator[]
282	//(
283	//	typename texture2D<genType, surface>::level_type Level
284	//)
285	//{
286	//	return this->Mipmaps[Level];
287	//}
288
289	////
290	//template
291	//<
292	//	typename genType,
293	//	template <typename> class surface
294	//>
295	//typename texture2D<genType, surface>::image const & texture2D<genType, surface>::operator[]
296	//(
297	//	typename texture2D<genType, surface>::level_type Level
298	//) const
299	//{
300	//	return this->Mipmaps[Level];
301	//}
302
303}//namespace wip
304}//namespace gli
305