1///////////////////////////////////////////////////////////////////////////////////////////////////
2// OpenGL Image Copyright (c) 2008 - 2011 G-Truc Creation (www.g-truc.net)
3///////////////////////////////////////////////////////////////////////////////////////////////////
4// Created : 2008-12-19
5// Updated : 2010-09-27
6// Licence : This source is under MIT License
7// File    : gli/gtx/fetch.inl
8///////////////////////////////////////////////////////////////////////////////////////////////////
9
10namespace gli{
11namespace gtx{
12namespace fetch
13{
14	template <typename genType>
15	inline genType texelFetch
16	(
17		texture2D const & Image,
18		texture2D::dimensions_type const & TexCoord,
19		texture2D::level_type const & Level
20	)
21	{
22		assert(Image[Level].format() == R8U || Image[Level].format() == RG8U || Image[Level].format() == RGB8U || Image[Level].format() == RGBA8U);
23
24		texture2D::dimensions_type Dimensions = Image[Level].dimensions();
25		texture2D::value_type const * const Data = Image[Level].data();
26
27		return reinterpret_cast<genType const * const>(Data)[TexCoord.x + TexCoord.y * Dimensions.x];
28	}
29
30	template <typename genType>
31	inline genType textureLod
32	(
33		texture2D const & Image,
34		texture2D::texcoord_type const & TexCoord,
35		texture2D::level_type const & Level
36	)
37	{
38		assert(Image[Level].format() == R8U || Image[Level].format() == RG8U || Image[Level].format() == RGB8U || Image[Level].format() == RGBA8U);
39
40		texture2D::dimensions_type Dimensions = Image[Level].dimensions();
41		texture2D::value_type const * const Data = Image[Level].data();
42
43		std::size_t s_below = std::size_t(glm::floor(TexCoord.s * float(Dimensions.x - 1)));
44		std::size_t s_above = std::size_t(glm::ceil( TexCoord.s * float(Dimensions.x - 1)));
45		std::size_t t_below = std::size_t(glm::floor(TexCoord.t * float(Dimensions.y - 1)));
46		std::size_t t_above = std::size_t(glm::ceil( TexCoord.t * float(Dimensions.y - 1)));
47
48		float s_step = 1.0f / float(Dimensions.x);
49		float t_step = 1.0f / float(Dimensions.y);
50
51		float s_below_normalized = s_below / float(Dimensions.x);
52		float s_above_normalized = s_above / float(Dimensions.x);
53		float t_below_normalized = t_below / float(Dimensions.y);
54		float t_above_normalized = t_above / float(Dimensions.y);
55
56		genType Value1 = reinterpret_cast<genType const * const>(Data)[s_below + t_below * Dimensions.x];
57		genType Value2 = reinterpret_cast<genType const * const>(Data)[s_above + t_below * Dimensions.x];
58		genType Value3 = reinterpret_cast<genType const * const>(Data)[s_above + t_above * Dimensions.x];
59		genType Value4 = reinterpret_cast<genType const * const>(Data)[s_below + t_above * Dimensions.x];
60
61		float BlendA = float(TexCoord.s - s_below_normalized) * float(Dimensions.x - 1);
62		float BlendB = float(TexCoord.s - s_below_normalized) * float(Dimensions.x - 1);
63		float BlendC = float(TexCoord.t - t_below_normalized) * float(Dimensions.y - 1);
64
65		genType ValueA(glm::mix(Value1, Value2, BlendA));
66		genType ValueB(glm::mix(Value4, Value3, BlendB));
67
68		return genType(glm::mix(ValueA, ValueB, BlendC));
69	}
70
71	template <typename genType>
72	void texelWrite
73	(
74		texture2D & Image,
75		texture2D::dimensions_type const & Texcoord,
76		texture2D::level_type const & Level,
77		genType const & Color
78	)
79	{
80		genType * Data = (genType*)Image[Level].data();
81		std::size_t Index = Texcoord.x + Texcoord.y * Image[Level].dimensions().x;
82
83		std::size_t Capacity = Image[Level].capacity();
84		assert(Index < Capacity);
85
86		*(Data + Index) = Color;
87	}
88
89}//namespace fetch
90}//namespace gtx
91}//namespace gli
92