OGLplus (0.52.0) a C++ wrapper for OpenGL

gradient.hpp
Go to the documentation of this file.
1 
12 #pragma once
13 #ifndef OGLPLUS_IMAGES_GRADIENT_1211090818_HPP
14 #define OGLPLUS_IMAGES_GRADIENT_1211090818_HPP
15 
16 #include <oglplus/images/image.hpp>
17 
18 #include <cassert>
19 #include <map>
20 
21 namespace oglplus {
22 namespace images {
23 
25 
29  : public Image
30 {
31 private:
32  template <
33  typename P,
34  typename T,
35  std::size_t N
36  > static void _make_gradient(
37  const Vector<T, N>& background,
38  GLsizei dimension,
39  const std::map<P, Vector<T, N>>& points,
40  std::vector<Vector<T, N>>& gradient
41  )
42  {
43  auto point_cur = points.begin(), point_end = points.end();
44  auto grad_cur = gradient.begin(), grad_end = gradient.end();
45 
46  const P step = P(1)/P(dimension);
47 
48  P prev_point = P(0);
49  P curr_point = P(0);
50  P next_point = P(1);
51 
52  Vector<T, N> prev_color = background;
53  Vector<T, N> next_color = background;
54 
55 
56  for(GLsizei p=0; p!=dimension; ++p)
57  {
58  if(point_cur != point_end)
59  {
60  if(point_cur->first <= curr_point)
61  {
62  prev_point = point_cur->first;
63  auto npp = point_cur;
64  ++npp;
65  if(npp != point_end)
66  {
67  prev_color = point_cur->second;
68  next_point = npp->first;
69  next_color = npp->second;
70  point_cur = npp;
71  }
72  else
73  {
74  prev_color = background;
75  next_point = P(1);
76  next_color = background;
77  }
78  }
79  else
80  {
81  next_point = point_cur->first;
82  }
83  }
84  P factor = P(0);
85  if(prev_point != next_point)
86  factor =(curr_point - prev_point)/
87  (next_point - prev_point);
88 
89  assert(grad_cur != grad_end);
90  *grad_cur = prev_color*(P(1)-factor)+next_color*factor;
91  ++grad_cur;
92 
93  curr_point += step;
94  }
95  assert(grad_cur == grad_end);
96  OGLPLUS_FAKE_USE(grad_end);
97  }
98 
99  static GLubyte _cc_max(void)
100  {
101  return ~GLubyte(0);
102  }
103 
104  template <typename T>
105  static T _clamp(T v)
106  {
107  if(v < T(0)) return T(0);
108  if(v > T(1)) return T(1);
109  return v;
110  }
111 
112  template <typename T, std::size_t N>
113  static void _apply_gradient(
114  const std::vector<Vector<T, N>>& grad0,
115  GLubyte* dp,
116  GLubyte* de
117  )
118  {
119  auto gb0 = grad0.begin(), ge0 = grad0.end();
120 
121  for(auto gp0=gb0; gp0!=ge0; ++gp0)
122  {
123  Vector<T, N> color = *gp0;
124  for(std::size_t c=0; c!=N; ++c)
125  {
126  assert(dp != de);
127  *dp++ = GLubyte(_clamp(color.At(c))*_cc_max());
128  }
129  }
130  OGLPLUS_FAKE_USE(de);
131  assert(dp == de);
132  }
133 
134  template <typename Combine, typename T, std::size_t N>
135  static void _apply_gradient(
136  Combine combine,
137  const std::vector<Vector<T, N>>& grad0,
138  const std::vector<Vector<T, N>>& grad1,
139  GLubyte* dp,
140  GLubyte* de
141  )
142  {
143  auto gb0 = grad0.begin(), ge0 = grad0.end();
144  auto gb1 = grad1.begin(), ge1 = grad1.end();
145 
146  for(auto gp0=gb0; gp0!=ge0; ++gp0)
147  for(auto gp1=gb1; gp1!=ge1; ++gp1)
148  {
149  Vector<T, N> color = combine(*gp0, *gp1);
150  for(std::size_t c=0; c!=N; ++c)
151  {
152  assert(dp != de);
153  *dp++ = GLubyte(_clamp(color.At(c))*_cc_max());
154  }
155  }
156  OGLPLUS_FAKE_USE(de);
157  assert(dp == de);
158  }
159 
160  template <typename Combine, typename T, std::size_t N>
161  static void _apply_gradient(
162  Combine combine,
163  const std::vector<Vector<T, N>>& grad0,
164  const std::vector<Vector<T, N>>& grad1,
165  const std::vector<Vector<T, N>>& grad2,
166  GLubyte* dp,
167  GLubyte* de
168  )
169  {
170  auto gb0 = grad0.begin(), ge0 = grad0.end();
171  auto gb1 = grad1.begin(), ge1 = grad1.end();
172  auto gb2 = grad2.begin(), ge2 = grad2.end();
173 
174  for(auto gp0=gb0; gp0!=ge0; ++gp0)
175  for(auto gp1=gb1; gp1!=ge1; ++gp1)
176  for(auto gp2=gb2; gp2!=ge2; ++gp2)
177  {
178  Vector<T, N> color = combine(*gp0, *gp1, *gp2);
179  for(std::size_t c=0; c!=N; ++c)
180  {
181  assert(dp != de);
182  *dp++ = GLubyte(_clamp(color.At(c))*_cc_max());
183  }
184  }
185  OGLPLUS_FAKE_USE(de);
186  assert(dp == de);
187  }
188 public:
189  struct AddComponents
190  {
191  template <typename T, std::size_t N>
192  Vector<T, N> operator()(
193  const Vector<T, N>& a,
194  const Vector<T, N>& b
195  ) const
196  {
197  return a + b;
198  }
199 
200  template <typename T, std::size_t N>
201  Vector<T, N> operator()(
202  const Vector<T, N>& a,
203  const Vector<T, N>& b,
204  const Vector<T, N>& c
205  ) const
206  {
207  return a + b + c;
208  }
209  };
210 
211  template <typename P, typename T, std::size_t N>
213  GLsizei width,
214  const Vector<T, N>& background,
215  const std::map<P, Vector<T, N>>& x_points
216  ): Image(width, 1, 1, N, (GLubyte*)0)
217  {
218  std::vector<Vector<T, N>> x_gradient(width);
219  _make_gradient(
220  background,
221  width,
222  x_points,
223  x_gradient
224  );
225  _apply_gradient(x_gradient, _begin_ub(), _end_ub());
226  }
227 
228  template <typename P, typename T, std::size_t N, typename Combine>
229  LinearGradient(
230  GLsizei width,
231  GLsizei height,
232  const Vector<T, N>& background,
233  const std::map<P, Vector<T, N>>& x_points,
234  const std::map<P, Vector<T, N>>& y_points,
235  Combine combine
236  ): Image(width, height, 1, N, (GLubyte*)0)
237  {
238  std::vector<Vector<T, N>> y_gradient(height);
239  _make_gradient(
240  background,
241  height,
242  y_points,
243  y_gradient
244  );
245 
246  std::vector<Vector<T, N>> x_gradient(width);
247  _make_gradient(
248  background,
249  width,
250  x_points,
251  x_gradient
252  );
253 
254  _apply_gradient(
255  combine,
256  y_gradient,
257  x_gradient,
258  _begin_ub(),
259  _end_ub()
260  );
261  }
262 
263  template <typename P, typename T, std::size_t N, typename Combine>
264  LinearGradient(
265  GLsizei width,
266  GLsizei height,
267  GLsizei depth,
268  const Vector<T, N>& background,
269  const std::map<P, Vector<T, N>>& x_points,
270  const std::map<P, Vector<T, N>>& y_points,
271  const std::map<P, Vector<T, N>>& z_points,
272  Combine combine
273  ): Image(width, height, depth, N, (GLubyte*)0)
274  {
275  std::vector<Vector<T, N>> z_gradient(depth);
276  _make_gradient(
277  background,
278  depth,
279  z_points,
280  z_gradient
281  );
282 
283  std::vector<Vector<T, N>> y_gradient(height);
284  _make_gradient(
285  background,
286  height,
287  y_points,
288  y_gradient
289  );
290 
291  std::vector<Vector<T, N>> x_gradient(width);
292  _make_gradient(
293  background,
294  width,
295  x_points,
296  x_gradient
297  );
298 
299  _apply_gradient(
300  combine,
301  z_gradient,
302  y_gradient,
303  x_gradient,
304  _begin_ub(),
305  _end_ub()
306  );
307  }
308 };
309 
310 } // images
311 } // oglplus
312 
313 #endif // include guard
T At(const Vector &vector, std::size_t i) const T x(void) const
Returns the value of the i-th coordinate of the vector.
Definition: vector.hpp:221
Wrapper for (texture) image data.
Definition: image.hpp:45
Creates a 1D, 2D or 3D linear gradient image.
Definition: gradient.hpp:28
Basic template for vector types.
Definition: fwd.hpp:43
Image data wrapper.

Copyright © 2010-2014 Matúš Chochlík, University of Žilina, Žilina, Slovakia.
<matus.chochlik -at- fri.uniza.sk>
<chochlik -at -gmail.com>
Documentation generated on Mon Sep 22 2014 by Doxygen (version 1.8.6).